Skip to content

Commit

Permalink
HACK: avcodec/rkmppdec: Alloc contig frame buffer when using default …
Browse files Browse the repository at this point in the history
…get_buffer2

Currently the librga only supports contig buffers.

The default get_buffer2 would use different buffers for planes, so we
need to replace them with contig one to take advantage of RGA 2D accel.

Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
  • Loading branch information
JeffyCN committed May 21, 2021
1 parent 2ddb699 commit 72ee109
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions libavcodec/rkmppdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ typedef struct {
AVPacket packet;
AVBufferRef *frames_ref;
AVBufferRef *device_ref;

AVBufferPool *pool;
int pool_size;
} RKMPPDecoder;

typedef struct {
Expand Down Expand Up @@ -95,6 +98,9 @@ static int rkmpp_close_decoder(AVCodecContext *avctx)

av_packet_unref(&decoder->packet);

if (decoder->pool)
av_buffer_pool_uninit(&decoder->pool);

av_buffer_unref(&rk_context->decoder_ref);
return 0;
}
Expand Down Expand Up @@ -442,6 +448,44 @@ static int rkmpp_get_frame(AVCodecContext *avctx, AVFrame *frame, int timeout)
goto fail;
}

// drm_prime does support internal frame allocation.
if (avctx->pix_fmt != AV_PIX_FMT_DRM_PRIME) {
if (avctx->get_buffer2 != avcodec_default_get_buffer2) {
ff_get_buffer(avctx, frame, 0);
} else {
// the avcodec_default_get_buffer2 would use different
// buffers for planes, let's alloc config buffer instead.
// TODO: support setting y/u/v address in librga?
// TODO: or replace with custom get_buffer2
int size = mpp_frame_get_buf_size(mppframe);
int hstride = mpp_frame_get_hor_stride(mppframe);
int vstride = mpp_frame_get_ver_stride(mppframe);

if (decoder->pool_size != size) {
if (decoder->pool)
av_buffer_pool_uninit(&decoder->pool);

decoder->pool = av_buffer_pool_init(size, NULL);
decoder->pool_size = size;
}

// free old buffers
av_buffer_unref(&frame->buf[0]);
av_buffer_unref(&frame->buf[1]);
av_buffer_unref(&frame->buf[2]);

frame->buf[0] = av_buffer_pool_get(decoder->pool);

frame->linesize[0] = hstride;
frame->linesize[1] = hstride / 2;
frame->linesize[2] = hstride / 2;

frame->data[0] = frame->buf[0]->data;
frame->data[1] = frame->data[0] + hstride * vstride;
frame->data[2] = frame->data[1] + hstride * vstride / 4;
}
}

// setup general frame fields
frame->format = avctx->pix_fmt;
frame->width = mpp_frame_get_width(mppframe);
Expand Down

0 comments on commit 72ee109

Please sign in to comment.