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>
Without this it is possible that we have a GSource with reference count
0 stored in the GstBus that is currently in the process of being
destroyed. gst_bus_remove_watch() might then access it, increase its
reference count to 1 again, call GSource API on it and then unref it,
which will then finalize it a second time.
The dispose function allows the GSource to be resurrected until it
returned so the above would be safe now.
This caused some spurious crashes during shutdown in various
applications.
It fixes below gir warnings.
../subprojects/gstreamer/gst/gstevent.c:2246: Warning: Gst:
gst_event_new_instant_rate_sync_time: unknown parameter
'rate_multiplier' in documentation comment, should be 'rate'
../subprojects/gstreamer/gst/gstevent.c:2296: Warning: Gst:
gst_event_parse_instant_rate_sync_time: unknown parameter
'rate_multiplier' in documentation comment, should be 'rate'
After release bison 2.5 the declaration %pure-parser was deprecated
in favor of %define api.pure
Nonetheless, until bison 3.4, the declaration was treated as backward
compatibility, but now bison shows a warning:
warning: deprecated directive, use ‘%define api.pure’
The patch's approach is to handle both directives according with the
used bison's version, by string replacement at source configuration
stage.
When playing gapless there were situations when some sticky events
like tags were stuck at some pad and then revived much later.
Therefore it is better to clear them upon stream-start.
Fixes#360
A seek with that flag set must be non-flushing, not change the playback
direction and start/stop position. A seek handler will then send the new
GST_EVENT_INSTANT_RATE_CHANGE event downstream for downstream elements
to immediately apply the new playback rate before the new in-band segment
event arrives.
The argument must be at least a GObject according to the GstLogFunction
definition, and while the default C log function handles miniobjects
just fine this is crashing bindings and user-supplied log functions that
(rightfully) don't expect anything but GObjects.
Not posting DEVICE_ADDED messages while a device provider is being
started makes things awkward for applications, as they have to call
get_devices() after starting the monitor.
This requires redundant code on the application side, and as far as
I understand also could cause race conditions, when a device gets
added between the calls to gst_device_monitor_start() and
gst_device_monitor_get_devices(), causing the application to "see"
the same device twice.
By passing NULL to `g_signal_new` instead of a marshaller, GLib will
actually internally optimize the signal (if the marshaller is available
in GLib itself) by also setting the valist marshaller. This makes the
signal emission a bit more performant than the regular marshalling,
which still needs to box into `GValue` and call libffi in case of a
generic marshaller.
Note that for custom marshallers, one would use
`g_signal_set_va_marshaller()` with the valist marshaller instead.
gst_pad_iterate_internal_links is usually used to find a single internal
link that a pad has, e.g. to find the corresponding pad of a multiqueue.
Added a helper function that will return either a single internal link,
if there's no other, or NULL.
In cases with many long-lived buffers that have qdata only very
briefly, the memory overhead of keeping an array of 16 GstQData
structs for each buffer can be significant. We free the array when
the last qdata is removed, like it was done in 1.14.
Fixes#436
This patch simply add a null check around a case where a child may have
been unparented concurrently to the deep_add_remove operation. This was
found by accident in the form of an "IS_GST_OBJECT" assertion, but had
no other known side effect in that test.
`g_object_notify()` actually takes a global lock to look up the
`GParamSpec` that corresponds to the given property name. It's not a
huge performance hit, but it's easily avoidable by using the
`_by_pspec()` variant.
On Windows, concurrent colored gstreamr debug output and usual
stdout/stderr string will cause broken output on terminal.
Since it's OS specific behavior, that's hard to completely avoid it
but we can protect it at least among our printing interfaces side.
For buffers with multiple memory chunks, gst_buffer_map() has the side
effect of merging the memory chunks into one contiguous
chunk. Since gst_util_dump_mem() used gst_buffer_map() the internals
of the buffer could actually change as a result of printing it.
For the case of a buffer containing several memory chunks,
gst_memory_map() is now used to obtain the memory address and each
memory chunk is dumped separately preceded by a header line. The
behaviour for a buffer containing a single memory chunk is left unchanged.
This was added in 1.16 and accidentally duplicated the value of
the existing GST_MESSAGE_REDIRECT.
As the only known user of this message is GStreamer core itself,
and it is quite an obscure message, it seems best to just fix up
the enum value even if that technically breaks API.
Fixes#418
gst_ring_buffer_logger_log calls several functions while formatting
the message which may in turn log a message while we already hold
the mutex. Do all formatting first before acquiring the mutex to
avoid this and reduce the time we hold the mutex.
And change it to do nothing at all.
As debug categories don't use reference counting and they can be
retrieved from anywhere at any time by name, it is fundamentally unsafe
to free them at any point in time except for right before the end of the
process.
No code apart from a unit test seems to be currently using the function,
so deprecate it and also change it to do nothing at all.
This will be useful in the next commit where we add action-signals on
the leaks tracer to get information about leaks and to manipulate
checkpoints as a replacement for the SIGUSR1 and SIGUSR2 signals for
doing the same.
The offset in gst_buffer_resize() is additive. So to move back the
offset to zero, we need to pass the opposite of the current offset. This
was raised through the related unit test failingon 32bit as on 64bit
the alignment padding was enough to hide the issue. The test was
modified to also fail on 64bit. This patch will remove spurious
assertions like:
assertion 'bufmax >= bufoffs + offset + size' failed
Fixes#316
It's not really possible for us to recover when someone uses the
gst_tracer_record_new() API incorrectly. Also, document a piece of
somewhat-obscure code.
Ensure that the code paths for HAVE_UNWIND and HAVE_DBGHELP are never
taken at the same time, even if the build file code changes.
Prefer DbgHelp over libunwind on Windows in case both are somehow
available because DbgHelp is only available when building with the
MSVC toolchain, and libunwind won't give us debug symbols from objects
built with the MSVC toolchain.
Also, print slightly more useful messages for the level of stack trace
support enabled, and document what each if conditional does.
The code implicitly uses this value when the stack trace is not FULL.
Mostly useful for documenting the behaviour when each flag is passed
and for translating to/from strings.
When using GStreamer with Universal Windows Platform apps, dynamic
plugins can only be loaded by filename (without a path) using
gst_plugin_load_file() which will call into g_module_open().
On Windows, GModule calls LoadLibrary() on the filename, but with
UWP we need to use LoadPackagedLibrary() which is basically the same
as LoadLibrary(), except it looks only for DLLs (by name) that have
been packaged as assets with the app.
These assets are not files and cannot be accessed using normal file
APIs such as open() or stat().
The upstream glib merge request for adding LoadPackagedLibrary support
is: https://gitlab.gnome.org/GNOME/glib/merge_requests/951
NOTE: Whitespcae removal is to make gst-indent happy
Since we started depending on GLib 2.44, we can be sure this macro is
defined (it will be a no-op on compilers that don't support it). For
plugins we should just start using `G_DECLARE_FINAL_TYPE` which means
we no longer need the macro there, but for most types in core we don't
want to break ABI, which means it's better to just keep it like it is
(and use the `#ifdef` instead).
Before GST_PAD_PROBE_HANDLED was introduced, we had to handle the case
where some probes would reset the probe info data field to NULL. This would
be considered an invalid use-case.
But with GST_PAD_PROBE_HANDLED it is totally fine to reset that, since
the probe has "handled" it.
* Making sure that `static inline` function are in the GIR (by first
defining them, and make sure to mark as skiped)
* Do not try to link to unexisting symbols
* Also generate GIR information about gst_tracers
Instead of the object value, this should be used every time a random
value will be returned by g_object_get This is also useful to make the
values returned by inspecting element stable accross runs.
And add strduped function pointer names to the global quark
table, so that they don't get reported as lost by valgrind.
This allows us to use GST_DEBUG when running tests under
valgrind.
Creating seek events segfaults on 32-bit ARM since commit 2fa15d5371
('event: add new seek parameter, "trickmode-interval"'), which missed
casting the trickmode-interval initializer in the variable argument list
to guint64.
Otherwise we'll get an assertion if the object behind the weak pointer
was already destroyed in the meantime as we would pass NULL as first
argument to g_object_remove_weak_pointer().
When performing a key unit trickmode seek, it may be useful to
specify a minimum interval between the output frames, either
in very high rate cases, or as a protection against streams
that may contain an overly large amount of key frames.
One use case is ONVIF Section 6.5.3:
<https://www.onvif.org/specs/stream/ONVIF-Streaming-Spec.pdf>
There is a deadlock if any thread from the pool tries to push
a new task while other thread is waiting for the pool of threads
to finish. With this patch the thread will get an error when it
tries to add a new task while the taskpool is being cleaned up.
MSVC also defines it as a keyword. Fixes build errors in projects that
include MSVC's xkeycheck.h which ensures that keywords aren't overriden
with a define.
Between getting the GSource with the mutex and destroying it, something
else might've destroyed it already and we would have a dangling pointer.
Keep an additional reference just in case.
Signal watches are reference counted and gst_bus_remove_watch() would
immediately remove it, breaking the reference counting. Only
gst_bus_remove_signal_watch() should be used for removing signal
watches.
For metas where order might be significant if multiple metas are
attached to the same buffer, so store a sequence number with the
meta when adding it to the buffer. This allows users of the meta
to make sure metas are processed in the right order.
We need a 64-bit integer for the sequence number here in the API,
a 32-bit one might overflow too easily with high packet/buffer
rates. We could do it rtp-seqnum style of course, but that's a
bit of a pain.
We could also make it so that gst_buffer_add_meta() just keeps metas in
order or rely on the order we add the metas in, but that seems too
fragile overall, when buffers (incl. metas) get merged or split.
Also add a compare function for easier sorting.
We store the seqnum in the MetaItem struct here and not in the
GstMeta struct since there's no padding in the GstMeta struct.
We could add a private struct to GstMeta before the start of
GstMeta, but that's what MetaItem effectively is implementation-
wise. We can still change this later if we want, since it's all
private.
Fixes#262
Thi introduces new APIs to post a `DEVICE_CHANGED` message on the
bus so the application is notifies when a device is modified. For
example, if the "defaultness" of a device was changed or any property
that can be changed at any time. Atomically changing the device
object notifying that way allow us to abtract away the internal threads.
New APIS:
- gst_message_new_device_changed
- gst_message_parse_device_changed
- gst_device_provider_device_changed
The hook->hook_id is a gulong for which there are no portability issues
when tracing in printf format with %lu. So use %lu and remove the upcast
to 64 bit. This makes the code more consistent with everything else
tracing that hook_id and other gulong id.
This was added in 7fdb15d6a2 but it is wrong. (scope call) is for
closures that only have to stay valid for the scope of the call, but the
tag merge function has to stay valid for the whole lifetime of the
application instead.
There's no appropriate scope annotation for that so we have to skip
these functions for now.
GstDeviceProvider has a started_count private variable counter,
and the gst_device_provider_start() documentation emphasizes the
importance of balancing the start and stop calls.
However, when starting a provider that is already started, the
current code will never increment the counter more than once.
So you start it twice, but it will have start_count 1, which is the
maximum value it will ever see.
Then when you stop it twice, on the 2nd stop, after decrementing the
counter in gst_device_provider_stop():
else if (provider->priv->started_count < 1) {
g_critical
("Trying to stop a GstDeviceProvider %s which is already stopped",
GST_OBJECT_NAME (provider));
and the program is killed.
Fix this by incrementing the counter when starting a device provider that
was already started.
This is racy if the state lock of the parent bin is not taken. The
parent bin might've just checked the flag in another thread and as the
next step proceed to change the child element's state.
We need to take the state lock here to ensure that we're
not currently just before setting the state of this child
element. Otherwise it can happen that we removed the element
here and e.g. set it to NULL state, and shortly afterwards
have another thread set it to a higher state again as part of
a state change for the whole bin.
When adding an element to the bin this is not needed as we
require callers to always ensure after adding to the bin that
the new element is set to the correct state.
There was a dead assignment used outside of the bin/pipeline creation
which was confusing (and unused). Just move that variable to
where it is actually used.
(Note that that variable was not needed outside of that block since
the refactoring done in 2b33d33185 )
Fix corruption of meta list head when removing metas at the beginning
during iteration. Linked list handling in gst_buffer_foreach_meta
failed to track the previous entry and update the correct next pointer
when removing items from beyond the head of the list, resulting in
arbitrary list pointer corruption.
Closes#332
Currently in Python it would become a signed 64 bit value but should
actually be an unsigned 32 bit value with all bits set.
This is the same problem as with GST_MESSAGE_TYPE_ANY.
See https://bugzilla.gnome.org/show_bug.cgi?id=732633
We won't be able to do ASSERT_CRITICAL, but the main body of the tests
are still valid, and given we ship GStreamer with this configuration, it
is important to be able to run some tests against it.
Allows determining from downstream what the expected bitrate of a stream
may be which is useful in queue2 for setting time based limits when
upstream does not provide timing information.
Implement bitrate query handling in queue2
https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/issues/60
A pointer to a hook in this list can easily not be unique, given both
the slice-allocator reusing memory, and the OS re-using freed blocks
in malloc.
By doing many repeated add and remove of probes, this becomes very easily
reproduced.
Instead use hook_id, which *is* unique for a added GHook.
This is based on g_clear_object(). Basically, you can use this instead
of using gst_mini_object_unref (which needs to be preceded by a NULL-check).
Also fixes#275
If a segment has stop == -1, then gst_segment_to_running_time()
would refuse to calculate a running time for negative rates,
but gst_segment_do_seek() allows this scenario and uses a
valid duration for calculations.
Make the 2 functions consistent by using any configured duration
to calculate a running time too in that case.
https://bugzilla.gnome.org/show_bug.cgi?id=796559
GST_TIME_FORMAT, GST_TIME_ARGS, GST_STIME_FORMAT, GST_STIME_ARGS
GST_PTR_FORMAT, GST_SEGMENT_FORMAT, GST_FOURCC_FORMAT and
GST_FOURCC_ARGS are format specifiers.
They can't be used outside of C and should be generated in the gir.
https://bugzilla.gnome.org/show_bug.cgi?id=797320
The Harware factory type classifier allows elements (decoders and encoders,
mostly) to advertize they rely on hardware devices to perform encoding or
decoding operations. This classifier can be used by applications to filter and
select only the elements that use hardware devices, for instance to ensure
zero-copy support is enabled for a specific pipeline.
https://bugzilla.gnome.org/show_bug.cgi?id=796921
In some cases the system protection ID is not present in the contents
or in their metadata.
This define is used to set the value of the "system_id" field in GstProtectionEvent,
with this value, the application will use an external information to choose which
protection system to use.
Example: The matroskademux uses this value in the case of encrypted WebM,
the application will choose the appropriate protection system based on the information
received through EME API.
https://bugzilla.gnome.org/show_bug.cgi?id=797231
The documentation incorrectly used to state that the pads were
not automatically activated when added, whereas we actually do
that when appropriate.
Callers of gst_element_add_pad must not hold the object lock,
which implies that they cannot perform the same checks as
add_pad in a non-racy manner.
This updates the documentation, and removes the g_warning
that was output before performing automatic activation.
https://bugzilla.gnome.org/show_bug.cgi?id=797181
Add new GST_API_EXPORT in config.h and use that for GST_*_API
decorators instead of GST_EXPORT.
The right export define depends on the toolchain and whether
we're using -fvisibility=hidden or not, so it's better to set it
to the right thing directly than hard-coding a compiler whitelist
in the public header.
We put the export define into config.h instead of passing it via the
command line to the compiler because it might contain spaces and brackets
and in the autotools scenario we'd have to pass that through multiple
layers of plumbing and Makefile/shell escaping and we're just not going
to be *that* lucky.
The export define is only used if we're compiling our lib, not by external
users of the lib headers, so it's not a problem to put it into config.h
Also, this means all .c files of libs need to include config.h
to get the export marker defined, so fix up a few that didn't
include config.h.
This commit depends on a common submodule commit that makes gst-glib-gen.mak
add an #include "config.h" to generated enum/marshal .c files for the
autotools build.
https://bugzilla.gnome.org/show_bug.cgi?id=797185
For each lib we build export its own API in headers when we're
building it, otherwise import the API from the headers.
This fixes linker warnings on Windows when building with MSVC.
The problem was that we had defined all GST_*_API decorators
unconditionally to GST_EXPORT. This was intentional and only
supposed to be temporary, but caused linker warnings because
we tell the linker that we want to export all symbols even
those from externall DLLs, and when the linker notices that
they were in external DLLS and not present locally it warns.
What we need to do when building each library is: export
the library's own symbols and import all other symbols. To
this end we define e.g. BUILDING_GST_FOO and then we define
the GST_FOO_API decorator either to export or to import
symbols depending on whether BUILDING_GST_FOO is set or not.
That way external users of each library API automatically
get the import.
https://bugzilla.gnome.org/show_bug.cgi?id=797185