39 #define AMF_AV_FRAME_REF L"av_frame_ref"
40 #define PTS_PROP L"PtsProp"
52 #define FFMPEG_AMF_WRITER_ID L"ffmpeg_amf"
92 if(!
ctx->pts_property_name)
97 if(!
ctx->av_frame_property_name)
123 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");
130 res = amf_device_ctx->factory->pVtbl->CreateComponent(amf_device_ctx->factory, amf_device_ctx->context,
codec_id, &
ctx->encoder);
133 ctx->submitted_frame = 0;
134 ctx->encoded_frame = 0;
145 ctx->encoder->pVtbl->Terminate(
ctx->encoder);
146 ctx->encoder->pVtbl->Release(
ctx->encoder);
153 if (
ctx->output_list) {
173 uint8_t *dst_data[4] = {0};
174 int dst_linesize[4] = {0};
178 planes = (int)surface->pVtbl->GetPlanesCount(surface);
182 plane = surface->pVtbl->GetPlaneAt(surface,
i);
183 dst_data[
i] = plane->pVtbl->GetNative(plane);
184 dst_linesize[
i] = plane->pVtbl->GetHPitch(plane);
197 AMFVariantStruct var = {0};
208 buffer->pVtbl->GetProperty(
buffer, AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE, &var);
209 if(var.int64Value == AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_IDR) {
214 buffer->pVtbl->GetProperty(
buffer, AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE, &var);
215 if (var.int64Value == AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_IDR) {
220 buffer->pVtbl->GetProperty(
buffer, AMF_VIDEO_ENCODER_AV1_OUTPUT_FRAME_TYPE, &var);
221 if (var.int64Value == AMF_VIDEO_ENCODER_AV1_OUTPUT_FRAME_TYPE_KEY) {
230 pkt->
pts = var.int64Value;
236 if ((
ctx->max_b_frames > 0 || ((
ctx->pa_adaptive_mini_gop == 1) ?
true :
false)) &&
ctx->dts_delay == 0) {
241 "timestamp_list is empty while max_b_frames = %d\n", avctx->
max_b_frames);
246 ctx->dts_delay = timestamp_last - timestamp;
262 if (!
ctx->timestamp_list) {
266 if (!
ctx->output_list)
271 ctx->hwsurfaces_in_queue = 0;
300 if (
ctx->pa_lookahead_buffer_depth >=
ctx->hwsurfaces_in_queue_max) {
302 "async_depth (%d) too small for lookahead (%d), increasing to (%d)\n",
303 ctx->hwsurfaces_in_queue_max,
304 ctx->pa_lookahead_buffer_depth,
305 ctx->pa_lookahead_buffer_depth + 1);
306 ctx->hwsurfaces_in_queue_max =
ctx->pa_lookahead_buffer_depth + 1;
320 AMFVariantStruct var;
321 res = AMFVariantInit(&var);
323 AMFGuid guid_AMFInterface = IID_AMFInterface();
324 AMFInterface *amf_interface;
325 res =
val->pVtbl->QueryInterface(
val, &guid_AMFInterface, (
void**)&amf_interface);
328 res = AMFVariantAssignInterface(&var, amf_interface);
329 amf_interface->pVtbl->Release(amf_interface);
332 res =
object->pVtbl->SetProperty(
object,
name, var);
334 AMFVariantClear(&var);
341 AMF_RESULT res = AMF_FAIL;
346 AMF_ASSIGN_PROPERTY_INT64(res, surface,
ctx->av_frame_property_name,
data);
353 AMFVariantStruct var = {0};
354 AMF_RESULT res =
buffer->pVtbl->GetProperty(
buffer,
ctx->av_frame_property_name, &var);
355 if(res == AMF_OK && var.int64Value){
375 switch (
frame->format) {
379 static const GUID AMFTextureArrayIndexGUID = { 0x28115527, 0xe7c3, 0x4b66, { 0x99, 0xd3, 0x4f, 0x2a, 0xe6, 0xb4, 0x7f, 0xaf } };
380 ID3D11Texture2D *texture = (ID3D11Texture2D*)
frame->data[0];
384 texture->lpVtbl->SetPrivateData(texture, &AMFTextureArrayIndexGUID,
sizeof(
index), &
index);
385 res = amf_device_ctx->context->pVtbl->CreateSurfaceFromDX11Native(amf_device_ctx->context, texture, &surface,
NULL);
394 IDirect3DSurface9 *texture = (IDirect3DSurface9 *)
frame->data[3];
395 res = amf_device_ctx->context->pVtbl->CreateSurfaceFromDX9Native(amf_device_ctx->context, texture, &surface,
NULL);
403 surface = (AMFSurface*)
frame->data[0];
404 surface->pVtbl->Acquire(surface);
410 res = amf_device_ctx->context->pVtbl->AllocSurface(amf_device_ctx->context, AMF_MEMORY_HOST,
ctx->format, avctx->
width, avctx->
height, &surface);
418 ctx->hwsurfaces_in_queue++;
420 surface->pVtbl->SetCrop(surface, 0, 0,
frame->width,
frame->height);
424 AMFBuffer * hdrmeta_buffer =
NULL;
425 res = amf_device_ctx->context->pVtbl->AllocBuffer(amf_device_ctx->context, AMF_MEMORY_HOST,
sizeof(AMFHDRMetadata), &hdrmeta_buffer);
427 AMFHDRMetadata * hdrmeta = (AMFHDRMetadata*)hdrmeta_buffer->pVtbl->GetNative(hdrmeta_buffer);
431 AMF_ASSIGN_PROPERTY_INTERFACE(res,
ctx->encoder, AMF_VIDEO_ENCODER_INPUT_HDR_METADATA, hdrmeta_buffer);
break;
433 AMF_ASSIGN_PROPERTY_INTERFACE(res,
ctx->encoder, AMF_VIDEO_ENCODER_HEVC_INPUT_HDR_METADATA, hdrmeta_buffer);
break;
435 AMF_ASSIGN_PROPERTY_INTERFACE(res,
ctx->encoder, AMF_VIDEO_ENCODER_AV1_INPUT_HDR_METADATA, hdrmeta_buffer);
break;
440 hdrmeta_buffer->pVtbl->Release(hdrmeta_buffer);
443 surface->pVtbl->SetPts(surface,
frame->pts);
445 AMF_ASSIGN_PROPERTY_INT64(res, surface,
ctx->pts_property_name,
frame->pts);
449 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_INSERT_AUD, !!
ctx->aud);
450 switch (
frame->pict_type) {
452 if (
ctx->forced_idr) {
453 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_INSERT_SPS, 1);
454 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_INSERT_PPS, 1);
455 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_IDR);
457 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_I);
461 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_P);
464 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_B);
469 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_INSERT_AUD, !!
ctx->aud);
470 switch (
frame->pict_type) {
472 if (
ctx->forced_idr) {
473 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_INSERT_HEADER, 1);
474 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_IDR);
476 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_I);
480 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_P);
486 if (
ctx->forced_idr) {
487 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_AV1_FORCE_INSERT_SEQUENCE_HEADER, 1);
488 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_AV1_FORCE_FRAME_TYPE, AMF_VIDEO_ENCODER_AV1_FORCE_FRAME_TYPE_KEY);
490 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_AV1_FORCE_FRAME_TYPE, AMF_VIDEO_ENCODER_AV1_FORCE_FRAME_TYPE_INTRA_ONLY);
498 res =
ctx->encoder->pVtbl->SubmitInput(
ctx->encoder, (AMFData*)surface);
499 if (res == AMF_INPUT_FULL) {
501 *surface_resubmit = surface;
503 surface->pVtbl->Release(surface);
505 ctx->submitted_frame++;
509 if(
ctx->submitted_frame <=
ctx->encoded_frame + output_delay)
522 if (amf_device_ctx->lock)
523 amf_device_ctx->lock(amf_device_ctx->lock_ctx);
525 if (amf_device_ctx->unlock)
526 amf_device_ctx->unlock(amf_device_ctx->lock_ctx);
534 AMF_RESULT
ret =
ctx->encoder->pVtbl->QueryOutput(
ctx->encoder, &
data);
537 AMFGuid guid = IID_AMFBuffer();
541 ctx->hwsurfaces_in_queue--;
542 ctx->encoded_frame++;
550 AMFSurface *surface =
NULL;
553 AMF_RESULT res_query;
577 if(
ctx->submitted_frame <=
ctx->encoded_frame + output_delay)
583 if (!
frame->buf[0]) {
585 if(!
ctx->delayed_drain) {
586 res =
ctx->encoder->pVtbl->Drain(
ctx->encoder);
587 if (res == AMF_INPUT_FULL) {
588 ctx->delayed_drain = 1;
618 if (
ctx->delayed_drain) {
619 res =
ctx->encoder->pVtbl->Drain(
ctx->encoder);
620 if (res != AMF_INPUT_FULL) {
621 ctx->delayed_drain = 0;
625 av_log(avctx,
AV_LOG_WARNING,
"Data acquired but delayed drain submission got AMF_INPUT_FULL- should not happen\n");
628 }
else if (
ctx->delayed_drain || (
ctx->eof && res_query != AMF_EOF) || (
ctx->hwsurfaces_in_queue >=
ctx->hwsurfaces_in_queue_max) || surface) {
632 if (!
ctx->query_timeout_supported || avpkt->
data || avpkt->
buf) {
636 }
while (block_and_wait);
638 if (res_query == AMF_EOF) {
646 res =
ctx->encoder->pVtbl->SubmitInput(
ctx->encoder, (AMFData*)surface);
647 if (res != AMF_INPUT_FULL)
650 if (!
ctx->query_timeout_supported)
661 }
while(res == AMF_INPUT_FULL);
663 surface->pVtbl->Release(surface);
664 if (res == AMF_INPUT_FULL) {
665 av_log(avctx,
AV_LOG_WARNING,
"Data acquired but delayed SubmitInput returned AMF_INPUT_FULL- should not happen\n");
671 ctx->submitted_frame++;