]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/ivfenc.c
configure: add -lvulkan to libglslang's lib flags
[ffmpeg] / libavformat / ivfenc.c
index 0ce4a85171f86d1103e90ee1550b14d3036bb91c..5aa8bd12574f95d6e647af7ab6f3a24406527569 100644 (file)
@@ -23,7 +23,7 @@
 
 typedef struct IVFEncContext {
     unsigned frame_cnt;
-    uint64_t last_pts, sum_delta_pts;
+    uint64_t last_pts, sum_delta_pts, last_pkt_duration;
 } IVFEncContext;
 
 static int ivf_init(AVFormatContext *s)
@@ -43,6 +43,16 @@ static int ivf_init(AVFormatContext *s)
         return AVERROR(EINVAL);
     }
 
+    if (par->codec_id == AV_CODEC_ID_VP9) {
+        int ret = ff_stream_add_bitstream_filter(s->streams[0], "vp9_superframe", NULL);
+        if (ret < 0)
+            return ret;
+    } else if (par->codec_id == AV_CODEC_ID_AV1) {
+        int ret = ff_stream_add_bitstream_filter(s->streams[0], "av1_metadata", "td=insert");
+        if (ret < 0)
+            return ret;
+    }
+
     return 0;
 }
 
@@ -76,6 +86,7 @@ static int ivf_write_packet(AVFormatContext *s, AVPacket *pkt)
     avio_write(pb, pkt->data, pkt->size);
     if (ctx->frame_cnt)
         ctx->sum_delta_pts += pkt->pts - ctx->last_pts;
+    ctx->last_pkt_duration = pkt->duration;
     ctx->frame_cnt++;
     ctx->last_pts = pkt->pts;
 
@@ -87,12 +98,15 @@ static int ivf_write_trailer(AVFormatContext *s)
     AVIOContext *pb = s->pb;
     IVFEncContext *ctx = s->priv_data;
 
-    if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && ctx->frame_cnt > 1) {
+    if ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
+        (ctx->frame_cnt > 1 || (ctx->frame_cnt == 1 && ctx->last_pkt_duration))) {
         int64_t end = avio_tell(pb);
 
         avio_seek(pb, 24, SEEK_SET);
         // overwrite the "length" field (duration)
-        avio_wl32(pb, ctx->frame_cnt * ctx->sum_delta_pts / (ctx->frame_cnt - 1));
+        avio_wl32(pb, ctx->last_pkt_duration ?
+                  ctx->sum_delta_pts + ctx->last_pkt_duration :
+                  ctx->frame_cnt * ctx->sum_delta_pts / (ctx->frame_cnt - 1));
         avio_wl32(pb, 0); // zero out unused bytes
         avio_seek(pb, end, SEEK_SET);
     }
@@ -100,19 +114,6 @@ static int ivf_write_trailer(AVFormatContext *s)
     return 0;
 }
 
-static int ivf_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt)
-{
-    int ret = 1;
-    AVStream *st = s->streams[pkt->stream_index];
-
-    if (st->codecpar->codec_id == AV_CODEC_ID_VP9)
-        ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
-    else if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
-        ret = ff_stream_add_bitstream_filter(st, "av1_metadata", "td=insert");
-
-    return ret;
-}
-
 static const AVCodecTag codec_ivf_tags[] = {
     { AV_CODEC_ID_VP8,  MKTAG('V', 'P', '8', '0') },
     { AV_CODEC_ID_VP9,  MKTAG('V', 'P', '9', '0') },
@@ -120,7 +121,7 @@ static const AVCodecTag codec_ivf_tags[] = {
     { AV_CODEC_ID_NONE, 0 }
 };
 
-AVOutputFormat ff_ivf_muxer = {
+const AVOutputFormat ff_ivf_muxer = {
     .priv_data_size = sizeof(IVFEncContext),
     .name         = "ivf",
     .long_name    = NULL_IF_CONFIG_SMALL("On2 IVF"),
@@ -131,6 +132,5 @@ AVOutputFormat ff_ivf_muxer = {
     .write_header = ivf_write_header,
     .write_packet = ivf_write_packet,
     .write_trailer = ivf_write_trailer,
-    .check_bitstream = ivf_check_bitstream,
     .codec_tag    = (const AVCodecTag* const []){ codec_ivf_tags, 0 },
 };