0004-ffmpeg-add-hevc-decoder-and-encoder-support.patch 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. From 3c303ebf3f382dedf953772385214601acca9977 Mon Sep 17 00:00:00 2001
  2. From: sw.multimedia <sw.multimedia@starfivetech.com>
  3. Date: Tue, 23 Nov 2021 11:46:05 +0800
  4. Subject: [PATCH] ffmpeg: add hevc decoder and encoder support
  5. ---
  6. configure | 2 ++
  7. libavcodec/allcodecs.c | 2 ++
  8. libavcodec/omx.c | 41 +++++++++++++++++++++++++++++++++++++
  9. libavcodec/omxdec.c | 46 ++++++++++++++++++++++++++++++++++++++----
  10. libavformat/utils.c | 7 +++++++
  11. 5 files changed, 94 insertions(+), 4 deletions(-)
  12. diff --git a/configure b/configure
  13. index 8ff76b5..5523c59 100755
  14. --- a/configure
  15. +++ b/configure
  16. @@ -3063,6 +3063,8 @@ h264_vaapi_encoder_select="cbs_h264 vaapi_encode"
  17. h264_v4l2m2m_decoder_deps="v4l2_m2m h264_v4l2_m2m"
  18. h264_v4l2m2m_decoder_select="h264_mp4toannexb_bsf"
  19. h264_v4l2m2m_encoder_deps="v4l2_m2m h264_v4l2_m2m"
  20. +hevc_omx_encoder_deps="omx"
  21. +hevc_omx_decoder_deps="omx"
  22. hevc_amf_encoder_deps="amf"
  23. hevc_cuvid_decoder_deps="cuvid"
  24. hevc_cuvid_decoder_select="hevc_mp4toannexb_bsf"
  25. diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
  26. index f0551c1..b9db275 100644
  27. --- a/libavcodec/allcodecs.c
  28. +++ b/libavcodec/allcodecs.c
  29. @@ -767,6 +767,8 @@ extern AVCodec ff_h264_mf_encoder;
  30. extern AVCodec ff_h264_nvenc_encoder;
  31. extern AVCodec ff_h264_omx_encoder;
  32. extern AVCodec ff_h264_omx_decoder;
  33. +extern AVCodec ff_hevc_omx_encoder;
  34. +extern AVCodec ff_hevc_omx_decoder;
  35. extern AVCodec ff_h264_qsv_encoder;
  36. extern AVCodec ff_h264_v4l2m2m_encoder;
  37. extern AVCodec ff_h264_vaapi_encoder;
  38. diff --git a/libavcodec/omx.c b/libavcodec/omx.c
  39. index 0a6a308..e3140f1 100644
  40. --- a/libavcodec/omx.c
  41. +++ b/libavcodec/omx.c
  42. @@ -43,6 +43,8 @@
  43. #include "avcodec.h"
  44. #include "h264.h"
  45. #include "internal.h"
  46. +#include "profiles.h"
  47. +
  48. #ifdef OMX_SKIP64BIT
  49. static OMX_TICKS to_omx_ticks(int64_t value)
  50. @@ -501,6 +503,8 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role)
  51. out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
  52. else if (avctx->codec->id == AV_CODEC_ID_H264)
  53. out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
  54. + else if (avctx->codec->id == AV_CODEC_ID_HEVC)
  55. + out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingHEVC;
  56. err = OMX_SetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params);
  57. CHECK(err);
  58. @@ -666,6 +670,9 @@ static av_cold int omx_encode_init(AVCodecContext *avctx)
  59. case AV_CODEC_ID_H264:
  60. role = "video_encoder.avc";
  61. break;
  62. + case AV_CODEC_ID_HEVC:
  63. + role = "video_encoder.hevc";
  64. + break;
  65. default:
  66. return AVERROR(ENOSYS);
  67. }
  68. @@ -941,6 +948,15 @@ static const AVOption options[] = {
  69. { NULL }
  70. };
  71. +
  72. +static const AVOption options_hevc[] = {
  73. + { "omx_libname", "OpenMAX library name", OFFSET(libname), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE },
  74. + { "omx_libprefix", "OpenMAX library prefix", OFFSET(libprefix), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE },
  75. + { "zerocopy", "Try to avoid copying input frames if possible", OFFSET(input_zerocopy), AV_OPT_TYPE_INT, { .i64 = CONFIG_OMX_RPI }, 0, 1, VE },
  76. + { NULL },
  77. +};
  78. +
  79. +
  80. static const enum AVPixelFormat omx_encoder_pix_fmts[] = {
  81. AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
  82. };
  83. @@ -972,6 +988,7 @@ static const AVClass omx_h264enc_class = {
  84. .option = options,
  85. .version = LIBAVUTIL_VERSION_INT,
  86. };
  87. +
  88. AVCodec ff_h264_omx_encoder = {
  89. .name = "h264_omx",
  90. .long_name = NULL_IF_CONFIG_SMALL("OpenMAX IL H.264 video encoder"),
  91. @@ -986,3 +1003,27 @@ AVCodec ff_h264_omx_encoder = {
  92. .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
  93. .priv_class = &omx_h264enc_class,
  94. };
  95. +
  96. +static const AVClass omx_hevcenc_class = {
  97. + .class_name = "hevc_omx",
  98. + .item_name = av_default_item_name,
  99. + .option = options_hevc,
  100. + .version = LIBAVUTIL_VERSION_INT,
  101. +};
  102. +AVCodec ff_hevc_omx_encoder = {
  103. + .name = "hevc_omx",
  104. + .long_name = NULL_IF_CONFIG_SMALL("OpenMAX IL HEVC video encoder"),
  105. + .type = AVMEDIA_TYPE_VIDEO,
  106. + .id = AV_CODEC_ID_HEVC,
  107. + .priv_data_size = sizeof(OMXCodecContext),
  108. + .init = omx_encode_init,
  109. + .encode2 = omx_encode_frame,
  110. + .close = omx_encode_end,
  111. + .pix_fmts = omx_encoder_pix_fmts,
  112. + .profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles),
  113. + .capabilities = AV_CODEC_CAP_DELAY,
  114. + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
  115. + .priv_class = &omx_hevcenc_class,
  116. +};
  117. +
  118. +
  119. diff --git a/libavcodec/omxdec.c b/libavcodec/omxdec.c
  120. index f7ae1ec..14be242 100755
  121. --- a/libavcodec/omxdec.c
  122. +++ b/libavcodec/omxdec.c
  123. @@ -44,6 +44,8 @@
  124. #include "avcodec.h"
  125. #include "h264.h"
  126. #include "internal.h"
  127. +#include "profiles.h"
  128. +
  129. #ifdef OMX_SKIP64BIT
  130. static OMX_TICKS to_omx_ticks(int64_t value)
  131. @@ -493,7 +495,9 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role)
  132. if (avctx->codec->id == AV_CODEC_ID_MPEG4)
  133. out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
  134. else if (avctx->codec->id == AV_CODEC_ID_H264)
  135. - out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
  136. + out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
  137. + else if (avctx->codec->id == AV_CODEC_ID_HEVC)
  138. + out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingHEVC;
  139. err = OMX_SetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params);
  140. CHECK(err);
  141. @@ -600,6 +604,7 @@ static av_cold void cleanup(OMXCodecContext *s)
  142. static av_cold int omx_decode_init(AVCodecContext *avctx)
  143. {
  144. OMXCodecContext *s = avctx->priv_data;
  145. +
  146. int ret = AVERROR_ENCODER_NOT_FOUND;
  147. const char *role;
  148. //OMX_BUFFERHEADERTYPE *buffer;
  149. @@ -627,6 +632,10 @@ static av_cold int omx_decode_init(AVCodecContext *avctx)
  150. case AV_CODEC_ID_H264:
  151. role = "video_decoder.avc";
  152. break;
  153. + case AV_CODEC_ID_HEVC:
  154. + role = "video_decoder.hevc";
  155. + break;
  156. +
  157. default:
  158. return AVERROR(ENOSYS);
  159. }
  160. @@ -638,7 +647,7 @@ static av_cold int omx_decode_init(AVCodecContext *avctx)
  161. if ((ret = omx_component_init(avctx, role)) < 0)
  162. goto fail;
  163. -
  164. +
  165. #if 0
  166. if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
  167. while (1) {
  168. @@ -733,7 +742,7 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data,
  169. buffer->nFilledLen = pkt->size;
  170. }
  171. - /* reduce memcpy. point it addr*/
  172. + /* avoid memcpy. point it addr*/
  173. //buffer->pAppPrivate = pkt;
  174. //buffer->pBuffer = pkt->data;
  175. //buffer->nFilledLen = pkt->size;
  176. @@ -817,7 +826,6 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data,
  177. if ((ret = av_frame_ref(data, avframe)) < 0)
  178. goto end;
  179. */
  180. -
  181. end:
  182. err = OMX_FillThisBuffer(s->handle, buffer);
  183. if (err != OMX_ErrorNone) {
  184. @@ -852,6 +860,14 @@ static const AVOption options[] = {
  185. };
  186. +static const AVOption options_hevc[] = {
  187. + { "omx_libname", "OpenMAX library name", OFFSET(libname), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE },
  188. + { "omx_libprefix", "OpenMAX library prefix", OFFSET(libprefix), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE },
  189. + { "zerocopy", "Try to avoid copying input frames if possible", OFFSET(input_zerocopy), AV_OPT_TYPE_INT, { .i64 = CONFIG_OMX_RPI }, 0, 1, VE },
  190. + { NULL },
  191. +};
  192. +
  193. +
  194. static const AVClass omx_mpeg4dec_class = {
  195. .class_name = "mpeg4_omx",
  196. .item_name = av_default_item_name,
  197. @@ -892,3 +908,25 @@ AVCodec ff_h264_omx_decoder = {
  198. .priv_class = &omx_h264dec_class,
  199. };
  200. +static const AVClass omx_hevcdec_class = {
  201. + .class_name = "hevc_omx",
  202. + .item_name = av_default_item_name,
  203. + .option = options_hevc,
  204. + .version = LIBAVUTIL_VERSION_INT,
  205. +};
  206. +AVCodec ff_hevc_omx_decoder = {
  207. + .name = "hevc_omx",
  208. + .long_name = NULL_IF_CONFIG_SMALL("OpenMAX IL HEVC video decoder"),
  209. + .type = AVMEDIA_TYPE_VIDEO,
  210. + .id = AV_CODEC_ID_HEVC,
  211. + .priv_data_size = sizeof(OMXCodecContext),
  212. + .init = omx_decode_init,
  213. + .decode = omx_decode_frame,
  214. + .close = omx_decode_end,
  215. + .profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles),
  216. + .capabilities = AV_CODEC_CAP_DELAY,
  217. + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
  218. + .priv_class = &omx_hevcdec_class,
  219. +};
  220. +
  221. +
  222. diff --git a/libavformat/utils.c b/libavformat/utils.c
  223. index ba8aaeb..11fdc44 100644
  224. --- a/libavformat/utils.c
  225. +++ b/libavformat/utils.c
  226. @@ -211,6 +211,13 @@ static const AVCodec *find_probe_decoder(AVFormatContext *s, const AVStream *st,
  227. return avcodec_find_decoder_by_name("h264");
  228. #endif
  229. +#if CONFIG_HEVC_DECODER
  230. + /* Other parts of the code assume this decoder to be used for h265,
  231. + * so force it if possible. */
  232. + if (codec_id == AV_CODEC_ID_HEVC)
  233. + return avcodec_find_decoder_by_name("hevc");
  234. +#endif
  235. +
  236. codec = find_decoder(s, st, codec_id);
  237. if (!codec)
  238. return NULL;
  239. --
  240. 2.17.1