oggdemux: Fix timestamp generation for theora

Timestamp generation was broken by the last commit for formats
with a non-zero granule shift.  Also keep track of the last keyframe
so that we can regenerate granulepos for theora.
This commit is contained in:
David Schleef 2009-11-24 22:08:09 -08:00
parent 78aad52cbf
commit 8c202593c6
4 changed files with 23 additions and 14 deletions

View file

@ -485,25 +485,21 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet)
GST_BUFFER_OFFSET (buf) = 0; GST_BUFFER_OFFSET (buf) = 0;
GST_BUFFER_OFFSET_END (buf) = -1; GST_BUFFER_OFFSET_END (buf) = -1;
} else { } else {
GST_BUFFER_TIMESTAMP (buf) = gst_ogg_stream_granule_to_time (&pad->map,
pad->current_granule);
GST_BUFFER_DURATION (buf) = gst_ogg_stream_granule_to_time (&pad->map,
pad->current_granule + duration) - GST_BUFFER_TIMESTAMP (buf);
pad->current_granule += duration; pad->current_granule += duration;
if (packet->granulepos != -1) { if (packet->granulepos != -1) {
gint64 granule; pad->current_granule = gst_ogg_stream_granulepos_to_granule (&pad->map,
granule = gst_ogg_stream_granulepos_to_granule (&pad->map, packet->granulepos);
pad->keyframe_granule =
gst_ogg_stream_granulepos_to_key_granule (&pad->map,
packet->granulepos); packet->granulepos);
if (granule != pad->current_granule) {
GST_WARNING ("calculated granule didn't match actual (%lld != %lld)",
pad->current_granule, granule);
}
pad->current_granule = granule;
} }
GST_BUFFER_TIMESTAMP (buf) = gst_ogg_stream_granule_to_time (&pad->map,
pad->current_granule - duration);
GST_BUFFER_DURATION (buf) = gst_ogg_stream_granule_to_time (&pad->map,
pad->current_granule) - GST_BUFFER_TIMESTAMP (buf);
GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_END (buf) =
gst_ogg_stream_granule_to_granulepos (&pad->map, pad->current_granule, gst_ogg_stream_granule_to_granulepos (&pad->map, pad->current_granule,
pad->current_granule); pad->keyframe_granule);
GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET (buf) =
gst_ogg_stream_granule_to_time (&pad->map, pad->current_granule); gst_ogg_stream_granule_to_time (&pad->map, pad->current_granule);
} }
@ -629,7 +625,7 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
GST_DEBUG ("start time %" G_GINT64_FORMAT, pad->start_time); GST_DEBUG ("start time %" G_GINT64_FORMAT, pad->start_time);
} else { } else {
packet->granulepos = gst_ogg_stream_granule_to_granulepos (&pad->map, packet->granulepos = gst_ogg_stream_granule_to_granulepos (&pad->map,
pad->map.accumulated_granule, pad->map.accumulated_granule); pad->map.accumulated_granule, pad->keyframe_granule);
} }
} }
} else { } else {

View file

@ -117,6 +117,7 @@ struct _GstOggPad
//gint serialno; //gint serialno;
gint64 packetno; gint64 packetno;
gint64 current_granule; gint64 current_granule;
gint64 keyframe_granule;
GstClockTime start_time; /* the timestamp of the first sample */ GstClockTime start_time; /* the timestamp of the first sample */

View file

@ -136,6 +136,16 @@ gst_ogg_stream_granulepos_to_granule (GstOggStream * pad, gint64 granulepos)
return mappers[pad->map].granulepos_to_granule_func (pad, granulepos); return mappers[pad->map].granulepos_to_granule_func (pad, granulepos);
} }
gint64
gst_ogg_stream_granulepos_to_key_granule (GstOggStream * pad, gint64 granulepos)
{
if (granulepos == -1 || granulepos == 0) {
return granulepos;
}
return granulepos >> pad->granuleshift;
}
gint64 gint64
gst_ogg_stream_granule_to_granulepos (GstOggStream * pad, gint64 granule, gst_ogg_stream_granule_to_granulepos (GstOggStream * pad, gint64 granule,
gint64 keyframe_granule) gint64 keyframe_granule)
@ -216,6 +226,7 @@ granulepos_to_granule_default (GstOggStream * pad, gint64 granulepos)
} }
} }
static gint64 static gint64
granule_to_granulepos_default (GstOggStream * pad, gint64 granule, granule_to_granulepos_default (GstOggStream * pad, gint64 granule,
gint64 keyframe_granule) gint64 keyframe_granule)

View file

@ -73,6 +73,7 @@ GstClockTime gst_ogg_stream_get_start_time_for_granulepos (GstOggStream *pad,
gint64 granulepos); gint64 granulepos);
GstClockTime gst_ogg_stream_granule_to_time (GstOggStream *pad, gint64 granule); GstClockTime gst_ogg_stream_granule_to_time (GstOggStream *pad, gint64 granule);
gint64 gst_ogg_stream_granulepos_to_granule (GstOggStream * pad, gint64 granulepos); gint64 gst_ogg_stream_granulepos_to_granule (GstOggStream * pad, gint64 granulepos);
gint64 gst_ogg_stream_granulepos_to_key_granule (GstOggStream * pad, gint64 granulepos);
gint64 gst_ogg_stream_granule_to_granulepos (GstOggStream * pad, gint64 granule, gint64 keyframe_granule); gint64 gst_ogg_stream_granule_to_granulepos (GstOggStream * pad, gint64 granule, gint64 keyframe_granule);
GstClockTime gst_ogg_stream_get_packet_start_time (GstOggStream *pad, GstClockTime gst_ogg_stream_get_packet_start_time (GstOggStream *pad,
ogg_packet *packet); ogg_packet *packet);