Message ID | 20200407181157.74792-1-ryo.hirafuji@gmail.com |
---|---|
State | Superseded |
Headers | show |
Series | [FFmpeg-devel,v3,1/2] libavcodec/libaomenc.c: Support gray input | expand |
Context | Check | Description |
---|---|---|
andriy/ffmpeg-patchwork | success | Make fate finished |
On 4/7/2020 3:11 PM, Ryo Hirafuji wrote: > From: Ryo Hirafuji <psi@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, >
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@gmail.com>: > On 4/7/2020 3:11 PM, Ryo Hirafuji wrote: > > From: Ryo Hirafuji <psi@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@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
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; 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]; + } 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,
From: Ryo Hirafuji <psi@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(-)