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 "hwconfig.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 {
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);
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);
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);
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);
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);
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);
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);
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);
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);
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 
551 static const AVCodecHWConfigInternal *const rkmpp_hw_configs[] = {
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  const 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")
hwconfig.h
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:424
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:224
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:209
rkmpp_init_decoder
static int rkmpp_init_decoder(AVCodecContext *avctx)
Definition: rkmppdec.c:152
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:333
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
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:247
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:373
AV_PIX_FMT_DRM_PRIME
@ AV_PIX_FMT_DRM_PRIME
DRM-managed buffers exposed through PRIME buffer sharing.
Definition: pixfmt.h:318
data
const char data[16]
Definition: mxf.c:143
RKMPPDecodeContext::decoder_ref
AVBufferRef * decoder_ref
Definition: rkmppdec.c:59
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:229
av_hwdevice_ctx_init
int av_hwdevice_ctx_init(AVBufferRef *ref)
Finalize the device context before use.
Definition: hwcontext.c:200
rkmpp_get_frameformat
static uint32_t rkmpp_get_frameformat(MppFrameFormat mppformat)
Definition: rkmppdec.c:78
decoder
static const chunk_decoder decoder[8]
Definition: dfa.c:330
fail
#define fail()
Definition: checkasm.h:127
pts
static int64_t pts
Definition: transcode_aac.c:653
AVDRMLayerDescriptor
DRM layer descriptor.
Definition: hwcontext_drm.h:96
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:180
AVHWFramesContext::height
int height
Definition: hwcontext.h:229
av_hwdevice_ctx_alloc
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given hardware type.
Definition: hwcontext.c:142
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:485
INPUT_MAX_PACKETS
#define INPUT_MAX_PACKETS
Definition: rkmppdec.c:43
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:218
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:50
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:393
if
if(ret)
Definition: filter_design.txt:179
rkmpp_send_packet
static int rkmpp_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
Definition: rkmppdec.c:269
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
RKMPPDecoder
Definition: rkmppdec.c:45
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:222
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:46
rkmpp_release_decoder
static void rkmpp_release_decoder(void *opaque, uint8_t *data)
Definition: rkmppdec.c:131
RKMPPDecoder::mpi
MppApi * mpi
Definition: rkmppdec.c:47
time.h
rkmpp_release_frame
static void rkmpp_release_frame(void *opaque, uint8_t *data)
Definition: rkmppdec.c:307
rkmpp_close_decoder
static int rkmpp_close_decoder(AVCodecContext *avctx)
Definition: rkmppdec.c:124
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:58
rkmpp_get_codingtype
static MppCodingType rkmpp_get_codingtype(AVCodecContext *avctx)
Definition: rkmppdec.c:67
AVPacket::size
int size
Definition: packet.h:374
rkmpp_receive_frame
static int rkmpp_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: rkmppdec.c:496
RKMPPDecoder::device_ref
AVBufferRef * device_ref
Definition: rkmppdec.c:54
size
int size
Definition: twinvq_data.h:10344
FRAMEGROUP_MAX_FRAMES
#define FRAMEGROUP_MAX_FRAMES
Definition: rkmppdec.c:42
HW_CONFIG_INTERNAL
#define HW_CONFIG_INTERNAL(format)
Definition: hwconfig.h:57
AVCodecHWConfigInternal
Definition: hwconfig.h:29
RKMPPFrameContext::decoder_ref
AVBufferRef * decoder_ref
Definition: rkmppdec.c:64
frame.h
buffer.h
RKMPP_DEC
#define RKMPP_DEC(NAME, ID, BSFS)
Definition: rkmppdec.c:562
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:366
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:484
common.h
RKMPPDecoder::frames_ref
AVBufferRef * frames_ref
Definition: rkmppdec.c:53
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:224
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:263
hwcontext_drm.h
AVCodecContext::height
int height
Definition: avcodec.h:556
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:593
RKMPPDecoder::frame_group
MppBufferGroup frame_group
Definition: rkmppdec.c:48
avcodec.h
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
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: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
rkmpp_write_data
static int rkmpp_write_data(AVCodecContext *avctx, uint8_t *buffer, int size, int64_t pts)
Definition: rkmppdec.c:89
AVCodecContext
main external API structure.
Definition: avcodec.h:383
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:65
RKMPPFrameContext::frame
MppFrame frame
Definition: rkmppdec.c:63
RKMPPDecodeContext
Definition: rkmppdec.c:57
desc
const char * desc
Definition: libsvtav1.c:79
RECEIVE_FRAME_TIMEOUT
#define RECEIVE_FRAME_TIMEOUT
Definition: rkmppdec.c:41
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
RKMPPFrameContext
Definition: rkmppdec.c:62
rkmpp_hw_configs
static const AVCodecHWConfigInternal *const rkmpp_hw_configs[]
Definition: rkmppdec.c:551
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVPacket
This structure stores compressed data.
Definition: packet.h:350
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:410
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:556
imgutils.h
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:190
hwcontext.h
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
RKMPPDecoder::eos_reached
char eos_reached
Definition: rkmppdec.c:51
rkmpp_flush
static void rkmpp_flush(AVCodecContext *avctx)
Definition: rkmppdec.c:536
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:320