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.
This commit is contained in:
Wim Taymans 2004-07-07 15:57:48 +00:00
parent 3b89a9be49
commit 3e712388ba
4 changed files with 47 additions and 12 deletions

View file

@ -1,3 +1,17 @@
2004-07-07 Wim Taymans <wim@fluendo.com>
* 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 <ds@schleef.org>
* gst/playback/Makefile.am: 'test' in bin_PROGRAMS? Are you

View file

@ -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;

View file

@ -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;

View file

@ -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);
}