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> 2004-07-06 David Schleef <ds@schleef.org>
* gst/playback/Makefile.am: 'test' in bin_PROGRAMS? Are you * 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")) if (!gst_library_load ("gsttags"))
return FALSE; 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 ())) gst_theora_dec_get_type ()))
return FALSE; return FALSE;

View File

@ -154,7 +154,7 @@ theora_dec_from_granulepos (GstTheoraDec * dec, GstFormat format, guint64 from,
guint64 * to) guint64 * to)
{ {
guint64 framecount; 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) if (dec->packetno < 1)
return FALSE; return FALSE;
@ -166,15 +166,14 @@ theora_dec_from_granulepos (GstTheoraDec * dec, GstFormat format, guint64 from,
switch (format) { switch (format) {
case GST_FORMAT_TIME: case GST_FORMAT_TIME:
*to = framecount = *to = framecount * (GST_SECOND * dec->info.fps_denominator /
from * GST_SECOND * dec->info.fps_denominator / dec->info.fps_numerator);
dec->info.fps_numerator;
break; break;
case GST_FORMAT_DEFAULT: case GST_FORMAT_DEFAULT:
*to = framecount; *to = framecount;
break; break;
case GST_FORMAT_BYTES: 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; break;
default: default:
return FALSE; 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)); GstTheoraDec *dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
GstFormat my_format = GST_FORMAT_DEFAULT; GstFormat my_format = GST_FORMAT_DEFAULT;
if (!gst_pad_query (GST_PAD_PEER (dec->sinkpad), query, &my_format, if (query == GST_QUERY_POSITION) {
&granulepos)) granulepos = dec->granulepos;
return FALSE; } 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)) if (!theora_dec_from_granulepos (dec, *format, granulepos, value))
return FALSE; return FALSE;
@ -321,6 +324,7 @@ theora_dec_chain (GstPad * pad, GstData * data)
GstBuffer *buf; GstBuffer *buf;
GstTheoraDec *dec; GstTheoraDec *dec;
ogg_packet packet; ogg_packet packet;
guint64 offset_end;
dec = GST_THEORA_DEC (gst_pad_get_parent (pad)); dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
if (GST_IS_EVENT (data)) { if (GST_IS_EVENT (data)) {
@ -329,10 +333,16 @@ theora_dec_chain (GstPad * pad, GstData * data)
} }
buf = GST_BUFFER (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 */ /* make ogg_packet out of the buffer */
packet.packet = GST_BUFFER_DATA (buf); packet.packet = GST_BUFFER_DATA (buf);
packet.bytes = GST_BUFFER_SIZE (buf); packet.bytes = GST_BUFFER_SIZE (buf);
packet.granulepos = GST_BUFFER_OFFSET_END (buf); packet.granulepos = dec->granulepos;
packet.packetno = dec->packetno++; packet.packetno = dec->packetno++;
packet.b_o_s = (packet.packetno == 0) ? 1 : 0; packet.b_o_s = (packet.packetno == 0) ? 1 : 0;
packet.e_o_s = 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_TIMESTAMP (buf) = timestamp;
GST_BUFFER_DURATION (buf) = duration; 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++; enc->packetno++;
return buf; return buf;
@ -419,6 +425,7 @@ theora_enc_chain (GstPad * pad, GstData * data)
yuv_buffer yuv; yuv_buffer yuv;
gint y_size; gint y_size;
guchar *pixels; guchar *pixels;
gboolean first_packet = TRUE;
pixels = GST_BUFFER_DATA (buf); pixels = GST_BUFFER_DATA (buf);
@ -438,8 +445,12 @@ theora_enc_chain (GstPad * pad, GstData * data)
theora_encode_YUVin (&enc->state, &yuv); theora_encode_YUVin (&enc->state, &yuv);
while (theora_encode_packetout (&enc->state, 0, &op)) { while (theora_encode_packetout (&enc->state, 0, &op)) {
GstClockTime out_time = GstClockTime out_time;
theora_granule_time (&enc->state, op.granulepos) * GST_SECOND;
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); theora_push_packet (enc, &op, out_time, GST_SECOND / enc->fps);
} }