22 #include <drm_fourcc.h>
24 #include <rockchip/mpp_buffer.h>
25 #include <rockchip/rk_mpi.h>
41 #define RECEIVE_FRAME_TIMEOUT 100
42 #define FRAMEGROUP_MAX_FRAMES 16
43 #define INPUT_MAX_PACKETS 4
74 default:
return MPP_VIDEO_CodingUnused;
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;
97 ret = mpp_packet_init(&packet, buffer, size);
103 mpp_packet_set_pts(packet, pts);
106 mpp_packet_set_eos(packet);
108 ret = decoder->
mpi->decode_put_packet(decoder->
ctx, packet);
110 if (ret == MPP_ERR_BUFFER_FULL) {
119 mpp_packet_deinit(&packet);
136 decoder->
mpi->reset(decoder->
ctx);
137 mpp_destroy(decoder->
ctx);
156 MppCodingType codectype = MPP_VIDEO_CodingUnused;
181 if (codectype == MPP_VIDEO_CodingUnused) {
187 ret = mpp_check_support_format(MPP_CTX_DEC, codectype);
195 ret = mpp_create(&decoder->
ctx, &decoder->
mpi);
203 ret = mpp_init(decoder->
ctx, MPP_CTX_DEC, codectype);
211 paramS32 = MPP_POLL_BLOCK;
212 ret = decoder->
mpi->control(decoder->
ctx, MPP_SET_OUTPUT_BLOCK, ¶mS32);
214 av_log(avctx,
AV_LOG_ERROR,
"Failed to set blocking mode on MPI (code = %d).\n", ret);
220 ret = decoder->
mpi->control(decoder->
ctx, MPP_SET_OUTPUT_BLOCK_TIMEOUT, ¶mS64);
222 av_log(avctx,
AV_LOG_ERROR,
"Failed to set block timeout on MPI (code = %d).\n", ret);
227 ret = mpp_buffer_group_get_internal(&decoder->
frame_group, MPP_BUFFER_TYPE_ION);
234 ret = decoder->
mpi->control(decoder->
ctx, MPP_DEC_SET_EXT_BUF_GROUP, decoder->
frame_group);
292 av_log(avctx,
AV_LOG_ERROR,
"Failed to write extradata to decoder (code = %d)\n", ret);
301 if (ret && ret!=
AVERROR(EAGAIN))
313 mpp_frame_deinit(&framecontext->
frame);
327 MppFrame mppframe =
NULL;
332 MppFrameFormat mppformat;
335 ret = decoder->
mpi->decode_get_frame(decoder->
ctx, &mppframe);
336 if (ret != MPP_OK && ret != MPP_ERR_TIMEOUT) {
343 if (mpp_frame_get_info_change(mppframe)) {
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));
350 avctx->
width = mpp_frame_get_width(mppframe);
351 avctx->
height = mpp_frame_get_height(mppframe);
353 decoder->
mpi->control(decoder->
ctx, MPP_DEC_SET_INFO_CHANGE_READY,
NULL);
363 mppformat = mpp_frame_get_fmt(mppframe);
378 }
else if (mpp_frame_get_eos(mppframe)) {
383 }
else if (mpp_frame_get_discard(mppframe)) {
387 }
else if (mpp_frame_get_errinfo(mppframe)) {
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);
403 frame->
color_trc = mpp_frame_get_color_trc(mppframe);
404 frame->
colorspace = mpp_frame_get_colorspace(mppframe);
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);
410 mppformat = mpp_frame_get_fmt(mppframe);
414 buffer = mpp_frame_get_buffer(mppframe);
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);
427 layer = &
desc->layers[0];
428 layer->format = drmformat;
429 layer->nb_planes = 2;
431 layer->planes[0].object_index = 0;
432 layer->planes[0].offset = 0;
433 layer->planes[0].pitch = mpp_frame_get_hor_stride(mppframe);
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;
442 if (!framecontextref) {
450 framecontext->frame = mppframe;
456 if (!frame->
buf[0]) {
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);
474 }
else if (ret == MPP_ERR_TIMEOUT) {
482 mpp_frame_deinit(&mppframe);
502 RK_S32 usedslots, freeslots;
506 ret =
decoder->mpi->control(
decoder->ctx, MPP_DEC_GET_STREAM_COUNT, &usedslots);
544 ret = decoder->
mpi->reset(decoder->
ctx);
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, \
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, \
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, \
578 .hw_configs = rkmpp_hw_configs, \
580 .wrapper_name = "rkmpp", \
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.
#define INPUT_MAX_PACKETS
#define HW_CONFIG_INTERNAL(format)
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
static const AVCodecHWConfigInternal * rkmpp_hw_configs[]
API-specific header for AV_HWDEVICE_TYPE_DRM.
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...