45 #define AMF_VIDEO_DECODER_OUTPUT_FORMAT L"OutputDecodeFormat"
70 AMFSurface *surface = (AMFSurface*)(
data);
71 surface->pVtbl->Release(surface);
76 if( AMF_GET_MAJOR_VERSION(amf_device_ctx->
version) <= 1 &&
77 AMF_GET_MINOR_VERSION(amf_device_ctx->
version) <= 4 &&
78 AMF_GET_SUBMINOR_VERSION(amf_device_ctx->
version) < 36)
91 amf_int64 color_profile;
95 ctx->resolution_changed = 0;
99 codec_id = AMFVideoDecoderUVD_H264_AVC;
102 codec_id = AMFVideoDecoderHW_H265_HEVC;
107 codec_id = AMFVideoDecoderHW_H265_MAIN10;
119 res = amf_device_ctx->factory->pVtbl->CreateComponent(amf_device_ctx->factory, amf_device_ctx->context,
codec_id, &
ctx->decoder);
125 AMF_ASSIGN_PROPERTY_BOOL(res,
ctx->decoder, AMF_VIDEO_DECODER_FULL_RANGE_COLOR, 1);
127 AMF_ASSIGN_PROPERTY_BOOL(res,
ctx->decoder, AMF_VIDEO_DECODER_FULL_RANGE_COLOR, 0);
129 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN;
133 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601;
135 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_601;
140 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709;
142 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_709;
148 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020;
150 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020;
154 if (color_profile != AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN)
155 AMF_ASSIGN_PROPERTY_INT64(res,
ctx->decoder, AMF_VIDEO_DECODER_COLOR_PROFILE, color_profile);
157 AMF_ASSIGN_PROPERTY_INT64(res,
ctx->decoder, AMF_VIDEO_DECODER_COLOR_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->
color_trc);
160 AMF_ASSIGN_PROPERTY_INT64(res,
ctx->decoder, AMF_VIDEO_DECODER_COLOR_PRIMARIES, (amf_int64)avctx->
color_primaries);
162 if (
ctx->timestamp_mode != -1)
163 AMF_ASSIGN_PROPERTY_INT64(res,
ctx->decoder, AMF_TIMESTAMP_MODE,
ctx->timestamp_mode);
164 if (
ctx->decoder_mode != -1)
165 AMF_ASSIGN_PROPERTY_INT64(res,
ctx->decoder, AMF_VIDEO_DECODER_REORDER_MODE,
ctx->decoder_mode);
166 if (
ctx->dpb_size != -1)
167 AMF_ASSIGN_PROPERTY_INT64(res,
ctx->decoder, AMF_VIDEO_DECODER_DPB_SIZE,
ctx->dpb_size);
168 if (
ctx->lowlatency != -1)
169 AMF_ASSIGN_PROPERTY_INT64(res,
ctx->decoder, AMF_VIDEO_DECODER_LOW_LATENCY,
ctx->lowlatency);
170 if (
ctx->smart_access_video != -1) {
171 AMF_ASSIGN_PROPERTY_INT64(res,
ctx->decoder, AMF_VIDEO_DECODER_ENABLE_SMART_ACCESS_VIDEO,
ctx->smart_access_video != 0);
173 av_log(avctx,
AV_LOG_ERROR,
"The Smart Access Video is not supported by AMF decoder.\n");
178 if (
ctx->smart_access_video != 0) {
179 AMF_ASSIGN_PROPERTY_INT64(res,
ctx->decoder, AMF_VIDEO_DECODER_LOW_LATENCY,
true);
180 av_log(avctx,
AV_LOG_INFO,
"The Smart Access Video set low latency mode for decoder.\n");
184 if (
ctx->skip_transfer_sav != -1)
185 AMF_ASSIGN_PROPERTY_INT64(res,
ctx->decoder, AMF_VIDEO_DECODER_SKIP_TRANSFER_SMART_ACCESS_VIDEO,
ctx->skip_transfer_sav);
187 if (
ctx->copy_output != -1)
188 AMF_ASSIGN_PROPERTY_INT64(res,
ctx->decoder, AMF_VIDEO_DECODER_SURFACE_COPY,
ctx->copy_output);
191 const uint8_t *extradata;
194 res = amf_device_ctx->context->pVtbl->AllocBuffer(amf_device_ctx->context, AMF_MEMORY_HOST, extradata_size, &
buffer);
196 memcpy(
buffer->pVtbl->GetNative(
buffer), extradata, extradata_size);
197 AMF_ASSIGN_PROPERTY_INTERFACE(res,
ctx->decoder, AMF_VIDEO_DECODER_EXTRADATA,
buffer);
202 if (
ctx->surface_pool_size == -1) {
203 ctx->surface_pool_size = pool_size;
212 if (
ctx->surface_pool_size > 100)
213 ctx->surface_pool_size = 100;
215 AMF_ASSIGN_PROPERTY_INT64(res,
ctx->decoder, AMF_VIDEO_DECODER_SURFACE_POOL_SIZE,
ctx->surface_pool_size);
216 res =
ctx->decoder->pVtbl->Init(
ctx->decoder, AMF_SURFACE_UNKNOWN, avctx->
width, avctx->
height);
229 ctx->decoder->pVtbl->Terminate(
ctx->decoder);
230 ctx->decoder->pVtbl->Release(
ctx->decoder);
255 hwframes_ctx->
width = new_width;
256 hwframes_ctx->
height = new_height;
310 AMFVariantStruct format_var = {0};
343 AMFVariantStruct var;
344 res = AMFVariantInit(&var);
346 res =
object->pVtbl->GetProperty(
object,
name, &var);
348 if (var.type == AMF_VARIANT_INTERFACE) {
349 AMFGuid guid_AMFBuffer = IID_AMFBuffer();
350 AMFInterface *amf_interface = AMFVariantInterface(&var);
351 res = amf_interface->pVtbl->QueryInterface(amf_interface, &guid_AMFBuffer, (
void**)
val);
353 res = AMF_INVALID_DATA_TYPE;
356 AMFVariantClear(&var);
363 AMFVariantStruct var = {0};
390 frame->data[0] = (uint8_t *)surface;
392 format_amf = surface->pVtbl->GetFormat(surface);
396 ret = surface->pVtbl->Convert(surface, AMF_MEMORY_HOST);
399 for (
i = 0;
i < surface->pVtbl->GetPlanesCount(surface);
i++) {
400 plane = surface->pVtbl->GetPlaneAt(surface,
i);
401 frame->data[
i] = plane->pVtbl->GetNative(plane);
402 frame->linesize[
i] = plane->pVtbl->GetHPitch(plane);
410 format_amf = surface->pVtbl->GetFormat(surface);
417 frame->pts = surface->pVtbl->GetPts(surface);
419 surface->pVtbl->GetProperty(surface,
L"FFMPEG:dts", &var);
420 frame->pkt_dts = var.int64Value;
422 frame->duration = surface->pVtbl->GetDuration(surface);
423 if (
frame->duration < 0)
432 AMFBuffer * hdrmeta_buffer =
NULL;
434 if (hdrmeta_buffer !=
NULL) {
435 AMFHDRMetadata * hdrmeta = (AMFHDRMetadata*)hdrmeta_buffer->pVtbl->GetNative(hdrmeta_buffer);
438 if (hdrmeta !=
NULL) {
440 const int chroma_den = 50000;
441 const int luma_den = 10000;
463 if (hdrmeta->maxContentLightLevel) {
469 light->
MaxCLL = hdrmeta->maxContentLightLevel;
470 light->
MaxFALL = hdrmeta->maxFrameAverageLightLevel;
481 AMF_RESULT
ret = AMF_OK;
482 AMFSurface *surface =
NULL;
483 AMFData *data_out =
NULL;
485 ret =
ctx->decoder->pVtbl->QueryOutput(
ctx->decoder, &data_out);
486 if (
ret != AMF_OK &&
ret != AMF_REPEAT) {
489 if (data_out ==
NULL) {
494 AMFGuid guid = IID_AMFSurface();
495 data_out->pVtbl->QueryInterface(data_out, &guid, (
void**)&surface);
496 data_out->pVtbl->Release(data_out);
506 surface->pVtbl->Release(surface);
520 AMF_ASSIGN_PROPERTY_INT64(res,
buffer,
L"FFMPEG:dts",
pkt->
dts);
531 AMFContext *ctxt = amf_device_ctx->context;
534 AMFBuffer *buf =
NULL;
542 err = buf->pVtbl->SetSize(buf,
pkt->
size);
543 AMF_RETURN_IF_FALSE(ctxt, err == AMF_OK, err,
"amf_buffer_from_packet() - SetSize failed");
545 mem = buf->pVtbl->GetNative(buf);
568 if(
ctx->resolution_changed)
569 ctx->resolution_changed = 0;
578 ctx->decoder->pVtbl->Drain(
ctx->decoder);
589 res =
ctx->decoder->pVtbl->SubmitInput(
ctx->decoder, (AMFData*) buf);
590 if(res == AMF_DECODER_NO_FREE_SURFACES)
594 }
while (res == AMF_DECODER_NO_FREE_SURFACES);
596 buf->pVtbl->Release(buf);
598 if(res == AMF_DECODER_NO_FREE_SURFACES) {
600 av_log(avctx,
AV_LOG_VERBOSE,
"SubmitInput() returned NO_FREE_SURFACES and came out of loop - should never happen\n");
602 }
else if (res == AMF_RESOLUTION_CHANGED) {
604 ctx->decoder->pVtbl->Drain(
ctx->decoder);
607 ctx->resolution_changed = 1;
609 }
else if (res != AMF_OK && res != AMF_NEED_MORE_INPUT && res != AMF_REPEAT) {
618 else if (res == AMF_REPEAT)
621 else if (res == AMF_EOF) {
624 if(
ctx->resolution_changed){
626 AMFVariantStruct size_var = {0};
627 AMFVariantStruct format_var = {0};
628 res =
ctx->decoder->pVtbl->GetProperty(
ctx->decoder, AMF_VIDEO_DECODER_CURRENT_SIZE, &size_var);
633 avctx->
width = size_var.sizeValue.width;
634 avctx->
height = size_var.sizeValue.height;
654 return got_frame ? 0 :
AVERROR(EAGAIN);
660 ctx->decoder->pVtbl->Flush(
ctx->decoder);
663 #define OFFSET(x) offsetof(AMFDecoderContext, x)
664 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
668 {
"decoder_mode",
"Decoder mode",
OFFSET(decoder_mode),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AMF_VIDEO_DECODER_MODE_LOW_LATENCY,
VD,
"decoder_mode" },
669 {
"regular",
"DPB delay is based on number of reference frames + 1", 0,
AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_DECODER_MODE_REGULAR }, 0, 0,
VD,
"decoder_mode" },
670 {
"compliant",
"DPB delay is based on profile - up to 16", 0,
AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_DECODER_MODE_COMPLIANT }, 0, 0,
VD,
"decoder_mode" },
671 {
"low_latency",
"DPB delay is 0", 0,
AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_DECODER_MODE_LOW_LATENCY }, 0, 0,
VD,
"decoder_mode" },
674 {
"timestamp_mode",
"Timestamp mode",
OFFSET(timestamp_mode),
AV_OPT_TYPE_INT, { .i64 = AMF_TS_SORT }, -1, AMF_TS_DECODE,
VD,
"timestamp_mode" },
675 {
"presentation",
"Preserve timestamps from input to output", 0,
AV_OPT_TYPE_CONST, { .i64 = AMF_TS_PRESENTATION }, 0, 0,
VD,
"timestamp_mode" },
676 {
"sort",
"Resort PTS list", 0,
AV_OPT_TYPE_CONST, { .i64 = AMF_TS_SORT }, 0, 0,
VD,
"timestamp_mode" },
677 {
"decode",
"Decode order", 0,
AV_OPT_TYPE_CONST, { .i64 = AMF_TS_DECODE }, 0, 0,
VD,
"timestamp_mode" },
680 {
"surface_pool_size",
"Number of surfaces in the decode pool",
OFFSET(surface_pool_size),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX,
VD,
NULL },
685 {
"skip_transfer_sav",
"Skip transfer on another GPU when SAV enabled",
OFFSET(skip_transfer_sav),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1,
VD,
NULL },
698 #define DEFINE_AMF_DECODER(x, X, bsf_name) \
699 const FFCodec ff_##x##_amf_decoder = { \
700 .p.name = #x "_amf", \
701 CODEC_LONG_NAME(#X " AMD AMF video decoder"), \
702 .priv_data_size = sizeof(AMFDecoderContext), \
703 .p.type = AVMEDIA_TYPE_VIDEO, \
704 .p.id = AV_CODEC_ID_##X, \
705 .init = amf_decode_init, \
706 FF_CODEC_RECEIVE_FRAME_CB(amf_decode_frame), \
707 .flush = amf_decode_flush, \
708 .close = amf_decode_close, \
710 .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \
711 .p.priv_class = &amf_decode_class, \
712 CODEC_PIXFMTS_ARRAY(amf_dec_pix_fmts), \
713 .hw_configs = amf_hw_configs, \
714 .p.wrapper_name = "amf", \
715 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, \