FFmpeg
Loading...
Searching...
No Matches
vf_amf_common.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "vf_amf_common.h"
20
21#include "libavutil/avassert.h"
22#include "avfilter.h"
23#include "avfilter_internal.h"
24#include "formats.h"
25#include "libavutil/mem.h"
26#include "libavutil/imgutils.h"
27#include "libavutil/pixdesc.h"
28
29#include "AMF/components/VideoDecoderUVD.h"
32#include "scale_eval.h"
33
34#if CONFIG_DXVA2
35#include <d3d9.h>
36#endif
37
38#if CONFIG_D3D11VA
39#include <d3d11.h>
40#endif
41
43{
44 AMFFilterContext *ctx = avctx->priv;
45
46 if (!strcmp(ctx->format_str, "same")) {
47 ctx->format = AV_PIX_FMT_NONE;
48 } else {
49 ctx->format = av_get_pix_fmt(ctx->format_str);
50 if (ctx->format == AV_PIX_FMT_NONE) {
51 av_log(avctx, AV_LOG_ERROR, "Unrecognized pixel format: %s\n", ctx->format_str);
52 return AVERROR(EINVAL);
53 }
54 }
55
56 return 0;
57}
58
60{
61 AMFFilterContext *ctx = avctx->priv;
62
63 if (ctx->component) {
64 ctx->component->pVtbl->Terminate(ctx->component);
65 ctx->component->pVtbl->Release(ctx->component);
66 ctx->component = NULL;
67 }
68
69 if (ctx->master_display)
70 av_freep(&ctx->master_display);
71
72 if (ctx->light_meta)
73 av_freep(&ctx->light_meta);
74
75 av_buffer_unref(&ctx->amf_device_ref);
76 av_buffer_unref(&ctx->hwdevice_ref);
77 av_buffer_unref(&ctx->hwframes_in_ref);
78 av_buffer_unref(&ctx->hwframes_out_ref);
79}
80
82{
83 AVFilterContext *avctx = inlink->dst;
84 AMFFilterContext *ctx = avctx->priv;
85 AVFilterLink *outlink = avctx->outputs[0];
86 AMF_RESULT res;
87 AMFSurface *surface_in;
88 AMFSurface *surface_out;
89 AMFData *data_out = NULL;
90 enum AVColorSpace out_colorspace;
91 enum AVColorRange out_color_range;
92
93 AVFrame *out = NULL;
94 int ret = 0;
95
96 if (!ctx->component)
97 return AVERROR(EINVAL);
98
99 ret = amf_avframe_to_amfsurface(avctx, in, &surface_in);
100 if (ret < 0)
101 goto fail;
102
103 res = ctx->component->pVtbl->SubmitInput(ctx->component, (AMFData*)surface_in);
104 surface_in->pVtbl->Release(surface_in); // release surface after use
105 AMF_GOTO_FAIL_IF_FALSE(avctx, res == AMF_OK, AVERROR_UNKNOWN, "SubmitInput() failed with error %d\n", res);
106 res = ctx->component->pVtbl->QueryOutput(ctx->component, &data_out);
107 AMF_GOTO_FAIL_IF_FALSE(avctx, res == AMF_OK, AVERROR_UNKNOWN, "QueryOutput() failed with error %d\n", res);
108
109 if (data_out) {
110 AMFGuid guid = IID_AMFSurface();
111 res = data_out->pVtbl->QueryInterface(data_out, &guid, (void**)&surface_out); // query for buffer interface
112 data_out->pVtbl->Release(data_out);
113 AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR_UNKNOWN, "QueryInterface(IID_AMFSurface) failed with error %d\n", res);
114 } else {
115 return AVERROR(EAGAIN);
116 }
117
118 out = amf_amfsurface_to_avframe(avctx, surface_out);
119
120 ret = av_frame_copy_props(out, in);
121 av_frame_unref(in);
122
123 out_colorspace = AVCOL_SPC_UNSPECIFIED;
124
125 if (ctx->color_profile != AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN) {
126 switch(ctx->color_profile) {
127 case AMF_VIDEO_CONVERTER_COLOR_PROFILE_601:
128 out_colorspace = AVCOL_SPC_SMPTE170M;
129 break;
130 case AMF_VIDEO_CONVERTER_COLOR_PROFILE_709:
131 out_colorspace = AVCOL_SPC_BT709;
132 break;
133 case AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020:
134 out_colorspace = AVCOL_SPC_BT2020_NCL;
135 break;
136 case AMF_VIDEO_CONVERTER_COLOR_PROFILE_JPEG:
137 out_colorspace = AVCOL_SPC_RGB;
138 break;
139 default:
140 out_colorspace = AVCOL_SPC_UNSPECIFIED;
141 break;
142 }
143 out->colorspace = out_colorspace;
144 }
145
146 out_color_range = AVCOL_RANGE_UNSPECIFIED;
147 if (ctx->out_color_range == AMF_COLOR_RANGE_FULL)
148 out_color_range = AVCOL_RANGE_JPEG;
149 else if (ctx->out_color_range == AMF_COLOR_RANGE_STUDIO)
150 out_color_range = AVCOL_RANGE_MPEG;
151
152 if (ctx->out_color_range != AMF_COLOR_RANGE_UNDEFINED)
153 out->color_range = out_color_range;
154
155 if (ctx->out_primaries != AMF_COLOR_PRIMARIES_UNDEFINED)
156 out->color_primaries = ctx->out_primaries;
157
158 if (ctx->out_trc != AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED)
159 out->color_trc = ctx->out_trc;
160
161
162 if (ret < 0)
163 goto fail;
164
165 out->hw_frames_ctx = av_buffer_ref(ctx->hwframes_out_ref);
166 if (!out->hw_frames_ctx) {
167 ret = AVERROR(ENOMEM);
168 goto fail;
169 }
170
171 av_frame_free(&in);
172 return ff_filter_frame(outlink, out);
173fail:
174 av_frame_free(&in);
176 return ret;
177}
178
179
180
182 const enum AVPixelFormat *input_pix_fmts,
183 const enum AVPixelFormat *output_pix_fmts)
184{
185 int err;
186 AVFilterFormats *input_formats;
187 AVFilterFormats *output_formats;
188
189 //in case if hw_device_ctx is set to DXVA2 we change order of pixel formats to set DXVA2 be chosen by default
190 //The order is ignored if hw_frames_ctx is not NULL on the config_output stage
191 if (avctx->hw_device_ctx) {
193
194 switch (device_ctx->type) {
195 #if CONFIG_D3D11VA
197 {
198 static const enum AVPixelFormat output_pix_fmts_d3d11[] = {
201 };
202 output_pix_fmts = output_pix_fmts_d3d11;
203 }
204 break;
205 #endif
206 #if CONFIG_DXVA2
208 {
209 static const enum AVPixelFormat output_pix_fmts_dxva2[] = {
212 };
213 output_pix_fmts = output_pix_fmts_dxva2;
214 }
215 break;
216 #endif
218 break;
219 default:
220 {
221 av_log(avctx, AV_LOG_ERROR, "Unsupported device : %s\n", av_hwdevice_get_type_name(device_ctx->type));
222 return AVERROR(EINVAL);
223 }
224 break;
225 }
226 }
227
228 input_formats = ff_make_pixel_format_list(output_pix_fmts);
229 if (!input_formats) {
230 return AVERROR(ENOMEM);
231 }
232 output_formats = ff_make_pixel_format_list(output_pix_fmts);
233 if (!output_formats) {
234 return AVERROR(ENOMEM);
235 }
236
237 if ((err = ff_formats_ref(input_formats, &avctx->inputs[0]->outcfg.formats)) < 0)
238 return err;
239
240 if ((err = ff_formats_ref(output_formats, &avctx->outputs[0]->incfg.formats)) < 0)
241 return err;
242 return 0;
243}
244
246 AMFSurface* surface)
247{
248 AMFPlane *plane;
249 uint8_t *dst_data[4];
250 int dst_linesize[4];
251 int planes;
252 int i;
253
254 planes = (int)surface->pVtbl->GetPlanesCount(surface);
255 av_assert0(planes < FF_ARRAY_ELEMS(dst_data));
256
257 for (i = 0; i < planes; i++) {
258 plane = surface->pVtbl->GetPlaneAt(surface, i);
259 dst_data[i] = plane->pVtbl->GetNative(plane);
260 dst_linesize[i] = plane->pVtbl->GetHPitch(plane);
261 }
262 av_image_copy(dst_data, dst_linesize,
263 (const uint8_t**)frame->data, frame->linesize, frame->format,
264 frame->width, frame->height);
265
266 return 0;
267}
268
270{
271 int err;
272 AMF_RESULT res;
273 AVFilterContext *avctx = outlink->src;
274 AVFilterLink *inlink = avctx->inputs[0];
275 AMFFilterContext *ctx = avctx->priv;
276 AVHWFramesContext *hwframes_out;
277 AVHWDeviceContext *hwdev_ctx;
278 enum AVPixelFormat in_sw_format = inlink->format;
279 enum AVPixelFormat out_sw_format = ctx->format;
280 FilterLink *inl = ff_filter_link(inlink);
281 FilterLink *outl = ff_filter_link(outlink);
282 double w_adj = 1.0;
283
284 if (ctx->w_expr && ctx->h_expr) {
285 if ((err = ff_scale_eval_dimensions(avctx,
286 ctx->w_expr, ctx->h_expr,
287 inlink, outlink,
288 &ctx->width, &ctx->height)) < 0)
289 return err;
290 } else {
291 ctx->width = inlink->w;
292 ctx->height = inlink->h;
293 }
294
295 if (ctx->reset_sar && inlink->sample_aspect_ratio.num)
296 w_adj = (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den;
297
298 err = ff_scale_adjust_dimensions(inlink, &ctx->width, &ctx->height,
299 ctx->force_original_aspect_ratio,
300 ctx->force_divisible_by, w_adj);
301 if (err < 0)
302 return err;
303
304 av_buffer_unref(&ctx->amf_device_ref);
305 av_buffer_unref(&ctx->hwframes_in_ref);
306 av_buffer_unref(&ctx->hwframes_out_ref);
307 ctx->local_context = 0;
308 if (inl->hw_frames_ctx) {
310 if (av_av_to_amf_format(frames_ctx->sw_format) == AMF_SURFACE_UNKNOWN) {
311 av_log(avctx, AV_LOG_ERROR, "Format of input frames context (%s) is not supported by AMF.\n",
312 av_get_pix_fmt_name(frames_ctx->sw_format));
313 return AVERROR(EINVAL);
314 }
315
316 err = av_hwdevice_ctx_create_derived(&ctx->amf_device_ref, AV_HWDEVICE_TYPE_AMF, frames_ctx->device_ref, 0);
317 if (err < 0)
318 return err;
319
320 ctx->hwframes_in_ref = av_buffer_ref(inl->hw_frames_ctx);
321 if (!ctx->hwframes_in_ref)
322 return AVERROR(ENOMEM);
323
324 in_sw_format = frames_ctx->sw_format;
325 } else if (avctx->hw_device_ctx) {
326 err = av_hwdevice_ctx_create_derived(&ctx->amf_device_ref, AV_HWDEVICE_TYPE_AMF, avctx->hw_device_ctx, 0);
327 if (err < 0)
328 return err;
329 ctx->hwdevice_ref = av_buffer_ref(avctx->hw_device_ctx);
330 if (!ctx->hwdevice_ref)
331 return AVERROR(ENOMEM);
332 } else {
333 res = av_hwdevice_ctx_create(&ctx->amf_device_ref, AV_HWDEVICE_TYPE_AMF, NULL, NULL, 0);
334 AMF_RETURN_IF_FALSE(avctx, res == 0, res, "Failed to create hardware device context (AMF) : %s\n", av_err2str(res));
335
336 }
337 if (out_sw_format == AV_PIX_FMT_NONE) {
339 if (desc && (desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
340 out_sw_format = in_sw_format;
341 else
342 out_sw_format = outlink->format;
343 }
344 ctx->hwframes_out_ref = av_hwframe_ctx_alloc(ctx->amf_device_ref);
345 if (!ctx->hwframes_out_ref)
346 return AVERROR(ENOMEM);
347 hwframes_out = (AVHWFramesContext*)ctx->hwframes_out_ref->data;
348 hwdev_ctx = (AVHWDeviceContext*)ctx->amf_device_ref->data;
349 if (hwdev_ctx->type == AV_HWDEVICE_TYPE_AMF)
350 {
351 ctx->amf_device_ctx = hwdev_ctx->hwctx;
352 }
353 hwframes_out->format = AV_PIX_FMT_AMF_SURFACE;
354 hwframes_out->sw_format = out_sw_format;
355
356 // in_sw_format is inlink->format for software input and the underlying
357 // sw_format for any hw frames input (AMF, D3D11, DXVA2); the component
358 // must always be initialized with a software surface format.
359 *in_format = in_sw_format;
360 outlink->w = ctx->width;
361 outlink->h = ctx->height;
362
363 if (ctx->reset_sar)
364 outlink->sample_aspect_ratio = (AVRational){1, 1};
365 else if (inlink->sample_aspect_ratio.num) {
366 outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink->w, outlink->w * inlink->h}, inlink->sample_aspect_ratio);
367 } else
368 outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
369
370 hwframes_out->width = outlink->w;
371 hwframes_out->height = outlink->h;
372
373 err = av_hwframe_ctx_init(ctx->hwframes_out_ref);
374 if (err < 0)
375 return err;
376
377 outl->hw_frames_ctx = av_buffer_ref(ctx->hwframes_out_ref);
378 if (!outl->hw_frames_ctx) {
379 return AVERROR(ENOMEM);
380 }
381 return 0;
382}
383
384void amf_free_amfsurface(void *opaque, uint8_t *data)
385{
386 AMFSurface *surface = (AMFSurface*)data;
387 surface->pVtbl->Release(surface);
388}
389
391{
393 AMFFilterContext *ctx = avctx->priv;
394
395 if (!frame)
396 return NULL;
397
398 if (ctx->hwframes_out_ref) {
399 AVHWFramesContext *hwframes_out = (AVHWFramesContext *)ctx->hwframes_out_ref->data;
400 if (hwframes_out->format == AV_PIX_FMT_AMF_SURFACE) {
401 int ret = av_hwframe_get_buffer(ctx->hwframes_out_ref, frame, 0);
402 if (ret < 0) {
403 av_log(avctx, AV_LOG_ERROR, "Get hw frame failed.\n");
404 goto fail;
405 }
406 frame->data[0] = (uint8_t *)pSurface;
407 frame->buf[1] = av_buffer_create((uint8_t *)pSurface, sizeof(AMFSurface),
409 (void*)avctx,
411 } else { // FIXME: add processing of other hw formats
412 av_log(ctx, AV_LOG_ERROR, "Unknown pixel format\n");
413 goto fail;
414 }
415 } else {
416
417 switch (pSurface->pVtbl->GetMemoryType(pSurface))
418 {
419 #if CONFIG_D3D11VA
420 case AMF_MEMORY_DX11:
421 {
422 AMFPlane *plane0 = pSurface->pVtbl->GetPlaneAt(pSurface, 0);
423 frame->data[0] = plane0->pVtbl->GetNative(plane0);
424 frame->data[1] = (uint8_t*)(intptr_t)0;
425
426 frame->buf[0] = av_buffer_create(NULL,
427 0,
429 pSurface,
431 }
432 break;
433 #endif
434 #if CONFIG_DXVA2
435 case AMF_MEMORY_DX9:
436 {
437 AMFPlane *plane0 = pSurface->pVtbl->GetPlaneAt(pSurface, 0);
438 frame->data[3] = plane0->pVtbl->GetNative(plane0);
439
440 frame->buf[0] = av_buffer_create(NULL,
441 0,
443 pSurface,
445 }
446 break;
447 #endif
448 default:
449 {
450 av_log(avctx, AV_LOG_ERROR, "Unsupported memory type : %d\n", pSurface->pVtbl->GetMemoryType(pSurface));
451 goto fail;
452 }
453 }
454 }
455
456
457 return frame;
458fail:
460 return NULL;
461}
462
463int amf_avframe_to_amfsurface(AVFilterContext *avctx, const AVFrame *frame, AMFSurface** ppSurface)
464{
465 AMFVariantStruct var = { 0 };
466 AMFFilterContext *ctx = avctx->priv;
467 AMFBuffer *hdrmeta_buffer = NULL;
468 AMFSurface *surface;
469 AMF_RESULT res;
470 int hw_surface = 0;
471
472 switch (frame->format) {
473#if CONFIG_D3D11VA
474 case AV_PIX_FMT_D3D11:
475 {
476 static const GUID AMFTextureArrayIndexGUID = { 0x28115527, 0xe7c3, 0x4b66, { 0x99, 0xd3, 0x4f, 0x2a, 0xe6, 0xb4, 0x7f, 0xaf } };
477 ID3D11Texture2D *texture = (ID3D11Texture2D*)frame->data[0]; // actual texture
478 int index = (intptr_t)frame->data[1]; // index is a slice in texture array is - set to tell AMF which slice to use
479 texture->lpVtbl->SetPrivateData(texture, &AMFTextureArrayIndexGUID, sizeof(index), &index);
480
481 res = ctx->amf_device_ctx->context->pVtbl->CreateSurfaceFromDX11Native(ctx->amf_device_ctx->context, texture, &surface, NULL); // wrap to AMF surface
482 AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR(ENOMEM), "CreateSurfaceFromDX11Native() failed with error %d\n", res);
483 hw_surface = 1;
484 }
485 break;
486#endif
488 {
489 surface = (AMFSurface*)frame->data[0]; // actual surface
490 surface->pVtbl->Acquire(surface); // returned surface has to be to be ref++
491 hw_surface = 1;
492 }
493 break;
494
495#if CONFIG_DXVA2
497 {
498 IDirect3DSurface9 *texture = (IDirect3DSurface9 *)frame->data[3]; // actual texture
499
500 res = ctx->amf_device_ctx->context->pVtbl->CreateSurfaceFromDX9Native(ctx->amf_device_ctx->context, texture, &surface, NULL); // wrap to AMF surface
501 AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR(ENOMEM), "CreateSurfaceFromDX9Native() failed with error %d\n", res);
502 hw_surface = 1;
503 }
504 break;
505#endif
506 default:
507 {
508 AMF_SURFACE_FORMAT amf_fmt = av_av_to_amf_format(frame->format);
509 res = ctx->amf_device_ctx->context->pVtbl->AllocSurface(ctx->amf_device_ctx->context, AMF_MEMORY_HOST, amf_fmt, frame->width, frame->height, &surface);
510 AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR(ENOMEM), "AllocSurface() failed with error %d\n", res);
511 amf_copy_surface(avctx, frame, surface);
512 }
513 break;
514 }
515
516 // If AMFSurface comes from other AMF components, it may have various
517 // properties already set. These properties can be used by other AMF
518 // components to perform their tasks. In the context of the AMF video
519 // filter, that other component could be an AMFVideoConverter. By default,
520 // AMFVideoConverter will use HDR related properties assigned to a surface
521 // by an AMFDecoder. If frames (surfaces) originated from any other source,
522 // i.e. from hevcdec, assign those properties from avframe; do not
523 // overwrite these properties if they already have a value.
524 res = surface->pVtbl->GetProperty(surface, AMF_VIDEO_DECODER_COLOR_TRANSFER_CHARACTERISTIC, &var);
525
526 if (res == AMF_NOT_FOUND && frame->color_trc != AVCOL_TRC_UNSPECIFIED)
527 // Note: as of now(Feb 2026), most AV and AMF enums are interchangeable.
528 // TBD: can enums change their values in the future?
529 // For better future-proofing it's better to have dedicated
530 // enum mapping functions.
531 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_DECODER_COLOR_TRANSFER_CHARACTERISTIC, frame->color_trc);
532
533 res = surface->pVtbl->GetProperty(surface, AMF_VIDEO_DECODER_COLOR_PRIMARIES, &var);
534 if (res == AMF_NOT_FOUND && frame->color_primaries != AVCOL_PRI_UNSPECIFIED)
535 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_DECODER_COLOR_PRIMARIES, frame->color_primaries);
536
537 res = surface->pVtbl->GetProperty(surface, AMF_VIDEO_DECODER_COLOR_RANGE, &var);
538 if (res == AMF_NOT_FOUND && frame->color_range != AVCOL_RANGE_UNSPECIFIED)
539 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_DECODER_COLOR_RANGE, frame->color_range);
540
541 // Color range for older drivers
542 if (frame->color_range == AVCOL_RANGE_JPEG) {
543 AMF_ASSIGN_PROPERTY_BOOL(res, surface, AMF_VIDEO_DECODER_FULL_RANGE_COLOR, 1);
544 } else if (frame->color_range != AVCOL_RANGE_UNSPECIFIED)
545 AMF_ASSIGN_PROPERTY_BOOL(res, surface, AMF_VIDEO_DECODER_FULL_RANGE_COLOR, 0);
546
547 // Color profile for newer drivers
548 res = surface->pVtbl->GetProperty(surface, AMF_VIDEO_DECODER_COLOR_PROFILE, &var);
549 if (res == AMF_NOT_FOUND && frame->color_range != AVCOL_RANGE_UNSPECIFIED && frame->colorspace != AVCOL_SPC_UNSPECIFIED) {
550 amf_int64 color_profile = color_profile = av_amf_get_color_profile(frame->color_range, frame->colorspace);
551
552 if (color_profile != AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN)
553 AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_DECODER_COLOR_PROFILE, color_profile);
554 }
555
556 if (ctx->in_trc == AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084 && (ctx->master_display || ctx->light_meta)) {
557 res = ctx->amf_device_ctx->context->pVtbl->AllocBuffer(ctx->amf_device_ctx->context, AMF_MEMORY_HOST, sizeof(AMFHDRMetadata), &hdrmeta_buffer);
558 if (res == AMF_OK) {
559 AMFHDRMetadata *hdrmeta = (AMFHDRMetadata*)hdrmeta_buffer->pVtbl->GetNative(hdrmeta_buffer);
560
561 av_amf_display_mastering_meta_to_hdrmeta(ctx->master_display, hdrmeta);
562 av_amf_light_metadata_to_hdrmeta(ctx->light_meta, hdrmeta);
563 AMF_ASSIGN_PROPERTY_INTERFACE(res, surface, AMF_VIDEO_DECODER_HDR_METADATA, hdrmeta_buffer);
564 }
565 } else if (frame->color_trc == AVCOL_TRC_SMPTE2084) {
566 res = surface->pVtbl->GetProperty(surface, AMF_VIDEO_DECODER_HDR_METADATA, &var);
567 if (res == AMF_NOT_FOUND) {
568 res = ctx->amf_device_ctx->context->pVtbl->AllocBuffer(ctx->amf_device_ctx->context, AMF_MEMORY_HOST, sizeof(AMFHDRMetadata), &hdrmeta_buffer);
569 if (res == AMF_OK) {
570 AMFHDRMetadata *hdrmeta = (AMFHDRMetadata*)hdrmeta_buffer->pVtbl->GetNative(hdrmeta_buffer);
571
572 if (av_amf_extract_hdr_metadata(frame, hdrmeta) == 0)
573 AMF_ASSIGN_PROPERTY_INTERFACE(res, surface, AMF_VIDEO_DECODER_HDR_METADATA, hdrmeta_buffer);
574 }
575 }
576 }
577
578 if (hdrmeta_buffer) {
579 hdrmeta_buffer->pVtbl->Release(hdrmeta_buffer);
580 hdrmeta_buffer = NULL;
581 }
582
583 if (frame->crop_left || frame->crop_right || frame->crop_top || frame->crop_bottom) {
584 size_t crop_x = frame->crop_left;
585 size_t crop_y = frame->crop_top;
586 size_t crop_w = frame->width - (frame->crop_left + frame->crop_right);
587 size_t crop_h = frame->height - (frame->crop_top + frame->crop_bottom);
588 AVFilterLink *outlink = avctx->outputs[0];
589 if (crop_x || crop_y) {
590 if (crop_w == outlink->w && crop_h == outlink->h) {
591 AMFData *cropped_buffer = NULL;
592 res = surface->pVtbl->Duplicate(surface, surface->pVtbl->GetMemoryType(surface), &cropped_buffer);
593 AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR(ENOMEM), "Duplicate() failed with error %d\n", res);
594 surface->pVtbl->Release(surface);
595 surface = (AMFSurface*)cropped_buffer;
596 }
597 else
598 surface->pVtbl->SetCrop(surface, (amf_int32)crop_x, (amf_int32)crop_y, (amf_int32)crop_w, (amf_int32)crop_h);
599 }
600 else
601 surface->pVtbl->SetCrop(surface, (amf_int32)crop_x, (amf_int32)crop_y, (amf_int32)crop_w, (amf_int32)crop_h);
602 }
603 else if (hw_surface) {
604 // input HW surfaces can be vertically aligned by 16; tell AMF the real size
605 surface->pVtbl->SetCrop(surface, 0, 0, frame->width, frame->height);
606 }
607
608 surface->pVtbl->SetPts(surface, frame->pts);
609 *ppSurface = surface;
610 return 0;
611}
static void amf_free_amfsurface(void *opaque, uint8_t *data)
Definition amfdec.c:58
#define AMF_RETURN_IF_FALSE(avctx, exp, ret_value,...)
Error handling helper.
Definition amfenc.h:169
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
Main libavfilter public API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
static AVFrame * frame
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add ref as a new reference to formats.
Definition formats.c:756
av_warn_unused_result AVFilterFormats * ff_make_pixel_format_list(const enum AVPixelFormat *fmts)
Create a list of supported pixel formats.
#define fail
Definition test.h:479
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition buffer.c:103
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Definition buffer.h:114
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.
Definition buffer.c:55
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition error.h:73
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition frame.c:496
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition frame.c:599
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition rational.c:80
void av_image_copy(uint8_t *const dst_data[4], const int dst_linesizes[4], const uint8_t *const src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Copy image in src_data to dst_data.
Definition imgutils.c:422
int index
Definition gxfenc.c:90
int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type, const char *device, AVDictionary *opts, int flags)
Open a device of the specified type and create an AVHWDeviceContext for it.
Definition hwcontext.c:615
const char * av_hwdevice_get_type_name(enum AVHWDeviceType type)
Get the string name of an AVHWDeviceType.
Definition hwcontext.c:120
int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr, enum AVHWDeviceType type, AVBufferRef *src_ref, int flags)
Create a new device of the specified type from an existing device.
Definition hwcontext.c:718
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition hwcontext.c:337
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition hwcontext.c:263
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
Definition hwcontext.c:506
@ AV_HWDEVICE_TYPE_D3D11VA
Definition hwcontext.h:35
@ AV_HWDEVICE_TYPE_AMF
Definition hwcontext.h:41
@ AV_HWDEVICE_TYPE_DXVA2
Definition hwcontext.h:32
int av_amf_display_mastering_meta_to_hdrmeta(const AVMasteringDisplayMetadata *display_meta, AMFHDRMetadata *hdrmeta)
int av_amf_light_metadata_to_hdrmeta(const AVContentLightMetadata *light_meta, AMFHDRMetadata *hdrmeta)
enum AMF_SURFACE_FORMAT av_av_to_amf_format(enum AVPixelFormat fmt)
int av_amf_extract_hdr_metadata(const AVFrame *frame, AMFHDRMetadata *hdrmeta)
enum AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM av_amf_get_color_profile(enum AVColorRange color_range, enum AVColorSpace color_space)
#define AMF_GOTO_FAIL_IF_FALSE(avctx, exp, ret_value,...)
misc image utilities
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition filters.h:199
const char * desc
Definition libsvtav1.c:83
static const struct @257111027162314367033347246032313251342043035002 planes[]
Memory handling functions.
const char data[16]
Definition mxf.c:149
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.
Definition pixdesc.c:3380
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition pixdesc.c:3392
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
Definition pixdesc.h:128
AVColorRange
Visual content value range.
Definition pixfmt.h:748
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AVCOL_RANGE_UNSPECIFIED
Definition pixfmt.h:749
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_DXVA2_VLD
HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer.
Definition pixfmt.h:134
@ AV_PIX_FMT_D3D11
Hardware surfaces for Direct3D11.
Definition pixfmt.h:336
@ AV_PIX_FMT_AMF_SURFACE
HW acceleration through AMF.
Definition pixfmt.h:477
@ AVCOL_PRI_UNSPECIFIED
Definition pixfmt.h:645
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition pixfmt.h:689
@ AVCOL_TRC_UNSPECIFIED
Definition pixfmt.h:675
AVColorSpace
YUV colorspace type.
Definition pixfmt.h:706
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
Definition pixfmt.h:708
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1
Definition pixfmt.h:707
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
Definition pixfmt.h:717
@ AVCOL_SPC_UNSPECIFIED
Definition pixfmt.h:709
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
Definition pixfmt.h:713
int ff_scale_adjust_dimensions(AVFilterLink *inlink, int *ret_w, int *ret_h, int force_original_aspect_ratio, int force_divisible_by, double w_adj)
Transform evaluated width and height obtained from ff_scale_eval_dimensions into actual target width ...
Definition scale_eval.c:123
int ff_scale_eval_dimensions(void *log_ctx, const char *w_expr, const char *h_expr, AVFilterLink *inlink, AVFilterLink *outlink, int *ret_w, int *ret_h)
Parse and evaluate string expressions for width and height.
Definition scale_eval.c:58
#define FF_ARRAY_ELEMS(a)
uint8_t * data
The data buffer.
Definition buffer.h:90
An instance of a filter.
Definition avfilter.h:273
AVFilterLink ** inputs
array of pointers to input links
Definition avfilter.h:281
void * priv
private data for use by the filter
Definition avfilter.h:288
AVBufferRef * hw_device_ctx
For filters which will create hardware frames, sets the device the filter should create them in.
Definition avfilter.h:336
AVFilterLink ** outputs
array of pointers to output links
Definition avfilter.h:285
AVFilterFormats * formats
List of supported formats (pixel or sample).
Definition avfilter.h:125
A list of supported formats for one end of a filter link.
Definition formats.h:64
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition hwcontext.h:63
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition hwcontext.h:88
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition hwcontext.h:75
This struct describes a set or pool of "hardware" frames (i.e.
Definition hwcontext.h:118
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition hwcontext.h:200
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition hwcontext.h:129
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition hwcontext.h:213
int width
The allocated dimensions of the frames in this pool.
Definition hwcontext.h:220
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
#define av_freep(p)
#define av_log(a,...)
static FILE * out
Definition movenc.c:55
static AVFormatContext * ctx
Definition movenc.c:49
void amf_free_amfsurface(void *opaque, uint8_t *data)
AVFrame * amf_amfsurface_to_avframe(AVFilterContext *avctx, AMFSurface *pSurface)
int amf_copy_surface(AVFilterContext *avctx, const AVFrame *frame, AMFSurface *surface)
int amf_avframe_to_amfsurface(AVFilterContext *avctx, const AVFrame *frame, AMFSurface **ppSurface)
int amf_filter_init(AVFilterContext *avctx)
int amf_init_filter_config(AVFilterLink *outlink, enum AVPixelFormat *in_format)
int amf_filter_filter_frame(AVFilterLink *inlink, AVFrame *in)
int amf_setup_input_output_formats(AVFilterContext *avctx, const enum AVPixelFormat *input_pix_fmts, const enum AVPixelFormat *output_pix_fmts)
void amf_filter_uninit(AVFilterContext *avctx)