oggmux: Use running time instead of timestamps

Theora and vorbis use running time (which is correct) for calculating
the granulepos for their ogg packets. Oggmux, however, used
timestamps to order the received buffers.

This patch makes it use the running time to compare buffer times
and also to timestamp pushed buffers.

Some bits of the code still use timestamps, but they are only
used to calculate durations, so it should be fine.

https://bugzilla.gnome.org/show_bug.cgi?id=643775
This commit is contained in:
Thiago Santos 2011-03-03 08:45:15 -03:00 committed by Sebastian Dröge
parent c3aae3dc17
commit d1c74779f9

View file

@ -62,6 +62,11 @@ GST_DEBUG_CATEGORY_STATIC (gst_ogg_mux_debug);
? GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf) \ ? GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf) \
: GST_BUFFER_TIMESTAMP (buf)) : GST_BUFFER_TIMESTAMP (buf))
#define GST_BUFFER_RUNNING_TIME(buf, oggpad) \
(GST_BUFFER_DURATION_IS_VALID (buf) \
? gst_segment_to_running_time ((oggpad)->segment, GST_FORMAT_TIME, \
GST_BUFFER_TIMESTAMP (buf)) : 0)
#define GST_GP_FORMAT "[gp %8" G_GINT64_FORMAT "]" #define GST_GP_FORMAT "[gp %8" G_GINT64_FORMAT "]"
#define GST_GP_CAST(_gp) ((gint64) _gp) #define GST_GP_CAST(_gp) ((gint64) _gp)
@ -538,7 +543,8 @@ gst_ogg_mux_buffer_from_page (GstOggMux * mux, ogg_page * page, gboolean delta)
} }
static GstFlowReturn static GstFlowReturn
gst_ogg_mux_push_buffer (GstOggMux * mux, GstBuffer * buffer) gst_ogg_mux_push_buffer (GstOggMux * mux, GstBuffer * buffer,
GstOggPadData * oggpad)
{ {
GstCaps *caps; GstCaps *caps;
@ -549,11 +555,11 @@ gst_ogg_mux_push_buffer (GstOggMux * mux, GstBuffer * buffer)
/* Ensure we have monotonically increasing timestamps in the output. */ /* Ensure we have monotonically increasing timestamps in the output. */
if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) { if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
if (mux->last_ts != GST_CLOCK_TIME_NONE && gint64 run_time = GST_BUFFER_RUNNING_TIME (buffer, oggpad);
GST_BUFFER_TIMESTAMP (buffer) < mux->last_ts) if (mux->last_ts != GST_CLOCK_TIME_NONE && run_time < mux->last_ts)
GST_BUFFER_TIMESTAMP (buffer) = mux->last_ts; GST_BUFFER_TIMESTAMP (buffer) = mux->last_ts;
else else
mux->last_ts = GST_BUFFER_TIMESTAMP (buffer); mux->last_ts = run_time;
} }
caps = gst_pad_get_negotiated_caps (mux->srcpad); caps = gst_pad_get_negotiated_caps (mux->srcpad);
@ -628,7 +634,7 @@ gst_ogg_mux_dequeue_page (GstOggMux * mux, GstFlowReturn * flowret)
while (buf && GST_BUFFER_OFFSET_END (buf) == -1) { while (buf && GST_BUFFER_OFFSET_END (buf) == -1) {
GST_LOG_OBJECT (pad->collect.pad, "[gp -1] pushing page"); GST_LOG_OBJECT (pad->collect.pad, "[gp -1] pushing page");
g_queue_pop_head (pad->pagebuffers); g_queue_pop_head (pad->pagebuffers);
*flowret = gst_ogg_mux_push_buffer (mux, buf); *flowret = gst_ogg_mux_push_buffer (mux, buf, pad);
buf = g_queue_peek_head (pad->pagebuffers); buf = g_queue_peek_head (pad->pagebuffers);
ret = TRUE; ret = TRUE;
} }
@ -662,7 +668,7 @@ gst_ogg_mux_dequeue_page (GstOggMux * mux, GstFlowReturn * flowret)
GST_GP_FORMAT " pushing oldest page buffer %p (granulepos time %" GST_GP_FORMAT " pushing oldest page buffer %p (granulepos time %"
GST_TIME_FORMAT ")", GST_BUFFER_OFFSET_END (buf), buf, GST_TIME_FORMAT ")", GST_BUFFER_OFFSET_END (buf), buf,
GST_TIME_ARGS (GST_BUFFER_OFFSET (buf))); GST_TIME_ARGS (GST_BUFFER_OFFSET (buf)));
*flowret = gst_ogg_mux_push_buffer (mux, buf); *flowret = gst_ogg_mux_push_buffer (mux, buf, opad);
ret = TRUE; ret = TRUE;
} }
@ -753,6 +759,11 @@ gst_ogg_mux_compare_pads (GstOggMux * ogg_mux, GstOggPadData * first,
if (secondtime == GST_CLOCK_TIME_NONE) if (secondtime == GST_CLOCK_TIME_NONE)
return 1; return 1;
firsttime = gst_segment_to_running_time (first->segment, GST_FORMAT_TIME,
firsttime);
secondtime = gst_segment_to_running_time (second->segment, GST_FORMAT_TIME,
secondtime);
/* first buffer has higher timestamp, second one should go first */ /* first buffer has higher timestamp, second one should go first */
if (secondtime < firsttime) if (secondtime < firsttime)
return 1; return 1;
@ -1226,7 +1237,7 @@ gst_ogg_mux_send_headers (GstOggMux * mux)
hbufs = g_list_delete_link (hbufs, hbufs); hbufs = g_list_delete_link (hbufs, hbufs);
if ((ret = gst_ogg_mux_push_buffer (mux, buf)) != GST_FLOW_OK) if ((ret = gst_ogg_mux_push_buffer (mux, buf, NULL)) != GST_FLOW_OK)
break; break;
} }
/* free any remaining nodes/buffers in case we couldn't push them */ /* free any remaining nodes/buffers in case we couldn't push them */