0007-avcoder-fix-decoder-bug.patch 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. From 9ca5512fde8d237977b102e240c957e7506a276a Mon Sep 17 00:00:00 2001
  2. From: "sw.multimedia" <se.multimedia@starfivetech.com>
  3. Date: Wed, 25 May 2022 20:52:37 +0800
  4. Subject: [PATCH 5/8] avcoder fix decoder bug
  5. Signed-off-by: sw.multimedia <se.multimedia@starfivetech.com>
  6. ---
  7. libavcodec/omxdec.c | 182 +++++++++++++++++++++++++++-----------------
  8. 1 file changed, 114 insertions(+), 68 deletions(-)
  9. diff --git a/libavcodec/omxdec.c b/libavcodec/omxdec.c
  10. index 96a2829..9eb5dca 100644
  11. --- a/libavcodec/omxdec.c
  12. +++ b/libavcodec/omxdec.c
  13. @@ -46,6 +46,11 @@
  14. #include "internal.h"
  15. #include "profiles.h"
  16. +int evnet_bufferflag;
  17. +int dec_out_height;
  18. +int dec_out_width;
  19. +int dec_pix_fmt;
  20. +
  21. #ifdef OMX_SKIP64BIT
  22. static OMX_TICKS to_omx_ticks(int64_t value)
  23. {
  24. @@ -223,7 +228,7 @@ typedef struct OMXCodecContext {
  25. int mutex_cond_inited;
  26. - int eos_sent, got_eos, first_get_outbuffer;
  27. + int eos_sent, got_eos, evnet_bufferflag;
  28. int extradata_sent;
  29. @@ -274,6 +279,11 @@ static OMX_ERRORTYPE event_handler(OMX_HANDLETYPE component, OMX_PTR app_data, O
  30. // This uses casts in the printfs, since OMX_U32 actually is a typedef for
  31. // unsigned long in official header versions (but there are also modified
  32. // versions where it is something else).
  33. + OMX_PARAM_PORTDEFINITIONTYPE out_port_params = { 0 };
  34. + OMX_PORT_PARAM_TYPE video_port_params = { 0 };
  35. + OMX_ERRORTYPE err;
  36. + int i;
  37. +
  38. switch (event) {
  39. case OMX_EventError:
  40. pthread_mutex_lock(&s->state_mutex);
  41. @@ -299,8 +309,36 @@ static OMX_ERRORTYPE event_handler(OMX_HANDLETYPE component, OMX_PTR app_data, O
  42. }
  43. break;
  44. case OMX_EventPortSettingsChanged:
  45. - av_log(s->avctx, AV_LOG_VERBOSE, "OMX port %"PRIu32" settings changed\n", (uint32_t) data1);
  46. + av_log(s->avctx, AV_LOG_ERROR, "OMX port %"PRIu32" settings changed\n", (uint32_t) data1);
  47. + INIT_STRUCT(video_port_params);
  48. + err = OMX_GetParameter(s->handle, OMX_IndexParamVideoInit, &video_port_params);
  49. + if(err != OMX_ErrorNone){
  50. + av_log(s->avctx, AV_LOG_ERROR, "err %d\n",err);
  51. + return AVERROR_UNKNOWN;
  52. + }
  53. +
  54. + for (i = 0; i < video_port_params.nPorts; i++) {
  55. + int port = video_port_params.nStartPortNumber + i;
  56. + OMX_PARAM_PORTDEFINITIONTYPE port_params = { 0 };
  57. + INIT_STRUCT(port_params);
  58. + port_params.nPortIndex = port;
  59. + err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &port_params);
  60. + if (err != OMX_ErrorNone) {
  61. + av_log(s->avctx, AV_LOG_WARNING, "port %d error %x\n", port, err);
  62. + return AVERROR_UNKNOWN;
  63. + }
  64. + if (port_params.eDir == OMX_DirOutput) {
  65. + out_port_params = port_params;
  66. + dec_out_width = out_port_params.format.video.nFrameWidth;
  67. + dec_out_height = out_port_params.format.video.nFrameHeight;
  68. + dec_pix_fmt = out_port_params.format.video.eColorFormat;
  69. +
  70. + }
  71. + }
  72. break;
  73. + case OMX_EventBufferFlag:
  74. + av_log(s->avctx, AV_LOG_VERBOSE, "OMX decoder competd set event_bufferflag\n");
  75. + evnet_bufferflag = 1;
  76. default:
  77. av_log(s->avctx, AV_LOG_VERBOSE, "OMX event %d %"PRIx32" %"PRIx32"\n",
  78. event, (uint32_t) data1, (uint32_t) data2);
  79. @@ -453,7 +491,7 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role)
  80. in_port_params.format.video.pNativeRender = NULL;
  81. in_port_params.format.video.bFlagErrorConcealment = OMX_FALSE;
  82. - //in_port_params.format.video.eColorFormat = s->color_format;
  83. + in_port_params.format.video.eColorFormat = s->color_format;
  84. s->stride = avctx->width;
  85. s->plane_size = avctx->height;
  86. // If specific codecs need to manually override the stride/plane_size,
  87. @@ -473,11 +511,10 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role)
  88. err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &in_port_params);
  89. CHECK(err);
  90. -#if 1
  91. s->stride = in_port_params.format.video.nStride;
  92. s->plane_size = in_port_params.format.video.nSliceHeight;
  93. s->num_in_buffers = in_port_params.nBufferCountActual;
  94. -#endif
  95. +
  96. err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params);
  97. out_port_params.bEnabled = OMX_TRUE;
  98. out_port_params.bPopulated = OMX_FALSE;
  99. @@ -645,51 +682,51 @@ static av_cold int omx_decode_init(AVCodecContext *avctx)
  100. if ((ret = omx_component_init(avctx, role)) < 0)
  101. goto fail;
  102. -#if 0
  103. - if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
  104. - while (1) {
  105. - buffer = get_buffer(&s->output_mutex, &s->output_cond,
  106. - &s->num_done_out_buffers, s->done_out_buffers, 1);
  107. - if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
  108. - if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
  109. - avctx->extradata_size = 0;
  110. - goto fail;
  111. - }
  112. - memcpy(avctx->extradata + avctx->extradata_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
  113. - avctx->extradata_size += buffer->nFilledLen;
  114. - memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
  115. - }
  116. - err = OMX_FillThisBuffer(s->handle, buffer);
  117. - if (err != OMX_ErrorNone) {
  118. - append_buffer(&s->output_mutex, &s->output_cond,
  119. - &s->num_done_out_buffers, s->done_out_buffers, buffer);
  120. - av_log(avctx, AV_LOG_ERROR, "OMX_FillThisBuffer failed: %x\n", err);
  121. - ret = AVERROR_UNKNOWN;
  122. - goto fail;
  123. - }
  124. - if (avctx->codec->id == AV_CODEC_ID_H264) {
  125. - // For H.264, the extradata can be returned in two separate buffers
  126. - // (the videocore encoder on raspberry pi does this);
  127. - // therefore check that we have got both SPS and PPS before continuing.
  128. - int nals[32] = { 0 };
  129. - int i;
  130. - for (i = 0; i + 4 < avctx->extradata_size; i++) {
  131. - if (!avctx->extradata[i + 0] &&
  132. - !avctx->extradata[i + 1] &&
  133. - !avctx->extradata[i + 2] &&
  134. - avctx->extradata[i + 3] == 1) {
  135. - nals[avctx->extradata[i + 4] & 0x1f]++;
  136. - }
  137. - }
  138. - if (nals[H264_NAL_SPS] && nals[H264_NAL_PPS])
  139. - break;
  140. - } else {
  141. - if (avctx->extradata_size > 0)
  142. - break;
  143. - }
  144. - }
  145. - }
  146. -#endif
  147. +// #if 0
  148. +// if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
  149. +// while (1) {
  150. +// buffer = get_buffer(&s->output_mutex, &s->output_cond,
  151. +// &s->num_done_out_buffers, s->done_out_buffers, 1);
  152. +// if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
  153. +// if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
  154. +// avctx->extradata_size = 0;
  155. +// goto fail;
  156. +// }
  157. +// memcpy(avctx->extradata + avctx->extradata_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
  158. +// avctx->extradata_size += buffer->nFilledLen;
  159. +// memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
  160. +// }
  161. +// err = OMX_FillThisBuffer(s->handle, buffer);
  162. +// if (err != OMX_ErrorNone) {
  163. +// append_buffer(&s->output_mutex, &s->output_cond,
  164. +// &s->num_done_out_buffers, s->done_out_buffers, buffer);
  165. +// av_log(avctx, AV_LOG_ERROR, "OMX_FillThisBuffer failed: %x\n", err);
  166. +// ret = AVERROR_UNKNOWN;
  167. +// goto fail;
  168. +// }
  169. +// if (avctx->codec->id == AV_CODEC_ID_H264) {
  170. +// // For H.264, the extradata can be returned in two separate buffers
  171. +// // (the videocore encoder on raspberry pi does this);
  172. +// // therefore check that we have got both SPS and PPS before continuing.
  173. +// int nals[32] = { 0 };
  174. +// int i;
  175. +// for (i = 0; i + 4 < avctx->extradata_size; i++) {
  176. +// if (!avctx->extradata[i + 0] &&
  177. +// !avctx->extradata[i + 1] &&
  178. +// !avctx->extradata[i + 2] &&
  179. +// avctx->extradata[i + 3] == 1) {
  180. +// nals[avctx->extradata[i + 4] & 0x1f]++;
  181. +// }
  182. +// }
  183. +// if (nals[H264_NAL_SPS] && nals[H264_NAL_PPS])
  184. +// break;
  185. +// } else {
  186. +// if (avctx->extradata_size > 0)
  187. +// break;
  188. +// }
  189. +// }
  190. +// }
  191. +// #endif
  192. return 0;
  193. fail:
  194. @@ -712,10 +749,6 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data,
  195. int linesize[4];
  196. if (pkt->size) {
  197. -
  198. - //VPU init and fill buffer slow, so empty buf sleep to send before get vpu fill buf.
  199. - if(!s->first_get_outbuffer)
  200. - av_usleep(100000);
  201. buffer = get_buffer(&s->input_mutex, &s->input_cond,
  202. &s->num_free_in_buffers, s->free_in_buffers, 1);
  203. @@ -726,7 +759,7 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data,
  204. }
  205. //cpy the extradata
  206. - if(!s->extradata_sent) {
  207. + if(!s->extradata_sent && avctx->extradata ) {
  208. memcpy(buffer->pBuffer + buffer->nOffset, avctx->extradata, avctx->extradata_size);
  209. memcpy(buffer->pBuffer + buffer->nOffset + avctx->extradata_size, pkt->data, pkt->size);
  210. @@ -746,6 +779,7 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data,
  211. buffer->pOutputPortPrivate = NULL;
  212. buffer->pAppPrivate = avctx->priv_data;
  213. + buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
  214. err = OMX_EmptyThisBuffer(s->handle, buffer);
  215. if (err != OMX_ErrorNone) {
  216. @@ -754,16 +788,19 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data,
  217. return AVERROR_UNKNOWN;
  218. }
  219. } else if (!s->eos_sent) {
  220. -
  221. - if(!s->first_get_outbuffer)
  222. - av_usleep(1000000);
  223. buffer = get_buffer(&s->input_mutex, &s->input_cond,
  224. &s->num_free_in_buffers, s->free_in_buffers, 1);
  225. + if(!buffer) {
  226. + av_log(avctx, AV_LOG_ERROR, "get_buffer NULL\n");
  227. + return AVERROR(ENOMEM);
  228. + }
  229. +
  230. buffer->nFilledLen = 0;
  231. buffer->nFlags = OMX_BUFFERFLAG_EOS;
  232. buffer->pAppPrivate = buffer->pOutputPortPrivate = NULL;
  233. +
  234. err = OMX_EmptyThisBuffer(s->handle, buffer);
  235. if (err != OMX_ErrorNone) {
  236. append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer);
  237. @@ -782,20 +819,26 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data,
  238. !pkt || had_partial);
  239. if (!buffer) {
  240. - /*eos is sent but fill buf still can't get then continue*/
  241. - if(!s->first_get_outbuffer && s->eos_sent)
  242. + /*eos is sent wait for vpu evnet_bufferflag to get all frames*/
  243. ++ if(s->eos_sent && !evnet_bufferflag){}
  244. continue;
  245. - else
  246. + }
  247. break;
  248. }
  249. //if (!buffer)
  250. // break;
  251. - if(!buffer->nFilledLen)
  252. - goto end;
  253. -
  254. - if(!s->first_get_outbuffer)
  255. - s->first_get_outbuffer = 1;
  256. + if(!buffer->nFilledLen){
  257. + av_log(avctx, AV_LOG_ERROR, "buffer->nFilledLen %d\n",(int)buffer->nFilledLen);
  258. + goto end;
  259. + }
  260. +
  261. + avctx->width = dec_out_width;
  262. + avctx->height = dec_out_height;
  263. + avctx->pix_fmt = AV_PIX_FMT_YUV420P;
  264. + s->stride = avctx->width;
  265. + s->plane_size = avctx->height;
  266. + //avctx->pix_fmt = dec_pix_fmt;
  267. if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
  268. s->got_eos = 1;
  269. @@ -807,8 +850,11 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data,
  270. ret = av_image_fill_arrays(dst, linesize, buffer->pBuffer,
  271. avctx->pix_fmt, s->stride, s->plane_size, 1);
  272. - if (ret < 0)
  273. - goto end;
  274. + if (ret < 0){
  275. + av_log(avctx, AV_LOG_ERROR, "av_image_fill_arrays ret:%d\n", ret);
  276. + goto end;
  277. + }
  278. +
  279. av_image_copy(avframe->data, avframe->linesize, (const uint8_t**)dst, linesize,
  280. avctx->pix_fmt, avctx->width, avctx->height);
  281. --
  282. 2.17.1