Go to the documentation of this file.
22 #include <drm_fourcc.h>
24 #include <rockchip/mpp_buffer.h>
25 #include <rockchip/rk_mpi.h>
44 #define RECEIVE_FRAME_TIMEOUT 100
45 #define FRAMEGROUP_MAX_FRAMES 16
46 #define INPUT_MAX_PACKETS 4
77 default:
return MPP_VIDEO_CodingUnused;
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;
106 mpp_packet_set_pts(packet,
pts);
109 mpp_packet_set_eos(packet);
113 if (
ret == MPP_ERR_BUFFER_FULL) {
122 mpp_packet_deinit(&packet);
145 mpp_buffer_group_put(
decoder->frame_group);
157 MppCodingType codectype = MPP_VIDEO_CodingUnused;
176 if (codectype == MPP_VIDEO_CodingUnused) {
182 ret = mpp_check_support_format(MPP_CTX_DEC, codectype);
198 ret = mpp_init(
decoder->ctx, MPP_CTX_DEC, codectype);
206 paramS32 = MPP_POLL_BLOCK;
215 ret =
decoder->mpi->control(
decoder->ctx, MPP_SET_OUTPUT_BLOCK_TIMEOUT, ¶mS64);
222 ret = mpp_buffer_group_get_internal(&
decoder->frame_group, MPP_BUFFER_TYPE_ION);
283 const uint8_t *extradata;
309 mpp_frame_deinit(&framecontext->
frame);
320 MppFrame mppframe =
NULL;
324 MppFrameFormat mppformat;
328 if (
ret != MPP_OK &&
ret != MPP_ERR_TIMEOUT) {
335 if (mpp_frame_get_info_change(mppframe)) {
338 av_log(avctx,
AV_LOG_INFO,
"Decoder noticed an info change (%dx%d), format=%d\n",
339 (
int)mpp_frame_get_width(mppframe), (
int)mpp_frame_get_height(mppframe),
340 (
int)mpp_frame_get_fmt(mppframe));
342 avctx->
width = mpp_frame_get_width(mppframe);
343 avctx->
height = mpp_frame_get_height(mppframe);
355 mppformat = mpp_frame_get_fmt(mppframe);
370 }
else if (mpp_frame_get_eos(mppframe)) {
375 }
else if (mpp_frame_get_discard(mppframe)) {
379 }
else if (mpp_frame_get_errinfo(mppframe)) {
390 frame->width = mpp_frame_get_width(mppframe);
391 frame->height = mpp_frame_get_height(mppframe);
392 frame->pts = mpp_frame_get_pts(mppframe);
393 frame->color_range = mpp_frame_get_color_range(mppframe);
394 frame->color_primaries = mpp_frame_get_color_primaries(mppframe);
395 frame->color_trc = mpp_frame_get_color_trc(mppframe);
396 frame->colorspace = mpp_frame_get_colorspace(mppframe);
398 mode = mpp_frame_get_mode(mppframe);
399 if ((
mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_DEINTERLACED)
401 if ((
mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_TOP_FIRST)
404 mppformat = mpp_frame_get_fmt(mppframe);
408 buffer = mpp_frame_get_buffer(mppframe);
418 } *combined_desc =
av_mallocz(
sizeof(*combined_desc));
419 if (!combined_desc) {
423 desc = &combined_desc->desc;
424 framecontext = &combined_desc->framecontext;
426 desc->nb_objects = 1;
427 desc->objects[0].fd = mpp_buffer_get_fd(
buffer);
428 desc->objects[0].size = mpp_buffer_get_size(
buffer);
431 layer = &
desc->layers[0];
432 layer->
format = drmformat;
437 layer->
planes[0].
pitch = mpp_frame_get_hor_stride(mppframe);
444 framecontext->
frame = mppframe;
450 if (!
frame->buf[0]) {
458 if (!
frame->hw_frames_ctx) {
465 av_log(avctx,
AV_LOG_ERROR,
"Failed to retrieve the frame buffer, frame is dropped (code = %d)\n",
ret);
466 mpp_frame_deinit(&mppframe);
468 }
else if (
decoder->eos_reached) {
470 }
else if (
ret == MPP_ERR_TIMEOUT) {
478 mpp_frame_deinit(&mppframe);
489 RK_S32 usedslots, freeslots;
543 #define RKMPP_DEC_CLASS(NAME) \
544 static const AVClass rkmpp_##NAME##_dec_class = { \
545 .class_name = "rkmpp_" #NAME "_dec", \
546 .version = LIBAVUTIL_VERSION_INT, \
549 #define RKMPP_DEC(NAME, ID, BSFS) \
550 RKMPP_DEC_CLASS(NAME) \
551 const FFCodec ff_##NAME##_rkmpp_decoder = { \
552 .p.name = #NAME "_rkmpp", \
553 CODEC_LONG_NAME(#NAME " (rkmpp)"), \
554 .p.type = AVMEDIA_TYPE_VIDEO, \
556 .priv_data_size = sizeof(RKMPPDecodeContext), \
557 .init = rkmpp_init_decoder, \
558 .close = rkmpp_close_decoder, \
559 FF_CODEC_RECEIVE_FRAME_CB(rkmpp_receive_frame), \
560 .flush = rkmpp_flush, \
561 .p.priv_class = &rkmpp_##NAME##_dec_class, \
562 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
563 .hw_configs = rkmpp_hw_configs, \
565 .p.wrapper_name = "rkmpp", \
566 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, \
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Called by decoders to get the next packet for decoding.
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
#define AVERROR_EOF
End of file.
RefStruct is an API for creating reference-counted objects with minimal overhead.
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
RKMPPDecoder * decoder
RefStruct reference.
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
This structure describes decoded (raw) audio or video data.
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
@ AV_PIX_FMT_DRM_PRIME
DRM-managed buffers exposed through PRIME buffer sharing.
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
int width
The allocated dimensions of the frames in this pool.
int av_hwdevice_ctx_init(AVBufferRef *ref)
Finalize the device context before use.
static void rkmpp_release_decoder(AVRefStructOpaque unused, void *obj)
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
const RKMPPDecoder * decoder_ref
RefStruct reference.
static uint32_t rkmpp_get_frameformat(MppFrameFormat mppformat)
static const chunk_decoder decoder[8]
int nb_planes
Number of planes in the layer.
AVDRMPlaneDescriptor planes[AV_DRM_MAX_PLANES]
Array of planes in this layer.
ptrdiff_t offset
Offset within that object of this plane.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given hardware type.
#define INPUT_MAX_PACKETS
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
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.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
static int rkmpp_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
Describe the class of an AVClass context structure.
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
static void rkmpp_release_frame(void *opaque, uint8_t *data)
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.
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.
static MppCodingType rkmpp_get_codingtype(AVCodecContext *avctx)
static int rkmpp_receive_frame(AVCodecContext *avctx, AVFrame *frame)
#define FRAMEGROUP_MAX_FRAMES
static av_cold int rkmpp_close_decoder(AVCodecContext *avctx)
#define HW_CONFIG_INTERNAL(format)
#define RKMPP_DEC(NAME, ID, BSFS)
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
#define AV_LOG_INFO
Standard information.
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
int object_index
Index of the object containing this plane in the objects array of the enclosing frame descriptor.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
MppBufferGroup frame_group
This struct describes a set or pool of "hardware" frames (i.e.
uint32_t format
Format of the layer (DRM_FORMAT_*).
@ 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...
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
static int rkmpp_write_data(AVCodecContext *avctx, uint8_t *buffer, int size, int64_t pts)
main external API structure.
static av_cold int rkmpp_init_decoder(AVCodecContext *avctx)
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
#define RECEIVE_FRAME_TIMEOUT
A reference to a data buffer.
static const AVCodecHWConfigInternal *const rkmpp_hw_configs[]
This structure stores compressed data.
int width
picture width / height.
ptrdiff_t pitch
Pitch (linesize) of this plane.
static av_cold void rkmpp_flush(AVCodecContext *avctx)
static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame)