mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 23:18:52 +00:00
ext/theora/theoradec.c: Use higher precision timestamps calculation.
Original commit message from CVS: * ext/theora/theoradec.c: (_theora_granule_frame), (_theora_granule_time), (_inc_granulepos), (theora_dec_src_convert), (theora_dec_sink_convert), (theora_handle_type_packet), (theora_handle_data_packet), (theora_dec_chain): Use higher precision timestamps calculation. Convert some other conversions to _scale.
This commit is contained in:
parent
b5398e7a9d
commit
344800fb30
2 changed files with 64 additions and 39 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2006-01-31 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* ext/theora/theoradec.c: (_theora_granule_frame),
|
||||||
|
(_theora_granule_time), (_inc_granulepos),
|
||||||
|
(theora_dec_src_convert), (theora_dec_sink_convert),
|
||||||
|
(theora_handle_type_packet), (theora_handle_data_packet),
|
||||||
|
(theora_dec_chain):
|
||||||
|
Use higher precision timestamps calculation.
|
||||||
|
Convert some other conversions to _scale.
|
||||||
|
|
||||||
2006-01-31 Stefan Kost <ensonic@users.sf.net>
|
2006-01-31 Stefan Kost <ensonic@users.sf.net>
|
||||||
|
|
||||||
* gst/audiotestsrc/gstaudiotestsrc.c:
|
* gst/audiotestsrc/gstaudiotestsrc.c:
|
||||||
|
|
|
@ -56,6 +56,7 @@ struct _GstTheoraDec
|
||||||
|
|
||||||
gboolean have_header;
|
gboolean have_header;
|
||||||
guint64 granulepos;
|
guint64 granulepos;
|
||||||
|
guint64 granule_shift;
|
||||||
|
|
||||||
GstClockTime last_timestamp;
|
GstClockTime last_timestamp;
|
||||||
guint64 frame_nr;
|
guint64 frame_nr;
|
||||||
|
@ -208,25 +209,52 @@ _theora_ilog (unsigned int v)
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gint64
|
||||||
_inc_granulepos (GstTheoraDec * dec)
|
_theora_granule_frame (GstTheoraDec * dec, gint64 granulepos)
|
||||||
{
|
{
|
||||||
guint ilog;
|
guint ilog;
|
||||||
gint framecount;
|
gint framecount;
|
||||||
|
|
||||||
if (dec->granulepos == -1)
|
if (granulepos == -1)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
ilog = _theora_ilog (dec->info.keyframe_frequency_force - 1);
|
ilog = dec->granule_shift;
|
||||||
|
|
||||||
framecount = dec->granulepos >> ilog;
|
/* granulepos is last ilog bits for counting pframes since last iframe and
|
||||||
framecount += dec->granulepos - (framecount << ilog);
|
* bits in front of that for the framenumber of the last iframe. */
|
||||||
|
framecount = granulepos >> ilog;
|
||||||
|
framecount += granulepos - (framecount << ilog);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dec, "framecount=%d, ilog=%u", framecount, ilog);
|
GST_DEBUG_OBJECT (dec, "framecount=%d, ilog=%u", framecount, ilog);
|
||||||
|
|
||||||
framecount++;
|
return framecount;
|
||||||
|
}
|
||||||
|
|
||||||
dec->granulepos = (framecount << ilog);
|
static GstClockTime
|
||||||
|
_theora_granule_time (GstTheoraDec * dec, gint64 granulepos)
|
||||||
|
{
|
||||||
|
gint framecount;
|
||||||
|
|
||||||
|
if (granulepos == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
framecount = _theora_granule_frame (dec, dec->granulepos);
|
||||||
|
|
||||||
|
return gst_util_uint64_scale_int (framecount * GST_SECOND,
|
||||||
|
dec->info.fps_denominator, dec->info.fps_numerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint64
|
||||||
|
_inc_granulepos (GstTheoraDec * dec, gint64 granulepos)
|
||||||
|
{
|
||||||
|
gint framecount;
|
||||||
|
|
||||||
|
if (granulepos == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
framecount = _theora_granule_frame (dec, granulepos);
|
||||||
|
|
||||||
|
return (framecount + 1) << dec->granule_shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -298,8 +326,8 @@ theora_dec_src_convert (GstPad * pad,
|
||||||
case GST_FORMAT_BYTES:
|
case GST_FORMAT_BYTES:
|
||||||
switch (*dest_format) {
|
switch (*dest_format) {
|
||||||
case GST_FORMAT_DEFAULT:
|
case GST_FORMAT_DEFAULT:
|
||||||
*dest_value =
|
*dest_value = gst_util_uint64_scale_int (src_value, 2,
|
||||||
src_value * 2 / (dec->info.height * dec->info.width * 3);
|
dec->info.height * dec->info.width * 3);
|
||||||
break;
|
break;
|
||||||
case GST_FORMAT_TIME:
|
case GST_FORMAT_TIME:
|
||||||
/* seems like a rather silly conversion, implement me if you like */
|
/* seems like a rather silly conversion, implement me if you like */
|
||||||
|
@ -312,9 +340,8 @@ theora_dec_src_convert (GstPad * pad,
|
||||||
case GST_FORMAT_BYTES:
|
case GST_FORMAT_BYTES:
|
||||||
scale = 3 * (dec->info.width * dec->info.height) / 2;
|
scale = 3 * (dec->info.width * dec->info.height) / 2;
|
||||||
case GST_FORMAT_DEFAULT:
|
case GST_FORMAT_DEFAULT:
|
||||||
*dest_value =
|
*dest_value = scale * gst_util_uint64_scale_int (src_value,
|
||||||
scale * (((guint64) src_value * dec->info.fps_numerator) /
|
dec->info.fps_numerator, dec->info.fps_denominator * GST_SECOND);
|
||||||
(dec->info.fps_denominator * GST_SECOND));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
|
@ -323,8 +350,8 @@ theora_dec_src_convert (GstPad * pad,
|
||||||
case GST_FORMAT_DEFAULT:
|
case GST_FORMAT_DEFAULT:
|
||||||
switch (*dest_format) {
|
switch (*dest_format) {
|
||||||
case GST_FORMAT_TIME:
|
case GST_FORMAT_TIME:
|
||||||
*dest_value = src_value * (GST_SECOND * dec->info.fps_denominator /
|
*dest_value = gst_util_uint64_scale_int (src_value,
|
||||||
dec->info.fps_numerator);
|
GST_SECOND * dec->info.fps_denominator, dec->info.fps_numerator);
|
||||||
break;
|
break;
|
||||||
case GST_FORMAT_BYTES:
|
case GST_FORMAT_BYTES:
|
||||||
*dest_value =
|
*dest_value =
|
||||||
|
@ -363,20 +390,9 @@ theora_dec_sink_convert (GstPad * pad,
|
||||||
switch (src_format) {
|
switch (src_format) {
|
||||||
case GST_FORMAT_DEFAULT:
|
case GST_FORMAT_DEFAULT:
|
||||||
{
|
{
|
||||||
guint64 framecount;
|
|
||||||
guint ilog;
|
|
||||||
|
|
||||||
ilog = _theora_ilog (dec->info.keyframe_frequency_force - 1);
|
|
||||||
|
|
||||||
/* granulepos is last ilog bits for counting pframes since last iframe and
|
|
||||||
* bits in front of that for the framenumber of the last iframe. */
|
|
||||||
framecount = src_value >> ilog;
|
|
||||||
framecount += src_value - (framecount << ilog);
|
|
||||||
|
|
||||||
switch (*dest_format) {
|
switch (*dest_format) {
|
||||||
case GST_FORMAT_TIME:
|
case GST_FORMAT_TIME:
|
||||||
*dest_value = framecount * (GST_SECOND * dec->info.fps_denominator /
|
*dest_value = _theora_granule_time (dec, src_value);
|
||||||
dec->info.fps_numerator);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
|
@ -388,17 +404,16 @@ theora_dec_sink_convert (GstPad * pad,
|
||||||
switch (*dest_format) {
|
switch (*dest_format) {
|
||||||
case GST_FORMAT_DEFAULT:
|
case GST_FORMAT_DEFAULT:
|
||||||
{
|
{
|
||||||
guint ilog = _theora_ilog (dec->info.keyframe_frequency_force - 1);
|
|
||||||
guint rest;
|
guint rest;
|
||||||
|
|
||||||
/* framecount */
|
/* framecount */
|
||||||
*dest_value = src_value * dec->info.fps_numerator /
|
*dest_value = gst_util_uint64_scale_int (src_value,
|
||||||
(GST_SECOND * dec->info.fps_denominator);
|
dec->info.fps_numerator, GST_SECOND * dec->info.fps_denominator);
|
||||||
|
|
||||||
/* funny way of calculating granulepos in theora */
|
/* funny way of calculating granulepos in theora */
|
||||||
rest = *dest_value / dec->info.keyframe_frequency_force;
|
rest = *dest_value / dec->info.keyframe_frequency_force;
|
||||||
*dest_value -= rest;
|
*dest_value -= rest;
|
||||||
*dest_value <<= ilog;
|
*dest_value <<= dec->granule_shift;
|
||||||
*dest_value += rest;
|
*dest_value += rest;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -743,6 +758,8 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
|
||||||
dec->offset_y = 0;
|
dec->offset_y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dec->granule_shift = _theora_ilog (dec->info.keyframe_frequency_force - 1);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (dec, "after fixup frame dimension %dx%d, offset %d:%d",
|
GST_DEBUG_OBJECT (dec, "after fixup frame dimension %dx%d, offset %d:%d",
|
||||||
dec->width, dec->height, dec->offset_x, dec->offset_y);
|
dec->width, dec->height, dec->offset_x, dec->offset_y);
|
||||||
|
|
||||||
|
@ -941,8 +958,8 @@ theora_handle_data_packet (GstTheoraDec * dec, ogg_packet * packet,
|
||||||
dec->frame_nr++;
|
dec->frame_nr++;
|
||||||
GST_BUFFER_OFFSET_END (out) = dec->frame_nr;
|
GST_BUFFER_OFFSET_END (out) = dec->frame_nr;
|
||||||
GST_BUFFER_DURATION (out) =
|
GST_BUFFER_DURATION (out) =
|
||||||
GST_SECOND * ((gdouble) dec->info.fps_denominator) /
|
gst_util_uint64_scale_int (GST_SECOND, dec->info.fps_denominator,
|
||||||
dec->info.fps_numerator;
|
dec->info.fps_numerator);
|
||||||
GST_BUFFER_TIMESTAMP (out) = outtime;
|
GST_BUFFER_TIMESTAMP (out) = outtime;
|
||||||
|
|
||||||
result = theora_dec_push (dec, out);
|
result = theora_dec_push (dec, out);
|
||||||
|
@ -1005,11 +1022,9 @@ theora_dec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
if (dec->have_header) {
|
if (dec->have_header) {
|
||||||
if (packet.granulepos != -1) {
|
if (packet.granulepos != -1) {
|
||||||
dec->granulepos = packet.granulepos;
|
dec->granulepos = packet.granulepos;
|
||||||
dec->last_timestamp =
|
dec->last_timestamp = _theora_granule_time (dec, packet.granulepos);
|
||||||
GST_SECOND * theora_granule_time (&dec->state, packet.granulepos);
|
|
||||||
} else if (dec->last_timestamp != -1) {
|
} else if (dec->last_timestamp != -1) {
|
||||||
dec->last_timestamp +=
|
dec->last_timestamp = _theora_granule_time (dec, dec->granulepos);
|
||||||
(GST_SECOND * dec->info.fps_denominator) / dec->info.fps_numerator;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dec->last_timestamp = -1;
|
dec->last_timestamp = -1;
|
||||||
|
@ -1030,7 +1045,7 @@ theora_dec_chain (GstPad * pad, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
_inc_granulepos (dec);
|
dec->granulepos = _inc_granulepos (dec, dec->granulepos);
|
||||||
|
|
||||||
gst_object_unref (dec);
|
gst_object_unref (dec);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue