20 #include "config_components.h"
43 #define AMF_AV_FRAME_REF L"av_frame_ref"
44 #define PTS_PROP L"PtsProp"
57 const unsigned int luma_den = 10000;
58 hdrmeta->maxMasteringLuminance =
60 hdrmeta->minMasteringLuminance =
64 const unsigned int chroma_den = 50000;
65 hdrmeta->redPrimary[0] =
67 hdrmeta->redPrimary[1] =
69 hdrmeta->greenPrimary[0] =
71 hdrmeta->greenPrimary[1] =
73 hdrmeta->bluePrimary[0] =
75 hdrmeta->bluePrimary[1] =
77 hdrmeta->whitePoint[0] =
79 hdrmeta->whitePoint[1] =
87 hdrmeta->maxContentLightLevel = (amf_uint16)light_meta->
MaxCLL;
88 hdrmeta->maxFrameAverageLightLevel = (amf_uint16)light_meta->
MaxFALL;
106 #define FFMPEG_AMF_WRITER_ID L"ffmpeg_amf"
146 if(!
ctx->pts_property_name)
150 ctx->av_frame_property_name =
av_memdup(
name, alloc_size *
sizeof(
wchar_t));
151 if(!
ctx->av_frame_property_name)
177 AMF_RETURN_IF_FALSE(
ctx, amf_device_ctx->version >= AMF_MAKE_FULL_VERSION(1, 4, 32, 0),
AVERROR_UNKNOWN,
"10-bit encoder is not supported by AMD GPU drivers versions lower than 23.30.\n");
184 res = amf_device_ctx->factory->pVtbl->CreateComponent(amf_device_ctx->factory, amf_device_ctx->context,
codec_id, &
ctx->encoder);
187 ctx->submitted_frame = 0;
188 ctx->encoded_frame = 0;
199 ctx->encoder->pVtbl->Terminate(
ctx->encoder);
200 ctx->encoder->pVtbl->Release(
ctx->encoder);
217 uint8_t *dst_data[4] = {0};
218 int dst_linesize[4] = {0};
222 planes = (int)surface->pVtbl->GetPlanesCount(surface);
226 plane = surface->pVtbl->GetPlaneAt(surface,
i);
227 dst_data[
i] = plane->pVtbl->GetNative(plane);
228 dst_linesize[
i] = plane->pVtbl->GetHPitch(plane);
241 AMFVariantStruct var = {0};
252 buffer->pVtbl->GetProperty(
buffer, AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE, &var);
253 if(var.int64Value == AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_IDR) {
258 buffer->pVtbl->GetProperty(
buffer, AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE, &var);
259 if (var.int64Value == AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_IDR) {
264 buffer->pVtbl->GetProperty(
buffer, AMF_VIDEO_ENCODER_AV1_OUTPUT_FRAME_TYPE, &var);
265 if (var.int64Value == AMF_VIDEO_ENCODER_AV1_OUTPUT_FRAME_TYPE_KEY) {
274 pkt->
pts = var.int64Value;
280 if ((
ctx->max_b_frames > 0 || ((
ctx->pa_adaptive_mini_gop == 1) ?
true :
false)) &&
ctx->dts_delay == 0) {
285 "timestamp_list is empty while max_b_frames = %d\n", avctx->
max_b_frames);
290 ctx->dts_delay = timestamp_last - timestamp;
306 if (!
ctx->timestamp_list) {
311 ctx->hwsurfaces_in_queue = 0;
351 AMFVariantStruct var;
352 res = AMFVariantInit(&var);
354 AMFGuid guid_AMFInterface = IID_AMFInterface();
355 AMFInterface *amf_interface;
356 res =
val->pVtbl->QueryInterface(
val, &guid_AMFInterface, (
void**)&amf_interface);
359 res = AMFVariantAssignInterface(&var, amf_interface);
360 amf_interface->pVtbl->Release(amf_interface);
363 res =
object->pVtbl->SetProperty(
object,
name, var);
365 AMFVariantClear(&var);
377 switch(amf_device_ctx->memory_type) {
378 case AMF_MEMORY_DX11:
379 res = amf_device_ctx->context->pVtbl->LockDX11(amf_device_ctx->context);
382 case AMF_MEMORY_DX12:
384 AMFContext2 *context2 =
NULL;
385 AMFGuid guid = IID_AMFContext2();
386 res = amf_device_ctx->context->pVtbl->QueryInterface(amf_device_ctx->context, &guid, (
void**)&context2);
388 res = context2->pVtbl->LockDX12(context2);
390 context2->pVtbl->Release(context2);
394 res = amf_device_ctx->context->pVtbl->LockDX9(amf_device_ctx->context);
397 case AMF_MEMORY_VULKAN:
399 AMFContext2 *context2 =
NULL;
400 AMFGuid guid = IID_AMFContext2();
401 res = amf_device_ctx->context->pVtbl->QueryInterface(amf_device_ctx->context, &guid, (
void**)&context2);
403 res = context2->pVtbl->LockVulkan(context2);
405 context2->pVtbl->Release(context2);
418 switch(amf_device_ctx->memory_type) {
419 case AMF_MEMORY_DX11:
420 res = amf_device_ctx->context->pVtbl->UnlockDX11(amf_device_ctx->context);
423 case AMF_MEMORY_DX12:
425 AMFContext2 *context2 =
NULL;
426 AMFGuid guid = IID_AMFContext2();
427 res = amf_device_ctx->context->pVtbl->QueryInterface(amf_device_ctx->context, &guid, (
void**)&context2);
429 res = context2->pVtbl->UnlockDX12(context2);
431 context2->pVtbl->Release(context2);
435 res = amf_device_ctx->context->pVtbl->UnlockDX9(amf_device_ctx->context);
438 case AMF_MEMORY_VULKAN:
440 AMFContext2 *context2 =
NULL;
441 AMFGuid guid = IID_AMFContext2();
442 res = amf_device_ctx->context->pVtbl->QueryInterface(amf_device_ctx->context, &guid, (
void**)&context2);
444 res = context2->pVtbl->UnlockVulkan(context2);
446 context2->pVtbl->Release(context2);
455 AMF_RESULT res = AMF_FAIL;
460 AMF_ASSIGN_PROPERTY_INT64(res, surface,
ctx->av_frame_property_name,
data);
467 AMFVariantStruct var = {0};
468 AMF_RESULT res =
buffer->pVtbl->GetProperty(
buffer,
ctx->av_frame_property_name, &var);
469 if(res == AMF_OK && var.int64Value){
486 int max_b_frames =
ctx->max_b_frames < 0 ? 0 :
ctx->max_b_frames;
489 switch (
frame->format) {
493 static const GUID AMFTextureArrayIndexGUID = { 0x28115527, 0xe7c3, 0x4b66, { 0x99, 0xd3, 0x4f, 0x2a, 0xe6, 0xb4, 0x7f, 0xaf } };
494 ID3D11Texture2D *texture = (ID3D11Texture2D*)
frame->data[0];
498 texture->lpVtbl->SetPrivateData(texture, &AMFTextureArrayIndexGUID,
sizeof(
index), &
index);
499 res = amf_device_ctx->context->pVtbl->CreateSurfaceFromDX11Native(amf_device_ctx->context, texture, &surface,
NULL);
508 IDirect3DSurface9 *texture = (IDirect3DSurface9 *)
frame->data[3];
509 res = amf_device_ctx->context->pVtbl->CreateSurfaceFromDX9Native(amf_device_ctx->context, texture, &surface,
NULL);
517 surface = (AMFSurface*)
frame->data[0];
518 surface->pVtbl->Acquire(surface);
524 res = amf_device_ctx->context->pVtbl->AllocSurface(amf_device_ctx->context, AMF_MEMORY_HOST,
ctx->format, avctx->
width, avctx->
height, &surface);
532 ctx->hwsurfaces_in_queue++;
534 surface->pVtbl->SetCrop(surface, 0, 0,
frame->width,
frame->height);
538 AMFBuffer * hdrmeta_buffer =
NULL;
539 res = amf_device_ctx->context->pVtbl->AllocBuffer(amf_device_ctx->context, AMF_MEMORY_HOST,
sizeof(AMFHDRMetadata), &hdrmeta_buffer);
541 AMFHDRMetadata * hdrmeta = (AMFHDRMetadata*)hdrmeta_buffer->pVtbl->GetNative(hdrmeta_buffer);
545 AMF_ASSIGN_PROPERTY_INTERFACE(res,
ctx->encoder, AMF_VIDEO_ENCODER_INPUT_HDR_METADATA, hdrmeta_buffer);
break;
547 AMF_ASSIGN_PROPERTY_INTERFACE(res,
ctx->encoder, AMF_VIDEO_ENCODER_HEVC_INPUT_HDR_METADATA, hdrmeta_buffer);
break;
549 AMF_ASSIGN_PROPERTY_INTERFACE(res,
ctx->encoder, AMF_VIDEO_ENCODER_AV1_INPUT_HDR_METADATA, hdrmeta_buffer);
break;
554 hdrmeta_buffer->pVtbl->Release(hdrmeta_buffer);
557 surface->pVtbl->SetPts(surface,
frame->pts);
559 AMF_ASSIGN_PROPERTY_INT64(res, surface,
ctx->pts_property_name,
frame->pts);
563 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_INSERT_AUD, !!
ctx->aud);
564 switch (
frame->pict_type) {
566 if (
ctx->forced_idr) {
567 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_INSERT_SPS, 1);
568 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_INSERT_PPS, 1);
569 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_IDR);
571 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_I);
575 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_P);
578 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_B);
583 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_INSERT_AUD, !!
ctx->aud);
584 switch (
frame->pict_type) {
586 if (
ctx->forced_idr) {
587 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_INSERT_HEADER, 1);
588 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_IDR);
590 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_I);
594 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_P);
600 if (
ctx->forced_idr) {
601 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_AV1_FORCE_INSERT_SEQUENCE_HEADER, 1);
602 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_AV1_FORCE_FRAME_TYPE, AMF_VIDEO_ENCODER_AV1_FORCE_FRAME_TYPE_KEY);
604 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_AV1_FORCE_FRAME_TYPE, AMF_VIDEO_ENCODER_AV1_FORCE_FRAME_TYPE_INTRA_ONLY);
612 res =
ctx->encoder->pVtbl->SubmitInput(
ctx->encoder, (AMFData*)surface);
613 if (res == AMF_INPUT_FULL) {
615 *surface_resubmit = surface;
617 surface->pVtbl->Release(surface);
619 ctx->submitted_frame++;
623 if(
ctx->submitted_frame <=
ctx->encoded_frame + max_b_frames + 1)
634 av_log(avctx,
AV_LOG_WARNING,
"amf_lock_context() failed with %d - should not happen\n", locked);
648 AMFSurface *surface =
NULL;
651 AMF_RESULT res_query;
656 int max_b_frames =
ctx->max_b_frames < 0 ? 0 :
ctx->max_b_frames;
667 if(
ctx->submitted_frame <=
ctx->encoded_frame + max_b_frames + 1)
673 if (!
frame->buf[0]) {
675 if(!
ctx->delayed_drain) {
676 res =
ctx->encoder->pVtbl->Drain(
ctx->encoder);
677 if (res == AMF_INPUT_FULL) {
678 ctx->delayed_drain = 1;
702 res_query =
ctx->encoder->pVtbl->QueryOutput(
ctx->encoder, &
data);
706 AMFGuid guid = IID_AMFBuffer();
710 ctx->hwsurfaces_in_queue--;
712 ctx->encoded_frame++;
718 if (
ctx->delayed_drain) {
719 res =
ctx->encoder->pVtbl->Drain(
ctx->encoder);
720 if (res != AMF_INPUT_FULL) {
721 ctx->delayed_drain = 0;
725 av_log(avctx,
AV_LOG_WARNING,
"Data acquired but delayed drain submission got AMF_INPUT_FULL- should not happen\n");
728 }
else if (
ctx->delayed_drain || (
ctx->eof && res_query != AMF_EOF) || (
ctx->hwsurfaces_in_queue >=
ctx->hwsurfaces_in_queue_max) || surface) {
732 if (!
ctx->query_timeout_supported || avpkt->
data || avpkt->
buf) {
736 }
while (block_and_wait);
738 if (res_query == AMF_EOF) {
745 res =
ctx->encoder->pVtbl->SubmitInput(
ctx->encoder, (AMFData*)surface);
746 surface->pVtbl->Release(surface);
747 if (res == AMF_INPUT_FULL) {
748 av_log(avctx,
AV_LOG_WARNING,
"Data acquired but delayed SubmitInput returned AMF_INPUT_FULL- should not happen\n");
754 ctx->submitted_frame++;
767 amf_int64 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN;
772 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601;
775 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709;
779 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020;
786 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_601;
789 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_709;
793 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020;
797 return color_profile;