From 10b1c060f9d2b6028ce4d3fc544a60ee6d7acc06 Mon Sep 17 00:00:00 2001 From: Reimar Döffinger Date: Sat, 18 Feb 2012 21:21:20 +0100 Subject: oggenc: fix condition when not to flush due to keyframe granule. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous condition of 0 page size was wrong, that would disable the mechanism for all frames at a start of a page, thus some keyframes still would not get their own granule. The real problem is that header packets must not be flushed, but they have (and must have) 0 granule and thus would be detected as keyframes. Add a separate parameter to mark header packets. Signed-off-by: Reimar Döffinger Signed-off-by: Justin Ruggles --- libavformat/oggenc.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'libavformat/oggenc.c') diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c index 1c040a7d3e..6ccbd58b17 100644 --- a/libavformat/oggenc.c +++ b/libavformat/oggenc.c @@ -192,7 +192,8 @@ static int ogg_buffer_page(AVFormatContext *s, OGGStreamContext *oggstream) } static int ogg_buffer_data(AVFormatContext *s, AVStream *st, - uint8_t *data, unsigned size, int64_t granule) + uint8_t *data, unsigned size, int64_t granule, + int header) { OGGStreamContext *oggstream = st->priv_data; OGGContext *ogg = s->priv_data; @@ -201,7 +202,7 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st, int i, segments, len, flush = 0; // Handles VFR by flushing page because this frame needs to have a timestamp - if (st->codec->codec_id == CODEC_ID_THEORA && + if (st->codec->codec_id == CODEC_ID_THEORA && !header && ogg_granule_to_timestamp(oggstream, granule) > ogg_granule_to_timestamp(oggstream, oggstream->last_granule) + 1) { if (oggstream->page.granule != -1) @@ -231,8 +232,8 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st, if (i == total_segments) page->granule = granule; - if (page->segments_count == 255 || - (ogg->pref_size > 0 && page->size >= ogg->pref_size)) { + if (!header && (page->segments_count == 255 || + (ogg->pref_size > 0 && page->size >= ogg->pref_size))) { ogg_buffer_page(s, oggstream); } } @@ -431,7 +432,7 @@ static int ogg_write_header(AVFormatContext *s) for (j = 0; j < s->nb_streams; j++) { OGGStreamContext *oggstream = s->streams[j]->priv_data; ogg_buffer_data(s, s->streams[j], oggstream->header[0], - oggstream->header_len[0], 0); + oggstream->header_len[0], 0, 1); oggstream->page.flags |= 2; // bos ogg_buffer_page(s, oggstream); } @@ -441,7 +442,7 @@ static int ogg_write_header(AVFormatContext *s) for (i = 1; i < 3; i++) { if (oggstream && oggstream->header_len[i]) ogg_buffer_data(s, st, oggstream->header[i], - oggstream->header_len[i], 0); + oggstream->header_len[i], 0, 1); } ogg_buffer_page(s, oggstream); } @@ -492,7 +493,7 @@ static int ogg_write_packet(AVFormatContext *s, AVPacket *pkt) } else granule = pkt->pts + pkt->duration; - ret = ogg_buffer_data(s, st, pkt->data, pkt->size, granule); + ret = ogg_buffer_data(s, st, pkt->data, pkt->size, granule, 0); if (ret < 0) return ret; -- cgit v1.2.3