Browse Source

avcodec: add AVCodecContext.frame_num as 64 bit variant to frame_number

Frame counters can overflow relatively easily (INT_MAX number of frames is
slightly more than 1 year for 60 fps content), so make sure we use 64 bit
values for them.

Also deprecate the old 32 bit frame_number attribute.

Signed-off-by: Marton Balint <cus@passwd.hu>
Marton Balint 2 years ago
parent
commit
6b6f7db819

+ 4 - 0
doc/APIchanges

@@ -2,6 +2,10 @@ The last version increases of all libraries were on 2023-02-09
 
 API changes, most recent first:
 
+2023-02-13 - xxxxxxxxxx - lavc 60.2.100 - avcodec.h
+  Add AVCodecContext.frame_num as a 64bit version of frame_number.
+  Deprecate AVCodecContext.frame_number.
+
 2023-02-12 - xxxxxxxxxx - lavfi 9.1.100 - avfilter.h
   Add filtergraph segment parsing API.
   New structs:

+ 2 - 2
doc/examples/decode_video.c

@@ -70,12 +70,12 @@ static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
             exit(1);
         }
 
-        printf("saving frame %3d\n", dec_ctx->frame_number);
+        printf("saving frame %3"PRId64"\n", dec_ctx->frame_num);
         fflush(stdout);
 
         /* the picture is allocated by the decoder. no need to
            free it */
-        snprintf(buf, sizeof(buf), "%s-%d", filename, dec_ctx->frame_number);
+        snprintf(buf, sizeof(buf), "%s-%"PRId64, filename, dec_ctx->frame_num);
         pgm_save(frame->data[0], frame->linesize[0],
                  frame->width, frame->height, buf);
     }

+ 1 - 1
fftools/ffmpeg.c

@@ -2115,7 +2115,7 @@ static int decode(InputStream *ist, AVCodecContext *avctx,
             fd      = (FrameData*)frame->opaque_ref->data;
             fd->pts = frame->pts;
             fd->tb  = avctx->pkt_timebase;
-            fd->idx = avctx->frame_number - 1;
+            fd->idx = avctx->frame_num - 1;
         }
 
         *got_frame = 1;

+ 4 - 4
libavcodec/4xm.c

@@ -875,7 +875,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
         }
 
         for (i = 0; i < CFRAME_BUFFER_COUNT; i++)
-            if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
+            if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_num)
                 av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n",
                        f->cfrm[i].id);
 
@@ -910,9 +910,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
             buf        = cfrm->data;
             frame_size = cfrm->size;
 
-            if (id != avctx->frame_number)
-                av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n",
-                       id, avctx->frame_number);
+            if (id != avctx->frame_num)
+                av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %"PRId64"\n",
+                       id, avctx->frame_num);
 
             if (f->version <= 1)
                 return AVERROR_INVALIDDATA;

+ 1 - 1
libavcodec/8svx.c

@@ -151,7 +151,7 @@ static int eightsvx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
 
     *got_frame_ptr = 1;
 
-    return ((avctx->frame_number == 0) * hdr_size + buf_size) * channels;
+    return ((avctx->frame_num == 0) * hdr_size + buf_size) * channels;
 }
 
 static av_cold int eightsvx_decode_init(AVCodecContext *avctx)

+ 2 - 2
libavcodec/aacenc.c

@@ -854,7 +854,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
     if (s->psypp)
         ff_psy_preprocess(s->psypp, s->planar_samples, s->channels);
 
-    if (!avctx->frame_number)
+    if (!avctx->frame_num)
         return 0;
 
     start_ch = 0;
@@ -958,7 +958,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
     do {
         init_put_bits(&s->pb, avpkt->data, avpkt->size);
 
-        if ((avctx->frame_number & 0xFF)==1 && !(avctx->flags & AV_CODEC_FLAG_BITEXACT))
+        if ((avctx->frame_num & 0xFF)==1 && !(avctx->flags & AV_CODEC_FLAG_BITEXACT))
             put_bitstream_info(s, LIBAVCODEC_IDENT);
         start_ch = 0;
         target_bits = 0;

+ 1 - 1
libavcodec/ansi.c

@@ -364,7 +364,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
 
     if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
         return ret;
-    if (!avctx->frame_number) {
+    if (!avctx->frame_num) {
         for (i=0; i<avctx->height; i++)
             memset(s->frame->data[0]+ i*s->frame->linesize[0], 0, avctx->width);
         memset(s->frame->data[1], 0, AVPALETTE_SIZE);

+ 2 - 2
libavcodec/atrac3plus.c

@@ -1391,9 +1391,9 @@ static int decode_band_numwavs(GetBitContext *gb, Atrac3pChanUnitCtx *ctx,
         if (band_has_tones[sb]) {
             if (ctx->waves_info->tones_index + dst[sb].num_wavs > 48) {
                 av_log(avctx, AV_LOG_ERROR,
-                       "Too many tones: %d (max. 48), frame: %d!\n",
+                       "Too many tones: %d (max. 48), frame: %"PRId64"!\n",
                        ctx->waves_info->tones_index + dst[sb].num_wavs,
-                       avctx->frame_number);
+                       avctx->frame_num);
                 return AVERROR_INVALIDDATA;
             }
             dst[sb].start_index           = ctx->waves_info->tones_index;

+ 6 - 1
libavcodec/avcodec.c

@@ -266,7 +266,12 @@ FF_ENABLE_DEPRECATION_WARNINGS
         goto free_and_end;
     }
 
-    avctx->frame_number = 0;
+    avctx->frame_num = 0;
+#if FF_API_AVCTX_FRAME_NUMBER
+FF_DISABLE_DEPRECATION_WARNINGS
+    avctx->frame_number = avctx->frame_num;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
     avctx->codec_descriptor = avcodec_descriptor_get(avctx->codec_id);
 
     if ((avctx->codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) &&

+ 15 - 0
libavcodec/avcodec.h

@@ -1061,6 +1061,7 @@ typedef struct AVCodecContext {
      */
     int frame_size;
 
+#if FF_API_AVCTX_FRAME_NUMBER
     /**
      * Frame counter, set by libavcodec.
      *
@@ -1069,8 +1070,11 @@ typedef struct AVCodecContext {
      *
      *   @note the counter is not incremented if encoding/decoding resulted in
      *   an error.
+     *   @deprecated use frame_num instead
      */
+    attribute_deprecated
     int frame_number;
+#endif
 
     /**
      * number of bytes per packet if constant and known or 0
@@ -2048,6 +2052,17 @@ typedef struct AVCodecContext {
      *             The decoder can then override during decoding as needed.
      */
     AVChannelLayout ch_layout;
+
+    /**
+     * Frame counter, set by libavcodec.
+     *
+     * - decoding: total number of frames returned from the decoder so far.
+     * - encoding: total number of frames passed to the encoder so far.
+     *
+     *   @note the counter is not incremented if encoding/decoding resulted in
+     *   an error.
+     */
+    int64_t frame_num;
 } AVCodecContext;
 
 /**

Some files were not shown because too many files changed in this diff