FFmpeg
qsvdec.c
Go to the documentation of this file.
1 /*
2  * Intel MediaSDK QSV codec-independent code
3  *
4  * copyright (c) 2013 Luca Barbato
5  * copyright (c) 2015 Anton Khirnov <anton@khirnov.net>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include <stdint.h>
25 #include <string.h>
26 #include <sys/types.h>
27 
28 #include <mfx/mfxvideo.h>
29 
30 #include "libavutil/common.h"
31 #include "libavutil/fifo.h"
32 #include "libavutil/frame.h"
33 #include "libavutil/hwcontext.h"
35 #include "libavutil/mem.h"
36 #include "libavutil/log.h"
37 #include "libavutil/opt.h"
38 #include "libavutil/pixfmt.h"
39 #include "libavutil/time.h"
40 #include "libavutil/imgutils.h"
41 
42 #include "avcodec.h"
43 #include "internal.h"
44 #include "decode.h"
45 #include "hwconfig.h"
46 #include "qsv.h"
47 #include "qsv_internal.h"
48 
49 typedef struct QSVContext {
50  // the session used for decoding
51  mfxSession session;
52 
53  // the session we allocated internally, in case the caller did not provide
54  // one
56 
58 
59  /**
60  * a linked list of frames currently being used by QSV
61  */
63 
68 
70  uint32_t fourcc;
71  mfxFrameInfo frame_info;
73 
75 
76  // options set by the caller
78  int iopattern;
79  int gpu_copy;
80 
81  char *load_plugins;
82 
83  mfxExtBuffer **ext_buffers;
85 } QSVContext;
86 
87 static const AVCodecHWConfigInternal *const qsv_hw_configs[] = {
88  &(const AVCodecHWConfigInternal) {
89  .public = {
93  .device_type = AV_HWDEVICE_TYPE_QSV,
94  },
95  .hwaccel = NULL,
96  },
97  NULL
98 };
99 
101  AVBufferPool *pool)
102 {
103  int ret = 0;
104 
106 
107  frame->width = avctx->width;
108  frame->height = avctx->height;
109 
110  switch (avctx->pix_fmt) {
111  case AV_PIX_FMT_NV12:
112  frame->linesize[0] = FFALIGN(avctx->width, 128);
113  break;
114  case AV_PIX_FMT_P010:
115  frame->linesize[0] = 2 * FFALIGN(avctx->width, 128);
116  break;
117  default:
118  av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format.\n");
119  return AVERROR(EINVAL);
120  }
121 
122  frame->linesize[1] = frame->linesize[0];
123  frame->buf[0] = av_buffer_pool_get(pool);
124  if (!frame->buf[0])
125  return AVERROR(ENOMEM);
126 
127  frame->data[0] = frame->buf[0]->data;
128  frame->data[1] = frame->data[0] +
129  frame->linesize[0] * FFALIGN(avctx->height, 64);
130 
132  if (ret < 0)
133  return ret;
134 
135  return 0;
136 }
137 
138 static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session,
139  AVBufferRef *hw_frames_ref, AVBufferRef *hw_device_ref)
140 {
141  int ret;
142 
143  if (q->gpu_copy == MFX_GPUCOPY_ON &&
144  !(q->iopattern & MFX_IOPATTERN_OUT_SYSTEM_MEMORY)) {
145  av_log(avctx, AV_LOG_WARNING, "GPU-accelerated memory copy "
146  "only works in system memory mode.\n");
147  q->gpu_copy = MFX_GPUCOPY_OFF;
148  }
149  if (session) {
150  q->session = session;
151  } else if (hw_frames_ref) {
152  if (q->internal_qs.session) {
153  MFXClose(q->internal_qs.session);
154  q->internal_qs.session = NULL;
155  }
157 
158  q->frames_ctx.hw_frames_ctx = av_buffer_ref(hw_frames_ref);
159  if (!q->frames_ctx.hw_frames_ctx)
160  return AVERROR(ENOMEM);
161 
163  &q->frames_ctx, q->load_plugins,
164  q->iopattern == MFX_IOPATTERN_OUT_OPAQUE_MEMORY,
165  q->gpu_copy);
166  if (ret < 0) {
168  return ret;
169  }
170 
171  q->session = q->internal_qs.session;
172  } else if (hw_device_ref) {
173  if (q->internal_qs.session) {
174  MFXClose(q->internal_qs.session);
175  q->internal_qs.session = NULL;
176  }
177 
179  hw_device_ref, q->load_plugins, q->gpu_copy);
180  if (ret < 0)
181  return ret;
182 
183  q->session = q->internal_qs.session;
184  } else {
185  if (!q->internal_qs.session) {
187  q->load_plugins, q->gpu_copy);
188  if (ret < 0)
189  return ret;
190  }
191 
192  q->session = q->internal_qs.session;
193  }
194 
195  /* make sure the decoder is uninitialized */
196  MFXVideoDECODE_Close(q->session);
197 
198  return 0;
199 }
200 
201 static inline unsigned int qsv_fifo_item_size(void)
202 {
203  return sizeof(mfxSyncPoint*) + sizeof(QSVFrame*);
204 }
205 
206 static inline unsigned int qsv_fifo_size(const AVFifoBuffer* fifo)
207 {
208  return av_fifo_size(fifo) / qsv_fifo_item_size();
209 }
210 
211 static int qsv_decode_preinit(AVCodecContext *avctx, QSVContext *q, enum AVPixelFormat pix_fmt, mfxVideoParam *param)
212 {
213  mfxSession session = NULL;
214  int iopattern = 0;
215  int ret;
216  enum AVPixelFormat pix_fmts[3] = {
217  AV_PIX_FMT_QSV, /* opaque format in case of video memory output */
218  pix_fmt, /* system memory format obtained from bitstream parser */
219  AV_PIX_FMT_NONE };
220 
221  ret = ff_get_format(avctx, pix_fmts);
222  if (ret < 0) {
223  q->orig_pix_fmt = avctx->pix_fmt = AV_PIX_FMT_NONE;
224  return ret;
225  }
226 
227  if (!q->async_fifo) {
229  if (!q->async_fifo)
230  return AVERROR(ENOMEM);
231  }
232 
233  if (avctx->pix_fmt == AV_PIX_FMT_QSV && avctx->hwaccel_context) {
234  AVQSVContext *user_ctx = avctx->hwaccel_context;
235  session = user_ctx->session;
236  iopattern = user_ctx->iopattern;
237  q->ext_buffers = user_ctx->ext_buffers;
238  q->nb_ext_buffers = user_ctx->nb_ext_buffers;
239  }
240 
241  if (avctx->hw_frames_ctx) {
242  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
243  AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
244 
245  if (!iopattern) {
246  if (frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)
247  iopattern = MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
248  else if (frames_hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)
249  iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
250  }
251  }
252 
253  if (!iopattern)
254  iopattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
255  q->iopattern = iopattern;
256 
257  ff_qsv_print_iopattern(avctx, q->iopattern, "Decoder");
258 
259  ret = qsv_init_session(avctx, q, session, avctx->hw_frames_ctx, avctx->hw_device_ctx);
260  if (ret < 0) {
261  av_log(avctx, AV_LOG_ERROR, "Error initializing an MFX session\n");
262  return ret;
263  }
264 
265  param->IOPattern = q->iopattern;
266  param->AsyncDepth = q->async_depth;
267  param->ExtParam = q->ext_buffers;
268  param->NumExtParam = q->nb_ext_buffers;
269 
270  return 0;
271  }
272 
273 static int qsv_decode_init_context(AVCodecContext *avctx, QSVContext *q, mfxVideoParam *param)
274 {
275  int ret;
276 
277  avctx->width = param->mfx.FrameInfo.CropW;
278  avctx->height = param->mfx.FrameInfo.CropH;
279  avctx->coded_width = param->mfx.FrameInfo.Width;
280  avctx->coded_height = param->mfx.FrameInfo.Height;
281  avctx->level = param->mfx.CodecLevel;
282  avctx->profile = param->mfx.CodecProfile;
283  avctx->field_order = ff_qsv_map_picstruct(param->mfx.FrameInfo.PicStruct);
284  avctx->pix_fmt = ff_qsv_map_fourcc(param->mfx.FrameInfo.FourCC);
285 
286  ret = MFXVideoDECODE_Init(q->session, param);
287  if (ret < 0)
288  return ff_qsv_print_error(avctx, ret,
289  "Error initializing the MFX video decoder");
290 
291  q->frame_info = param->mfx.FrameInfo;
292 
293  if (!avctx->hw_frames_ctx)
295  FFALIGN(avctx->width, 128), FFALIGN(avctx->height, 64), 1), av_buffer_allocz);
296  return 0;
297 }
298 
300  const AVPacket *avpkt, enum AVPixelFormat pix_fmt,
301  mfxVideoParam *param)
302 {
303  int ret;
304 
305  mfxBitstream bs = { 0 };
306 
307  if (avpkt->size) {
308  bs.Data = avpkt->data;
309  bs.DataLength = avpkt->size;
310  bs.MaxLength = bs.DataLength;
311  bs.TimeStamp = avpkt->pts;
312  if (avctx->field_order == AV_FIELD_PROGRESSIVE)
313  bs.DataFlag |= MFX_BITSTREAM_COMPLETE_FRAME;
314  } else
315  return AVERROR_INVALIDDATA;
316 
317 
318  if(!q->session) {
319  ret = qsv_decode_preinit(avctx, q, pix_fmt, param);
320  if (ret < 0)
321  return ret;
322  }
323 
325  if (ret < 0)
326  return ret;
327 
328  param->mfx.CodecId = ret;
329  ret = MFXVideoDECODE_DecodeHeader(q->session, &bs, param);
330  if (MFX_ERR_MORE_DATA == ret) {
331  return AVERROR(EAGAIN);
332  }
333  if (ret < 0)
334  return ff_qsv_print_error(avctx, ret,
335  "Error decoding stream header");
336 
337  return 0;
338 }
339 
341 {
342  int ret;
343 
344  if (q->pool)
345  ret = qsv_get_continuous_buffer(avctx, frame->frame, q->pool);
346  else
347  ret = ff_get_buffer(avctx, frame->frame, AV_GET_BUFFER_FLAG_REF);
348 
349  if (ret < 0)
350  return ret;
351 
352  if (frame->frame->format == AV_PIX_FMT_QSV) {
353  frame->surface = *(mfxFrameSurface1*)frame->frame->data[3];
354  } else {
355  frame->surface.Info = q->frame_info;
356 
357  frame->surface.Data.PitchLow = frame->frame->linesize[0];
358  frame->surface.Data.Y = frame->frame->data[0];
359  frame->surface.Data.UV = frame->frame->data[1];
360  }
361 
362  if (q->frames_ctx.mids) {
364  if (ret < 0)
365  return ret;
366 
367  frame->surface.Data.MemId = &q->frames_ctx.mids[ret];
368  }
369  frame->surface.Data.ExtParam = &frame->ext_param;
370  frame->surface.Data.NumExtParam = 1;
371  frame->ext_param = (mfxExtBuffer*)&frame->dec_info;
372  frame->dec_info.Header.BufferId = MFX_EXTBUFF_DECODED_FRAME_INFO;
373  frame->dec_info.Header.BufferSz = sizeof(frame->dec_info);
374 
375  frame->used = 1;
376 
377  return 0;
378 }
379 
381 {
382  QSVFrame *cur = q->work_frames;
383  while (cur) {
384  if (cur->used && !cur->surface.Data.Locked && !cur->queued) {
385  cur->used = 0;
386  av_frame_unref(cur->frame);
387  }
388  cur = cur->next;
389  }
390 }
391 
392 static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf)
393 {
394  QSVFrame *frame, **last;
395  int ret;
396 
398 
399  frame = q->work_frames;
400  last = &q->work_frames;
401  while (frame) {
402  if (!frame->used) {
403  ret = alloc_frame(avctx, q, frame);
404  if (ret < 0)
405  return ret;
406  *surf = &frame->surface;
407  return 0;
408  }
409 
410  last = &frame->next;
411  frame = frame->next;
412  }
413 
414  frame = av_mallocz(sizeof(*frame));
415  if (!frame)
416  return AVERROR(ENOMEM);
417  frame->frame = av_frame_alloc();
418  if (!frame->frame) {
419  av_freep(&frame);
420  return AVERROR(ENOMEM);
421  }
422  *last = frame;
423 
424  ret = alloc_frame(avctx, q, frame);
425  if (ret < 0)
426  return ret;
427 
428  *surf = &frame->surface;
429 
430  return 0;
431 }
432 
433 static QSVFrame *find_frame(QSVContext *q, mfxFrameSurface1 *surf)
434 {
435  QSVFrame *cur = q->work_frames;
436  while (cur) {
437  if (surf == &cur->surface)
438  return cur;
439  cur = cur->next;
440  }
441  return NULL;
442 }
443 
444 static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
445  AVFrame *frame, int *got_frame,
446  const AVPacket *avpkt)
447 {
448  QSVFrame *out_frame;
449  mfxFrameSurface1 *insurf;
450  mfxFrameSurface1 *outsurf;
451  mfxSyncPoint *sync;
452  mfxBitstream bs = { { { 0 } } };
453  int ret;
454 
455  if (avpkt->size) {
456  bs.Data = avpkt->data;
457  bs.DataLength = avpkt->size;
458  bs.MaxLength = bs.DataLength;
459  bs.TimeStamp = avpkt->pts;
460  if (avctx->field_order == AV_FIELD_PROGRESSIVE)
461  bs.DataFlag |= MFX_BITSTREAM_COMPLETE_FRAME;
462  }
463 
464  sync = av_mallocz(sizeof(*sync));
465  if (!sync) {
466  av_freep(&sync);
467  return AVERROR(ENOMEM);
468  }
469 
470  do {
471  ret = get_surface(avctx, q, &insurf);
472  if (ret < 0) {
473  av_freep(&sync);
474  return ret;
475  }
476 
477  ret = MFXVideoDECODE_DecodeFrameAsync(q->session, avpkt->size ? &bs : NULL,
478  insurf, &outsurf, sync);
479  if (ret == MFX_WRN_DEVICE_BUSY)
480  av_usleep(500);
481 
482  } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_ERR_MORE_SURFACE);
483 
484  if (ret != MFX_ERR_NONE &&
485  ret != MFX_ERR_MORE_DATA &&
486  ret != MFX_WRN_VIDEO_PARAM_CHANGED &&
487  ret != MFX_ERR_MORE_SURFACE) {
488  av_freep(&sync);
489  return ff_qsv_print_error(avctx, ret,
490  "Error during QSV decoding.");
491  }
492 
493  /* make sure we do not enter an infinite loop if the SDK
494  * did not consume any data and did not return anything */
495  if (!*sync && !bs.DataOffset) {
496  bs.DataOffset = avpkt->size;
497  ++q->zero_consume_run;
498  if (q->zero_consume_run > 1)
499  ff_qsv_print_warning(avctx, ret, "A decode call did not consume any data");
500  } else if (!*sync && bs.DataOffset) {
501  ++q->buffered_count;
502  } else {
503  q->zero_consume_run = 0;
504  }
505 
506  if (*sync) {
507  QSVFrame *out_frame = find_frame(q, outsurf);
508 
509  if (!out_frame) {
510  av_log(avctx, AV_LOG_ERROR,
511  "The returned surface does not correspond to any frame\n");
512  av_freep(&sync);
513  return AVERROR_BUG;
514  }
515 
516  out_frame->queued = 1;
517  av_fifo_generic_write(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
518  av_fifo_generic_write(q->async_fifo, &sync, sizeof(sync), NULL);
519  } else {
520  av_freep(&sync);
521  }
522 
523  if ((qsv_fifo_size(q->async_fifo) >= q->async_depth) ||
524  (!avpkt->size && av_fifo_size(q->async_fifo))) {
525  AVFrame *src_frame;
526 
527  av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
528  av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
529  out_frame->queued = 0;
530 
531  if (avctx->pix_fmt != AV_PIX_FMT_QSV) {
532  do {
533  ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000);
534  } while (ret == MFX_WRN_IN_EXECUTION);
535  }
536 
537  av_freep(&sync);
538 
539  src_frame = out_frame->frame;
540 
541  ret = av_frame_ref(frame, src_frame);
542  if (ret < 0)
543  return ret;
544 
545  outsurf = &out_frame->surface;
546 
547 #if FF_API_PKT_PTS
549  frame->pkt_pts = outsurf->Data.TimeStamp;
551 #endif
552  frame->pts = outsurf->Data.TimeStamp;
553 
554  frame->repeat_pict =
555  outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
556  outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
557  outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
558  frame->top_field_first =
559  outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
560  frame->interlaced_frame =
561  !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
562  frame->pict_type = ff_qsv_map_pictype(out_frame->dec_info.FrameType);
563  //Key frame is IDR frame is only suitable for H264. For HEVC, IRAPs are key frames.
564  if (avctx->codec_id == AV_CODEC_ID_H264)
565  frame->key_frame = !!(out_frame->dec_info.FrameType & MFX_FRAMETYPE_IDR);
566 
567  /* update the surface properties */
568  if (avctx->pix_fmt == AV_PIX_FMT_QSV)
569  ((mfxFrameSurface1*)frame->data[3])->Info = outsurf->Info;
570 
571  *got_frame = 1;
572  }
573 
574  return bs.DataOffset;
575 }
576 
578 {
579  QSVFrame *cur = q->work_frames;
580 
581  if (q->session)
582  MFXVideoDECODE_Close(q->session);
583 
584  while (q->async_fifo && av_fifo_size(q->async_fifo)) {
585  QSVFrame *out_frame;
586  mfxSyncPoint *sync;
587 
588  av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
589  av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
590 
591  av_freep(&sync);
592  }
593 
594  while (cur) {
595  q->work_frames = cur->next;
596  av_frame_free(&cur->frame);
597  av_freep(&cur);
598  cur = q->work_frames;
599  }
600 
602  q->async_fifo = NULL;
603 
605 
609 }
610 
612  AVFrame *frame, int *got_frame, const AVPacket *pkt)
613 {
614  int ret;
615  mfxVideoParam param = { 0 };
617 
618  if (!pkt->size)
619  return qsv_decode(avctx, q, frame, got_frame, pkt);
620 
621  /* TODO: flush delayed frames on reinit */
622 
623  // sw_pix_fmt, coded_width/height should be set for ff_get_format(),
624  // assume sw_pix_fmt is NV12 and coded_width/height to be 1280x720,
625  // the assumption may be not corret but will be updated after header decoded if not true.
626  if (q->orig_pix_fmt != AV_PIX_FMT_NONE)
627  pix_fmt = q->orig_pix_fmt;
628  if (!avctx->coded_width)
629  avctx->coded_width = 1280;
630  if (!avctx->coded_height)
631  avctx->coded_height = 720;
632 
633  ret = qsv_decode_header(avctx, q, pkt, pix_fmt, &param);
634 
635  if (ret >= 0 && (q->orig_pix_fmt != ff_qsv_map_fourcc(param.mfx.FrameInfo.FourCC) ||
636  avctx->coded_width != param.mfx.FrameInfo.Width ||
637  avctx->coded_height != param.mfx.FrameInfo.Height)) {
638  AVPacket zero_pkt = {0};
639 
640  if (q->buffered_count) {
641  q->reinit_flag = 1;
642  /* decode zero-size pkt to flush the buffered pkt before reinit */
643  q->buffered_count--;
644  return qsv_decode(avctx, q, frame, got_frame, &zero_pkt);
645  }
646  q->reinit_flag = 0;
647 
648  q->orig_pix_fmt = avctx->pix_fmt = pix_fmt = ff_qsv_map_fourcc(param.mfx.FrameInfo.FourCC);
649 
650  avctx->coded_width = param.mfx.FrameInfo.Width;
651  avctx->coded_height = param.mfx.FrameInfo.Height;
652 
653  ret = qsv_decode_preinit(avctx, q, pix_fmt, &param);
654  if (ret < 0)
655  goto reinit_fail;
656  q->initialized = 0;
657  }
658 
659  if (!q->initialized) {
660  ret = qsv_decode_init_context(avctx, q, &param);
661  if (ret < 0)
662  goto reinit_fail;
663  q->initialized = 1;
664  }
665 
666  return qsv_decode(avctx, q, frame, got_frame, pkt);
667 
668 reinit_fail:
669  q->orig_pix_fmt = avctx->pix_fmt = AV_PIX_FMT_NONE;
670  return ret;
671 }
672 
677 };
678 
679 typedef struct QSVDecContext {
680  AVClass *class;
682 
684 
686 
688 } QSVDecContext;
689 
691 {
692  AVPacket pkt;
693  while (av_fifo_size(s->packet_fifo) >= sizeof(pkt)) {
694  av_fifo_generic_read(s->packet_fifo, &pkt, sizeof(pkt), NULL);
696  }
697 
698  av_packet_unref(&s->buffer_pkt);
699 }
700 
702 {
703  QSVDecContext *s = avctx->priv_data;
704 
705  av_freep(&s->qsv.load_plugins);
706 
708 
710 
711  av_fifo_free(s->packet_fifo);
712 
713  return 0;
714 }
715 
717 {
718  QSVDecContext *s = avctx->priv_data;
719  int ret;
720  const char *uid = NULL;
721 
722  if (avctx->codec_id == AV_CODEC_ID_VP8) {
723  uid = "f622394d8d87452f878c51f2fc9b4131";
724  } else if (avctx->codec_id == AV_CODEC_ID_VP9) {
725  uid = "a922394d8d87452f878c51f2fc9b4131";
726  }
727  else if (avctx->codec_id == AV_CODEC_ID_HEVC && s->load_plugin != LOAD_PLUGIN_NONE) {
728  static const char * const uid_hevcdec_sw = "15dd936825ad475ea34e35f3f54217a6";
729  static const char * const uid_hevcdec_hw = "33a61c0b4c27454ca8d85dde757c6f8e";
730 
731  if (s->qsv.load_plugins[0]) {
732  av_log(avctx, AV_LOG_WARNING,
733  "load_plugins is not empty, but load_plugin is not set to 'none'."
734  "The load_plugin value will be ignored.\n");
735  } else {
736  if (s->load_plugin == LOAD_PLUGIN_HEVC_SW)
737  uid = uid_hevcdec_sw;
738  else
739  uid = uid_hevcdec_hw;
740  }
741  }
742  if (uid) {
743  av_freep(&s->qsv.load_plugins);
744  s->qsv.load_plugins = av_strdup(uid);
745  if (!s->qsv.load_plugins)
746  return AVERROR(ENOMEM);
747  }
748 
749  s->qsv.orig_pix_fmt = AV_PIX_FMT_NV12;
750  s->packet_fifo = av_fifo_alloc(sizeof(AVPacket));
751  if (!s->packet_fifo) {
752  ret = AVERROR(ENOMEM);
753  goto fail;
754  }
755 
756  return 0;
757 fail:
758  qsv_decode_close(avctx);
759  return ret;
760 }
761 
762 static int qsv_decode_frame(AVCodecContext *avctx, void *data,
763  int *got_frame, AVPacket *avpkt)
764 {
765  QSVDecContext *s = avctx->priv_data;
766  AVFrame *frame = data;
767  int ret;
768 
769  /* buffer the input packet */
770  if (avpkt->size) {
771  AVPacket input_ref;
772 
773  if (av_fifo_space(s->packet_fifo) < sizeof(input_ref)) {
774  ret = av_fifo_realloc2(s->packet_fifo,
775  av_fifo_size(s->packet_fifo) + sizeof(input_ref));
776  if (ret < 0)
777  return ret;
778  }
779 
780  ret = av_packet_ref(&input_ref, avpkt);
781  if (ret < 0)
782  return ret;
783  av_fifo_generic_write(s->packet_fifo, &input_ref, sizeof(input_ref), NULL);
784  }
785 
786  /* process buffered data */
787  while (!*got_frame) {
788  /* prepare the input data */
789  if (s->buffer_pkt.size <= 0) {
790  /* no more data */
791  if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket))
792  return avpkt->size ? avpkt->size : qsv_process_data(avctx, &s->qsv, frame, got_frame, avpkt);
793  /* in progress of reinit, no read from fifo and keep the buffer_pkt */
794  if (!s->qsv.reinit_flag) {
795  av_packet_unref(&s->buffer_pkt);
796  av_fifo_generic_read(s->packet_fifo, &s->buffer_pkt, sizeof(s->buffer_pkt), NULL);
797  }
798  }
799 
800  ret = qsv_process_data(avctx, &s->qsv, frame, got_frame, &s->buffer_pkt);
801  if (ret < 0){
802  /* Drop buffer_pkt when failed to decode the packet. Otherwise,
803  the decoder will keep decoding the failure packet. */
804  av_packet_unref(&s->buffer_pkt);
805  return ret;
806  }
807  if (s->qsv.reinit_flag)
808  continue;
809 
810  s->buffer_pkt.size -= ret;
811  s->buffer_pkt.data += ret;
812  }
813 
814  return avpkt->size;
815 }
816 
817 static void qsv_decode_flush(AVCodecContext *avctx)
818 {
819  QSVDecContext *s = avctx->priv_data;
820 
822 
823  s->qsv.orig_pix_fmt = AV_PIX_FMT_NONE;
824  s->qsv.initialized = 0;
825 }
826 
827 #define OFFSET(x) offsetof(QSVDecContext, x)
828 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
829 
830 #define DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, opt) \
831 static const AVClass x##_qsv_class = { \
832  .class_name = #x "_qsv", \
833  .item_name = av_default_item_name, \
834  .option = opt, \
835  .version = LIBAVUTIL_VERSION_INT, \
836 }; \
837 AVCodec ff_##x##_qsv_decoder = { \
838  .name = #x "_qsv", \
839  .long_name = NULL_IF_CONFIG_SMALL(#X " video (Intel Quick Sync Video acceleration)"), \
840  .priv_data_size = sizeof(QSVDecContext), \
841  .type = AVMEDIA_TYPE_VIDEO, \
842  .id = AV_CODEC_ID_##X, \
843  .init = qsv_decode_init, \
844  .decode = qsv_decode_frame, \
845  .flush = qsv_decode_flush, \
846  .close = qsv_decode_close, \
847  .bsfs = bsf_name, \
848  .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID, \
849  .priv_class = &x##_qsv_class, \
850  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, \
851  AV_PIX_FMT_P010, \
852  AV_PIX_FMT_QSV, \
853  AV_PIX_FMT_NONE }, \
854  .hw_configs = qsv_hw_configs, \
855  .wrapper_name = "qsv", \
856 }; \
857 
858 #define DEFINE_QSV_DECODER(x, X, bsf_name) DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, options)
859 
860 #if CONFIG_HEVC_QSV_DECODER
861 static const AVOption hevc_options[] = {
862  { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VD },
863 
864  { "load_plugin", "A user plugin to load in an internal session", OFFSET(load_plugin), AV_OPT_TYPE_INT, { .i64 = LOAD_PLUGIN_HEVC_HW }, LOAD_PLUGIN_NONE, LOAD_PLUGIN_HEVC_HW, VD, "load_plugin" },
865  { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_NONE }, 0, 0, VD, "load_plugin" },
866  { "hevc_sw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_SW }, 0, 0, VD, "load_plugin" },
867  { "hevc_hw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_HW }, 0, 0, VD, "load_plugin" },
868 
869  { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to load in an internal session",
870  OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VD },
871 
872  { "gpu_copy", "A GPU-accelerated copy between video and system memory", OFFSET(qsv.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_DEFAULT }, MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, VD, "gpu_copy"},
873  { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_DEFAULT }, 0, 0, VD, "gpu_copy"},
874  { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON }, 0, 0, VD, "gpu_copy"},
875  { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_OFF }, 0, 0, VD, "gpu_copy"},
876  { NULL },
877 };
878 DEFINE_QSV_DECODER_WITH_OPTION(hevc, HEVC, "hevc_mp4toannexb", hevc_options)
879 #endif
880 
881 static const AVOption options[] = {
882  { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VD },
883 
884  { "gpu_copy", "A GPU-accelerated copy between video and system memory", OFFSET(qsv.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_DEFAULT }, MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, VD, "gpu_copy"},
885  { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_DEFAULT }, 0, 0, VD, "gpu_copy"},
886  { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON }, 0, 0, VD, "gpu_copy"},
887  { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_OFF }, 0, 0, VD, "gpu_copy"},
888  { NULL },
889 };
890 
891 #if CONFIG_H264_QSV_DECODER
892 DEFINE_QSV_DECODER(h264, H264, "h264_mp4toannexb")
893 #endif
894 
895 #if CONFIG_MPEG2_QSV_DECODER
896 DEFINE_QSV_DECODER(mpeg2, MPEG2VIDEO, NULL)
897 #endif
898 
899 #if CONFIG_VC1_QSV_DECODER
900 DEFINE_QSV_DECODER(vc1, VC1, NULL)
901 #endif
902 
903 #if CONFIG_MJPEG_QSV_DECODER
904 DEFINE_QSV_DECODER(mjpeg, MJPEG, NULL)
905 #endif
906 
907 #if CONFIG_VP8_QSV_DECODER
908 DEFINE_QSV_DECODER(vp8, VP8, NULL)
909 #endif
910 
911 #if CONFIG_VP9_QSV_DECODER
912 DEFINE_QSV_DECODER(vp9, VP9, NULL)
913 #endif
914 
915 #if CONFIG_AV1_QSV_DECODER
916 DEFINE_QSV_DECODER(av1, AV1, NULL)
917 #endif
hwconfig.h
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:634
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:84
AVCodecContext::hwaccel_context
void * hwaccel_context
Hardware accelerator context.
Definition: avcodec.h:1692
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
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
uid
UID uid
Definition: mxfenc.c:2205
opt.h
qsv_process_data
static int qsv_process_data(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, const AVPacket *pkt)
Definition: qsvdec.c:611
av_fifo_generic_write
int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int(*func)(void *, void *, int))
Feed data from a user-supplied callback to an AVFifoBuffer.
Definition: fifo.c:122
ff_get_format
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
Definition: decode.c:1317
QSVFramesContext::hw_frames_ctx
AVBufferRef * hw_frames_ctx
Definition: qsv_internal.h:94
AVBufferPool
The buffer pool.
Definition: buffer_internal.h:78
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:92
av_fifo_free
void av_fifo_free(AVFifoBuffer *f)
Free an AVFifoBuffer.
Definition: fifo.c:55
qsv_fifo_size
static unsigned int qsv_fifo_size(const AVFifoBuffer *fifo)
Definition: qsvdec.c:206
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:204
ff_qsv_close_internal_session
int ff_qsv_close_internal_session(QSVSession *qs)
Definition: qsv.c:813
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:324
ff_qsv_map_pictype
enum AVPictureType ff_qsv_map_pictype(int mfx_pic_type)
Definition: qsv.c:270
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:369
AVCodecContext::field_order
enum AVFieldOrder field_order
Field order.
Definition: avcodec.h:1193
AVOption
AVOption.
Definition: opt.h:248
ff_qsv_find_surface_idx
int ff_qsv_find_surface_idx(QSVFramesContext *ctx, QSVFrame *frame)
Definition: qsv.c:241
LOAD_PLUGIN_NONE
@ LOAD_PLUGIN_NONE
Definition: qsvdec.c:674
data
const char data[16]
Definition: mxf.c:142
av_buffer_allocz
AVBufferRef * av_buffer_allocz(buffer_size_t size)
Same as av_buffer_alloc(), except the returned buffer will be initialized to zero.
Definition: buffer.c:83
QSVContext::work_frames
QSVFrame * work_frames
a linked list of frames currently being used by QSV
Definition: qsvdec.c:62
LOAD_PLUGIN_HEVC_HW
@ LOAD_PLUGIN_HEVC_HW
Definition: qsvdec.c:676
av_fifo_generic_read
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void(*func)(void *, void *, int))
Feed data from an AVFifoBuffer to a user-supplied callback.
Definition: fifo.c:213
QSVFrame::frame
AVFrame * frame
Definition: qsv_internal.h:73
AVQSVContext::iopattern
int iopattern
The IO pattern to use.
Definition: qsv.h:46
QSVFrame::used
int used
Definition: qsv_internal.h:80
ff_qsv_init_session_device
int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession, AVBufferRef *device_ref, const char *load_plugins, int gpu_copy)
Definition: qsv.c:689
AVFifoBuffer
Definition: fifo.h:31
av_buffer_pool_init
AVBufferPool * av_buffer_pool_init(buffer_size_t size, AVBufferRef *(*alloc)(buffer_size_t size))
Allocate and initialize a buffer pool.
Definition: buffer.c:266
QSVDecContext::packet_fifo
AVFifoBuffer * packet_fifo
Definition: qsvdec.c:685
fifo.h
DEFINE_QSV_DECODER
#define DEFINE_QSV_DECODER(x, X, bsf_name)
Definition: qsvdec.c:858
fail
#define fail()
Definition: checkasm.h:133
QSVDecContext::qsv
QSVContext qsv
Definition: qsvdec.c:681
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:724
LOAD_PLUGIN_HEVC_SW
@ LOAD_PLUGIN_HEVC_SW
Definition: qsvdec.c:675
options
static const AVOption options[]
Definition: qsvdec.c:881
DEFINE_QSV_DECODER_WITH_OPTION
#define DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, opt)
Definition: qsvdec.c:830
QSVContext
Definition: qsvdec.c:49
qsv_internal.h
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:191
find_frame
static QSVFrame * find_frame(QSVContext *q, mfxFrameSurface1 *surf)
Definition: qsvdec.c:433
qsv_decode_header
static int qsv_decode_header(AVCodecContext *avctx, QSVContext *q, const AVPacket *avpkt, enum AVPixelFormat pix_fmt, mfxVideoParam *param)
Definition: qsvdec.c:299
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
ff_qsv_print_warning
int ff_qsv_print_warning(void *log_ctx, mfxStatus err, const char *warning_string)
Definition: qsv.c:186
av_fifo_space
int av_fifo_space(const AVFifoBuffer *f)
Return the amount of space in bytes in the AVFifoBuffer, that is the amount of data you can write int...
Definition: fifo.c:82
ASYNC_DEPTH_DEFAULT
#define ASYNC_DEPTH_DEFAULT
Definition: qsv_internal.h:51
av_cold
#define av_cold
Definition: attributes.h:90
QSVDecContext
Definition: qsvdec.c:679
QSVContext::iopattern
int iopattern
Definition: qsvdec.c:78
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:429
av_buffer_pool_get
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
Definition: buffer.c:373
qsv_decode_init
static av_cold int qsv_decode_init(AVCodecContext *avctx)
Definition: qsvdec.c:716
s
#define s(width, name)
Definition: cbs_vp9.c:257
hevc_options
static const AVOption hevc_options[]
Definition: videotoolboxenc.c:2678
QSVContext::reinit_flag
int reinit_flag
Definition: qsvdec.c:67
qsv_fifo_item_size
static unsigned int qsv_fifo_item_size(void)
Definition: qsvdec.c:201
QSVContext::frames_ctx
QSVFramesContext frames_ctx
Definition: qsvdec.c:57
QSVContext::internal_qs
QSVSession internal_qs
Definition: qsvdec.c:55
qsv_decode_frame
static int qsv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: qsvdec.c:762
AV_GET_BUFFER_FLAG_REF
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
Definition: avcodec.h:514
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:217
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:303
decode.h
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:457
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demuxing_decoding.c:40
av_usleep
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
av_fifo_realloc2
int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
Resize an AVFifoBuffer.
Definition: fifo.c:87
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:76
AVQSVContext::nb_ext_buffers
int nb_ext_buffers
Definition: qsv.h:52
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:546
if
if(ret)
Definition: filter_design.txt:179
ff_qsv_init_session_frames
int ff_qsv_init_session_frames(AVCodecContext *avctx, mfxSession *psession, QSVFramesContext *qsv_frames_ctx, const char *load_plugins, int opaque, int gpu_copy)
Definition: qsv.c:766
QSVFrame
Definition: qsv_internal.h:72
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
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:125
qsv.h
ff_qsv_print_iopattern
int ff_qsv_print_iopattern(void *log_ctx, int mfx_iopattern, const char *extra_string)
Definition: qsv.c:104
av_buffer_pool_uninit
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
Definition: buffer.c:308
QSVContext::nb_ext_buffers
int nb_ext_buffers
Definition: qsvdec.c:84
QSVFrame::surface
mfxFrameSurface1 surface
Definition: qsv_internal.h:74
time.h
QSVFramesContext::mids_buf
AVBufferRef * mids_buf
Definition: qsv_internal.h:101
QSVContext::async_fifo
AVFifoBuffer * async_fifo
Definition: qsvdec.c:64
AV_PIX_FMT_QSV
@ AV_PIX_FMT_QSV
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
Definition: pixfmt.h:222
av_packet_ref
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: avpacket.c:641
QSVContext::load_plugins
char * load_plugins
Definition: qsvdec.c:81
AVCodecContext::level
int level
level
Definition: avcodec.h:1984
QSVContext::initialized
int initialized
Definition: qsvdec.c:74
qsv_clear_buffers
static void qsv_clear_buffers(QSVDecContext *s)
Definition: qsvdec.c:690
QSVContext::fourcc
uint32_t fourcc
Definition: qsvdec.c:70
QSVContext::ext_buffers
mfxExtBuffer ** ext_buffers
Definition: qsvdec.c:83
qsv_decode_close_qsvcontext
static void qsv_decode_close_qsvcontext(QSVContext *q)
Definition: qsvdec.c:577
QSVContext::frame_info
mfxFrameInfo frame_info
Definition: qsvdec.c:71
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1893
AVPacket::size
int size
Definition: packet.h:370
QSVContext::buffered_count
int buffered_count
Definition: qsvdec.c:66
av_frame_ref
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:444
AVQSVContext::session
mfxSession session
If non-NULL, the session to use for encoding or decoding.
Definition: qsv.h:41
LoadPlugin
LoadPlugin
Definition: qsvdec.c:673
alloc_frame
static int alloc_frame(AVCodecContext *avctx, QSVContext *q, QSVFrame *frame)
Definition: qsvdec.c:340
qsv_decode
static int qsv_decode(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, const AVPacket *avpkt)
Definition: qsvdec.c:444
AVCodecHWConfigInternal
Definition: hwconfig.h:29
qsv_decode_close
static av_cold int qsv_decode_close(AVCodecContext *avctx)
Definition: qsvdec.c:701
frame.h
AVQSVContext::ext_buffers
mfxExtBuffer ** ext_buffers
Extra buffers to pass to encoder or decoder initialization.
Definition: qsv.h:51
av_image_get_buffer_size
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align)
Return the size in bytes of the amount of data required to store an image with the given parameters.
Definition: imgutils.c:466
get_surface
static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf)
Definition: qsvdec.c:392
QSVFramesContext::mids
QSVMid * mids
Definition: qsv_internal.h:102
hwcontext_qsv.h
QSVContext::pool
AVBufferPool * pool
Definition: qsvdec.c:72
log.h
ff_qsv_map_picstruct
enum AVFieldOrder ff_qsv_map_picstruct(int mfx_pic_struct)
Definition: qsv.c:252
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:362
AV_CODEC_HW_CONFIG_METHOD_AD_HOC
@ AV_CODEC_HW_CONFIG_METHOD_AD_HOC
The codec supports this format by some ad-hoc method.
Definition: codec.h:445
QSVDecContext::buffer_pkt
AVPacket buffer_pkt
Definition: qsvdec.c:687
common.h
QSVContext::session
mfxSession session
Definition: qsvdec.c:51
qsv_decode_preinit
static int qsv_decode_preinit(AVCodecContext *avctx, QSVContext *q, enum AVPixelFormat pix_fmt, mfxVideoParam *param)
Definition: qsvdec.c:211
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:223
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:554
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:237
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:2270
AVCodecContext::height
int height
Definition: avcodec.h:709
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:746
QSVDecContext::load_plugin
int load_plugin
Definition: qsvdec.c:683
OFFSET
#define OFFSET(x)
Definition: qsvdec.c:827
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:2218
qsv_init_session
static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session, AVBufferRef *hw_frames_ref, AVBufferRef *hw_device_ref)
Definition: qsvdec.c:138
avcodec.h
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
ret
ret
Definition: filter_design.txt:187
pixfmt.h
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:89
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:264
QSVFrame::queued
int queued
Definition: qsv_internal.h:79
QSVContext::async_depth
int async_depth
Definition: qsvdec.c:77
QSVSession
Definition: qsv_internal.h:85
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:162
ff_qsv_codec_id_to_mfx
int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id)
Definition: qsv.c:43
QSVContext::zero_consume_run
int zero_consume_run
Definition: qsvdec.c:65
AV_HWDEVICE_TYPE_QSV
@ AV_HWDEVICE_TYPE_QSV
Definition: hwcontext.h:33
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:1722
AVCodecContext
main external API structure.
Definition: avcodec.h:536
QSVContext::orig_pix_fmt
enum AVPixelFormat orig_pix_fmt
Definition: qsvdec.c:69
qsv_decode_init_context
static int qsv_decode_init_context(AVCodecContext *avctx, QSVContext *q, mfxVideoParam *param)
Definition: qsvdec.c:273
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1858
AVQSVContext
This struct is used for communicating QSV parameters between libavcodec and the caller.
Definition: qsv.h:36
QSVSession::session
mfxSession session
Definition: qsv_internal.h:86
ff_qsv_map_fourcc
enum AVPixelFormat ff_qsv_map_fourcc(uint32_t fourcc)
Definition: qsv.c:196
av_buffer_ref
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:93
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:448
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:83
qsv_get_continuous_buffer
static int qsv_get_continuous_buffer(AVCodecContext *avctx, AVFrame *frame, AVBufferPool *pool)
Definition: qsvdec.c:100
VD
#define VD
Definition: qsvdec.c:828
AVQSVFramesContext
This struct is allocated as AVHWFramesContext.hwctx.
Definition: hwcontext_qsv.h:42
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:724
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:253
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:84
QSVFrame::dec_info
mfxExtDecodedFrameInfo dec_info
Definition: qsv_internal.h:76
ff_attach_decode_data
int ff_attach_decode_data(AVFrame *frame)
Definition: decode.c:1869
av_fifo_size
int av_fifo_size(const AVFifoBuffer *f)
Return the amount of data in bytes in the AVFifoBuffer, that is the amount of data you can read from ...
Definition: fifo.c:77
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: codec_par.h:38
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:48
QSVFramesContext
Definition: qsv_internal.h:93
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:563
AVPacket
This structure stores compressed data.
Definition: packet.h:346
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
qsv_clear_unused_frames
static void qsv_clear_unused_frames(QSVContext *q)
Definition: qsvdec.c:380
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:709
av_fifo_alloc
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
Definition: fifo.c:43
imgutils.h
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:189
hwcontext.h
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
QSVContext::gpu_copy
int gpu_copy
Definition: qsvdec.c:79
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
AVCodecHWConfigInternal::public
AVCodecHWConfig public
This is the structure which will be returned to the user by avcodec_get_hw_config().
Definition: hwconfig.h:34
QSVFrame::next
struct QSVFrame * next
Definition: qsv_internal.h:82
ff_qsv_print_error
int ff_qsv_print_error(void *log_ctx, mfxStatus err, const char *error_string)
Definition: qsv.c:176
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
ff_qsv_init_internal_session
int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, const char *load_plugins, int gpu_copy)
Definition: qsv.c:383
qsv_decode_flush
static void qsv_decode_flush(AVCodecContext *avctx)
Definition: qsvdec.c:817
qsv_hw_configs
static const AVCodecHWConfigInternal *const qsv_hw_configs[]
Definition: qsvdec.c:87