22 #include <drm_fourcc.h>
24 #include <rockchip/mpp_buffer.h>
25 #include <rockchip/rk_mpi.h>
40 #define RECEIVE_FRAME_TIMEOUT 100
41 #define FRAMEGROUP_MAX_FRAMES 16
73 default:
return MPP_VIDEO_CodingUnused;
80 case MPP_FMT_YUV420SP:
return DRM_FORMAT_NV12;
81 #ifdef DRM_FORMAT_NV12_10
82 case MPP_FMT_YUV420SP_10BIT:
return DRM_FORMAT_NV12_10;
96 ret = mpp_packet_init(&packet, buffer, size);
102 mpp_packet_set_pts(packet, pts);
105 mpp_packet_set_eos(packet);
107 ret = decoder->
mpi->decode_put_packet(decoder->
ctx, packet);
109 if (ret == MPP_ERR_BUFFER_FULL) {
118 mpp_packet_deinit(&packet);
135 decoder->
mpi->reset(decoder->
ctx);
136 mpp_destroy(decoder->
ctx);
155 MppCodingType codectype = MPP_VIDEO_CodingUnused;
180 if (codectype == MPP_VIDEO_CodingUnused) {
186 ret = mpp_check_support_format(MPP_CTX_DEC, codectype);
194 ret = mpp_create(&decoder->
ctx, &decoder->
mpi);
202 ret = mpp_init(decoder->
ctx, MPP_CTX_DEC, codectype);
210 paramS32 = MPP_POLL_BLOCK;
211 ret = decoder->
mpi->control(decoder->
ctx, MPP_SET_OUTPUT_BLOCK, ¶mS32);
213 av_log(avctx,
AV_LOG_ERROR,
"Failed to set blocking mode on MPI (code = %d).\n", ret);
219 ret = decoder->
mpi->control(decoder->
ctx, MPP_SET_OUTPUT_BLOCK_TIMEOUT, ¶mS64);
221 av_log(avctx,
AV_LOG_ERROR,
"Failed to set block timeout on MPI (code = %d).\n", ret);
226 ret = mpp_buffer_group_get_internal(&decoder->
frame_group, MPP_BUFFER_TYPE_ION);
233 ret = decoder->
mpi->control(decoder->
ctx, MPP_DEC_SET_EXT_BUF_GROUP, decoder->
frame_group);
291 av_log(avctx,
AV_LOG_ERROR,
"Failed to write extradata to decoder (code = %d)\n", ret);
300 if (ret && ret!=
AVERROR(EAGAIN))
312 mpp_frame_deinit(&framecontext->
frame);
326 MppFrame mppframe =
NULL;
332 MppFrameFormat mppformat;
341 ret = decoder->
mpi->decode_get_frame(decoder->
ctx, &mppframe);
342 if (ret != MPP_OK && ret != MPP_ERR_TIMEOUT && !decoder->
first_frame) {
343 if (retrycount < 5) {
344 av_log(avctx,
AV_LOG_DEBUG,
"Failed to get a frame, retrying (code = %d, retrycount = %d)\n", ret, retrycount);
347 goto retry_get_frame;
356 if (mpp_frame_get_info_change(mppframe)) {
359 av_log(avctx,
AV_LOG_INFO,
"Decoder noticed an info change (%dx%d), format=%d\n",
360 (
int)mpp_frame_get_width(mppframe), (
int)mpp_frame_get_height(mppframe),
361 (
int)mpp_frame_get_fmt(mppframe));
363 avctx->
width = mpp_frame_get_width(mppframe);
364 avctx->
height = mpp_frame_get_height(mppframe);
366 decoder->
mpi->control(decoder->
ctx, MPP_DEC_SET_INFO_CHANGE_READY,
NULL);
377 mppformat = mpp_frame_get_fmt(mppframe);
392 }
else if (mpp_frame_get_eos(mppframe)) {
397 }
else if (mpp_frame_get_discard(mppframe)) {
401 }
else if (mpp_frame_get_errinfo(mppframe)) {
412 frame->
width = mpp_frame_get_width(mppframe);
413 frame->
height = mpp_frame_get_height(mppframe);
414 frame->
pts = mpp_frame_get_pts(mppframe);
415 frame->
color_range = mpp_frame_get_color_range(mppframe);
417 frame->
color_trc = mpp_frame_get_color_trc(mppframe);
418 frame->
colorspace = mpp_frame_get_colorspace(mppframe);
420 mode = mpp_frame_get_mode(mppframe);
421 frame->
interlaced_frame = ((
mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_DEINTERLACED);
422 frame->
top_field_first = ((
mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_TOP_FIRST);
424 mppformat = mpp_frame_get_fmt(mppframe);
428 buffer = mpp_frame_get_buffer(mppframe);
436 desc->nb_objects = 1;
437 desc->objects[0].fd = mpp_buffer_get_fd(
buffer);
438 desc->objects[0].size = mpp_buffer_get_size(
buffer);
441 layer = &
desc->layers[0];
442 layer->format = drmformat;
443 layer->nb_planes = 2;
445 layer->planes[0].object_index = 0;
446 layer->planes[0].offset = 0;
447 layer->planes[0].pitch = mpp_frame_get_hor_stride(mppframe);
449 layer->planes[1].object_index = 0;
450 layer->planes[1].offset = layer->planes[0].pitch * mpp_frame_get_ver_stride(mppframe);
451 layer->planes[1].pitch = layer->planes[0].pitch;
456 if (!framecontextref) {
464 framecontext->frame = mppframe;
470 if (!frame->
buf[0]) {
484 av_log(avctx,
AV_LOG_ERROR,
"Failed to retrieve the frame buffer, frame is dropped (code = %d)\n", ret);
485 mpp_frame_deinit(&mppframe);
489 }
else if (ret == MPP_ERR_TIMEOUT) {
497 mpp_frame_deinit(&mppframe);
521 ret =
decoder->mpi->control(
decoder->ctx, MPP_DEC_GET_FREE_PACKET_SLOT_COUNT, &freeslots);
543 if (freeslots > 1 &&
decoder->first_frame)
558 ret = decoder->
mpi->reset(decoder->
ctx);
567 #define RKMPP_DEC_CLASS(NAME) \
568 static const AVClass rkmpp_##NAME##_dec_class = { \
569 .class_name = "rkmpp_" #NAME "_dec", \
570 .version = LIBAVUTIL_VERSION_INT, \
573 #define RKMPP_DEC(NAME, ID, BSFS) \
574 RKMPP_DEC_CLASS(NAME) \
575 AVCodec ff_##NAME##_rkmpp_decoder = { \
576 .name = #NAME "_rkmpp", \
577 .long_name = NULL_IF_CONFIG_SMALL(#NAME " (rkmpp)"), \
578 .type = AVMEDIA_TYPE_VIDEO, \
580 .priv_data_size = sizeof(RKMPPDecodeContext), \
581 .init = rkmpp_init_decoder, \
582 .close = rkmpp_close_decoder, \
583 .receive_frame = rkmpp_receive_frame, \
584 .flush = rkmpp_flush, \
585 .priv_class = &rkmpp_##NAME##_dec_class, \
586 .capabilities = AV_CODEC_CAP_DELAY, \
587 .caps_internal = AV_CODEC_CAP_AVOID_PROBING, \
588 .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_DRM_PRIME, \
static int rkmpp_write_data(AVCodecContext *avctx, uint8_t *buffer, int size, int64_t pts)
static void rkmpp_flush(AVCodecContext *avctx)
#define RECEIVE_FRAME_TIMEOUT
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
This structure describes decoded (raw) audio or video data.
#define FRAMEGROUP_MAX_FRAMES
ptrdiff_t const GLvoid * data
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
static MppCodingType rkmpp_get_codingtype(AVCodecContext *avctx)
int width
The allocated dimensions of the frames in this pool.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
static int rkmpp_close_decoder(AVCodecContext *avctx)
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame...
static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame)
AVBufferRef * decoder_ref
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Called by decoders to get the next packet for decoding.
static uint32_t rkmpp_get_frameformat(MppFrameFormat mppformat)
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
#define AVERROR_EOF
End of file.
int interlaced_frame
The content of the picture is interlaced.
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
static int rkmpp_init_decoder(AVCodecContext *avctx)
static void rkmpp_release_decoder(void *opaque, uint8_t *data)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
enum AVColorRange color_range
MPEG vs JPEG YUV range.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
enum AVColorSpace colorspace
YUV colorspace type.
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
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.
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
reference-counted frame API
MppBufferGroup frame_group
static const chunk_decoder decoder[8]
int width
picture width / height.
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
#define AV_LOG_INFO
Standard information.
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given hardware type.
Libavcodec external API header.
static int rkmpp_receive_frame(AVCodecContext *avctx, AVFrame *frame)
main external API structure.
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
uint8_t * data
The data buffer.
#define RKMPP_DEC(NAME, ID, BSFS)
AVBufferRef * av_buffer_allocz(int size)
Same as av_buffer_alloc(), except the returned buffer will be initialized to zero.
int av_hwdevice_ctx_init(AVBufferRef *ref)
Finalize the device context before use.
Describe the class of an AVClass context structure.
DRM-managed buffers exposed through PRIME buffer sharing.
This struct describes a set or pool of "hardware" frames (i.e.
refcounted data buffer API
API-specific header for AV_HWDEVICE_TYPE_DRM.
static int64_t pts
Global timestamp for the audio frames.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
A reference to a data buffer.
static int rkmpp_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
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.
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
int top_field_first
If the content is interlaced, is top field displayed first.
enum AVColorPrimaries color_primaries
enum AVColorTransferCharacteristic color_trc
AVBufferRef * decoder_ref
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
This structure stores compressed data.
static void rkmpp_release_frame(void *opaque, uint8_t *data)
mode
Use these values in ebur128_init (or'ed).
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...