[FFmpeg-devel] Added HW H.264 and HEVC encoding for AMD GPUs based on AMF SDK

Philip Langdale philipl at overt.org
Mon Nov 27 04:48:21 EET 2017


On Wen, 22 Nov 2017 18:28:47 -0500
mmironov <mikhail.mironov at amd.com> wrote:

> From c669277afd764903d3da09d92a263d0fb58e24b1 Mon Sep 17 00:00:00 2001
> From: mmironov <mikhail.mironov at amd.com>
> Date: Tue, 14 Nov 2017 17:54:24 -0500
> Subject: [PATCH] Added HW H.264 and HEVC encoding for AMD GPUs based
> on AMF SDK
> 
> Signed-off-by: mmironov <mikhail.mironov at amd.com>
> ---
>  Changelog                |    1 +
>  compat/amd/amfsdkenc.h   | 1755
> ++++++++++++++++++++++++++++++++++++++++++++++
> configure                |   18 +- libavcodec/Makefile      |    4 +
>  libavcodec/allcodecs.c   |    2 +
>  libavcodec/amfenc.c      |  596 ++++++++++++++++
>  libavcodec/amfenc.h      |  143 ++++
>  libavcodec/amfenc_h264.c |  397 +++++++++++
>  libavcodec/amfenc_hevc.c |  327 +++++++++
>  9 files changed, 3242 insertions(+), 1 deletion(-)
>  create mode 100644 compat/amd/amfsdkenc.h
>  create mode 100644 libavcodec/amfenc.c
>  create mode 100644 libavcodec/amfenc.h
>  create mode 100644 libavcodec/amfenc_h264.c
>  create mode 100644 libavcodec/amfenc_hevc.c
> 
> diff --git a/Changelog b/Changelog
> index 68829f2..e5e5ffd 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -15,6 +15,7 @@ version <next>:
>  - Raw aptX muxer and demuxer
>  - NVIDIA NVDEC-accelerated H.264, HEVC and VP9 hwaccel decoding
>  - Intel QSV-accelerated overlay filter
> +- AMD NW H.264 and HEVC encoders
>  
>  
>  version 3.4:
> diff --git a/compat/amd/amfsdkenc.h b/compat/amd/amfsdkenc.h
> new file mode 100644
> index 0000000..282656d
> --- /dev/null
> +++ b/compat/amd/amfsdkenc.h
> @@ -0,0 +1,1755 @@
> +// 
> +// MIT license 
> +// 
> +// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights
> reserved. +//
> +// Permission is hereby granted, free of charge, to any person
> obtaining a copy +// of this software and associated documentation
> files (the "Software"), to deal +// in the Software without
> restriction, including without limitation the rights +// to use,
> copy, modify, merge, publish, distribute, sublicense, and/or sell +//
> copies of the Software, and to permit persons to whom the Software is
> +// furnished to do so, subject to the following conditions: +//
> +// The above copyright notice and this permission notice shall be
> included in +// all copies or substantial portions of the Software.
> +//
> +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND
> NONINFRINGEMENT.  IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT
> HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY,
> WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> DEALINGS IN +// THE SOFTWARE. +//
> +
> +// Reduced AMF API
> +//
> +// Full version of AMF SDK and the latest version of this file 
> +// can be found at https://github.com/GPUOpen-LibrariesAndSDKs/AMF
> +
> +#ifndef __AMF_SDK_Enc_h__
> +#define __AMF_SDK_Enc_h__
> +#pragma once
> +
> +//-----------------------------------------------------------------------------
> +// Platform.h
> +//-----------------------------------------------------------------------------
> +//----------------------------------------------------------------------------------------------
> +// export declaration
> +//----------------------------------------------------------------------------------------------
> +#ifdef _WIN32
> +#if defined(AMF_CORE_STATIC)
> +#define AMF_CORE_LINK
> +#else
> +#if defined(AMF_CORE_EXPORTS)
> +#define AMF_CORE_LINK __declspec(dllexport)
> +#else
> +#define AMF_CORE_LINK __declspec(dllimport)
> +#endif
> +#endif
> +#else // #ifdef _WIN32
> +#define AMF_CORE_LINK
> +#endif // #ifdef _WIN32
> +
> +#define AMF_MACRO_STRING2(x) #x
> +#define AMF_MACRO_STRING(x) AMF_MACRO_STRING2(x)
> +
> +#define AMF_TODO(_todo) (__FILE__ "(" AMF_MACRO_STRING(__LINE__) "):
> TODO: "_todo) +
> +
> +#if defined(__GNUC__) || defined(__clang__)
> +#define AMF_ALIGN(n) __attribute__((aligned(n)))
> +#elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
> +#define AMF_ALIGN(n) __declspec(align(n))
> +#else
> +#define AMF_ALIGN(n)
> +//     #error Need to define AMF_ALIGN
> +#endif
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +
> +#if defined(_WIN32)
> +
> +
> +#ifndef NOMINMAX
> +#define NOMINMAX
> +#endif
> +#define AMF_STD_CALL            __stdcall
> +#define AMF_CDECL_CALL          __cdecl
> +#define AMF_FAST_CALL           __fastcall
> +#if defined(__GNUC__) || defined(__clang__)
> +#define AMF_INLINE              inline
> +#define AMF_FORCEINLINE         inline
> +#else
> +#define AMF_INLINE              __inline
> +#define AMF_FORCEINLINE         __forceinline
> +#endif
> +#define AMF_NO_VTABLE           __declspec(novtable)
> +
> +#define AMFPRId64   "I64d"
> +#define LPRId64    L"I64d"
> +
> +#define AMFPRIud64   "Iu64d"
> +#define LPRIud64    L"Iu64d"
> +
> +#define AMFPRIx64   "I64x"
> +#define LPRIx64    L"I64x"
> +
> +#else // !WIN32 - Linux and Mac
> +
> +#define AMF_STD_CALL
> +#define AMF_CDECL_CALL
> +#define AMF_FAST_CALL
> +#if defined(__GNUC__) || defined(__clang__)
> +#define AMF_INLINE              inline
> +#define AMF_FORCEINLINE         inline
> +#else
> +#define AMF_INLINE              __inline__
> +#define AMF_FORCEINLINE         __inline__
> +#endif
> +#define AMF_NO_VTABLE
> +
> +#if !defined(AMFPRId64)
> +#define AMFPRId64    "lld"
> +#define LPRId64     L"lld"
> +
> +#define AMFPRIud64    "ulld"
> +#define LPRIud64     L"ulld"
> +
> +#define AMFPRIx64    "llx"
> +#define LPRIx64     L"llx"
> +#endif
> +
> +#endif // WIN32
> +
> +
> +#if defined(_MSC_VER)
> +#define AMF_WEAK __declspec( selectany ) 
> +#elif defined (__GCC__) || defined(__clang__)//GCC or CLANG
> +#define AMF_WEAK __attribute__((weak))
> +#endif
> +
> +#define amf_countof(x) (sizeof(x) / sizeof(x[0]))
> +
> +//-------------------------------------------------------------------------------------------------
> +// basic data types
> +//-------------------------------------------------------------------------------------------------
> +typedef     int64_t             amf_int64;
> +typedef     int32_t             amf_int32;
> +typedef     int16_t             amf_int16;
> +typedef     int8_t              amf_int8;
> +
> +typedef     uint64_t            amf_uint64;
> +typedef     uint32_t            amf_uint32;
> +typedef     uint16_t            amf_uint16;
> +typedef     uint8_t             amf_uint8;
> +typedef     size_t              amf_size;
> +
> +typedef     void*               amf_handle;
> +typedef     double              amf_double;
> +typedef     float               amf_float;
> +
> +typedef     void                amf_void;
> +
> +#if defined(__cplusplus)
> +typedef     bool                amf_bool;
> +#else
> +typedef     amf_uint8           amf_bool;
> +#define     true                1 
> +#define     false               0 
> +#endif
> +
> +typedef     long                amf_long;
> +typedef     int                 amf_int;
> +typedef     unsigned long       amf_ulong;
> +typedef     unsigned int        amf_uint;
> +
> +typedef     amf_int64           amf_pts;     // in 100 nanosecs
> +
> +#define AMF_SECOND          10000000L    // 1 second in 100
> nanoseconds +
> +#define AMF_MIN(a, b) ((a) < (b) ? (a) : (b))
> +#define AMF_MAX(a, b) ((a) > (b) ? (a) : (b))
> +
> +#if defined(_WIN32)
> +#define PATH_SEPARATOR_WSTR         L"\\"
> +#define PATH_SEPARATOR_WCHAR        L'\\'
> +#elif defined(__linux) // Linux
> +#define PATH_SEPARATOR_WSTR          L"/"
> +#define PATH_SEPARATOR_WCHAR         L'/'
> +#endif
> +
> +typedef struct AMFRect
> +{
> +    amf_int32 left;
> +    amf_int32 top;
> +    amf_int32 right;
> +    amf_int32 bottom;
> +} AMFRect;
> +
> +static AMF_INLINE struct AMFRect AMFConstructRect(amf_int32 left,
> amf_int32 top, amf_int32 right, amf_int32 bottom) +{
> +    struct AMFRect object = { left, top, right, bottom };
> +    return object;
> +}
> +
> +typedef struct AMFSize
> +{
> +    amf_int32 width;
> +    amf_int32 height;
> +} AMFSize;
> +
> +static AMF_INLINE struct AMFSize AMFConstructSize(amf_int32 width,
> amf_int32 height) +{
> +    struct AMFSize object = { width, height };
> +    return object;
> +}
> +
> +typedef struct AMFPoint
> +{
> +    amf_int32 x;
> +    amf_int32 y;
> +} AMFPoint;
> +
> +static AMF_INLINE struct AMFPoint AMFConstructPoint(amf_int32 x,
> amf_int32 y) +{
> +    struct AMFPoint object = { x, y };
> +    return object;
> +}
> +
> +typedef struct AMFRate
> +{
> +    amf_uint32 num;
> +    amf_uint32 den;
> +} AMFRate;
> +
> +static AMF_INLINE struct AMFRate AMFConstructRate(amf_uint32 num,
> amf_uint32 den) +{
> +    struct AMFRate object = { num, den };
> +    return object;
> +}
> +
> +typedef struct AMFRatio
> +{
> +    amf_uint32 num;
> +    amf_uint32 den;
> +} AMFRatio;
> +
> +static AMF_INLINE struct AMFRatio AMFConstructRatio(amf_uint32 num,
> amf_uint32 den) +{
> +    struct AMFRatio object = { num, den };
> +    return object;
> +}
> +
> +#pragma pack(push, 1)
> +#if defined(_MSC_VER)
> +#pragma warning( push )
> +#endif
> +#if defined(WIN32)
> +#if defined(_MSC_VER)
> +#pragma warning(disable : 4200)
> +#pragma warning(disable : 4201)
> +#endif
> +#endif
> +typedef struct AMFColor
> +{
> +    union
> +    {
> +        struct
> +        {
> +            amf_uint8 r;
> +            amf_uint8 g;
> +            amf_uint8 b;
> +            amf_uint8 a;
> +        };
> +        amf_uint32 rgba;
> +    };
> +} AMFColor;
> +#if defined(_MSC_VER)
> +#pragma warning( pop )
> +#endif
> +#pragma pack(pop)
> +
> +
> +static AMF_INLINE struct AMFColor AMFConstructColor(amf_uint8 r,
> amf_uint8 g, amf_uint8 b, amf_uint8 a) +{
> +    struct AMFColor object;
> +    object.r = r;
> +    object.g = g;
> +    object.b = b;
> +    object.a = a;
> +    return object;
> +}
> +
> +#if defined(_WIN32)
> +#include <combaseapi.h>
> +
> +#if defined(__cplusplus)
> +extern "C"
> +{
> +#endif
> +    // allocator
> +    static AMF_INLINE void* AMF_CDECL_CALL
> amf_variant_alloc(amf_size count)
> +    {
> +        return CoTaskMemAlloc(count);
> +    }
> +    static AMF_INLINE void AMF_CDECL_CALL amf_variant_free(void* ptr)
> +    {
> +        CoTaskMemFree(ptr);
> +    }
> +#if defined(__cplusplus)
> +}
> +#endif
> +
> +#else // defined(_WIN32)
> +#include <stdlib.h>
> +#if defined(__cplusplus)
> +extern "C"
> +{
> +#endif
> +    // allocator
> +    static AMF_INLINE void* AMF_CDECL_CALL
> amf_variant_alloc(amf_size count)
> +    {
> +        return malloc(count);
> +    }
> +    static AMF_INLINE void AMF_CDECL_CALL amf_variant_free(void* ptr)
> +    {
> +        free(ptr);
> +    }
> +#if defined(__cplusplus)
> +}
> +#endif
> +#endif // defined(_WIN32)
> +
> +
> +typedef struct AMFGuid
> +{
> +    amf_uint32 data1;
> +    amf_uint16 data2;
> +    amf_uint16 data3;
> +    amf_uint8 data41;
> +    amf_uint8 data42;
> +    amf_uint8 data43;
> +    amf_uint8 data44;
> +    amf_uint8 data45;
> +    amf_uint8 data46;
> +    amf_uint8 data47;
> +    amf_uint8 data48;
> +} AMFGuid;
> +
> +//-----------------------------------------------------------------------------
> +// Version.h
> +//-----------------------------------------------------------------------------
> +#define AMF_MAKE_FULL_VERSION(VERSION_MAJOR, VERSION_MINOR,
> VERSION_RELEASE, VERSION_BUILD_NUM)    ( ((amf_uint64)(VERSION_MAJOR)
> << 48ull) | ((amf_uint64)(VERSION_MINOR) << 32ull) |
> ((amf_uint64)(VERSION_RELEASE) << 16ull)  |
> (amf_uint64)(VERSION_BUILD_NUM)) + +#define
> AMF_GET_MAJOR_VERSION(x)      ((x >> 48ull) & 0xFFFF) +#define
> AMF_GET_MINOR_VERSION(x)      ((x >> 32ull) & 0xFFFF) +#define
> AMF_GET_SUBMINOR_VERSION(x)   ((x >> 16ull) & 0xFFFF) +#define
> AMF_GET_BUILD_VERSION(x)      ((x >>  0ull) & 0xFFFF) + +#define
> AMF_VERSION_MAJOR       1 +#define AMF_VERSION_MINOR       4 +#define
> AMF_VERSION_RELEASE     4 +#define AMF_VERSION_BUILD_NUM   0
> +
> +#define AMF_FULL_VERSION AMF_MAKE_FULL_VERSION(AMF_VERSION_MAJOR,
> AMF_VERSION_MINOR, AMF_VERSION_RELEASE, AMF_VERSION_BUILD_NUM) +
> +//-----------------------------------------------------------------------------
> +// Result.h
> +//-----------------------------------------------------------------------------
> +//----------------------------------------------------------------------------------------------
> +// result codes
> +//----------------------------------------------------------------------------------------------
> +
> +typedef enum AMF_RESULT
> +{
> +    AMF_OK                                   = 0,
> +    AMF_FAIL                                    ,
> +
> +// common errors
> +    AMF_UNEXPECTED                              ,
> +
> +    AMF_ACCESS_DENIED                           ,
> +    AMF_INVALID_ARG                             ,
> +    AMF_OUT_OF_RANGE                            ,
> +
> +    AMF_OUT_OF_MEMORY                           ,
> +    AMF_INVALID_POINTER                         ,
> +
> +    AMF_NO_INTERFACE                            ,
> +    AMF_NOT_IMPLEMENTED                         ,
> +    AMF_NOT_SUPPORTED                           ,
> +    AMF_NOT_FOUND                               ,
> +
> +    AMF_ALREADY_INITIALIZED                     ,
> +    AMF_NOT_INITIALIZED                         ,
> +
> +    AMF_INVALID_FORMAT                          ,// invalid data
> format +
> +    AMF_WRONG_STATE                             ,
> +    AMF_FILE_NOT_OPEN                           ,// cannot open file
> +
> +// device common codes
> +    AMF_NO_DEVICE                               ,
> +
> +// device directx
> +    AMF_DIRECTX_FAILED                          ,
> +// device opencl 
> +    AMF_OPENCL_FAILED                           ,
> +// device opengl 
> +    AMF_GLX_FAILED                              ,//failed to use GLX
> +// device XV 
> +    AMF_XV_FAILED                               , //failed to use Xv
> extension +// device alsa
> +    AMF_ALSA_FAILED                             ,//failed to use ALSA
> +
> +// component common codes
> +
> +    //result codes
> +    AMF_EOF                                     ,
> +    AMF_REPEAT                                  ,
> +    AMF_INPUT_FULL                              ,//returned by
> AMFComponent::SubmitInput if input queue is full
> +    AMF_RESOLUTION_CHANGED                      ,//resolution
> changed client needs to Drain/Terminate/Init
> +    AMF_RESOLUTION_UPDATED                      ,//resolution
> changed in adaptive mode. New ROI will be set on output on newly
> decoded frames +
> +    //error codes
> +    AMF_INVALID_DATA_TYPE                       ,//invalid data type
> +    AMF_INVALID_RESOLUTION                      ,//invalid
> resolution (width or height)
> +    AMF_CODEC_NOT_SUPPORTED                     ,//codec not
> supported
> +    AMF_SURFACE_FORMAT_NOT_SUPPORTED            ,//surface format
> not supported
> +    AMF_SURFACE_MUST_BE_SHARED                  ,//surface should be
> shared (DX11: (MiscFlags & D3D11_RESOURCE_MISC_SHARED) == 0, DX9: No
> shared handle found) + +// component video decoder
> +    AMF_DECODER_NOT_PRESENT                     ,//failed to create
> the decoder
> +    AMF_DECODER_SURFACE_ALLOCATION_FAILED       ,//failed to create
> the surface for decoding
> +    AMF_DECODER_NO_FREE_SURFACES                ,
> +
> +// component video encoder
> +    AMF_ENCODER_NOT_PRESENT                     ,//failed to create
> the encoder +
> +// component video processor
> +
> +// component video conveter
> +
> +// component dem
> +    AMF_DEM_ERROR                               ,
> +    AMF_DEM_PROPERTY_READONLY                   ,
> +    AMF_DEM_REMOTE_DISPLAY_CREATE_FAILED        ,
> +    AMF_DEM_START_ENCODING_FAILED               ,
> +    AMF_DEM_QUERY_OUTPUT_FAILED                 ,
> +
> +// component TAN
> +    AMF_TAN_CLIPPING_WAS_REQUIRED               , // Resulting data
> was truncated to meet output type's value limits.
> +    AMF_TAN_UNSUPPORTED_VERSION                 , // Not supported
> version requested, solely for TANCreateContext(). +
> +    AMF_NEED_MORE_INPUT                         ,//returned by
> AMFComponent::SubmitInput did not produce buffer +} AMF_RESULT;
> +
> +
> +//-----------------------------------------------------------------------------
> +// Interface.h
> +//-----------------------------------------------------------------------------
> +#define AMF_DECLARE_IID(name, _data1, _data2, _data3, _data41,
> _data42, _data43, _data44, _data45, _data46, _data47, _data48) \
> +        static AMF_INLINE const AMFGuid IID_##name(void) \
> +        { \
> +            AMFGuid uid = {_data1, _data2, _data3, _data41, _data42,
> _data43, _data44, _data45, _data46, _data47, _data48}; \
> +            return uid; \
> +        }
> +AMF_DECLARE_IID(AMFInterface, 0x9d872f34, 0x90dc, 0x4b93, 0xb6,
> 0xb2, 0x6c, 0xa3, 0x7c, 0x85, 0x25, 0xdb) +typedef struct
> AMFInterface AMFInterface; +
> +typedef struct AMFInterfaceVtbl
> +{
> +    // AMFInterface interface
> +    amf_long(AMF_STD_CALL *Acquire)(AMFInterface* pThis);
> +    amf_long(AMF_STD_CALL *Release)(AMFInterface* pThis);
> +    enum AMF_RESULT(AMF_STD_CALL *QueryInterface)(AMFInterface*
> pThis, const struct AMFGuid *interfaceID, void** ppInterface); +}
> AMFInterfaceVtbl; +
> +struct AMFInterface
> +{
> +    const AMFInterfaceVtbl *pVtbl;
> +};
> +
> +//-----------------------------------------------------------------------------
> +// Variant.h
> +//-----------------------------------------------------------------------------
> +
> +//----------------------------------------------------------------------------------------------
> +// variant types
> +//----------------------------------------------------------------------------------------------
> +typedef enum AMF_VARIANT_TYPE
> +{
> +    AMF_VARIANT_EMPTY = 0,
> +
> +    AMF_VARIANT_BOOL = 1,
> +    AMF_VARIANT_INT64 = 2,
> +    AMF_VARIANT_DOUBLE = 3,
> +
> +    AMF_VARIANT_RECT = 4,
> +    AMF_VARIANT_SIZE = 5,
> +    AMF_VARIANT_POINT = 6,
> +    AMF_VARIANT_RATE = 7,
> +    AMF_VARIANT_RATIO = 8,
> +    AMF_VARIANT_COLOR = 9,
> +
> +    AMF_VARIANT_STRING = 10,  // value is char*
> +    AMF_VARIANT_WSTRING = 11,  // value is wchar_t*
> +    AMF_VARIANT_INTERFACE = 12,  // value is AMFInterface*
> +} AMF_VARIANT_TYPE;
> +//----------------------------------------------------------------------------------------------
> +// variant struct
> +//----------------------------------------------------------------------------------------------
> +typedef struct AMFVariantStruct
> +{
> +    AMF_VARIANT_TYPE            type;
> +    union
> +    {
> +        amf_bool                boolValue;
> +        amf_int64               int64Value;
> +        amf_double              doubleValue;
> +        char*                   stringValue;
> +        wchar_t*                wstringValue;
> +        AMFInterface*           pInterface;
> +        struct AMFRect          rectValue;
> +        struct AMFSize          sizeValue;
> +        struct AMFPoint         pointValue;
> +        struct AMFRate          rateValue;
> +        struct AMFRatio         ratioValue;
> +        struct AMFColor         colorValue;
> +    };
> +} AMFVariantStruct;
> +
> +#define AMF_VARIANT_RETURN_IF_INVALID_POINTER(p) \
> +       { \
> +            if(p == NULL) \
> +                    { \
> +                 return AMF_INVALID_POINTER; \
> +            } \
> +       }
> +
> +static AMF_INLINE AMF_RESULT AMF_CDECL_CALL
> AMFVariantInit(AMFVariantStruct* pVariant) +{
> +    AMF_VARIANT_RETURN_IF_INVALID_POINTER(pVariant);
> +    pVariant->type = AMF_VARIANT_EMPTY;
> +    return AMF_OK;
> +}
> +
> +static AMF_INLINE AMF_RESULT AMF_CDECL_CALL
> AMFVariantClear(AMFVariantStruct* pVariant) +{
> +    AMF_RESULT errRet = AMF_OK;
> +    AMF_VARIANT_RETURN_IF_INVALID_POINTER(pVariant);
> +
> +    switch (pVariant->type)
> +    {
> +    case AMF_VARIANT_STRING:
> +        amf_variant_free(pVariant->stringValue);
> +        pVariant->type = AMF_VARIANT_EMPTY;
> +        break;
> +
> +    case AMF_VARIANT_WSTRING:
> +        amf_variant_free(pVariant->wstringValue);
> +        pVariant->type = AMF_VARIANT_EMPTY;
> +        break;
> +
> +    case AMF_VARIANT_INTERFACE:
> +        if (pVariant->pInterface != NULL)
> +        {
> +#if defined(__cplusplus)
> +            pVariant->pInterface->Release();
> +#else
> +
> pVariant->pInterface->pVtbl->Release(pVariant->pInterface); +#endif
> +            pVariant->pInterface = NULL;
> +        }
> +        pVariant->type = AMF_VARIANT_EMPTY;
> +        break;
> +
> +    default:
> +        pVariant->type = AMF_VARIANT_EMPTY;
> +        break;
> +    }
> +    return errRet;
> +}
> +//-------------------------------------------------------------------------------------------------
> +static AMF_INLINE AMF_RESULT AMF_CDECL_CALL
> AMFVariantAssignBool(AMFVariantStruct* pDest, amf_bool value) +{
> +    AMF_RESULT errRet = AMF_OK;
> +    AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
> +
> +    errRet = AMFVariantClear(pDest);
> +    if (errRet == AMF_OK)
> +    {
> +        pDest->type = AMF_VARIANT_BOOL;
> +        pDest->boolValue = value;
> +    }
> +    return errRet;
> +}
> +//-------------------------------------------------------------------------------------------------
> +static AMF_INLINE AMF_RESULT AMF_CDECL_CALL
> AMFVariantAssignInt64(AMFVariantStruct* pDest, amf_int64 value) +{
> +    AMF_RESULT errRet = AMF_OK;
> +    AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
> +
> +    errRet = AMFVariantClear(pDest);
> +    if (errRet == AMF_OK)
> +    {
> +        pDest->type = AMF_VARIANT_INT64;
> +        pDest->int64Value = value;
> +    }
> +    return errRet;
> +}
> +//-------------------------------------------------------------------------------------------------
> +static AMF_INLINE AMF_RESULT AMF_CDECL_CALL
> AMFVariantAssignDouble(AMFVariantStruct* pDest, amf_double value) +{
> +    AMF_RESULT errRet = AMF_OK;
> +    AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
> +
> +    errRet = AMFVariantClear(pDest);
> +    if (errRet == AMF_OK)
> +    {
> +        pDest->type = AMF_VARIANT_DOUBLE;
> +        pDest->doubleValue = value;
> +    }
> +    return errRet;
> +}
> +//-------------------------------------------------------------------------------------------------
> +static AMF_INLINE AMF_RESULT AMF_CDECL_CALL
> AMFVariantAssignSize(AMFVariantStruct* pDest, const AMFSize* value) +{
> +    AMF_RESULT errRet = AMF_OK;
> +    AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
> +
> +    errRet = AMFVariantClear(pDest);
> +    if (errRet == AMF_OK)
> +    {
> +        pDest->type = AMF_VARIANT_SIZE;
> +        pDest->sizeValue = *value;
> +    }
> +    return errRet;
> +}
> +//-------------------------------------------------------------------------------------------------
> +static AMF_INLINE AMF_RESULT AMF_CDECL_CALL
> AMFVariantAssignPoint(AMFVariantStruct* pDest, const AMFPoint* value)
> +{
> +    AMF_RESULT errRet = AMF_OK;
> +    AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
> +
> +    errRet = AMFVariantClear(pDest);
> +    if (errRet == AMF_OK)
> +    {
> +        pDest->type = AMF_VARIANT_POINT;
> +        pDest->pointValue = *value;
> +    }
> +    return errRet;
> +}
> +//-------------------------------------------------------------------------------------------------
> +static AMF_INLINE AMF_RESULT AMF_CDECL_CALL
> AMFVariantAssignRate(AMFVariantStruct* pDest, const AMFRate* value) +{
> +    AMF_RESULT errRet = AMF_OK;
> +    AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
> +
> +    errRet = AMFVariantClear(pDest);
> +    if (errRet == AMF_OK)
> +    {
> +        pDest->type = AMF_VARIANT_RATE;
> +        pDest->rateValue = *value;
> +    }
> +    return errRet;
> +}
> +//-------------------------------------------------------------------------------------------------
> +static AMF_INLINE AMF_RESULT AMF_CDECL_CALL
> AMFVariantAssignRatio(AMFVariantStruct* pDest, const AMFRatio* value)
> +{
> +    AMF_RESULT errRet = AMF_OK;
> +    AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
> +
> +    errRet = AMFVariantClear(pDest);
> +    if (errRet == AMF_OK)
> +    {
> +        pDest->type = AMF_VARIANT_RATIO;
> +        pDest->ratioValue = *value;
> +    }
> +    return errRet;
> +}
> +//-------------------------------------------------------------------------------------------------
> +static AMF_INLINE AMF_RESULT AMF_CDECL_CALL
> AMFVariantAssignColor(AMFVariantStruct* pDest, const AMFColor* value)
> +{
> +    AMF_RESULT errRet = AMF_OK;
> +    AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest);
> +
> +    errRet = AMFVariantClear(pDest);
> +    if (errRet == AMF_OK)
> +    {
> +        pDest->type = AMF_VARIANT_COLOR;
> +        pDest->colorValue = *value;
> +    }
> +    return errRet;
> +}
> +
> +//-----------------------------------------------------------------------------
> +// PropertyStorage.h
> +//-----------------------------------------------------------------------------
> +typedef struct AMFPropertyStorageObserver AMFPropertyStorageObserver;
> +typedef struct AMFPropertyStorage AMFPropertyStorage;
> +
> +#define AMF_ASSIGN_PROPERTY_DATA(res, varType, pThis, name, val ) \
> +    { \
> +        AMFVariantStruct var = {0}; \
> +        AMFVariantAssign##varType(&var, val); \
> +        res = pThis->pVtbl->SetProperty(pThis, name, var ); \
> +    }
> +#define AMF_ASSIGN_PROPERTY_TYPE(res, varType, dataType , pThis,
> name, val )  AMF_ASSIGN_PROPERTY_DATA(res, varType, pThis, name,
> (dataType)val) + +#define AMF_ASSIGN_PROPERTY_INT64(res, pThis, name,
> val ) AMF_ASSIGN_PROPERTY_TYPE(res, Int64, amf_int64, pThis, name,
> val) +#define AMF_ASSIGN_PROPERTY_DOUBLE(res, pThis, name, val )
> AMF_ASSIGN_PROPERTY_TYPE(res, Double, amf_double, pThis, name, val)
> +#define AMF_ASSIGN_PROPERTY_BOOL(res, pThis, name, val )
> AMF_ASSIGN_PROPERTY_TYPE(res, Bool, amf_bool, pThis, name, val)
> +#define AMF_ASSIGN_PROPERTY_RECT(res, pThis, name, val )
> AMF_ASSIGN_PROPERTY_DATA(res, Rect, pThis, name, &val) +#define
> AMF_ASSIGN_PROPERTY_SIZE(res, pThis, name, val )
> AMF_ASSIGN_PROPERTY_DATA(res, Size, pThis, name, &val) +#define
> AMF_ASSIGN_PROPERTY_POINT(res, pThis, name, val )
> AMF_ASSIGN_PROPERTY_DATA(res, Point, pThis, name, &val) +#define
> AMF_ASSIGN_PROPERTY_RATE(res, pThis, name, val )
> AMF_ASSIGN_PROPERTY_DATA(res, Rate, pThis, name, &val) +#define
> AMF_ASSIGN_PROPERTY_RATIO(res, pThis, name, val )
> AMF_ASSIGN_PROPERTY_DATA(res, Ratio, pThis, name, &val) +#define
> AMF_ASSIGN_PROPERTY_COLOR(res, pThis, name, val )
> AMF_ASSIGN_PROPERTY_DATA(res, Color, pThis, name, &val) +
> +//-----------------------------------------------------------------------------
> +// PropertyStorageEx.h
> +//-----------------------------------------------------------------------------
> +//----------------------------------------------------------------------------------------------
> +typedef enum AMF_PROPERTY_CONTENT_ENUM +{
> +    AMF_PROPERTY_CONTENT_DEFAULT = 0,
> +    AMF_PROPERTY_CONTENT_XML,               // m_eType is
> AMF_VARIANT_STRING +
> +    AMF_PROPERTY_CONTENT_FILE_OPEN_PATH,    // m_eType
> AMF_VARIANT_WSTRING
> +    AMF_PROPERTY_CONTENT_FILE_SAVE_PATH     // m_eType
> AMF_VARIANT_WSTRING +} AMF_PROPERTY_CONTENT_ENUM;
> +//----------------------------------------------------------------------------------------------
> +typedef enum AMF_PROPERTY_ACCESS_TYPE
> +{
> +    AMF_PROPERTY_ACCESS_PRIVATE = 0,
> +    AMF_PROPERTY_ACCESS_READ = 0x1,
> +    AMF_PROPERTY_ACCESS_WRITE = 0x2,
> +    AMF_PROPERTY_ACCESS_READ_WRITE = (AMF_PROPERTY_ACCESS_READ |
> AMF_PROPERTY_ACCESS_WRITE),
> +    AMF_PROPERTY_ACCESS_WRITE_RUNTIME = 0x4,
> +    AMF_PROPERTY_ACCESS_FULL = 0xFF,
> +} AMF_PROPERTY_ACCESS_TYPE;
> +//----------------------------------------------------------------------------------------------
> +typedef struct AMFEnumDescriptionEntry
> +{
> +    amf_int             value;
> +    const wchar_t*      name;
> +} AMFEnumDescriptionEntry;
> +//----------------------------------------------------------------------------------------------
> +typedef amf_uint32 AMF_PROPERTY_CONTENT_TYPE;
> +
> +typedef struct AMFPropertyInfo
> +{
> +    const wchar_t*                  name;
> +    const wchar_t*                  desc;
> +    AMF_VARIANT_TYPE                type;
> +    AMF_PROPERTY_CONTENT_TYPE       contentType;
> +
> +    AMFVariantStruct                defaultValue;
> +    AMFVariantStruct                minValue;
> +    AMFVariantStruct                maxValue;
> +    AMF_PROPERTY_ACCESS_TYPE        accessType;
> +    const AMFEnumDescriptionEntry*  pEnumDescription;
> +} AMFPropertyInfo;
> +//-----------------------------------------------------------------------------
> +// Data.h
> +//-----------------------------------------------------------------------------
> +//----------------------------------------------------------------------------------------------
> +typedef enum AMF_DATA_TYPE
> +{
> +    AMF_DATA_BUFFER = 0,
> +    AMF_DATA_SURFACE = 1,
> +    AMF_DATA_AUDIO_BUFFER = 2,
> +    AMF_DATA_USER = 1000,
> +    // all extensions will be AMF_DATA_USER+i
> +} AMF_DATA_TYPE;
> +//----------------------------------------------------------------------------------------------
> +typedef enum AMF_MEMORY_TYPE
> +{
> +    AMF_MEMORY_UNKNOWN = 0,
> +    AMF_MEMORY_HOST = 1,
> +    AMF_MEMORY_DX9 = 2,
> +    AMF_MEMORY_DX11 = 3,
> +    AMF_MEMORY_OPENCL = 4,
> +    AMF_MEMORY_OPENGL = 5,
> +    AMF_MEMORY_XV = 6,
> +    AMF_MEMORY_GRALLOC = 7,
> +    AMF_MEMORY_COMPUTE_FOR_DX9 = 8,
> +    AMF_MEMORY_COMPUTE_FOR_DX11 = 9,
> +} AMF_MEMORY_TYPE;
> +
> +//----------------------------------------------------------------------------------------------
> +typedef enum AMF_DX_VERSION
> +{
> +    AMF_DX9 = 90,
> +    AMF_DX9_EX = 91,
> +    AMF_DX11_0 = 110,
> +    AMF_DX11_1 = 111
> +} AMF_DX_VERSION;
> +
> +typedef struct AMFData AMFData;
> +AMF_DECLARE_IID(AMFData, 0xa1159bf6, 0x9104, 0x4107, 0x8e, 0xaa,
> 0xc5, 0x3d, 0x5d, 0xba, 0xc5, 0x11) +
> +typedef struct AMFDataVtbl
> +{
> +    // AMFInterface interface
> +    amf_long(AMF_STD_CALL *Acquire)(AMFData* pThis);
> +    amf_long(AMF_STD_CALL *Release)(AMFData* pThis);
> +    enum AMF_RESULT(AMF_STD_CALL *QueryInterface)(AMFData* pThis,
> const struct AMFGuid *interfaceID, void** ppInterface); +
> +    // AMFPropertyStorage interface
> +    AMF_RESULT(AMF_STD_CALL *SetProperty)(AMFData* pThis, const
> wchar_t* name, AMFVariantStruct value);
> +    AMF_RESULT(AMF_STD_CALL *GetProperty)(AMFData* pThis, const
> wchar_t* name, AMFVariantStruct* pValue);
> +    amf_bool(AMF_STD_CALL *HasProperty)(AMFData* pThis, const
> wchar_t* name);
> +    amf_size(AMF_STD_CALL *GetPropertyCount)(AMFData* pThis);
> +    AMF_RESULT(AMF_STD_CALL *GetPropertyAt)(AMFData* pThis, amf_size
> index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue);
> +    AMF_RESULT(AMF_STD_CALL *Clear)(AMFData* pThis);
> +    AMF_RESULT(AMF_STD_CALL *AddTo)(AMFData* pThis,
> AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
> +    AMF_RESULT(AMF_STD_CALL *CopyTo)(AMFData* pThis,
> AMFPropertyStorage* pDest, amf_bool deep);
> +    void                (AMF_STD_CALL *AddObserver)(AMFData* pThis,
> AMFPropertyStorageObserver* pObserver);
> +    void                (AMF_STD_CALL *RemoveObserver)(AMFData*
> pThis, AMFPropertyStorageObserver* pObserver); +
> +    // AMFData interface
> +
> +    AMF_MEMORY_TYPE(AMF_STD_CALL *GetMemoryType)(AMFData* pThis);
> +
> +    AMF_RESULT(AMF_STD_CALL *Duplicate)(AMFData* pThis,
> AMF_MEMORY_TYPE type, AMFData** ppData);
> +    AMF_RESULT(AMF_STD_CALL *Convert)(AMFData* pThis,
> AMF_MEMORY_TYPE type); // optimal interop if possilble. Copy through
> host memory if needed
> +    AMF_RESULT(AMF_STD_CALL *Interop)(AMFData* pThis,
> AMF_MEMORY_TYPE type); // only optimal interop if possilble. No copy
> through host memory for GPU objects +
> +    AMF_DATA_TYPE(AMF_STD_CALL *GetDataType)(AMFData* pThis);
> +
> +    amf_bool(AMF_STD_CALL *IsReusable)(AMFData* pThis);
> +
> +    void                (AMF_STD_CALL *SetPts)(AMFData* pThis,
> amf_pts pts);
> +    amf_pts(AMF_STD_CALL *GetPts)(AMFData* pThis);
> +    void                (AMF_STD_CALL *SetDuration)(AMFData* pThis,
> amf_pts duration);
> +    amf_pts(AMF_STD_CALL *GetDuration)(AMFData* pThis);
> +
> +} AMFDataVtbl;
> +
> +struct AMFData
> +{
> +    const AMFDataVtbl *pVtbl;
> +};
> +//-----------------------------------------------------------------------------
> +// Plane.h
> +//-----------------------------------------------------------------------------
> +//---------------------------------------------------------------------------------------------
> +typedef enum AMF_PLANE_TYPE
> +{
> +    AMF_PLANE_UNKNOWN = 0,
> +    AMF_PLANE_PACKED = 1,             // for all packed formats:
> BGRA, YUY2, etc
> +    AMF_PLANE_Y = 2,
> +    AMF_PLANE_UV = 3,
> +    AMF_PLANE_U = 4,
> +    AMF_PLANE_V = 5,
> +} AMF_PLANE_TYPE;
> +
> +//---------------------------------------------------------------------------------------------
> +// AMFPlane interface
> +//---------------------------------------------------------------------------------------------
> +AMF_DECLARE_IID(AMFPlane, 0xbede1aa6, 0xd8fa, 0x4625, 0x94, 0x65,
> 0x6c, 0x82, 0xc4, 0x37, 0x71, 0x2e) +typedef struct AMFPlane AMFPlane;
> +typedef struct AMFPlaneVtbl
> +{
> +    // AMFInterface interface
> +    amf_long(AMF_STD_CALL *Acquire)(AMFPlane* pThis);
> +    amf_long(AMF_STD_CALL *Release)(AMFPlane* pThis);
> +    enum AMF_RESULT(AMF_STD_CALL *QueryInterface)(AMFPlane* pThis,
> const struct AMFGuid *interfaceID, void** ppInterface); +
> +    // AMFPlane interface
> +    AMF_PLANE_TYPE(AMF_STD_CALL *GetType)(AMFPlane* pThis);
> +    void*               (AMF_STD_CALL *GetNative)(AMFPlane* pThis);
> +    amf_int32(AMF_STD_CALL *GetPixelSizeInBytes)(AMFPlane* pThis);
> +    amf_int32(AMF_STD_CALL *GetOffsetX)(AMFPlane* pThis);
> +    amf_int32(AMF_STD_CALL *GetOffsetY)(AMFPlane* pThis);
> +    amf_int32(AMF_STD_CALL *GetWidth)(AMFPlane* pThis);
> +    amf_int32(AMF_STD_CALL *GetHeight)(AMFPlane* pThis);
> +    amf_int32(AMF_STD_CALL *GetHPitch)(AMFPlane* pThis);
> +    amf_int32(AMF_STD_CALL *GetVPitch)(AMFPlane* pThis);
> +    amf_bool(AMF_STD_CALL *IsTiled)(AMFPlane* pThis);
> +
> +} AMFPlaneVtbl;
> +
> +struct AMFPlane
> +{
> +    const AMFPlaneVtbl *pVtbl;
> +};
> +//-----------------------------------------------------------------------------
> +// Buffer.h
> +//-----------------------------------------------------------------------------
> +#if defined(_MSC_VER)
> +#pragma warning( push )
> +#pragma warning(disable : 4263)
> +#pragma warning(disable : 4264)
> +#endif
> +
> +typedef struct AMFBuffer AMFBuffer;
> +typedef struct AMFBufferObserver AMFBufferObserver;
> +
> +AMF_DECLARE_IID(AMFBuffer, 0xb04b7248, 0xb6f0, 0x4321, 0xb6, 0x91,
> 0xba, 0xa4, 0x74, 0xf, 0x9f, 0xcb) +
> +typedef struct AMFBufferVtbl
> +{
> +    // AMFInterface interface
> +    amf_long(AMF_STD_CALL *Acquire)(AMFBuffer* pThis);
> +    amf_long(AMF_STD_CALL *Release)(AMFBuffer* pThis);
> +    enum AMF_RESULT(AMF_STD_CALL *QueryInterface)(AMFBuffer* pThis,
> const struct AMFGuid *interfaceID, void** ppInterface); +
> +    // AMFPropertyStorage interface
> +    AMF_RESULT(AMF_STD_CALL *SetProperty)(AMFBuffer* pThis, const
> wchar_t* name, AMFVariantStruct value);
> +    AMF_RESULT(AMF_STD_CALL *GetProperty)(AMFBuffer* pThis, const
> wchar_t* name, AMFVariantStruct* pValue);
> +    amf_bool(AMF_STD_CALL *HasProperty)(AMFBuffer* pThis, const
> wchar_t* name);
> +    amf_size(AMF_STD_CALL *GetPropertyCount)(AMFBuffer* pThis);
> +    AMF_RESULT(AMF_STD_CALL *GetPropertyAt)(AMFBuffer* pThis,
> amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct*
> pValue);
> +    AMF_RESULT(AMF_STD_CALL *Clear)(AMFBuffer* pThis);
> +    AMF_RESULT(AMF_STD_CALL *AddTo)(AMFBuffer* pThis,
> AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
> +    AMF_RESULT(AMF_STD_CALL *CopyTo)(AMFBuffer* pThis,
> AMFPropertyStorage* pDest, amf_bool deep);
> +    void                (AMF_STD_CALL *AddObserver)(AMFBuffer*
> pThis, AMFPropertyStorageObserver* pObserver);
> +    void                (AMF_STD_CALL *RemoveObserver)(AMFBuffer*
> pThis, AMFPropertyStorageObserver* pObserver); +
> +    // AMFData interface
> +
> +    AMF_MEMORY_TYPE(AMF_STD_CALL *GetMemoryType)(AMFBuffer* pThis);
> +
> +    AMF_RESULT(AMF_STD_CALL *Duplicate)(AMFBuffer* pThis,
> AMF_MEMORY_TYPE type, AMFData** ppData);
> +    AMF_RESULT(AMF_STD_CALL *Convert)(AMFBuffer* pThis,
> AMF_MEMORY_TYPE type); // optimal interop if possilble. Copy through
> host memory if needed
> +    AMF_RESULT(AMF_STD_CALL *Interop)(AMFBuffer* pThis,
> AMF_MEMORY_TYPE type); // only optimal interop if possilble. No copy
> through host memory for GPU objects +
> +    AMF_DATA_TYPE(AMF_STD_CALL *GetDataType)(AMFBuffer* pThis);
> +
> +    amf_bool(AMF_STD_CALL *IsReusable)(AMFBuffer* pThis);
> +
> +    void                (AMF_STD_CALL *SetPts)(AMFBuffer* pThis,
> amf_pts pts);
> +    amf_pts(AMF_STD_CALL *GetPts)(AMFBuffer* pThis);
> +    void                (AMF_STD_CALL *SetDuration)(AMFBuffer*
> pThis, amf_pts duration);
> +    amf_pts(AMF_STD_CALL *GetDuration)(AMFBuffer* pThis);
> +
> +    // AMFBuffer interface
> +
> +    AMF_RESULT(AMF_STD_CALL *SetSize)(AMFBuffer* pThis, amf_size
> newSize);
> +    amf_size(AMF_STD_CALL *GetSize)(AMFBuffer* pThis);
> +    void*               (AMF_STD_CALL *GetNative)(AMFBuffer* pThis);
> +
> +    // Observer management
> +    void                (AMF_STD_CALL
> *AddObserver_Buffer)(AMFBuffer* pThis, AMFBufferObserver* pObserver);
> +    void                (AMF_STD_CALL
> *RemoveObserver_Buffer)(AMFBuffer* pThis, AMFBufferObserver*
> pObserver); + +} AMFBufferVtbl;
> +
> +struct AMFBuffer
> +{
> +    const AMFBufferVtbl *pVtbl;
> +};
> +
> +//-----------------------------------------------------------------------------
> +// AudioBuffer.h
> +//-----------------------------------------------------------------------------
> +typedef enum AMF_AUDIO_FORMAT
> +{
> +    AMFAF_UNKNOWN = -1,
> +    AMFAF_U8 = 0,               // amf_uint8
> +    AMFAF_S16 = 1,               // amf_int16
> +    AMFAF_S32 = 2,               // amf_int32
> +    AMFAF_FLT = 3,               // amf_float
> +    AMFAF_DBL = 4,               // amf_double
> +
> +    AMFAF_U8P = 5,               // amf_uint8
> +    AMFAF_S16P = 6,               // amf_int16
> +    AMFAF_S32P = 7,               // amf_int32
> +    AMFAF_FLTP = 8,               // amf_float
> +    AMFAF_DBLP = 9,               // amf_double
> +    AMFAF_FIRST = AMFAF_U8,
> +    AMFAF_LAST = AMFAF_DBLP,
> +} AMF_AUDIO_FORMAT;
> +
> +typedef struct AMFAudioBuffer AMFAudioBuffer;
> +typedef struct AMFAudioBufferObserver AMFAudioBufferObserver;
> +//-----------------------------------------------------------------------------
> +// Surface.h
> +//-----------------------------------------------------------------------------
> +
> +typedef enum AMF_SURFACE_FORMAT
> +{
> +    AMF_SURFACE_UNKNOWN = 0,
> +    AMF_SURFACE_NV12,               ///< 1 - planar Y width x height
> + packed UV width/2 x height/2 - 8 bit per component
> +    AMF_SURFACE_YV12,               ///< 2 - planar Y width x height
> + V width/2 x height/2 + U width/2 x height/2 - 8 bit per component
> +    AMF_SURFACE_BGRA,               ///< 3 - packed - 8 bit per
> component
> +    AMF_SURFACE_ARGB,               ///< 4 - packed - 8 bit per
> component
> +    AMF_SURFACE_RGBA,               ///< 5 - packed - 8 bit per
> component
> +    AMF_SURFACE_GRAY8,              ///< 6 - single component - 8 bit
> +    AMF_SURFACE_YUV420P,            ///< 7 - planar Y width x height
> + U width/2 x height/2 + V width/2 x height/2 - 8 bit per component
> +    AMF_SURFACE_U8V8,               ///< 8 - double component - 8
> bit per component
> +    AMF_SURFACE_YUY2,               ///< 9 - YUY2: Byte 0=8-bit Y'0;
> Byte 1=8-bit Cb; Byte 2=8-bit Y'1; Byte 3=8-bit Cr
> +    AMF_SURFACE_P010,               ///< 10- planar Y width x height
> + packed UV width/2 x height/2 - 10 bit per component (16 allocated,
> upper 10 bits are used)
> +    AMF_SURFACE_RGBA_F16,           ///< 11 - packed - 16 bit per
> component float +
> +    AMF_SURFACE_FIRST = AMF_SURFACE_NV12,
> +    AMF_SURFACE_LAST = AMF_SURFACE_RGBA_F16
> +} AMF_SURFACE_FORMAT;
> +
> +//----------------------------------------------------------------------------------------------
> +// frame type
> +//----------------------------------------------------------------------------------------------
> +typedef enum AMF_FRAME_TYPE
> +{
> +    // flags
> +    AMF_FRAME_STEREO_FLAG = 0x10000000,
> +    AMF_FRAME_LEFT_FLAG = AMF_FRAME_STEREO_FLAG | 0x20000000,
> +    AMF_FRAME_RIGHT_FLAG = AMF_FRAME_STEREO_FLAG | 0x40000000,
> +    AMF_FRAME_BOTH_FLAG = AMF_FRAME_LEFT_FLAG | AMF_FRAME_RIGHT_FLAG,
> +    AMF_FRAME_INTERLEAVED_FLAG = 0x01000000,
> +    AMF_FRAME_FIELD_FLAG = 0x02000000,
> +    AMF_FRAME_EVEN_FLAG = 0x04000000,
> +    AMF_FRAME_ODD_FLAG = 0x08000000,
> +
> +    // values
> +    AMF_FRAME_UNKNOWN = -1,
> +    AMF_FRAME_PROGRESSIVE = 0,
> +
> +    AMF_FRAME_INTERLEAVED_EVEN_FIRST = AMF_FRAME_INTERLEAVED_FLAG |
> AMF_FRAME_EVEN_FLAG,
> +    AMF_FRAME_INTERLEAVED_ODD_FIRST = AMF_FRAME_INTERLEAVED_FLAG |
> AMF_FRAME_ODD_FLAG,
> +    AMF_FRAME_FIELD_SINGLE_EVEN = AMF_FRAME_FIELD_FLAG |
> AMF_FRAME_EVEN_FLAG,
> +    AMF_FRAME_FIELD_SINGLE_ODD = AMF_FRAME_FIELD_FLAG |
> AMF_FRAME_ODD_FLAG, +
> +    AMF_FRAME_STEREO_LEFT = AMF_FRAME_LEFT_FLAG,
> +    AMF_FRAME_STEREO_RIGHT = AMF_FRAME_RIGHT_FLAG,
> +    AMF_FRAME_STEREO_BOTH = AMF_FRAME_BOTH_FLAG,
> +
> +    AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_LEFT =
> AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_EVEN_FLAG |
> AMF_FRAME_LEFT_FLAG,
> +    AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_RIGHT =
> AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_EVEN_FLAG |
> AMF_FRAME_RIGHT_FLAG,
> +    AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_BOTH =
> AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_EVEN_FLAG |
> AMF_FRAME_BOTH_FLAG, +
> +    AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_LEFT =
> AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_ODD_FLAG | AMF_FRAME_LEFT_FLAG,
> +    AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_RIGHT =
> AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_ODD_FLAG |
> AMF_FRAME_RIGHT_FLAG,
> +    AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_BOTH =
> AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_ODD_FLAG |
> AMF_FRAME_BOTH_FLAG, +} AMF_FRAME_TYPE; +
> +typedef struct AMFSurface AMFSurface;
> +typedef struct AMFSurfaceObserver AMFSurfaceObserver;
> +
> +typedef struct AMFSurfaceObserverVtbl
> +{
> +    void                (AMF_STD_CALL
> *OnSurfaceDataRelease)(AMFSurfaceObserver* pThis, AMFSurface*
> pSurface); +} AMFSurfaceObserverVtbl; +
> +struct AMFSurfaceObserver
> +{
> +    const AMFSurfaceObserverVtbl *pVtbl;
> +};
> +
> +AMF_DECLARE_IID(AMFSurface, 0x3075dbe3, 0x8718, 0x4cfa, 0x86, 0xfb,
> 0x21, 0x14, 0xc0, 0xa5, 0xa4, 0x51) +typedef struct AMFSurfaceVtbl
> +{
> +    // AMFInterface interface
> +    amf_long(AMF_STD_CALL *Acquire)(AMFSurface* pThis);
> +    amf_long(AMF_STD_CALL *Release)(AMFSurface* pThis);
> +    enum AMF_RESULT(AMF_STD_CALL *QueryInterface)(AMFSurface* pThis,
> const struct AMFGuid *interfaceID, void** ppInterface); +
> +    // AMFPropertyStorage interface
> +    AMF_RESULT(AMF_STD_CALL *SetProperty)(AMFSurface* pThis, const
> wchar_t* name, AMFVariantStruct value);
> +    AMF_RESULT(AMF_STD_CALL *GetProperty)(AMFSurface* pThis, const
> wchar_t* name, AMFVariantStruct* pValue);
> +    amf_bool(AMF_STD_CALL *HasProperty)(AMFSurface* pThis, const
> wchar_t* name);
> +    amf_size(AMF_STD_CALL *GetPropertyCount)(AMFSurface* pThis);
> +    AMF_RESULT(AMF_STD_CALL *GetPropertyAt)(AMFSurface* pThis,
> amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct*
> pValue);
> +    AMF_RESULT(AMF_STD_CALL *Clear)(AMFSurface* pThis);
> +    AMF_RESULT(AMF_STD_CALL *AddTo)(AMFSurface* pThis,
> AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
> +    AMF_RESULT(AMF_STD_CALL *CopyTo)(AMFSurface* pThis,
> AMFPropertyStorage* pDest, amf_bool deep);
> +    void                (AMF_STD_CALL *AddObserver)(AMFSurface*
> pThis, AMFPropertyStorageObserver* pObserver);
> +    void                (AMF_STD_CALL *RemoveObserver)(AMFSurface*
> pThis, AMFPropertyStorageObserver* pObserver); +
> +    // AMFData interface
> +
> +    AMF_MEMORY_TYPE(AMF_STD_CALL *GetMemoryType)(AMFSurface* pThis);
> +
> +    AMF_RESULT(AMF_STD_CALL *Duplicate)(AMFSurface* pThis,
> AMF_MEMORY_TYPE type, AMFData** ppData);
> +    AMF_RESULT(AMF_STD_CALL *Convert)(AMFSurface* pThis,
> AMF_MEMORY_TYPE type); // optimal interop if possilble. Copy through
> host memory if needed
> +    AMF_RESULT(AMF_STD_CALL *Interop)(AMFSurface* pThis,
> AMF_MEMORY_TYPE type); // only optimal interop if possilble. No copy
> through host memory for GPU objects +
> +    AMF_DATA_TYPE(AMF_STD_CALL *GetDataType)(AMFSurface* pThis);
> +
> +    amf_bool(AMF_STD_CALL *IsReusable)(AMFSurface* pThis);
> +
> +    void                (AMF_STD_CALL *SetPts)(AMFSurface* pThis,
> amf_pts pts);
> +    amf_pts(AMF_STD_CALL *GetPts)(AMFSurface* pThis);
> +    void                (AMF_STD_CALL *SetDuration)(AMFSurface*
> pThis, amf_pts duration);
> +    amf_pts(AMF_STD_CALL *GetDuration)(AMFSurface* pThis);
> +
> +    // AMFSurface interface
> +
> +    AMF_SURFACE_FORMAT(AMF_STD_CALL *GetFormat)(AMFSurface* pThis);
> +
> +    // do not store planes outside. should be used together with
> Surface
> +    amf_size(AMF_STD_CALL *GetPlanesCount)(AMFSurface* pThis);
> +    AMFPlane*           (AMF_STD_CALL *GetPlaneAt)(AMFSurface*
> pThis, amf_size index);
> +    AMFPlane*           (AMF_STD_CALL *GetPlane)(AMFSurface* pThis,
> AMF_PLANE_TYPE type); +
> +    AMF_FRAME_TYPE(AMF_STD_CALL *GetFrameType)(AMFSurface* pThis);
> +    void                (AMF_STD_CALL *SetFrameType)(AMFSurface*
> pThis, AMF_FRAME_TYPE type); +
> +    AMF_RESULT(AMF_STD_CALL *SetCrop)(AMFSurface* pThis, amf_int32
> x, amf_int32 y, amf_int32 width, amf_int32 height);
> +    AMF_RESULT(AMF_STD_CALL *CopySurfaceRegion)(AMFSurface* pThis,
> AMFSurface* pDest, amf_int32 dstX, amf_int32 dstY, amf_int32 srcX,
> amf_int32 srcY, amf_int32 width, amf_int32 height); + +
> +    // Observer management
> +    void                (AMF_STD_CALL
> *AddObserver_Surface)(AMFSurface* pThis, AMFSurfaceObserver*
> pObserver);
> +    void                (AMF_STD_CALL
> *RemoveObserver_Surface)(AMFSurface* pThis, AMFSurfaceObserver*
> pObserver); + +} AMFSurfaceVtbl;
> +
> +struct AMFSurface
> +{
> +    const AMFSurfaceVtbl *pVtbl;
> +};
> +
> +#define   AMFTextureArrayIndexGUIDDef { 0x28115527, 0xe7c3,
> 0x4b66,{ 0x99, 0xd3, 0x4f, 0x2a, 0xe6, 0xb4, 0x7f, 0xaf } } +
> +//-----------------------------------------------------------------------------
> +// Component.h
> +//-----------------------------------------------------------------------------
> +AMF_DECLARE_IID(AMFComponent, 0x8b51e5e4, 0x455d, 0x4034, 0xa7,
> 0x46, 0xde, 0x1b, 0xed, 0xc3, 0xc4, 0x6) +typedef struct AMFComponent
> AMFComponent; +typedef struct AMFContext AMFContext;
> +typedef struct AMFIOCaps AMFIOCaps;
> +typedef struct AMFCaps AMFCaps;
> +
> +typedef struct AMFDataAllocatorCB AMFDataAllocatorCB;
> +typedef struct AMFComponentOptimizationCallback
> AMFComponentOptimizationCallback; +
> +typedef struct AMFComponentVtbl
> +{
> +    // AMFInterface interface
> +    amf_long(AMF_STD_CALL *Acquire)(AMFComponent* pThis);
> +    amf_long(AMF_STD_CALL *Release)(AMFComponent* pThis);
> +    enum AMF_RESULT(AMF_STD_CALL *QueryInterface)(AMFComponent*
> pThis, const struct AMFGuid *interfaceID, void** ppInterface); +
> +    // AMFPropertyStorage interface
> +    AMF_RESULT(AMF_STD_CALL *SetProperty)(AMFComponent* pThis, const
> wchar_t* name, AMFVariantStruct value);
> +    AMF_RESULT(AMF_STD_CALL *GetProperty)(AMFComponent* pThis, const
> wchar_t* name, AMFVariantStruct* pValue);
> +    amf_bool(AMF_STD_CALL *HasProperty)(AMFComponent* pThis, const
> wchar_t* name);
> +    amf_size(AMF_STD_CALL *GetPropertyCount)(AMFComponent* pThis);
> +    AMF_RESULT(AMF_STD_CALL *GetPropertyAt)(AMFComponent* pThis,
> amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct*
> pValue);
> +    AMF_RESULT(AMF_STD_CALL *Clear)(AMFComponent* pThis);
> +    AMF_RESULT(AMF_STD_CALL *AddTo)(AMFComponent* pThis,
> AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
> +    AMF_RESULT(AMF_STD_CALL *CopyTo)(AMFComponent* pThis,
> AMFPropertyStorage* pDest, amf_bool deep);
> +    void                (AMF_STD_CALL *AddObserver)(AMFComponent*
> pThis, AMFPropertyStorageObserver* pObserver);
> +    void                (AMF_STD_CALL *RemoveObserver)(AMFComponent*
> pThis, AMFPropertyStorageObserver* pObserver); +
> +    // AMFPropertyStorageEx interface
> +
> +    amf_size(AMF_STD_CALL *GetPropertiesInfoCount)(AMFComponent*
> pThis);
> +    AMF_RESULT(AMF_STD_CALL *GetPropertyInfoAt)(AMFComponent* pThis,
> amf_size index, const AMFPropertyInfo** ppInfo);
> +    AMF_RESULT(AMF_STD_CALL *GetPropertyInfo)(AMFComponent* pThis,
> const wchar_t* name, const AMFPropertyInfo** ppInfo);
> +    AMF_RESULT(AMF_STD_CALL *ValidateProperty)(AMFComponent* pThis,
> const wchar_t* name, AMFVariantStruct value, AMFVariantStruct*
> pOutValidated); +
> +    // AMFComponent interface
> +
> +    AMF_RESULT(AMF_STD_CALL *Init)(AMFComponent* pThis,
> AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height);
> +    AMF_RESULT(AMF_STD_CALL *ReInit)(AMFComponent* pThis, amf_int32
> width, amf_int32 height);
> +    AMF_RESULT(AMF_STD_CALL *Terminate)(AMFComponent* pThis);
> +    AMF_RESULT(AMF_STD_CALL *Drain)(AMFComponent* pThis);
> +    AMF_RESULT(AMF_STD_CALL *Flush)(AMFComponent* pThis);
> +
> +    AMF_RESULT(AMF_STD_CALL *SubmitInput)(AMFComponent* pThis,
> AMFData* pData);
> +    AMF_RESULT(AMF_STD_CALL *QueryOutput)(AMFComponent* pThis,
> AMFData** ppData);
> +    AMFContext* (AMF_STD_CALL *GetContext)(AMFComponent* pThis);
> +    AMF_RESULT(AMF_STD_CALL *SetOutputDataAllocatorCB)(AMFComponent*
> pThis, AMFDataAllocatorCB* callback); +
> +    AMF_RESULT(AMF_STD_CALL *GetCaps)(AMFComponent* pThis, AMFCaps**
> ppCaps);
> +    AMF_RESULT(AMF_STD_CALL *Optimize)(AMFComponent* pThis,
> AMFComponentOptimizationCallback* pCallback); +} AMFComponentVtbl;
> +
> +struct AMFComponent
> +{
> +    const AMFComponentVtbl *pVtbl;
> +};
> +
> +//-----------------------------------------------------------------------------
> +// Context.h
> +//-----------------------------------------------------------------------------
> +typedef struct AMFCompute AMFCompute;
> +typedef struct AMFComputeFactory AMFComputeFactory;
> +typedef struct AMFComputeDevice AMFComputeDevice;
> +typedef struct AMFContext AMFContext;
> +AMF_DECLARE_IID(AMFContext, 0xa76a13f0, 0xd80e, 0x4fcc, 0xb5, 0x8,
> 0x65, 0xd0, 0xb5, 0x2e, 0xd9, 0xee) +
> +typedef struct AMFContextVtbl
> +{
> +    // AMFInterface interface
> +    amf_long(AMF_STD_CALL *Acquire)(AMFContext* pThis);
> +    amf_long(AMF_STD_CALL *Release)(AMFContext* pThis);
> +    enum AMF_RESULT(AMF_STD_CALL *QueryInterface)(AMFContext* pThis,
> const struct AMFGuid *interfaceID, void** ppInterface); +
> +    // AMFInterface AMFPropertyStorage
> +
> +    AMF_RESULT(AMF_STD_CALL *SetProperty)(AMFContext* pThis, const
> wchar_t* name, AMFVariantStruct value);
> +    AMF_RESULT(AMF_STD_CALL *GetProperty)(AMFContext* pThis, const
> wchar_t* name, AMFVariantStruct* pValue);
> +    amf_bool(AMF_STD_CALL *HasProperty)(AMFContext* pThis, const
> wchar_t* name);
> +    amf_size(AMF_STD_CALL *GetPropertyCount)(AMFContext* pThis);
> +    AMF_RESULT(AMF_STD_CALL *GetPropertyAt)(AMFContext* pThis,
> amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct*
> pValue);
> +    AMF_RESULT(AMF_STD_CALL *Clear)(AMFContext* pThis);
> +    AMF_RESULT(AMF_STD_CALL *AddTo)(AMFContext* pThis,
> AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep);
> +    AMF_RESULT(AMF_STD_CALL *CopyTo)(AMFContext* pThis,
> AMFPropertyStorage* pDest, amf_bool deep);
> +    void                (AMF_STD_CALL *AddObserver)(AMFContext*
> pThis, AMFPropertyStorageObserver* pObserver);
> +    void                (AMF_STD_CALL *RemoveObserver)(AMFContext*
> pThis, AMFPropertyStorageObserver* pObserver); +
> +    // AMFContext interface
> +
> +    // Cleanup
> +    AMF_RESULT(AMF_STD_CALL *Terminate)(AMFContext* pThis);
> +
> +    // DX9
> +    AMF_RESULT(AMF_STD_CALL *InitDX9)(AMFContext* pThis, void*
> pDX9Device);
> +    void*               (AMF_STD_CALL *GetDX9Device)(AMFContext*
> pThis, AMF_DX_VERSION dxVersionRequired);
> +    AMF_RESULT(AMF_STD_CALL *LockDX9)(AMFContext* pThis);
> +    AMF_RESULT(AMF_STD_CALL *UnlockDX9)(AMFContext* pThis);
> +    // DX11
> +    AMF_RESULT(AMF_STD_CALL *InitDX11)(AMFContext* pThis, void*
> pDX11Device, AMF_DX_VERSION dxVersionRequired);
> +    void*               (AMF_STD_CALL *GetDX11Device)(AMFContext*
> pThis, AMF_DX_VERSION dxVersionRequired);
> +    AMF_RESULT(AMF_STD_CALL *LockDX11)(AMFContext* pThis);
> +    AMF_RESULT(AMF_STD_CALL *UnlockDX11)(AMFContext* pThis);
> +
> +    // OpenCL
> +    AMF_RESULT(AMF_STD_CALL *InitOpenCL)(AMFContext* pThis, void*
> pCommandQueue);
> +    void*               (AMF_STD_CALL *GetOpenCLContext)(AMFContext*
> pThis);
> +    void*               (AMF_STD_CALL
> *GetOpenCLCommandQueue)(AMFContext* pThis);
> +    void*               (AMF_STD_CALL
> *GetOpenCLDeviceID)(AMFContext* pThis);
> +    AMF_RESULT(AMF_STD_CALL *GetOpenCLComputeFactory)(AMFContext*
> pThis, AMFComputeFactory **ppFactory); // advanced compute - multiple
> queries
> +    AMF_RESULT(AMF_STD_CALL *InitOpenCLEx)(AMFContext* pThis,
> AMFComputeDevice *pDevice);
> +    AMF_RESULT(AMF_STD_CALL *LockOpenCL)(AMFContext* pThis);
> +    AMF_RESULT(AMF_STD_CALL *UnlockOpenCL)(AMFContext* pThis);
> +
> +    // OpenGL
> +    AMF_RESULT(AMF_STD_CALL *InitOpenGL)(AMFContext* pThis,
> amf_handle hOpenGLContext, amf_handle hWindow, amf_handle hDC);
> +    amf_handle(AMF_STD_CALL *GetOpenGLContext)(AMFContext* pThis);
> +    amf_handle(AMF_STD_CALL *GetOpenGLDrawable)(AMFContext* pThis);
> +    AMF_RESULT(AMF_STD_CALL *LockOpenGL)(AMFContext* pThis);
> +    AMF_RESULT(AMF_STD_CALL *UnlockOpenGL)(AMFContext* pThis);
> +    // XV - Linux
> +    AMF_RESULT(AMF_STD_CALL *InitXV)(AMFContext* pThis, void*
> pXVDevice);
> +    void*               (AMF_STD_CALL *GetXVDevice)(AMFContext*
> pThis);
> +    AMF_RESULT(AMF_STD_CALL *LockXV)(AMFContext* pThis);
> +    AMF_RESULT(AMF_STD_CALL *UnlockXV)(AMFContext* pThis);
> +
> +    // Gralloc - Android
> +    AMF_RESULT(AMF_STD_CALL *InitGralloc)(AMFContext* pThis, void*
> pGrallocDevice);
> +    void*               (AMF_STD_CALL *GetGrallocDevice)(AMFContext*
> pThis);
> +    AMF_RESULT(AMF_STD_CALL *LockGralloc)(AMFContext* pThis);
> +    AMF_RESULT(AMF_STD_CALL *UnlockGralloc)(AMFContext* pThis);
> +    // Allocation
> +    AMF_RESULT(AMF_STD_CALL *AllocBuffer)(AMFContext* pThis,
> AMF_MEMORY_TYPE type, amf_size size, AMFBuffer** ppBuffer);
> +    AMF_RESULT(AMF_STD_CALL *AllocSurface)(AMFContext* pThis,
> AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, amf_int32 width,
> amf_int32 height, AMFSurface** ppSurface);
> +    AMF_RESULT(AMF_STD_CALL *AllocAudioBuffer)(AMFContext* pThis,
> AMF_MEMORY_TYPE type, AMF_AUDIO_FORMAT format, amf_int32 samples,
> amf_int32 sampleRate, amf_int32 channels,
> +        AMFAudioBuffer** ppAudioBuffer);
> +
> +    // Wrap existing objects
> +    AMF_RESULT(AMF_STD_CALL *CreateBufferFromHostNative)(AMFContext*
> pThis, void* pHostBuffer, amf_size size, AMFBuffer** ppBuffer,
> AMFBufferObserver* pObserver);
> +    AMF_RESULT(AMF_STD_CALL
> *CreateSurfaceFromHostNative)(AMFContext* pThis, AMF_SURFACE_FORMAT
> format, amf_int32 width, amf_int32 height, amf_int32 hPitch,
> amf_int32 vPitch, void* pData,
> +        AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
> +    AMF_RESULT(AMF_STD_CALL *CreateSurfaceFromDX9Native)(AMFContext*
> pThis, void* pDX9Surface, AMFSurface** ppSurface, AMFSurfaceObserver*
> pObserver);
> +    AMF_RESULT(AMF_STD_CALL
> *CreateSurfaceFromDX11Native)(AMFContext* pThis, void* pDX11Surface,
> AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
> +    AMF_RESULT(AMF_STD_CALL
> *CreateSurfaceFromOpenGLNative)(AMFContext* pThis, AMF_SURFACE_FORMAT
> format, amf_handle hGLTextureID, AMFSurface** ppSurface,
> AMFSurfaceObserver* pObserver);
> +    AMF_RESULT(AMF_STD_CALL
> *CreateSurfaceFromGrallocNative)(AMFContext* pThis, amf_handle
> hGrallocSurface, AMFSurface** ppSurface, AMFSurfaceObserver*
> pObserver);
> +    AMF_RESULT(AMF_STD_CALL
> *CreateSurfaceFromOpenCLNative)(AMFContext* pThis, AMF_SURFACE_FORMAT
> format, amf_int32 width, amf_int32 height, void** pClPlanes,
> +        AMFSurface** ppSurface, AMFSurfaceObserver* pObserver);
> +    AMF_RESULT(AMF_STD_CALL
> *CreateBufferFromOpenCLNative)(AMFContext* pThis, void* pCLBuffer,
> amf_size size, AMFBuffer** ppBuffer); +
> +    // Access to AMFCompute interface - AMF_MEMORY_OPENCL,
> AMF_MEMORY_COMPUTE_FOR_DX9, AMF_MEMORY_COMPUTE_FOR_DX11 are currently
> supported
> +    AMF_RESULT(AMF_STD_CALL *GetCompute)(AMFContext* pThis,
> AMF_MEMORY_TYPE eMemType, AMFCompute** ppCompute); +
> +} AMFContextVtbl;
> +
> +struct AMFContext
> +{
> +    const AMFContextVtbl *pVtbl;
> +};
> +
> +//-----------------------------------------------------------------------------
> +// Debug.h 
> +//-----------------------------------------------------------------------------
> +
> +typedef struct AMFDebug AMFDebug;
> +typedef struct AMFDebugVtbl
> +{
> +    // AMFDebug interface
> +    void               (AMF_STD_CALL
> *EnablePerformanceMonitor)(AMFDebug* pThis, amf_bool enable);
> +    amf_bool(AMF_STD_CALL *PerformanceMonitorEnabled)(AMFDebug*
> pThis);
> +    void               (AMF_STD_CALL *AssertsEnable)(AMFDebug*
> pThis, amf_bool enable);
> +    amf_bool(AMF_STD_CALL *AssertsEnabled)(AMFDebug* pThis);
> +} AMFDebugVtbl;
> +
> +struct AMFDebug
> +{
> +    const AMFDebugVtbl *pVtbl;
> +};
> +
> +//-----------------------------------------------------------------------------
> +// Trace.h 
> +//-----------------------------------------------------------------------------
> +//----------------------------------------------------------------------------------------------
> +// trace levels
> +//----------------------------------------------------------------------------------------------
> +#define AMF_TRACE_ERROR     0
> +#define AMF_TRACE_WARNING   1
> +#define AMF_TRACE_INFO      2 // default in sdk
> +#define AMF_TRACE_DEBUG     3
> +#define AMF_TRACE_TRACE     4
> +
> +#define AMF_TRACE_TEST      5
> +#define AMF_TRACE_NOLOG     100
> +
> +//----------------------------------------------------------------------------------------------
> +// available trace writers
> +//----------------------------------------------------------------------------------------------
> +#define AMF_TRACE_WRITER_CONSOLE            L"Console"
> +#define AMF_TRACE_WRITER_DEBUG_OUTPUT       L"DebugOutput"
> +#define AMF_TRACE_WRITER_FILE               L"File"
> +
> +
> +typedef struct AMFTraceWriter AMFTraceWriter;
> +
> +typedef struct AMFTraceWriterVtbl
> +{
> +    // AMFTraceWriter interface
> +    void (AMF_CDECL_CALL *Write)(AMFTraceWriter* pThis, const
> wchar_t* scope, const wchar_t* message);
> +    void (AMF_CDECL_CALL *Flush)(AMFTraceWriter* pThis);
> +} AMFTraceWriterVtbl;
> +
> +struct AMFTraceWriter
> +{
> +    const AMFTraceWriterVtbl *pVtbl;
> +};
> +typedef struct AMFTrace AMFTrace;
> +
> +typedef struct AMFTraceVtbl
> +{
> +    // AMFTrace interface
> +    void               (AMF_STD_CALL *TraceW)(AMFTrace* pThis, const
> wchar_t* src_path, amf_int32 line, amf_int32 level, const wchar_t*
> scope, amf_int32 countArgs, const wchar_t* format, ...);
> +    void               (AMF_STD_CALL *Trace)(AMFTrace* pThis, const
> wchar_t* src_path, amf_int32 line, amf_int32 level, const wchar_t*
> scope, const wchar_t* message, va_list* pArglist); +
> +    amf_int32(AMF_STD_CALL *SetGlobalLevel)(AMFTrace* pThis,
> amf_int32 level);
> +    amf_int32(AMF_STD_CALL *GetGlobalLevel)(AMFTrace* pThis);
> +
> +    amf_bool(AMF_STD_CALL *EnableWriter)(AMFTrace* pThis, const
> wchar_t* writerID, amf_bool enable);
> +    amf_bool(AMF_STD_CALL *WriterEnabled)(AMFTrace* pThis, const
> wchar_t* writerID);
> +    AMF_RESULT(AMF_STD_CALL *TraceEnableAsync)(AMFTrace* pThis,
> amf_bool enable);
> +    AMF_RESULT(AMF_STD_CALL *TraceFlush)(AMFTrace* pThis);
> +    AMF_RESULT(AMF_STD_CALL *SetPath)(AMFTrace* pThis, const
> wchar_t* path);
> +    AMF_RESULT(AMF_STD_CALL *GetPath)(AMFTrace* pThis, wchar_t*
> path, amf_size* pSize);
> +    amf_int32(AMF_STD_CALL *SetWriterLevel)(AMFTrace* pThis, const
> wchar_t* writerID, amf_int32 level);
> +    amf_int32(AMF_STD_CALL *GetWriterLevel)(AMFTrace* pThis, const
> wchar_t* writerID);
> +    amf_int32(AMF_STD_CALL *SetWriterLevelForScope)(AMFTrace* pThis,
> const wchar_t* writerID, const wchar_t* scope, amf_int32 level);
> +    amf_int32(AMF_STD_CALL *GetWriterLevelForScope)(AMFTrace* pThis,
> const wchar_t* writerID, const wchar_t* scope); +
> +    amf_int32(AMF_STD_CALL *GetIndentation)(AMFTrace* pThis);
> +    void                (AMF_STD_CALL *Indent)(AMFTrace* pThis,
> amf_int32 addIndent); +
> +    void                (AMF_STD_CALL *RegisterWriter)(AMFTrace*
> pThis, const wchar_t* writerID, AMFTraceWriter* pWriter, amf_bool
> enable);
> +    void                (AMF_STD_CALL *UnregisterWriter)(AMFTrace*
> pThis, const wchar_t* writerID); +
> +    const wchar_t*      (AMF_STD_CALL *GetResultText)(AMFTrace*
> pThis, AMF_RESULT res);
> +    const wchar_t*      (AMF_STD_CALL
> *SurfaceGetFormatName)(AMFTrace* pThis, const AMF_SURFACE_FORMAT
> eSurfaceFormat);
> +    AMF_SURFACE_FORMAT(AMF_STD_CALL
> *SurfaceGetFormatByName)(AMFTrace* pThis, const wchar_t* name); +
> +    const wchar_t* const (AMF_STD_CALL *GetMemoryTypeName)(AMFTrace*
> pThis, const AMF_MEMORY_TYPE memoryType);
> +    AMF_MEMORY_TYPE(AMF_STD_CALL *GetMemoryTypeByName)(AMFTrace*
> pThis, const wchar_t* name); +
> +    const wchar_t* const (AMF_STD_CALL
> *GetSampleFormatName)(AMFTrace* pThis, const AMF_AUDIO_FORMAT
> eFormat);
> +    AMF_AUDIO_FORMAT(AMF_STD_CALL *GetSampleFormatByName)(AMFTrace*
> pThis, const wchar_t* name); +} AMFTraceVtbl;
> +
> +struct AMFTrace
> +{
> +    const AMFTraceVtbl *pVtbl;
> +};
> +//-----------------------------------------------------------------------------
> +// Factory.h
> +//-----------------------------------------------------------------------------
> +typedef struct AMFPrograms AMFPrograms;
> +
> +typedef struct AMFFactory AMFFactory;
> +
> +typedef struct AMFFactoryVtbl
> +{
> +    AMF_RESULT(AMF_STD_CALL *CreateContext)(AMFFactory* pThis,
> AMFContext** ppContext);
> +    AMF_RESULT(AMF_STD_CALL *CreateComponent)(AMFFactory* pThis,
> AMFContext* pContext, const wchar_t* id, AMFComponent** ppComponent);
> +    AMF_RESULT(AMF_STD_CALL *SetCacheFolder)(AMFFactory* pThis,
> const wchar_t* path);
> +    const wchar_t*      (AMF_STD_CALL *GetCacheFolder)(AMFFactory*
> pThis);
> +    AMF_RESULT(AMF_STD_CALL *GetDebug)(AMFFactory* pThis, AMFDebug**
> ppDebug);
> +    AMF_RESULT(AMF_STD_CALL *GetTrace)(AMFFactory* pThis, AMFTrace**
> ppTrace);
> +    AMF_RESULT(AMF_STD_CALL *GetPrograms)(AMFFactory* pThis,
> AMFPrograms** ppPrograms); +} AMFFactoryVtbl;
> +
> +struct AMFFactory
> +{
> +    const AMFFactoryVtbl *pVtbl;
> +};
> +
> +#define AMF_INIT_FUNCTION_NAME             "AMFInit"
> +#define AMF_QUERY_VERSION_FUNCTION_NAME    "AMFQueryVersion"
> +
> +typedef AMF_RESULT(AMF_CDECL_CALL *AMFInit_Fn)(amf_uint64 version,
> AMFFactory **ppFactory); +typedef AMF_RESULT(AMF_CDECL_CALL
> *AMFQueryVersion_Fn)(amf_uint64 *pVersion); +
> +#if defined(_M_AMD64)
> +#define AMF_DLL_NAME    L"amfrt64.dll"
> +#define AMF_DLL_NAMEA   "amfrt64.dll"
> +#else
> +#define AMF_DLL_NAME    L"amfrt32.dll"
> +#define AMF_DLL_NAMEA   "amfrt32.dll"
> +#endif
> +
> +
> +//-----------------------------------------------------------------------------
> +// VideoEncoderVCE.h
> +//-----------------------------------------------------------------------------
> +#define AMFVideoEncoderVCE_AVC L"AMFVideoEncoderVCE_AVC"
> +#define AMFVideoEncoderVCE_SVC L"AMFVideoEncoderVCE_SVC"
> +
> +enum AMF_VIDEO_ENCODER_USAGE_ENUM
> +{
> +    AMF_VIDEO_ENCODER_USAGE_TRANSCONDING = 0,
> +    AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY,
> +    AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY,
> +    AMF_VIDEO_ENCODER_USAGE_WEBCAM
> +};
> +
> +enum AMF_VIDEO_ENCODER_PROFILE_ENUM
> +{
> +    AMF_VIDEO_ENCODER_PROFILE_UNKNOWN = 0,
> +    AMF_VIDEO_ENCODER_PROFILE_BASELINE = 66,
> +    AMF_VIDEO_ENCODER_PROFILE_MAIN = 77,
> +    AMF_VIDEO_ENCODER_PROFILE_HIGH = 100,
> +    AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE = 256,
> +    AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH = 257,
> +};
> +
> +enum AMF_VIDEO_ENCODER_SCANTYPE_ENUM
> +{
> +    AMF_VIDEO_ENCODER_SCANTYPE_PROGRESSIVE = 0,
> +    AMF_VIDEO_ENCODER_SCANTYPE_INTERLACED
> +};
> +
> +enum AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_ENUM
> +{
> +    AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN = -1,
> +    AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP = 0,
> +    AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR,
> +    AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR,
> +    AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR
> +};
> +
> +enum AMF_VIDEO_ENCODER_QUALITY_PRESET_ENUM
> +{
> +    AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED = 0,
> +    AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED,
> +    AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY
> +};
> +
> +enum AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_ENUM
> +{
> +    AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_NONE = 0,
> +    AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_FRAME,
> +    AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_TOP_FIELD,
> +    AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_BOTTOM_FIELD
> +};
> +
> +enum AMF_VIDEO_ENCODER_PICTURE_TYPE_ENUM
> +{
> +    AMF_VIDEO_ENCODER_PICTURE_TYPE_NONE = 0,
> +    AMF_VIDEO_ENCODER_PICTURE_TYPE_SKIP,
> +    AMF_VIDEO_ENCODER_PICTURE_TYPE_IDR,
> +    AMF_VIDEO_ENCODER_PICTURE_TYPE_I,
> +    AMF_VIDEO_ENCODER_PICTURE_TYPE_P,
> +    AMF_VIDEO_ENCODER_PICTURE_TYPE_B
> +};
> +
> +enum AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_ENUM
> +{
> +    AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_IDR,
> +    AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_I,
> +    AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_P,
> +    AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_B
> +};
> +
> +enum AMF_VIDEO_ENCODER_PREENCODE_MODE_ENUM
> +{
> +    AMF_VIDEO_ENCODER_PREENCODE_DISABLED = 0,
> +    AMF_VIDEO_ENCODER_PREENCODE_ENABLED = 1,
> +};
> +
> +enum AMF_VIDEO_ENCODER_CODING_ENUM
> +{
> +    AMF_VIDEO_ENCODER_UNDEFINED = 0, // BASELINE = CALV; MAIN, HIGH
> = CABAC
> +    AMF_VIDEO_ENCODER_CABAC,
> +    AMF_VIDEO_ENCODER_CALV,
> +
> +};
> +
> +
> +// Static properties - can be set before Init()
> +
> +#define AMF_VIDEO_ENCODER_FRAMESIZE
> L"FrameSize"                // AMFSize; default = 0,0; Frame size
> +#define AMF_VIDEO_ENCODER_FRAMERATE
> L"FrameRate"                // AMFRate; default = depends on usage;
> Frame Rate + +#define
> AMF_VIDEO_ENCODER_EXTRADATA
> L"ExtraData"                // AMFInterface* - > AMFBuffer*; SPS/PPS
> buffer in Annex B format - read-only +#define
> AMF_VIDEO_ENCODER_USAGE
> L"Usage"                    //
> amf_int64(AMF_VIDEO_ENCODER_USAGE_ENUM); default = N/A; Encoder usage
> type. fully configures parameter set. +#define
> AMF_VIDEO_ENCODER_PROFILE
> L"Profile"                  //
> amf_int64(AMF_VIDEO_ENCODER_PROFILE_ENUM) ; default =
> AMF_VIDEO_ENCODER_PROFILE_MAIN;  H264 profile +#define
> AMF_VIDEO_ENCODER_PROFILE_LEVEL
> L"ProfileLevel"             // amf_int64; default = 42; H264 profile
> level +#define
> AMF_VIDEO_ENCODER_MAX_LTR_FRAMES
> L"MaxOfLTRFrames"           // amf_int64; default = 0; Max number of
> LTR frames +#define
> AMF_VIDEO_ENCODER_SCANTYPE
> L"ScanType"                 //
> amf_int64(AMF_VIDEO_ENCODER_SCANTYPE_ENUM); default =
> AMF_VIDEO_ENCODER_SCANTYPE_PROGRESSIVE; indicates input stream type
> +#define AMF_VIDEO_ENCODER_MAX_NUM_REFRAMES
> L"MaxNumRefFrames"          // amf_int64; Maximum number of reference
> frames +#define
> AMF_VIDEO_ENCODER_ASPECT_RATIO
> L"AspectRatio"              // AMFRatio; default = 1, 1 +#define
> AMF_VIDEO_ENCODER_FULL_RANGE_COLOR
> L"FullRangeColor"           // bool; default = false; inidicates that
> YUV input is (0,255) +#define
> AMF_VIDEO_ENCODER_RATE_CONTROL_PREANALYSIS_ENABLE
> L"RateControlPreanalysisEnable"     //
> amf_int64(AMF_VIDEO_ENCODER_PREENCODE_MODE_ENUM); default =
> AMF_VIDEO_ENCODER_PREENCODE_DISABLED; controls Pre-analysis assisted
> rate control + +// Quality preset property +#define
> AMF_VIDEO_ENCODER_QUALITY_PRESET
> L"QualityPreset"            //
> amf_int64(AMF_VIDEO_ENCODER_QUALITY_PRESET_ENUM); default = depends
> on USAGE; Quality Preset + + +// Dynamic properties - can be set at
> any time + +// Rate control properties +#define
> AMF_VIDEO_ENCODER_B_PIC_DELTA_QP
> L"BPicturesDeltaQP"         // amf_int64; default = depends on USAGE;
> B-picture Delta +#define
> AMF_VIDEO_ENCODER_REF_B_PIC_DELTA_QP
> L"ReferenceBPicturesDeltaQP"// amf_int64; default = depends on USAGE;
> Reference B-picture Delta + +#define
> AMF_VIDEO_ENCODER_ENFORCE_HRD
> L"EnforceHRD"               // bool; default = depends on USAGE;
> Enforce HRD +#define
> AMF_VIDEO_ENCODER_FILLER_DATA_ENABLE
> L"FillerDataEnable"         // bool; default = false; Filler Data
> Enable +#define
> AMF_VIDEO_ENCODER_ENABLE_VBAQ
> L"EnableVBAQ"               // bool; default = depends on USAGE;
> Enable VBAQ + + +#define
> AMF_VIDEO_ENCODER_VBV_BUFFER_SIZE
> L"VBVBufferSize"            // amf_int64; default = depends on USAGE;
> VBV Buffer Size in bits +#define
> AMF_VIDEO_ENCODER_INITIAL_VBV_BUFFER_FULLNESS
> L"InitialVBVBufferFullness" // amf_int64; default =  64; Initial VBV
> Buffer Fullness 0=0% 64=100% + +#define
> AMF_VIDEO_ENCODER_MAX_AU_SIZE
> L"MaxAUSize"                // amf_int64; default = 60; Max AU Size
> in bits + +#define
> AMF_VIDEO_ENCODER_MIN_QP
> L"MinQP"                    // amf_int64; default = depends on USAGE;
> Min QP; range = 0-51 +#define
> AMF_VIDEO_ENCODER_MAX_QP
> L"MaxQP"                    // amf_int64; default = depends on USAGE;
> Max QP; range = 0-51 +#define
> AMF_VIDEO_ENCODER_QP_I
> L"QPI"                      // amf_int64; default = 22; I-frame QP;
> range = 0-51 +#define
> AMF_VIDEO_ENCODER_QP_P
> L"QPP"                      // amf_int64; default = 22; P-frame QP;
> range = 0-51 +#define
> AMF_VIDEO_ENCODER_QP_B
> L"QPB"                      // amf_int64; default = 22; B-frame QP;
> range = 0-51 +#define
> AMF_VIDEO_ENCODER_TARGET_BITRATE
> L"TargetBitrate"            // amf_int64; default = depends on USAGE;
> Target bit rate in bits +#define
> AMF_VIDEO_ENCODER_PEAK_BITRATE
> L"PeakBitrate"              // amf_int64; default = depends on USAGE;
> Peak bit rate in bits +#define
> AMF_VIDEO_ENCODER_RATE_CONTROL_SKIP_FRAME_ENABLE
> L"RateControlSkipFrameEnable"   // bool; default =  depends on USAGE;
> Rate Control Based Frame Skip +#define
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD
> L"RateControlMethod"        //
> amf_int64(AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_ENUM); default =
> depends on USAGE; Rate Control Method + +// Picture control
> properties +#define
> AMF_VIDEO_ENCODER_HEADER_INSERTION_SPACING
> L"HeaderInsertionSpacing"   // amf_int64; default = depends on USAGE;
> Header Insertion Spacing; range 0-1000 +#define
> AMF_VIDEO_ENCODER_B_PIC_PATTERN
> L"BPicturesPattern"         // amf_int64; default = 3; B-picture
> Pattern (number of B-Frames) +#define
> AMF_VIDEO_ENCODER_DE_BLOCKING_FILTER
> L"DeBlockingFilter"         // bool; default = depends on USAGE;
> De-blocking Filter +#define
> AMF_VIDEO_ENCODER_B_REFERENCE_ENABLE
> L"BReferenceEnable"         // bool; default = true; Enable Refrence
> to B-frames +#define
> AMF_VIDEO_ENCODER_IDR_PERIOD
> L"IDRPeriod"                // amf_int64; default = depends on USAGE;
> IDR Period in frames +#define
> AMF_VIDEO_ENCODER_INTRA_REFRESH_NUM_MBS_PER_SLOT
> L"IntraRefreshMBsNumberPerSlot" // amf_int64; default = depends on
> USAGE; Intra Refresh MBs Number Per Slot in Macroblocks +#define
> AMF_VIDEO_ENCODER_SLICES_PER_FRAME
> L"SlicesPerFrame"           // amf_int64; default = 1; Number of
> slices Per Frame +#define
> AMF_VIDEO_ENCODER_CABAC_ENABLE
> L"CABACEnable"              //
> amf_int64(AMF_VIDEO_ENCODER_CODING_ENUM) default =
> AMF_VIDEO_ENCODER_UNDEFINED + +// Motion estimation +#define
> AMF_VIDEO_ENCODER_MOTION_HALF_PIXEL
> L"HalfPixel"                // bool; default= true; Half Pixel
> +#define AMF_VIDEO_ENCODER_MOTION_QUARTERPIXEL
> L"QuarterPixel"             // bool; default= true; Quarter Pixel +
> +// SVC +#define
> AMF_VIDEO_ENCODER_NUM_TEMPORAL_ENHANCMENT_LAYERS
> L"NumOfTemporalEnhancmentLayers" // amf_int64; default = 0; range =
> 0, min(2, caps->GetMaxNumOfTemporalLayers()) number of temporal
> enhancment Layers (SVC) + +// Per-submittion properties - can be set
> on input surface interface +#define
> AMF_VIDEO_ENCODER_END_OF_SEQUENCE
> L"EndOfSequence"            // bool; default = false; generate end of
> sequence +#define
> AMF_VIDEO_ENCODER_END_OF_STREAM
> L"EndOfStream"              // bool; default = false; generate end of
> stream +#define
> AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE
> L"ForcePictureType"         //
> amf_int64(AMF_VIDEO_ENCODER_PICTURE_TYPE_ENUM); default =
> AMF_VIDEO_ENCODER_PICTURE_TYPE_NONE; generate particular picture type
> +#define AMF_VIDEO_ENCODER_INSERT_AUD
> L"InsertAUD"                // bool; default = false; insert AUD
> +#define AMF_VIDEO_ENCODER_INSERT_SPS
> L"InsertSPS"                // bool; default = false; insert SPS
> +#define AMF_VIDEO_ENCODER_INSERT_PPS
> L"InsertPPS"                // bool; default = false; insert PPS
> +#define AMF_VIDEO_ENCODER_PICTURE_STRUCTURE
> L"PictureStructure"         //
> amf_int64(AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_ENUM); default =
> AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_FRAME; indicate picture type
> +#define AMF_VIDEO_ENCODER_MARK_CURRENT_WITH_LTR_INDEX
> L"MarkCurrentWithLTRIndex"  // //amf_int64; default = N/A; Mark
> current frame with LTR index +#define
> AMF_VIDEO_ENCODER_FORCE_LTR_REFERENCE_BITFIELD
> L"ForceLTRReferenceBitfield"// amf_int64; default = 0; force LTR
> bit-field + +// properties set by encoder on output buffer interface
> +#define AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE
> L"OutputDataType"           //
> amf_int64(AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_ENUM); default = N/A
> +#define AMF_VIDEO_ENCODER_OUTPUT_MARKED_LTR_INDEX
> L"MarkedLTRIndex"           //amf_int64; default = -1; Marked LTR
> index +#define
> AMF_VIDEO_ENCODER_OUTPUT_REFERENCED_LTR_INDEX_BITFIELD
> L"ReferencedLTRIndexBitfield" // amf_int64; default = 0; referenced
> LTR bit-field + + +#define
> AMF_VIDEO_ENCODER_HDCP_COUNTER
> L"HDCPCounter"              //  const void* + +// Properties for
> multi-instance cloud gaming +#define
> AMF_VIDEO_ENCODER_MAX_INSTANCES
> L"EncoderMaxInstances"      //  amf_uint32; default = 1; max number
> of encoder instances +#define
> AMF_VIDEO_ENCODER_MULTI_INSTANCE_MODE
> L"MultiInstanceMode"        //  bool; default = false; +#define
> AMF_VIDEO_ENCODER_CURRENT_QUEUE
> L"MultiInstanceCurrentQueue"//  amf_uin32; default = 0; + +// VCE
> Encoder capabilities - exposed in AMFCaps interface +#define
> AMF_VIDEO_ENCODER_CAP_MAX_BITRATE
> L"MaxBitrate"               // amf_int64; Maximum bit rate in bits
> +#define AMF_VIDEO_ENCODER_CAP_NUM_OF_STREAMS
> L"NumOfStreams"             // amf_int64; maximum number of encode
> streams supported +#define
> AMF_VIDEO_ENCODER_CAP_MAX_PROFILE
> L"MaxProfile"               // AMF_VIDEO_ENCODER_PROFILE_ENUM
> +#define AMF_VIDEO_ENCODER_CAP_MAX_LEVEL
> L"MaxLevel"                 // amf_int64 maximum profile level
> +#define AMF_VIDEO_ENCODER_CAP_BFRAMES
> L"BFrames"                  // bool  is B-Frames supported +#define
> AMF_VIDEO_ENCODER_CAP_MIN_REFERENCE_FRAMES
> L"MinReferenceFrames"       // amf_int64 minimum number of reference
> frames +#define
> AMF_VIDEO_ENCODER_CAP_MAX_REFERENCE_FRAMES
> L"MaxReferenceFrames"       // amf_int64 maximum number of reference
> frames +#define
> AMF_VIDEO_ENCODER_CAP_MAX_TEMPORAL_LAYERS
> L"MaxTemporalLayers"        // amf_int64 maximum number of temporal
> layers +#define
> AMF_VIDEO_ENCODER_CAP_FIXED_SLICE_MODE
> L"FixedSliceMode"           // bool  is fixed slice mode supported
> +#define AMF_VIDEO_ENCODER_CAP_NUM_OF_HW_INSTANCES
> L"NumOfHwInstances"         // amf_int64 number of HW encoder
> instances +
> +//-----------------------------------------------------------------------------
> +// VideoEncoderHEVC.h
> +//-----------------------------------------------------------------------------
> +#define AMFVideoEncoder_HEVC L"AMFVideoEncoderHW_HEVC" + +enum
> AMF_VIDEO_ENCODER_HEVC_USAGE_ENUM +{
> +    AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING = 0,
> +    AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY,
> +    AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY,
> +    AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM
> +};
> +
> +enum AMF_VIDEO_ENCODER_HEVC_PROFILE_ENUM
> +{
> +    AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN = 1
> +};
> +
> +enum AMF_VIDEO_ENCODER_HEVC_TIER_ENUM
> +{
> +    AMF_VIDEO_ENCODER_HEVC_TIER_MAIN = 0,
> +    AMF_VIDEO_ENCODER_HEVC_TIER_HIGH = 1
> +};
> +
> +enum AMF_VIDEO_ENCODER_LEVEL_ENUM
> +{
> +    AMF_LEVEL_1 = 30,
> +    AMF_LEVEL_2 = 60,
> +    AMF_LEVEL_2_1 = 63,
> +    AMF_LEVEL_3 = 90,
> +    AMF_LEVEL_3_1 = 93,
> +    AMF_LEVEL_4 = 120,
> +    AMF_LEVEL_4_1 = 123,
> +    AMF_LEVEL_5 = 150,
> +    AMF_LEVEL_5_1 = 153,
> +    AMF_LEVEL_5_2 = 156,
> +    AMF_LEVEL_6 = 180,
> +    AMF_LEVEL_6_1 = 183,
> +    AMF_LEVEL_6_2 = 186
> +};
> +
> +enum AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_ENUM
> +{
> +    AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_UNKNOWN = -1,
> +    AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP = 0,
> +
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR,
> +    AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR,
> +    AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR
> +};
> +
> +enum AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_ENUM
> +{
> +    AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_NONE = 0,
> +    AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_SKIP,
> +    AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_IDR,
> +    AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_I,
> +    AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_P
> +};
> +
> +enum AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_ENUM
> +{
> +    AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_IDR,
> +    AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_I,
> +    AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_P
> +};
> +
> +enum AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_ENUM
> +{
> +    AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY = 0,
> +    AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED = 5,
> +    AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED = 10
> +};
> +
> +enum AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_ENUM
> +{
> +    AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_NONE = 0,
> +    AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_GOP_ALIGNED,
> +    AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_IDR_ALIGNED
> +};
> +
> +
> +
> +// Static properties - can be set before Init()
> +#define AMF_VIDEO_ENCODER_HEVC_FRAMESIZE
> L"HevcFrameSize"                // AMFSize; default = 0,0; Frame size
> + +#define
> AMF_VIDEO_ENCODER_HEVC_USAGE
> L"HevcUsage"                    //
> amf_int64(AMF_VIDEO_ENCODER_HEVC_USAGE_ENUM); default = N/A; Encoder
> usage type. fully configures parameter set. +#define
> AMF_VIDEO_ENCODER_HEVC_PROFILE
> L"HevcProfile"                  //
> amf_int64(AMF_VIDEO_ENCODER_HEVC_PROFILE_ENUM) ; default =
> AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN; +#define
> AMF_VIDEO_ENCODER_HEVC_TIER
> L"HevcTier"                     //
> amf_int64(AMF_VIDEO_ENCODER_HEVC_TIER_ENUM) ; default =
> AMF_VIDEO_ENCODER_HEVC_TIER_MAIN; +#define
> AMF_VIDEO_ENCODER_HEVC_PROFILE_LEVEL
> L"HevcProfileLevel"             // amf_int64
> (AMF_VIDEO_ENCODER_LEVEL_ENUM, default depends on HW capabilities);
> +#define AMF_VIDEO_ENCODER_HEVC_MAX_LTR_FRAMES
> L"HevcMaxOfLTRFrames"           // amf_int64; default = 0; Max number
> of LTR frames +#define
> AMF_VIDEO_ENCODER_HEVC_MAX_NUM_REFRAMES
> L"HevcMaxNumRefFrames"          // amf_int64; default = 1; Maximum
> number of reference frames +#define
> AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET
> L"HevcQualityPreset"            //
> amf_int64(AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_ENUM); default =
> depends on USAGE; Quality Preset +#define
> AMF_VIDEO_ENCODER_HEVC_EXTRADATA
> L"HevcExtraData"                // AMFInterface* - > AMFBuffer*;
> SPS/PPS buffer - read-only +#define
> AMF_VIDEO_ENCODER_HEVC_ASPECT_RATIO
> L"HevcAspectRatio"              // AMFRatio; default = 1, 1 + +//
> Picture control properties +#define
> AMF_VIDEO_ENCODER_HEVC_NUM_GOPS_PER_IDR
> L"HevcGOPSPerIDR"               // amf_int64; default = 60; The
> frequency to insert IDR as start of a GOP. 0 means no IDR will be
> inserted. +#define
> AMF_VIDEO_ENCODER_HEVC_GOP_SIZE
> L"HevcGOPSize"                  // amf_int64; default = 60; GOP Size,
> in frames +#define
> AMF_VIDEO_ENCODER_HEVC_DE_BLOCKING_FILTER_DISABLE
> L"HevcDeBlockingFilter"         // bool; default = depends on USAGE;
> De-blocking Filter +#define
> AMF_VIDEO_ENCODER_HEVC_SLICES_PER_FRAME
> L"HevcSlicesPerFrame"           // amf_int64; default = 1; Number of
> slices Per Frame +#define
> AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE
> L"HevcHeaderInsertionMode"      //
> amf_int64(AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_ENUM); default
> = NONE + +// Rate control properties +#define
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD
> L"HevcRateControlMethod"        //
> amf_int64(AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_MODE_ENUM); default =
> depends on USAGE; Rate Control Method +#define
> AMF_VIDEO_ENCODER_HEVC_FRAMERATE
> L"HevcFrameRate"                // AMFRate; default = depends on
> usage; Frame Rate +#define
> AMF_VIDEO_ENCODER_HEVC_VBV_BUFFER_SIZE
> L"HevcVBVBufferSize"            // amf_int64; default = depends on
> USAGE; VBV Buffer Size in bits +#define
> AMF_VIDEO_ENCODER_HEVC_INITIAL_VBV_BUFFER_FULLNESS
> L"HevcInitialVBVBufferFullness" // amf_int64; default =  64; Initial
> VBV Buffer Fullness 0=0% 64=100% +#define
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_PREANALYSIS_ENABLE
> L"HevcRateControlPreAnalysisEnable"  // bool; default =  depends on
> USAGE; enable Pre-analysis assisted rate control +#define
> AMF_VIDEO_ENCODER_HEVC_ENABLE_VBAQ
> L"HevcEnableVBAQ"               // // bool; default = depends on
> USAGE; Enable auto VBAQ + +// Motion estimation +#define
> AMF_VIDEO_ENCODER_HEVC_MOTION_HALF_PIXEL
> L"HevcHalfPixel"                // bool; default= true; Half Pixel
> +#define AMF_VIDEO_ENCODER_HEVC_MOTION_QUARTERPIXEL
> L"HevcQuarterPixel"             // bool; default= true; Quarter Pixel
> + +// Dynamic properties - can be set at any time + +// Rate control
> properties +#define
> AMF_VIDEO_ENCODER_HEVC_ENFORCE_HRD
> L"HevcEnforceHRD"               // bool; default = depends on USAGE;
> Enforce HRD +#define
> AMF_VIDEO_ENCODER_HEVC_FILLER_DATA_ENABLE
> L"HevcFillerDataEnable"         // bool; default = depends on USAGE;
> Enforce HRD +#define
> AMF_VIDEO_ENCODER_HEVC_TARGET_BITRATE
> L"HevcTargetBitrate"            // amf_int64; default = depends on
> USAGE; Target bit rate in bits +#define
> AMF_VIDEO_ENCODER_HEVC_PEAK_BITRATE
> L"HevcPeakBitrate"              // amf_int64; default = depends on
> USAGE; Peak bit rate in bits + +#define
> AMF_VIDEO_ENCODER_HEVC_MAX_AU_SIZE
> L"HevcMaxAUSize"                // amf_int64; default = 60; Max AU
> Size in bits + +#define
> AMF_VIDEO_ENCODER_HEVC_MIN_QP_I
> L"HevcMinQP_I"                  // amf_int64; default = depends on
> USAGE; Min QP; range = +#define
> AMF_VIDEO_ENCODER_HEVC_MAX_QP_I
> L"HevcMaxQP_I"                  // amf_int64; default = depends on
> USAGE; Max QP; range = +#define
> AMF_VIDEO_ENCODER_HEVC_MIN_QP_P
> L"HevcMinQP_P"                  // amf_int64; default = depends on
> USAGE; Min QP; range = +#define
> AMF_VIDEO_ENCODER_HEVC_MAX_QP_P
> L"HevcMaxQP_P"                  // amf_int64; default = depends on
> USAGE; Max QP; range = + +#define
> AMF_VIDEO_ENCODER_HEVC_QP_I
> L"HevcQP_I"                     // amf_int64; default = 26; P-frame
> QP; range = 0-51 +#define
> AMF_VIDEO_ENCODER_HEVC_QP_P
> L"HevcQP_P"                     // amf_int64; default = 26; P-frame
> QP; range = 0-51 + +#define
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_SKIP_FRAME_ENABLE
> L"HevcRateControlSkipFrameEnable" // bool; default =  depends on
> USAGE; Rate Control Based Frame Skip + + + +// Per-submittion
> properties - can be set on input surface interface +#define
> AMF_VIDEO_ENCODER_HEVC_END_OF_SEQUENCE
> L"HevcEndOfSequence"            // bool; default = false; generate
> end of sequence +#define
> AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE
> L"HevcForcePictureType"         //
> amf_int64(AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_ENUM); default =
> AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_NONE; generate particular picture
> type +#define
> AMF_VIDEO_ENCODER_HEVC_INSERT_AUD
> L"HevcInsertAUD"                // bool; default = false; insert AUD
> +#define AMF_VIDEO_ENCODER_HEVC_INSERT_HEADER
> L"HevcInsertHeader"             // bool; default = false; insert
> header(SPS, PPS, VPS) + +#define
> AMF_VIDEO_ENCODER_HEVC_MARK_CURRENT_WITH_LTR_INDEX
> L"HevcMarkCurrentWithLTRIndex"  // amf_int64; default = N/A; Mark
> current frame with LTR index +#define
> AMF_VIDEO_ENCODER_HEVC_FORCE_LTR_REFERENCE_BITFIELD
> L"HevcForceLTRReferenceBitfield"// amf_int64; default = 0; force LTR
> bit-field + +// Properties set by encoder on output buffer interface
> +#define AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE
> L"HevcOutputDataType"           //
> amf_int64(AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_ENUM); default =
> N/A +#define
> AMF_VIDEO_ENCODER_HEVC_OUTPUT_MARKED_LTR_INDEX
> L"HevcMarkedLTRIndex"           // amf_int64; default = -1; Marked
> LTR index +#define
> AMF_VIDEO_ENCODER_HEVC_OUTPUT_REFERENCED_LTR_INDEX_BITFIELD
> L"HevcReferencedLTRIndexBitfield"// amf_int64; default = 0;
> referenced LTR bit-field + +// HEVC Encoder capabilities - exposed in
> AMFCaps interface +#define
> AMF_VIDEO_ENCODER_HEVC_CAP_MAX_BITRATE
> L"HevcMaxBitrate"               // amf_int64; Maximum bit rate in
> bits +#define
> AMF_VIDEO_ENCODER_HEVC_CAP_NUM_OF_STREAMS
> L"HevcNumOfStreams"             // amf_int64; maximum number of
> encode streams supported +#define
> AMF_VIDEO_ENCODER_HEVC_CAP_MAX_PROFILE
> L"HevcMaxProfile"               //
> amf_int64(AMF_VIDEO_ENCODER_HEVC_PROFILE_ENUM) +#define
> AMF_VIDEO_ENCODER_HEVC_CAP_MAX_TIER
> L"HevcMaxTier"                  //
> amf_int64(AMF_VIDEO_ENCODER_HEVC_TIER_ENUM) maximum profile tier
> +#define AMF_VIDEO_ENCODER_HEVC_CAP_MAX_LEVEL
> L"HevcMaxLevel"                 // amf_int64 maximum profile level
> +#define AMF_VIDEO_ENCODER_HEVC_CAP_MIN_REFERENCE_FRAMES
> L"HevcMinReferenceFrames"       // amf_int64 minimum number of
> reference frames +#define
> AMF_VIDEO_ENCODER_HEVC_CAP_MAX_REFERENCE_FRAMES
> L"HevcMaxReferenceFrames"       // amf_int64 maximum number of
> reference frames + +
> +//-----------------------------------------------------------------------------
> +//-----------------------------------------------------------------------------
> + +#endif // __AMF_SDK_Enc_h__ diff --git a/configure b/configure
> index 3788f26..a562a2a 100755 --- a/configure +++ b/configure @@
> -303,6 +303,7 @@ External library support: --disable-zlib
> disable zlib [autodetect] The following libraries provide various
> hardware acceleration features:
> +  --disable-amf            disable AMF video encoding code
> [autodetect] --disable-audiotoolbox   disable Apple AudioToolbox code
> [autodetect] --disable-cuda           disable dynamically linked
> Nvidia CUDA code [autodetect] --enable-cuda-sdk        enable CUDA
> features that require the CUDA SDK [no] @@ -1639,6 +1640,7 @@
> EXTERNAL_LIBRARY_LIST=" "
>  
>  HWACCEL_AUTODETECT_LIBRARY_LIST="
> +    amf
>      audiotoolbox
>      crystalhd
>      cuda
> @@ -2781,12 +2783,15 @@ scale_npp_filter_deps="cuda libnpp"
>  scale_cuda_filter_deps="cuda_sdk"
>  thumbnail_cuda_filter_deps="cuda_sdk"
>  
> +amf_deps_any="libdl LoadLibrary"
> +
>  nvenc_deps="cuda"
>  nvenc_deps_any="libdl LoadLibrary"
>  nvenc_encoder_deps="nvenc"
>  
>  h263_v4l2m2m_decoder_deps="v4l2_m2m h263_v4l2_m2m"
>  h263_v4l2m2m_encoder_deps="v4l2_m2m h263_v4l2_m2m"
> +h264_amf_encoder_deps="amf"
>  h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf
> h264_parser" h264_cuvid_decoder_deps="cuvid"
>  h264_cuvid_decoder_select="h264_mp4toannexb_bsf"
> @@ -2803,6 +2808,7 @@
> h264_vaapi_encoder_deps="VAEncPictureParameterBufferH264"
> h264_vaapi_encoder_select="cbs_h264 vaapi_encode"
> h264_v4l2m2m_decoder_deps="v4l2_m2m h264_v4l2_m2m"
> h264_v4l2m2m_encoder_deps="v4l2_m2m h264_v4l2_m2m"
> +hevc_amf_encoder_deps="amf" hevc_cuvid_decoder_deps="cuvid"
>  hevc_cuvid_decoder_select="hevc_mp4toannexb_bsf"
>  hevc_mediacodec_decoder_deps="mediacodec"
> @@ -6164,9 +6170,12 @@ if enabled x86; then
>          mingw32*|mingw64*|win32|win64|linux|cygwin*)
>              ;;
>          *)
> -            disable cuda cuvid nvdec nvenc
> +            disable cuda cuvid nvdec nvenc amf
>              ;;
>      esac
> +    if test $target_os = "linux"; then
> +        disable amf
> +    fi
>  else
>      disable cuda cuvid nvdec nvenc
>  fi
> @@ -6179,6 +6188,13 @@ void f(void) { struct { const GUID guid; } s[]
> = { { NV_ENC_PRESET_HQ_GUID } }; int main(void) { return 0; }
>  EOF
>  
> +enabled amf &&
> +    check_cc -I$source_path <<EOF || disable amf
> +#include "compat/amd/amfsdkenc.h"
> +AMFFactory *factory;
> +int main(void) { return 0; }
> +EOF
> +
>  # Funny iconv installations are not unusual, so check it after all
> flags have been set if enabled libc_iconv; then
>      check_func_headers iconv.h iconv
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index 2476aec..9bbb60e 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -55,6 +55,7 @@ OBJS =
> ac3_parser.o                                                     \
> OBJS-$(CONFIG_AANDCTTABLES)            += aandcttab.o
> OBJS-$(CONFIG_AC3DSP)                  += ac3dsp.o ac3.o ac3tab.o
> OBJS-$(CONFIG_ADTS_HEADER)             += adts_header.o mpeg4audio.o
> +OBJS-$(CONFIG_AMF)                     += amfenc.o
> OBJS-$(CONFIG_AUDIO_FRAME_QUEUE)       += audio_frame_queue.o
> OBJS-$(CONFIG_AUDIODSP)                += audiodsp.o
> OBJS-$(CONFIG_BLOCKDSP)                += blockdsp.o @@ -332,6 +333,7
> @@ OBJS-$(CONFIG_H263_ENCODER)            += mpeg4videoenc.o
> mpeg4video.o  \ h263.o ituh263enc.o flvenc.o h263data.o
> OBJS-$(CONFIG_H263_V4L2M2M_DECODER)    += v4l2_m2m_dec.o
> OBJS-$(CONFIG_H263_V4L2M2M_ENCODER)    += v4l2_m2m_enc.o
> +OBJS-$(CONFIG_H264_AMF_ENCODER)        += amfenc_h264.o
> OBJS-$(CONFIG_H264_DECODER)            += h264dec.o h264_cabac.o
> h264_cavlc.o \ h264_direct.o h264_loopfilter.o  \ h264_mb.o
> h264_picture.o \ @@ -353,6 +355,7 @@
> OBJS-$(CONFIG_H264_V4L2M2M_DECODER)    += v4l2_m2m_dec.o
> OBJS-$(CONFIG_H264_V4L2M2M_ENCODER)    += v4l2_m2m_enc.o
> OBJS-$(CONFIG_HAP_DECODER)             += hapdec.o hap.o
> OBJS-$(CONFIG_HAP_ENCODER)             += hapenc.o hap.o
> +OBJS-$(CONFIG_HEVC_AMF_ENCODER)        += amfenc_hevc.o
> OBJS-$(CONFIG_HEVC_DECODER)            += hevcdec.o hevc_mvs.o \
> hevc_cabac.o hevc_refs.o hevcpred.o    \ hevcdsp.o hevc_filter.o
> hevc_data.o @@ -1059,6 +1062,7 @@
> SKIPHEADERS                            +=
> %_tablegen.h                  \ aacenc_quantization_misc.h    \
> $(ARCH)/vp56_arith.h          \ 
> +SKIPHEADERS-$(CONFIG_AMF)              += amfenc.h
>  SKIPHEADERS-$(CONFIG_D3D11VA)          += d3d11va.h dxva2_internal.h
>  SKIPHEADERS-$(CONFIG_DXVA2)            += dxva2.h dxva2_internal.h
>  SKIPHEADERS-$(CONFIG_JNI)              += ffjni.h
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index 0781862..20c19ec 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -653,6 +653,7 @@ static void register_all(void)
>       * above is available */
>      REGISTER_ENCODER(H263_V4L2M2M,      h263_v4l2m2m);
>      REGISTER_ENCDEC (LIBOPENH264,       libopenh264);
> +    REGISTER_ENCODER(H264_AMF,          h264_amf);
>      REGISTER_DECODER(H264_CUVID,        h264_cuvid);
>      REGISTER_ENCODER(H264_NVENC,        h264_nvenc);
>      REGISTER_ENCODER(H264_OMX,          h264_omx);
> @@ -665,6 +666,7 @@ static void register_all(void)
>      REGISTER_ENCODER(NVENC_H264,        nvenc_h264);
>      REGISTER_ENCODER(NVENC_HEVC,        nvenc_hevc);
>  #endif
> +    REGISTER_ENCODER(HEVC_AMF,          hevc_amf);
>      REGISTER_DECODER(HEVC_CUVID,        hevc_cuvid);
>      REGISTER_DECODER(HEVC_MEDIACODEC,   hevc_mediacodec);
>      REGISTER_ENCODER(HEVC_NVENC,        hevc_nvenc);
> diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
> new file mode 100644
> index 0000000..6b23f64
> --- /dev/null
> +++ b/libavcodec/amfenc.c
> @@ -0,0 +1,596 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301 USA
> + */
> +
> +#include "libavutil/avassert.h"
> +#include "libavutil/imgutils.h"
> +#include "libavutil/hwcontext.h"
> +#if CONFIG_D3D11VA
> +#include "libavutil/hwcontext_d3d11va.h"
> +#endif
> +#include "libavutil/mem.h"
> +#include "libavutil/pixdesc.h"
> +#include "libavutil/time.h"
> +
> +#include "amfenc.h"
> +#include "internal.h"
> +
> +#if CONFIG_D3D11VA
> +#include <d3d11.h>
> +#endif
> +
> +#ifdef _WIN32
> +#include "compat/w32dlfcn.h"
> +#else
> +#include <dlfcn.h>
> +#endif
> +
> +#define FFMPEG_AMF_WRITER_ID L"ffmpeg_amf"
> +
> +#define PTS_PROP L"PtsProp"
> +
> +const enum AVPixelFormat ff_amf_pix_fmts[] = {
> +    AV_PIX_FMT_NV12,
> +    AV_PIX_FMT_YUV420P,
> +    AV_PIX_FMT_D3D11,
> +    AV_PIX_FMT_NONE
> +};
> +
> +typedef struct FormatMap {
> +    enum AVPixelFormat       av_format;
> +    enum AMF_SURFACE_FORMAT  amf_format;
> +} FormatMap;
> +
> +static const FormatMap format_map[] =
> +{
> +    { AV_PIX_FMT_NONE,       AMF_SURFACE_UNKNOWN },
> +    { AV_PIX_FMT_NV12,       AMF_SURFACE_NV12 },
> +    { AV_PIX_FMT_BGR0,       AMF_SURFACE_BGRA },
> +    { AV_PIX_FMT_RGB0,       AMF_SURFACE_RGBA },
> +    { AV_PIX_FMT_GRAY8,      AMF_SURFACE_GRAY8 },
> +    { AV_PIX_FMT_YUV420P,    AMF_SURFACE_YUV420P },
> +    { AV_PIX_FMT_YUYV422,    AMF_SURFACE_YUY2 },
> +    { AV_PIX_FMT_D3D11,      AMF_SURFACE_NV12 },
> +};
> +
> +
> +static int is_hwaccel_pix_fmt(enum AVPixelFormat pix_fmt)
> +{
> +    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
> +    return desc->flags & AV_PIX_FMT_FLAG_HWACCEL;
> +}
> +
> +
> +static enum AMF_SURFACE_FORMAT amf_av_to_amf_format(enum
> AVPixelFormat fmt) +{
> +    int i;
> +    for (i = 0; i < amf_countof(format_map); i++) {
> +        if (format_map[i].av_format == fmt) {
> +            return format_map[i].amf_format;
> +        }
> +    }
> +    return AMF_SURFACE_UNKNOWN;
> +}
> +
> +static void AMF_CDECL_CALL AMFTraceWriter_Write(AMFTraceWriter
> *pThis,
> +    const wchar_t *scope, const wchar_t *message)
> +{
> +    AmfTraceWriter *tracer = (AmfTraceWriter*)pThis;
> +    av_log(tracer->avctx, AV_LOG_DEBUG, "%ls: %ls", scope,
> message); // \n is provided from AMF +}
> +
> +static void AMF_CDECL_CALL AMFTraceWriter_Flush(AMFTraceWriter
> *pThis) +{
> +}
> +
> +static AMFTraceWriterVtbl tracer_vtbl =
> +{
> +    .Write = AMFTraceWriter_Write,
> +    .Flush = AMFTraceWriter_Flush,
> +};
> +
> +static int amf_load_library(AVCodecContext *avctx)
> +{
> +    AmfContext             *ctx = avctx->priv_data;
> +    AMFInit_Fn              init_fun = NULL;
> +    AMFQueryVersion_Fn      version_fun = NULL;
> +    AMF_RESULT              res = AMF_OK;
> +
> +    ctx->eof = 0;
> +    ctx->delayed_drain = 0;
> +    ctx->hw_frames_ctx = NULL;
> +    ctx->hw_device_ctx = NULL;
> +    ctx->delayed_surface = NULL;
> +    ctx->delayed_frame = av_frame_alloc();
> +    if (!ctx->delayed_frame) {
> +        return AVERROR(ENOMEM);
> +    }
> +    // hardcoded to current HW queue size - will realloc in
> timestamp_queue_enqueue() if too small
> +    ctx->timestamp_list = av_fifo_alloc((avctx->max_b_frames + 16) *
> sizeof(int64_t));
> +    if (!ctx->timestamp_list) {
> +        return AVERROR(ENOMEM);
> +    }
> +    ctx->dts_delay = 0;
> +
> +
> +    ctx->library = dlopen(AMF_DLL_NAMEA, RTLD_NOW | RTLD_LOCAL);
> +    AMF_RETURN_IF_FALSE(ctx, ctx->library != NULL,
> +        AVERROR_UNKNOWN, "DLL %s failed to open\n", AMF_DLL_NAMEA);
> +
> +    init_fun = (AMFInit_Fn)dlsym(ctx->library,
> AMF_INIT_FUNCTION_NAME);
> +    AMF_RETURN_IF_FALSE(ctx, init_fun != NULL, AVERROR_UNKNOWN, "DLL
> %s failed to find function %s\n", AMF_DLL_NAMEA,
> AMF_INIT_FUNCTION_NAME); +
> +    version_fun = (AMFQueryVersion_Fn)dlsym(ctx->library,
> AMF_QUERY_VERSION_FUNCTION_NAME);
> +    AMF_RETURN_IF_FALSE(ctx, version_fun != NULL, AVERROR_UNKNOWN,
> "DLL %s failed to find function %s\n", AMF_DLL_NAMEA,
> AMF_QUERY_VERSION_FUNCTION_NAME); +
> +    res = version_fun(&ctx->version);
> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "%s
> failed with error %d\n", AMF_QUERY_VERSION_FUNCTION_NAME, res);
> +    res = init_fun(AMF_FULL_VERSION, &ctx->factory);
> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "%s
> failed with error %d\n", AMF_INIT_FUNCTION_NAME, res);
> +    res = ctx->factory->pVtbl->GetTrace(ctx->factory, &ctx->trace);
> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN,
> "GetTrace() failed with error %d\n", res);
> +    res = ctx->factory->pVtbl->GetDebug(ctx->factory, &ctx->debug);
> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN,
> "GetDebug() failed with error %d\n", res);
> +    return 0;
> +}
> +
> +static int amf_init_context(AVCodecContext *avctx)
> +{
> +    AmfContext         *ctx = avctx->priv_data;
> +    AMF_RESULT          res = AMF_OK;
> +
> +    // confugure AMF logger
> +    // the return of these functions indicates old state and do not
> affect behaviour
> +    ctx->trace->pVtbl->EnableWriter(ctx->trace,
> AMF_TRACE_WRITER_DEBUG_OUTPUT, ctx->log_to_dbg != 0 );
> +    if (ctx->log_to_dbg)
> +        ctx->trace->pVtbl->SetWriterLevel(ctx->trace,
> AMF_TRACE_WRITER_DEBUG_OUTPUT, AMF_TRACE_TRACE);
> +    ctx->trace->pVtbl->EnableWriter(ctx->trace,
> AMF_TRACE_WRITER_CONSOLE, 0);
> +    ctx->trace->pVtbl->SetGlobalLevel(ctx->trace, AMF_TRACE_TRACE);
> +
> +    // connect AMF logger to av_log
> +    ctx->tracer.vtbl = &tracer_vtbl;
> +    ctx->tracer.avctx = avctx;
> +    ctx->trace->pVtbl->RegisterWriter(ctx->trace,
> FFMPEG_AMF_WRITER_ID,(AMFTraceWriter*)&ctx->tracer, 1);
> +    ctx->trace->pVtbl->SetWriterLevel(ctx->trace,
> FFMPEG_AMF_WRITER_ID, AMF_TRACE_TRACE); +
> +    res = ctx->factory->pVtbl->CreateContext(ctx->factory,
> &ctx->context);
> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN,
> "CreateContext() failed with error %d\n", res);
> +    // try to reuse existing DX device
> +#if CONFIG_D3D11VA
> +    if (avctx->hw_frames_ctx) {
> +        AVHWFramesContext *device_ctx =
> (AVHWFramesContext*)avctx->hw_frames_ctx->data;
> +        if (device_ctx->device_ctx->type ==
> AV_HWDEVICE_TYPE_D3D11VA){
> +            if (amf_av_to_amf_format(device_ctx->sw_format) !=
> AMF_SURFACE_UNKNOWN) {
> +                if (device_ctx->device_ctx->hwctx) {
> +                    AVD3D11VADeviceContext *device_d3d11 =
> (AVD3D11VADeviceContext *)device_ctx->device_ctx->hwctx;
> +                    res =
> ctx->context->pVtbl->InitDX11(ctx->context, device_d3d11->device,
> AMF_DX11_1);
> +                    if (res == AMF_OK) {
> +                        ctx->hw_frames_ctx =
> av_buffer_ref(avctx->hw_frames_ctx);
> +                    }else {
> +                        if(res == AMF_NOT_SUPPORTED)
> +                            av_log(avctx, AV_LOG_INFO, "amf_shared:
> avctx->hw_frames_ctx has D3D11 device which doesn't have D3D11VA
> interface, switching to default\n");
> +                        else
> +                            av_log(avctx, AV_LOG_INFO, "amf_shared:
> avctx->hw_frames_ctx has non-AMD device, switching to default\n");
> +                    }
> +                }
> +            }else {
> +                av_log(avctx, AV_LOG_INFO, "amf_shared:
> avctx->hw_frames_ctx has format not uspported by AMF, switching to
> default\n");
> +            }
> +        }
> +    } else if (avctx->hw_device_ctx) {
> +        AVHWDeviceContext *device_ctx =
> (AVHWDeviceContext*)(avctx->hw_device_ctx->data);
> +        if (device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
> +            if (device_ctx->hwctx) {
> +                AVD3D11VADeviceContext *device_d3d11 =
> (AVD3D11VADeviceContext *)device_ctx->hwctx;
> +                res = ctx->context->pVtbl->InitDX11(ctx->context,
> device_d3d11->device, AMF_DX11_1);
> +                if (res == AMF_OK) {
> +                    ctx->hw_device_ctx =
> av_buffer_ref(avctx->hw_device_ctx);
> +                } else {
> +                    if (res == AMF_NOT_SUPPORTED)
> +                        av_log(avctx, AV_LOG_INFO, "amf_shared:
> avctx->hw_device_ctx has D3D11 device which doesn't have D3D11VA
> interface, switching to default\n");
> +                    else
> +                        av_log(avctx, AV_LOG_INFO, "amf_shared:
> avctx->hw_device_ctx has non-AMD device, switching to default\n");
> +                }
> +            }
> +        }
> +    }
> +#endif
> +    if (!ctx->hw_frames_ctx && !ctx->hw_device_ctx) {
> +        res = ctx->context->pVtbl->InitDX11(ctx->context, NULL,
> AMF_DX11_1);
> +        if (res != AMF_OK) {
> +            res = ctx->context->pVtbl->InitDX9(ctx->context, NULL);
> +            AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN,
> "InitDX9() failed with error %d\n", res);
> +        }
> +    }
> +    return 0;
> +}
> +
> +static int amf_init_encoder(AVCodecContext *avctx)
> +{
> +    AmfContext          *ctx = avctx->priv_data;
> +    const wchar_t       *codec_id = NULL;
> +    AMF_RESULT           res = AMF_OK;
> +
> +    switch (avctx->codec->id) {
> +        case AV_CODEC_ID_H264:
> +            codec_id = AMFVideoEncoderVCE_AVC;
> +            break;
> +        case AV_CODEC_ID_HEVC:
> +            codec_id = AMFVideoEncoder_HEVC;
> +            break;
> +        default:
> +            break;
> +    }
> +    AMF_RETURN_IF_FALSE(ctx, codec_id != NULL, AVERROR(EINVAL),
> "Codec %d is not supported\n", avctx->codec->id); +
> +    ctx->format = amf_av_to_amf_format(avctx->pix_fmt);
> +    AMF_RETURN_IF_FALSE(ctx, ctx->format != AMF_SURFACE_UNKNOWN,
> AVERROR(EINVAL), "Format %d is not supported\n", avctx->pix_fmt); +
> +    res = ctx->factory->pVtbl->CreateComponent(ctx->factory,
> ctx->context, codec_id, &ctx->encoder);
> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK,
> AVERROR_ENCODER_NOT_FOUND, "CreateComponent(%ls) failed with error
> %d\n", codec_id, res); +
> +    return 0;
> +}
> +
> +int av_cold ff_amf_encode_close(AVCodecContext *avctx)
> +{
> +    AmfContext      *ctx = avctx->priv_data;
> +    if (ctx->delayed_surface)
> +    {
> +        ctx->delayed_surface->pVtbl->Release(ctx->delayed_surface);
> +        ctx->delayed_surface = NULL;
> +    }
> +
> +    if (ctx->encoder) {
> +        ctx->encoder->pVtbl->Terminate(ctx->encoder);
> +        ctx->encoder->pVtbl->Release(ctx->encoder);
> +        ctx->encoder = NULL;
> +    }
> +
> +    if (ctx->context) {
> +        ctx->context->pVtbl->Terminate(ctx->context);
> +        ctx->context->pVtbl->Release(ctx->context);
> +        ctx->context = NULL;
> +    }
> +    av_buffer_unref(&ctx->hw_device_ctx);
> +    av_buffer_unref(&ctx->hw_frames_ctx);
> +
> +    if (ctx->trace) {
> +        ctx->trace->pVtbl->UnregisterWriter(ctx->trace,
> FFMPEG_AMF_WRITER_ID);
> +    }
> +    if (ctx->library) {
> +        dlclose(ctx->library);
> +        ctx->library = NULL;
> +    }
> +    ctx->trace = NULL;
> +    ctx->debug = NULL;
> +    ctx->factory = NULL;
> +    ctx->version = 0;
> +    ctx->delayed_drain = 0;
> +    av_frame_free(&ctx->delayed_frame);
> +    av_fifo_freep(&ctx->timestamp_list);
> +
> +    return 0;
> +}
> +
> +static int amf_copy_surface(AVCodecContext *avctx, const AVFrame
> *frame,
> +    AMFSurface* surface)
> +{
> +    AVFrame        *sw_frame = NULL;
> +    AMFPlane       *plane = NULL;
> +    uint8_t        *dst_data[4];
> +    int             dst_linesize[4];
> +    int             ret = 0;
> +    int             planes;
> +
> +    if (frame->hw_frames_ctx && is_hwaccel_pix_fmt(frame->format)) {
> +        if (!(sw_frame = av_frame_alloc())) {
> +            av_log(avctx, AV_LOG_ERROR, "Can not alloc frame\n");
> +            ret = AVERROR(ENOMEM);
> +            goto fail;
> +        }
> +        if ((ret = av_hwframe_transfer_data(sw_frame, frame, 0)) <
> 0) {
> +            av_log(avctx, AV_LOG_ERROR, "Error transferring the data
> to system memory\n");
> +            ret = AVERROR(EINVAL);
> +            goto fail;
> +        }
> +        frame = sw_frame;
> +    }
> +    planes = (int)surface->pVtbl->GetPlanesCount(surface);
> +    if (planes > amf_countof(dst_data)) {
> +        av_log(avctx, AV_LOG_ERROR, "Invalid number of planes %d in
> surface\n", planes);
> +        ret = AVERROR(EINVAL);
> +        goto fail;
> +    }
> +
> +    for (int i = 0; i < planes; i++) {
> +        plane = surface->pVtbl->GetPlaneAt(surface, i);
> +        dst_data[i] = plane->pVtbl->GetNative(plane);
> +        dst_linesize[i] = plane->pVtbl->GetHPitch(plane);
> +    }
> +    av_image_copy(dst_data, dst_linesize,
> +        (const uint8_t**)frame->data, frame->linesize, frame->format,
> +        avctx->width, avctx->height);
> +
> +fail:
> +    if (sw_frame){
> +        av_frame_free(&sw_frame);
> +    }
> +    return ret;
> +}
> +
> +static inline int timestamp_queue_enqueue(AVCodecContext *avctx,
> int64_t timestamp) +{
> +    AmfContext         *ctx = avctx->priv_data;
> +    if (av_fifo_space(ctx->timestamp_list) < sizeof(timestamp)){
> +        if (av_fifo_grow(ctx->timestamp_list, sizeof(timestamp)) <
> 0) {
> +            return AVERROR(ENOMEM);
> +        }
> +    }
> +    av_fifo_generic_write(ctx->timestamp_list, &timestamp,
> sizeof(timestamp), NULL);
> +    return 0;
> +}
> +
> +static int amf_copy_buffer(AVCodecContext *avctx, AVPacket *pkt,
> AMFBuffer *buffer) +{
> +    AmfContext             *ctx = avctx->priv_data;
> +    int                     ret;
> +    AMFVariantStruct        var = {0};
> +    int64_t                 timestamp = AV_NOPTS_VALUE;
> +    int64_t                 size = buffer->pVtbl->GetSize(buffer);
> +
> +    if ((ret = ff_alloc_packet2(avctx, pkt, size, 0)) < 0) {
> +        return ret;
> +    }
> +    memcpy(pkt->data, buffer->pVtbl->GetNative(buffer), size);
> +
> +    switch (avctx->codec->id) {
> +        case AV_CODEC_ID_H264:
> +            buffer->pVtbl->GetProperty(buffer,
> AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE, &var);
> +            if(var.int64Value ==
> AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_IDR) {
> +                pkt->flags = AV_PKT_FLAG_KEY;
> +            }
> +            break;
> +        case AV_CODEC_ID_HEVC:
> +            buffer->pVtbl->GetProperty(buffer,
> AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE, &var);
> +            if (var.int64Value ==
> AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_IDR) {
> +                pkt->flags = AV_PKT_FLAG_KEY;
> +            }
> +            break;
> +        default:
> +            break;
> +    }
> +
> +    buffer->pVtbl->GetProperty(buffer, PTS_PROP, &var);
> +
> +    pkt->pts = var.int64Value; // original pts
> +
> +
> +    AMF_RETURN_IF_FALSE(ctx, av_fifo_size(ctx->timestamp_list) > 0,
> AVERROR_UNKNOWN, "timestamp_list is empty\n"); +
> +    av_fifo_generic_read(ctx->timestamp_list, &timestamp,
> sizeof(timestamp), NULL); +
> +    // calc dts shift if max_b_frames > 0
> +    if (avctx->max_b_frames > 0 && ctx->dts_delay == 0){
> +        int64_t timestamp_last = AV_NOPTS_VALUE;
> +        AMF_RETURN_IF_FALSE(ctx, av_fifo_size(ctx->timestamp_list) >
> 0, AVERROR_UNKNOWN,
> +            "timestamp_list is empty while max_b_frames = %d\n",
> avctx->max_b_frames);
> +        av_fifo_generic_peek_at(
> +            ctx->timestamp_list, 
> +            &timestamp_last,
> +            (av_fifo_size(ctx->timestamp_list) / sizeof(timestamp) -
> 1) * sizeof(timestamp_last),
> +            sizeof(timestamp_last), 
> +            NULL);
> +        if (timestamp < 0 || timestamp_last < AV_NOPTS_VALUE) {
> +            return AVERROR(ERANGE);
> +        }
> +        ctx->dts_delay = timestamp_last - timestamp;
> +    }
> +    pkt->dts = timestamp - ctx->dts_delay;
> +    return 0;
> +}
> +
> +// amfenc API implmentation
> +int ff_amf_encode_init(AVCodecContext *avctx)
> +{
> +    AmfContext     *ctx = avctx->priv_data;
> +    int             ret;
> +
> +    ctx->factory = NULL;
> +    ctx->debug = NULL;
> +    ctx->trace = NULL;
> +    ctx->context = NULL;
> +    ctx->encoder = NULL;
> +    ctx->library = NULL;
> +    ctx->version = 0;
> +    ctx->eof = 0;
> +    ctx->format = 0;
> +    ctx->tracer.vtbl = NULL;
> +    ctx->tracer.avctx = NULL;
> +
> +    if ((ret = amf_load_library(avctx)) == 0) {
> +        if ((ret = amf_init_context(avctx)) == 0) {
> +            if ((ret = amf_init_encoder(avctx)) == 0) {
> +                return 0;
> +            }
> +        }
> +    }
> +    ff_amf_encode_close(avctx);
> +    return ret;
> +}
> +
> +
> +int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame)
> +{
> +    AMF_RESULT      res = AMF_OK;
> +    AmfContext     *ctx = avctx->priv_data;
> +    AMFSurface     *surface = NULL;
> +    int             ret;
> +
> +    if (!ctx->encoder)
> +        return AVERROR(EINVAL);
> +
> +    if (!frame) { // submit drain
> +        if (!ctx->eof) { // submit drain one time only
> +            if (ctx->delayed_surface != NULL) {
> +                ctx->delayed_drain = 1; // input queue is full:
> resubmit Drain() in ff_amf_receive_packet
> +            } else if(!ctx->delayed_drain){
> +                res = ctx->encoder->pVtbl->Drain(ctx->encoder);
> +                if (res == AMF_INPUT_FULL) {
> +                    ctx->delayed_drain = 1; // input queue is full:
> resubmit Drain() in ff_amf_receive_packet
> +                }else {
> +                    if (res == AMF_OK) {
> +                        ctx->eof = 1; // drain started
> +                    }
> +                    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK,
> AVERROR_UNKNOWN, "Drain() failed with error %d\n", res);
> +                }
> +            }
> +        }else{
> +            return AVERROR_EOF;
> +        }
> +    } else { // submit frame
> +        if (ctx->delayed_surface != NULL) {
> +            return AVERROR(EAGAIN); // should not happen when called
> from ffmpeg, other clients may resubmit
> +        }
> +        // prepare surface from frame
> +        if (frame->hw_frames_ctx && ( // HW frame detected
> +            // check if the same hw_frames_ctx as used in
> initialization
> +            (ctx->hw_frames_ctx && frame->hw_frames_ctx->data ==
> ctx->hw_frames_ctx->data) ||
> +            // check if the same hw_device_ctx as used in
> initialization
> +            (ctx->hw_device_ctx &&
> ((AVHWFramesContext*)frame->hw_frames_ctx->data)->device_ctx ==
> +            (AVHWDeviceContext*)ctx->hw_device_ctx->data)
> +        )) {
> +#if CONFIG_D3D11VA
> +            GUID             AMFTextureArrayIndexGUID =
> AMFTextureArrayIndexGUIDDef;
> +            ID3D11Texture2D *texture =
> (ID3D11Texture2D*)frame->data[0]; // actual texture
> +            int index = (int)(size_t)frame->data[1]; // index is a
> slice in texture array is - set to tell AMF which slice to use
> +            texture->lpVtbl->SetPrivateData(texture,
> &AMFTextureArrayIndexGUID, sizeof(index), &index); +
> +            res =
> ctx->context->pVtbl->CreateSurfaceFromDX11Native(ctx->context,
> texture, &surface, NULL); // wrap to AMF surface
> +            AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM),
> "CreateSurfaceFromDX11Native() failed  with error %d\n", res); +
> +            // input HW surfaces can be vertically aligned by 16;
> tell AMF the real size
> +            surface->pVtbl->SetCrop(surface, 0, 0, frame->width,
> frame->height); +#endif
> +        } else {
> +            res = ctx->context->pVtbl->AllocSurface(ctx->context,
> AMF_MEMORY_HOST, ctx->format, avctx->width, avctx->height, &surface);
> +            AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM),
> "AllocSurface() failed  with error %d\n", res);
> +            amf_copy_surface(avctx, frame, surface);
> +        }
> +        surface->pVtbl->SetPts(surface, frame->pts);
> +        AMF_ASSIGN_PROPERTY_INT64(res, surface, PTS_PROP,
> frame->pts); +
> +        switch (avctx->codec->id) {
> +        case AV_CODEC_ID_H264:
> +            AMF_ASSIGN_PROPERTY_INT64(res, surface,
> AMF_VIDEO_ENCODER_INSERT_AUD, !!ctx->aud);
> +            break;
> +        case AV_CODEC_ID_HEVC:
> +            AMF_ASSIGN_PROPERTY_INT64(res, surface,
> AMF_VIDEO_ENCODER_HEVC_INSERT_AUD, !!ctx->aud);
> +            break;
> +        default:
> +            break;
> +        }
> +
> +
> +        // submit surface
> +        res = ctx->encoder->pVtbl->SubmitInput(ctx->encoder,
> (AMFData*)surface);
> +        if (res == AMF_INPUT_FULL) { // handle full queue
> +            //store surface for later submission
> +            ctx->delayed_surface = surface;
> +            if (surface->pVtbl->GetMemoryType(surface) ==
> AMF_MEMORY_DX11) {
> +                av_frame_ref(ctx->delayed_frame, frame);
> +            }
> +        } else {
> +            surface->pVtbl->Release(surface);
> +            AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN,
> "SubmitInput() failed with error %d\n", res); +
> +            if ((ret = timestamp_queue_enqueue(avctx, frame->pts)) <
> 0) {
> +                return ret;
> +            }
> +
> +        }
> +    }
> +    return 0;
> +}
> +int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
> +{
> +    int             ret;
> +    AMF_RESULT      res;
> +    AMF_RESULT      res_query;
> +    AmfContext     *ctx = avctx->priv_data;
> +    AMFData        *data = NULL;
> +    int             block_and_wait;
> +
> +    if (!ctx->encoder)
> +        return AVERROR(EINVAL);
> +
> +    do {
> +        block_and_wait = 0;
> +        // poll data
> +        res_query = ctx->encoder->pVtbl->QueryOutput(ctx->encoder,
> &data);
> +        if (data) {
> +            // copy data to packet
> +            AMFBuffer* buffer;
> +            AMFGuid guid = IID_AMFBuffer();
> +            data->pVtbl->QueryInterface(data, &guid,
> (void**)&buffer); // query for buffer interface
> +            ret = amf_copy_buffer(avctx, avpkt, buffer);
> +
> +            buffer->pVtbl->Release(buffer);
> +            data->pVtbl->Release(data);
> +
> +            AMF_RETURN_IF_FALSE(ctx, ret >= 0, ret,
> "amf_copy_buffer() failed with error %d\n", ret); +
> +            if (ctx->delayed_surface != NULL) { // try to resubmit
> frame
> +                res = ctx->encoder->pVtbl->SubmitInput(ctx->encoder,
> (AMFData*)ctx->delayed_surface);
> +                if (res != AMF_INPUT_FULL) {
> +                    int64_t pts =
> ctx->delayed_surface->pVtbl->GetPts(ctx->delayed_surface);
> +
> ctx->delayed_surface->pVtbl->Release(ctx->delayed_surface);
> +                    ctx->delayed_surface = NULL;
> +                    av_frame_unref(ctx->delayed_frame);
> +                    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK,
> AVERROR_UNKNOWN, "Repeated SubmitInput() failed with error %d\n",
> res); +
> +                    if ((ret = timestamp_queue_enqueue(avctx, pts))
> < 0) {
> +                        return ret;
> +                    }
> +                }else {
> +                    av_log(avctx, AV_LOG_WARNING, "Data acquired but
> delayed frame submission got AMF_INPUT_FULL- should not happen\n");
> +                }
> +            }else if (ctx->delayed_drain) { // try to resubmit drain
> +                res = ctx->encoder->pVtbl->Drain(ctx->encoder);
> +                if (res != AMF_INPUT_FULL) {
> +                    ctx->delayed_drain = 0;
> +                    ctx->eof = 1; // drain started
> +                    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK,
> AVERROR_UNKNOWN, "Repeated Drain() failed with error %d\n", res);
> +                }else {
> +                    av_log(avctx, AV_LOG_WARNING, "Data acquired but
> delayed drain submission got AMF_INPUT_FULL- should not happen\n");
> +                }
> +            }
> +        }else if (ctx->delayed_surface != NULL || ctx->delayed_drain
> || (ctx->eof && res_query != AMF_EOF)) {
> +            block_and_wait = 1;
> +            av_usleep(1000); // wait and poll again
> +        }
> +    } while (block_and_wait);
> +
> +    if (res_query == AMF_EOF) {
> +        ret = AVERROR_EOF;
> +    }else if (data == NULL) {
> +        ret = AVERROR(EAGAIN);
> +    }else {
> +        ret = 0;
> +    }
> +    return ret;
> +}
> diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
> new file mode 100644
> index 0000000..fb19ed4
> --- /dev/null
> +++ b/libavcodec/amfenc.h
> @@ -0,0 +1,143 @@
> +/*
> +* This file is part of FFmpeg.
> +*
> +* FFmpeg is free software; you can redistribute it and/or
> +* modify it under the terms of the GNU Lesser General Public
> +* License as published by the Free Software Foundation; either
> +* version 2.1 of the License, or (at your option) any later version.
> +*
> +* FFmpeg is distributed in the hope that it will be useful,
> +* but WITHOUT ANY WARRANTY; without even the implied warranty of
> +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +* Lesser General Public License for more details.
> +*
> +* You should have received a copy of the GNU Lesser General Public
> +* License along with FFmpeg; if not, write to the Free Software
> +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301 USA +*/
> +
> +#ifndef AVCODEC_AMFENC_H
> +#define AVCODEC_AMFENC_H
> +
> +#include "config.h"
> +#include "avcodec.h"
> +#include "compat/amd/amfsdkenc.h"
> +#include "libavutil/fifo.h"
> +
> +
> +/**
> +* AMF trace writer callback class
> +* Used to capture all AMF logging
> +*/
> +
> +typedef struct AmfTraceWriter {
> +    AMFTraceWriterVtbl* vtbl;
> +    AVCodecContext      *avctx;
> +} AmfTraceWriter;
> +
> +/**
> +* AMF encoder context
> +*/
> +
> +typedef struct AmfContext {
> +    AVClass            *avclass;
> +    // access to AMF runtime
> +    amf_handle          library; ///< handle to DLL library
> +    AMFFactory         *factory; ///< pointer to AMF factory
> +    AMFDebug*           debug;   ///< pointer to AMF debug interface
> +    AMFTrace*           trace;   ///< pointer to AMF trace interface
> +
> +    amf_uint64          version; ///< version of AMF runtime
> +    AmfTraceWriter      tracer;  ///< AMF writer registered with AMF
> +    AMFContext         *context; ///< AMF context
> +    //encoder
> +    AMFComponent*       encoder; ///< AMF encoder object
> +    amf_bool            eof;     ///< flag indicating EOF happened
> +    AMF_SURFACE_FORMAT  format;  ///< AMF surface format
> +
> +    AVBufferRef        *hw_device_ctx; ///< pointer to HW
> accelerator (decoder)
> +    AVBufferRef        *hw_frames_ctx; ///< pointer to HW
> accelerator (frame allocator) +
> +    // helpers to handle async calls
> +    int                 delayed_drain;
> +    AMFSurface         *delayed_surface;
> +    AVFrame            *delayed_frame;
> +
> +    // shift dts back by max_b_frames in timing
> +    AVFifoBuffer       *timestamp_list;
> +    int64_t             dts_delay;
> +
> +    // common encoder option options
> +
> +    int                 log_to_dbg;
> +
> +    // Static options, have to be set before Init() call
> +    int                 usage;
> +    int                 profile;
> +    int                 level;
> +    int                 preanalysis;
> +    int                 quality;
> +    int                 b_frame_delta_qp;
> +    int                 ref_b_frame_delta_qp;
> +
> +    // Dynamic options, can be set after Init() call
> +
> +    int                 rate_control_mode;
> +    int                 enforce_hrd;
> +    int                 filler_data;
> +    int                 enable_vbaq;
> +    int                 skip_frame;
> +    int                 qp_i;
> +    int                 qp_p;
> +    int                 qp_b;
> +    int                 max_au_size;
> +    int                 header_spacing;
> +    int                 b_frame_ref;
> +    int                 intra_refresh_mb;
> +    int                 coding_mode;
> +    int                 me_half_pel;
> +    int                 me_quarter_pel;
> +    int                 aud;
> +
> +    // HEVC - specific options
> +
> +    int                 gops_per_idr;
> +    int                 header_insertion_mode;
> +    int                 min_qp_i;
> +    int                 max_qp_i;
> +    int                 min_qp_p;
> +    int                 max_qp_p;
> +    int                 tier;
> +} AmfContext;
> +
> +/**
> +* Common encoder initization function
> +*/
> +int ff_amf_encode_init(AVCodecContext *avctx);
> +/**
> +* Common encoder termination function
> +*/
> +int ff_amf_encode_close(AVCodecContext *avctx);
> +
> +/**
> +* Ecoding one frame - common function for all AMF encoders
> +*/
> +
> +int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame);
> +int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
> +
> +/**
> +* Supported formats
> +*/
> +extern const enum AVPixelFormat ff_amf_pix_fmts[];
> +
> +/**
> +* Error handling helper
> +*/
> +#define AMF_RETURN_IF_FALSE(avctx, exp, ret_value, /*message,*/ ...)
> \
> +    if (!(exp)) { \
> +        av_log(avctx, AV_LOG_ERROR, __VA_ARGS__); \
> +        return ret_value; \
> +    }
> +
> +#endif //AVCODEC_AMFENC_H
> diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
> new file mode 100644
> index 0000000..ae13bba
> --- /dev/null
> +++ b/libavcodec/amfenc_h264.c
> @@ -0,0 +1,397 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301 USA
> + */
> +
> +
> +#include "libavutil/internal.h"
> +#include "libavutil/opt.h"
> +#include "amfenc.h"
> +#include "internal.h"
> +
> +#define OFFSET(x) offsetof(AmfContext, x)
> +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
> +
> +static const AVOption options[] = {
> +    // Static
> +    /// Usage
> +    { "usage",          "Encoder Usage",        OFFSET(usage),
> AV_OPT_TYPE_INT,   { .i64 =
> AMF_VIDEO_ENCODER_USAGE_TRANSCONDING      },
> AMF_VIDEO_ENCODER_USAGE_TRANSCONDING, AMF_VIDEO_ENCODER_USAGE_WEBCAM,
> VE, "usage" },
> +    { "transcoding",    "Generic Transcoding",  0,
> AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_USAGE_TRANSCONDING      }, 0, 0, VE, "usage" },
> +    { "ultralowlatency","",                     0,
> AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY }, 0, 0, VE, "usage" },
> +    { "lowlatency",     "",                     0,
> AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY       }, 0, 0, VE, "usage" },
> +    { "webcam",         "Webcam",               0,
> AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_USAGE_WEBCAM            }, 0, 0, VE, "usage" }, +
> +    /// Profile,
> +    { "profile",        "Profile",
> OFFSET(profile),AV_OPT_TYPE_INT, { .i64 =
> AMF_VIDEO_ENCODER_PROFILE_MAIN       },
> AMF_VIDEO_ENCODER_PROFILE_BASELINE,
> AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH, VE, "profile" },
> +    { "main",           "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN     }, 0,
> 0, VE, "profile" },
> +    { "high",           "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_HIGH     }, 0,
> 0, VE, "profile" },
> +    { "constrained_baseline",           "",     0,
> AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE }, 0, 0, VE,
> "profile" },
> +    { "constrained_high",           "",         0,
> AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH }, 0, 0, VE, "profile" }, +
> +    /// Profile Level
> +    { "level",          "Profile Level",        OFFSET(level),
> AV_OPT_TYPE_INT,   { .i64 = 0  }, 0, 62, VE, "level" },
> +    { "auto",           "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 0  }, 0, 0,  VE, "level" },
> +    { "1.0",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 10 }, 0, 0,  VE, "level" },
> +    { "1.1",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 11 }, 0, 0,  VE, "level" },
> +    { "1.2",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 12 }, 0, 0,  VE, "level" },
> +    { "1.3",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 13 }, 0, 0,  VE, "level" },
> +    { "2.0",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 20 }, 0, 0,  VE, "level" },
> +    { "2.1",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 21 }, 0, 0,  VE, "level" },
> +    { "2.2",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 22 }, 0, 0,  VE, "level" },
> +    { "3.0",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 30 }, 0, 0,  VE, "level" },
> +    { "3.1",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 31 }, 0, 0,  VE, "level" },
> +    { "3.2",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 32 }, 0, 0,  VE, "level" },
> +    { "4.0",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 40 }, 0, 0,  VE, "level" },
> +    { "4.1",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 41 }, 0, 0,  VE, "level" },
> +    { "4.2",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 42 }, 0, 0,  VE, "level" },
> +    { "5.0",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 50 }, 0, 0,  VE, "level" },
> +    { "5.1",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 51 }, 0, 0,  VE, "level" },
> +    { "5.2",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 52 }, 0, 0,  VE, "level" },
> +    { "6.0",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 60 }, 0, 0,  VE, "level" },
> +    { "6.1",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 61 }, 0, 0,  VE, "level" },
> +    { "6.2",            "",                     0,
> AV_OPT_TYPE_CONST, { .i64 = 62 }, 0, 0,  VE, "level" }, +
> +
> +    /// Quality Preset
> +    { "quality",        "Quality Preference",
> OFFSET(quality),    AV_OPT_TYPE_INT,   { .i64 =
> AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED    },
> AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED,
> AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY, VE, "quality" },
> +    { "speed",          "Prefer Speed",
> 0,                  AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED    },       0, 0, VE,
> "quality" },
> +    { "balanced",       "Balanced",
> 0,                  AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED },    0, 0, VE, "quality" },
> +    { "quality",        "Prefer Quality",
> 0,                  AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY  },     0, 0, VE,
> "quality" }, +
> +    // Dynamic
> +    /// Rate Control Method
> +    { "rc",             "Rate Control Method",
> OFFSET(rate_control_mode),  AV_OPT_TYPE_INT,   { .i64 =
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN },
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN,
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR, VE,
> "rc" },
> +    { "unknown",        "Unknown",
> 0,                          AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN                 }, 0,
> 0, VE, "rc" },
> +    { "cqp",            "Constant Quantization Parameter",
> 0,                          AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP             }, 0,
> 0, VE, "rc" },
> +    { "cbr",            "Constant Bitrate",
> 0,                          AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR                     }, 0,
> 0, VE, "rc" },
> +    { "vbr_peak",       "Peak Contrained Variable Bitrate",
> 0,                          AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR    }, 0,
> 0, VE, "rc" },
> +    { "vbr_latency",    "Latency Constrained Variable Bitrate",
> 0,                          AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR }, 0,
> 0, VE, "rc" }, +
> +    /// Enforce HRD, Filler Data, VBAQ, Frame Skipping
> +    { "enforce_hrd",    "Enforce HRD",
> OFFSET(enforce_hrd),        AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1,
> VE },
> +    { "filler_data",    "Filler Data Enable",
> OFFSET(filler_data),        AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1,
> VE },
> +    { "vbaq",           "Enable VBAQ",
> OFFSET(enable_vbaq),        AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1,
> VE },
> +    { "frame_skipping", "Rate Control Based Frame Skip",
> OFFSET(skip_frame),         AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1,
> VE }, +
> +    /// QP Values
> +    { "qp_i",           "Quantization Parameter for I-Frame",
> OFFSET(qp_i),               AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51,
> VE },
> +    { "qp_p",           "Quantization Parameter for P-Frame",
> OFFSET(qp_p),               AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51,
> VE },
> +    { "qp_b",           "Quantization Parameter for B-Frame",
> OFFSET(qp_b),               AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51,
> VE }, +
> +    /// Pre-Pass, Pre-Analysis, Two-Pass
> +    { "preanalysis",    "Pre-Analysis Mode",
> OFFSET(preanalysis),        AV_OPT_TYPE_BOOL,{ .i64 = 0 }, 0, 1, VE,
> NULL }, +
> +    /// Maximum Access Unit Size
> +    { "max_au_size",    "Maximum Access Unit Size for rate control
> (in bits)",   OFFSET(max_au_size),        AV_OPT_TYPE_INT, { .i64 =
> 0 }, 0, INT_MAX, VE }, +
> +    /// Header Insertion Spacing
> +    { "header_spacing", "Header Insertion Spacing",
> OFFSET(header_spacing),     AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1000,
> VE }, +
> +    /// B-Frames
> +    // BPicturesPattern=bf
> +    { "bf_delta_qp",    "B-Picture Delta QP",
> OFFSET(b_frame_delta_qp),   AV_OPT_TYPE_INT,  { .i64 = 4 }, -10, 10,
> VE },
> +    { "bf_ref",         "Enable Reference to B-Frames",
> OFFSET(b_frame_ref),        AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1,
> VE },
> +    { "bf_ref_delta_qp","Reference B-Picture Delta QP",
> OFFSET(ref_b_frame_delta_qp), AV_OPT_TYPE_INT,  { .i64 = 4 }, -10,
> 10, VE }, +
> +    /// Intra-Refresh
> +    { "intra_refresh_mb","Intra Refresh MBs Number Per Slot in
> Macroblocks",       OFFSET(intra_refresh_mb),    AV_OPT_TYPE_INT,
> { .i64 = 0 }, 0, INT_MAX, VE }, +
> +    /// coder
> +    { "coder",          "Coding Type",
> OFFSET(coding_mode),   AV_OPT_TYPE_INT,   { .i64 =
> AMF_VIDEO_ENCODER_UNDEFINED }, AMF_VIDEO_ENCODER_UNDEFINED,
> AMF_VIDEO_ENCODER_CALV, VE, "coder" },
> +    { "auto",           "Automatic",
> 0,                     AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_UNDEFINED }, 0, 0, VE, "coder" },
> +    { "cavlc",          "Context Adaptive Variable-Length Coding",
> 0,                  AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_CALV },      0, 0, VE, "coder" },
> +    { "cabac",          "Context Adaptive Binary Arithmetic Coding",
> 0,                AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_CABAC },     0, 0, VE, "coder" }, +
> +    { "me_half_pel",    "Enable ME Half Pixel",
> OFFSET(me_half_pel),   AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> +    { "me_quarter_pel", "Enable ME Quarter Pixel",
> OFFSET(me_quarter_pel),AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE }, +
> +    { "aud",            "Inserts AU Delimiter NAL unit",
> OFFSET(aud)          ,AV_OPT_TYPE_BOOL,  { .i64 = 0 }, 0, 1, VE }, +
> +    { "log_to_dbg",     "Enable AMF logging to debug output",
> OFFSET(log_to_dbg)    , AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, +
> +    
> +    { NULL }
> +};
> +
> +static av_cold int amf_encode_init_h264(AVCodecContext *avctx)
> +{
> +    int                              ret = 0;
> +    AMF_RESULT                       res = AMF_OK;
> +    AmfContext                      *ctx = avctx->priv_data;
> +    AMFVariantStruct                 var = { 0 };
> +    amf_int64                        profile = 0;
> +    amf_int64                        profile_level = 0;
> +    AMFBuffer                       *buffer;
> +    AMFGuid                          guid;
> +    AMFRate                          framerate;
> +    AMFSize                          framesize =
> AMFConstructSize(avctx->width, avctx->height);
> +    int                              deblocking_filter =
> (avctx->flags & AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0; +
> +    if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
> +        framerate = AMFConstructRate(avctx->framerate.num,
> avctx->framerate.den);
> +    }else {
> +        framerate = AMFConstructRate(avctx->time_base.den,
> avctx->time_base.num * avctx->ticks_per_frame);
> +    }
> +
> +    if ((ret = ff_amf_encode_init(avctx)) != 0)
> +        return ret;
> +
> +    // Static parameters
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_USAGE, ctx->usage); +
> +    AMF_ASSIGN_PROPERTY_SIZE(res, ctx->encoder,
> AMF_VIDEO_ENCODER_FRAMESIZE, framesize); +
> +    AMF_ASSIGN_PROPERTY_RATE(res, ctx->encoder,
> AMF_VIDEO_ENCODER_FRAMERATE, framerate); +
> +    switch (avctx->profile) {
> +    case FF_PROFILE_H264_BASELINE:
> +        profile = AMF_VIDEO_ENCODER_PROFILE_BASELINE;
> +        break;
> +    case FF_PROFILE_H264_MAIN:
> +        profile = AMF_VIDEO_ENCODER_PROFILE_MAIN;
> +        break;
> +    case FF_PROFILE_H264_HIGH:
> +        profile = AMF_VIDEO_ENCODER_PROFILE_HIGH;
> +        break;
> +    case FF_PROFILE_H264_CONSTRAINED_BASELINE:
> +        profile = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE;
> +        break;
> +    case (FF_PROFILE_H264_HIGH | FF_PROFILE_H264_CONSTRAINED):
> +        profile = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH;
> +        break;
> +    }
> +    if (profile == 0) {
> +        profile = ctx->profile;
> +    }
> +
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_PROFILE, profile); +
> +    profile_level = avctx->level;
> +    if (profile_level == FF_LEVEL_UNKNOWN) {
> +        profile_level = ctx->level;
> +    }
> +    if (profile_level != 0) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_PROFILE_LEVEL, profile_level);
> +    }
> +
> +    // Maximum Reference Frames
> +    if (avctx->refs != -1) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_MAX_NUM_REFRAMES, avctx->refs);
> +    }
> +    if (avctx->sample_aspect_ratio.den &&
> avctx->sample_aspect_ratio.num) {
> +        AMFRatio ratio =
> AMFConstructRatio(avctx->sample_aspect_ratio.num,
> avctx->sample_aspect_ratio.den);
> +        AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder,
> AMF_VIDEO_ENCODER_ASPECT_RATIO, ratio);
> +    }
> +
> +    /// Color Range (Partial/TV/MPEG or Full/PC/JPEG)
> +    if (avctx->color_range == AVCOL_RANGE_JPEG) {
> +        AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_FULL_RANGE_COLOR, 1);
> +    }
> +
> +    // autodetect rate control method
> +    if (ctx->rate_control_mode ==
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN) { 
> +        if (ctx->qp_i != -1 || ctx->qp_p != -1 || ctx->qp_b != -1) {
> +            ctx->rate_control_mode =
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP;
> +            av_log(ctx, AV_LOG_DEBUG, "Rate control turned to
> CQP\n");
> +        }else if (avctx->rc_max_rate > 0 ) {
> +            ctx->rate_control_mode =
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
> +            av_log(ctx, AV_LOG_DEBUG, "Rate control turned to Peak
> VBR\n");
> +        } else {
> +            ctx->rate_control_mode =
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR;
> +            av_log(ctx, AV_LOG_DEBUG, "Rate control turned to
> CBR\n");
> +        }
> +    }
> +
> +
> +    if (ctx->rate_control_mode ==
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_RATE_CONTROL_PREANALYSIS_ENABLE,
> AMF_VIDEO_ENCODER_PREENCODE_DISABLED);
> +        if (ctx->preanalysis)
> +            av_log(ctx, AV_LOG_WARNING, "Pre-Analysis is not
> supported by cqp Rate Control Method, automatically disabled\n");
> +    } else {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_RATE_CONTROL_PREANALYSIS_ENABLE, ctx->preanalysis);
> +    }
> +
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_QUALITY_PRESET, ctx->quality); +
> +    // Initialize Encoder
> +    res = ctx->encoder->pVtbl->Init(ctx->encoder, ctx->format,
> avctx->width, avctx->height);
> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG,
> "encoder->Init() failed with error %d\n", res); +
> +    // Dynamic parmaters
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD, ctx->rate_control_mode); +
> +    /// VBV Buffer
> +    if (avctx->rc_buffer_size != 0) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_VBV_BUFFER_SIZE, avctx->rc_buffer_size);
> +        if (avctx->rc_initial_buffer_occupancy != 0) {
> +            int amf_buffer_fullness =
> avctx->rc_initial_buffer_occupancy * 64 / avctx->rc_buffer_size;
> +            if (amf_buffer_fullness > 64)
> +                amf_buffer_fullness = 64;
> +            AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_INITIAL_VBV_BUFFER_FULLNESS, amf_buffer_fullness);
> +        }
> +    }
> +    /// Maximum Access Unit Size
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_MAX_AU_SIZE, ctx->max_au_size); +
> +    if (ctx->max_au_size)
> +        ctx->enforce_hrd = 1;
> +
> +    // QP Minimum / Maximum
> +    if (ctx->rate_control_mode ==
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_MIN_QP, 0);
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_MAX_QP, 51);
> +    } else {
> +        if (avctx->qmin != -1) {
> +            int qval = avctx->qmin > 51 ? 51 : avctx->qmin;
> +            AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_MIN_QP, qval);
> +        }
> +        if (avctx->qmax != -1) {
> +            int qval = avctx->qmax > 51 ? 51 : avctx->qmax;
> +            AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_MAX_QP, qval);
> +        }
> +    }
> +    // QP Values
> +    if (ctx->qp_i != -1)
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_QP_I, ctx->qp_i);
> +    if (ctx->qp_p != -1)
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_QP_P, ctx->qp_p);
> +    if (ctx->qp_b != -1)
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_QP_B, ctx->qp_b); +
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_TARGET_BITRATE, avctx->bit_rate); +
> +    if (ctx->rate_control_mode ==
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_PEAK_BITRATE, avctx->bit_rate);
> +    }
> +    if (avctx->rc_max_rate) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_PEAK_BITRATE, avctx->rc_max_rate);
> +    }else if (ctx->rate_control_mode ==
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR) {
> +        av_log(ctx, AV_LOG_WARNING, "rate control mode is
> PEAK_CONSTRAINED_VBR but rc_max_rate is not set\n");
> +    }
> +    // Enforce HRD, Filler Data, VBAQ, Frame Skipping, Deblocking
> Filter
> +    AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_ENFORCE_HRD, !!ctx->enforce_hrd);
> +    AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_FILLER_DATA_ENABLE, !!ctx->filler_data);
> +    AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_RATE_CONTROL_SKIP_FRAME_ENABLE, !!ctx->skip_frame);
> +    if (ctx->rate_control_mode ==
> AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
> +        AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_ENABLE_VBAQ, 0);
> +        if (ctx->enable_vbaq)
> +            av_log(ctx, AV_LOG_WARNING, "VBAQ is not supported by
> cqp Rate Control Method, automatically disabled\n");
> +    } else {
> +        AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_ENABLE_VBAQ, !!ctx->enable_vbaq);
> +    }
> +    AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_DE_BLOCKING_FILTER, !!deblocking_filter); +
> +    // B-Frames
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_B_PIC_PATTERN, avctx->max_b_frames);
> +    if (res != AMF_OK) {
> +        res = ctx->encoder->pVtbl->GetProperty(ctx->encoder,
> AMF_VIDEO_ENCODER_B_PIC_PATTERN, &var);
> +        av_log(ctx, AV_LOG_WARNING, "B-frames=%d is not supported by
> this GPU, switched to %d\n", 
> +            avctx->max_b_frames, (int)var.int64Value);
> +        avctx->max_b_frames = (int)var.int64Value;
> +    }
> +    if (avctx->max_b_frames) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_B_PIC_DELTA_QP, ctx->b_frame_delta_qp);
> +        AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_B_REFERENCE_ENABLE, !!ctx->b_frame_ref);
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_REF_B_PIC_DELTA_QP, ctx->ref_b_frame_delta_qp);
> +    }
> +
> +    // Keyframe Interval
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_IDR_PERIOD, avctx->gop_size); +
> +    // Header Insertion Spacing
> +    if (ctx->header_spacing >= 0)
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEADER_INSERTION_SPACING, ctx->header_spacing); +
> +    // Intra-Refresh, Slicing
> +    if (ctx->intra_refresh_mb > 0)
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_INTRA_REFRESH_NUM_MBS_PER_SLOT,
> ctx->intra_refresh_mb);
> +    if (avctx->slices > 1)
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_SLICES_PER_FRAME, avctx->slices); +
> +    // Coding
> +    if (ctx->coding_mode != 0)
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_CABAC_ENABLE, ctx->coding_mode); +
> +    // Motion Estimation
> +    AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_MOTION_HALF_PIXEL, !!ctx->me_half_pel);
> +    AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_MOTION_QUARTERPIXEL, !!ctx->me_quarter_pel); +
> +    // fill extradata
> +    res = AMFVariantInit(&var);
> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG,
> "AMFVariantInit() failed with error %d\n", res); +
> +    res = ctx->encoder->pVtbl->GetProperty(ctx->encoder,
> AMF_VIDEO_ENCODER_EXTRADATA, &var);
> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG,
> "GetProperty(AMF_VIDEO_ENCODER_EXTRADATA) failed with error %d\n",
> res);
> +    AMF_RETURN_IF_FALSE(ctx, var.pInterface != NULL, AVERROR_BUG,
> "GetProperty(AMF_VIDEO_ENCODER_EXTRADATA) returned NULL\n"); +
> +    guid = IID_AMFBuffer();
> +
> +    res = var.pInterface->pVtbl->QueryInterface(var.pInterface,
> &guid, (void**)&buffer); // query for buffer interface
> +    if (res != AMF_OK) {
> +        var.pInterface->pVtbl->Release(var.pInterface);
> +    }
> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG,
> "QueryInterface(IID_AMFBuffer) failed with error %d\n", res); +
> +    avctx->extradata_size = (int)buffer->pVtbl->GetSize(buffer);
> +    avctx->extradata = av_mallocz(avctx->extradata_size +
> AV_INPUT_BUFFER_PADDING_SIZE);
> +    if (!avctx->extradata) {
> +        buffer->pVtbl->Release(buffer);
> +        var.pInterface->pVtbl->Release(var.pInterface);
> +        return AVERROR(ENOMEM);
> +    }
> +    memcpy(avctx->extradata, buffer->pVtbl->GetNative(buffer),
> avctx->extradata_size); +
> +    buffer->pVtbl->Release(buffer);
> +    var.pInterface->pVtbl->Release(var.pInterface);
> +    
> +    return 0;
> +}
> +
> +static const AVCodecDefault defaults[] = {
> +    { "refs",       "-1"  },
> +    { "aspect",     "0"   },
> +    { "sar",        "0"   },
> +    { "qmin",       "-1"  },
> +    { "qmax",       "-1"  },
> +    { "b",          "2M"  },
> +    { "g",          "250" },
> +    { "slices",     "1"   },
> +    { NULL                },
> +};
> +
> +static const AVClass h264_amf_class = {
> +    .class_name = "h264_amf",
> +    .item_name = av_default_item_name,
> +    .option = options,
> +    .version = LIBAVUTIL_VERSION_INT,
> +};
> +//TODO declare as HW encoder when available
> +AVCodec ff_h264_amf_encoder = {
> +    .name           = "h264_amf",
> +    .long_name      = NULL_IF_CONFIG_SMALL("AMD AMF H.264 Encoder"),
> +    .type           = AVMEDIA_TYPE_VIDEO,
> +    .id             = AV_CODEC_ID_H264,
> +    .init           = amf_encode_init_h264,
> +    .send_frame     = ff_amf_send_frame,
> +    .receive_packet = ff_amf_receive_packet,
> +    .close          = ff_amf_encode_close,
> +    .priv_data_size = sizeof(AmfContext),
> +    .priv_class     = &h264_amf_class,
> +    .defaults       = defaults,
> +    .capabilities   = AV_CODEC_CAP_DELAY,
> +    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
> +    .pix_fmts       = ff_amf_pix_fmts,
> +};
> diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
> new file mode 100644
> index 0000000..b6536b3
> --- /dev/null
> +++ b/libavcodec/amfenc_hevc.c
> @@ -0,0 +1,327 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> 02110-1301 USA
> + */
> +
> +#include "libavutil/internal.h"
> +#include "libavutil/opt.h"
> +#include "amfenc.h"
> +#include "internal.h"
> +
> +#define OFFSET(x) offsetof(AmfContext, x)
> +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
> +static const AVOption options[] = {
> +    { "usage",          "Set the encoding usage",
> OFFSET(usage),          AV_OPT_TYPE_INT,   { .i64 =
> AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING },
> AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING,
> AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM, VE, "usage" },
> +    { "transcoding",    "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING },         0, 0, VE,
> "usage" },
> +    { "ultralowlatency","", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY },    0, 0, VE,
> "usage" },
> +    { "lowlatency",     "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY },          0, 0, VE,
> "usage" },
> +    { "webcam",         "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM },               0, 0, VE,
> "usage" }, +
> +    { "profile",        "Set the profile (default main)",
> OFFSET(profile),   AV_OPT_TYPE_INT,{ .i64 =
> AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN },
> AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN,
> AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN, VE, "profile" },
> +    { "main",           "", 0,
> AV_OPT_TYPE_CONST,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN }, 0,
> 0, VE, "profile" }, +
> +    { "profile_tier",   "Set the profile tier (default main)",
> OFFSET(tier), AV_OPT_TYPE_INT,{ .i64 =
> AMF_VIDEO_ENCODER_HEVC_TIER_MAIN }, AMF_VIDEO_ENCODER_HEVC_TIER_MAIN,
> AMF_VIDEO_ENCODER_HEVC_TIER_HIGH, VE, "tier" },
> +    { "main",           "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_TIER_MAIN }, 0, 0, VE, "tier" },
> +    { "high",           "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_TIER_HIGH }, 0, 0, VE, "tier" }, +
> +    { "level",          "Set the encoding level (default auto)",
> OFFSET(level), AV_OPT_TYPE_INT,{ .i64 = 0 }, 0, AMF_LEVEL_6_2, VE,
> "level" },
> +    { "auto",           "", 0, AV_OPT_TYPE_CONST, { .i64 =
> 0             }, 0, 0, VE, "level" },
> +    { "1.0",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_LEVEL_1   }, 0, 0, VE, "level" },
> +    { "2.0",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_LEVEL_2   }, 0, 0, VE, "level" },
> +    { "2.1",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_LEVEL_2_1 }, 0, 0, VE, "level" },
> +    { "3.0",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_LEVEL_3   }, 0, 0, VE, "level" },
> +    { "3.1",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_LEVEL_3_1 }, 0, 0, VE, "level" },
> +    { "4.0",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_LEVEL_4   }, 0, 0, VE, "level" },
> +    { "4.1",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_LEVEL_4_1 }, 0, 0, VE, "level" },
> +    { "5.0",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_LEVEL_5   }, 0, 0, VE, "level" },
> +    { "5.1",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_LEVEL_5_1 }, 0, 0, VE, "level" },
> +    { "5.2",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_LEVEL_5_2 }, 0, 0, VE, "level" },
> +    { "6.0",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_LEVEL_6   }, 0, 0, VE, "level" },
> +    { "6.1",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_LEVEL_6_1 }, 0, 0, VE, "level" },
> +    { "6.2",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_LEVEL_6_2 }, 0, 0, VE, "level" }, +
> +    { "quality",        "Set the encoding quality",
> OFFSET(quality),      AV_OPT_TYPE_INT,   { .i64 =
> AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED },
> AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY,
> AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED, VE, "quality" },
> +    { "balanced",       "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED }, 0, 0, VE,
> "quality" },
> +    { "speed",          "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED    }, 0, 0, VE,
> "quality" },
> +    { "quality",        "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY  }, 0, 0, VE,
> "quality" }, +
> +    { "rc",             "Set the rate control mode",
> OFFSET(rate_control_mode),   AV_OPT_TYPE_INT,   { .i64 =
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_UNKNOWN },
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_UNKNOWN,
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR, VE, "rc" },
> +    { "unknown",        "Unknown",                              0,
> AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_UNKNOWN                 },
> 0, 0, VE, "rc" },
> +    { "cqp",            "Constant Quantization Parameter",      0,
> AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP             },
> 0, 0, VE, "rc" },
> +    { "cbr",            "Constant Bitrate",                     0,
> AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR                     },
> 0, 0, VE, "rc" },
> +    { "vbr_peak",       "Peak Contrained Variable Bitrate",     0,
> AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR    },
> 0, 0, VE, "rc" },
> +    { "vbr_latency",    "Latency Constrained Variable Bitrate", 0,
> AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR },
> 0, 0, VE, "rc" }, +
> +    { "header_insertion_mode",        "Set header insertion mode",
> OFFSET(header_insertion_mode),      AV_OPT_TYPE_INT,{ .i64 =
> AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_NONE },
> AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_NONE,
> AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_IDR_ALIGNED, VE,
> "hdrmode" },
> +    { "none",           "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_NONE        }, 0, 0, VE,
> "hdrmode" },
> +    { "gop",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_GOP_ALIGNED }, 0, 0, VE,
> "hdrmode" },
> +    { "idr",            "", 0, AV_OPT_TYPE_CONST, { .i64 =
> AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_IDR_ALIGNED }, 0, 0, VE,
> "hdrmode" }, +
> +    { "gops_per_idr",    "GOPs per IDR 0-no IDR will be inserted",
> OFFSET(gops_per_idr),  AV_OPT_TYPE_INT,  { .i64 = 60 },  0, INT_MAX,
> VE },
> +    { "preanalysis",    "Enable preanalysis",
> OFFSET(preanalysis),   AV_OPT_TYPE_BOOL, { .i64 = 0  },  0, 1, VE},
> +    { "vbaq",           "Enable VBAQ",
> OFFSET(enable_vbaq),   AV_OPT_TYPE_BOOL, { .i64 = 0  },  0, 1, VE},
> +    { "enforce_hrd",    "Enforce HRD",
> OFFSET(enforce_hrd),   AV_OPT_TYPE_BOOL, { .i64 = 0  },  0, 1, VE},
> +    { "filler_data",    "Filler Data Enable",
> OFFSET(filler_data),   AV_OPT_TYPE_BOOL, { .i64 = 0  },  0, 1, VE},
> +    { "max_au_size",    "Maximum Access Unit Size for rate control
> (in bits)", OFFSET(max_au_size),   AV_OPT_TYPE_INT,{ .i64 = 0 }, 0,
> INT_MAX, VE},
> +    { "min_qp_i",       "min quantization parameter for I-frame",
> OFFSET(min_qp_i),      AV_OPT_TYPE_INT, { .i64 = -1  }, -1, 51, VE },
> +    { "max_qp_i",       "max quantization parameter for I-frame",
> OFFSET(max_qp_i),      AV_OPT_TYPE_INT, { .i64 = -1  }, -1, 51, VE },
> +    { "min_qp_p",       "min quantization parameter for P-frame",
> OFFSET(min_qp_p),      AV_OPT_TYPE_INT, { .i64 = -1  }, -1, 51, VE },
> +    { "max_qp_p",       "max quantization parameter for P-frame",
> OFFSET(max_qp_p),      AV_OPT_TYPE_INT, { .i64 = -1  }, -1, 51, VE },
> +    { "qp_p",           "quantization parameter for P-frame",
> OFFSET(qp_p),          AV_OPT_TYPE_INT, { .i64 = -1  }, -1, 51, VE },
> +    { "qp_i",           "quantization parameter for I-frame",
> OFFSET(qp_i),          AV_OPT_TYPE_INT, { .i64 = -1  }, -1, 51, VE },
> +    { "skip_frame",     "Rate Control Based Frame Skip",
> OFFSET(skip_frame),    AV_OPT_TYPE_BOOL,{ .i64 = 0   },  0, 1, VE },
> +    { "me_half_pel",    "Enable ME Half Pixel",
> OFFSET(me_half_pel),   AV_OPT_TYPE_BOOL,{ .i64 = 1   },  0, 1, VE },
> +    { "me_quarter_pel", "Enable ME Quarter Pixel ",
> OFFSET(me_quarter_pel),AV_OPT_TYPE_BOOL,{ .i64 = 1   },  0, 1, VE }, +
> +    { "aud",            "Inserts AU Delimiter NAL unit",
> OFFSET(aud)           ,AV_OPT_TYPE_BOOL,{ .i64 = 0 }, 0, 1, VE }, +
> +    { "log_to_dbg",     "Enable AMF logging to debug output",
> OFFSET(log_to_dbg), AV_OPT_TYPE_BOOL,{ .i64 = 0 }, 0, 1, VE },
> +    { NULL }
> +};
> +
> +static av_cold int amf_encode_init_hevc(AVCodecContext *avctx)
> +{
> +    int                 ret = 0;
> +    AMF_RESULT          res = AMF_OK;
> +    AmfContext         *ctx = avctx->priv_data;
> +    AMFVariantStruct    var = {0};
> +    amf_int64           profile = 0;
> +    amf_int64           profile_level = 0;
> +    AMFBuffer          *buffer;
> +    AMFGuid             guid;
> +    AMFRate             framerate;
> +    AMFSize             framesize = AMFConstructSize(avctx->width,
> avctx->height);
> +    int                 deblocking_filter = (avctx->flags &
> AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0; +
> +    if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
> +        framerate = AMFConstructRate(avctx->framerate.num,
> avctx->framerate.den);
> +    }else {
> +        framerate = AMFConstructRate(avctx->time_base.den,
> avctx->time_base.num * avctx->ticks_per_frame);
> +    }
> +
> +    if ((ret = ff_amf_encode_init(avctx)) < 0)
> +        return ret;
> +
> +    // init static parameters
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_USAGE, ctx->usage); +
> +    AMF_ASSIGN_PROPERTY_SIZE(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_FRAMESIZE, framesize); +
> +    AMF_ASSIGN_PROPERTY_RATE(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_FRAMERATE, framerate); +
> +    switch (avctx->profile) {
> +    case FF_PROFILE_HEVC_MAIN:
> +        profile = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN;
> +        break;
> +    default:
> +        break;
> +    }
> +    if (profile == 0) {
> +        profile = ctx->profile;
> +    }
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_PROFILE, profile); +
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_TIER, ctx->tier); +
> +    profile_level = avctx->level;
> +    if (profile_level == 0) {
> +        profile_level = ctx->level;
> +    }
> +    if (profile_level != 0) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_PROFILE_LEVEL, profile_level);
> +    }
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET, ctx->quality);
> +    // Maximum Reference Frames
> +    if (avctx->refs != 0) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_MAX_NUM_REFRAMES, avctx->refs);
> +    }
> +    // Aspect Ratio
> +    if (avctx->sample_aspect_ratio.den &&
> avctx->sample_aspect_ratio.num) {
> +        AMFRatio ratio =
> AMFConstructRatio(avctx->sample_aspect_ratio.num,
> avctx->sample_aspect_ratio.den);
> +        AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_ASPECT_RATIO, ratio);
> +    }
> +
> +    // Picture control properties
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_NUM_GOPS_PER_IDR, ctx->gops_per_idr);
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_GOP_SIZE, avctx->gop_size);
> +    if (avctx->slices > 1) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_SLICES_PER_FRAME, avctx->slices);
> +    }
> +    AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_DE_BLOCKING_FILTER_DISABLE, deblocking_filter);
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE,
> ctx->header_insertion_mode); +
> +    // Rate control
> +    // autodetect rate control method
> +    if (ctx->rate_control_mode ==
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_UNKNOWN) {
> +        if (ctx->min_qp_i != -1 || ctx->max_qp_i != -1 || 
> +            ctx->min_qp_p != -1 || ctx->max_qp_p != -1 ||
> +            ctx->qp_i !=-1 || ctx->qp_p != -1) {
> +            ctx->rate_control_mode =
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP;
> +            av_log(ctx, AV_LOG_DEBUG, "Rate control turned to
> CQP\n");
> +        }else if (avctx->rc_max_rate > 0) {
> +            ctx->rate_control_mode =
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
> +            av_log(ctx, AV_LOG_DEBUG, "Rate control turned to Peak
> VBR\n");
> +        }else {
> +            ctx->rate_control_mode =
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR;
> +            av_log(ctx, AV_LOG_DEBUG, "Rate control turned to
> CBR\n");
> +        }
> +    }
> +
> +
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD, ctx->rate_control_mode);
> +    if (avctx->rc_buffer_size) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_VBV_BUFFER_SIZE, avctx->rc_buffer_size); +
> +        if (avctx->rc_initial_buffer_occupancy != 0) {
> +            int amf_buffer_fullness =
> avctx->rc_initial_buffer_occupancy * 64 / avctx->rc_buffer_size;
> +            if (amf_buffer_fullness > 64)
> +                amf_buffer_fullness = 64;
> +            AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_INITIAL_VBV_BUFFER_FULLNESS,
> amf_buffer_fullness);
> +        }
> +    }
> +    // Pre-Pass, Pre-Analysis, Two-Pass
> +    AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_PREANALYSIS_ENABLE,
> ctx->preanalysis); +
> +    if (ctx->rate_control_mode ==
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP) {
> +        AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_ENABLE_VBAQ, false);
> +        if (ctx->enable_vbaq)
> +            av_log(ctx, AV_LOG_WARNING, "VBAQ is not supported by
> cqp Rate Control Method, automatically disabled\n");
> +    } else {
> +        AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_ENABLE_VBAQ, !!ctx->enable_vbaq);
> +    }
> +    AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_MOTION_HALF_PIXEL, ctx->me_half_pel);
> +    AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_MOTION_QUARTERPIXEL, ctx->me_quarter_pel); +
> +    // init encoder
> +    res = ctx->encoder->pVtbl->Init(ctx->encoder, ctx->format,
> avctx->width, avctx->height);
> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG,
> "encoder->Init() failed with error %d\n", res); +
> +    // init dynamic rate control params
> +    if (ctx->max_au_size)
> +        ctx->enforce_hrd = 1;
> +    AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_ENFORCE_HRD, ctx->enforce_hrd);
> +    AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_FILLER_DATA_ENABLE, ctx->filler_data); +
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_TARGET_BITRATE, avctx->bit_rate); +
> +    if (ctx->rate_control_mode ==
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_PEAK_BITRATE, avctx->bit_rate);
> +    } 
> +    if(avctx->rc_max_rate){
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_PEAK_BITRATE, avctx->rc_max_rate);
> +    }else if (ctx->rate_control_mode ==
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR) {
> +        av_log(ctx, AV_LOG_WARNING, "rate control mode is
> PEAK_CONSTRAINED_VBR but rc_max_rate is not set\n");
> +    }
> +
> +    // init dynamic picture control params
> +    AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_MAX_AU_SIZE, ctx->max_au_size); +
> +    if (ctx->min_qp_i != -1) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_MIN_QP_I, ctx->min_qp_i);
> +    }else if (avctx->qmin != -1) {
> +        int qval = avctx->qmin > 51 ? 51 : avctx->qmin;
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_MIN_QP_I, qval);
> +    }
> +    if (ctx->max_qp_i != -1) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_MAX_QP_I, ctx->max_qp_i);
> +    }else if (avctx->qmax != -1) {
> +        int qval = avctx->qmax > 51 ? 51 : avctx->qmax;
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_MAX_QP_I, qval);
> +    }
> +    if (ctx->min_qp_p != -1) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_MIN_QP_P, ctx->min_qp_p);
> +    }else if (avctx->qmin != -1) {
> +        int qval = avctx->qmin > 51 ? 51 : avctx->qmin;
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_MIN_QP_P, qval);
> +    }
> +    if (ctx->max_qp_p != -1) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_MAX_QP_P, ctx->max_qp_p);
> +    }else if (avctx->qmax != -1) {
> +        int qval = avctx->qmax > 51 ? 51 : avctx->qmax;
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_MAX_QP_P, qval);
> +    }
> +
> +    if (ctx->qp_p != -1) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_QP_I, ctx->qp_p);
> +    }
> +    if (ctx->qp_i != -1) {
> +        AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_QP_P, ctx->qp_i);
> +    }
> +    AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_SKIP_FRAME_ENABLE,
> ctx->skip_frame); + +
> +    // fill extradata
> +    res = AMFVariantInit(&var);
> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG,
> "AMFVariantInit() failed with error %d\n", res); +
> +    res = ctx->encoder->pVtbl->GetProperty(ctx->encoder,
> AMF_VIDEO_ENCODER_HEVC_EXTRADATA, &var);
> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG,
> "GetProperty(AMF_VIDEO_ENCODER_EXTRADATA) failed with error %d\n",
> res);
> +    AMF_RETURN_IF_FALSE(ctx, var.pInterface != NULL, AVERROR_BUG,
> "GetProperty(AMF_VIDEO_ENCODER_EXTRADATA) returned NULL\n"); +
> +    guid = IID_AMFBuffer();
> +
> +    res = var.pInterface->pVtbl->QueryInterface(var.pInterface,
> &guid, (void**)&buffer); // query for buffer interface
> +    if (res != AMF_OK) {
> +        var.pInterface->pVtbl->Release(var.pInterface);
> +    }
> +    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG,
> "QueryInterface(IID_AMFBuffer) failed with error %d\n", res); +
> +    avctx->extradata_size = (int)buffer->pVtbl->GetSize(buffer);
> +    avctx->extradata = av_mallocz(avctx->extradata_size +
> AV_INPUT_BUFFER_PADDING_SIZE);
> +    if (!avctx->extradata) {
> +        buffer->pVtbl->Release(buffer);
> +        var.pInterface->pVtbl->Release(var.pInterface);
> +        return AVERROR(ENOMEM);
> +    }
> +    memcpy(avctx->extradata, buffer->pVtbl->GetNative(buffer),
> avctx->extradata_size); +
> +    buffer->pVtbl->Release(buffer);
> +    var.pInterface->pVtbl->Release(var.pInterface);
> +
> +    return 0;
> +}
> +static const AVCodecDefault defaults[] = {
> +    { "refs",       "-1"  },
> +    { "aspect",     "0"   },
> +    { "sar",        "0"   },
> +    { "b",          "2M"  },
> +    { "g",          "250" },
> +    { "slices",     "1"   },
> +    { NULL                },
> +};
> +static const AVClass hevc_amf_class = {
> +    .class_name = "hevc_amf",
> +    .item_name = av_default_item_name,
> +    .option = options,
> +    .version = LIBAVUTIL_VERSION_INT,
> +};
> +//TODO declare as HW encoder when available
> +AVCodec ff_hevc_amf_encoder = {
> +    .name           = "hevc_amf",
> +    .long_name      = NULL_IF_CONFIG_SMALL("AMD AMF HEVC encoder"),
> +    .type           = AVMEDIA_TYPE_VIDEO,
> +    .id             = AV_CODEC_ID_HEVC,
> +    .init           = amf_encode_init_hevc,
> +    .send_frame     = ff_amf_send_frame,
> +    .receive_packet = ff_amf_receive_packet,
> +    .close          = ff_amf_encode_close,
> +    .priv_data_size = sizeof(AmfContext),
> +    .priv_class     = &hevc_amf_class,
> +    .defaults       = defaults,
> +    .capabilities   = AV_CODEC_CAP_DELAY,
> +    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
> +    .pix_fmts       = ff_amf_pix_fmts,
> +};

Mostly just repeating myself from the last thread, but I'm happy for
this to go in with the header. I don't have a problem with it being
bundled, and I separately think it's unfair to gate this change on a
possible change to our policy on bundled headers. If we choose to make
any changes there, then we'll deal with all the affected files
together; this change doesn't set any new precedent.

--phil


More information about the ffmpeg-devel mailing list