From 2b91bd1baddb58d170c33c4b533d26379d72b8b4 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sat, 20 Nov 2010 19:02:50 -0800 Subject: [PATCH] oggparse: Set DELTA_UNIT on buffers --- ext/ogg/gstoggparse.c | 37 ++++++++++++++++++++++++++++++------- ext/ogg/gstoggstream.c | 11 ++++++----- ext/ogg/gstoggstream.h | 1 + 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/ext/ogg/gstoggparse.c b/ext/ogg/gstoggparse.c index 69e1e2e..e05c054 100644 --- a/ext/ogg/gstoggparse.c +++ b/ext/ogg/gstoggparse.c @@ -72,6 +72,8 @@ struct _GstOggParse ogg_sync_state sync; /* Ogg page synchronisation */ GstCaps *caps; /* Our src caps */ + + GstOggStream *video_stream; /* Stream used to construct delta_unit flags */ }; struct _GstOggParseClass @@ -155,6 +157,9 @@ gst_ogg_parse_new_stream (GstOggParse * parser, ogg_page * page) ret = ogg_stream_packetout (&stream->stream, &packet); if (ret == 1) { gst_ogg_stream_setup_map (stream, &packet); + if (stream->is_video) { + parser->video_stream = stream; + } } parser->oggstreams = g_slist_append (parser->oggstreams, stream); @@ -345,7 +350,7 @@ gst_ogg_parse_is_header (GstOggParse * ogg, GstOggStream * stream, static GstBuffer * gst_ogg_parse_buffer_from_page (ogg_page * page, - guint64 offset, gboolean delta, GstClockTime timestamp) + guint64 offset, gboolean keyframe, GstClockTime timestamp) { int size = page->header_len + page->body_len; GstBuffer *buf = gst_buffer_new_and_alloc (size); @@ -356,6 +361,9 @@ gst_ogg_parse_buffer_from_page (ogg_page * page, GST_BUFFER_TIMESTAMP (buf) = timestamp; GST_BUFFER_OFFSET (buf) = offset; GST_BUFFER_OFFSET_END (buf) = offset + size; + if (!keyframe) { + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); + } return buf; } @@ -402,6 +410,7 @@ gst_ogg_parse_chain (GstPad * pad, GstBuffer * buffer) #endif guint64 startoffset = ogg->offset; GstOggStream *stream; + gboolean keyframe; serialno = ogg_page_serialno (&page); stream = gst_ogg_parse_find_stream (ogg, serialno); @@ -409,10 +418,24 @@ gst_ogg_parse_chain (GstPad * pad, GstBuffer * buffer) GST_LOG_OBJECT (ogg, "Timestamping outgoing buffer as %" GST_TIME_FORMAT, GST_TIME_ARGS (buffertimestamp)); - buffertimestamp = gst_ogg_stream_get_end_time_for_granulepos (stream, - granule); - pagebuffer = gst_ogg_parse_buffer_from_page (&page, startoffset, FALSE, - buffertimestamp); + if (stream) { + buffertimestamp = gst_ogg_stream_get_end_time_for_granulepos (stream, + granule); + if (ogg->video_stream) { + if (stream == ogg->video_stream) { + keyframe = gst_ogg_stream_granulepos_is_key_frame (stream, granule); + } else { + keyframe = FALSE; + } + } else { + keyframe = TRUE; + } + } else { + buffertimestamp = GST_CLOCK_TIME_NONE; + keyframe = TRUE; + } + pagebuffer = gst_ogg_parse_buffer_from_page (&page, startoffset, + keyframe, buffertimestamp); /* We read out 'ret' bytes, so we set the next offset appropriately */ ogg->offset += ret; @@ -420,9 +443,9 @@ gst_ogg_parse_chain (GstPad * pad, GstBuffer * buffer) GST_LOG_OBJECT (ogg, "processing ogg page (serial %08x, pageno %ld, " "granule pos %" G_GUINT64_FORMAT ", bos %d, offset %" - G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT ")", + G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT ") keyframe=%d", serialno, ogg_page_pageno (&page), - granule, bos, startoffset, ogg->offset); + granule, bos, startoffset, ogg->offset, keyframe); if (ogg_page_bos (&page)) { /* If we've seen this serialno before, this is technically an error, diff --git a/ext/ogg/gstoggstream.c b/ext/ogg/gstoggstream.c index 82df0bb..e25b5ca 100644 --- a/ext/ogg/gstoggstream.c +++ b/ext/ogg/gstoggstream.c @@ -173,10 +173,8 @@ gst_ogg_stream_granule_to_granulepos (GstOggStream * pad, gint64 granule, keyframe_granule); } -#if 0 gboolean -gst_ogg_stream_packet_granulepos_is_key_frame (GstOggStream * pad, - gint64 granulepos) +gst_ogg_stream_granulepos_is_key_frame (GstOggStream * pad, gint64 granulepos) { if (granulepos == -1) { return FALSE; @@ -189,7 +187,6 @@ gst_ogg_stream_packet_granulepos_is_key_frame (GstOggStream * pad, return mappers[pad->map].is_key_frame_func (pad, granulepos); } -#endif gboolean gst_ogg_stream_packet_is_header (GstOggStream * pad, ogg_packet * packet) @@ -304,6 +301,7 @@ setup_theora_mapper (GstOggStream * pad, ogg_packet * packet) pad->granuleshift = ((GST_READ_UINT8 (data + 40) & 0x03) << 3) + (GST_READ_UINT8 (data + 41) >> 5); + pad->is_video = TRUE; pad->n_header_packets = 3; pad->frame_size = 1; @@ -362,7 +360,7 @@ is_keyframe_theora (GstOggStream * pad, gint64 granulepos) if (granulepos == (gint64) - 1) return FALSE; - frame_mask = (1 << (pad->granuleshift + 1)) - 1; + frame_mask = (1 << pad->granuleshift) - 1; return ((granulepos & frame_mask) == 0); } @@ -388,6 +386,7 @@ setup_dirac_mapper (GstOggStream * pad, ogg_packet * packet) return FALSE; } + pad->is_video = TRUE; pad->granulerate_n = header.frame_rate_numerator * 2; pad->granulerate_d = header.frame_rate_denominator; pad->granuleshift = 22; @@ -508,6 +507,7 @@ setup_vp8_mapper (GstOggStream * pad, ogg_packet * packet) fps_n = GST_READ_UINT32_BE (packet->packet + 18); fps_d = GST_READ_UINT32_BE (packet->packet + 22); + pad->is_video = TRUE; pad->is_vp8 = TRUE; pad->granulerate_n = fps_n; pad->granulerate_d = fps_d; @@ -1276,6 +1276,7 @@ setup_ogmvideo_mapper (GstOggStream * pad, ogg_packet * packet) GST_DEBUG ("time unit %d", GST_READ_UINT32_LE (data + 16)); GST_DEBUG ("samples per unit %d", GST_READ_UINT32_LE (data + 24)); + pad->is_video = TRUE; pad->granulerate_n = 10000000; time_unit = GST_READ_UINT64_LE (data + 17); if (time_unit > G_MAXINT || time_unit < G_MININT) { diff --git a/ext/ogg/gstoggstream.h b/ext/ogg/gstoggstream.h index a8bc2c8..54d2fa4 100644 --- a/ext/ogg/gstoggstream.h +++ b/ext/ogg/gstoggstream.h @@ -70,6 +70,7 @@ struct _GstOggStream GstCaps *caps; + gboolean is_video; /* vorbis stuff */ int nln_increments[4]; int nsn_increment; -- 2.7.4