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