FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 <string.h>
25 #include <sys/types.h>
26 
27 #include <mfx/mfxvideo.h>
28 
29 #include "libavutil/common.h"
30 #include "libavutil/mem.h"
31 #include "libavutil/log.h"
32 #include "libavutil/pixfmt.h"
33 #include "libavutil/time.h"
34 
35 #include "avcodec.h"
36 #include "internal.h"
37 #include "qsv.h"
38 #include "qsv_internal.h"
39 #include "qsvdec.h"
40 
42 {
43  switch (format) {
44  case AV_PIX_FMT_YUV420P:
46  return AV_PIX_FMT_NV12;
47  default:
48  return AVERROR(ENOSYS);
49  }
50 }
51 
52 static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session)
53 {
54  if (!session) {
55  if (!q->internal_qs.session) {
56  int ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
57  q->load_plugins);
58  if (ret < 0)
59  return ret;
60  }
61 
62  q->session = q->internal_qs.session;
63  } else {
64  q->session = session;
65  }
66 
67  return 0;
68 }
69 
70 static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt)
71 {
72  mfxSession session = NULL;
73  mfxVideoParam param = { { 0 } };
74  mfxBitstream bs = { { { 0 } } };
75  int ret;
79 
80  ret = ff_get_format(avctx, pix_fmts);
81  if (ret < 0)
82  return ret;
83 
84  avctx->pix_fmt = ret;
85 
86  q->iopattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
87  if (avctx->hwaccel_context) {
88  AVQSVContext *qsv = avctx->hwaccel_context;
89 
90  session = qsv->session;
91  q->iopattern = qsv->iopattern;
92  q->ext_buffers = qsv->ext_buffers;
94  }
95 
96  ret = qsv_init_session(avctx, q, session);
97  if (ret < 0) {
98  av_log(avctx, AV_LOG_ERROR, "Error initializing an MFX session\n");
99  return ret;
100  }
101 
102  if (avpkt->size) {
103  bs.Data = avpkt->data;
104  bs.DataLength = avpkt->size;
105  bs.MaxLength = bs.DataLength;
106  bs.TimeStamp = avpkt->pts;
107  } else
108  return AVERROR_INVALIDDATA;
109 
110  ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
111  if (ret < 0) {
112  av_log(avctx, AV_LOG_ERROR, "Unsupported codec_id %08x\n", avctx->codec_id);
113  return ret;
114  }
115 
116  param.mfx.CodecId = ret;
117 
118  ret = MFXVideoDECODE_DecodeHeader(q->session, &bs, &param);
119  if (MFX_ERR_MORE_DATA==ret) {
120  /* this code means that header not found so we return packet size to skip
121  a current packet
122  */
123  return avpkt->size;
124  } else if (ret < 0) {
125  av_log(avctx, AV_LOG_ERROR, "Decode header error %d\n", ret);
126  return ff_qsv_error(ret);
127  }
128  param.IOPattern = q->iopattern;
129  param.AsyncDepth = q->async_depth;
130  param.ExtParam = q->ext_buffers;
131  param.NumExtParam = q->nb_ext_buffers;
132  param.mfx.FrameInfo.BitDepthLuma = 8;
133  param.mfx.FrameInfo.BitDepthChroma = 8;
134 
135  ret = MFXVideoDECODE_Init(q->session, &param);
136  if (ret < 0) {
137  if (MFX_ERR_INVALID_VIDEO_PARAM==ret) {
138  av_log(avctx, AV_LOG_ERROR,
139  "Error initializing the MFX video decoder, unsupported video\n");
140  } else {
141  av_log(avctx, AV_LOG_ERROR,
142  "Error initializing the MFX video decoder %d\n", ret);
143  }
144  return ff_qsv_error(ret);
145  }
146 
147  avctx->profile = param.mfx.CodecProfile;
148  avctx->level = param.mfx.CodecLevel;
149  avctx->coded_width = param.mfx.FrameInfo.Width;
150  avctx->coded_height = param.mfx.FrameInfo.Height;
151  avctx->width = param.mfx.FrameInfo.CropW - param.mfx.FrameInfo.CropX;
152  avctx->height = param.mfx.FrameInfo.CropH - param.mfx.FrameInfo.CropY;
153 
154  /* maximum decoder latency should be not exceed max DPB size for h.264 and
155  HEVC which is 16 for both cases.
156  So weare pre-allocating fifo big enough for 17 elements:
157  */
158  if (!q->async_fifo) {
159  q->async_fifo = av_fifo_alloc((1 + 16) *
160  (sizeof(mfxSyncPoint) + sizeof(QSVFrame*)));
161  if (!q->async_fifo)
162  return AVERROR(ENOMEM);
163  }
164 
165  if (!q->input_fifo) {
166  q->input_fifo = av_fifo_alloc(1024*16);
167  if (!q->input_fifo)
168  return AVERROR(ENOMEM);
169  }
170 
171  if (!q->pkt_fifo) {
172  q->pkt_fifo = av_fifo_alloc( sizeof(AVPacket) * (1 + 16) );
173  if (!q->pkt_fifo)
174  return AVERROR(ENOMEM);
175  }
176  q->engine_ready = 1;
177 
178  return 0;
179 }
180 
182 {
183  int ret;
184 
185  ret = ff_get_buffer(avctx, frame->frame, AV_GET_BUFFER_FLAG_REF);
186  if (ret < 0)
187  return ret;
188 
189  if (frame->frame->format == AV_PIX_FMT_QSV) {
190  frame->surface = (mfxFrameSurface1*)frame->frame->data[3];
191  } else {
192  frame->surface_internal.Info.BitDepthLuma = 8;
193  frame->surface_internal.Info.BitDepthChroma = 8;
194  frame->surface_internal.Info.FourCC = MFX_FOURCC_NV12;
195  frame->surface_internal.Info.Width = avctx->coded_width;
196  frame->surface_internal.Info.Height = avctx->coded_height;
197  frame->surface_internal.Info.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
198 
199  frame->surface_internal.Data.PitchLow = frame->frame->linesize[0];
200  frame->surface_internal.Data.Y = frame->frame->data[0];
201  frame->surface_internal.Data.UV = frame->frame->data[1];
202 
203  frame->surface = &frame->surface_internal;
204  }
205 
206  return 0;
207 }
208 
210 {
211  QSVFrame *cur = q->work_frames;
212  while (cur) {
213  if (cur->surface && !cur->surface->Data.Locked && !cur->queued) {
214  cur->surface = NULL;
215  av_frame_unref(cur->frame);
216  }
217  cur = cur->next;
218  }
219 }
220 
221 static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf)
222 {
223  QSVFrame *frame, **last;
224  int ret;
225 
227 
228  frame = q->work_frames;
229  last = &q->work_frames;
230  while (frame) {
231  if (!frame->surface) {
232  ret = alloc_frame(avctx, frame);
233  if (ret < 0)
234  return ret;
235  *surf = frame->surface;
236  return 0;
237  }
238 
239  last = &frame->next;
240  frame = frame->next;
241  }
242 
243  frame = av_mallocz(sizeof(*frame));
244  if (!frame)
245  return AVERROR(ENOMEM);
246  frame->frame = av_frame_alloc();
247  if (!frame->frame) {
248  av_freep(&frame);
249  return AVERROR(ENOMEM);
250  }
251  *last = frame;
252 
253  ret = alloc_frame(avctx, frame);
254  if (ret < 0)
255  return ret;
256 
257  *surf = frame->surface;
258 
259  return 0;
260 }
261 
262 static QSVFrame *find_frame(QSVContext *q, mfxFrameSurface1 *surf)
263 {
264  QSVFrame *cur = q->work_frames;
265  while (cur) {
266  if (surf == cur->surface)
267  return cur;
268  cur = cur->next;
269  }
270  return NULL;
271 }
272 
273 /* This function uses for 'smart' releasing of consumed data
274  from the input bitstream fifo.
275  Since the input fifo mapped to mfxBitstream which does not understand
276  a wrapping of data over fifo end, we should also to relocate a possible
277  data rest to fifo begin. If rest of data is absent then we just reset fifo's
278  pointers to initial positions.
279  NOTE the case when fifo does contain unconsumed data is rare and typical
280  amount of such data is 1..4 bytes.
281 */
282 static void qsv_fifo_relocate(AVFifoBuffer *f, int bytes_to_free)
283 {
284  int data_size;
285  int data_rest = 0;
286 
287  av_fifo_drain(f, bytes_to_free);
288 
289  data_size = av_fifo_size(f);
290  if (data_size > 0) {
291  if (f->buffer!=f->rptr) {
292  if ( (f->end - f->rptr) < data_size) {
293  data_rest = data_size - (f->end - f->rptr);
294  data_size-=data_rest;
295  memmove(f->buffer+data_size, f->buffer, data_rest);
296  }
297  memmove(f->buffer, f->rptr, data_size);
298  data_size+= data_rest;
299  }
300  }
301  f->rptr = f->buffer;
302  f->wptr = f->buffer + data_size;
303  f->wndx = data_size;
304  f->rndx = 0;
305 }
306 
307 
308 static void close_decoder(QSVContext *q)
309 {
310  QSVFrame *cur;
311 
312  if (q->session)
313  MFXVideoDECODE_Close(q->session);
314 
315  cur = q->work_frames;
316  while (cur) {
317  q->work_frames = cur->next;
318  av_frame_free(&cur->frame);
319  av_freep(&cur);
320  cur = q->work_frames;
321  }
322 
323  q->engine_ready = 0;
324  q->reinit_pending = 0;
325 }
326 
328  AVFrame *frame, int *got_frame,
329  AVPacket *avpkt)
330 {
331  QSVFrame *out_frame;
332  mfxFrameSurface1 *insurf;
333  mfxFrameSurface1 *outsurf;
334  mfxSyncPoint sync;
335  mfxBitstream bs = { { { 0 } } };
336  int ret;
337  int n_out_frames;
338  int buffered = 0;
339  int flush = !avpkt->size || q->reinit_pending;
340 
341  if (!q->engine_ready) {
342  ret = qsv_decode_init(avctx, q, avpkt);
343  if (ret)
344  return ret;
345  }
346 
347  if (!flush) {
348  if (av_fifo_size(q->input_fifo)) {
349  /* we have got rest of previous packet into buffer */
350  if (av_fifo_space(q->input_fifo) < avpkt->size) {
351  ret = av_fifo_grow(q->input_fifo, avpkt->size);
352  if (ret < 0)
353  return ret;
354  }
355  av_fifo_generic_write(q->input_fifo, avpkt->data, avpkt->size, NULL);
356  bs.Data = q->input_fifo->rptr;
357  bs.DataLength = av_fifo_size(q->input_fifo);
358  buffered = 1;
359  } else {
360  bs.Data = avpkt->data;
361  bs.DataLength = avpkt->size;
362  }
363  bs.MaxLength = bs.DataLength;
364  bs.TimeStamp = avpkt->pts;
365  }
366 
367  while (1) {
368  ret = get_surface(avctx, q, &insurf);
369  if (ret < 0)
370  return ret;
371  do {
372  ret = MFXVideoDECODE_DecodeFrameAsync(q->session, flush ? NULL : &bs,
373  insurf, &outsurf, &sync);
374  if (ret != MFX_WRN_DEVICE_BUSY)
375  break;
376  av_usleep(500);
377  } while (1);
378 
379  if (MFX_WRN_VIDEO_PARAM_CHANGED==ret) {
380  /* TODO: handle here minor sequence header changing */
381  } else if (MFX_ERR_INCOMPATIBLE_VIDEO_PARAM==ret) {
383  flush = q->reinit_pending = 1;
384  continue;
385  }
386 
387  if (sync) {
388  QSVFrame *out_frame = find_frame(q, outsurf);
389 
390  if (!out_frame) {
391  av_log(avctx, AV_LOG_ERROR,
392  "The returned surface does not correspond to any frame\n");
393  return AVERROR_BUG;
394  }
395 
396  out_frame->queued = 1;
397  av_fifo_generic_write(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
398  av_fifo_generic_write(q->async_fifo, &sync, sizeof(sync), NULL);
399 
400  continue;
401  }
402  if (MFX_ERR_MORE_SURFACE != ret && ret < 0)
403  break;
404  }
405 
406  /* make sure we do not enter an infinite loop if the SDK
407  * did not consume any data and did not return anything */
408  if (!sync && !bs.DataOffset && !flush) {
409  av_log(avctx, AV_LOG_WARNING, "A decode call did not consume any data\n");
410  bs.DataOffset = avpkt->size;
411  }
412 
413  if (buffered) {
414  qsv_fifo_relocate(q->input_fifo, bs.DataOffset);
415  } else if (bs.DataOffset!=avpkt->size) {
416  /* some data of packet was not consumed. store it to local buffer */
417  av_fifo_generic_write(q->input_fifo, avpkt->data+bs.DataOffset,
418  avpkt->size - bs.DataOffset, NULL);
419  }
420 
421  if (MFX_ERR_MORE_DATA!=ret && ret < 0) {
422  av_log(avctx, AV_LOG_ERROR, "Error %d during QSV decoding.\n", ret);
423  return ff_qsv_error(ret);
424  }
425  n_out_frames = av_fifo_size(q->async_fifo) / (sizeof(out_frame)+sizeof(sync));
426 
427  if (n_out_frames > q->async_depth || (flush && n_out_frames) ) {
428  AVFrame *src_frame;
429 
430  av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL);
431  av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
432  out_frame->queued = 0;
433 
434  do {
435  ret = MFXVideoCORE_SyncOperation(q->session, sync, 1000);
436  } while (ret == MFX_WRN_IN_EXECUTION);
437 
438  src_frame = out_frame->frame;
439 
440  ret = av_frame_ref(frame, src_frame);
441  if (ret < 0)
442  return ret;
443 
444  outsurf = out_frame->surface;
445 
446 #if FF_API_PKT_PTS
448  frame->pkt_pts = outsurf->Data.TimeStamp;
450 #endif
451  frame->pts = outsurf->Data.TimeStamp;
452 
453  frame->repeat_pict =
454  outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
455  outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
456  outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
457  frame->top_field_first =
458  outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
459  frame->interlaced_frame =
460  !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
461 
462  *got_frame = 1;
463  }
464 
465  return avpkt->size;
466 }
467 /*
468  This function inserts a packet at fifo front.
469 */
471 {
472  int fifo_size = av_fifo_size(q->pkt_fifo);
473  if (!fifo_size) {
474  /* easy case fifo is empty */
475  av_fifo_generic_write(q->pkt_fifo, avpkt, sizeof(*avpkt), NULL);
476  } else {
477  /* realloc necessary */
478  AVPacket pkt;
479  AVFifoBuffer *fifo = av_fifo_alloc(fifo_size+av_fifo_space(q->pkt_fifo));
480 
481  av_fifo_generic_write(fifo, avpkt, sizeof(*avpkt), NULL);
482 
483  while (av_fifo_size(q->pkt_fifo)) {
484  av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
485  av_fifo_generic_write(fifo, &pkt, sizeof(pkt), NULL);
486  }
488  q->pkt_fifo = fifo;
489  }
490 }
492  AVFrame *frame, int *got_frame,
493  AVPacket *avpkt)
494 {
495  AVPacket pkt_ref = { 0 };
496  int ret = 0;
497 
498  if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
499  /* we already have got some buffered packets. so add new to tail */
500  ret = av_packet_ref(&pkt_ref, avpkt);
501  if (ret < 0)
502  return ret;
503  av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
504  }
505  if (q->reinit_pending) {
506  ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
507 
508  if (!*got_frame) {
509  /* Flushing complete, no more frames */
510  close_decoder(q);
511  //return ff_qsv_decode(avctx, q, frame, got_frame, avpkt);
512  }
513  }
514  if (!q->reinit_pending) {
515  if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
516  /* process buffered packets */
517  while (!*got_frame && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
518  av_fifo_generic_read(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
519  ret = do_qsv_decode(avctx, q, frame, got_frame, &pkt_ref);
520  if (q->reinit_pending) {
521  /*
522  A rare case: new reinit pending when buffering existing.
523  We should to return the pkt_ref back to same place of fifo
524  */
525  qsv_packet_push_front(q, &pkt_ref);
526  } else {
527  av_packet_unref(&pkt_ref);
528  }
529  }
530  } else {
531  /* general decoding */
532  ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
533  if (q->reinit_pending) {
534  ret = av_packet_ref(&pkt_ref, avpkt);
535  if (ret < 0)
536  return ret;
537  av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
538  }
539  }
540  }
541 
542  return ret;
543 }
544 /*
545  This function resets decoder and corresponded buffers before seek operation
546 */
548 {
549  QSVFrame *cur;
550  AVPacket pkt;
551  int ret = 0;
552  mfxVideoParam param = { { 0 } };
553 
554  if (q->reinit_pending) {
555  close_decoder(q);
556  } else if (q->engine_ready) {
557  ret = MFXVideoDECODE_GetVideoParam(q->session, &param);
558  if (ret < 0) {
559  av_log(avctx, AV_LOG_ERROR, "MFX decode get param error %d\n", ret);
560  }
561 
562  ret = MFXVideoDECODE_Reset(q->session, &param);
563  if (ret < 0) {
564  av_log(avctx, AV_LOG_ERROR, "MFX decode reset error %d\n", ret);
565  }
566 
567  /* Free all frames*/
568  cur = q->work_frames;
569  while (cur) {
570  q->work_frames = cur->next;
571  av_frame_free(&cur->frame);
572  av_freep(&cur);
573  cur = q->work_frames;
574  }
575  }
576 
577  /* Reset output surfaces */
578  if (q->async_fifo)
580 
581  /* Reset input packets fifo */
582  while (q->pkt_fifo && av_fifo_size(q->pkt_fifo)) {
583  av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
584  av_packet_unref(&pkt);
585  }
586 
587  /* Reset input bitstream fifo */
588  if (q->input_fifo)
590 }
591 
593 {
594  close_decoder(q);
595 
596  q->session = NULL;
597 
599 
601  q->async_fifo = NULL;
602 
604  q->input_fifo = NULL;
605 
607  q->pkt_fifo = NULL;
608 
609  return 0;
610 }
static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt)
Definition: qsvdec.c:70
#define NULL
Definition: coverity.c:32
int av_fifo_grow(AVFifoBuffer *f, unsigned int size)
Enlarge an AVFifoBuffer.
Definition: fifo.c:107
int iopattern
Definition: qsvdec.h:71
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition: qsvdec.c:491
int reinit_pending
Definition: qsvdec.h:67
AVFifoBuffer * pkt_fifo
Definition: qsvdec.h:57
AVFifoBuffer * input_fifo
Definition: qsvdec.h:52
This structure describes decoded (raw) audio or video data.
Definition: frame.h:184
static void flush(AVCodecContext *avctx)
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:1878
uint8_t * wptr
Definition: fifo.h:33
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
Memory handling functions.
int repeat_pict
When decoding, this signals how much the picture must be delayed.
Definition: frame.h:317
int size
Definition: avcodec.h:1602
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1904
mfxFrameSurface1 * surface
Definition: qsv_internal.h:58
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:252
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:76
static AVPacket pkt
int profile
profile
Definition: avcodec.h:3181
QSVSession internal_qs
Definition: qsvdec.h:44
uint32_t rndx
Definition: fifo.h:34
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
void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
Definition: qsvdec.c:547
static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition: qsvdec.c:327
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:145
void * hwaccel_context
Hardware accelerator context.
Definition: avcodec.h:3008
mfxExtBuffer * ext_buffers[1]
Definition: ffmpeg_qsv.c:41
int ff_qsv_decode_close(QSVContext *q)
Definition: qsvdec.c:592
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:383
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:268
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
static AVFrame * frame
int queued
Definition: qsv_internal.h:63
uint8_t * data
Definition: avcodec.h:1601
void av_fifo_free(AVFifoBuffer *f)
Free an AVFifoBuffer.
Definition: fifo.c:55
int interlaced_frame
The content of the picture is interlaced.
Definition: frame.h:322
#define av_log(a,...)
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: avpacket.c:576
static QSVFrame * find_frame(QSVContext *q, mfxFrameSurface1 *surf)
Definition: qsvdec.c:262
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
struct QSVFrame * next
Definition: qsv_internal.h:65
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:158
static void qsv_packet_push_front(QSVContext *q, AVPacket *avpkt)
Definition: qsvdec.c:470
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
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:90
int iopattern
The IO pattern to use.
Definition: qsv.h:46
int ff_qsv_close_internal_session(QSVSession *qs)
Definition: qsv.c:254
int nb_ext_buffers
Definition: qsv.h:52
AVFrame * frame
Definition: qsv_internal.h:57
static void qsv_fifo_relocate(AVFifoBuffer *f, int bytes_to_free)
Definition: qsvdec.c:282
static void close_decoder(QSVContext *q)
Definition: qsvdec.c:308
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:74
uint8_t * end
Definition: fifo.h:33
int width
picture width / height.
Definition: avcodec.h:1863
uint8_t * rptr
Definition: fifo.h:33
int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id)
Definition: qsv.c:33
int engine_ready
Definition: qsvdec.h:61
int level
level
Definition: avcodec.h:3279
mfxFrameSurface1 surface_internal
Definition: qsv_internal.h:61
int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, const char *load_plugins)
Initialize a MSDK session.
Definition: qsv.c:171
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
Definition: utils.c:1111
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:248
Libavcodec external API header.
enum AVCodecID codec_id
Definition: avcodec.h:1693
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
mfxExtBuffer ** ext_buffers
Extra buffers to pass to encoder or decoder initialization.
Definition: qsv.h:51
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:215
main external API structure.
Definition: avcodec.h:1676
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:567
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: utils.c:947
static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf)
Definition: qsvdec.c:221
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
int coded_height
Definition: avcodec.h:1878
static const char * format
Definition: movenc.c:47
uint8_t * buffer
Definition: fifo.h:32
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
Definition: pixfmt.h:236
char * load_plugins
Definition: qsvdec.h:73
static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session)
Definition: qsvdec.c:52
This struct is used for communicating QSV parameters between libavcodec and the caller.
Definition: qsv.h:36
static void qsv_clear_unused_frames(QSVContext *q)
Definition: qsvdec.c:209
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:262
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:493
uint32_t wndx
Definition: fifo.h:34
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:198
attribute_deprecated int64_t pkt_pts
PTS copied from the AVPacket that was decoded to produce this frame.
Definition: frame.h:276
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:62
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:80
common internal api header.
common internal and external API header
int ff_qsv_map_pixfmt(enum AVPixelFormat format)
Definition: qsvdec.c:41
int ff_qsv_error(int mfx_err)
Convert a libmfx error code into a ffmpeg error code.
Definition: qsv.c:54
pixel format definitions
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:81
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
Definition: fifo.c:43
int top_field_first
If the content is interlaced, is top field displayed first.
Definition: frame.h:327
mfxSession session
Definition: ffmpeg_qsv.c:32
AVFifoBuffer * async_fifo
Definition: qsvdec.h:51
static int alloc_frame(AVCodecContext *avctx, QSVFrame *frame)
Definition: qsvdec.c:181
#define av_freep(p)
int async_depth
Definition: qsvdec.h:70
void av_fifo_reset(AVFifoBuffer *f)
Reset the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied...
Definition: fifo.c:71
void av_fifo_drain(AVFifoBuffer *f, int size)
Discard data from the FIFO.
Definition: fifo.c:233
QSVFrame * work_frames
a linked list of frames currently being used by QSV
Definition: qsvdec.h:49
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
This structure stores compressed data.
Definition: avcodec.h:1578
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
Definition: avcodec.h:1354
mfxSession session
If non-NULL, the session to use for encoding or decoding.
Definition: qsv.h:41
mfxSession session
Definition: qsv_internal.h:69
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1594
int nb_ext_buffers
Definition: qsvdec.h:76