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