32#include <AMF/core/Surface.h>
33#include <AMF/core/Trace.h>
53#define FFMPEG_AMF_WRITER_ID L"ffmpeg_amf"
72 const wchar_t *scope,
const wchar_t *
message)
91 writer->
avctx = avctx;
111typedef struct AVAMFFormatMap {
141 return AMF_SURFACE_UNKNOWN;
157 switch (color_space) {
160 return AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601;
162 return AMF_VIDEO_CONVERTER_COLOR_PROFILE_601;
167 return AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709;
169 return AMF_VIDEO_CONVERTER_COLOR_PROFILE_709;
175 return AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020;
177 return AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020;
182 return AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN;
188 if (!display_meta || !hdrmeta)
192 const unsigned int luma_den = 10000;
193 hdrmeta->maxMasteringLuminance =
195 hdrmeta->minMasteringLuminance =
200 const unsigned int chroma_den = 50000;
201 hdrmeta->redPrimary[0] =
203 hdrmeta->redPrimary[1] =
205 hdrmeta->greenPrimary[0] =
207 hdrmeta->greenPrimary[1] =
209 hdrmeta->bluePrimary[0] =
211 hdrmeta->bluePrimary[1] =
213 hdrmeta->whitePoint[0] =
215 hdrmeta->whitePoint[1] =
224 if (!light_meta || !hdrmeta)
227 hdrmeta->maxContentLightLevel = (amf_uint16)light_meta->
MaxCLL;
228 hdrmeta->maxFrameAverageLightLevel = (amf_uint16)light_meta->
MaxFALL;
239 if (!
frame || !hdrmeta)
246 mastering_display =
NULL;
253 content_light =
NULL;
256 if (!mastering_display && !content_light)
263 if (!hdrmeta || !
frame)
268 const int chroma_den = 50000;
269 const int luma_den = 10000;
275 av_make_q(hdrmeta->redPrimary[0], chroma_den);
277 av_make_q(hdrmeta->redPrimary[1], chroma_den);
280 av_make_q(hdrmeta->greenPrimary[0], chroma_den);
282 av_make_q(hdrmeta->greenPrimary[1], chroma_den);
285 av_make_q(hdrmeta->bluePrimary[0], chroma_den);
287 av_make_q(hdrmeta->bluePrimary[1], chroma_den);
293 av_make_q(hdrmeta->maxMasteringLuminance, luma_den);
295 av_make_q(hdrmeta->maxMasteringLuminance, luma_den);
299 if (hdrmeta->maxContentLightLevel) {
306 light->
MaxCLL = hdrmeta->maxContentLightLevel;
307 light->
MaxFALL = hdrmeta->maxFrameAverageLightLevel;
341 const void *hwconfig,
439 AMFSurface *surface = (AMFSurface*)(
data);
440 surface->pVtbl->Release(surface);
447 AMFSurface* surface = (AMFSurface*)
dst->data[0];
449 uint8_t *dst_data[4];
457 if (
dst->hw_frames_ctx->data != (uint8_t *)
ctx ||
src->format !=
ctx->sw_format)
464 res = amf_device_ctx->
context->pVtbl->AllocSurface(amf_device_ctx->
context, AMF_MEMORY_HOST,
format,
dst->width,
dst->height, &surface);
466 dst->data[0] = (uint8_t *)surface;
474 planes = (int)surface->pVtbl->GetPlanesCount(surface);
478 plane = surface->pVtbl->GetPlaneAt(surface,
i);
479 dst_data[
i] = plane->pVtbl->GetNative(plane);
480 dst_linesize[
i] = plane->pVtbl->GetHPitch(plane);
492 AMFSurface* surface = (AMFSurface*)
src->data[0];
494 uint8_t *src_data[4];
502 if (
src->hw_frames_ctx->data != (uint8_t *)
ctx ||
dst->format !=
ctx->sw_format)
505 ret = surface->pVtbl->Convert(surface, AMF_MEMORY_HOST);
508 planes = (int)surface->pVtbl->GetPlanesCount(surface);
512 plane = surface->pVtbl->GetPlaneAt(surface,
i);
513 src_data[
i] = plane->pVtbl->GetNative(plane);
514 src_linesize[
i] = plane->pVtbl->GetHPitch(plane);
517 src_data, src_linesize,
dst->format,
527 AMF_RESULT res = AMF_NOT_INITIALIZED;
537 res = amf_ctx->
factory->pVtbl->GetTrace(amf_ctx->
factory, &trace);
564 AMFContext1 *context1 =
NULL;
567 if (!amf_ctx->
lock) {
579 if (res == AMF_OK || res == AMF_ALREADY_INITIALIZED) {
587 AMFGuid guid = IID_AMFContext1();
588 res = amf_ctx->
context->pVtbl->QueryInterface(amf_ctx->
context, &guid, (
void**)&context1);
591 res = context1->pVtbl->InitVulkan(context1,
NULL);
592 context1->pVtbl->Release(context1);
593 if (res != AMF_OK && res != AMF_ALREADY_INITIALIZED) {
594 if (res == AMF_NOT_SUPPORTED)
612 AMFQueryVersion_Fn version_fun;
615 amf_ctx->
library = dlopen(AMF_DLL_NAMEA, RTLD_NOW | RTLD_LOCAL);
619 init_fun = (AMFInit_Fn)dlsym(amf_ctx->
library, AMF_INIT_FUNCTION_NAME);
622 version_fun = (AMFQueryVersion_Fn)dlsym(amf_ctx->
library, AMF_QUERY_VERSION_FUNCTION_NAME);
629 res = init_fun(AMF_FULL_VERSION, &amf_ctx->
factory);
642 ret =
ctx->factory->pVtbl->GetTrace(
ctx->factory, &trace);
645 int level_amf = AMF_TRACE_TRACE;
646 amf_bool enable_log =
true;
650 level_amf = AMF_TRACE_ERROR;
656 level_amf = AMF_TRACE_ERROR;
660 level_amf = AMF_TRACE_WARNING;
663 level_amf = AMF_TRACE_INFO;
666 level_amf = AMF_TRACE_DEBUG;
669 level_amf = AMF_TRACE_TRACE;
672 if(
ctx->version == AMF_MAKE_FULL_VERSION(1, 4, 35, 0)){
673 level_amf = AMF_TRACE_WARNING;
676 trace->pVtbl->EnableWriter(trace, AMF_TRACE_WRITER_CONSOLE, 0);
677 trace->pVtbl->SetGlobalLevel(trace, level_amf);
684 trace->pVtbl->SetWriterLevel(trace, AMF_TRACE_WRITER_DEBUG_OUTPUT, level_amf);
685 trace->pVtbl->EnableWriter(trace, AMF_TRACE_WRITER_DEBUG_OUTPUT, enable_log);
689 ret =
ctx->factory->pVtbl->CreateContext(
ctx->factory, &
ctx->context);
691 AMF_ASSIGN_PROPERTY_INT64(ret,
ctx->context,
L"DeviceSurfaceCacheSize", 50 );
704 IDirect3DDevice9 *device;
705 HANDLE device_handle;
710 hr = IDirect3DDeviceManager9_OpenDeviceHandle(hwctx->
devmgr, &device_handle);
712 av_log(child_device_ctx,
AV_LOG_ERROR,
"Failed to open device handle for Direct3D9 device: %lx.\n", (
unsigned long)hr);
716 hr = IDirect3DDeviceManager9_LockDevice(hwctx->
devmgr, device_handle, &device, FALSE);
718 IDirect3DDeviceManager9_UnlockDevice(hwctx->
devmgr, device_handle, FALSE);
721 av_log(child_device_ctx,
AV_LOG_ERROR,
"Failed to lock device handle for Direct3D9 device: %lx.\n", (
unsigned long)hr);
726 IDirect3DDeviceManager9_CloseDeviceHandle(hwctx->
devmgr, device_handle);
733 IDirect3DDevice9_Release(device);
735 if (res != AMF_OK && res != AMF_ALREADY_INITIALIZED) {
736 if (res == AMF_NOT_SUPPORTED)
737 av_log(child_device_ctx,
AV_LOG_ERROR,
"AMF via D3D9 is not supported on the given device.\n");
739 av_log(child_device_ctx,
AV_LOG_ERROR,
"AMF failed to initialise on given D3D9 device: %d.\n", res);
753 if (res != AMF_OK && res != AMF_ALREADY_INITIALIZED) {
754 if (res == AMF_NOT_SUPPORTED)
755 av_log(child_device_ctx,
AV_LOG_ERROR,
"AMF via D3D11 is not supported on the given device.\n");
757 av_log(child_device_ctx,
AV_LOG_ERROR,
"AMF failed to initialise on the given D3D11 device: %d.\n", res);
770 AMFContext2 *context2 =
NULL;
771 AMFGuid guid = IID_AMFContext2();
772 res = amf_ctx->
context->pVtbl->QueryInterface(amf_ctx->
context, &guid, (
void**)&context2);
774 res = context2->pVtbl->InitDX12(context2, hwctx->
device, AMF_DX12);
775 context2->pVtbl->Release(context2);
776 if (res != AMF_OK && res != AMF_ALREADY_INITIALIZED) {
777 if (res == AMF_NOT_SUPPORTED)
778 av_log(child_device_ctx,
AV_LOG_ERROR,
"AMF via D3D12 is not supported on the given device.\n");
780 av_log(child_device_ctx,
AV_LOG_ERROR,
"AMF failed to initialise on the given D3D12 device: %d.\n", res);
793#if CONFIG_DXVA2 || CONFIG_D3D11VA
802 switch (child_device_ctx->
type) {
805 return amf_init_from_dxva2_device(amf_ctx, child_device_ctx);
809 return amf_init_from_d3d11_device(amf_ctx, child_device_ctx);
813 return amf_init_from_d3d12_device(amf_ctx, child_device_ctx);
816 av_log(child_device_ctx,
AV_LOG_ERROR,
"AMF initialisation from a %s device is not supported.\n",
824 AMFSurface1 *surface1 = hwmap->
priv;
831 AMFSurface *surface = (AMFSurface *)
src->data[0];
832 AMFSurface1 *surface1 =
NULL;
833 size_t *linesizes =
NULL;
835 int amf_mem_flags = AMF_MEMORY_CPU_NONE;
836 const AMFGuid guid = IID_AMFSurface1();
837 AMF_RESULT res = AMF_FAIL;
838 size_t plane_count = 0;
843 res =
AMF_IFACE_CALL(surface, QueryInterface, &guid, (
void**)&surface1);
847 amf_mem_flags |= AMF_MEMORY_CPU_READ;
850 amf_mem_flags |= AMF_MEMORY_CPU_WRITE;
861 res =
AMF_IFACE_CALL(surface1, Map, amf_mem_flags, plane_count, linesizes, (
void**)
map);
868 dst->height =
src->height;
874 for (
int plane = 0; plane < plane_count; ++plane)
876 dst->data[plane] =
map[plane];
877 dst->linesize[plane] = linesizes[plane];
887 if (ret < 0 && surface1 !=
NULL)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
static const char *const format[]
static void amf_free_amfsurface(void *opaque, uint8_t *data)
#define FFMPEG_AMF_WRITER_ID
#define AMF_RETURN_IF_FALSE(avctx, exp, ret_value,...)
Error handling helper.
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
refcounted data buffer API
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
AVBufferPool * av_buffer_pool_init2(size_t size, void *opaque, AVBufferRef *(*alloc)(void *opaque, size_t size), void(*pool_free)(void *opaque))
Allocate and initialize a buffer pool with a more complex allocator.
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
#define AVERROR_EXTERNAL
Generic error in an external library.
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
@ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL
Content light level (based on CTA-861.3).
@ AV_FRAME_DATA_MASTERING_DISPLAY_METADATA
Mastering display metadata associated with a video frame.
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
#define AV_LOG_PANIC
Something went really wrong and we will crash now.
#define AV_LOG_QUIET
Print no output.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int av_log_get_level(void)
Get the current log level.
static AVRational av_make_q(int num, int den)
Create an AVRational.
static double av_q2d(AVRational a)
Convert an AVRational to a double.
static void av_image_copy2(uint8_t *const dst_data[4], const int dst_linesizes[4], uint8_t *const src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Wrapper around av_image_copy() to workaround the limitation that the conversion from uint8_t * const ...
const char * av_hwdevice_get_type_name(enum AVHWDeviceType type)
Get the string name of an AVHWDeviceType.
int ff_hwframe_map_create(AVBufferRef *hwframe_ref, AVFrame *dst, const AVFrame *src, void(*unmap)(AVHWFramesContext *ctx, HWMapDescriptor *hwmap), void *priv)
@ AV_HWFRAME_MAP_READ
The mapping must be readable.
@ AV_HWFRAME_MAP_WRITE
The mapping must be writeable.
AVHWFrameTransferDirection
@ AV_HWDEVICE_TYPE_D3D11VA
@ AV_HWDEVICE_TYPE_D3D12VA
int av_amf_display_mastering_meta_to_hdrmeta(const AVMasteringDisplayMetadata *display_meta, AMFHDRMetadata *hdrmeta)
static int amf_device_create(AVHWDeviceContext *device_ctx, const char *device, AVDictionary *opts, int flags)
static void amf_unmap_frame(av_unused AVHWFramesContext *unused, HWMapDescriptor *hwmap)
static int amf_device_init(AVHWDeviceContext *ctx)
static void amf_unlock_default(void *opaque)
static int amf_load_library(AVAMFDeviceContext *amf_ctx, void *avcl)
static int amf_map_frame(AVHWFramesContext *device_ctx, AVFrame *dst, const AVFrame *src, int flags)
int av_amf_attach_hdr_metadata(AVFrame *frame, const AMFHDRMetadata *hdrmeta)
static void AMF_CDECL_CALL AMFTraceWriter_Write(AMFTraceWriter *pThis, const wchar_t *scope, const wchar_t *message)
static int amf_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
static int amf_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src)
const FormatMap format_map[]
const HWContextType ff_hwcontext_type_amf
int av_amf_light_metadata_to_hdrmeta(const AVContentLightMetadata *light_meta, AMFHDRMetadata *hdrmeta)
static void amf_device_uninit(AVHWDeviceContext *device_ctx)
static int amf_frames_init(AVHWFramesContext *ctx)
enum AMF_SURFACE_FORMAT av_av_to_amf_format(enum AVPixelFormat fmt)
static void amf_writer_free(void *opaque)
static enum AVPixelFormat supported_transfer_formats[]
static AmfTraceWriter * amf_writer_alloc(void *avctx)
static int amf_device_derive(AVHWDeviceContext *device_ctx, AVHWDeviceContext *child_device_ctx, AVDictionary *opts, int flags)
static int amf_get_buffer(AVHWFramesContext *ctx, AVFrame *frame)
static void amf_free_amfsurface(void *opaque, uint8_t *data)
int av_amf_extract_hdr_metadata(const AVFrame *frame, AMFHDRMetadata *hdrmeta)
enum AVPixelFormat av_amf_to_av_format(enum AMF_SURFACE_FORMAT fmt)
static void amf_lock_default(void *opaque)
static int amf_transfer_get_formats(AVHWFramesContext *ctx, enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats)
static void amf_dummy_free(void *opaque, uint8_t *data)
enum AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM av_amf_get_color_profile(enum AVColorRange color_range, enum AVColorSpace color_space)
static int amf_frames_get_constraints(AVHWDeviceContext *ctx, const void *hwconfig, AVHWFramesConstraints *constraints)
static AVBufferRef * amf_pool_alloc(void *opaque, size_t size)
static void AMF_CDECL_CALL AMFTraceWriter_Flush(AMFTraceWriter *pThis)
#define AMF_GOTO_FAIL_IF_FALSE(avctx, exp, ret_value,...)
#define AMF_IFACE_CALL(this, function,...)
An API-specific header for AV_HWDEVICE_TYPE_D3D11VA.
An API-specific header for AV_HWDEVICE_TYPE_D3D12VA.
An API-specific header for AV_HWDEVICE_TYPE_DXVA2.
static FFHWFramesContext * ffhwframesctx(AVHWFramesContext *ctx)
const VDPAUPixFmtMap * map
API-specific header for AV_HWDEVICE_TYPE_VULKAN.
static int ff_mutex_unlock(AVMutex *mutex)
static int ff_mutex_lock(AVMutex *mutex)
static int ff_mutex_destroy(AVMutex *mutex)
static int ff_mutex_init(AVMutex *mutex, const void *attr)
static const struct @257111027162314367033347246032313251342043035002 planes[]
Memory handling functions.
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
#define AV_PIX_FMT_RGBAF16
AVColorRange
Visual content value range.
@ AVCOL_RANGE_JPEG
Full range content.
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
@ AV_PIX_FMT_D3D12
Hardware surfaces for Direct3D 12.
@ AV_PIX_FMT_DXVA2_VLD
HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer.
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
@ AV_PIX_FMT_D3D11
Hardware surfaces for Direct3D11.
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
@ AV_PIX_FMT_AMF_SURFACE
HW acceleration through AMF.
#define AV_PIX_FMT_X2BGR10
AVColorSpace
YUV colorspace type.
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
@ AVCOL_SPC_BT2020_CL
ITU-R BT2020 constant luminance system.
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
#define FF_ARRAY_ELEMS(a)
We still need AVHWFramesContext to utilize our hardware memory otherwise, we will receive the error "...
This struct is allocated as AVHWDeviceContext.hwctx.
void(* lock)(void *lock_ctx)
void(* unlock)(void *lock_ctx)
int64_t version
version of AMF runtime
A reference to a data buffer.
Content light level needed by to transmit HDR over HDMI (CTA-861.3).
unsigned MaxFALL
Max average light level per frame (cd/m^2).
unsigned MaxCLL
Max content light level (cd/m^2).
This struct is allocated as AVHWDeviceContext.hwctx.
ID3D11Device * device
Device used for texture creation and access.
This struct is allocated as AVHWDeviceContext.hwctx.
ID3D12Device * device
Device used for objects creation and access.
This struct is allocated as AVHWDeviceContext.hwctx.
IDirect3DDeviceManager9 * devmgr
Structure to hold side data for an AVFrame.
This structure describes decoded (raw) audio or video data.
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
enum AVPixelFormat * valid_hw_formats
A list of possible values for format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
enum AVPixelFormat * valid_sw_formats
A list of possible values for sw_format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
This struct describes a set or pool of "hardware" frames (i.e.
AMFTraceWriterVtbl * vtblp
AVBufferPool * pool_internal
void * priv
Hardware-specific private data associated with the mapping.
#define av_malloc_array(a, b)
static AVFormatContext * ctx
static AVDictionary * opts
static enum AVPixelFormat supported_formats[]