There were a few errors:
* The plugin scanner now accepts executable path as an argument.
In case it is NULL, argc == 2
* We find the executable path in init_pre instead of gst_init,
allowing this to work when gst is initialized through the
option group (eg gst-inspect)
* There was a semi-colon missing in the __APPLE__ #ifdef
When a plugin declares a dependency using this flag, all the
relative paths are considered to be relative to the path of
the main executable.
We try to determine the path of the executable portably,
with implementations provided for Linux, Windows and Mac.
If retrieval of the path fails, we will not detect changes.
In order for the main executable path to be the same when
scanning a plugin in a child process, a new variable is
exposed in gst_private.h, _gst_executable_path
https://bugzilla.gnome.org/show_bug.cgi?id=788152
If multiple probes are set on a pad and one probe returns either
GST_PAD_PROBE_HANDLED or GST_PAD_PROBE_DROPPED we need to stop
calling the remaining probes.
https://bugzilla.gnome.org/show_bug.cgi?id=787243
for vararg parameters. Vararg functions are not introspectable anyway,
so might just as well mark them as '(skip)' while we're at it.
gstutils.c:2611: Warning: Gst: invalid "transfer" annotation for <varargs>: only valid for object and GVariant types
Without the former, event changes (e.g. setting a pad offset) does not
take effect for the current buffer but only for the next one. Without
the latter, non-blocking event probes would not see any updated events
yet.
This stores debug logs in memory per thread and uses up to a
configurable amount of bytes per thread for the logs. Inactive threads
are timed out after a configurable amount of time.
https://bugzilla.gnome.org/show_bug.cgi?id=785035
Add back function guard that checks the refcount in a read-only
operation first, and bail out without modifying the passed-in
memory if it's clearly not a valid mini object. Otherwise we
probably cause more harm than good. We keep the second sanity
check based on the 'real refcount' at the time of the unref
around for now too.
https://bugzilla.gnome.org/show_bug.cgi?id=784383
gst_protection_filter_systems_by_available_decryptors() takes an array
of strings and returns a new array of strings filtered by the available
decryptors for them so the ones you get are the ones that you should be
able to decrypt.
https://bugzilla.gnome.org/show_bug.cgi?id=770107
Need to pass -DGST_DISABLE_DEPRECATED to avoid warnings when
testing deprecated API such as gst_uri_construct().
Also remove #ifndef GST_DISABLE_DEPRECATED guard from header
file, we don't use those any more for functions, the
GST_DEPRECATED_FOR macro is enough.
The gst_uri_construct function was escaping the location string
as a generic uri string. This is incorrect since the slash('/')
characters are reserved for use in this exact case. The patch
changes the escape_string function mode to handle the path correctly.
I have deleted the escape_string function since it is no longer being
used and have created a unit test for the function. I have also
deprecated this function in favour of the GstUri API.
https://bugzilla.gnome.org/show_bug.cgi?id=783787
This is something bindings can't handle and it causes leaks. Instead
move the ref_sink() to the explicit, new() constructors.
This means that abstract classes, and anything that can have subclasses,
will have to do ref_sink() in their new() function now. Specifically
this affects GstClock and GstControlSource.
https://bugzilla.gnome.org/show_bug.cgi?id=743062
If a function takes a floating reference parameter, it should also be
sinked in error cases. Otherwise the function behaves differently
between error and normal cases, which is impossible for bindings to
handle.
https://bugzilla.gnome.org/show_bug.cgi?id=747990
If a function takes a floating reference and sinks it, it should also do
that in error cases. I.e. call ref_sink() followed by unref().
Otherwise the reference counting behaviour of the function will be
different between the good and the error case, and simply inconsistent.
https://bugzilla.gnome.org/show_bug.cgi?id=747990
Can't use a #ifndef GST_DISABLE_DEPRECATED guard around deprecated
functions any more, as they won't get exported then. Besides, we
get a nicer error message from the compiler telling us what function
to use instead this way.
This is a meta that generically allows to attach additional reference
timestamps to a buffer, that don't have to relate to the pipeline clock
in any way.
Examples of this could be an NTP timestamp when the media was captured,
a frame counter on the capture side or the (local) UNIX timestamp when
the media was captured.
https://bugzilla.gnome.org/show_bug.cgi?id=779213
This is useful for integration with other event loops that work by
polling file descriptors. G_IO_IN will always be set whenever a message
is available currently.
https://bugzilla.gnome.org/show_bug.cgi?id=776126
This patch changes the entry point of each plugin in order to unify the
interface for static and dynamic plugin. What we do is replace the
current static plugin interface and extend the dymamic one. The plugin
entry was a C structure, name "gst_plugin_desc". With this patch, the
interface is now:
GstPpluginDesc *gst_plugin_<name>_get_desc(void);
The reason we change the C structure into function, is that it is
potentially more common to have function pointers, avoiding possible
binding language limitation. Additionally to that. This change prevents
the symbols from clashing between plugins, allowing to build once the
plugin (assuming you have -fPIC).
On the plugin loader side, we symply derive the shared object basename
to extract the plugin name. If this symbol is not found, we fallback to
gst_plugin_desc for backward compatibility.
This has one side effect, which is that the shared objects now need to
be named after their plugin name. This is generally the case with few
exceptions. The benifit of this limitation is that you can control the
gst_plugin_<name>_desc clash at file level.
https://bugzilla.gnome.org/show_bug.cgi?id=779344
It is possible to use gst_deinit() without registering the base
classes. For example, when using gst_init_get_option_group() and
call the program with an invalid parameter. In that case,
gst_deinit() will lead to a segmentation fault, since there is a
dereference to a pointer that is null.
This patch validates if the type is non-null before dereferencing
it.
https://bugzilla.gnome.org/show_bug.cgi?id=781914
Use g_object_new() instead which nowadays has a shortcut for the
no-properties check. It still does an extra GType check in the
function guard, but there's a pending patch to remove that
and it's hardly going to be a performance issue in practice,
even less so on a system that's compiled without run-time checks.
Alternative would be to move to the new g_object_new_properties()
with a fallback define for older glib versions, but it makes the
code look more unwieldy and doesn't seem worth it.
Fixes deprecation warnings when building against newer GLib versions.
https://bugzilla.gnome.org/show_bug.cgi?id=780903
They were (signed!) gint64 before because of G_GINT64_CONSTANT() already
and they are actually used in signed calculations.
With this change we at least ensure that an integer type of the correct
size is used for GI (it was using gint before).
The issue happens when the structure is printed by the logging
subsystem: the object is included in the log, and this will cause the
full object printout to be done there. However, after dispose, the queue
was already cleared, so the access to it (to print the object) would
assert, as the queue was already freed. The patch changes it so that the
queue is merely empty, and only freed in _finalize.
https://bugzilla.gnome.org/show_bug.cgi?id=776293
A paramspec validation should modify the content to match what the spec
requires and return TURE if a modification happened. This previous
implementation would only fix the first element of the array and return.
It was also return TRUE for empty array, while no modification was
needed.
https://bugzilla.gnome.org/show_bug.cgi?id=780111
The GST_TYPE macro points to global variables initialized by the
first call to get_type. This is not an issue if you call gst_init()
but unfortunatly pygi will need to acces the param type before
init can be called. This removes an assertion.
Those aren't suppose to be called from multiple thread, but all
fundamental get_type() function are thread safe. Fix it to
be consistent and it may help if we change the typing mechanism
in GStreamer come day.
This is to help bindings access properties of type GST_TYPE_ARRAY.
This function will get/set the property and convert form/to
GValueArray.
New API:
gst_util_set_object_array
gst_util_get_object_array
https://bugzilla.gnome.org/show_bug.cgi?id=753754
This adds a binding friendly interface to get and set arrays
and list into GstStructure.
New API:
- gst_structure_set_array
- gst_structure_set_list
- gst_structure_get_array
- gst_structure_get_list
https://bugzilla.gnome.org/show_bug.cgi?id=753754
When registering GstParamSpecArray, use the gst_value_array_get_type()
function to get the type, rather than the GST_TYPE_ARRAY macro, which
gets it from the _gst_value_array_type, which is in turn only
initialised during gst_init()
Fixes criticals with (python) bindings that look up all the
types from the gobject-introspection info as soon as they
are imported.
/usr/lib64/python3.5/site-packages/gi/module.py:178: Warning: g_param_type_register_static: assertion 'g_type_name (pspec_info->value_type) != NULL' failed
g_type = info.get_g_type()
/usr/lib64/python3.5/site-packages/gi/module.py:212: Warning: g_type_get_qdata: assertion 'node != NULL' failed
type_ = g_type.pytype
/usr/lib64/python3.5/site-packages/gi/module.py:226: Warning: g_type_get_qdata: assertion 'node != NULL' failed
g_type.pytype = wrapper
/usr/lib64/python3.5/site-packages/gi/module.py:226: Warning: g_type_set_qdata: assertion 'node != NULL' failed
g_type.pytype = wrapper
If guessing that a string matches a flagset, be more thorough
at checking that the string following a string of hex:hex:
actually looks like a flag set string. Add some unit tests
to catch more cases.
https://bugzilla.gnome.org/show_bug.cgi?id=779755
But only when serializing outside of GstStructures, because in case of
GstStructure the type is already preprended to the array/list and the
GstStructure API makes sure that they have the same "generic" type so
deserialization works properly.
This keeps serialization of GstStructures the same as before, and the
GstCaps unit tests already test for that. However when serializing
standalone arrays/lists get the types added now.
This can easily deadlock if the element uses the object lock for
something internally, like posting an error message. Use an GstIterator
for iterating over the pads instead.
https://bugzilla.gnome.org/show_bug.cgi?id=777449
When registering a new debug category after _debug_init(), we need to
re check the GST_DEBUG filter settings again.
In addition when parsing the filter setting, we need to already bump up
the min-debug level to not suppress debug log statments that dynamically
register a category. This happens in libraries that use a function to
register a category on first use.
A property not defined in a preset file can simply mean that the
user wants it to be set as it default value, and we should not warn
about that.
A missing preset file in a directory can happen has there are several
directory where a preset can be found in.
Saves us a custom script. Template files are nicer than passing
multiline templating stuff through to glib-mkenums. And we can
get rid of our custom python script.
It's a programming error to pass other pads here, and it easily causes
crashes or other problematic behaviour down the road as subclasses
usually assume to only get their pads.
Allows proper usage of structures in structures in caps. Subtraction
is not implemented due to complications with empty fields representing
all possible values.
The only implementation that doesn't delegate to the already existing
GstStructure functions is the union function.
https://bugzilla.gnome.org/show_bug.cgi?id=775796
After b76ecfd992 introduced
GST_PAD_FLAG_ACCEPT_TEMPLATE, the performance penalty this
message is refering to (the cascading ACCEPT_CAPS query)
only applies to the cases where !GST_PAD_IS_ACCEPT_TEMPLATE
This is an API break but that API has not been released yet.
We are passing a flag rather than a simple boolean as we can imagine
to implement more features in the future for example to retrieve a
stack trace for all the threads, etc..
Retrieving source file and line numbers is pretty
expensive while getting a stack trace, this new argument
allows the user to decide to retrieve a backtrace
without those infos instead which is much faster.
For example running $ GST_LEAKS_TRACER_STACK_TRACE=1 GST_DEBUG=GST_TRACER:7 \
GST_TRACERS=leaks time gst-launch-1.0 videotestsrc num-buffers=1 ! fakesink:
* With simple stack traces:
0.04s user 0.02s system 99% cpu 0.060 total
* With full stack traces:
0.66s user 0.23s system 96% cpu 0.926 total
https://bugzilla.gnome.org/show_bug.cgi?id=775423
As an usecase of URI fragment, it can indicate temporal or spatial
dimension of a media stream. To easily parse key-value pair,
newly added gst_uri_get_media_fragment_table () API will provide
the table of key-value pair likewise URI query.
See also https://www.w3.org/TR/media-frags/https://bugzilla.gnome.org/show_bug.cgi?id=774830
We were creating a new session to retrive each line of a stack trace
and we are supposed to start it once for a whole stack trace.
And pass the whole file to gst-indent.
https://bugzilla.gnome.org/show_bug.cgi?id=775365
This structure is always allocated by GStreamer, can't be
subclassed or extended, and is never allocated or used on
the stack, so we don't need any padding and can extend it
as we please.
When requesting a pad from a template and it's already linked, this
means it was a static pad. Since we only want to return an *available*
pad, we must return NULL ... but we must also remove the reference
we got from getting that static pad.
The "No need to unref" message (which wasn't true for quite some time)
dates back from the very very very first commit introducing the 0.10
features.
The caller might pass arbitrary data here that caused the error, and
trying to set invalid UTF-8 in a GstStructure causes it to be not set at
all. Later when trying to parse it, the field will not exist and the
return value will point to invalid memory. Prevent this by storing NULL
instead.
Also print a g_warning(), the caller should never ever do this to begin
with.
Add unit test to ensure that.
It can be a normal execution path to do some map trials and there is
no need to worry the user in that case.
The application has to check the return value of gst_memory_map.
https://bugzilla.gnome.org/show_bug.cgi?id=765600
To make sure the value is only expanded/used once, in case
there are side effects to it, and to avoid calculating it
or looking it up multiple times if there is a calculation
or lookup involved.
MSVC warns on this and the documentation about the warning says:
> The compiler assumes the function returns a value of type int
which is a little scary, so lets just remove the unnecessary 'return'
https://bugzilla.gnome.org/show_bug.cgi?id=774293
gstpoll.c: In function 'release_event':
gstpoll.c:239:3: error: suggest parentheses around assignment used as
truth value [-Werror=parentheses]
if (status = WaitForSingleObject (set->wakeup_event, INFINITE)) {
^~
https://bugzilla.gnome.org/show_bug.cgi?id=774108
Introduce a new operator ':' - e.g. element1 ':' element2
For example, 'uridecodebin : encodebin' -
if the encodebin has multiple profiles compatible with the
decodebin, multiple links will be created.
With '!' , after one delayed link is successfully done, the
pad-added callback is disconnected.
https://bugzilla.gnome.org/show_bug.cgi?id=751450
Implement GstDynamicTypeFactory as a new registry feature.
GstDynamicTypeFactory provides a way of registering a GType
into the registry, such that it will be registered as a dynamic
type when the registry is loaded, and then automatically loaded
if the type is needed during caps parsing.
This allows using non-core types in pad templates, by loading a
registry feature to create the GType on the fly.
https://bugzilla.gnome.org/show_bug.cgi?id=750079
It's useful to be able to set a name pattern for GST_DEBUG_FILE so that
the same environment variable can be used for multiple processes and
still write to different files. Especially useful if these processes
run simultaneously.
%p: Replaced with PID
%r: Replaced with random number
%p is obviously useful. %r is useful when for instance running two
processes with same PID but in different containers.
https://bugzilla.gnome.org/show_bug.cgi?id=773092
Enable it to prevent sending reconfigure when linking elements.
Useful for autoplugging when we know caps or bufferpools shouldn't change
to save doing caps renegotiation to end up with the same final scenario.
The no-reconfigure is not a proper check, it is a flag. It is implemented
as a GstPadLinkCheck to avoid creating another gst_pad_link variant.
https://bugzilla.gnome.org/show_bug.cgi?id=757653
Fixes xgettext warnings when doing 'make update-po':
gst/parse/grammar.y:217: warning: Empty msgid. It is reserved by GNU gettext:
gettext("") returns the header entry with
meta information, not the empty string.
This flag is to indicate to child elements that they can add and
remove pads at any point in time without re-adding existing ones.
Elements should post before-hand a GST_MESSAGE_STREAM_COLLECTION
https://bugzilla.gnome.org/show_bug.cgi?id=772741
When we get GST_ITERATOR_RESYNC, we need to call gst_iterator_resync()
otherwise we will always get GST_ITERATOR_RESYNC (and that loop would
run forever).
gst/gstprintf unit test would fail on 32-bit x86 with:
gstprintf.c:83:printf_I32_I64:0: 'str' (64-bit x value = b5a6978f) is not equal to '"64-bit x value = f1e2d3c4b5a6978f"'
This reverts commit cfc565e2d8.
The commit was redundant since gst_gen_sources already contains
gstenum_h. We're still investigating why some people are still seeing
a racy build failure.
This forces gstenumtypes.h to be built whenever something uses gst_dep
as a subproject dependency. This is needed since gst/gst.h includes
gstenumtypes.h
Closes https://github.com/mesonbuild/meson/issues/714 which is not
actually a Meson bug.
Earlier we were only using __declspec(dllexport/import) when we were
built with MSVC because when built with MinGW and linking with MinGW we
don't need it (and we get linker errors because of it).
However, when we're built with MinGW and someone wants to link to us
with MSVC, we still need the prototypes to have __declspec(dllimport)
since MSVC cannot do auto-import like GCC can.
https://bugzilla.gnome.org/show_bug.cgi?id=771029
When using seek_simple() in combination with other kinds of seeks, this
becomes problematic. seek_simple() does not reset the stop position to
GST_CLOCK_TIME_NONE but keeps whatever a previous seek did. So for example
when doing a seek_simple() after a rate=-1 seek, we would usually get
assertions that start>stop (and stop being the old stop from the rate=1 seek).
https://bugzilla.gnome.org/show_bug.cgi?id=771104
In many parts of the code we raise streaming error when the flow
goes wrong, and each time we create more or less similare error
message. Also that message does not let the application know what
has actually gone wrong. In the new API we add a "flow-return" detail
field inside the GstMessage so that the application has all the information
if it needs it.
API:
GST_ELEMENT_FLOW_ERROR
https://bugzilla.gnome.org/show_bug.cgi?id=770158
We only use GST_EXPORT consistently when building with MSVC by using the
visual studio definitions files (win32/common/*.def), so always disable
it when building with Autotools and only enable it with Meson when
building with MSVC.
This allows you to use MinGW to link to a GStreamer built with MSVC and
get the correct function prototypes to find functions and variables in
DLLs.
Fixes g-i warning "Gst: Constructor return type mismatch
symbol='gst_element_message_new_details' constructed='Gst.Element'
return='Gst.Structure'".
This is a newly-added function in git that has not been in a stable
release yet, so it's fine to rename it. It's also only used indirectly
via macros.
https://github.com/mesonbuild/meson
With contributions from:
Tim-Philipp Müller <tim@centricular.com>
Mathieu Duponchelle <mathieu.duponchelle@opencreed.com>
Jussi Pakkanen <jpakkane@gmail.com> (original port)
Highlights of the features provided are:
* Faster builds on Linux (~40-50% faster)
* The ability to build with MSVC on Windows
* Generate Visual Studio project files
* Generate XCode project files
* Much faster builds on Windows (on-par with Linux)
* Seriously fast configure and building on embedded
... and many more. For more details see:
http://blog.nirbheek.in/2016/05/gstreamer-and-meson-new-hope.htmlhttp://blog.nirbheek.in/2016/07/building-and-developing-gstreamer-using.html
Building with Meson should work on both Linux and Windows, but may
need a few more tweaks on other operating systems.
This makes gstconfig.h completely arch-independent. Should cover all
compilers that gstreamer is known to build on, and all architectures
that I could find information on. People are encouraged to file bugs if
their platform/arch is missing.
A new event which precedes EOS in situations where we
need downstream to unblock any pads waiting on a stream
before we can send EOS. E.g, decodebin draining a chain
so it can switch pads.
https://bugzilla.gnome.org/show_bug.cgi?id=768995
Redirection messages are already used in fragmented sources and in
uridecodebin, so it makes sense to introduce these as an official message
type.
https://bugzilla.gnome.org/show_bug.cgi?id=631673
In some corner cases, the error 'code' part passed to
GST_ELEMENT_ERROR() is a valid define as well, in which
case it won't survive two levels of macro expansion, but
only one. Fixes:
oss4-sink.c: In function ‘gst_oss4_sink_open’:
error: ‘GST_RESOURCE_ERROR_0x00000002’ undeclared (first use in this function)
GST_ ## domain ## _ERROR_ ## code, __txt, __dbg, __FILE__,
which is from GST_ELEMENT_ERROR(el,RESOURCE,OPEN_WRITE,..)
and OPEN_WRITE happens to be defined to 2 here.
https://bugzilla.gnome.org/show_bug.cgi?id=756806https://bugzilla.gnome.org/show_bug.cgi?id=769117
gst_structure_id_get() returns a new reference so the returned object is
actually (transfer full).
The unit tests was already unreffing the objects.
https://bugzilla.gnome.org/show_bug.cgi?id=768776
gst_structure_id_get() returns a new reference so the returned device is
actually (transfer full).
The code using this API was already correct but the code example in
comments was not.
https://bugzilla.gnome.org/show_bug.cgi?id=768776
We don't free this from gst_deinit() but from gst_task_cleanup_all(),
so more GStreamer API may be called. In particular makes unit tests
work again with CK_FORK=no.
https://bugzilla.gnome.org/show_bug.cgi?id=768577
This ensures that all async operations (started from gst_element_call_async())
have been completed and so there is no extra thread running.
Fix races when checking for leaks on unit tests as some of those
operations were still running when the leaks tracer was checking for
leaked objects.
https://bugzilla.gnome.org/show_bug.cgi?id=768577
gcc 6 has problems detecting and avoiding throwing
a warning for tautological compares in macros (they
should only trigger for compares outside macros).
Avoid them with a nasty cast of one parameter to void *
https://bugzilla.gnome.org/show_bug.cgi?id=764526
Especially if multiple threads are waiting for buffers to be available again,
the current code was wrong. Fix this and document clearly how the GstPoll is
supposed to be used.
Also fix some potential races with reading from the GstPoll before writing
actually happened.
https://bugzilla.gnome.org/show_bug.cgi?id=767979
It might happen that we popped the message before writing of the control
happened. In this case we just have to retry again a bit later, and failure to
do so will cause an additional byte in the control and the GSource /
gst_poll_wait() to always wake up again immediately.
https://bugzilla.gnome.org/show_bug.cgi?id=750397
And also mention what the expected values of errno are going to be.
write_control() will only ever return FALSE if there was a critical error. It
will never return because of EINTR, EAGAIN or EWOULDBLOCK.
read_control() will return FALSE if there was no byte to read, in which case
errno would be EWOULDBLOCK.
In all other cases there was a critical error.
https://bugzilla.gnome.org/show_bug.cgi?id=750397
On timer GstPolls it will cause the control socket state to become
inconsistent as now one less read_control() than write_control() be would
needed.
Similarly, read_control() and write_control() are only valid on timer
GstPolls.
https://bugzilla.gnome.org/show_bug.cgi?id=750397
This might fail even under correct usage, e.g. if read_control() is called
from another thread before write_control() finished in another. It has to be
retried then, or other measures have to be taken, depending on how it is used
by the surrounding code.
https://bugzilla.gnome.org/show_bug.cgi?id=750397
This addresses slightly different race conditions on Linux and Windows, and
fixes gst_poll_read_control() when control_pending == 0.
On Linux, the socketpair() used for control should not be made O_NONBLOCK.
If there's any propagation delay between set->control_write_fd.fd and
set->control_read_fd.fd, even the mutex now held will not be sufficient to
prevent a race condition. There's no benefit to using O_NONBLOCK, here.
Only liabilities.
For Windows, it's necessary to fix the race condition between testing
set->control_pending and performing WAKE_EVENT()/RELEASE_EVENT(). This is
accomplished by acquiring and holding set->lock, for both of these operations.
We could optimize the Linux version by making this Windows-specific.
For consistency with the Linux implementation, Windows' RELEASE_EVENT()
has also been made to block, although it should never happen.
Also, changed release_wakeup() to return TRUE and decrement control_pending
only when > 0. Furthermore, RELEASE_EVENT() is called only when
control_pending == 1.
Finally, changed control_pending to use normal, non-atomic arithmetic
operations, since it's now protected by set->lock.
Note: even though the underlying signaling mechanisms are blocking,
release_wakeup() is effectively non-blocking, as it will only attempt to read
from control_read_fd.fd after a byte has been written to control_write_fd.fd
or WaitForSingleObject() after it's been signaled.
https://bugzilla.gnome.org/show_bug.cgi?id=750397
GCC emits an error for this with -Werror:
plugin.c:22:1: error: 'gst_plugin_desc' initialized and declared 'extern' [-Werror]
This matches how glib does symbol exporting.
https://bugzilla.gnome.org/show_bug.cgi?id=767463
If the prototypes in the public API have dllimport in them when building
statically on Windows, the compiler will look for symbols with symbol
mangling and indirection corresponding to a DLL. This will cause a build
failure when trying to link tests/examples/etc.
External users of GStreamer also need to define -DGST_STATIC_COMPILATION
if they want to link to static gstreamer libraries on Windows.
A similar version of this patch has been committed to all gstreamer
repositories.
https://bugzilla.gnome.org/show_bug.cgi?id=767463
We already had a _full() version, but having that alone seems inconsistent.
Add a non-full version that mirrors the behaviour of gst_pad_link() vs
gst_pad_link_full().