FFmpeg
rkmppdec.c
Go to the documentation of this file.
1 /*
2  * RockChip MPP Video Decoder
3  * Copyright (c) 2017 Lionel CHAZALLON
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <drm_fourcc.h>
23 #include <pthread.h>
24 #include <rockchip/mpp_buffer.h>
25 #include <rockchip/rk_mpi.h>
26 #include <time.h>
27 #include <unistd.h>
28 
29 #include "avcodec.h"
30 #include "decode.h"
31 #include "hwaccel.h"
32 #include "internal.h"
33 #include "libavutil/buffer.h"
34 #include "libavutil/common.h"
35 #include "libavutil/frame.h"
36 #include "libavutil/hwcontext.h"
38 #include "libavutil/imgutils.h"
39 #include "libavutil/log.h"
40 
41 #define RECEIVE_FRAME_TIMEOUT 100
42 #define FRAMEGROUP_MAX_FRAMES 16
43 #define INPUT_MAX_PACKETS 4
44 
45 typedef struct {
46  MppCtx ctx;
47  MppApi *mpi;
48  MppBufferGroup frame_group;
49 
52 
55 } RKMPPDecoder;
56 
57 typedef struct {
61 
62 typedef struct {
63  MppFrame frame;
66 
67 static MppCodingType rkmpp_get_codingtype(AVCodecContext *avctx)
68 {
69  switch (avctx->codec_id) {
70  case AV_CODEC_ID_H264: return MPP_VIDEO_CodingAVC;
71  case AV_CODEC_ID_HEVC: return MPP_VIDEO_CodingHEVC;
72  case AV_CODEC_ID_VP8: return MPP_VIDEO_CodingVP8;
73  case AV_CODEC_ID_VP9: return MPP_VIDEO_CodingVP9;
74  default: return MPP_VIDEO_CodingUnused;
75  }
76 }
77 
78 static uint32_t rkmpp_get_frameformat(MppFrameFormat mppformat)
79 {
80  switch (mppformat) {
81  case MPP_FMT_YUV420SP: return DRM_FORMAT_NV12;
82 #ifdef DRM_FORMAT_NV12_10
83  case MPP_FMT_YUV420SP_10BIT: return DRM_FORMAT_NV12_10;
84 #endif
85  default: return 0;
86  }
87 }
88 
89 static int rkmpp_write_data(AVCodecContext *avctx, uint8_t *buffer, int size, int64_t pts)
90 {
91  RKMPPDecodeContext *rk_context = avctx->priv_data;
93  int ret;
94  MppPacket packet;
95 
96  // create the MPP packet
97  ret = mpp_packet_init(&packet, buffer, size);
98  if (ret != MPP_OK) {
99  av_log(avctx, AV_LOG_ERROR, "Failed to init MPP packet (code = %d)\n", ret);
100  return AVERROR_UNKNOWN;
101  }
102 
103  mpp_packet_set_pts(packet, pts);
104 
105  if (!buffer)
106  mpp_packet_set_eos(packet);
107 
108  ret = decoder->mpi->decode_put_packet(decoder->ctx, packet);
109  if (ret != MPP_OK) {
110  if (ret == MPP_ERR_BUFFER_FULL) {
111  av_log(avctx, AV_LOG_DEBUG, "Buffer full writing %d bytes to decoder\n", size);
112  ret = AVERROR(EAGAIN);
113  } else
115  }
116  else
117  av_log(avctx, AV_LOG_DEBUG, "Wrote %d bytes to decoder\n", size);
118 
119  mpp_packet_deinit(&packet);
120 
121  return ret;
122 }
123 
125 {
126  RKMPPDecodeContext *rk_context = avctx->priv_data;
127  av_buffer_unref(&rk_context->decoder_ref);
128  return 0;
129 }
130 
131 static void rkmpp_release_decoder(void *opaque, uint8_t *data)
132 {
133  RKMPPDecoder *decoder = (RKMPPDecoder *)data;
134 
135  if (decoder->mpi) {
136  decoder->mpi->reset(decoder->ctx);
137  mpp_destroy(decoder->ctx);
138  decoder->ctx = NULL;
139  }
140 
141  if (decoder->frame_group) {
142  mpp_buffer_group_put(decoder->frame_group);
143  decoder->frame_group = NULL;
144  }
145 
146  av_buffer_unref(&decoder->frames_ref);
147  av_buffer_unref(&decoder->device_ref);
148 
149  av_free(decoder);
150 }
151 
153 {
154  RKMPPDecodeContext *rk_context = avctx->priv_data;
156  MppCodingType codectype = MPP_VIDEO_CodingUnused;
157  int ret;
158  RK_S64 paramS64;
159  RK_S32 paramS32;
160 
161  avctx->pix_fmt = AV_PIX_FMT_DRM_PRIME;
162 
163  // create a decoder and a ref to it
164  decoder = av_mallocz(sizeof(RKMPPDecoder));
165  if (!decoder) {
166  ret = AVERROR(ENOMEM);
167  goto fail;
168  }
169 
170  rk_context->decoder_ref = av_buffer_create((uint8_t *)decoder, sizeof(*decoder), rkmpp_release_decoder,
172  if (!rk_context->decoder_ref) {
173  av_free(decoder);
174  ret = AVERROR(ENOMEM);
175  goto fail;
176  }
177 
178  av_log(avctx, AV_LOG_DEBUG, "Initializing RKMPP decoder.\n");
179 
180  codectype = rkmpp_get_codingtype(avctx);
181  if (codectype == MPP_VIDEO_CodingUnused) {
182  av_log(avctx, AV_LOG_ERROR, "Unknown codec type (%d).\n", avctx->codec_id);
183  ret = AVERROR_UNKNOWN;
184  goto fail;
185  }
186 
187  ret = mpp_check_support_format(MPP_CTX_DEC, codectype);
188  if (ret != MPP_OK) {
189  av_log(avctx, AV_LOG_ERROR, "Codec type (%d) unsupported by MPP\n", avctx->codec_id);
190  ret = AVERROR_UNKNOWN;
191  goto fail;
192  }
193 
194  // Create the MPP context
195  ret = mpp_create(&decoder->ctx, &decoder->mpi);
196  if (ret != MPP_OK) {
197  av_log(avctx, AV_LOG_ERROR, "Failed to create MPP context (code = %d).\n", ret);
198  ret = AVERROR_UNKNOWN;
199  goto fail;
200  }
201 
202  // initialize mpp
203  ret = mpp_init(decoder->ctx, MPP_CTX_DEC, codectype);
204  if (ret != MPP_OK) {
205  av_log(avctx, AV_LOG_ERROR, "Failed to initialize MPP context (code = %d).\n", ret);
206  ret = AVERROR_UNKNOWN;
207  goto fail;
208  }
209 
210  // make decode calls blocking with a timeout
211  paramS32 = MPP_POLL_BLOCK;
212  ret = decoder->mpi->control(decoder->ctx, MPP_SET_OUTPUT_BLOCK, &paramS32);
213  if (ret != MPP_OK) {
214  av_log(avctx, AV_LOG_ERROR, "Failed to set blocking mode on MPI (code = %d).\n", ret);
215  ret = AVERROR_UNKNOWN;
216  goto fail;
217  }
218 
219  paramS64 = RECEIVE_FRAME_TIMEOUT;
220  ret = decoder->mpi->control(decoder->ctx, MPP_SET_OUTPUT_BLOCK_TIMEOUT, &paramS64);
221  if (ret != MPP_OK) {
222  av_log(avctx, AV_LOG_ERROR, "Failed to set block timeout on MPI (code = %d).\n", ret);
223  ret = AVERROR_UNKNOWN;
224  goto fail;
225  }
226 
227  ret = mpp_buffer_group_get_internal(&decoder->frame_group, MPP_BUFFER_TYPE_ION);
228  if (ret) {
229  av_log(avctx, AV_LOG_ERROR, "Failed to retrieve buffer group (code = %d)\n", ret);
230  ret = AVERROR_UNKNOWN;
231  goto fail;
232  }
233 
234  ret = decoder->mpi->control(decoder->ctx, MPP_DEC_SET_EXT_BUF_GROUP, decoder->frame_group);
235  if (ret) {
236  av_log(avctx, AV_LOG_ERROR, "Failed to assign buffer group (code = %d)\n", ret);
237  ret = AVERROR_UNKNOWN;
238  goto fail;
239  }
240 
241  ret = mpp_buffer_group_limit_config(decoder->frame_group, 0, FRAMEGROUP_MAX_FRAMES);
242  if (ret) {
243  av_log(avctx, AV_LOG_ERROR, "Failed to set buffer group limit (code = %d)\n", ret);
244  ret = AVERROR_UNKNOWN;
245  goto fail;
246  }
247 
248  decoder->first_packet = 1;
249 
250  av_log(avctx, AV_LOG_DEBUG, "RKMPP decoder initialized successfully.\n");
251 
253  if (!decoder->device_ref) {
254  ret = AVERROR(ENOMEM);
255  goto fail;
256  }
257  ret = av_hwdevice_ctx_init(decoder->device_ref);
258  if (ret < 0)
259  goto fail;
260 
261  return 0;
262 
263 fail:
264  av_log(avctx, AV_LOG_ERROR, "Failed to initialize RKMPP decoder.\n");
265  rkmpp_close_decoder(avctx);
266  return ret;
267 }
268 
269 static int rkmpp_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
270 {
271  RKMPPDecodeContext *rk_context = avctx->priv_data;
272  RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
273  int ret;
274 
275  // handle EOF
276  if (!avpkt->size) {
277  av_log(avctx, AV_LOG_DEBUG, "End of stream.\n");
278  decoder->eos_reached = 1;
279  ret = rkmpp_write_data(avctx, NULL, 0, 0);
280  if (ret)
281  av_log(avctx, AV_LOG_ERROR, "Failed to send EOS to decoder (code = %d)\n", ret);
282  return ret;
283  }
284 
285  // on first packet, send extradata
286  if (decoder->first_packet) {
287  if (avctx->extradata_size) {
288  ret = rkmpp_write_data(avctx, avctx->extradata,
289  avctx->extradata_size,
290  avpkt->pts);
291  if (ret) {
292  av_log(avctx, AV_LOG_ERROR, "Failed to write extradata to decoder (code = %d)\n", ret);
293  return ret;
294  }
295  }
296  decoder->first_packet = 0;
297  }
298 
299  // now send packet
300  ret = rkmpp_write_data(avctx, avpkt->data, avpkt->size, avpkt->pts);
301  if (ret && ret!=AVERROR(EAGAIN))
302  av_log(avctx, AV_LOG_ERROR, "Failed to write data to decoder (code = %d)\n", ret);
303 
304  return ret;
305 }
306 
307 static void rkmpp_release_frame(void *opaque, uint8_t *data)
308 {
310  AVBufferRef *framecontextref = (AVBufferRef *)opaque;
311  RKMPPFrameContext *framecontext = (RKMPPFrameContext *)framecontextref->data;
312 
313  mpp_frame_deinit(&framecontext->frame);
314  av_buffer_unref(&framecontext->decoder_ref);
315  av_buffer_unref(&framecontextref);
316 
317  av_free(desc);
318 }
319 
321 {
322  RKMPPDecodeContext *rk_context = avctx->priv_data;
323  RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
324  RKMPPFrameContext *framecontext = NULL;
325  AVBufferRef *framecontextref = NULL;
326  int ret;
327  MppFrame mppframe = NULL;
328  MppBuffer buffer = NULL;
330  AVDRMLayerDescriptor *layer = NULL;
331  int mode;
332  MppFrameFormat mppformat;
333  uint32_t drmformat;
334 
335  ret = decoder->mpi->decode_get_frame(decoder->ctx, &mppframe);
336  if (ret != MPP_OK && ret != MPP_ERR_TIMEOUT) {
337  av_log(avctx, AV_LOG_ERROR, "Failed to get a frame from MPP (code = %d)\n", ret);
338  goto fail;
339  }
340 
341  if (mppframe) {
342  // Check whether we have a special frame or not
343  if (mpp_frame_get_info_change(mppframe)) {
344  AVHWFramesContext *hwframes;
345 
346  av_log(avctx, AV_LOG_INFO, "Decoder noticed an info change (%dx%d), format=%d\n",
347  (int)mpp_frame_get_width(mppframe), (int)mpp_frame_get_height(mppframe),
348  (int)mpp_frame_get_fmt(mppframe));
349 
350  avctx->width = mpp_frame_get_width(mppframe);
351  avctx->height = mpp_frame_get_height(mppframe);
352 
353  decoder->mpi->control(decoder->ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL);
354 
355  av_buffer_unref(&decoder->frames_ref);
356 
357  decoder->frames_ref = av_hwframe_ctx_alloc(decoder->device_ref);
358  if (!decoder->frames_ref) {
359  ret = AVERROR(ENOMEM);
360  goto fail;
361  }
362 
363  mppformat = mpp_frame_get_fmt(mppframe);
364  drmformat = rkmpp_get_frameformat(mppformat);
365 
366  hwframes = (AVHWFramesContext*)decoder->frames_ref->data;
367  hwframes->format = AV_PIX_FMT_DRM_PRIME;
368  hwframes->sw_format = drmformat == DRM_FORMAT_NV12 ? AV_PIX_FMT_NV12 : AV_PIX_FMT_NONE;
369  hwframes->width = avctx->width;
370  hwframes->height = avctx->height;
371  ret = av_hwframe_ctx_init(decoder->frames_ref);
372  if (ret < 0)
373  goto fail;
374 
375  // here decoder is fully initialized, we need to feed it again with data
376  ret = AVERROR(EAGAIN);
377  goto fail;
378  } else if (mpp_frame_get_eos(mppframe)) {
379  av_log(avctx, AV_LOG_DEBUG, "Received a EOS frame.\n");
380  decoder->eos_reached = 1;
381  ret = AVERROR_EOF;
382  goto fail;
383  } else if (mpp_frame_get_discard(mppframe)) {
384  av_log(avctx, AV_LOG_DEBUG, "Received a discard frame.\n");
385  ret = AVERROR(EAGAIN);
386  goto fail;
387  } else if (mpp_frame_get_errinfo(mppframe)) {
388  av_log(avctx, AV_LOG_ERROR, "Received a errinfo frame.\n");
390  goto fail;
391  }
392 
393  // here we should have a valid frame
394  av_log(avctx, AV_LOG_DEBUG, "Received a frame.\n");
395 
396  // setup general frame fields
397  frame->format = AV_PIX_FMT_DRM_PRIME;
398  frame->width = mpp_frame_get_width(mppframe);
399  frame->height = mpp_frame_get_height(mppframe);
400  frame->pts = mpp_frame_get_pts(mppframe);
401  frame->color_range = mpp_frame_get_color_range(mppframe);
402  frame->color_primaries = mpp_frame_get_color_primaries(mppframe);
403  frame->color_trc = mpp_frame_get_color_trc(mppframe);
404  frame->colorspace = mpp_frame_get_colorspace(mppframe);
405 
406  mode = mpp_frame_get_mode(mppframe);
407  frame->interlaced_frame = ((mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_DEINTERLACED);
408  frame->top_field_first = ((mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_TOP_FIRST);
409 
410  mppformat = mpp_frame_get_fmt(mppframe);
411  drmformat = rkmpp_get_frameformat(mppformat);
412 
413  // now setup the frame buffer info
414  buffer = mpp_frame_get_buffer(mppframe);
415  if (buffer) {
417  if (!desc) {
418  ret = AVERROR(ENOMEM);
419  goto fail;
420  }
421 
422  desc->nb_objects = 1;
423  desc->objects[0].fd = mpp_buffer_get_fd(buffer);
424  desc->objects[0].size = mpp_buffer_get_size(buffer);
425 
426  desc->nb_layers = 1;
427  layer = &desc->layers[0];
428  layer->format = drmformat;
429  layer->nb_planes = 2;
430 
431  layer->planes[0].object_index = 0;
432  layer->planes[0].offset = 0;
433  layer->planes[0].pitch = mpp_frame_get_hor_stride(mppframe);
434 
435  layer->planes[1].object_index = 0;
436  layer->planes[1].offset = layer->planes[0].pitch * mpp_frame_get_ver_stride(mppframe);
437  layer->planes[1].pitch = layer->planes[0].pitch;
438 
439  // we also allocate a struct in buf[0] that will allow to hold additionnal information
440  // for releasing properly MPP frames and decoder
441  framecontextref = av_buffer_allocz(sizeof(*framecontext));
442  if (!framecontextref) {
443  ret = AVERROR(ENOMEM);
444  goto fail;
445  }
446 
447  // MPP decoder needs to be closed only when all frames have been released.
448  framecontext = (RKMPPFrameContext *)framecontextref->data;
449  framecontext->decoder_ref = av_buffer_ref(rk_context->decoder_ref);
450  framecontext->frame = mppframe;
451 
452  frame->data[0] = (uint8_t *)desc;
453  frame->buf[0] = av_buffer_create((uint8_t *)desc, sizeof(*desc), rkmpp_release_frame,
454  framecontextref, AV_BUFFER_FLAG_READONLY);
455 
456  if (!frame->buf[0]) {
457  ret = AVERROR(ENOMEM);
458  goto fail;
459  }
460 
461  frame->hw_frames_ctx = av_buffer_ref(decoder->frames_ref);
462  if (!frame->hw_frames_ctx) {
463  ret = AVERROR(ENOMEM);
464  goto fail;
465  }
466 
467  return 0;
468  } else {
469  av_log(avctx, AV_LOG_ERROR, "Failed to retrieve the frame buffer, frame is dropped (code = %d)\n", ret);
470  mpp_frame_deinit(&mppframe);
471  }
472  } else if (decoder->eos_reached) {
473  return AVERROR_EOF;
474  } else if (ret == MPP_ERR_TIMEOUT) {
475  av_log(avctx, AV_LOG_DEBUG, "Timeout when trying to get a frame from MPP\n");
476  }
477 
478  return AVERROR(EAGAIN);
479 
480 fail:
481  if (mppframe)
482  mpp_frame_deinit(&mppframe);
483 
484  if (framecontext)
485  av_buffer_unref(&framecontext->decoder_ref);
486 
487  if (framecontextref)
488  av_buffer_unref(&framecontextref);
489 
490  if (desc)
491  av_free(desc);
492 
493  return ret;
494 }
495 
497 {
498  RKMPPDecodeContext *rk_context = avctx->priv_data;
499  RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
500  int ret = MPP_NOK;
501  AVPacket pkt = {0};
502  RK_S32 usedslots, freeslots;
503 
504  if (!decoder->eos_reached) {
505  // we get the available slots in decoder
506  ret = decoder->mpi->control(decoder->ctx, MPP_DEC_GET_STREAM_COUNT, &usedslots);
507  if (ret != MPP_OK) {
508  av_log(avctx, AV_LOG_ERROR, "Failed to get decoder used slots (code = %d).\n", ret);
509  return ret;
510  }
511 
512  freeslots = INPUT_MAX_PACKETS - usedslots;
513  if (freeslots > 0) {
514  ret = ff_decode_get_packet(avctx, &pkt);
515  if (ret < 0 && ret != AVERROR_EOF) {
516  return ret;
517  }
518 
519  ret = rkmpp_send_packet(avctx, &pkt);
521 
522  if (ret < 0) {
523  av_log(avctx, AV_LOG_ERROR, "Failed to send packet to decoder (code = %d)\n", ret);
524  return ret;
525  }
526  }
527 
528  // make sure we keep decoder full
529  if (freeslots > 1)
530  return AVERROR(EAGAIN);
531  }
532 
533  return rkmpp_retrieve_frame(avctx, frame);
534 }
535 
536 static void rkmpp_flush(AVCodecContext *avctx)
537 {
538  RKMPPDecodeContext *rk_context = avctx->priv_data;
539  RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
540  int ret = MPP_NOK;
541 
542  av_log(avctx, AV_LOG_DEBUG, "Flush.\n");
543 
544  ret = decoder->mpi->reset(decoder->ctx);
545  if (ret == MPP_OK) {
546  decoder->first_packet = 1;
547  } else
548  av_log(avctx, AV_LOG_ERROR, "Failed to reset MPI (code = %d)\n", ret);
549 }
550 
552  HW_CONFIG_INTERNAL(DRM_PRIME),
553  NULL
554 };
555 
556 #define RKMPP_DEC_CLASS(NAME) \
557  static const AVClass rkmpp_##NAME##_dec_class = { \
558  .class_name = "rkmpp_" #NAME "_dec", \
559  .version = LIBAVUTIL_VERSION_INT, \
560  };
561 
562 #define RKMPP_DEC(NAME, ID, BSFS) \
563  RKMPP_DEC_CLASS(NAME) \
564  AVCodec ff_##NAME##_rkmpp_decoder = { \
565  .name = #NAME "_rkmpp", \
566  .long_name = NULL_IF_CONFIG_SMALL(#NAME " (rkmpp)"), \
567  .type = AVMEDIA_TYPE_VIDEO, \
568  .id = ID, \
569  .priv_data_size = sizeof(RKMPPDecodeContext), \
570  .init = rkmpp_init_decoder, \
571  .close = rkmpp_close_decoder, \
572  .receive_frame = rkmpp_receive_frame, \
573  .flush = rkmpp_flush, \
574  .priv_class = &rkmpp_##NAME##_dec_class, \
575  .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
576  .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_DRM_PRIME, \
577  AV_PIX_FMT_NONE}, \
578  .hw_configs = rkmpp_hw_configs, \
579  .bsfs = BSFS, \
580  .wrapper_name = "rkmpp", \
581  };
582 
583 RKMPP_DEC(h264, AV_CODEC_ID_H264, "h264_mp4toannexb")
584 RKMPP_DEC(hevc, AV_CODEC_ID_HEVC, "hevc_mp4toannexb")
static int rkmpp_write_data(AVCodecContext *avctx, uint8_t *buffer, int size, int64_t pts)
Definition: rkmppdec.c:89
char eos_reached
Definition: rkmppdec.c:51
#define NULL
Definition: coverity.c:32
static void rkmpp_flush(AVCodecContext *avctx)
Definition: rkmppdec.c:536
#define RECEIVE_FRAME_TIMEOUT
Definition: rkmppdec.c:41
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
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
#define FRAMEGROUP_MAX_FRAMES
Definition: rkmppdec.c:42
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
misc image utilities
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:486
const char * desc
Definition: nvenc.c:68
int size
Definition: avcodec.h:1478
static MppCodingType rkmpp_get_codingtype(AVCodecContext *avctx)
Definition: rkmppdec.c:67
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:228
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1775
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:208
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
static AVPacket pkt
static int rkmpp_close_decoder(AVCodecContext *avctx)
Definition: rkmppdec.c:124
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame...
Definition: frame.h:634
static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: rkmppdec.c:320
DRM frame descriptor.
AVClass * av_class
Definition: rkmppdec.c:58
AVBufferRef * decoder_ref
Definition: rkmppdec.c:59
uint8_t
MppApi * mpi
Definition: rkmppdec.c:47
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Called by decoders to get the next packet for decoding.
Definition: decode.c:328
static uint32_t rkmpp_get_frameformat(MppFrameFormat mppformat)
Definition: rkmppdec.c:78
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1666
uint8_t * data
Definition: avcodec.h:1477
#define AVERROR_EOF
End of file.
Definition: error.h:55
int interlaced_frame
The content of the picture is interlaced.
Definition: frame.h:442
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Definition: buffer.h:113
ptrdiff_t size
Definition: opengl_enc.c:100
#define av_log(a,...)
static int rkmpp_init_decoder(AVCodecContext *avctx)
Definition: rkmppdec.c:152
DRM layer descriptor.
Definition: hwcontext_drm.h:96
static void rkmpp_release_decoder(void *opaque, uint8_t *data)
Definition: rkmppdec.c:131
char first_packet
Definition: rkmppdec.c:50
int width
Definition: frame.h:353
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define INPUT_MAX_PACKETS
Definition: rkmppdec.c:43
#define HW_CONFIG_INTERNAL(format)
Definition: hwaccel.h:57
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:539
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:550
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
AVBufferRef * av_buffer_create(uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:28
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:329
#define fail()
Definition: checkasm.h:120
reference-counted frame API
MppBufferGroup frame_group
Definition: rkmppdec.c:48
static const chunk_decoder decoder[8]
Definition: dfa.c:330
int width
picture width / height.
Definition: avcodec.h:1738
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
if(ret)
AVBufferRef * device_ref
Definition: rkmppdec.c:54
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:368
MppFrame frame
Definition: rkmppdec.c:63
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given hardware type.
Definition: hwcontext.c:138
Libavcodec external API header.
static int rkmpp_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: rkmppdec.c:496
enum AVCodecID codec_id
Definition: avcodec.h:1575
main external API structure.
Definition: avcodec.h:1565
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:599
uint8_t * data
The data buffer.
Definition: buffer.h:89
#define RKMPP_DEC(NAME, ID, BSFS)
Definition: rkmppdec.c:562
int extradata_size
Definition: avcodec.h:1667
AVBufferRef * av_buffer_allocz(int size)
Same as av_buffer_alloc(), except the returned buffer will be initialized to zero.
Definition: buffer.c:83
int av_hwdevice_ctx_init(AVBufferRef *ref)
Finalize the device context before use.
Definition: hwcontext.c:196
Describe the class of an AVClass context structure.
Definition: log.h:67
DRM-managed buffers exposed through PRIME buffer sharing.
Definition: pixfmt.h:328
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:123
refcounted data buffer API
static const AVCodecHWConfigInternal * rkmpp_hw_configs[]
Definition: rkmppdec.c:551
API-specific header for AV_HWDEVICE_TYPE_DRM.
static int64_t pts
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
A reference to a data buffer.
Definition: buffer.h:81
static int rkmpp_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
Definition: rkmppdec.c:269
common internal api header.
common internal and external API header
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:243
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:93
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:71
void * priv_data
Definition: avcodec.h:1592
#define av_free(p)
int top_field_first
If the content is interlaced, is top field displayed first.
Definition: frame.h:447
MppCtx ctx
Definition: rkmppdec.c:46
enum AVColorPrimaries color_primaries
Definition: frame.h:541
int height
Definition: frame.h:353
enum AVColorTransferCharacteristic color_trc
Definition: frame.h:543
AVBufferRef * frames_ref
Definition: rkmppdec.c:53
AVBufferRef * decoder_ref
Definition: rkmppdec.c:64
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
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:221
This structure stores compressed data.
Definition: avcodec.h:1454
static void rkmpp_release_frame(void *opaque, uint8_t *data)
Definition: rkmppdec.c:307
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1470
GLuint buffer
Definition: opengl_enc.c:101