From 3e712388badf91a7200a1a0a34087846111b35fd Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 7 Jul 2004 15:57:48 +0000 Subject: [PATCH] ext/theora/: Fix theora granulepos calculation. Original commit message from CVS: * ext/theora/theora.c: (plugin_init): * ext/theora/theoradec.c: (theora_dec_from_granulepos), (theora_dec_src_query), (theora_dec_chain): * ext/theora/theoraenc.c: (gst_theora_enc_class_init), (theora_enc_sink_link), (theora_buffer_from_packet), (theora_push_packet), (theora_enc_chain): Fix theora granulepos calculation. Fix overflow in duration/position calculation. Bump rank to PRIMARY for theoradec. Use granulepos of last packet to calculate position. Set keyframe flag on buffers when needed. --- ChangeLog | 14 ++++++++++++++ ext/theora/theora.c | 2 +- ext/theora/theoradec.c | 28 +++++++++++++++++++--------- ext/theora/theoraenc.c | 15 +++++++++++++-- 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2bd6e0b..a2d7047 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2004-07-07 Wim Taymans + + * ext/theora/theora.c: (plugin_init): + * ext/theora/theoradec.c: (theora_dec_from_granulepos), + (theora_dec_src_query), (theora_dec_chain): + * ext/theora/theoraenc.c: (gst_theora_enc_class_init), + (theora_enc_sink_link), (theora_buffer_from_packet), + (theora_push_packet), (theora_enc_chain): + Fix theora granulepos calculation. + Fix overflow in duration/position calculation. + Bump rank to PRIMARY for theoradec. + Use granulepos of last packet to calculate position. + Set keyframe flag on buffers when needed. + 2004-07-06 David Schleef * gst/playback/Makefile.am: 'test' in bin_PROGRAMS? Are you diff --git a/ext/theora/theora.c b/ext/theora/theora.c index 9d9470c..9f82b72 100644 --- a/ext/theora/theora.c +++ b/ext/theora/theora.c @@ -32,7 +32,7 @@ plugin_init (GstPlugin * plugin) if (!gst_library_load ("gsttags")) return FALSE; - if (!gst_element_register (plugin, "theoradec", GST_RANK_SECONDARY, + if (!gst_element_register (plugin, "theoradec", GST_RANK_PRIMARY, gst_theora_dec_get_type ())) return FALSE; diff --git a/ext/theora/theoradec.c b/ext/theora/theoradec.c index df59681..2229879 100644 --- a/ext/theora/theoradec.c +++ b/ext/theora/theoradec.c @@ -154,7 +154,7 @@ theora_dec_from_granulepos (GstTheoraDec * dec, GstFormat format, guint64 from, guint64 * to) { guint64 framecount; - guint ilog = _theora_ilog (dec->info.keyframe_frequency_force); + guint ilog = _theora_ilog (dec->info.keyframe_frequency_force - 1); if (dec->packetno < 1) return FALSE; @@ -166,15 +166,14 @@ theora_dec_from_granulepos (GstTheoraDec * dec, GstFormat format, guint64 from, switch (format) { case GST_FORMAT_TIME: - *to = framecount = - from * GST_SECOND * dec->info.fps_denominator / - dec->info.fps_numerator; + *to = framecount * (GST_SECOND * dec->info.fps_denominator / + dec->info.fps_numerator); break; case GST_FORMAT_DEFAULT: *to = framecount; break; case GST_FORMAT_BYTES: - *to = framecount * dec->info.height * dec->info.width * 12 / 8; + *to = framecount * dec->info.height * dec->info.width * 3 / 2; break; default: return FALSE; @@ -219,9 +218,13 @@ theora_dec_src_query (GstPad * pad, GstQueryType query, GstFormat * format, GstTheoraDec *dec = GST_THEORA_DEC (gst_pad_get_parent (pad)); GstFormat my_format = GST_FORMAT_DEFAULT; - if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format, - &granulepos)) - return FALSE; + if (query == GST_QUERY_POSITION) { + granulepos = dec->granulepos; + } else { + if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format, + &granulepos)) + return FALSE; + } if (!theora_dec_from_granulepos (dec, *format, granulepos, value)) return FALSE; @@ -321,6 +324,7 @@ theora_dec_chain (GstPad * pad, GstData * data) GstBuffer *buf; GstTheoraDec *dec; ogg_packet packet; + guint64 offset_end; dec = GST_THEORA_DEC (gst_pad_get_parent (pad)); if (GST_IS_EVENT (data)) { @@ -329,10 +333,16 @@ theora_dec_chain (GstPad * pad, GstData * data) } buf = GST_BUFFER (data); + + offset_end = GST_BUFFER_OFFSET_END (buf); + if (offset_end != -1) { + dec->granulepos = offset_end; + } + /* make ogg_packet out of the buffer */ packet.packet = GST_BUFFER_DATA (buf); packet.bytes = GST_BUFFER_SIZE (buf); - packet.granulepos = GST_BUFFER_OFFSET_END (buf); + packet.granulepos = dec->granulepos; packet.packetno = dec->packetno++; packet.b_o_s = (packet.packetno == 0) ? 1 : 0; packet.e_o_s = 0; diff --git a/ext/theora/theoraenc.c b/ext/theora/theoraenc.c index e3ef26e..40384c7 100644 --- a/ext/theora/theoraenc.c +++ b/ext/theora/theoraenc.c @@ -292,6 +292,12 @@ theora_buffer_from_packet (GstTheoraEnc * enc, ogg_packet * packet, GST_BUFFER_TIMESTAMP (buf) = timestamp; GST_BUFFER_DURATION (buf) = duration; + /* the second most significant bit of the first data byte is cleared + * for keyframes */ + if ((packet->packet[0] & 40) == 0) { + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_KEY_UNIT); + } + enc->packetno++; return buf; @@ -419,6 +425,7 @@ theora_enc_chain (GstPad * pad, GstData * data) yuv_buffer yuv; gint y_size; guchar *pixels; + gboolean first_packet = TRUE; pixels = GST_BUFFER_DATA (buf); @@ -438,8 +445,12 @@ theora_enc_chain (GstPad * pad, GstData * data) theora_encode_YUVin (&enc->state, &yuv); while (theora_encode_packetout (&enc->state, 0, &op)) { - GstClockTime out_time = - theora_granule_time (&enc->state, op.granulepos) * GST_SECOND; + GstClockTime out_time; + + if (first_packet) { + first_packet = FALSE; + } + out_time = theora_granule_time (&enc->state, op.granulepos) * GST_SECOND; theora_push_packet (enc, &op, out_time, GST_SECOND / enc->fps); } -- 2.7.4