oggenc: fix condition when not to flush due to keyframe granule.
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>
Sat, 18 Feb 2012 20:21:20 +0000 (21:21 +0100)
committerReimar Döffinger <Reimar.Doeffinger@gmx.de>
Sat, 18 Feb 2012 20:35:49 +0000 (21:35 +0100)
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>
libavformat/oggenc.c
tests/ref/lavf-fate/ogg_vp3

index 315b8da..c92ee0c 100644 (file)
@@ -195,7 +195,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;
@@ -207,9 +208,9 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st,
     // For theora, keyframes also need to have a timestamp to correctly mark
     // them as such, otherwise seeking will not work correctly at the very
     // least with old libogg versions.
-    // Do not try to flush empty packets though, that will create broken files.
+    // Do not try to flush header packets though, that will create broken files.
     if (st->codec->codec_id == CODEC_ID_THEORA &&
-        oggstream->page.size &&
+        !header &&
         (ogg_granule_to_timestamp(oggstream, granule) >
          ogg_granule_to_timestamp(oggstream, oggstream->last_granule) + 1 ||
          ogg_key_granule(oggstream, granule))) {
@@ -440,7 +441,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);
     }
@@ -450,7 +451,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);
     }
@@ -501,7 +502,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;
 
index 9f36eee..635dd3e 100644 (file)
@@ -1,3 +1,3 @@
-cf4184d736685fb698bb3be4656353bd *./tests/data/lavf-fate/lavf.ogg
-417698 ./tests/data/lavf-fate/lavf.ogg
+adbe6c30bdfe934dc5ae397f4db2960d *./tests/data/lavf-fate/lavf.ogg
+417644 ./tests/data/lavf-fate/lavf.ogg
 ./tests/data/lavf-fate/lavf.ogg CRC=0x45a9df79