mirror of
https://github.com/nyanmisaka/ffmpeg-rockchip.git
synced 2025-09-27 05:09:41 +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;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_colorspace_info(RGAFrameInfo *in_info, const AVFrame *in,
|
static void set_colorspace_info(RGAFrameInfo *in_info,
|
||||||
RGAFrameInfo *out_info, AVFrame *out,
|
enum AVColorSpace in_spc,
|
||||||
int *color_space_mode)
|
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;
|
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 */
|
/* rgb2yuv */
|
||||||
if ((in_info->pix_desc->flags & AV_PIX_FMT_FLAG_RGB) &&
|
if (rgb_in && !rgb_out) {
|
||||||
!(out_info->pix_desc->flags & AV_PIX_FMT_FLAG_RGB)) {
|
|
||||||
/* rgb full -> yuv full/limit */
|
/* rgb full -> yuv full/limit */
|
||||||
if (in->color_range == AVCOL_RANGE_JPEG) {
|
if (in_rng == AVCOL_RANGE_JPEG) {
|
||||||
switch (in->colorspace) {
|
if ((out_rng && *out_rng == AVCOL_RANGE_JPEG) ||
|
||||||
case AVCOL_SPC_BT709:
|
(out_spc && *out_spc == AVCOL_SPC_BT470BG)) {
|
||||||
out->colorspace = AVCOL_SPC_BT709;
|
if (out_spc)
|
||||||
*color_space_mode = 0xb << 8; /* rgb2yuv_709_limit */
|
*out_spc = AVCOL_SPC_BT470BG;
|
||||||
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 (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 */
|
/* yuv2rgb */
|
||||||
if (!(in_info->pix_desc->flags & AV_PIX_FMT_FLAG_RGB) &&
|
else if (!rgb_in && rgb_out) {
|
||||||
(out_info->pix_desc->flags & AV_PIX_FMT_FLAG_RGB)) {
|
|
||||||
/* yuv full/limit -> rgb full */
|
/* yuv full/limit -> rgb full */
|
||||||
switch (in->color_range) {
|
switch (in_rng) {
|
||||||
case AVCOL_RANGE_MPEG:
|
case AVCOL_RANGE_MPEG:
|
||||||
if (in->colorspace == AVCOL_SPC_BT709) {
|
if (in_spc == AVCOL_SPC_BT709)
|
||||||
out->colorspace = AVCOL_SPC_BT709;
|
out_mode = 3 << 0; /* IM_YUV_TO_RGB_BT709_LIMIT */
|
||||||
*color_space_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 */
|
||||||
if (in->colorspace == AVCOL_SPC_BT470BG) {
|
|
||||||
out->colorspace = AVCOL_SPC_BT470BG;
|
|
||||||
*color_space_mode = 1 << 0; /* IM_YUV_TO_RGB_BT601_LIMIT */
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case AVCOL_RANGE_JPEG:
|
case AVCOL_RANGE_JPEG:
|
||||||
#if 0
|
#if 0
|
||||||
if (in->colorspace == AVCOL_SPC_BT709) {
|
if (in_spc == AVCOL_SPC_BT709)
|
||||||
out->colorspace = AVCOL_SPC_BT709;
|
out_mode = 0xc << 8; /* yuv2rgb_709_full */
|
||||||
*color_space_mode = 0xc << 8; /* yuv2rgb_709_full */
|
if (in_spc == AVCOL_SPC_BT470BG)
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
if (in->colorspace == AVCOL_SPC_BT470BG) {
|
out_mode = 2 << 0; /* IM_YUV_TO_RGB_BT601_FULL */
|
||||||
out->colorspace = AVCOL_SPC_BT470BG;
|
|
||||||
*color_space_mode = 2 << 0; /* IM_YUV_TO_RGB_BT601_FULL */
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (*color_space_mode) {
|
if (out_spc)
|
||||||
out->color_trc = AVCOL_TRC_UNSPECIFIED;
|
*out_spc = AVCOL_SPC_RGB;
|
||||||
out->color_primaries = AVCOL_PRI_UNSPECIFIED;
|
if (out_rng)
|
||||||
out->color_range = AVCOL_RANGE_JPEG;
|
*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 */
|
/* yuvj2yuv */
|
||||||
if ((in_info->pix_fmt == AV_PIX_FMT_YUVJ420P ||
|
if ((in_info->pix_fmt == AV_PIX_FMT_YUVJ420P ||
|
||||||
in_info->pix_fmt == AV_PIX_FMT_YUVJ422P) &&
|
in_info->pix_fmt == AV_PIX_FMT_YUVJ422P) && !rgb_out) {
|
||||||
!(out_info->pix_desc->flags & AV_PIX_FMT_FLAG_RGB)) {
|
if (out_rng)
|
||||||
out->color_range = AVCOL_RANGE_JPEG;
|
*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,
|
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;
|
RGAFrame *rga_frame;
|
||||||
AVFilterContext *ctx = inlink->dst;
|
AVFilterContext *ctx = inlink->dst;
|
||||||
@@ -532,7 +544,7 @@ static RGAFrame *submit_frame(RKRGAContext *r, AVFilterLink *inlink,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static RGAFrame *query_frame(RKRGAContext *r, AVFilterLink *outlink,
|
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;
|
AVFilterContext *ctx = outlink->src;
|
||||||
AVFilterLink *inlink = ctx->inputs[0];
|
AVFilterLink *inlink = ctx->inputs[0];
|
||||||
@@ -611,8 +623,29 @@ static RGAFrame *query_frame(RKRGAContext *r, AVFilterLink *outlink,
|
|||||||
if (out_info->uncompact_10b_msb)
|
if (out_info->uncompact_10b_msb)
|
||||||
info.is_10b_compact = info.is_10b_endian = 1;
|
info.is_10b_compact = info.is_10b_endian = 1;
|
||||||
|
|
||||||
if (!pat_preproc)
|
if (!pat_preproc) {
|
||||||
set_colorspace_info(in0_info, in, out_info, out_frame->frame, &info.color_space_mode);
|
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)
|
if (pat_preproc)
|
||||||
rga_set_rect(&info.rect, in1_info->overlay_x, in1_info->overlay_y,
|
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 { \
|
#define PRINT_RGA_INFO(ctx, info, name) do { \
|
||||||
if (info && name) \
|
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", \
|
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->rect.xoffset, info->rect.yoffset, \
|
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)); \
|
info->rect.width, info->rect.height, info->rect.wstride, info->rect.hstride, (info->rect.format >> 8)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
@@ -1290,7 +1323,7 @@ int ff_rkrga_filter_frame(RKRGAContext *r,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* DST */
|
/* 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");
|
av_log(ctx, AV_LOG_ERROR, "Failed to query an output frame\n");
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
@@ -1313,7 +1346,7 @@ int ff_rkrga_filter_frame(RKRGAContext *r,
|
|||||||
FF_INLINK_IDX(inlink_pat));
|
FF_INLINK_IDX(inlink_pat));
|
||||||
return AVERROR(ENOMEM);
|
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");
|
av_log(ctx, AV_LOG_ERROR, "Failed to query an output frame\n");
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user