avidemux: Drop video frames up to the desired keyframe after a seek
The audio packets in AVI are generally muxed ~0.5s before the corresponding video packet. This changes causes downstream to only receive packets with roughly corresponding timestamps.
This commit is contained in:
parent
1175d0698c
commit
dd23397b4f
@ -4191,7 +4191,7 @@ avi_demux_handle_seek_push (GstAviDemux * avi, GstPad * pad, GstEvent * event)
|
|||||||
/* re-use cur to be the timestamp of the seek as it _will_ be */
|
/* re-use cur to be the timestamp of the seek as it _will_ be */
|
||||||
cur = stream->current_timestamp;
|
cur = stream->current_timestamp;
|
||||||
|
|
||||||
min_offset = stream->index[index].offset;
|
min_offset = avi->seek_kf_offset = stream->index[index].offset;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (avi,
|
GST_DEBUG_OBJECT (avi,
|
||||||
"Seek to: ts %" GST_TIME_FORMAT " (on str %u, idx %u, offset %"
|
"Seek to: ts %" GST_TIME_FORMAT " (on str %u, idx %u, offset %"
|
||||||
@ -4838,15 +4838,28 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
|
|||||||
} else {
|
} else {
|
||||||
GstAviStream *stream;
|
GstAviStream *stream;
|
||||||
GstClockTime next_ts = 0;
|
GstClockTime next_ts = 0;
|
||||||
GstBuffer *buf;
|
GstBuffer *buf = NULL;
|
||||||
guint64 offset;
|
guint64 offset;
|
||||||
|
gboolean saw_desired_kf = stream_nr != avi->main_stream
|
||||||
|
|| avi->offset >= avi->seek_kf_offset;
|
||||||
|
|
||||||
|
if (stream_nr == avi->main_stream && avi->offset == avi->seek_kf_offset) {
|
||||||
|
GST_DEBUG_OBJECT (avi, "Desired keyframe reached");
|
||||||
|
avi->seek_kf_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saw_desired_kf) {
|
||||||
gst_adapter_flush (avi->adapter, 8);
|
gst_adapter_flush (avi->adapter, 8);
|
||||||
|
|
||||||
/* get buffer */
|
/* get buffer */
|
||||||
buf = gst_adapter_take_buffer (avi->adapter, GST_ROUND_UP_2 (size));
|
buf = gst_adapter_take_buffer (avi->adapter, GST_ROUND_UP_2 (size));
|
||||||
/* patch the size */
|
/* patch the size */
|
||||||
GST_BUFFER_SIZE (buf) = size;
|
GST_BUFFER_SIZE (buf) = size;
|
||||||
|
} else {
|
||||||
|
GST_DEBUG_OBJECT (avi,
|
||||||
|
"Desired keyframe not yet reached, flushing chunk");
|
||||||
|
gst_adapter_flush (avi->adapter, 8 + GST_ROUND_UP_2 (size));
|
||||||
|
}
|
||||||
|
|
||||||
offset = avi->offset;
|
offset = avi->offset;
|
||||||
avi->offset += 8 + GST_ROUND_UP_2 (size);
|
avi->offset += 8 + GST_ROUND_UP_2 (size);
|
||||||
|
|
||||||
@ -4862,10 +4875,9 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
|
|||||||
if (G_UNLIKELY (!stream->pad)) {
|
if (G_UNLIKELY (!stream->pad)) {
|
||||||
GST_WARNING_OBJECT (avi, "no pad for stream ID %" GST_FOURCC_FORMAT,
|
GST_WARNING_OBJECT (avi, "no pad for stream ID %" GST_FOURCC_FORMAT,
|
||||||
GST_FOURCC_ARGS (tag));
|
GST_FOURCC_ARGS (tag));
|
||||||
|
if (buf)
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
} else {
|
} else {
|
||||||
GstClockTime dur_ts = 0;
|
|
||||||
|
|
||||||
/* get time of this buffer */
|
/* get time of this buffer */
|
||||||
gst_pad_query_position (stream->pad, &format, (gint64 *) & next_ts);
|
gst_pad_query_position (stream->pad, &format, (gint64 *) & next_ts);
|
||||||
if (G_UNLIKELY (format != GST_FORMAT_TIME))
|
if (G_UNLIKELY (format != GST_FORMAT_TIME))
|
||||||
@ -4877,6 +4889,12 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
|
|||||||
stream->current_entry++;
|
stream->current_entry++;
|
||||||
stream->current_total += size;
|
stream->current_total += size;
|
||||||
|
|
||||||
|
/* update current position in the segment */
|
||||||
|
gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, next_ts);
|
||||||
|
|
||||||
|
if (saw_desired_kf && buf) {
|
||||||
|
GstClockTime dur_ts = 0;
|
||||||
|
|
||||||
/* invert the picture if needed */
|
/* invert the picture if needed */
|
||||||
buf = gst_avi_demux_invert (stream, buf);
|
buf = gst_avi_demux_invert (stream, buf);
|
||||||
|
|
||||||
@ -4899,11 +4917,8 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
|
|||||||
"Pushing buffer with time=%" GST_TIME_FORMAT ", duration %"
|
"Pushing buffer with time=%" GST_TIME_FORMAT ", duration %"
|
||||||
GST_TIME_FORMAT ", offset %" G_GUINT64_FORMAT
|
GST_TIME_FORMAT ", offset %" G_GUINT64_FORMAT
|
||||||
" and size %d over pad %s", GST_TIME_ARGS (next_ts),
|
" and size %d over pad %s", GST_TIME_ARGS (next_ts),
|
||||||
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf),
|
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)),
|
||||||
size, GST_PAD_NAME (stream->pad));
|
GST_BUFFER_OFFSET (buf), size, GST_PAD_NAME (stream->pad));
|
||||||
|
|
||||||
/* update current position in the segment */
|
|
||||||
gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, next_ts);
|
|
||||||
|
|
||||||
/* mark discont when pending */
|
/* mark discont when pending */
|
||||||
if (G_UNLIKELY (stream->discont)) {
|
if (G_UNLIKELY (stream->discont)) {
|
||||||
@ -4922,6 +4937,7 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return res;
|
return res;
|
||||||
|
@ -199,6 +199,8 @@ typedef struct _GstAviDemux {
|
|||||||
guint odml_stream;
|
guint odml_stream;
|
||||||
guint odml_subidx;
|
guint odml_subidx;
|
||||||
guint64 *odml_subidxs;
|
guint64 *odml_subidxs;
|
||||||
|
|
||||||
|
guint64 seek_kf_offset; /* offset of the keyframe to which we want to seek */
|
||||||
} GstAviDemux;
|
} GstAviDemux;
|
||||||
|
|
||||||
typedef struct _GstAviDemuxClass {
|
typedef struct _GstAviDemuxClass {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user