mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-29 05:01:23 +00:00
videodecoder: use new segment earlier for reverse playback
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
This commit is contained in:
parent
0d66d05c98
commit
5b8e1925b5
1 changed files with 33 additions and 0 deletions
|
@ -1938,6 +1938,39 @@ gst_video_decoder_flush_parse (GstVideoDecoder * dec, gboolean at_eos)
|
|||
/* move it to the front of the decode queue */
|
||||
priv->decode = g_list_concat (walk, priv->decode);
|
||||
|
||||
/* this is reverse playback, check if we need to apply some segment
|
||||
* to the output before decoding, as during decoding the segment.rate
|
||||
* must be used to determine if a buffer should be pushed or added to
|
||||
* the output list for reverse pushing.
|
||||
*
|
||||
* The new segment is not immediately pushed here because we must
|
||||
* wait for negotiation to happen before it can be pushed to avoid
|
||||
* pushing a segment before caps event. Negotiation only happens
|
||||
* when finish_frame is called.
|
||||
*/
|
||||
for (walk = frame->events; walk;) {
|
||||
GList *cur = walk;
|
||||
GstEvent *event = walk->data;
|
||||
|
||||
walk = g_list_next (walk);
|
||||
if (GST_EVENT_TYPE (event) <= GST_EVENT_SEGMENT) {
|
||||
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
|
||||
GstSegment segment;
|
||||
|
||||
GST_DEBUG_OBJECT (dec, "Segment at frame %p %" GST_TIME_FORMAT,
|
||||
frame, GST_TIME_ARGS (GST_BUFFER_PTS (frame->input_buffer)));
|
||||
gst_event_copy_segment (event, &segment);
|
||||
if (segment.format == GST_FORMAT_TIME) {
|
||||
dec->output_segment = segment;
|
||||
}
|
||||
}
|
||||
dec->priv->pending_events =
|
||||
g_list_append (dec->priv->pending_events, event);
|
||||
frame->events = g_list_delete_link (frame->events, cur);
|
||||
}
|
||||
}
|
||||
|
||||
/* if we copied a keyframe, flush and decode the decode queue */
|
||||
if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) {
|
||||
GST_DEBUG_OBJECT (dec, "found keyframe %p with PTS %" GST_TIME_FORMAT
|
||||
|
|
Loading…
Reference in a new issue