[FFmpeg-devel] [PATCH v3 1/2] libavcodec/libaomenc.c: Support gray input
Ryo Hirafuji
ryo.hirafuji at link-u.co.jp
Tue Apr 7 21:36:38 EEST 2020
James, thank you for your review!
> You can merge these with the AV_PIX_FMT_YUV420P* cases below, doing
> something like
> enccfg->monochrome = avctx->pix_fmt == AV_PIX_FMT_GRAY8;
> and
> enccfg->monochrome = avctx->pix_fmt == AV_PIX_FMT_GRAY10 ||
> avctx->pix_fmt == AV_PIX_FMT_GRAY12;
> to enable monochrome in the gray cases.
It sounds great. Thanks, I will change in patch v4.
Are these meant to all point to the Y plane, or can they be NULL/0? If
> so, then leaving this chunk as it was should AFAIK work.
U plane and V plane will be ignored when "monochorme=1", but it crashes
with SIGSEGV when U plane or V plane is NULL.
So we have to set some valid pointers.
If aom_image is allocated by aom_img_alloc function, U plane and V plane
are allocated.
But we use aom_img_wrap function, so we have to prepare some valid pointers
ourselves.
> + rawimg->planes[AOM_PLANE_Y] = frame->data[0];
> + rawimg->planes[AOM_PLANE_U] = frame->data[1];
> + rawimg->planes[AOM_PLANE_V] = frame->data[2];
> + rawimg->stride[AOM_PLANE_Y] = frame->linesize[0];
> + rawimg->stride[AOM_PLANE_U] = frame->linesize[1];
> + rawimg->stride[AOM_PLANE_V] = frame->linesize[2];
I also tested with this code before, but frame->data[1] or frame->[2]
sometimes becomes NULL or (maybe) invalid pointer for gray data.
(gray doesn't have U and V, so I think it's not strange.)
2020年4月8日(水) 3:23 James Almer <jamrial at gmail.com>:
> On 4/7/2020 3:11 PM, Ryo Hirafuji wrote:
> > From: Ryo Hirafuji <psi at 7io.org>
> >
> > AV1 decoders, libaomdec and libdav1d, both support grayscale image.
> > However, libaomenc does not support it yet.
> > In this patch, I add a grayscale image support also to libaomenc.
> >
> > Fixes ticket #7599
> > ---
> > libavcodec/libaomenc.c | 51 ++++++++++++++++++++++++++++++++++++------
> > 1 file changed, 44 insertions(+), 7 deletions(-)
> >
> > diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
> > index 096aadbe1c..a3c5ae8f54 100644
> > --- a/libavcodec/libaomenc.c
> > +++ b/libavcodec/libaomenc.c
> > @@ -154,7 +154,7 @@ static av_cold void dump_enc_cfg(AVCodecContext
> *avctx,
> > av_log(avctx, level, "aom_codec_enc_cfg\n");
> > av_log(avctx, level, "generic settings\n"
> > " %*s%u\n %*s%u\n %*s%u\n %*s%u\n %*s%u\n"
> > - " %*s%u\n %*s%u\n"
> > + " %*s%u\n %*s%u\n %*s%u\n"
> > " %*s{%u/%u}\n %*s%u\n %*s%d\n %*s%u\n",
> > width, "g_usage:", cfg->g_usage,
> > width, "g_threads:", cfg->g_threads,
> > @@ -163,6 +163,7 @@ static av_cold void dump_enc_cfg(AVCodecContext
> *avctx,
> > width, "g_h:", cfg->g_h,
> > width, "g_bit_depth:", cfg->g_bit_depth,
> > width, "g_input_bit_depth:", cfg->g_input_bit_depth,
> > + width, "monochrome:", cfg->monochrome,
> > width, "g_timebase:", cfg->g_timebase.num,
> cfg->g_timebase.den,
> > width, "g_error_resilient:", cfg->g_error_resilient,
> > width, "g_pass:", cfg->g_pass,
> > @@ -276,6 +277,25 @@ static int set_pix_fmt(AVCodecContext *avctx,
> aom_codec_caps_t codec_caps,
> > AOMContext av_unused *ctx = avctx->priv_data;
> > enccfg->g_bit_depth = enccfg->g_input_bit_depth = 8;
> > switch (avctx->pix_fmt) {
> > + case AV_PIX_FMT_GRAY8:
> > + enccfg->monochrome = 1u;
> > + enccfg->g_profile = FF_PROFILE_AV1_MAIN;
> > + *img_fmt = AOM_IMG_FMT_I420;
> > + return 0;
> > + case AV_PIX_FMT_GRAY10:
> > + case AV_PIX_FMT_GRAY12:
> > + if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) {
> > + enccfg->monochrome = 1u;
> > + enccfg->g_profile =
> > + avctx->pix_fmt == AV_PIX_FMT_GRAY10 ?
> FF_PROFILE_AV1_MAIN
> > + :
> FF_PROFILE_AV1_PROFESSIONAL;
> > + enccfg->g_bit_depth = enccfg->g_input_bit_depth =
> > + avctx->pix_fmt == AV_PIX_FMT_GRAY10 ? 10 : 12;
> > + *img_fmt = AOM_IMG_FMT_I42016;
> > + *flags |= AOM_CODEC_USE_HIGHBITDEPTH;
> > + return 0;
> > + }
> > + break;
>
> You can merge these with the AV_PIX_FMT_YUV420P* cases below, doing
> something like
>
> enccfg->monochrome = avctx->pix_fmt == AV_PIX_FMT_GRAY8;
>
> and
>
> enccfg->monochrome = avctx->pix_fmt == AV_PIX_FMT_GRAY10 ||
> avctx->pix_fmt == AV_PIX_FMT_GRAY12;
>
> to enable monochrome in the gray cases.
>
> > case AV_PIX_FMT_YUV420P:
> > enccfg->g_profile = FF_PROFILE_AV1_MAIN;
> > *img_fmt = AOM_IMG_FMT_I420;
> > @@ -979,12 +999,25 @@ static int aom_encode(AVCodecContext *avctx,
> AVPacket *pkt,
> >
> > if (frame) {
> > rawimg = &ctx->rawimg;
> > - rawimg->planes[AOM_PLANE_Y] = frame->data[0];
> > - rawimg->planes[AOM_PLANE_U] = frame->data[1];
> > - rawimg->planes[AOM_PLANE_V] = frame->data[2];
> > - rawimg->stride[AOM_PLANE_Y] = frame->linesize[0];
> > - rawimg->stride[AOM_PLANE_U] = frame->linesize[1];
> > - rawimg->stride[AOM_PLANE_V] = frame->linesize[2];
> > + if (frame->format == AV_PIX_FMT_GRAY8 ||
> > + frame->format == AV_PIX_FMT_GRAY10 ||
> > + frame->format == AV_PIX_FMT_GRAY12) {
> > + rawimg->monochrome = 1;
> > + rawimg->planes[AOM_PLANE_Y] = frame->data[0];
> > + rawimg->planes[AOM_PLANE_U] = frame->data[0];
> > + rawimg->planes[AOM_PLANE_V] = frame->data[0];
> > + rawimg->stride[AOM_PLANE_Y] = frame->linesize[0];
> > + rawimg->stride[AOM_PLANE_U] = frame->linesize[0];
> > + rawimg->stride[AOM_PLANE_V] = frame->linesize[0];
>
> Are these meant to all point to the Y plane, or can they be NULL/0? If
> so, then leaving this chunk as it was should AFAIK work.
>
> > + } else {
> > + rawimg->monochrome = 0;
> > + rawimg->planes[AOM_PLANE_Y] = frame->data[0];
> > + rawimg->planes[AOM_PLANE_U] = frame->data[1];
> > + rawimg->planes[AOM_PLANE_V] = frame->data[2];
> > + rawimg->stride[AOM_PLANE_Y] = frame->linesize[0];
> > + rawimg->stride[AOM_PLANE_U] = frame->linesize[1];
> > + rawimg->stride[AOM_PLANE_V] = frame->linesize[2];
> > + }
> > timestamp = frame->pts;
> > switch (frame->color_range) {
> > case AVCOL_RANGE_MPEG:
> > @@ -1025,6 +1058,7 @@ static int aom_encode(AVCodecContext *avctx,
> AVPacket *pkt,
> > }
> >
> > static const enum AVPixelFormat av1_pix_fmts[] = {
> > + AV_PIX_FMT_GRAY8,
> > AV_PIX_FMT_YUV420P,
> > AV_PIX_FMT_YUV422P,
> > AV_PIX_FMT_YUV444P,
> > @@ -1032,6 +1066,9 @@ static const enum AVPixelFormat av1_pix_fmts[] = {
> > };
> >
> > static const enum AVPixelFormat av1_pix_fmts_highbd[] = {
> > + AV_PIX_FMT_GRAY8,
> > + AV_PIX_FMT_GRAY10,
> > + AV_PIX_FMT_GRAY12,
> > AV_PIX_FMT_YUV420P,
> > AV_PIX_FMT_YUV422P,
> > AV_PIX_FMT_YUV444P,
> >
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
More information about the ffmpeg-devel
mailing list