From: wm4 <[email protected]>

I feel like this has been beaten to death, but let's do it one more
time.

No code, this is just about the API itself.

I also found a way to make one of Mark T.'s RFCs do what I want, so
another proposal is included in the doxygen comments.
---
 libavcodec/avcodec.h | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 96 insertions(+)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 162f1abe4b..5e7735ae1a 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -3436,6 +3436,102 @@ int avcodec_open2(AVCodecContext *avctx, const AVCodec 
*codec, AVDictionary **op
  */
 int avcodec_close(AVCodecContext *avctx);
 
+/**
+ * Fill the given hw_frames struct with values adequate for hardware decoding.
+ * This is meant to get called from the get_format callback. There are a number
+ * of requirements for calling this function:
+ *
+ * - It must be called from get_format with the same avctx parameter if you
+ *   expect it to fill correct parameters. Calling it outside of get_format may
+ *   or may not work correctly, but only within get_format, enough of the video
+ *   bitstream will be parsed. This API function may access arbitrary
+ *   AVCodecContext fields (even non-public ones), so the API user cannot know
+ *   or ensure whether this will work correctly outside of get_format.
+ * - The hw_pix_fmt must be one of the choices suggested by get_format, and if
+ *   the user decides to use a hw_frames context prepared with this API 
function,
+ *   the user must return the same hw_pix_fmt from get_format. hw_pix_fmt
+ *   selects the hwaccel implementation, and most parameters are implementation
+ *   dependent.
+ * - The hw_frames context must be allocated from a device type that supports
+ *   the given hw_pix_fmt.
+ * - The hw_frames context must not have been initialized yet. The API function
+ *   may overwrite any fields in the hw_frames struct. A user can modify the
+ *   parameters after calling the function. Once that is done, the hw_frames
+ *   context must be initialized. Then set AVCodecContext.hw_frames_ctx to it.
+ *   All of this has to happen before returning from get_format.
+ * - It is perfectly possible to call this function, without actually using
+ *   the resulting hw_frames context. A common use-case might be reusing a
+ *   previously initialized hw_frames_ctx, and only calling this function on
+ *   a dummy hw_frames_ctx to check whether the codec requirements have 
changed.
+ *
+ * The function will set at least the following fields on hw_frames 
(potentially
+ * more, depending on hwaccel API):
+ *
+ * - Set the format field to hw_pix_fmt.
+ * - Set the sw_format field to the most suited and most versatile format. (An
+ *   implication is that this will require generic formats over opaque formats
+ *   with arbitrary restrictions, if possible.)
+ * - Set the width/height fields to the coded frame size, rounded up to the
+ *   minimum alignment.
+ * - Only _if_ the hwaccel requires a pre-allocated pool: set the 
initial_pool_size
+ *   field to the number of maximum reference surfaces possible with the codec,
+ *   plus 1 surface for the user to work (meaning the user can safely reference
+ *   at most 1 decoded surface at a time). If the hwaccel does not require pre-
+ *   allocation, the field is left to 0, and the codec will allocate new
+ *   surfaces on demand during decoding.
+ *
+ * This API is for decoding with hardware acceleration only. Calling this
+ * function is not a requirement. An API user can setup
+ * AVCodecContext.hw_frames_ctx manually, or set AVCodecContext.hw_device_ctx
+ * (which will make the hwaccel implementation setup hw_frames_ctx fully
+ * automatically).
+ *
+ * ---- To discuss: ----
+ *
+ * - Does this require the implementation to lookup the codec profile twice in
+ *   the worst case? (See vaapi, or if d3d11va checked whether it has to use
+ *   the opaque surface format on very restricted devices.)
+ * - Should there be a way to select difference performance or convenience
+ *   characteristics? For example, there might be cases where selecting an 
opaque
+ *   pixel format could be faster than nv12, or such. Or use cases like 
enabling
+ *   shared surfaces in an API-independent way. The current API wouldn't allow
+ *   passing such hints (except AV_HWACCEL_FLAG_* or new avctx fields).
+ * - Should there be a way to enable preallocation always?
+ * - Having to call this in get_format is unavoidable, but the fragile use 
rules
+ *   are still annoying. The earlier proposed "refine" callback would at least
+ *   have to advantage that the user could not call it at the "wrong" time.
+ *   Possible modification of the earlier proposal to make it roughly as 
powerful
+ *   as this proposed API:
+ *
+ *      struct AVCodecContext {
+ *          ...
+ *
+ *          / **
+ *           * Called when hwaccel hardware decoding is setup. 
avctx->hw_frames_ctx
+ *           * will be set to an unintialized context, but with essential 
parameters
+ *           * already filled (like format/width/height/etc.). The user can 
modify
+ *           * the parameters.
+ *           *
+ *           * If this function returns successfully, the user MUST initialize 
the
+ *           * avctx->hw_frames_ctx. Not doing so is an API usage error.
+ *           *
+ *           * It is explicitly possible to unref avctx->hw_frames_ctx in this
+ *           * callback, and to set it to a reference of an existing frames 
ctx.
+ *           * This allows reusing an existing frames context (for example to
+ *           * avoid expensive frame reallocations when performing seeks).
+ *           * /
+ *          int (*init_hw_frames)(AVCodecContext *avctx);
+ *      };
+ *
+ *   Quite similar to an earlier patch by Mark T., but actually allows reuse of
+ *   frames  contexts. (The API could be even more similar if there were a way
+ *   to detect whether a hw_frames_ctx was initialized. Being able to set this 
to
+ *   an initialized frames_ctx is the only difference.)
+ *   I have no idea what changing the hw_frames_ctx field means if frame 
threading
+ *   is enabled.
+ */
+int avcodec_fill_hw_frames_parameters(AVCodecContext *avctx, enum 
AVPixelFormat hw_pix_fmt, AVHWFramesContext *hw_frames);
+
 /**
  * Free all allocated data in the given subtitle struct.
  *
-- 
2.14.1

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to