Skip to content
This repository has been archived by the owner on Mar 6, 2024. It is now read-only.

Commit

Permalink
faster sw conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
boogieeeee committed Apr 16, 2023
1 parent 5dfd208 commit adaeb45
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 20 deletions.
2 changes: 2 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -6796,6 +6796,8 @@ enabled openssl && { { check_pkg_config openssl "openssl >= 3.0.0" ope
enabled pocketsphinx && require_pkg_config pocketsphinx pocketsphinx pocketsphinx/pocketsphinx.h ps_init
enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/rk_mpi.h mpp_create &&
require_pkg_config rockchip_mpp "rockchip_mpp >= 1.3.7" rockchip/rk_mpi.h mpp_create &&
check_lib libyuv libyuv/planar_functions.h SplitUVPlane -lyuv &&
prepend rkmpp_deps "yuv" &&
{ enabled libdrm ||
die "ERROR: rkmpp requires --enable-libdrm"; }
}
Expand Down
43 changes: 23 additions & 20 deletions libavcodec/rkmppdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "libavutil/hwcontext_drm.h"
#include "libavutil/imgutils.h"
#include "libavutil/log.h"
#include "libyuv/planar_functions.h"

#ifndef DRM_FORMAT_NV12_10
#define DRM_FORMAT_NV12_10 fourcc_code('N', 'A', '1', '5')
Expand Down Expand Up @@ -277,18 +278,20 @@ static void rkmpp_release_frame(void *opaque, uint8_t *data)
av_free(desc);
}

static void rkmpp_release_buffer(void *opaque, uint8_t *data)
{
MppFrame mppframe = opaque;
mpp_frame_deinit(&mppframe);
}

static int rkmpp_convert_frame(AVCodecContext *avctx, AVFrame *frame,
MppFrame mppframe, MppBuffer buffer)
{
char *src = mpp_buffer_get_ptr(buffer);
char *dst_y = frame->data[0];
char *dst_u = frame->data[1];
char *dst_v = frame->data[2];
int width = mpp_frame_get_width(mppframe);
int height = mpp_frame_get_height(mppframe);
int hstride = mpp_frame_get_hor_stride(mppframe);
int vstride = mpp_frame_get_ver_stride(mppframe);
int y_pitch = frame->linesize[0];
int u_pitch = frame->linesize[1];
int v_pitch = frame->linesize[2];
int i, j;
Expand All @@ -298,23 +301,24 @@ static int rkmpp_convert_frame(AVCodecContext *avctx, AVFrame *frame,
return -1;
}

av_log(avctx, AV_LOG_WARNING, "Doing slow software conversion\n");

for (i = 0; i < frame->height; i++)
memcpy(dst_y + i * y_pitch, src + i * hstride, frame->width);
//data[0] points to buf[1] where the mppbuffer is referenced for y plane
//so that we can still use y plane without extra copies
//data[1,2] points to allready allocated AVBuffer Pool (buf[0]), we will convert to
//that buffer only u+v planes, which is half the size operation
frame->data[0] = mpp_buffer_get_ptr(buffer);
frame->buf[1] = av_buffer_create(frame->data[0], mpp_buffer_get_size(buffer),
rkmpp_release_buffer, mppframe,
AV_BUFFER_FLAG_READONLY);
if (!frame->buf[1]) {
return AVERROR(ENOMEM);
}
frame->linesize[0] = hstride;
av_log(avctx, AV_LOG_WARNING, "Doing software conversion for uv planes\n");

src += hstride * vstride;

for (i = 0; i < frame->height / 2; i++) {
for (j = 0; j < frame->width; j++) {
dst_u[j] = src[2 * j + 0];
dst_v[j] = src[2 * j + 1];
}
dst_u += u_pitch;
dst_v += v_pitch;
src += hstride;
}

SplitUVPlane(src, hstride, dst_u, u_pitch, dst_v, v_pitch,
(frame->width + 1) >> 1, (frame->height + 1) >> 1);
return 0;
}

Expand Down Expand Up @@ -496,8 +500,7 @@ static int rkmpp_get_frame(AVCodecContext *avctx, AVFrame *frame, int timeout)
frame->top_field_first = ((mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_TOP_FIRST);

if (avctx->pix_fmt != AV_PIX_FMT_DRM_PRIME) {
ret = rkmpp_convert_frame(avctx, frame, mppframe, buffer);
goto out;
return rkmpp_convert_frame(avctx, frame, mppframe, buffer);
}

mppformat = mpp_frame_get_fmt(mppframe);
Expand Down

0 comments on commit adaeb45

Please sign in to comment.