0016-FFmpeg-omx-add-scale-option-for-omx.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. From 246a5308151416e99dbe53ad52d415abdfb6df29 Mon Sep 17 00:00:00 2001
  2. From: "arvin.zhu" <arvin.zhu@starfivetech.com>
  3. Date: Fri, 14 Oct 2022 16:50:55 +0800
  4. Subject: [PATCH] FFmpeg:omx: add scale option for omx
  5. add scale option for omx decoder
  6. Signed-off-by: arvin.zhu <arvin.zhu@starfivetech.com>
  7. ---
  8. libavcodec/omx.c | 4 +-
  9. libavcodec/omxdec.c | 92 +++++++++++++++++++++++++++------------------
  10. 2 files changed, 58 insertions(+), 38 deletions(-)
  11. diff --git a/libavcodec/omx.c b/libavcodec/omx.c
  12. index 6976884..77012ce 100755
  13. --- a/libavcodec/omx.c
  14. +++ b/libavcodec/omx.c
  15. @@ -1,6 +1,6 @@
  16. /*
  17. - * OMX Video decoder
  18. - * Copyright (C) 2018-2022 Starfive Technology
  19. + * OMX Video encoder
  20. + * Copyright (C) 2011 Martin Storsjo
  21. *
  22. * This file is part of FFmpeg.
  23. *
  24. diff --git a/libavcodec/omxdec.c b/libavcodec/omxdec.c
  25. index 0957605..87e5a1a 100755
  26. --- a/libavcodec/omxdec.c
  27. +++ b/libavcodec/omxdec.c
  28. @@ -1,6 +1,6 @@
  29. /*
  30. - * OMX Video encoder
  31. - * Copyright (C) 2011 Martin Storsjo
  32. + * OMX Video decoder
  33. + * Copyright (C) 2018-2022 Starfive Technology
  34. *
  35. * This file is part of FFmpeg.
  36. *
  37. @@ -274,6 +274,9 @@ typedef struct OMXCodecContext {
  38. uint8_t *output_buf;
  39. int output_buf_size;
  40. + OMX_U32 scale_width;
  41. + OMX_U32 scale_height;
  42. +
  43. int input_zerocopy;
  44. int profile;
  45. char *pixel_format; /**< Set by a private option. */
  46. @@ -481,7 +484,6 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role)
  47. //OMX_VIDEO_PARAM_BITRATETYPE vid_param_bitrate = { 0 };
  48. OMX_ERRORTYPE err;
  49. int i;
  50. -av_log(avctx, AV_LOG_VERBOSE, "OMX avctx pixel_format:%s\n", av_get_pix_fmt_name(avctx->pix_fmt));
  51. s->version.s.nVersionMajor = 1;
  52. s->version.s.nVersionMinor = 1;
  53. s->version.s.nRevision = 2;
  54. @@ -564,8 +566,6 @@ av_log(avctx, AV_LOG_VERBOSE, "OMX avctx pixel_format:%s\n", av_get_pix_fmt_name
  55. out_port_params.eDomain = OMX_PortDomainVideo;
  56. out_port_params.format.video.pNativeRender = NULL;
  57. out_port_params.format.video.bFlagErrorConcealment = OMX_FALSE;
  58. - out_port_params.format.video.nFrameWidth = avctx->width;
  59. - out_port_params.format.video.nFrameHeight = avctx->height;
  60. out_port_params.format.video.nStride = 0;
  61. out_port_params.format.video.nSliceHeight = 0;
  62. out_port_params.format.video.nBitrate = avctx->bit_rate;
  63. @@ -576,41 +576,29 @@ av_log(avctx, AV_LOG_VERBOSE, "OMX avctx pixel_format:%s\n", av_get_pix_fmt_name
  64. out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
  65. else if (avctx->codec->id == AV_CODEC_ID_H264) {
  66. out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
  67. -
  68. - switch (av_get_pix_fmt(s->pixel_format)) {
  69. - case AV_PIX_FMT_NV12:
  70. - out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
  71. - break;
  72. - case AV_PIX_FMT_NV21:
  73. - out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYVU420SemiPlanar;
  74. - break;
  75. - case AV_PIX_FMT_YUV420P:
  76. - out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
  77. - break;
  78. - default:
  79. - return AVERROR_OPTION_NOT_FOUND;
  80. - }
  81. }
  82. else if (avctx->codec->id == AV_CODEC_ID_HEVC) {
  83. out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingHEVC;
  84. -
  85. - switch (av_get_pix_fmt(s->pixel_format)) {
  86. - case AV_PIX_FMT_NV12:
  87. - out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
  88. - break;
  89. - case AV_PIX_FMT_NV21:
  90. - out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYVU420SemiPlanar;
  91. - break;
  92. - case AV_PIX_FMT_YUV420P:
  93. - out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
  94. - break;
  95. - default:
  96. - return AVERROR_OPTION_NOT_FOUND;
  97. - }
  98. }
  99. else if (avctx->codec->id == AV_CODEC_ID_MJPEG){
  100. out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingMJPEG;
  101. + /* Set Scale config setting*/
  102. + if (s->scale_width || s->scale_height) {
  103. + av_log(avctx, AV_LOG_TRACE, "mjpeg decoder: scaling width: %ld scaling height: %ld .\n", s->scale_width, s->scale_height);
  104. + OMX_CONFIG_SCALEFACTORTYPE ScaleConfig;
  105. + INIT_STRUCT(ScaleConfig);
  106. + ScaleConfig.nPortIndex = 1;
  107. + OMX_GetConfig(s->handle, OMX_IndexConfigCommonScale, &ScaleConfig);
  108. + /* in Q16 format */
  109. + ScaleConfig.xWidth = (1 << 16) >> (s->scale_width & 0x3);
  110. + ScaleConfig.xHeight = (1 << 16) >> (s->scale_height & 0x3);
  111. + OMX_SetConfig(s->handle, OMX_IndexConfigCommonScale, &ScaleConfig);
  112. + } else {
  113. + out_port_params.format.video.nFrameWidth = avctx->width;
  114. + out_port_params.format.video.nFrameHeight = avctx->height;
  115. + }
  116. +
  117. switch (av_get_pix_fmt(s->pixel_format)) {
  118. case AV_PIX_FMT_NV12:
  119. out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
  120. @@ -643,6 +631,35 @@ av_log(avctx, AV_LOG_VERBOSE, "OMX avctx pixel_format:%s\n", av_get_pix_fmt_name
  121. return AVERROR_OPTION_NOT_FOUND;
  122. }
  123. }
  124. + if (avctx->codec->id == AV_CODEC_ID_H264 || avctx->codec->id == AV_CODEC_ID_HEVC) {
  125. + /* Set Scale config setting*/
  126. + if ((s->scale_width != 0) && ((s->scale_width < avctx->width/8) ||
  127. + (s->scale_width > avctx->width) || (s->scale_width % 8 != 0))) {
  128. + av_log(avctx, AV_LOG_ERROR, "scale_width: Invalid scale parameter\n");
  129. + return AVERROR_INVALIDDATA;
  130. + }
  131. + if ((s->scale_height != 0) && ((s->scale_height < avctx->height/8) ||
  132. + (s->scale_height > avctx->height) || (s->scale_height % 8 != 0))) {
  133. + av_log(avctx, AV_LOG_ERROR, "scale_height: Invalid scale parameter\n");
  134. + return AVERROR_INVALIDDATA;
  135. + }
  136. + out_port_params.format.video.nFrameWidth = s->scale_width ? s->scale_width : avctx->width;
  137. + out_port_params.format.video.nFrameHeight = s->scale_height ? s->scale_height : avctx->height;
  138. +
  139. + switch (av_get_pix_fmt(s->pixel_format)) {
  140. + case AV_PIX_FMT_NV12:
  141. + out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
  142. + break;
  143. + case AV_PIX_FMT_NV21:
  144. + out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYVU420SemiPlanar;
  145. + break;
  146. + case AV_PIX_FMT_YUV420P:
  147. + out_port_params.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
  148. + break;
  149. + default:
  150. + return AVERROR_OPTION_NOT_FOUND;
  151. + }
  152. + }
  153. err = OMX_SetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params);
  154. CHECK(err);
  155. @@ -650,10 +667,8 @@ av_log(avctx, AV_LOG_VERBOSE, "OMX avctx pixel_format:%s\n", av_get_pix_fmt_name
  156. CHECK(err);
  157. s->num_out_buffers = out_port_params.nBufferCountActual;
  158. -
  159. err = OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
  160. CHECK(err);
  161. -
  162. s->in_buffer_headers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_in_buffers);
  163. s->free_in_buffers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_in_buffers);
  164. s->out_buffer_headers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_out_buffers);
  165. @@ -674,7 +689,6 @@ av_log(avctx, AV_LOG_VERBOSE, "OMX avctx pixel_format:%s\n", av_get_pix_fmt_name
  166. err = OMX_AllocateBuffer(s->handle, &s->out_buffer_headers[i], s->out_port, s, out_port_params.nBufferSize);
  167. CHECK(err);
  168. s->num_out_buffers = i;
  169. -
  170. if (wait_for_state(s, OMX_StateIdle) < 0) {
  171. av_log(avctx, AV_LOG_ERROR, "Didn't get OMX_StateIdle\n");
  172. return AVERROR_UNKNOWN;
  173. @@ -1022,6 +1036,8 @@ static const AVOption options[] = {
  174. { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_MAIN }, 0, 0, VE, "profile" },
  175. { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_HIGH }, 0, 0, VE, "profile" },
  176. { "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 },
  177. + { "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 },
  178. + { "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 },
  179. { NULL }
  180. };
  181. @@ -1030,6 +1046,8 @@ static const AVOption options_hevc[] = {
  182. { "omx_libprefix", "OpenMAX library prefix", OFFSET(libprefix), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE },
  183. { "zerocopy", "Try to avoid copying input frames if possible", OFFSET(input_zerocopy), AV_OPT_TYPE_INT, { .i64 = CONFIG_OMX_RPI }, 0, 1, VE },
  184. { "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 },
  185. + { "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 },
  186. + { "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 },
  187. { NULL },
  188. };
  189. @@ -1038,6 +1056,8 @@ static const AVOption options_mjpeg[] = {
  190. { "omx_libprefix", "OpenMAX library prefix", OFFSET(libprefix), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE },
  191. { "zerocopy", "Try to avoid copying input frames if possible", OFFSET(input_zerocopy), AV_OPT_TYPE_INT, { .i64 = CONFIG_OMX_RPI }, 0, 1, VD },
  192. { "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 },
  193. + { "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 },
  194. + { "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 },
  195. { NULL },
  196. };
  197. --
  198. 2.17.1