Go to the documentation of this file.
22 #include <drm_fourcc.h>
24 #include <rockchip/mpp_buffer.h>
25 #include <rockchip/rk_mpi.h>
43 #define RECEIVE_FRAME_TIMEOUT 100
44 #define FRAMEGROUP_MAX_FRAMES 16
45 #define INPUT_MAX_PACKETS 4
76 default:
return MPP_VIDEO_CodingUnused;
83 case MPP_FMT_YUV420SP:
return DRM_FORMAT_NV12;
84 #ifdef DRM_FORMAT_NV12_10
85 case MPP_FMT_YUV420SP_10BIT:
return DRM_FORMAT_NV12_10;
105 mpp_packet_set_pts(packet,
pts);
108 mpp_packet_set_eos(packet);
112 if (
ret == MPP_ERR_BUFFER_FULL) {
121 mpp_packet_deinit(&packet);
144 mpp_buffer_group_put(
decoder->frame_group);
156 MppCodingType codectype = MPP_VIDEO_CodingUnused;
175 if (codectype == MPP_VIDEO_CodingUnused) {
181 ret = mpp_check_support_format(MPP_CTX_DEC, codectype);
197 ret = mpp_init(
decoder->ctx, MPP_CTX_DEC, codectype);
205 paramS32 = MPP_POLL_BLOCK;
214 ret =
decoder->mpi->control(
decoder->ctx, MPP_SET_OUTPUT_BLOCK_TIMEOUT, ¶mS64);
221 ret = mpp_buffer_group_get_internal(&
decoder->frame_group, MPP_BUFFER_TYPE_ION);
306 mpp_frame_deinit(&framecontext->
frame);
317 MppFrame mppframe =
NULL;
321 MppFrameFormat mppformat;
325 if (
ret != MPP_OK &&
ret != MPP_ERR_TIMEOUT) {
332 if (mpp_frame_get_info_change(mppframe)) {
335 av_log(avctx,
AV_LOG_INFO,
"Decoder noticed an info change (%dx%d), format=%d\n",
336 (
int)mpp_frame_get_width(mppframe), (
int)mpp_frame_get_height(mppframe),
337 (
int)mpp_frame_get_fmt(mppframe));
339 avctx->
width = mpp_frame_get_width(mppframe);
340 avctx->
height = mpp_frame_get_height(mppframe);
352 mppformat = mpp_frame_get_fmt(mppframe);
367 }
else if (mpp_frame_get_eos(mppframe)) {
372 }
else if (mpp_frame_get_discard(mppframe)) {
376 }
else if (mpp_frame_get_errinfo(mppframe)) {
387 frame->width = mpp_frame_get_width(mppframe);
388 frame->height = mpp_frame_get_height(mppframe);
389 frame->pts = mpp_frame_get_pts(mppframe);
390 frame->color_range = mpp_frame_get_color_range(mppframe);
391 frame->color_primaries = mpp_frame_get_color_primaries(mppframe);
392 frame->color_trc = mpp_frame_get_color_trc(mppframe);
393 frame->colorspace = mpp_frame_get_colorspace(mppframe);
395 mode = mpp_frame_get_mode(mppframe);
396 if ((
mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_DEINTERLACED)
398 if ((
mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_TOP_FIRST)
401 mppformat = mpp_frame_get_fmt(mppframe);
405 buffer = mpp_frame_get_buffer(mppframe);
415 } *combined_desc =
av_mallocz(
sizeof(*combined_desc));
416 if (!combined_desc) {
420 desc = &combined_desc->desc;
421 framecontext = &combined_desc->framecontext;
423 desc->nb_objects = 1;
424 desc->objects[0].fd = mpp_buffer_get_fd(
buffer);
425 desc->objects[0].size = mpp_buffer_get_size(
buffer);
428 layer = &
desc->layers[0];
429 layer->
format = drmformat;
434 layer->
planes[0].
pitch = mpp_frame_get_hor_stride(mppframe);
441 framecontext->
frame = mppframe;
447 if (!
frame->buf[0]) {
455 if (!
frame->hw_frames_ctx) {
462 av_log(avctx,
AV_LOG_ERROR,
"Failed to retrieve the frame buffer, frame is dropped (code = %d)\n",
ret);
463 mpp_frame_deinit(&mppframe);
465 }
else if (
decoder->eos_reached) {
467 }
else if (
ret == MPP_ERR_TIMEOUT) {
475 mpp_frame_deinit(&mppframe);
486 RK_S32 usedslots, freeslots;
540 #define RKMPP_DEC_CLASS(NAME) \
541 static const AVClass rkmpp_##NAME##_dec_class = { \
542 .class_name = "rkmpp_" #NAME "_dec", \
543 .version = LIBAVUTIL_VERSION_INT, \
546 #define RKMPP_DEC(NAME, ID, BSFS) \
547 RKMPP_DEC_CLASS(NAME) \
548 const FFCodec ff_##NAME##_rkmpp_decoder = { \
549 .p.name = #NAME "_rkmpp", \
550 CODEC_LONG_NAME(#NAME " (rkmpp)"), \
551 .p.type = AVMEDIA_TYPE_VIDEO, \
553 .priv_data_size = sizeof(RKMPPDecodeContext), \
554 .init = rkmpp_init_decoder, \
555 .close = rkmpp_close_decoder, \
556 FF_CODEC_RECEIVE_FRAME_CB(rkmpp_receive_frame), \
557 .flush = rkmpp_flush, \
558 .p.priv_class = &rkmpp_##NAME##_dec_class, \
559 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
560 .hw_configs = rkmpp_hw_configs, \
562 .p.wrapper_name = "rkmpp", \
563 .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.
void * ff_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
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.
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
static void * ff_refstruct_alloc_ext(size_t size, unsigned flags, void *opaque, void(*free_cb)(FFRefStructOpaque opaque, void *obj))
A wrapper around ff_refstruct_alloc_ext_c() for the common case of a non-const qualified opaque.
RKMPPDecoder * decoder
RefStruct reference.
static int rkmpp_init_decoder(AVCodecContext *avctx)
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.
RefStruct is an API for creating reference-counted objects with minimal overhead.
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.
#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.
static void rkmpp_release_decoder(FFRefStructOpaque unused, void *obj)
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.
#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 int rkmpp_close_decoder(AVCodecContext *avctx)
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
#define HW_CONFIG_INTERNAL(format)
#define RKMPP_DEC(NAME, ID, BSFS)
#define AV_LOG_INFO
Standard information.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
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.
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.
void ff_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
static void rkmpp_flush(AVCodecContext *avctx)
static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame)