FFmpeg
amfdec.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 
21 #include "libavutil/pixdesc.h"
22 #include "amfdec.h"
23 #include "codec_internal.h"
24 #include "hwconfig.h"
25 #include "libavutil/time.h"
26 #include "decode.h"
27 #include "decode_bsf.h"
28 
29 #if CONFIG_D3D11VA
31 #endif
32 #if CONFIG_DXVA2
33 #define COBJMACROS
35 #endif
36 
37 #ifdef _WIN32
38 #include "compat/w32dlfcn.h"
39 #else
40 #include <dlfcn.h>
41 #endif
42 //will be in public headers soon
43 #define AMF_VIDEO_DECODER_OUTPUT_FORMAT L"OutputDecodeFormat"
44 
45 static const AVCodecHWConfigInternal *const amf_hw_configs[] = {
46  &(const AVCodecHWConfigInternal) {
47  .public = {
51  .device_type = AV_HWDEVICE_TYPE_AMF,
52  },
53  .hwaccel = NULL,
54  },
55  NULL
56 };
57 
58 static void amf_free_amfsurface(void *opaque, uint8_t *data)
59 {
60  AMFSurface *surface = (AMFSurface*)(data);
61  surface->pVtbl->Release(surface);
62 }
63 
65 {
66  if( AMF_GET_MAJOR_VERSION(amf_device_ctx->version) <= 1 &&
67  AMF_GET_MINOR_VERSION(amf_device_ctx->version) <= 4 &&
68  AMF_GET_SUBMINOR_VERSION(amf_device_ctx->version) < 36)
69  return 1;
70  return 0;
71 }
72 
73 static int amf_init_decoder(AVCodecContext *avctx)
74 {
76  AVHWDeviceContext *hw_device_ctx = (AVHWDeviceContext*)ctx->device_ctx_ref->data;
77  AVAMFDeviceContext *amf_device_ctx = (AVAMFDeviceContext*)hw_device_ctx->hwctx;
78  const wchar_t *codec_id = NULL;
79  AMF_RESULT res;
80  AMFBuffer *buffer;
81  amf_int64 color_profile;
82  int pool_size = 36;
83  // way-around for older drivers that don't support dynamic bitness detection -
84  // define HEVC and VP9 10-bit based on container info
85  int no_bitness_detect = amf_legacy_driver_no_bitness_detect(amf_device_ctx);
86 
87  ctx->drain = 0;
88  ctx->resolution_changed = 0;
89 
90  switch (avctx->codec->id) {
91  case AV_CODEC_ID_H264:
92  codec_id = AMFVideoDecoderUVD_H264_AVC;
93  break;
94  case AV_CODEC_ID_HEVC: {
95  codec_id = AMFVideoDecoderHW_H265_HEVC;
96  if(no_bitness_detect){
97  if(avctx->pix_fmt == AV_PIX_FMT_YUV420P10)
98  codec_id = AMFVideoDecoderHW_H265_MAIN10;
99  }
100  } break;
101  case AV_CODEC_ID_VP9: {
102  codec_id = AMFVideoDecoderHW_VP9;
103  if(no_bitness_detect){
104  if(avctx->pix_fmt == AV_PIX_FMT_YUV420P10)
105  codec_id = AMFVideoDecoderHW_VP9_10BIT;
106  }
107  } break;
108  case AV_CODEC_ID_AV1:
109  codec_id = AMFVideoDecoderHW_AV1;
110  break;
111  default:
112  break;
113  }
114  AMF_RETURN_IF_FALSE(ctx, codec_id != NULL, AVERROR(EINVAL), "Codec %d is not supported\n", avctx->codec->id);
115 
116  res = amf_device_ctx->factory->pVtbl->CreateComponent(amf_device_ctx->factory, amf_device_ctx->context, codec_id, &ctx->decoder);
117  AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_ENCODER_NOT_FOUND, "CreateComponent(%ls) failed with error %d\n", codec_id, res);
118 
119  // Color Metadata
120  /// Color Range (Support for older Drivers)
121  if (avctx->color_range == AVCOL_RANGE_JPEG) {
122  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->decoder, AMF_VIDEO_DECODER_FULL_RANGE_COLOR, 1);
123  } else if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED) {
124  AMF_ASSIGN_PROPERTY_BOOL(res, ctx->decoder, AMF_VIDEO_DECODER_FULL_RANGE_COLOR, 0);
125  }
126  color_profile = av_amf_get_color_profile(avctx->color_range, avctx->colorspace);
127  if (color_profile != AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN)
128  AMF_ASSIGN_PROPERTY_INT64(res, ctx->decoder, AMF_VIDEO_DECODER_COLOR_PROFILE, color_profile);
129  if (avctx->color_trc != AVCOL_TRC_UNSPECIFIED)
130  AMF_ASSIGN_PROPERTY_INT64(res, ctx->decoder, AMF_VIDEO_DECODER_COLOR_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->color_trc);
131 
133  AMF_ASSIGN_PROPERTY_INT64(res, ctx->decoder, AMF_VIDEO_DECODER_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries);
134 
135  if (ctx->timestamp_mode != -1)
136  AMF_ASSIGN_PROPERTY_INT64(res, ctx->decoder, AMF_TIMESTAMP_MODE, ctx->timestamp_mode);
137  if (ctx->decoder_mode != -1)
138  AMF_ASSIGN_PROPERTY_INT64(res, ctx->decoder, AMF_VIDEO_DECODER_REORDER_MODE, ctx->decoder_mode);
139  if (ctx->dpb_size != -1)
140  AMF_ASSIGN_PROPERTY_INT64(res, ctx->decoder, AMF_VIDEO_DECODER_DPB_SIZE, ctx->dpb_size);
141  if (ctx->lowlatency != -1)
142  AMF_ASSIGN_PROPERTY_INT64(res, ctx->decoder, AMF_VIDEO_DECODER_LOW_LATENCY, ctx->lowlatency);
143  if (ctx->smart_access_video != -1) {
144  AMF_ASSIGN_PROPERTY_INT64(res, ctx->decoder, AMF_VIDEO_DECODER_ENABLE_SMART_ACCESS_VIDEO, ctx->smart_access_video != 0);
145  if (res != AMF_OK) {
146  av_log(avctx, AV_LOG_ERROR, "The Smart Access Video is not supported by AMF decoder.\n");
147  return AVERROR(EINVAL);
148  } else {
149  av_log(avctx, AV_LOG_INFO, "The Smart Access Video (%d) is set.\n", ctx->smart_access_video);
150  // Set low latency mode if Smart Access Video is enabled
151  if (ctx->smart_access_video != 0) {
152  AMF_ASSIGN_PROPERTY_INT64(res, ctx->decoder, AMF_VIDEO_DECODER_LOW_LATENCY, true);
153  av_log(avctx, AV_LOG_INFO, "The Smart Access Video set low latency mode for decoder.\n");
154  }
155  }
156  }
157  if (ctx->skip_transfer_sav != -1)
158  AMF_ASSIGN_PROPERTY_INT64(res, ctx->decoder, AMF_VIDEO_DECODER_SKIP_TRANSFER_SMART_ACCESS_VIDEO, ctx->skip_transfer_sav);
159 
160  if (ctx->copy_output != -1)
161  AMF_ASSIGN_PROPERTY_INT64(res, ctx->decoder, AMF_VIDEO_DECODER_SURFACE_COPY, ctx->copy_output);
162 
163  if (avctx->extradata_size) {
164  const uint8_t *extradata;
165  int extradata_size;
166  ff_decode_get_extradata(avctx, &extradata, &extradata_size);
167  res = amf_device_ctx->context->pVtbl->AllocBuffer(amf_device_ctx->context, AMF_MEMORY_HOST, extradata_size, &buffer);
168  if (res == AMF_OK) {
169  memcpy(buffer->pVtbl->GetNative(buffer), extradata, extradata_size);
170  AMF_ASSIGN_PROPERTY_INTERFACE(res,ctx->decoder, AMF_VIDEO_DECODER_EXTRADATA, buffer);
171  buffer->pVtbl->Release(buffer);
172  buffer = NULL;
173  }
174  }
175  if (ctx->surface_pool_size == -1) {
176  ctx->surface_pool_size = pool_size;
177  if (avctx->extra_hw_frames > 0)
178  ctx->surface_pool_size += avctx->extra_hw_frames;
179  if (avctx->active_thread_type & FF_THREAD_FRAME)
180  ctx->surface_pool_size += avctx->thread_count;
181  }
182 
183  //at the moment, there is such a restriction in AMF.
184  //when it is possible, I will remove this code
185  if (ctx->surface_pool_size > 100)
186  ctx->surface_pool_size = 100;
187 
188  AMF_ASSIGN_PROPERTY_INT64(res, ctx->decoder, AMF_VIDEO_DECODER_SURFACE_POOL_SIZE, ctx->surface_pool_size);
189  res = ctx->decoder->pVtbl->Init(ctx->decoder, AMF_SURFACE_UNKNOWN, avctx->width, avctx->height);
190  if (res != AMF_OK) {
191  av_log(avctx, AV_LOG_ERROR, "Decoder initialization failed with error %d\n", res);
192  return AVERROR(EINVAL);
193  }
194  return 0;
195 }
196 
198 {
199  AMFDecoderContext *ctx = avctx->priv_data;
200 
201  if (ctx->decoder) {
202  ctx->decoder->pVtbl->Terminate(ctx->decoder);
203  ctx->decoder->pVtbl->Release(ctx->decoder);
204  ctx->decoder = NULL;
205  }
206 
207  av_buffer_unref(&ctx->device_ctx_ref);
208  av_packet_free(&ctx->in_pkt);
209 
210  return 0;
211 }
212 
213 static int amf_init_frames_context(AVCodecContext *avctx, int sw_format, int new_width, int new_height)
214 {
215  int ret;
216  AVHWDeviceContext *hwdev_ctx;
217  AVHWFramesContext *hwframes_ctx;
219  if (!avctx->hw_frames_ctx || !avctx->hw_device_ctx)
220  return 0;
221  hwdev_ctx = (AVHWDeviceContext*)avctx->hw_device_ctx->data;
222  hwframes_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
223  ctx = avctx->priv_data;
224 
225  if (hwdev_ctx->type != AV_HWDEVICE_TYPE_AMF)
226  return 0;
227 
228  hwframes_ctx->width = new_width;
229  hwframes_ctx->height = new_height;
230  hwframes_ctx->format = AV_PIX_FMT_AMF_SURFACE;
231  hwframes_ctx->sw_format = sw_format;
232  hwframes_ctx->initial_pool_size = ctx->surface_pool_size + 8;
233 
235  if (ret < 0) {
236  av_log(avctx, AV_LOG_ERROR, "Error initializing a AMF frame pool\n");
238  return ret;
239  }
240  return 0;
241 }
242 
243 static int amf_reinit_frames_context(AVCodecContext *avctx, int sw_format,
244  int new_width, int new_height)
245 {
246  if (!avctx->hw_device_ctx)
247  return 0;
248 
251  if (!avctx->hw_frames_ctx)
252  return AVERROR(ENOMEM);
253 
254  return amf_init_frames_context(avctx, sw_format, new_width, new_height);
255 }
256 
257 static int amf_decode_init(AVCodecContext *avctx)
258 {
259  AMFDecoderContext *ctx = avctx->priv_data;
260  ctx->dimensions_initialized = 0;
261  int ret;
262  ctx->in_pkt = av_packet_alloc();
263  if (!ctx->in_pkt)
264  return AVERROR(ENOMEM);
265 
266  if (avctx->hw_device_ctx) {
267  AVHWDeviceContext *hwdev_ctx;
268  hwdev_ctx = (AVHWDeviceContext*)avctx->hw_device_ctx->data;
269  if (hwdev_ctx->type == AV_HWDEVICE_TYPE_AMF)
270  {
271  ctx->device_ctx_ref = av_buffer_ref(avctx->hw_device_ctx);
272  if (!avctx->hw_frames_ctx) {
274  AMF_GOTO_FAIL_IF_FALSE(avctx, !!avctx->hw_frames_ctx, AVERROR(ENOMEM), "av_hwframe_ctx_alloc failed\n");
275  }
276  } else {
278  AMF_GOTO_FAIL_IF_FALSE(avctx, ret == 0, ret, "Failed to create derived AMF device context: %s\n", av_err2str(ret));
279  }
280  } else {
281  ret = av_hwdevice_ctx_create(&ctx->device_ctx_ref, AV_HWDEVICE_TYPE_AMF, NULL, NULL, 0);
282  AMF_GOTO_FAIL_IF_FALSE(avctx, ret == 0, ret, "Failed to create hardware device context (AMF) : %s\n", av_err2str(ret));
283  }
284  if ((ret = amf_init_decoder(avctx)) == 0) {
285  AVHWDeviceContext *hw_device_ctx = (AVHWDeviceContext*)ctx->device_ctx_ref->data;
286  AVAMFDeviceContext *amf_device_ctx = (AVAMFDeviceContext*)hw_device_ctx->hwctx;
287  enum AVPixelFormat surf_pix_fmt = AV_PIX_FMT_NONE;
288 
289  if (amf_legacy_driver_no_bitness_detect(amf_device_ctx)) {
290  // if bitness detection is not supported in legacy driver use format from container
291  switch (avctx->pix_fmt) {
292  case AV_PIX_FMT_YUV420P:
293  case AV_PIX_FMT_YUVJ420P:
294  surf_pix_fmt = AV_PIX_FMT_NV12; break;
296  surf_pix_fmt = AV_PIX_FMT_P010; break;
297  }
298  } else {
299  AMFVariantStruct format_var = {0};
300 
301  ret = ctx->decoder->pVtbl->GetProperty(ctx->decoder, AMF_VIDEO_DECODER_OUTPUT_FORMAT, &format_var);
302  AMF_GOTO_FAIL_IF_FALSE(avctx, ret == AMF_OK, AVERROR(EINVAL), "Failed to get output format (AMF) : %d\n", ret);
303 
304  surf_pix_fmt = av_amf_to_av_format(format_var.int64Value);
305  }
306  if (avctx->hw_frames_ctx)
307  {
308  // this values should be set for avcodec_open2
309  // will be updated after header decoded if not true.
310  if (surf_pix_fmt == AV_PIX_FMT_NONE)
311  surf_pix_fmt = AV_PIX_FMT_NV12; // for older drivers
312  int frames_w = 0;
313  int frames_h = 0;
314 
315  if (avctx->coded_width > 0 && avctx->coded_height > 0) {
316  frames_w = avctx->coded_width;
317  frames_h = avctx->coded_height;
318  } else if (avctx->width > 0 && avctx->height > 0) {
319  frames_w = avctx->width;
320  frames_h = avctx->height;
321  } else {
322  frames_w = 1280;
323  frames_h = 720;
324  }
325  ret = amf_init_frames_context(avctx, surf_pix_fmt, frames_w, frames_h);
326  AMF_GOTO_FAIL_IF_FALSE(avctx, ret == 0, ret, "Failed to init frames context (AMF) : %s\n", av_err2str(ret));
327  }
328  else
329  avctx->pix_fmt = surf_pix_fmt;
330 
331  return 0;
332  }
333 fail:
334  amf_decode_close(avctx);
335  return ret;
336 }
337 
339 {
340  return pri != AVCOL_PRI_UNSPECIFIED && pri != AVCOL_PRI_RESERVED0 &&
342 }
343 
345 {
346  return trc != AVCOL_TRC_UNSPECIFIED && trc != AVCOL_TRC_RESERVED0 &&
348 }
349 
350 static enum AVColorPrimaries amf_to_av_primaries(enum AMF_COLOR_PRIMARIES_ENUM pri)
351 {
352  enum AVColorPrimaries avpri = (enum AVColorPrimaries)pri;
353 
354  switch (pri) {
355  case AMF_COLOR_PRIMARIES_UNDEFINED:
356  case AMF_COLOR_PRIMARIES_UNSPECIFIED:
357  case AMF_COLOR_PRIMARIES_RESERVED:
358  return AVCOL_PRI_UNSPECIFIED;
359  default:
360  if (amf_color_primaries_valid(avpri))
361  return avpri;
362  return AVCOL_PRI_UNSPECIFIED;
363  }
364 }
365 
366 static enum AVColorTransferCharacteristic amf_to_av_trc(enum AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM trc)
367 {
369 
370  switch (trc) {
371  case AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED:
372  case AMF_COLOR_TRANSFER_CHARACTERISTIC_UNSPECIFIED:
373  case AMF_COLOR_TRANSFER_CHARACTERISTIC_RESERVED:
374  return AVCOL_TRC_UNSPECIFIED;
375  default:
376  if (amf_color_trc_valid(avtrc))
377  return avtrc;
378  return AVCOL_TRC_UNSPECIFIED;
379  }
380 }
381 
382 static enum AVColorRange amf_to_av_range(enum AMF_COLOR_RANGE_ENUM range)
383 {
384  switch (range) {
385  case AMF_COLOR_RANGE_FULL:
386  return AVCOL_RANGE_JPEG;
387  case AMF_COLOR_RANGE_STUDIO:
388  return AVCOL_RANGE_MPEG;
389  default:
391  }
392 }
393 
394 static enum AVColorSpace amf_to_av_colorspace(enum AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM profile)
395 {
396  switch (profile) {
397  case AMF_VIDEO_CONVERTER_COLOR_PROFILE_601:
398  case AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601:
399  return AVCOL_SPC_SMPTE170M;
400  case AMF_VIDEO_CONVERTER_COLOR_PROFILE_709:
401  case AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709:
402  return AVCOL_SPC_BT709;
403  case AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020:
404  case AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020:
405  return AVCOL_SPC_BT2020_NCL;
406  default:
407  return AVCOL_SPC_UNSPECIFIED;
408  }
409 }
410 
411 static void amf_read_surface_color(AVCodecContext *avctx, AMFSurface *surface,
412  AVFrame *frame)
413 {
414  AMFVariantStruct var = {0};
415  AMF_RESULT res;
417  enum AVColorTransferCharacteristic trc = avctx->color_trc;
418  enum AVColorSpace colorspace = avctx->colorspace;
419  enum AVColorRange range = avctx->color_range;
420 
421  res = surface->pVtbl->GetProperty(surface, AMF_VIDEO_DECODER_COLOR_PRIMARIES, &var);
422  if (res == AMF_OK)
423  primaries = amf_to_av_primaries((enum AMF_COLOR_PRIMARIES_ENUM)var.int64Value);
424  AMFVariantClear(&var);
425 
426  res = surface->pVtbl->GetProperty(surface, AMF_VIDEO_DECODER_COLOR_TRANSFER_CHARACTERISTIC, &var);
427  if (res == AMF_OK)
428  trc = amf_to_av_trc((enum AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM)var.int64Value);
429  AMFVariantClear(&var);
430 
431  res = surface->pVtbl->GetProperty(surface, AMF_VIDEO_DECODER_COLOR_PROFILE, &var);
432  if (res == AMF_OK)
433  colorspace = amf_to_av_colorspace((enum AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM)var.int64Value);
434  AMFVariantClear(&var);
435 
437  colorspace != AVCOL_SPC_UNSPECIFIED) {
438  res = surface->pVtbl->GetProperty(surface, AMF_VIDEO_DECODER_COLOR_RANGE, &var);
439  if (res == AMF_OK)
440  range = amf_to_av_range((enum AMF_COLOR_RANGE_ENUM)var.int64Value);
441  AMFVariantClear(&var);
442  }
443  avctx->color_primaries = primaries;
444  avctx->color_trc = trc;
445  avctx->colorspace = colorspace;
446  avctx->color_range = range;
447 
448  frame->color_primaries = primaries;
449  frame->color_trc = trc;
450  frame->colorspace = colorspace;
451  frame->color_range = range;
452 }
453 
454 static AMF_RESULT amf_get_property_buffer(AMFData *object, const wchar_t *name, AMFBuffer **val)
455 {
456  AMF_RESULT res;
457  AMFVariantStruct var;
458  res = AMFVariantInit(&var);
459  if (res == AMF_OK) {
460  res = object->pVtbl->GetProperty(object, name, &var);
461  if (res == AMF_OK) {
462  if (var.type == AMF_VARIANT_INTERFACE) {
463  AMFGuid guid_AMFBuffer = IID_AMFBuffer();
464  AMFInterface *amf_interface = AMFVariantInterface(&var);
465  res = amf_interface->pVtbl->QueryInterface(amf_interface, &guid_AMFBuffer, (void**)val);
466  } else {
467  res = AMF_INVALID_DATA_TYPE;
468  }
469  }
470  AMFVariantClear(&var);
471  }
472  return res;
473 }
474 
475 static int amf_attach_hdr_metadata(AVCodecContext *avctx, AMFSurface *surface, AVFrame *frame)
476 {
477  AMFBuffer *hdrmeta_buffer = NULL;
478  AMFHDRMetadata *hdrmeta;
479  AMF_RESULT res;
480  int ret;
481 
482  if (frame->color_trc != AVCOL_TRC_SMPTE2084)
483  return 0;
484 
485  res = amf_get_property_buffer((AMFData *)surface, AMF_VIDEO_DECODER_HDR_METADATA,
486  &hdrmeta_buffer);
487  if (!hdrmeta_buffer)
488  return 0;
489 
490  if (res != AMF_OK) {
491  hdrmeta_buffer->pVtbl->Release(hdrmeta_buffer);
492  return AVERROR(EINVAL);
493  }
494 
495  hdrmeta = (AMFHDRMetadata *)hdrmeta_buffer->pVtbl->GetNative(hdrmeta_buffer);
496  if (!hdrmeta) {
497  hdrmeta_buffer->pVtbl->Release(hdrmeta_buffer);
498  return AVERROR(EINVAL);
499  }
500 
502  hdrmeta_buffer->pVtbl->Release(hdrmeta_buffer);
503  return ret;
504 }
505 
506 static int amf_amfsurface_to_avframe(AVCodecContext *avctx, AMFSurface* surface, AVFrame *frame)
507 {
508  AMFVariantStruct var = {0};
509  AMFPlane *plane;
510  int i;
511  int ret;
512  int format_amf;
513 
514  if (avctx->hw_device_ctx && ((AVHWDeviceContext*)avctx->hw_device_ctx->data)->type == AV_HWDEVICE_TYPE_AMF) {
515  // prepare frame similar to ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF);
516 
517  ret = ff_decode_frame_props(avctx, frame);
518  if (ret < 0)
519  return ret;
520 
521  avctx->sw_pix_fmt = avctx->pix_fmt;
522 
523  ret = ff_attach_decode_data(avctx, frame);
524  if (ret < 0)
525  return ret;
526  frame->width = avctx->width;
527  frame->height = avctx->height;
528 
529  ////
530  frame->buf[0] = av_buffer_create((uint8_t *)surface, sizeof(surface),
531  amf_free_amfsurface, (void*)avctx,
533  AMF_RETURN_IF_FALSE(avctx, !!frame->buf[0], AVERROR(ENOMEM), "av_buffer_create for amf surface failed.");
534 
535  frame->data[0] = (uint8_t *)surface;
536  frame->format = AV_PIX_FMT_AMF_SURFACE;
537  format_amf = surface->pVtbl->GetFormat(surface);
538  avctx->sw_pix_fmt = av_amf_to_av_format(format_amf);
539  frame->hw_frames_ctx = av_buffer_ref(avctx->hw_frames_ctx);
540  } else {
541  ret = surface->pVtbl->Convert(surface, AMF_MEMORY_HOST);
542  AMF_RETURN_IF_FALSE(avctx, ret == AMF_OK, AVERROR_UNKNOWN, "Convert(amf::AMF_MEMORY_HOST) failed with error %d\n", ret);
543 
544  for (i = 0; i < surface->pVtbl->GetPlanesCount(surface); i++) {
545  plane = surface->pVtbl->GetPlaneAt(surface, i);
546  frame->data[i] = plane->pVtbl->GetNative(plane);
547  frame->linesize[i] = plane->pVtbl->GetHPitch(plane);
548  }
549 
550  frame->buf[0] = av_buffer_create((uint8_t *)surface, sizeof(surface),
551  amf_free_amfsurface, (void*)avctx,
553  AMF_RETURN_IF_FALSE(avctx, !!frame->buf[0], AVERROR(ENOMEM), "av_buffer_create for amf surface failed.");
554 
555  format_amf = surface->pVtbl->GetFormat(surface);
556  frame->format = av_amf_to_av_format(format_amf);
557  }
558 
559  frame->width = avctx->width;
560  frame->height = avctx->height;
561 
562  frame->pts = surface->pVtbl->GetPts(surface);
563 
564  surface->pVtbl->GetProperty(surface, L"FFMPEG:dts", &var);
565  frame->pkt_dts = var.int64Value;
566 
567  frame->duration = surface->pVtbl->GetDuration(surface);
568  if (frame->duration < 0)
569  frame->duration = 0;
570 
571  amf_read_surface_color(avctx, surface, frame);
572 
573  ret = amf_attach_hdr_metadata(avctx, surface, frame);
574  if (ret < 0)
575  return ret;
576 
577  return 0;
578 }
579 
580 static AMF_RESULT amf_receive_frame(AVCodecContext *avctx, AVFrame *frame)
581 {
582  AMFDecoderContext *ctx = avctx->priv_data;
583  AMF_RESULT ret = AMF_OK;
584  AMFSurface *surface = NULL;
585  AMFData *data_out = NULL;
586 
587  ret = ctx->decoder->pVtbl->QueryOutput(ctx->decoder, &data_out);
588  if (ret != AMF_OK && ret != AMF_REPEAT) {
589  return ret;
590  }
591  if (data_out == NULL) {
592  return AMF_REPEAT;
593  }
594 
595  if (data_out) {
596  AMFGuid guid = IID_AMFSurface();
597  data_out->pVtbl->QueryInterface(data_out, &guid, (void**)&surface); // query for buffer interface
598  data_out->pVtbl->Release(data_out);
599  data_out = NULL;
600  }
601 
602  ret = amf_amfsurface_to_avframe(avctx, surface, frame);
603  AMF_GOTO_FAIL_IF_FALSE(avctx, ret >= 0, AMF_FAIL, "Failed to convert AMFSurface to AVFrame = %d\n", ret);
604  return AMF_OK;
605 fail:
606 
607  if (surface) {
608  surface->pVtbl->Release(surface);
609  surface = NULL;
610  }
611  return ret;
612 }
613 
614 static AMF_RESULT amf_update_buffer_properties(AVCodecContext *avctx, AMFBuffer* buffer, const AVPacket* pkt)
615 {
616  AMF_RESULT res;
617 
618  AMF_RETURN_IF_FALSE(avctx, buffer != NULL, AMF_INVALID_ARG, "update_buffer_properties() - buffer not passed in");
619  AMF_RETURN_IF_FALSE(avctx, pkt != NULL, AMF_INVALID_ARG, "update_buffer_properties() - packet not passed in");
620  buffer->pVtbl->SetPts(buffer, pkt->pts);
621  buffer->pVtbl->SetDuration(buffer, pkt->duration);
622  AMF_ASSIGN_PROPERTY_INT64(res, buffer, L"FFMPEG:dts", pkt->dts);
623  if (res != AMF_OK)
624  av_log(avctx, AV_LOG_VERBOSE, "Failed to assign dts value.");
625  return AMF_OK;
626 }
627 
628 static AMF_RESULT amf_buffer_from_packet(AVCodecContext *avctx, const AVPacket* pkt, AMFBuffer** buffer)
629 {
630  AMFDecoderContext *ctx = avctx->priv_data;
631  AVHWDeviceContext *hw_device_ctx = (AVHWDeviceContext*)ctx->device_ctx_ref->data;
632  AVAMFDeviceContext *amf_device_ctx = (AVAMFDeviceContext *)hw_device_ctx->hwctx;
633  AMFContext *ctxt = amf_device_ctx->context;
634  void *mem;
635  AMF_RESULT err;
636  AMFBuffer *buf = NULL;
637 
638  AMF_RETURN_IF_FALSE(ctxt, pkt != NULL, AMF_INVALID_ARG, "amf_buffer_from_packet() - packet not passed in");
639  AMF_RETURN_IF_FALSE(ctxt, buffer != NULL, AMF_INVALID_ARG, "amf_buffer_from_packet() - buffer pointer not passed in");
640 
641  err = ctxt->pVtbl->AllocBuffer(ctxt, AMF_MEMORY_HOST, pkt->size + AV_INPUT_BUFFER_PADDING_SIZE, buffer);
642  AMF_RETURN_IF_FALSE(ctxt, err == AMF_OK, err, "amf_buffer_from_packet() - failed");
643  buf = *buffer;
644  err = buf->pVtbl->SetSize(buf, pkt->size);
645  AMF_RETURN_IF_FALSE(ctxt, err == AMF_OK, err, "amf_buffer_from_packet() - SetSize failed");
646  // get the memory location and check the buffer was indeed allocated
647  mem = buf->pVtbl->GetNative(buf);
648  AMF_RETURN_IF_FALSE(ctxt, mem != NULL, AMF_INVALID_POINTER, "amf_buffer_from_packet() - GetNative failed");
649 
650  // copy the packet memory and clear data padding
651  memcpy(mem, pkt->data, pkt->size);
652  memset((amf_int8*)(mem)+pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
653 
654  return amf_update_buffer_properties(avctx, buf, pkt);
655 }
656 
658 {
659  AMFDecoderContext *ctx = avctx->priv_data;
660  AMFVariantStruct size_var = {0};
661  AMF_RESULT res = AMF_OK;
662 
663  res = ctx->decoder->pVtbl->GetProperty(ctx->decoder, AMF_VIDEO_DECODER_CURRENT_SIZE, &size_var);
664  if (res == AMF_OK && size_var.sizeValue.width > 0 && size_var.sizeValue.height > 0) {
665  avctx->width = size_var.sizeValue.width;
666  avctx->height = size_var.sizeValue.height;
667  avctx->coded_width = size_var.sizeValue.width;
668  avctx->coded_height = size_var.sizeValue.height;
669 
670  ctx->dimensions_initialized = 1;
671 
672  av_log(avctx, AV_LOG_DEBUG, "AMF: detected initial decoder size %dx%d\n", avctx->width, avctx->height);
673  }
674 }
675 
676 static int amf_decode_frame(AVCodecContext *avctx, struct AVFrame *frame)
677 {
678  AMFDecoderContext *ctx = avctx->priv_data;
679  AMFBuffer *buf;
680  AMF_RESULT res;
681  int got_frame = 0;
682  AVPacket *avpkt = ctx->in_pkt;
683 
684  if (!ctx->decoder)
685  return AVERROR(EINVAL);
686 
687  // get packet if needed
688  if(!ctx->drain){
689  if(ctx->resolution_changed)
690  ctx->resolution_changed = 0;
691  else{
692  int ret;
693  av_packet_unref(avpkt);
694  ret = ff_decode_get_packet(avctx, avpkt);
695  if (ret < 0 && ret != AVERROR_EOF)
696  return ret;
697  if (ret == AVERROR_EOF) {
698  //nothing to consume, start external drain
699  ctx->decoder->pVtbl->Drain(ctx->decoder);
700  ctx->drain = 1;
701  }
702  }
703  }
704 
705  if(!ctx->drain){
706  // submit frame
707  res = amf_buffer_from_packet(avctx, avpkt, &buf);
708  AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, 0, "Cannot convert AVPacket to AMFbuffer");
709  do{
710  res = ctx->decoder->pVtbl->SubmitInput(ctx->decoder, (AMFData*) buf);
711  if(res == AMF_DECODER_NO_FREE_SURFACES)
712  {
713  av_usleep(100);
714  }
715  } while (res == AMF_DECODER_NO_FREE_SURFACES);
716 
717  buf->pVtbl->Release(buf);
718 
719  if(res == AMF_DECODER_NO_FREE_SURFACES) {
720  // input is not consumed, need to QueryOutput and submit again
721  av_log(avctx, AV_LOG_VERBOSE, "SubmitInput() returned NO_FREE_SURFACES and came out of loop - should never happen\n");
722  res = AMF_OK;
723  } else if (res == AMF_RESOLUTION_CHANGED) {
724  //input is not consumed, start internal drain
725  ctx->decoder->pVtbl->Drain(ctx->decoder);
726  ctx->drain = 1;
727  // process resolution_changed when internal drain is complete
728  ctx->resolution_changed = 1;
729  res = AMF_OK;
730  } else if (res != AMF_OK && res != AMF_NEED_MORE_INPUT && res != AMF_REPEAT) {
731  av_log(avctx, AV_LOG_ERROR, "SubmitInput() returned error %d\n", res);
732  return AVERROR(EINVAL);
733  }
734  }
735 
736  res = amf_receive_frame(avctx, frame);
737  if (res == AMF_OK) {
738  got_frame = 1;
739  if (!ctx->dimensions_initialized)
740  amf_init_dimensions(avctx);
741  } else if (res == AMF_REPEAT)
742  // decoder has no output yet
743  res = AMF_OK;
744  else if (res == AMF_EOF) {
745  // drain is complete
746  ctx->drain = 0;
747  if(ctx->resolution_changed){
748  // re-initialze decoder
749  AMFVariantStruct size_var = {0};
750  AMFVariantStruct format_var = {0};
751  res = ctx->decoder->pVtbl->GetProperty(ctx->decoder, AMF_VIDEO_DECODER_CURRENT_SIZE, &size_var);
752  if (res != AMF_OK) {
753  return AVERROR(EINVAL);
754  }
755 
756  avctx->width = size_var.sizeValue.width;
757  avctx->height = size_var.sizeValue.height;
758  avctx->coded_width = size_var.sizeValue.width;
759  avctx->coded_height = size_var.sizeValue.height;
760  res = ctx->decoder->pVtbl->ReInit(ctx->decoder, avctx->width, avctx->height);
761  if (res != AMF_OK) {
762  av_log(avctx, AV_LOG_ERROR, "ReInit() returned %d\n", res);
763  return AVERROR(EINVAL);
764  }
765  res = ctx->decoder->pVtbl->GetProperty(ctx->decoder, AMF_VIDEO_DECODER_OUTPUT_FORMAT, &format_var);
766  if (res != AMF_OK) {
767  return AVERROR(EINVAL);
768  }
769  int ret = amf_reinit_frames_context(avctx, av_amf_to_av_format(format_var.int64Value), avctx->coded_width, avctx->coded_height);
770  if (ret < 0)
771  return ret;
772  } else
773  return AVERROR_EOF;
774  } else {
775  av_log(avctx, AV_LOG_ERROR, "Unknown result from QueryOutput %d\n", res);
776  }
777  return got_frame ? 0 : AVERROR(EAGAIN);
778 }
779 
780 static void amf_decode_flush(AVCodecContext *avctx)
781 {
782  AMFDecoderContext *ctx = avctx->priv_data;
783  ctx->decoder->pVtbl->Flush(ctx->decoder);
784 }
785 
786 #define OFFSET(x) offsetof(AMFDecoderContext, x)
787 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
788 
789 static const AVOption options[] = {
790  // Decoder mode
791  { "decoder_mode", "Decoder mode", OFFSET(decoder_mode), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AMF_VIDEO_DECODER_MODE_LOW_LATENCY, VD, "decoder_mode" },
792  { "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" },
793  { "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" },
794  { "low_latency", "DPB delay is 0", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_DECODER_MODE_LOW_LATENCY }, 0, 0, VD, "decoder_mode" },
795 
796  // Timestamp mode
797  { "timestamp_mode", "Timestamp mode", OFFSET(timestamp_mode), AV_OPT_TYPE_INT, { .i64 = AMF_TS_SORT }, -1, AMF_TS_DECODE, VD, "timestamp_mode" },
798  { "presentation", "Preserve timestamps from input to output", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_TS_PRESENTATION }, 0, 0, VD, "timestamp_mode" },
799  { "sort", "Resort PTS list", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_TS_SORT }, 0, 0, VD, "timestamp_mode" },
800  { "decode", "Decode order", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_TS_DECODE }, 0, 0, VD, "timestamp_mode" },
801 
802  // Reference frame management
803  { "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 },
804  { "dpb_size", "Minimum number of surfaces for reordering", OFFSET(dpb_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 32, VD, NULL },
805 
806  { "lowlatency", "Low latency", OFFSET(lowlatency), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VD, NULL },
807  { "smart_access_video", "Smart Access Video", OFFSET(smart_access_video), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VD, NULL },
808  { "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 },
809  { "copy_output", "Copy Output", OFFSET(copy_output), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VD, NULL },
810 
811  { NULL }
812 };
813 
814 static const AVClass amf_decode_class = {
815  .class_name = "amf",
816  .item_name = av_default_item_name,
817  .option = options,
818  .version = LIBAVUTIL_VERSION_INT,
819 };
820 
821 #define DEFINE_AMF_DECODER(x, X, bsf_name) \
822 const FFCodec ff_##x##_amf_decoder = { \
823  .p.name = #x "_amf", \
824  CODEC_LONG_NAME(#X " AMD AMF video decoder"), \
825  .priv_data_size = sizeof(AMFDecoderContext), \
826  .p.type = AVMEDIA_TYPE_VIDEO, \
827  .p.id = AV_CODEC_ID_##X, \
828  .init = amf_decode_init, \
829  FF_CODEC_RECEIVE_FRAME_CB(amf_decode_frame), \
830  .flush = amf_decode_flush, \
831  .close = amf_decode_close, \
832  .bsfs = bsf_name, \
833  .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \
834  .p.priv_class = &amf_decode_class, \
835  .hw_configs = amf_hw_configs, \
836  .p.wrapper_name = "amf", \
837  .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, \
838 }; \
839 
840 DEFINE_AMF_DECODER(h264, H264, "h264_mp4toannexb")
841 DEFINE_AMF_DECODER(hevc, HEVC, NULL)
842 DEFINE_AMF_DECODER(vp9, VP9, NULL)
843 DEFINE_AMF_DECODER(av1, AV1, NULL)
AVCOL_PRI_RESERVED
@ AVCOL_PRI_RESERVED
Definition: pixfmt.h:640
hwconfig.h
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:434
ff_decode_get_packet
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Called by decoders to get the next packet for decoding.
Definition: decode.c:254
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
name
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 name
Definition: writing_filters.txt:88
AVERROR
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
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:671
AVColorTransferCharacteristic
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:666
amf_amfsurface_to_avframe
static int amf_amfsurface_to_avframe(AVCodecContext *avctx, AMFSurface *surface, AVFrame *frame)
Definition: amfdec.c:506
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
amf_decode_frame
static int amf_decode_frame(AVCodecContext *avctx, struct AVFrame *frame)
Definition: amfdec.c:676
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:200
amf_decode_init
static int amf_decode_init(AVCodecContext *avctx)
Definition: amfdec.c:257
av_amf_attach_hdr_metadata
int av_amf_attach_hdr_metadata(AVFrame *frame, const AMFHDRMetadata *hdrmeta)
Definition: hwcontext_amf.c:262
AMF_VIDEO_DECODER_OUTPUT_FORMAT
#define AMF_VIDEO_DECODER_OUTPUT_FORMAT
Definition: amfdec.c:43
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:337
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:466
pixdesc.h
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:664
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:777
av_hwframe_ctx_alloc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:263
AVPacket::data
uint8_t * data
Definition: packet.h:603
amf_read_surface_color
static void amf_read_surface_color(AVCodecContext *avctx, AMFSurface *surface, AVFrame *frame)
Definition: amfdec.c:411
AVOption
AVOption.
Definition: opt.h:429
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:669
data
const char data[16]
Definition: mxf.c:149
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:539
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:621
AVColorPrimaries
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:636
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
AMF_RETURN_IF_FALSE
#define AMF_RETURN_IF_FALSE(avctx, exp, ret_value,...)
Error handling helper.
Definition: amfenc.h:169
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:220
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: packet.c:74
AV_PIX_FMT_AMF_SURFACE
@ AV_PIX_FMT_AMF_SURFACE
HW acceleration through AMF.
Definition: pixfmt.h:477
primaries
enum AVColorPrimaries primaries
Definition: mediacodec_wrapper.c:2612
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:452
copy_output
static int copy_output(SANMVideoContext *ctx, int sanm)
Definition: sanm.c:2682
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1579
av_amf_to_av_format
enum AVPixelFormat av_amf_to_av_format(enum AMF_SURFACE_FORMAT fmt)
Definition: hwcontext_amf.c:144
val
static double val(void *priv, double ch)
Definition: aeval.c:77
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:619
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:63
amf_to_av_colorspace
static enum AVColorSpace amf_to_av_colorspace(enum AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM profile)
Definition: amfdec.c:394
decode_bsf.h
amf_to_av_primaries
static enum AVColorPrimaries amf_to_av_primaries(enum AMF_COLOR_PRIMARIES_ENUM pri)
Definition: amfdec.c:350
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:657
amf_attach_hdr_metadata
static int amf_attach_hdr_metadata(AVCodecContext *avctx, AMFSurface *surface, AVFrame *frame)
Definition: amfdec.c:475
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
av_amf_get_color_profile
enum AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM av_amf_get_color_profile(enum AVColorRange color_range, enum AVColorSpace color_space)
Definition: hwcontext_amf.c:155
AVHWFramesContext::height
int height
Definition: hwcontext.h:220
AVCOL_PRI_RESERVED0
@ AVCOL_PRI_RESERVED0
Definition: pixfmt.h:637
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:527
amf_color_primaries_valid
static int amf_color_primaries_valid(enum AVColorPrimaries pri)
Definition: amfdec.c:338
AV_BUFFER_FLAG_READONLY
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Definition: buffer.h:114
AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX
@ AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX
The codec supports this format via the hw_frames_ctx interface.
Definition: codec.h:311
AVCOL_SPC_SMPTE170M
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
Definition: pixfmt.h:707
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
amf_update_buffer_properties
static AMF_RESULT amf_update_buffer_properties(AVCodecContext *avctx, AMFBuffer *buffer, const AVPacket *pkt)
Definition: amfdec.c:614
AV_HWDEVICE_TYPE_AMF
@ AV_HWDEVICE_TYPE_AMF
Definition: hwcontext.h:41
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
decode.h
AMF_GOTO_FAIL_IF_FALSE
#define AMF_GOTO_FAIL_IF_FALSE(avctx, exp, ret_value,...)
Definition: hwcontext_amf_internal.h:34
AVCodecHWConfig::pix_fmt
enum AVPixelFormat pix_fmt
For decoders, a hardware pixel format which that decoder may be able to decode to if suitable hardwar...
Definition: codec.h:339
hwcontext_amf.h
AVAMFDeviceContext::version
int64_t version
version of AMF runtime
Definition: hwcontext_amf.h:40
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:410
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
av_usleep
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:639
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
dpb_size
int dpb_size
Definition: h264_levels.c:111
if
if(ret)
Definition: filter_design.txt:179
DEFINE_AMF_DECODER
#define DEFINE_AMF_DECODER(x, X, bsf_name)
Definition: amfdec.c:821
ff_attach_decode_data
int ff_attach_decode_data(AVCodecContext *avctx, AVFrame *frame)
Definition: decode.c:1698
AMFDecoderContext
AMF decoder context.
Definition: amfdec.h:39
fail
#define fail
Definition: test.h:478
AVCOL_TRC_RESERVED0
@ AVCOL_TRC_RESERVED0
Definition: pixfmt.h:667
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:213
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:681
av_buffer_unref
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
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:284
amf_buffer_from_packet
static AMF_RESULT amf_buffer_from_packet(AVCodecContext *avctx, const AVPacket *pkt, AMFBuffer **buffer)
Definition: amfdec.c:628
AV_PIX_FMT_YUVJ420P
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:85
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
OFFSET
#define OFFSET(x)
Definition: amfdec.c:786
options
Definition: swscale.c:50
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3790
amf_init_dimensions
static void amf_init_dimensions(AVCodecContext *avctx)
Definition: amfdec.c:657
time.h
ff_decode_get_extradata
static void ff_decode_get_extradata(const AVCodecContext *avctx, const uint8_t **extradata, int *extradata_size)
Helper function for decoders that may use a BSF that changes extradata.
Definition: decode_bsf.h:32
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:743
av_buffer_create
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
AVCOL_TRC_SMPTE2084
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition: pixfmt.h:683
hwcontext_dxva2.h
amf_reinit_frames_context
static int amf_reinit_frames_context(AVCodecContext *avctx, int sw_format, int new_width, int new_height)
Definition: amfdec.c:243
AVPacket::size
int size
Definition: packet.h:604
AVCodecContext::extra_hw_frames
int extra_hw_frames
Video decoding only.
Definition: avcodec.h:1516
codec_internal.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
AVAMFDeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_amf.h:35
AVCodecHWConfigInternal
Definition: hwconfig.h:25
range
enum AVColorRange range
Definition: mediacodec_wrapper.c:2594
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:602
amf_color_trc_valid
static int amf_color_trc_valid(enum AVColorTransferCharacteristic trc)
Definition: amfdec.c:344
amf_to_av_trc
static enum AVColorTransferCharacteristic amf_to_av_trc(enum AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM trc)
Definition: amfdec.c:366
amfdec.h
amf_init_decoder
static int amf_init_decoder(AVCodecContext *avctx)
Definition: amfdec.c:73
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: packet.c:63
amf_to_av_range
static enum AVColorRange amf_to_av_range(enum AMF_COLOR_RANGE_ENUM range)
Definition: amfdec.c:382
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
FF_THREAD_FRAME
#define FF_THREAD_FRAME
Decode more than one frame at once.
Definition: avcodec.h:1590
AVCodec::id
enum AVCodecID id
Definition: codec.h:186
av_hwdevice_ctx_create_derived
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
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:596
AVCOL_SPC_BT2020_NCL
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
Definition: pixfmt.h:711
amf_init_frames_context
static int amf_init_frames_context(AVCodecContext *avctx, int sw_format, int new_width, int new_height)
Definition: amfdec.c:213
AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX
@ AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX
The codec supports this format via the hw_device_ctx interface.
Definition: codec.h:298
hw_device_ctx
static AVBufferRef * hw_device_ctx
Definition: hw_decode.c:45
VD
#define VD
Definition: amfdec.c:787
AVColorSpace
AVColorSpace
YUV colorspace type.
Definition: pixfmt.h:700
amf_legacy_driver_no_bitness_detect
static int amf_legacy_driver_no_bitness_detect(AVAMFDeviceContext *amf_device_ctx)
Definition: amfdec.c:64
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
AVCodecContext::hw_device_ctx
AVBufferRef * hw_device_ctx
A reference to the AVHWDeviceContext describing the device which will be used by a hardware encoder/d...
Definition: avcodec.h:1493
profile
int profile
Definition: mxfenc.c:2299
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:703
AVCodecContext::height
int height
Definition: avcodec.h:604
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:643
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:760
amf_decode_flush
static void amf_decode_flush(AVCodecContext *avctx)
Definition: amfdec.c:780
amf_hw_configs
static const AVCodecHWConfigInternal *const amf_hw_configs[]
Definition: amfdec.c:45
AVCodecContext::hw_frames_ctx
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition: avcodec.h:1471
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:118
ret
ret
Definition: filter_design.txt:187
AVHWDeviceContext::type
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition: hwcontext.h:75
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:96
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
frame
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
Definition: filter_design.txt:265
av_hwdevice_ctx_create
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
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
amf_decode_class
static const AVClass amf_decode_class
Definition: amfdec.c:814
ff_decode_frame_props
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
Set various frame properties from the codec context / packet data.
Definition: decode.c:1592
AVCodecContext
main external API structure.
Definition: avcodec.h:443
AVCodecContext::active_thread_type
int active_thread_type
Which multithreading methods are in use by the codec.
Definition: avcodec.h:1598
hwcontext_amf_internal.h
amf_decode_close
static int amf_decode_close(AVCodecContext *avctx)
Definition: amfdec.c:197
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
amf_receive_frame
static AMF_RESULT amf_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: amfdec.c:580
L
#define L(x)
Definition: vpx_arith.h:36
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:602
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:619
AVHWFramesContext::initial_pool_size
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:190
AVERROR_ENCODER_NOT_FOUND
#define AVERROR_ENCODER_NOT_FOUND
Encoder not found.
Definition: error.h:56
amf_get_property_buffer
static AMF_RESULT amf_get_property_buffer(AMFData *object, const wchar_t *name, AMFBuffer **val)
Definition: amfdec.c:454
AVCOL_TRC_RESERVED
@ AVCOL_TRC_RESERVED
Definition: pixfmt.h:670
AVPacket
This structure stores compressed data.
Definition: packet.h:580
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:470
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:604
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:650
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
AVCOL_SPC_BT709
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
Definition: pixfmt.h:702
AVColorRange
AVColorRange
Visual content value range.
Definition: pixfmt.h:742
AVCodecHWConfigInternal::public
AVCodecHWConfig public
This is the structure which will be returned to the user by avcodec_get_hw_config().
Definition: hwconfig.h:30
amf_free_amfsurface
static void amf_free_amfsurface(void *opaque, uint8_t *data)
Definition: amfdec.c:58
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
hwcontext_d3d11va.h
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3823
options
static const AVOption options[]
Definition: amfdec.c:789
w32dlfcn.h