aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>2012-02-18 21:21:20 +0100
committerJustin Ruggles <justin.ruggles@gmail.com>2012-03-30 16:32:16 -0400
commit10b1c060f9d2b6028ce4d3fc544a60ee6d7acc06 (patch)
tree18c9ed35f5e0818e05ac1df4c959fa1d6651efe6
parented3e1b485acfba72ac9741407836c6125559d567 (diff)
downloadffmpeg-10b1c060f9d2b6028ce4d3fc544a60ee6d7acc06.tar.gz
oggenc: fix condition when not to flush due to keyframe granule.
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 <Reimar.Doeffinger@gmx.de> Signed-off-by: Justin Ruggles <justin.ruggles@gmail.com>
-rw-r--r--libavformat/oggenc.c15
1 files changed, 8 insertions, 7 deletions
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;