From 474232dff26df2188fe37287aeb7834f6d3853d1 Mon Sep 17 00:00:00 2001 From: "arvin.zhu" Date: Thu, 29 Sep 2022 16:05:09 +0800 Subject: [PATCH] ffmpeg: add pixel foramt add pixel format option for codecs of VPU Signed-off-by: arvin.zhu --- libavcodec/omx.c | 19 ++++++++++++++++--- libavcodec/omxdec.c | 43 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/libavcodec/omx.c b/libavcodec/omx.c index 1c4179f..6976884 100755 --- a/libavcodec/omx.c +++ b/libavcodec/omx.c @@ -456,18 +456,31 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role) break; } } + if (s->color_format == 0) { av_log(avctx, AV_LOG_ERROR, "No supported pixel formats (%d formats available)\n", i); return AVERROR_UNKNOWN; } - + av_log(avctx, AV_LOG_VERBOSE, "OMX setting pixel_format:%s\n", av_get_pix_fmt_name(avctx->pix_fmt)); in_port_params.bEnabled = OMX_TRUE; in_port_params.bPopulated = OMX_FALSE; in_port_params.eDomain = OMX_PortDomainVideo; in_port_params.format.video.pNativeRender = NULL; in_port_params.format.video.bFlagErrorConcealment = OMX_FALSE; - in_port_params.format.video.eColorFormat = s->color_format; + switch (avctx->pix_fmt) { + case AV_PIX_FMT_NV12: + in_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + break; + case AV_PIX_FMT_NV21: + in_port_params.format.video.eColorFormat = OMX_COLOR_FormatYVU420SemiPlanar; + break; + case AV_PIX_FMT_YUV420P: + out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; + break; + default: + return AVERROR_OPTION_NOT_FOUND; + } s->stride = avctx->width; s->plane_size = avctx->height; // If specific codecs need to manually override the stride/plane_size, @@ -986,7 +999,7 @@ static const AVOption options_hevc[] = { }; static const enum AVPixelFormat omx_encoder_pix_fmts[] = { - AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE + AV_PIX_FMT_YUV420P, AV_PIX_FMT_NV12, AV_PIX_FMT_NV21, AV_PIX_FMT_NONE }; static const AVClass omx_mpeg4enc_class = { diff --git a/libavcodec/omxdec.c b/libavcodec/omxdec.c index 20298b8..074ff4a 100755 --- a/libavcodec/omxdec.c +++ b/libavcodec/omxdec.c @@ -481,7 +481,7 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role) //OMX_VIDEO_PARAM_BITRATETYPE vid_param_bitrate = { 0 }; OMX_ERRORTYPE err; int i; - +av_log(avctx, AV_LOG_VERBOSE, "OMX avctx pixel_format:%s\n", av_get_pix_fmt_name(avctx->pix_fmt)); s->version.s.nVersionMajor = 1; s->version.s.nVersionMinor = 1; s->version.s.nRevision = 2; @@ -571,16 +571,46 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role) out_port_params.format.video.nBitrate = avctx->bit_rate; out_port_params.format.video.xFramerate = in_port_params.format.video.xFramerate; out_port_params.format.video.bFlagErrorConcealment = OMX_FALSE; + av_log(avctx, AV_LOG_VERBOSE, "OMX setting pixel_format:%s\n", s->pixel_format); if (avctx->codec->id == AV_CODEC_ID_MPEG4) out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; - else if (avctx->codec->id == AV_CODEC_ID_H264) + else if (avctx->codec->id == AV_CODEC_ID_H264) { out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; - else if (avctx->codec->id == AV_CODEC_ID_HEVC) + + switch (av_get_pix_fmt(s->pixel_format)) { + case AV_PIX_FMT_NV12: + out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + break; + case AV_PIX_FMT_NV21: + out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYVU420SemiPlanar; + break; + case AV_PIX_FMT_YUV420P: + out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; + break; + default: + return AVERROR_OPTION_NOT_FOUND; + } + } + else if (avctx->codec->id == AV_CODEC_ID_HEVC) { out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingHEVC; + + switch (av_get_pix_fmt(s->pixel_format)) { + case AV_PIX_FMT_NV12: + out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + break; + case AV_PIX_FMT_NV21: + out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYVU420SemiPlanar; + break; + case AV_PIX_FMT_YUV420P: + out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; + break; + default: + return AVERROR_OPTION_NOT_FOUND; + } + } else if (avctx->codec->id == AV_CODEC_ID_MJPEG){ out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingMJPEG; - av_log(avctx, AV_LOG_VERBOSE, "OMX_pixel_format:%s\n", s->pixel_format); switch (av_get_pix_fmt(s->pixel_format)) { case AV_PIX_FMT_NV12: out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; @@ -610,7 +640,7 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role) out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV444Planar; break; default: - out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; + return AVERROR_OPTION_NOT_FOUND; } } @@ -991,6 +1021,7 @@ static const AVOption options[] = { { "baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_BASELINE }, 0, 0, VE, "profile" }, { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_MAIN }, 0, 0, VE, "profile" }, { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_HIGH }, 0, 0, VE, "profile" }, + { "omx_pix_fmt", "Set the decoding pixel format for h264_omx decoder. The following formats are supported: yuv420p, nv12, nv21.", OFFSET(pixel_format), AV_OPT_TYPE_STRING, { .str = "yuv420p" }, 0, 0, VD }, { NULL } }; @@ -998,6 +1029,7 @@ static const AVOption options_hevc[] = { { "omx_libname", "OpenMAX library name", OFFSET(libname), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE }, { "omx_libprefix", "OpenMAX library prefix", OFFSET(libprefix), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE }, { "zerocopy", "Try to avoid copying input frames if possible", OFFSET(input_zerocopy), AV_OPT_TYPE_INT, { .i64 = CONFIG_OMX_RPI }, 0, 1, VE }, + { "omx_pix_fmt", "Set the decoding pixel format for hevc_omx decoder. The following formats are supported: yuv420p, nv12, nv21.", OFFSET(pixel_format), AV_OPT_TYPE_STRING, { .str = "yuv420p" }, 0, 0, VD }, { NULL }, }; @@ -1006,7 +1038,6 @@ static const AVOption options_mjpeg[] = { { "omx_libprefix", "OpenMAX library prefix", OFFSET(libprefix), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE }, { "zerocopy", "Try to avoid copying input frames if possible", OFFSET(input_zerocopy), AV_OPT_TYPE_INT, { .i64 = CONFIG_OMX_RPI }, 0, 1, VD }, { "omx_pix_fmt", "Set the decoding pixel format for mjpeg_omx decoder. The following formats are supported: yuv420p, nv12, nv21, nv16, yuv422p, yuyv422, yvyu422, uyvy422, yuv444p.", OFFSET(pixel_format), AV_OPT_TYPE_STRING, { .str = "yuv420p" }, 0, 0, VD }, - { NULL }, }; -- 2.17.1