This makes sure that the element is in the same state before start() is called
the very first time and every future call after the element was used already.
Also it ensure that we always have a clean state before start(), cleaned the
same way in every case.
The stop() vfunc might mess with some of our fields we have just
reset, which could cause memory leaks or invalid state taken over
to later.
Also the stop() vfunc, or anything called until it from another thread,
might want to be able to use the fields that were just resetted and
become confused because of that.
In the decoder we already had a workaround for things like this happening,
this workaround is not needed anymore.
Allows subclasses to do custom caps query replies.
Also exposes the standard caps query handler so subclasses can just
extend on top of it instead of reimplementing the caps query proxying.
https://bugzilla.gnome.org/show_bug.cgi?id=741263
With the new caps query results the caps returned might have extra fields
that are not required by the decoder (framerate for image decoders) and it
causes a regression making, for example, jpegdec reject caps that don't
have framerates.
The accept-caps implementation will do 2 checks:
1) Do subset check with the template caps, making sure all the required
fields that are present on the template are present on the received caps.
2) Do a intersection check with the result of a caps query, making sure
that downstream can accept the fields in the received caps.
https://bugzilla.gnome.org/show_bug.cgi?id=741263
Refactor the encoder's caps query proxying function to a common place
and use it in the videodecoder to proxy downstream restrictions.
The new function is private to the gstvideo lib.
https://bugzilla.gnome.org/show_bug.cgi?id=741263
Reset last_timestamp_out when applying the output segment
change, to avoid decoder confusion over new timestamp timelines when
a seamless segment change happens.
Move some locks/unlocks to later when they're actually needed.
https://bugzilla.gnome.org/show_bug.cgi?id=734617
This fixes the reverse playback scenario when upstream is not fully
parsing the stream and does not send every keyframe chain separately
with the DISCONT flag on the keyframe.
To explain this, let's suppose we have this stream:
0 1 2 3 4 5 6 7 8
K K K
In most circumstances, the upstream parser will chain in the
decoder the buffers in the following order:
6 7 8 3 4 5 0 1 2
D D D
In this case, GstVideoDecoder will flush the parse queue every time
it receives discont (D) and we will eventually get in the output queue:
(flush here) 8 7 6 (flush here) 5 4 3 (flush here) 2 1 0
In case the upstream parser doesn't do this work, though,
GstVideoDecoder will receive the whole stream at once and will flush
the parse queue afterwards:
0 1 2 3 4 5 6 7 8
D
During the flush, it will look backwards for keyframes and will
decode in this order:
6 7 8 3 4 5 0 1 2
This is the same order that it would receive from upstream if
upstream was parsing and looking for the keyframes, only that now
there is no flushing of the output queue in between keyframes,
which will result in the output queue looking like this:
2 1 0 6 5 3 8 7 6
This will confuse downstream obviously and will play incorrectly.
This patch forces the decoder to flush the output queue every time
it picks a new keyframe to decode, so it will end up decoding 6 7 8
and then flushing before picking 3 for decoding, so the output will
get 8 7 6 before 6 5 3 and the video will play back correctly.
https://bugzilla.gnome.org/show_bug.cgi?id=734441
Fix gst_video_decoder_parse_available() to really parse any pending
source data that is still available in the adapter. This is a memory
optimization to avoid expansion of video packed added to the adapter,
but also a fix to EOS condition when the subclass parse() function
ultimately only needed to call into gvd_have_frame() and no additional
source bytes were consumed, i.e. gvd_add_to_frame() is not called.
This situation can occur when decoding H.264 streams in byte-stream/nal
mode for instance. A decoder always requires the next NAL unit to be
parsed so that to determine picture boundaries. When a new picture is
found, no byte is consumed (i.e. gvd_add_to_frame() is not called)
but gvd_have_frame() is called (i.e. priv->current_frame is gone).
Also make sure to avoid infinite loops caused by incorrect subclass
parse() implementations. This can occur when no byte gets consumed
and no appropriate indication (GST_VIDEO_DECODER_FLOW_NEED_DATA) is
returned.
https://bugzilla.gnome.org/show_bug.cgi?id=731974
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
Buffer pool set_config() may return FALSE if requested configuration needed small
changes. Reget the config and try setting it again. This ensure we have a configured
pool if possible.
Videodecoder does late renegotiation, it will wait for the next
buffer before renegotiating its caps and bufferpool. It might happen
that downstream element switched from passthrough to non-passthrough
and sent a reconfigure upstream (that caused this renegotiation).
This downstream element will ask the video sink below for the bufferpool
with an allocation query and will get the same bufferpool that
videodecoder is holding, too.
When renegotiating, if videodecoder deactivates its bufferpool it
might be deactivating the bufferpool that some element downstream
is using and cause the pipeline to fail.
https://bugzilla.gnome.org/show_bug.cgi?id=727498
baseparse will reverse each GOP for us already, so the segment events can
be after our keyframe. Make sure to get it and all other relevant sticky
events before starting to decode.
For reverse playback, the segment event will only be pushed when
the first buffer is actually pushed. But for decoding frames and storing
those into the list to be pushed the output_segment.rate value is used
to determine if it is forward or reverse playback.
In case a previous segment event (or none) is in use it will mistakenly
think it is doing forward playback and push the buffers immediatelly and
try to clip buffers based on an old segment (or an uninitialized one, leading
to an assertion)
This patch fixes this by copying the segment earlier if on reverse playback
https://bugzilla.gnome.org/show_bug.cgi?id=721666
So that it avoids to send an allocation query twice.
One from an early call to gst_video_encoder_negotiate from a
subclass, then one from gst_video_encoder_allocate_output_frame.
Which means that previously gst_video_encoder_negotiate was not
clearing the GST_PAD_FLAG_NEED_RECONFIGURE even on success.
Fixes bug https://bugzilla.gnome.org/show_bug.cgi?id=719684
... so subclasses can release a frame all the way (also from frame list)
without having to pass through _finish_frame or _drop_frame.
The latter may not be applicable, or may or may not have already
been called for the frame in question.
See https://bugzilla.gnome.org/show_bug.cgi?id=693772
We could have allocation query before caps event and even without caps inside
the query. In such cases , the downstream can return a bufferpool object with
out actually configuring it. This feature is helpful to negotiate the bufferpool
with out knowing the output video format. For eg: some hardware accelerated
decoders can interpret the o/p video format only after it finishes the decoding
of one buffer at least.
https://bugzilla.gnome.org/show_bug.cgi?id=687183
This avoids triggering plenty of extra code/methods/overhead downstream when
we can just quickly check whenever we want to set caps whether they are
identical or not
https://bugzilla.gnome.org/show_bug.cgi?id=706600
Either there was a flush before that resets everything anyway,
or resetting would make us lose information we might need if
it's just a segment update.
In the unlikely case that the decoder drops a frame before the first
input frame is outputted, use the input segment (since it wasn't
carried over to the output segment yet)
https://bugzilla.gnome.org/show_bug.cgi?id=702502
We have no way of tell the caller of the exact error (e.g. if we're flushing),
so will have to wait until the caller uses API that returns a GstFlowReturn,
for example when pushing this buffer.
https://bugzilla.gnome.org/show_bug.cgi?id=700006
For this release the corresponding GstVideoCodecFrame before
pushing the buffer. The buffer will now be writable unless
the subclass still holds another reference to the buffer or
the frame.
When we get a new buffer, always call the parse function, even if it is a 0
sized buffer. For theora we need to also decode 0 sized buffers.
Ideally we would like to make theoradec be packetized but that fails currently
because of oggdemux and because of the assumptions that the base class makes.
DTS and PTS usually have a non-zero offset between them in MPEG-TS,
so assigning DTS to PTS is almost always wrong. The other, newer
timestamp recovery code does it correctly if we leave it as invalid.
And only return the proportion. The earliest time already can be
retrieved from get_max_decode_time() and by renaming we allow this
to be more extensible in the future.
Add a getter for the QoS proportion and earliest_time to help
subclasses do better estimations based on the proportion.
API: gst_video_decoder_get_qos_info()
https://bugzilla.gnome.org/show_bug.cgi?id=687991
Monitor for reordered output timestamps, and then avoid oldest DTS
as PTS approach, and try for an oldest PTS as out PTS approach,
if at least all valid PTS available.
Avoids bogus estimating upon sparse available input PTS, and tries
to handle all-keyframe input, or input PTS which are actually DTS.
Hold both the stream and the object lock to modify the output_state,
this way it can be safely modified while hold either one or the other.
Also, only hold the object lock in the query
https://bugzilla.gnome.org/show_bug.cgi?id=684832
... by having some more timestamp tracking in a private frame field.
Not doing so would lead to (a.o.) losing the needed minimum timestamp in
an earlier sent frame.
Don't try to take STREAM_LOCK on upstream events such as QOS.
Protect qos-related variables with object lock instead. Fixes
possible deadlock when shutting down in certain situations.
https://bugzilla.gnome.org/show_bug.cgi?id=684658
Drain out the decoder when encountering a gap. Needed for DVD 'still'
sequences which consist of a single video frame, and a large gap
while audio plays.
Only hold back events until the first buffer is generated, then just
send them directly. Otherwise, important events like 'still-frame' are
held forever, waiting for a frame that'll never arrive.
Sometimes the decoder would need to use the pool or the allocator for
something else than just allocating output buffers. For example, the querying
for different parameters, such as asking for a bigger number of buffers to
allocate in the pool.
This patch expose a two getters accessors: one for the buffer pool and the
other for the memory allocator.
Unifies the code and ensures that:
* subclasses needing to use the frame_number on a void* field will
always work
* wraparounds will be automatically taken care of if we have to deal
with more than 2**32 frames
Check that we have a valid output_state before attempting to use it to calculate
the duration of a buffer. It is possible that we don't have a state yet, for
example when we are dropping the first buffers.
Make sure the frame deadline was set before calculating the
max_decode_time. Fixes problems with ffmpeg skipping frames when
it doesn't need to, when the input doesn't have full timestamping
(divx in avi)
Interpolating the timestamps from the picture numbers
does more harm than good, getting it wrong in a lot of
cases (especially reverse playback). Removing it in favour
of simply incrementing the timestamps until there's
something better
Use g_list_free_full instead of walking lists twice when freeing
them.
Remove pointless clause in gst_video_decoder_chain that doesn't
actually have any effect.
Other changes to make the code slightly more like the 0.11
version.
Move processing of the gather list into the flush_parse function.
Add a last ditch attempt to apply timestamps to outgoing buffers
when walking backwards through decoded frames. Requires that each
gathered region has at least one timestamp.
Make sure to remove decoded packets from the decode list when
they are sent - otherwise the list just grows on each cycle, with
more and more frames being decoded and then clipped away.
Break out of the processing loop early on a bad flow return to make
seeking more responsive.
Use the gst_video_decoder_clip_and_push_buf function in reverse
mode, instead of pushing all buffers arbitrarily.
A couple of small efficiency gains in the list handling, by moving
list elements directly and not reallocating, and by reversing
and concatenating the gather list instead of moving it one node
at a time.
Rename the gst_video_decoder_do_finish_frame function to
gst_video_decoder_release_frame.
Rename gst_video_decoder_have_frame_2 to
gst_video_decoder_decode_frame and pass the frame to process
directly, rather than using the current_frame pointer as a holding
pen.
Move the negative rate handling out of the function to where it
is needed, and remove the process flag.
The frames are the owners of the buffers. In cases where a decoder
would keep around reference frames, we need to ensure they don't
disappear early.
To handle this, we pass downstream a complete sub-buffer of the output
buffer, ensuring that the buffer will only be released when downstream
is done with it *AND* the frame is no longer used.
Conflicts:
gst-libs/gst/video/gstvideodecoder.c
Don't replace the initial frame's timestamp with a bogus
one calculated from the (incorrect for Ogg) frame number just
because the 'sync time' hasn't changed.
Also, don't output a bogus warning about the output_frame being
NULL when it's being dropped/skipped due to QoS.