oggparse: Set DELTA_UNIT on buffers

This commit is contained in:
David Schleef 2010-11-20 19:02:50 -08:00
parent a2e896df66
commit 2b91bd1bad
3 changed files with 37 additions and 12 deletions

View file

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

View file

@ -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) {

View file

@ -70,6 +70,7 @@ struct _GstOggStream
GstCaps *caps;
gboolean is_video;
/* vorbis stuff */
int nln_increments[4];
int nsn_increment;