mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
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:
parent
3b89a9be49
commit
3e712388ba
4 changed files with 47 additions and 12 deletions
14
ChangeLog
14
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue