From e3382dff689c871aa64995213afac23cc4505cf6 Mon Sep 17 00:00:00 2001 From: "arvin.zhu" Date: Fri, 14 Oct 2022 16:54:53 +0800 Subject: [PATCH] FFmpeg:omx: add scale option for omx add scale option for omx decoder Signed-off-by: arvin.zhu --- ...-FFmpeg-omx-add-scale-option-for-omx.patch | 209 ++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 package/ffmpeg/0016-FFmpeg-omx-add-scale-option-for-omx.patch diff --git a/package/ffmpeg/0016-FFmpeg-omx-add-scale-option-for-omx.patch b/package/ffmpeg/0016-FFmpeg-omx-add-scale-option-for-omx.patch new file mode 100644 index 00000000..072fad20 --- /dev/null +++ b/package/ffmpeg/0016-FFmpeg-omx-add-scale-option-for-omx.patch @@ -0,0 +1,209 @@ +From 246a5308151416e99dbe53ad52d415abdfb6df29 Mon Sep 17 00:00:00 2001 +From: "arvin.zhu" +Date: Fri, 14 Oct 2022 16:50:55 +0800 +Subject: [PATCH] FFmpeg:omx: add scale option for omx + +add scale option for omx decoder + +Signed-off-by: arvin.zhu +--- + libavcodec/omx.c | 4 +- + libavcodec/omxdec.c | 92 +++++++++++++++++++++++++++------------------ + 2 files changed, 58 insertions(+), 38 deletions(-) + +diff --git a/libavcodec/omx.c b/libavcodec/omx.c +index 6976884..77012ce 100755 +--- a/libavcodec/omx.c ++++ b/libavcodec/omx.c +@@ -1,6 +1,6 @@ + /* +- * OMX Video decoder +- * Copyright (C) 2018-2022 Starfive Technology ++ * OMX Video encoder ++ * Copyright (C) 2011 Martin Storsjo + * + * This file is part of FFmpeg. + * +diff --git a/libavcodec/omxdec.c b/libavcodec/omxdec.c +index 0957605..87e5a1a 100755 +--- a/libavcodec/omxdec.c ++++ b/libavcodec/omxdec.c +@@ -1,6 +1,6 @@ + /* +- * OMX Video encoder +- * Copyright (C) 2011 Martin Storsjo ++ * OMX Video decoder ++ * Copyright (C) 2018-2022 Starfive Technology + * + * This file is part of FFmpeg. + * +@@ -274,6 +274,9 @@ typedef struct OMXCodecContext { + uint8_t *output_buf; + int output_buf_size; + ++ OMX_U32 scale_width; ++ OMX_U32 scale_height; ++ + int input_zerocopy; + int profile; + char *pixel_format; /**< Set by a private option. */ +@@ -481,7 +484,6 @@ 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; +@@ -564,8 +566,6 @@ av_log(avctx, AV_LOG_VERBOSE, "OMX avctx pixel_format:%s\n", av_get_pix_fmt_name + out_port_params.eDomain = OMX_PortDomainVideo; + out_port_params.format.video.pNativeRender = NULL; + out_port_params.format.video.bFlagErrorConcealment = OMX_FALSE; +- out_port_params.format.video.nFrameWidth = avctx->width; +- out_port_params.format.video.nFrameHeight = avctx->height; + out_port_params.format.video.nStride = 0; + out_port_params.format.video.nSliceHeight = 0; + out_port_params.format.video.nBitrate = avctx->bit_rate; +@@ -576,41 +576,29 @@ av_log(avctx, AV_LOG_VERBOSE, "OMX avctx pixel_format:%s\n", av_get_pix_fmt_name + out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + else if (avctx->codec->id == AV_CODEC_ID_H264) { + out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; +- +- 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; + ++ /* Set Scale config setting*/ ++ if (s->scale_width || s->scale_height) { ++ av_log(avctx, AV_LOG_TRACE, "mjpeg decoder: scaling width: %ld scaling height: %ld .\n", s->scale_width, s->scale_height); ++ OMX_CONFIG_SCALEFACTORTYPE ScaleConfig; ++ INIT_STRUCT(ScaleConfig); ++ ScaleConfig.nPortIndex = 1; ++ OMX_GetConfig(s->handle, OMX_IndexConfigCommonScale, &ScaleConfig); ++ /* in Q16 format */ ++ ScaleConfig.xWidth = (1 << 16) >> (s->scale_width & 0x3); ++ ScaleConfig.xHeight = (1 << 16) >> (s->scale_height & 0x3); ++ OMX_SetConfig(s->handle, OMX_IndexConfigCommonScale, &ScaleConfig); ++ } else { ++ out_port_params.format.video.nFrameWidth = avctx->width; ++ out_port_params.format.video.nFrameHeight = avctx->height; ++ } ++ + switch (av_get_pix_fmt(s->pixel_format)) { + case AV_PIX_FMT_NV12: + out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; +@@ -643,6 +631,35 @@ av_log(avctx, AV_LOG_VERBOSE, "OMX avctx pixel_format:%s\n", av_get_pix_fmt_name + return AVERROR_OPTION_NOT_FOUND; + } + } ++ if (avctx->codec->id == AV_CODEC_ID_H264 || avctx->codec->id == AV_CODEC_ID_HEVC) { ++ /* Set Scale config setting*/ ++ if ((s->scale_width != 0) && ((s->scale_width < avctx->width/8) || ++ (s->scale_width > avctx->width) || (s->scale_width % 8 != 0))) { ++ av_log(avctx, AV_LOG_ERROR, "scale_width: Invalid scale parameter\n"); ++ return AVERROR_INVALIDDATA; ++ } ++ if ((s->scale_height != 0) && ((s->scale_height < avctx->height/8) || ++ (s->scale_height > avctx->height) || (s->scale_height % 8 != 0))) { ++ av_log(avctx, AV_LOG_ERROR, "scale_height: Invalid scale parameter\n"); ++ return AVERROR_INVALIDDATA; ++ } ++ out_port_params.format.video.nFrameWidth = s->scale_width ? s->scale_width : avctx->width; ++ out_port_params.format.video.nFrameHeight = s->scale_height ? s->scale_height : avctx->height; ++ ++ 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; ++ } ++ } + + err = OMX_SetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params); + CHECK(err); +@@ -650,10 +667,8 @@ av_log(avctx, AV_LOG_VERBOSE, "OMX avctx pixel_format:%s\n", av_get_pix_fmt_name + CHECK(err); + s->num_out_buffers = out_port_params.nBufferCountActual; + +- + err = OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateIdle, NULL); + CHECK(err); +- + s->in_buffer_headers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_in_buffers); + s->free_in_buffers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_in_buffers); + s->out_buffer_headers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_out_buffers); +@@ -674,7 +689,6 @@ av_log(avctx, AV_LOG_VERBOSE, "OMX avctx pixel_format:%s\n", av_get_pix_fmt_name + err = OMX_AllocateBuffer(s->handle, &s->out_buffer_headers[i], s->out_port, s, out_port_params.nBufferSize); + CHECK(err); + s->num_out_buffers = i; +- + if (wait_for_state(s, OMX_StateIdle) < 0) { + av_log(avctx, AV_LOG_ERROR, "Didn't get OMX_StateIdle\n"); + return AVERROR_UNKNOWN; +@@ -1022,6 +1036,8 @@ static const AVOption options[] = { + { "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 }, ++ { "scale_width", "Set the scaling width for omx (Only zoom out is support, ceil 8(width/8) and minimum 1/8)", OFFSET(scale_width), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VD }, ++ { "scale_height", "Set the scaling height for omx (Only zoom out is support, ceil 8(height/8) and minimum 1/8)", OFFSET(scale_height), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VD }, + { NULL } + }; + +@@ -1030,6 +1046,8 @@ static const AVOption options_hevc[] = { + { "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 }, ++ { "scale_width", "Set the scaling width for omx (Only zoom out is support, ceil 8(width/8) and minimum 1/8)", OFFSET(scale_width), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VD }, ++ { "scale_height", "Set the scaling height for omx (Only zoom out is support, ceil 8(height/8) and minimum 1/8)", OFFSET(scale_height), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VD }, + { NULL }, + }; + +@@ -1038,6 +1056,8 @@ 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 }, ++ { "scale_width", "Set the scaling width for omx (Only zoom out is support, Horizontal downscale: 0(none), 1(1/2), 2(1/4), 3(1/8)) and minimum 1/8)", OFFSET(scale_width), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 3, VD }, ++ { "scale_height", "Set the scaling height for omx (Only zoom out is support, Vertical downscale: 0(none), 1(1/2), 2(1/4), 3(1/8)) and minimum 1/8)", OFFSET(scale_height), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 3, VD }, + { NULL }, + }; + +-- +2.17.1 +