mirror of
https://github.com/nyanmisaka/ffmpeg-rockchip.git
synced 2025-09-26 21:03:43 +08:00
fixup! lavf/rkrga: add RKRGA scale, vpp and overlay filter
refine colorspace conversion handling. Signed-off-by: nyanmisaka <nst799610810@gmail.com>
This commit is contained in:
@@ -258,78 +258,90 @@ static RGAFrame *get_free_frame(RGAFrame **list)
|
||||
return out;
|
||||
}
|
||||
|
||||
static void set_colorspace_info(RGAFrameInfo *in_info, const AVFrame *in,
|
||||
RGAFrameInfo *out_info, AVFrame *out,
|
||||
int *color_space_mode)
|
||||
static void set_colorspace_info(RGAFrameInfo *in_info,
|
||||
enum AVColorSpace in_spc,
|
||||
enum AVColorRange in_rng,
|
||||
RGAFrameInfo *out_info,
|
||||
enum AVColorSpace *out_spc,
|
||||
enum AVColorRange *out_rng,
|
||||
int *color_space_mode,
|
||||
int is_rga2_used)
|
||||
{
|
||||
if (!in_info || !out_info || !in || !out || !color_space_mode)
|
||||
int rgb_in, rgb_out, out_mode = 0;
|
||||
|
||||
if (!in_info || !out_info || !color_space_mode)
|
||||
return;
|
||||
|
||||
*color_space_mode = 0;
|
||||
rgb_in = in_info->pix_desc->flags & AV_PIX_FMT_FLAG_RGB;
|
||||
rgb_out = out_info->pix_desc->flags & AV_PIX_FMT_FLAG_RGB;
|
||||
|
||||
/* rgb2yuv */
|
||||
if ((in_info->pix_desc->flags & AV_PIX_FMT_FLAG_RGB) &&
|
||||
!(out_info->pix_desc->flags & AV_PIX_FMT_FLAG_RGB)) {
|
||||
if (rgb_in && !rgb_out) {
|
||||
/* rgb full -> yuv full/limit */
|
||||
if (in->color_range == AVCOL_RANGE_JPEG) {
|
||||
switch (in->colorspace) {
|
||||
case AVCOL_SPC_BT709:
|
||||
out->colorspace = AVCOL_SPC_BT709;
|
||||
*color_space_mode = 0xb << 8; /* rgb2yuv_709_limit */
|
||||
break;
|
||||
case AVCOL_SPC_BT470BG:
|
||||
out->colorspace = AVCOL_SPC_BT470BG;
|
||||
*color_space_mode = 2 << 2; /* IM_RGB_TO_YUV_BT601_LIMIT */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*color_space_mode) {
|
||||
out->color_trc = AVCOL_TRC_UNSPECIFIED;
|
||||
out->color_primaries = AVCOL_PRI_UNSPECIFIED;
|
||||
out->color_range = AVCOL_RANGE_MPEG;
|
||||
}
|
||||
}
|
||||
if (in_rng == AVCOL_RANGE_JPEG) {
|
||||
if ((out_rng && *out_rng == AVCOL_RANGE_JPEG) ||
|
||||
(out_spc && *out_spc == AVCOL_SPC_BT470BG)) {
|
||||
if (out_spc)
|
||||
*out_spc = AVCOL_SPC_BT470BG;
|
||||
|
||||
if (out_rng && *out_rng == AVCOL_RANGE_JPEG)
|
||||
out_mode = 1 << 2; /* IM_RGB_TO_YUV_BT601_FULL */
|
||||
else {
|
||||
if (out_rng)
|
||||
*out_rng = AVCOL_RANGE_MPEG;
|
||||
out_mode = 2 << 2; /* IM_RGB_TO_YUV_BT601_LIMIT */
|
||||
}
|
||||
} else {
|
||||
if (out_spc)
|
||||
*out_spc = AVCOL_SPC_BT709;
|
||||
if (out_rng)
|
||||
*out_rng = AVCOL_RANGE_MPEG;
|
||||
out_mode = is_rga2_used ? (0xb << 8) /* rgb2yuv_709_limit */
|
||||
: (3 << 2); /* IM_RGB_TO_YUV_BT709_LIMIT */
|
||||
}
|
||||
}
|
||||
if (out_mode)
|
||||
*color_space_mode |= out_mode;
|
||||
}
|
||||
/* yuv2rgb */
|
||||
if (!(in_info->pix_desc->flags & AV_PIX_FMT_FLAG_RGB) &&
|
||||
(out_info->pix_desc->flags & AV_PIX_FMT_FLAG_RGB)) {
|
||||
else if (!rgb_in && rgb_out) {
|
||||
/* yuv full/limit -> rgb full */
|
||||
switch (in->color_range) {
|
||||
switch (in_rng) {
|
||||
case AVCOL_RANGE_MPEG:
|
||||
if (in->colorspace == AVCOL_SPC_BT709) {
|
||||
out->colorspace = AVCOL_SPC_BT709;
|
||||
*color_space_mode = 3 << 0; /* IM_YUV_TO_RGB_BT709_LIMIT */
|
||||
}
|
||||
if (in->colorspace == AVCOL_SPC_BT470BG) {
|
||||
out->colorspace = AVCOL_SPC_BT470BG;
|
||||
*color_space_mode = 1 << 0; /* IM_YUV_TO_RGB_BT601_LIMIT */
|
||||
}
|
||||
if (in_spc == AVCOL_SPC_BT709)
|
||||
out_mode = 3 << 0; /* IM_YUV_TO_RGB_BT709_LIMIT */
|
||||
if (in_spc == AVCOL_SPC_BT470BG)
|
||||
out_mode = 1 << 0; /* IM_YUV_TO_RGB_BT601_LIMIT */
|
||||
break;
|
||||
case AVCOL_RANGE_JPEG:
|
||||
#if 0
|
||||
if (in->colorspace == AVCOL_SPC_BT709) {
|
||||
out->colorspace = AVCOL_SPC_BT709;
|
||||
*color_space_mode = 0xc << 8; /* yuv2rgb_709_full */
|
||||
}
|
||||
if (in_spc == AVCOL_SPC_BT709)
|
||||
out_mode = 0xc << 8; /* yuv2rgb_709_full */
|
||||
if (in_spc == AVCOL_SPC_BT470BG)
|
||||
#endif
|
||||
if (in->colorspace == AVCOL_SPC_BT470BG) {
|
||||
out->colorspace = AVCOL_SPC_BT470BG;
|
||||
*color_space_mode = 2 << 0; /* IM_YUV_TO_RGB_BT601_FULL */
|
||||
}
|
||||
out_mode = 2 << 0; /* IM_YUV_TO_RGB_BT601_FULL */
|
||||
break;
|
||||
}
|
||||
if (*color_space_mode) {
|
||||
out->color_trc = AVCOL_TRC_UNSPECIFIED;
|
||||
out->color_primaries = AVCOL_PRI_UNSPECIFIED;
|
||||
out->color_range = AVCOL_RANGE_JPEG;
|
||||
}
|
||||
if (out_spc)
|
||||
*out_spc = AVCOL_SPC_RGB;
|
||||
if (out_rng)
|
||||
*out_rng = AVCOL_RANGE_JPEG;
|
||||
if (out_mode)
|
||||
*color_space_mode |= out_mode;
|
||||
}
|
||||
/* passthrough */
|
||||
else {
|
||||
if (out_spc)
|
||||
*out_spc = in_spc;
|
||||
if (out_rng)
|
||||
*out_rng = in_rng;
|
||||
}
|
||||
|
||||
/* yuvj2yuv */
|
||||
if ((in_info->pix_fmt == AV_PIX_FMT_YUVJ420P ||
|
||||
in_info->pix_fmt == AV_PIX_FMT_YUVJ422P) &&
|
||||
!(out_info->pix_desc->flags & AV_PIX_FMT_FLAG_RGB)) {
|
||||
out->color_range = AVCOL_RANGE_JPEG;
|
||||
in_info->pix_fmt == AV_PIX_FMT_YUVJ422P) && !rgb_out) {
|
||||
if (out_rng)
|
||||
*out_rng = AVCOL_RANGE_JPEG;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,7 +403,7 @@ static int verify_rga_frame_info_io_dynamic(AVFilterContext *avctx,
|
||||
}
|
||||
|
||||
static RGAFrame *submit_frame(RKRGAContext *r, AVFilterLink *inlink,
|
||||
AVFrame *picref, int do_overlay, int pat_preproc)
|
||||
const AVFrame *picref, int do_overlay, int pat_preproc)
|
||||
{
|
||||
RGAFrame *rga_frame;
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
@@ -532,7 +544,7 @@ static RGAFrame *submit_frame(RKRGAContext *r, AVFilterLink *inlink,
|
||||
}
|
||||
|
||||
static RGAFrame *query_frame(RKRGAContext *r, AVFilterLink *outlink,
|
||||
const AVFrame *in, int pat_preproc)
|
||||
const AVFrame *in, const AVFrame *picref_pat, int pat_preproc)
|
||||
{
|
||||
AVFilterContext *ctx = outlink->src;
|
||||
AVFilterLink *inlink = ctx->inputs[0];
|
||||
@@ -611,8 +623,29 @@ static RGAFrame *query_frame(RKRGAContext *r, AVFilterLink *outlink,
|
||||
if (out_info->uncompact_10b_msb)
|
||||
info.is_10b_compact = info.is_10b_endian = 1;
|
||||
|
||||
if (!pat_preproc)
|
||||
set_colorspace_info(in0_info, in, out_info, out_frame->frame, &info.color_space_mode);
|
||||
if (!pat_preproc) {
|
||||
int is_rga2_used = r->is_rga2_used || out_info->scheduler_core == (out_info->scheduler_core & 0xc);
|
||||
|
||||
#ifdef RGA_NORMAL_DST_FULL_CSC_FIXUP
|
||||
if (in1_info && picref_pat) {
|
||||
enum AVColorSpace pat_colorspace = picref_pat->colorspace;
|
||||
enum AVColorRange pat_color_range = picref_pat->color_range;
|
||||
/* yuv2rgb src->pat */
|
||||
set_colorspace_info(in0_info, in->colorspace, in->color_range,
|
||||
in1_info, &pat_colorspace, &pat_color_range,
|
||||
&info.color_space_mode, is_rga2_used);
|
||||
/* rgb2yuv pat->dst */
|
||||
set_colorspace_info(in1_info, pat_colorspace, pat_color_range,
|
||||
out_info, &out_frame->frame->colorspace, &out_frame->frame->color_range,
|
||||
&info.color_space_mode, is_rga2_used);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
set_colorspace_info(in0_info, in->colorspace, in->color_range,
|
||||
out_info, &out_frame->frame->colorspace, &out_frame->frame->color_range,
|
||||
&info.color_space_mode, is_rga2_used);
|
||||
}
|
||||
}
|
||||
|
||||
if (pat_preproc)
|
||||
rga_set_rect(&info.rect, in1_info->overlay_x, in1_info->overlay_y,
|
||||
@@ -1223,8 +1256,8 @@ static int call_rkrga_blit(AVFilterContext *avctx,
|
||||
|
||||
#define PRINT_RGA_INFO(ctx, info, name) do { \
|
||||
if (info && name) \
|
||||
av_log(ctx, AV_LOG_DEBUG, "RGA %s | fd:%d mmu:%d rd_mode:%d | x:%d y:%d w:%d h:%d ws:%d hs:%d fmt:0x%x\n", \
|
||||
name, info->fd, info->mmuFlag, (info->rd_mode >> 1), info->rect.xoffset, info->rect.yoffset, \
|
||||
av_log(ctx, AV_LOG_DEBUG, "RGA %s | fd:%d mmu:%d rd:%d csc:%d | x:%d y:%d w:%d h:%d ws:%d hs:%d fmt:0x%x\n", \
|
||||
name, info->fd, info->mmuFlag, (info->rd_mode >> 1), info->color_space_mode, info->rect.xoffset, info->rect.yoffset, \
|
||||
info->rect.width, info->rect.height, info->rect.wstride, info->rect.hstride, (info->rect.format >> 8)); \
|
||||
} while (0)
|
||||
|
||||
@@ -1290,7 +1323,7 @@ int ff_rkrga_filter_frame(RKRGAContext *r,
|
||||
}
|
||||
|
||||
/* DST */
|
||||
if (!(dst_frame = query_frame(r, outlink, src_frame->frame, 0))) {
|
||||
if (!(dst_frame = query_frame(r, outlink, src_frame->frame, picref_pat, 0))) {
|
||||
av_log(ctx, AV_LOG_ERROR, "Failed to query an output frame\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
@@ -1313,7 +1346,7 @@ int ff_rkrga_filter_frame(RKRGAContext *r,
|
||||
FF_INLINK_IDX(inlink_pat));
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
if (!(pat_out = query_frame(r, outlink, picref_pat, 1))) {
|
||||
if (!(pat_out = query_frame(r, outlink, picref_pat, NULL, 1))) {
|
||||
av_log(ctx, AV_LOG_ERROR, "Failed to query an output frame\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
Reference in New Issue
Block a user