+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
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;
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;
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;
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;
GstBuffer *buf;
GstTheoraDec *dec;
ogg_packet packet;
+ guint64 offset_end;
dec = GST_THEORA_DEC (gst_pad_get_parent (pad));
if (GST_IS_EVENT (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;
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;
yuv_buffer yuv;
gint y_size;
guchar *pixels;
+ gboolean first_packet = TRUE;
pixels = GST_BUFFER_DATA (buf);
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);
}