From: <tho...@fr...> - 2005-06-21 17:34:06
|
CVS Root: /cvs//gstreamer Module: gst-plugins Changes by: thomasvs Date: Tue Jun 21 2005 10:33:38 PDT Branch: BRANCH-GSTREAMER-0_8 Log message: * ext/theora/theoraenc.c: (_ilog), (gst_theora_enc_init), (theora_enc_sink_link), (theora_buffer_from_packet): fix granulepos bug from #305231 Modified files: . : ChangeLog ext/theora : theoraenc.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ChangeLog.diff?r1=1.1641.2.255&r2=1.1641.2.256 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins/ext/theora/theoraenc.c.diff?r1=1.19.2.4&r2=1.19.2.5 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs//gstreamer/gst-plugins/ChangeLog,v retrieving revision 1.1641.2.255 retrieving revision 1.1641.2.256 diff -u -d -r1.1641.2.255 -r1.1641.2.256 --- ChangeLog 21 Jun 2005 16:59:09 -0000 1.1641.2.255 +++ ChangeLog 21 Jun 2005 17:33:26 -0000 1.1641.2.256 @@ -1,5 +1,11 @@ 2005-06-21 Thomas Vander Stichele <thomas at apestaart dot org> + * ext/theora/theoraenc.c: (_ilog), (gst_theora_enc_init), + (theora_enc_sink_link), (theora_buffer_from_packet): + fix granulepos bug from #305231 + +2005-06-21 Thomas Vander Stichele <thomas at apestaart dot org> * gst/videotestsrc/gstvideotestsrc.c: (gst_videotestsrc_class_init), (gst_videotestsrc_set_property), expose timestamp_offset as a gobject property Index: theoraenc.c RCS file: /cvs//gstreamer/gst-plugins/ext/theora/Attic/theoraenc.c,v retrieving revision 1.19.2.4 retrieving revision 1.19.2.5 diff -u -d -r1.19.2.4 -r1.19.2.5 --- theoraenc.c 8 Jun 2005 17:58:19 -0000 1.19.2.4 +++ theoraenc.c 21 Jun 2005 17:33:26 -0000 1.19.2.5 @@ -96,6 +96,7 @@ gint keyframe_mindistance; gint noise_sensitivity; gint sharpness; + gint granule_shift; gint info_width, info_height; gint width, height; @@ -129,6 +130,19 @@ #define THEORA_DEF_NOISE_SENSITIVITY 1 #define THEORA_DEF_SHARPNESS 0 +/* taken from theora/lib/toplevel.c */ +static int +_ilog (unsigned int v) +{ + int ret = 0; + while (v) { + ret++; + v >>= 1; + } + return (ret); +} enum { ARG_0, @@ -285,6 +299,12 @@ enc->noise_sensitivity = THEORA_DEF_NOISE_SENSITIVITY; enc->sharpness = THEORA_DEF_SHARPNESS; + /* as done in theora */ + enc->granule_shift = _ilog (enc->info.keyframe_frequency_force - 1); + GST_DEBUG_OBJECT (enc, + "keyframe_frequency_force is %d, granule shift is %d", + enc->info.keyframe_frequency_force, enc->granule_shift); GST_FLAG_SET (enc, GST_ELEMENT_EVENT_AWARE); } @@ -338,7 +358,7 @@ enc->info.aspect_numerator = gst_value_get_fraction_numerator (par); enc->info.aspect_denominator = gst_value_get_fraction_denominator (par); } else { - /* setting them to 0 indicates that the decoder can chose a good aspect + /* setting them to 0 indicates that the decoder can choose a good aspect * ratio, defaulting to 1/1 */ enc->info.aspect_numerator = 0; enc->info.aspect_denominator = 0; @@ -359,6 +379,13 @@ enc->info.noise_sensitivity = enc->noise_sensitivity; enc->info.sharpness = enc->sharpness; theora_encode_init (&enc->state, &enc->info); return GST_PAD_LINK_OK; @@ -371,22 +398,33 @@ GstBuffer *buf; guint64 granulepos_delta, timestamp_delta; + guint64 iframe, pframe; + /* we try and convert our starting timestamp delta to a granulepos delta, + * shifting all frames ahead. This introduces a time error of up to a + * frame with the current code though */ - /* if duration is 0, it's a header packet and should - * have granulepos 0 (so no delta regardless of delay) */ if (duration == 0) { + /* if duration is 0, it's a header packet and should + * keep having granulepos 0 */ granulepos_delta = 0; timestamp_delta = 0; + /* granulepos is an encoding of iframe/pframe; + * our offset needs to be added to the iframe value */ granulepos_delta = enc->initial_delay * enc->fps / GST_SECOND; timestamp_delta = enc->initial_delay; } + iframe = packet->granulepos >> enc->granule_shift; + pframe = packet->granulepos - (iframe << enc->granule_shift); + iframe += granulepos_delta; + packet->granulepos = (iframe << enc->granule_shift) + pframe; buf = gst_pad_alloc_buffer (enc->srcpad, GST_BUFFER_OFFSET_NONE, packet->bytes); memcpy (GST_BUFFER_DATA (buf), packet->packet, packet->bytes); GST_BUFFER_OFFSET (buf) = enc->bytes_out; - GST_BUFFER_OFFSET_END (buf) = packet->granulepos + granulepos_delta; + GST_BUFFER_OFFSET_END (buf) = packet->granulepos; GST_BUFFER_TIMESTAMP (buf) = timestamp + timestamp_delta; GST_BUFFER_DURATION (buf) = duration; @@ -402,10 +440,10 @@ enc->packetno++; - GST_DEBUG ("encoded buffer of %d bytes. granulepos = %" G_GINT64_FORMAT - " + %" G_GINT64_FORMAT " = %" G_GINT64_FORMAT, GST_BUFFER_SIZE (buf), - packet->granulepos, granulepos_delta, - packet->granulepos + granulepos_delta); + GST_LOG_OBJECT (enc, + "set granulepos to %" G_GINT64_FORMAT "/%" G_GINT64_FORMAT, + iframe, pframe); + GST_LOG_OBJECT (enc, "encoded buffer of %d bytes", GST_BUFFER_SIZE (buf)); return buf; |