These can be passed to gst_type_mark_as_plugin_api, to inform
plugin cache generation.
For now a single flag is specified, "IGNORE_ENUM_MEMBERS", it
can be used for dynamically generated enums to avoid documenting
environment-specific enumeration members. An example is
GstX265EncTune.
This can be used to mark additional types exposed by plugins (i.e.
enums, flags and GObjects) via properties, signals or pad templates as
plugin API. They can then be picked up by the documentation for the
plugin.
Not all types exposed by plugins are documented automatically because
they might come from an external library and should be documented from
there instead.
Nowadays we are only waking up the head entry waiting if either the head
entry is unscheduled (which is handled some lines above already), or
when the head entry specifically is woken up because a new entry became
the new head entry.
We're not waking up *all* entries anymore whenever any entry in the last
was unscheduled.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/500>
We already have a mutex in each clock entry anyway and need to make use
of that mutex in most cases when the status changes. Removal of the
atomic operations and usage of the mutex instead simplifies the code
considerably.
The only downside is that unscheduling a clock entry might block for the
time it needs for the waiting thread to go from checking the status of
the entry to actually waiting, which is not a lot of code.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/500>
Otherwise it can happen that unscheduling a clock id never takes place
and instead it is waiting until the normal timeout. This can happen if
the wait thread checks the status and sets it to busy, then the
unschedule thread sets it to unscheduled and signals the condition
variable, and then the waiting thread starts waiting. As condition
variables don't have a state (unlike Windows event objects), we have to
remember ourselves in a new boolean flag protected by the entry mutex
whether it is currently signalled, and reset this after waiting.
Previously this was not a problem because a file descriptor was written
to for waking up, and the token was left on the file descriptor until
the read from it for waiting.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/500>
This was effectively disabled in 1.0 with the intent of maybe re-enabling it.
The problem is that caching duration at a bin level doesn't make much sense
since there might be queueing/buffering taking place internally and therefore
the duration reported might have no correlation to what is actually being
outputted.
Remove commented code and fixmes, and update documentation
Fixes#4
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/489>
We must not retry fclose() on EINTR as POSIX states:
After the call to fclose(), any use of stream results in undefined
behavior.
We ensure above with fflush() and fsync() that everything is written out
so chances of running into EINTR are very low. Nonetheless assume that
the file can't be safely renamed, we'll just try again on the next
opportunity.
CID #1462697
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/465>
...instead of a file descriptor so buffered I/O is used when writing
the binary cache. This boosts performance at startup, particularly on
network filesystems where writes may be quite slow.
Fixes gstreamer#545.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/458>
For value types that aren't subclassable, just check the type directly.
For flags, compare against the fundamental type directly instead of going through
the more expensive recursive check of `G_TYPE_CHECK_VALUE_TYPE()`
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/453>
The problem is that:
* g_value_init will end up allocating an internal list/array
* g_value_copy *clears* the existing value by calling the free func
and then the copy function (creating it again)
To avoid that alloc/free/alloc cycle, directly call the appropriate
function
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/453>
Previously this was:
* iterating and referencing all plugin features in a GList
* *then* filtering out the ones we want
* Was doing that filtering by name (i.e. `strcmp`) instead of direct pointer
comparision
Instead, just create a private direct function to get the list of plugin
features
Uses 4 times less instructions ...
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/462>
The intersection function table is a legacy of 2005, when one could
register random intersection functions. This is no longer the case.
The only place where that table was used was:
* `gst_value_can_intersect()`, where it was already only used for identical
GType
* `gst_value_intersect()`, where the table iteration was insanely expensive
Instead this patch:
* Only stored intersection functions for *different* types (of which there are
only 4)
* Make gst_value_intersect directly call the same-type intersection functions
and only use the table if ever it doesn't match.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/454>
This was going through a few locks and doing temporarily allocations for every
single task creation.. just to get a name.
We don't need to take locks since:
* The parent exists (we have a reference to it)
* The pad exists (the task belongs to it)
* Changing names of pad/elements when activating is a big no-no
Instead use the existing direct GST_DEBUG_PAD_NAME macro
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/455>
This reverts commit cd751c2de3.
Reverts https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/406
Fixes glviewconvert negotiation in e.g.:
gltestsrc ! glviewconvert output-mode-override=side-by-side ! glstereosplit name=s s.left ! queue ! fakesink s.right ! queue ! glimagesink
Problem here is that intersecting flagsets in gst_value_intersect will
always find a value comparison function but may fail a direct type
comparison due to flagsets supporting derived types. When flagset
derived types are intersected, an intersection will therefore always
fail.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/441>
If this is not done, tools like xdot fail with "unexpected char
b'\\'". This is a regression caused by commit
74938f07c2 (multiqueue: Add stats
property).
The deserialized value coming out of g_object_get_property looks like
this,
$24 = (gchar *) 0x7f560c0046a0 "application/x-gst-multi-queue-stats, queues=(structure)< \\\"queue_0\\\\,\\\\ buffers\\\\=\\\\(uint\\\\)39\\\\,\\\\ bytes\\\\=\\\\(uint\\\\)8
120251\\\\,\\\\ time\\\\=\\\\(guint64\\\\)1460000000\\\\;\\\", \\\"queue_1\\\\,\\\\ buffers\\\\=\\\\(uint\\\\)186\\\\,\\\\ bytes\\\\=\\\\(uint\\\\)838020\\\\,\\\\ time\\\\=\
\\\(guint64\\\\)1984000002\\\\;\\\" >;"
That is immediately looking wrong. I don't know enough about GNOME
serialization details to say with confidence what happened here. It
gets worse after this is sent through g_strescape and then written to
the dot file. Interestingly, dot -Tpng is fine to ignore them it
seems.
Since the stats are by definition verbose, I decided the best choice
to omit them from the dot file, since such details are not of interest
there.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/442>
To allow the refcounting tracer to work better. In childproxy/iterator
these might be plain GObjects but gst_object_unref() also works on them.
In other places where it is never GstObject, g_object_unref() is kept.
There is not point waiting if the time to wait is less than this
platform specific value. The worst case here is GCond usage on windows
where the granularity is 1ms.
Problem:
multiple aggregator elements (audiomixer, compositor) in a live
pipeline use a lot of CPU waiting each other up. This is because
of the previously unused clock entry unscheduling during regular
operation.
Clock entry unscheduling has the potential to wake up every clock entry
waiting using the system clock which may be a large number.
Solution:
Implement waiting per entry and only wakeup the unscheduled entry.
While this may be possible using GCond, theoretically GCond only gives
us microsecond accuracy and uses relative waits in a number of places.
We can unfortunately do better poking at the platform specifics
ourselves by using futexes on linux and pthread on other unix. Windows
may have a possible implementation using Waitable timers but that is
not implemented here and instead falls back to the GCond implementation.
GCond waits on Windows is still as accurate as the previous GstPoll-based
implementation.
When a live pipeline goes to PLAYING, its change_state method
is called twice for PAUSED_TO_PLAYING: the first time is
from GstElement, when NO_PREROLL is returned, the second
is from GstBin, after all async_done messages have been
collected.
base_time selection is done only the first time, through
comparisons with start_time.
On the other hand, when this live pipeline gets flush seeked,
even though start_time is reset by the sink upon reception
of flush_stop(reset_time=TRUE), PAUSED_TO_PLAYING only occurs
once, from GstBin, after all async_done messages have been
collected. This causes the base_time to be off by <latency>.
This commit addresses this by mimicing the behaviour of
GstElement on NO_PREROLL, and calling the change_state
method manually when the following conditions are met:
* The pipeline is live
* The target state is PLAYING
This new API allow resuming a task if it was paused, while leaving it to
stopped stated if it was stopped or not started yet. This new API can be
useful for callback driver workflow, where you basically want to pause and
resume the task when buffers are notified while avoiding the race with a
gst_task_stop() coming from another thread.
The old code would leave a dangling pointer in oldstr_ptr if two threads
attempted to take the same structure into the same location at the same
time:
1. First "oldstr == newstr" check (before the loop) fails.
2. Compare-and-exchange fails, due to a second thread completing the
same gst_structure_take.
3. Second "oldstr == newstr" check (in the loop) succeeds, loop breaks.
4. "oldstr" check succeeds, old structure gets freed.
5. oldstr_ptr now contains a dangling pointer.
This shouldn't happen in code that handles ownership sanely, so check
that we don't try to do this and complain loudly.
Also simplify the function by using a do-while loop, like
gst_mini_object_take.
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/413
When this `_strnlen` internal method was added, strnlen (in glibc)
was not available yet (appeared in 2.10 it was released that same
year).
If available, use the much more optimized strnlen
The type checks at the end of `gst_value_intersect` to call the flagset
intersection are relatively expensive.
If we already know that:
* There was a compare function but it didn't return GST_VALUE_EQUAL
* AND none of the registered intersect functions failed
Then we know they can't intersect and can return early.
Trims ~20% of the instruction calls
For subtracting a list from another, the previous implementation would
do a double subtraction of one from another (which would create temporary
arrays/values which would then be discarded). Instead iterate and do
the comparision directly.
For intersecting a list with another, we can directly iterate both at
once and therefore avoid doing a *full* check of all values of the list
against all other values of the list.
This tries to inline as much as possible array/list and its contents
in order to avoid double allocation/freeing. This also improves the
locality of data.
The internal value is still API/ABI compatible with the *public*
GArray structure. This allows READ-ONLY backwards compatibility with
any external users that assume that the content of a list/array value
is backed by a GArray.
In case the buffer is not writable, the parent (the BufferList) is not
removed before calling func. So if it is changed, the parent (the BufferList)
of the previous buffer should be removed after calling func.
For all the structure creation using valist/varargs we calculate
the number of fields we will need to store. This ensures all callers
will end up with a single allocation.
Instead of having 3 allocations:
* One for GstStructure
* One for GArray
* One for the array *within* GArray
We try to limit this to a single allocation, inlining everything. This
reduces the number of micro-allocations and improves locality of data
access.
Before that commit `{test, }` wouldn't be accepted as an array
because of the trailing coma, the commit fixes that.
At the same time, the code has been refactored to avoid special casing
the first element of the list, making `{,}` or `<,>` valid lists.
We kept the start time around and subtracted it everywhere for "easy of
debugging", but we don't do anything like this anywhere else and it
only complicates the code unnecessarily.
fixate() will return empty caps if it gets empty caps passed and assert
early if any caps are provided as there's no meaningful way of fixating
any caps.
truncate() and simplify() will return the input caps in case of
any/empty caps as before, but slightly optimized and as documented
behaviour.
Also add tests for this and a few other operations behaviour on
empty/any caps.
Seems unnecessary to print the parent name for every
element in the pipeline graph, it's clear from the
graph what the parent element is and it's hard to
imagine a case where this is useful info rather than
just distracting spam. So far this was only done for
pads, but we should just do it for everything.
Previously we would use the object lock only for storing the sync
handler and its user_data in a local variable, then unlock it and only
then call the sync handler. Between unlocking and calling the sync
handler it might be unset and the user_data be freed, causing it to be
called with a freed pointer.
To prevent this add a refcounting wrapper struct around the sync
handler, hold the object lock while retrieving it and increasing the
reference count and only actually free it once the reference count
reaches zero.
As a side-effect we can now also allow to actually replace the sync
handler. Previously it was only allowed to clear it after initially
setting it according to the docs, but the code still allowed to clear it
and then set a different one.
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/issues/506
Keep the ANY caps empty internally when appending and merging
caps/structures. Previously, an ANY caps could end up containing
internal structures, which could be fetched by the user, and gave the
caps a non-zero length.
Also, made sure that `gst_caps_set_features_simple` frees the features
if caps is empty.
Fixed gst_caps_is_strictly_equal() to take into account whether either of
the caps are ANY caps. Previously, two ANY caps could be considered not
strictly equal if one of them still contained some remnant *internal*
structure (this can happen if an ANY caps has emerged from an append or
merge operation). Also, an ANY caps with no remnant internal structures
was considered strictly equal to an EMPTY caps. Similarly, a non-ANY caps
was considered strictly equal to an ANY caps if its remnant internal
structures happened to match.
Also changed gst_caps_is_fixed to take into account that an ANY caps
should not be considered fixed even if it contains a single remnant
internal fixed structure. This affects gst_caps_is_equal(), which uses a
separate method if both caps are fixed. Previously, this meant that a
non-ANY fixed caps was considered equal to an ANY caps if it contained a
single matching remnant internal structure.
Added some tests for these two equality methods, which covers the above
examples, as well as asserts existing behaviour.
Fixes#496
GST_CLOCK_TYPE_TAI is GStreamer abstraction for CLOCK_TAI. Main
motivation for this patch is support for transmission offloading features
- when network packets are timestamped with the time they are deemed to
be actually transmitted. Linux API for that requires that time to be
in CLOCK_TAI coordinate.
With GST_CLOCK_TYPE_TAI, applications can use CLOCK_TAI directly on
their pipelines, avoiding the need to cross timestamp packet times. By
leveraging system's CLOCK_TAI, applications also don't need to keep track
of leap seconds - less burden for them. Just keep system's CLOCK_TAI
accurate and use it.
This would cause us to set GST_GROUP_ID_INVALID as group-id in the
aggregated STREAM_START message if there are no sinks at all or none of
them have a STREAM_START message, which is simply wrong.
If we have not a single STREAM_START message then the bin should not be
considered STREAM_START.
They are optional on STREAM_START messages/events but if available
should have at least a valid value.
For STREAM_GROUP_DONE events don't allow creating it with an invalid
group id as this does not make any sense.
Introducing "GST_PLUGIN_FEATURE_RANK" environment variable in order for users
to adjust rank of plugin(s) via environment.
A "feature" and "rank" key-value pair should be separable by ":",
and each key-value pair is recognized per "," delimiters. The rank
can be a numerical value or one of pre-defined rank values
such as "NONE", "MARGINAL", "SECONDARY", and "PRIMARY" in case-insensitive manner.
In addition to pre-defined { NONE, MARGINAL, SECONDARY, PRIMARY },
"MAX" can be passed to key value used to ensure having a higher rank
than other plugin features.
Example)
- GST_PLUGIN_FEATURE_RANK=qtdemux:256,h264parse:NONE
Set rank of qtdemux plugin to 256 (primary) and 0 (none) for h264parse.
If you're using a custom log handler, you had to reverse-engineer the
debug log format and create your own format function. Now, you can
call `gst_debug_log_get_line()` and it will return a string (without
ANSI escape color codes) representation instead.
This is useful in situations when you need to log the ordinary
gst_debug log to a resource that can't be opened as a `FILE` handle.
Also includes a test.
A common use case of a dynamically built pipeline is that you want to
(conditionally) find a certain element, e.g. the `rtpbin`s in a
`uridecodebin`. If that element has a fixed name inside its parent bin
(and only has a single instance) this can be easily done by
`gst_bin_get_by_name()`.
If there are multiple instances of the element however, you can only use
`gst_bin_iterate_all_by_interface()`, but this doesn't work if you don't
have the specific `GType` (which is often the case, due to plugins being
dynamically loaded). As such, another fallback could be to use the
well-known name of the element's factory (in case of our example, this
is of course `"rtpbin"`).
According to [1] EINTR is a possible errno for fsync(),
so handle it as all other EINTR (do/while(errno == EINTR)).
Signed-off-by: Peter Seiderer <ps.report@gmx.net>
According to [1] EINTR is a possible errno for fsync(),
so handle it as all other EINTR (do/while(errno == EINTR)).
Signed-off-by: Peter Seiderer <ps.report@gmx.net>