49 #define FFMPEG_AMF_WRITER_ID L"ffmpeg_amf" 51 #define PTS_PROP L"PtsProp" 84 for (i = 0; i < amf_countof(format_map); i++) {
89 return AMF_SURFACE_UNKNOWN;
93 const wchar_t *scope,
const wchar_t *
message)
113 AMFQueryVersion_Fn version_fun;
128 ctx->
library = dlopen(AMF_DLL_NAMEA, RTLD_NOW | RTLD_LOCAL);
132 init_fun = (AMFInit_Fn)dlsym(ctx->
library, AMF_INIT_FUNCTION_NAME);
135 version_fun = (AMFQueryVersion_Fn)dlsym(ctx->
library, AMF_QUERY_VERSION_FUNCTION_NAME);
138 res = version_fun(&ctx->
version);
140 res = init_fun(AMF_FULL_VERSION, &ctx->
factory);
157 if (res == AMF_NOT_SUPPORTED)
160 av_log(avctx,
AV_LOG_ERROR,
"AMF failed to initialise on the given D3D11 device: %d.\n", res);
172 HANDLE device_handle;
173 IDirect3DDevice9 *device;
178 hr = IDirect3DDeviceManager9_OpenDeviceHandle(hwctx->
devmgr, &device_handle);
180 av_log(avctx,
AV_LOG_ERROR,
"Failed to open device handle for Direct3D9 device: %lx.\n", (
unsigned long)hr);
184 hr = IDirect3DDeviceManager9_LockDevice(hwctx->
devmgr, device_handle, &device, FALSE);
186 IDirect3DDeviceManager9_UnlockDevice(hwctx->
devmgr, device_handle, FALSE);
189 av_log(avctx,
AV_LOG_ERROR,
"Failed to lock device handle for Direct3D9 device: %lx.\n", (
unsigned long)hr);
193 IDirect3DDeviceManager9_CloseDeviceHandle(hwctx->
devmgr, device_handle);
200 IDirect3DDevice9_Release(device);
203 if (res == AMF_NOT_SUPPORTED)
206 av_log(avctx,
AV_LOG_ERROR,
"AMF failed to initialise on given D3D9 device: %d.\n", res);
217 AMFContext1 *context1 =
NULL;
226 ctx->
trace->pVtbl->EnableWriter(ctx->
trace, AMF_TRACE_WRITER_DEBUG_OUTPUT, ctx->
log_to_dbg != 0 );
228 ctx->
trace->pVtbl->SetWriterLevel(ctx->
trace, AMF_TRACE_WRITER_DEBUG_OUTPUT, AMF_TRACE_TRACE);
229 ctx->
trace->pVtbl->EnableWriter(ctx->
trace, AMF_TRACE_WRITER_CONSOLE, 0);
230 ctx->
trace->pVtbl->SetGlobalLevel(ctx->
trace, AMF_TRACE_TRACE);
246 av_log(avctx,
AV_LOG_ERROR,
"Format of input frames context (%s) is not supported by AMF.\n",
254 ret = amf_init_from_d3d11_device(avctx, frames_ctx->
device_ctx->
hwctx);
261 ret = amf_init_from_dxva2_device(avctx, frames_ctx->
device_ctx->
hwctx);
267 av_log(avctx,
AV_LOG_ERROR,
"AMF initialisation from a %s frames context is not supported.\n",
282 switch (device_ctx->
type) {
285 ret = amf_init_from_d3d11_device(avctx, device_ctx->
hwctx);
292 ret = amf_init_from_dxva2_device(avctx, device_ctx->
hwctx);
298 av_log(avctx,
AV_LOG_ERROR,
"AMF initialisation from a %s device is not supported.\n",
316 AMFGuid guid = IID_AMFContext1();
317 res = ctx->
context->pVtbl->QueryInterface(ctx->
context, &guid, (
void**)&context1);
320 res = context1->pVtbl->InitVulkan(context1,
NULL);
321 context1->pVtbl->Release(context1);
323 if (res == AMF_NOT_SUPPORTED)
324 av_log(avctx,
AV_LOG_ERROR,
"AMF via Vulkan is not supported on the given device.\n");
326 av_log(avctx,
AV_LOG_ERROR,
"AMF failed to initialise on the given Vulkan device: %d.\n", res);
345 codec_id = AMFVideoEncoderVCE_AVC;
348 codec_id = AMFVideoEncoder_HEVC;
420 planes = surface->pVtbl->GetPlanesCount(surface);
423 for (i = 0; i <
planes; i++) {
424 plane = surface->pVtbl->GetPlaneAt(surface, i);
425 dst_data[
i] = plane->pVtbl->GetNative(plane);
426 dst_linesize[
i] = plane->pVtbl->GetHPitch(plane);
451 AMFVariantStruct var = {0};
453 int64_t
size = buffer->pVtbl->GetSize(buffer);
458 memcpy(pkt->
data, buffer->pVtbl->GetNative(buffer),
size);
462 buffer->pVtbl->GetProperty(buffer, AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE, &var);
463 if(var.int64Value == AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_IDR) {
468 buffer->pVtbl->GetProperty(buffer, AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE, &var);
469 if (var.int64Value == AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_IDR) {
477 buffer->pVtbl->GetProperty(buffer,
PTS_PROP, &var);
479 pkt->
pts = var.int64Value;
490 "timestamp_list is empty while max_b_frames = %d\n", avctx->
max_b_frames);
495 sizeof(timestamp_last),
500 ctx->
dts_delay = timestamp_last - timestamp;
525 AMFVariantStruct var;
526 res = AMFVariantInit(&var);
528 AMFGuid guid_AMFInterface = IID_AMFInterface();
529 AMFInterface *amf_interface;
530 res = val->pVtbl->QueryInterface(val, &guid_AMFInterface, (
void**)&amf_interface);
533 res = AMFVariantAssignInterface(&var, amf_interface);
534 amf_interface->pVtbl->Release(amf_interface);
537 res =
object->pVtbl->SetProperty(
object, name, var);
539 AMFVariantClear(&var);
547 AMFVariantStruct var;
548 res = AMFVariantInit(&var);
550 res =
object->pVtbl->GetProperty(
object, name, &var);
552 if (var.type == AMF_VARIANT_INTERFACE) {
553 AMFGuid guid_AMFBuffer = IID_AMFBuffer();
554 AMFInterface *amf_interface = AMFVariantInterface(&var);
555 res = amf_interface->pVtbl->QueryInterface(amf_interface, &guid_AMFBuffer, (
void**)val);
557 res = AMF_INVALID_DATA_TYPE;
560 AMFVariantClear(&var);
568 AMFBuffer *frame_ref_storage_buffer =
NULL;
571 res = context->pVtbl->AllocBuffer(context, AMF_MEMORY_HOST,
sizeof(frame_ref), &frame_ref_storage_buffer);
575 memcpy(frame_ref_storage_buffer->pVtbl->GetNative(frame_ref_storage_buffer), &frame_ref,
sizeof(frame_ref));
577 frame_ref_storage_buffer->pVtbl->Release(frame_ref_storage_buffer);
578 frame_ref_storage_buffer =
NULL;
581 return frame_ref_storage_buffer;
587 memcpy(&frame_ref, frame_ref_storage_buffer->pVtbl->GetNative(frame_ref_storage_buffer),
sizeof(frame_ref));
589 frame_ref_storage_buffer->pVtbl->Release(frame_ref_storage_buffer);
598 AMF_RESULT res_query;
606 if (!frame->
buf[0]) {
612 if (!frame->
buf[0]) {
618 if (res == AMF_INPUT_FULL) {
636 static const GUID AMFTextureArrayIndexGUID = { 0x28115527, 0xe7c3, 0x4b66, { 0x99, 0xd3, 0x4f, 0x2a, 0xe6, 0xb4, 0x7f, 0xaf } };
637 ID3D11Texture2D *texture = (ID3D11Texture2D*)frame->
data[0];
643 texture->lpVtbl->SetPrivateData(texture, &AMFTextureArrayIndexGUID,
sizeof(
index), &
index);
645 res = ctx->
context->pVtbl->CreateSurfaceFromDX11Native(ctx->
context, texture, &surface,
NULL);
655 IDirect3DSurface9 *texture = (IDirect3DSurface9 *)frame->
data[3];
657 res = ctx->
context->pVtbl->CreateSurfaceFromDX9Native(ctx->
context, texture, &surface,
NULL);
674 AMFBuffer *frame_ref_storage_buffer;
677 surface->pVtbl->SetCrop(surface, 0, 0, frame->
width, frame->
height);
685 frame_ref_storage_buffer->pVtbl->Release(frame_ref_storage_buffer);
688 surface->pVtbl->SetPts(surface, frame->
pts);
689 AMF_ASSIGN_PROPERTY_INT64(res, surface,
PTS_PROP, frame->
pts);
693 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_INSERT_AUD, !!ctx->
aud);
696 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_INSERT_AUD, !!ctx->
aud);
703 res = ctx->
encoder->pVtbl->SubmitInput(ctx->
encoder, (AMFData*)surface);
704 if (res == AMF_INPUT_FULL) {
709 surface->pVtbl->Release(surface);
723 res_query = ctx->
encoder->pVtbl->QueryOutput(ctx->
encoder, &data);
727 AMFGuid guid = IID_AMFBuffer();
728 data->pVtbl->QueryInterface(data, &guid, (
void**)&buffer);
731 buffer->pVtbl->Release(buffer);
733 if (data->pVtbl->HasProperty(data,
L"av_frame_ref")) {
734 AMFBuffer *frame_ref_storage_buffer;
741 data->pVtbl->Release(data);
747 if (res != AMF_INPUT_FULL) {
758 av_log(avctx,
AV_LOG_WARNING,
"Data acquired but delayed frame submission got AMF_INPUT_FULL- should not happen\n");
762 if (res != AMF_INPUT_FULL) {
767 av_log(avctx,
AV_LOG_WARNING,
"Data acquired but delayed drain submission got AMF_INPUT_FULL- should not happen\n");
774 }
while (block_and_wait);
776 if (res_query == AMF_EOF) {
778 }
else if (data ==
NULL) {
#define AVERROR_ENCODER_NOT_FOUND
Encoder not found.
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
static int amf_init_encoder(AVCodecContext *avctx)
const struct AVCodec * codec
int av_fifo_grow(AVFifoBuffer *f, unsigned int size)
Enlarge an AVFifoBuffer.
AMFContext * context
AMF context.
static enum AVPixelFormat pix_fmt
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
#define FFMPEG_AMF_WRITER_ID
This structure describes decoded (raw) audio or video data.
const AVCodecHWConfigInternal *const ff_amfenc_hw_configs[]
ptrdiff_t const GLvoid * data
An API-specific header for AV_HWDEVICE_TYPE_D3D11VA.
#define AV_LOG_WARNING
Something somehow does not look correct.
Memory handling functions.
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
An API-specific header for AV_HWDEVICE_TYPE_DXVA2.
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
AVBufferRef * hw_device_ctx
pointer to HW accelerator (decoder)
static int amf_init_context(AVCodecContext *avctx)
int hwsurfaces_in_queue_max
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
#define AMF_RETURN_IF_FALSE(avctx, exp, ret_value,...)
Error handling helper.
#define FF_ARRAY_ELEMS(a)
int av_usleep(unsigned usec)
Sleep for a period of time.
static void AMF_CDECL_CALL AMFTraceWriter_Write(AMFTraceWriter *pThis, const wchar_t *scope, const wchar_t *message)
static int timestamp_queue_enqueue(AVCodecContext *avctx, int64_t timestamp)
static const struct @322 planes[]
int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int(*func)(void *, void *, int))
Feed data from a user-supplied callback to an AVFifoBuffer.
AMF_SURFACE_FORMAT format
AMF surface format.
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame...
static void amf_release_buffer_with_frame_ref(AMFBuffer *frame_ref_storage_buffer)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
int av_fifo_space(const AVFifoBuffer *f)
Return the amount of space in bytes in the AVFifoBuffer, that is the amount of data you can write int...
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
ID3D11Device * device
Device used for texture creation and access.
#define AVERROR_EOF
End of file.
#define AV_LOG_VERBOSE
Detailed information.
#define HW_CONFIG_ENCODER_DEVICE(format, device_type_)
static int amf_load_library(AVCodecContext *avctx)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
AMF trace writer callback class Used to capture all AMF logging.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int av_cold ff_amf_encode_close(AVCodecContext *avctx)
Common encoder termination function.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
static AMFTraceWriterVtbl tracer_vtbl
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void(*func)(void *, void *, int))
Feed data from an AVFifoBuffer to a user-supplied callback.
static AMF_RESULT amf_set_property_buffer(AMFSurface *object, const wchar_t *name, AMFBuffer *val)
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
simple assert() macros that are a bit more flexible than ISO C assert().
IDirect3DDeviceManager9 * devmgr
static int amf_copy_surface(AVCodecContext *avctx, const AVFrame *frame, AMFSurface *surface)
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], const uint8_t *src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Copy image in src_data to dst_data.
enum AVPixelFormat ff_amf_pix_fmts[]
Supported formats.
int flags
A combination of AV_PKT_FLAG values.
static enum AMF_SURFACE_FORMAT amf_av_to_amf_format(enum AVPixelFormat fmt)
int initial_pool_size
Initial size of the frame pool.
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
static AMFBuffer * amf_create_buffer_with_frame_ref(const AVFrame *frame, AMFContext *context)
int ff_amf_encode_init(AVCodecContext *avctx)
Common encoder initization function.
int width
picture width / height.
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames...
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
static void AMF_CDECL_CALL AMFTraceWriter_Flush(AMFTraceWriter *pThis)
AMFFactory * factory
pointer to AMF factory
AVBufferRef * hw_frames_ctx
pointer to HW accelerator (frame allocator)
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
AMFTraceWriterVtbl * vtbl
static int amf_copy_buffer(AVCodecContext *avctx, AVPacket *pkt, AMFBuffer *buffer)
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
amf_handle library
handle to DLL library
AMFComponent * encoder
AMF encoder object.
int av_fifo_size(const AVFifoBuffer *f)
Return the amount of data in bytes in the AVFifoBuffer, that is the amount of data you can read from ...
int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void(*func)(void *, void *, int))
Feed data at specific position from an AVFifoBuffer to a user-supplied callback.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
AMFDebug * debug
pointer to AMF debug interface
AVFifoBuffer * timestamp_list
main external API structure.
uint8_t * data
The data buffer.
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
amf_bool eof
flag indicating EOF happened
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
const char * av_hwdevice_get_type_name(enum AVHWDeviceType type)
Get the string name of an AVHWDeviceType.
amf_uint64 version
version of AMF runtime
This struct describes a set or pool of "hardware" frames (i.e.
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
Ecoding one frame - common function for all AMF encoders.
HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer. ...
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static const FormatMap format_map[]
Hardware surfaces for Direct3D11.
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
static AMF_RESULT amf_get_property_buffer(AMFData *object, const wchar_t *name, AMFBuffer **val)
common internal api header.
AmfTraceWriter tracer
AMF writer registered with AMF.
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
This struct is allocated as AVHWDeviceContext.hwctx.
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
This struct is allocated as AVHWDeviceContext.hwctx.
AMFSurface * delayed_surface
void av_fifo_freep(AVFifoBuffer **f)
Free an AVFifoBuffer and reset pointer to NULL.
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.
AMFTrace * trace
pointer to AMF trace interface
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option keep it simple and lowercase description are in without and describe what they for example set the foo of the bar offset is the offset of the field in your local context
AVBufferRef * hw_device_ctx
A reference to the AVHWDeviceContext describing the device which will be used by a hardware encoder/d...
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
#define AVERROR_EXTERNAL
Generic error in an external library.
AVPixelFormat
Pixel format.
static double val(void *priv, double ch)
This structure stores compressed data.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
#define AV_NOPTS_VALUE
Undefined timestamp value.
int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
Called by encoders to get the next frame for encoding.