lavc: Add support for increasing hardware frame pool sizes
authorMark Thompson <sw@jkqxz.net>
Mon, 29 Jan 2018 22:18:00 +0000 (22:18 +0000)
committerMark Thompson <sw@jkqxz.net>
Sun, 11 Feb 2018 22:00:33 +0000 (22:00 +0000)
AVCodecContext.extra_hw_frames is added to the size of hardware frame
pools created by libavcodec for APIs which require fixed-size pools.
This allows the user to keep references to a greater number of frames
after decode, which may be necessary for some use-cases.

It is also added to the initial_pool_size value returned by
avcodec_get_hw_frames_parameters() if a fixed-size pool is required.

doc/APIchanges
libavcodec/avcodec.h
libavcodec/decode.c
libavcodec/options_table.h
libavcodec/version.h

index 0bde3a0..d62f767 100644 (file)
@@ -13,6 +13,9 @@ libavutil:     2017-03-23
 
 API changes, most recent first:
 
+2018-02-xx - xxxxxxx - lavc 58.9.0 - avcodec.h
+  Add AVCodecContext.extra_hw_frames.
+
 2017-xx-xx - xxxxxxx - lavc 58.8.0 - avcodec.h
   Add const to AVCodecContext.hwaccel.
 
index 7eaa0c9..03a3d5b 100644 (file)
@@ -2739,6 +2739,20 @@ typedef struct AVCodecContext {
      *             AVCodecContext.get_format callback)
      */
     int hwaccel_flags;
+
+    /**
+     * Video decoding only.  Sets the number of extra hardware frames which
+     * the decoder will allocate for use by the caller.  This must be set
+     * before avcodec_open2() is called.
+     *
+     * Some hardware decoders require all frames that they will use for
+     * output to be defined in advance before decoding starts.  For such
+     * decoders, the hardware frame pool must therefore be of a fixed size.
+     * The extra frames set here are on top of any number that the decoder
+     * needs internally in order to operate normally (for example, frames
+     * used as reference pictures).
+     */
+    int extra_hw_frames;
 } AVCodecContext;
 
 /**
index 12a95d4..e024a32 100644 (file)
@@ -791,6 +791,15 @@ int avcodec_get_hw_frames_parameters(AVCodecContext *avctx,
 
     ret = hwa->frame_params(avctx, frames_ref);
     if (ret >= 0) {
+        AVHWFramesContext *frames_ctx = (AVHWFramesContext*)frames_ref->data;
+
+        if (frames_ctx->initial_pool_size) {
+            // If the user has requested that extra output surfaces be
+            // available then add them here.
+            if (avctx->extra_hw_frames > 0)
+                frames_ctx->initial_pool_size += avctx->extra_hw_frames;
+        }
+
         *out_frames_ref = frames_ref;
     } else {
         av_buffer_unref(&frames_ref);
index 925ef37..4b0a834 100644 (file)
@@ -419,6 +419,7 @@ static const AVOption avcodec_options[] = {
 {"side_data_only_packets", NULL, OFFSET(side_data_only_packets), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, A|V|E },
 #endif
 {"apply_cropping", NULL, OFFSET(apply_cropping), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, V | D },
+{"extra_hw_frames", "Number of extra hardware frames to allocate for the user", OFFSET(extra_hw_frames), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, V|D },
 {NULL},
 };
 
index 9b47110..36a0149 100644 (file)
@@ -28,7 +28,7 @@
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR 58
-#define LIBAVCODEC_VERSION_MINOR  8
+#define LIBAVCODEC_VERSION_MINOR  9
 #define LIBAVCODEC_VERSION_MICRO  0
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \