mirror of
https://github.com/nyanmisaka/ffmpeg-rockchip.git
synced 2025-09-26 21:03:43 +08:00
lavc/rkmppenc: add chroma_fmt option for MJPEG encoder
Signed-off-by: nyanmisaka <nst799610810@gmail.com>
This commit is contained in:
@@ -73,9 +73,19 @@ static MppFrameFormat rkmpp_get_mpp_fmt_mjpeg(enum AVPixelFormat pix_fmt)
|
||||
switch (pix_fmt) {
|
||||
case AV_PIX_FMT_YUVJ420P:
|
||||
case AV_PIX_FMT_YUV420P: return MPP_FMT_YUV420P;
|
||||
case AV_PIX_FMT_YUVJ422P:
|
||||
case AV_PIX_FMT_YUV422P: return MPP_FMT_YUV422P; /* RK3576+ only */
|
||||
case AV_PIX_FMT_YUVJ444P:
|
||||
case AV_PIX_FMT_YUV444P: return MPP_FMT_YUV444P; /* RK3576+ only */
|
||||
case AV_PIX_FMT_NV12: return MPP_FMT_YUV420SP;
|
||||
case AV_PIX_FMT_NV21: return MPP_FMT_YUV420SP_VU; /* RK3576+ only */
|
||||
case AV_PIX_FMT_NV16: return MPP_FMT_YUV422SP; /* RK3576+ only */
|
||||
case AV_PIX_FMT_NV24: return MPP_FMT_YUV444SP; /* RK3576+ only */
|
||||
case AV_PIX_FMT_YUYV422: return MPP_FMT_YUV422_YUYV;
|
||||
case AV_PIX_FMT_UYVY422: return MPP_FMT_YUV422_UYVY;
|
||||
case AV_PIX_FMT_YVYU422: return MPP_FMT_YUV422_YVYU; /* RK3576+ only */
|
||||
|
||||
/* RGB: pre-RK3576 only */
|
||||
case AV_PIX_FMT_RGB444BE: return MPP_FMT_RGB444;
|
||||
case AV_PIX_FMT_BGR444BE: return MPP_FMT_BGR444;
|
||||
case AV_PIX_FMT_RGB555BE: return MPP_FMT_RGB555;
|
||||
@@ -105,6 +115,38 @@ static uint32_t rkmpp_get_drm_afbc_format(MppFrameFormat mpp_fmt)
|
||||
}
|
||||
}
|
||||
|
||||
static MppFrameChromaFormat rkmpp_fix_chroma_fmt(int chroma_fmt,
|
||||
enum AVPixelFormat pix_fmt)
|
||||
{
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
|
||||
int log2_chroma_sum = desc->log2_chroma_w + desc->log2_chroma_h;
|
||||
int is_yuv = !(desc->flags & AV_PIX_FMT_FLAG_RGB) &&
|
||||
desc->nb_components >= 2;
|
||||
|
||||
if (!is_yuv)
|
||||
return MPP_CHROMA_UNSPECIFIED;
|
||||
|
||||
switch (chroma_fmt) {
|
||||
case -1:
|
||||
return log2_chroma_sum == 0 ? MPP_CHROMA_444 :
|
||||
log2_chroma_sum == 1 ? MPP_CHROMA_422 :
|
||||
MPP_CHROMA_UNSPECIFIED;
|
||||
case MPP_CHROMA_400:
|
||||
return chroma_fmt;
|
||||
case MPP_CHROMA_420:
|
||||
return log2_chroma_sum <= 2 ?
|
||||
chroma_fmt : MPP_CHROMA_UNSPECIFIED;
|
||||
case MPP_CHROMA_422:
|
||||
return log2_chroma_sum <= 1 ?
|
||||
chroma_fmt : MPP_CHROMA_UNSPECIFIED;
|
||||
case MPP_CHROMA_444:
|
||||
return log2_chroma_sum == 0 ?
|
||||
chroma_fmt : MPP_CHROMA_UNSPECIFIED;
|
||||
default:
|
||||
return MPP_CHROMA_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
static int get_byte_stride(const AVDRMObjectDescriptor *object,
|
||||
const AVDRMLayerDescriptor *layer,
|
||||
int is_rgb, int is_planar,
|
||||
@@ -310,6 +352,12 @@ static int rkmpp_set_enc_cfg_prep(AVCodecContext *avctx, AVFrame *frame)
|
||||
mpp_enc_cfg_set_s32(cfg, "prep:colorrange", AVCOL_RANGE_JPEG);
|
||||
}
|
||||
|
||||
if (avctx->codec_id == AV_CODEC_ID_MJPEG) {
|
||||
/* always output full range if the MJPEG encoder supports CSC */
|
||||
mpp_enc_cfg_set_s32(cfg, "prep:range_out", AVCOL_RANGE_JPEG);
|
||||
mpp_enc_cfg_set_s32(cfg, "prep:format_out", rkmpp_fix_chroma_fmt(r->chroma_fmt, r->pix_fmt));
|
||||
}
|
||||
|
||||
if (is_afbc) {
|
||||
const AVDRMLayerDescriptor *layer = &drm_desc->layers[0];
|
||||
uint32_t drm_afbc_fmt = rkmpp_get_drm_afbc_format(mpp_fmt);
|
||||
@@ -368,6 +416,12 @@ static int rkmpp_set_enc_cfg(AVCodecContext *avctx)
|
||||
mpp_enc_cfg_set_s32(cfg, "prep:colorrange", AVCOL_RANGE_JPEG);
|
||||
}
|
||||
|
||||
if (avctx->codec_id == AV_CODEC_ID_MJPEG) {
|
||||
/* always output full range if the MJPEG encoder supports CSC */
|
||||
mpp_enc_cfg_set_s32(cfg, "prep:range_out", AVCOL_RANGE_JPEG);
|
||||
mpp_enc_cfg_set_s32(cfg, "prep:format_out", rkmpp_fix_chroma_fmt(r->chroma_fmt, r->pix_fmt));
|
||||
}
|
||||
|
||||
if (avctx->framerate.den > 0 && avctx->framerate.num > 0)
|
||||
av_reduce(&fps_num, &fps_den, avctx->framerate.num, avctx->framerate.den, 65535);
|
||||
else
|
||||
|
@@ -82,6 +82,7 @@ typedef struct RKMPPEncContext {
|
||||
int dct8x8;
|
||||
int udu_sei;
|
||||
int prefix_mode;
|
||||
int chroma_fmt;
|
||||
} RKMPPEncContext;
|
||||
|
||||
static const AVRational mpp_tb = { 1, 1000000 };
|
||||
@@ -190,6 +191,13 @@ static const AVOption mjpeg_options[] = {
|
||||
{ .i64 = -1 }, -1, 99, VE, "qp_max" }, \
|
||||
{ "qp_min", "Set the min QP/Q_Factor value", OFFSET(qp_min), AV_OPT_TYPE_INT, \
|
||||
{ .i64 = -1 }, -1, 99, VE, "qp_min" }, \
|
||||
{ "chroma_fmt", "Specify the output chroma format for down subsampling", OFFSET(chroma_fmt), AV_OPT_TYPE_INT, \
|
||||
{ .i64 = MPP_CHROMA_UNSPECIFIED }, -1, MPP_CHROMA_444, VE, .unit = "chroma_fmt" }, \
|
||||
{ "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, 0, 0, VE, .unit = "chroma_fmt" },
|
||||
{ "400", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MPP_CHROMA_400 }, 0, 0, VE, .unit = "chroma_fmt" },
|
||||
{ "420", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MPP_CHROMA_420 }, 0, 0, VE, .unit = "chroma_fmt" },
|
||||
{ "422", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MPP_CHROMA_422 }, 0, 0, VE, .unit = "chroma_fmt" },
|
||||
{ "444", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MPP_CHROMA_444 }, 0, 0, VE, .unit = "chroma_fmt" },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
@@ -225,9 +233,19 @@ static const enum AVPixelFormat rkmpp_enc_pix_fmts_h26x[] = {
|
||||
static const enum AVPixelFormat rkmpp_enc_pix_fmts_mjpeg[] = {
|
||||
AV_PIX_FMT_YUV420P,
|
||||
AV_PIX_FMT_YUVJ420P,
|
||||
AV_PIX_FMT_YUV422P, /* RK3576+ only */
|
||||
AV_PIX_FMT_YUVJ422P,
|
||||
AV_PIX_FMT_YUV444P, /* RK3576+ only */
|
||||
AV_PIX_FMT_YUVJ444P,
|
||||
AV_PIX_FMT_NV12,
|
||||
AV_PIX_FMT_NV21, /* RK3576+ only */
|
||||
AV_PIX_FMT_NV16, /* RK3576+ only */
|
||||
AV_PIX_FMT_NV24, /* RK3576+ only */
|
||||
AV_PIX_FMT_YUYV422,
|
||||
AV_PIX_FMT_UYVY422,
|
||||
AV_PIX_FMT_YVYU422, /* RK3576+ only */
|
||||
|
||||
/* RGB: pre-RK3576 only */
|
||||
AV_PIX_FMT_RGB444BE,
|
||||
AV_PIX_FMT_BGR444BE,
|
||||
AV_PIX_FMT_RGB555BE,
|
||||
|
Reference in New Issue
Block a user