123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- From 9ca5512fde8d237977b102e240c957e7506a276a Mon Sep 17 00:00:00 2001
- From: "sw.multimedia" <se.multimedia@starfivetech.com>
- Date: Wed, 25 May 2022 20:52:37 +0800
- Subject: [PATCH 5/8] avcoder fix decoder bug
- Signed-off-by: sw.multimedia <se.multimedia@starfivetech.com>
- ---
- libavcodec/omxdec.c | 182 +++++++++++++++++++++++++++-----------------
- 1 file changed, 114 insertions(+), 68 deletions(-)
- diff --git a/libavcodec/omxdec.c b/libavcodec/omxdec.c
- index 96a2829..9eb5dca 100644
- --- a/libavcodec/omxdec.c
- +++ b/libavcodec/omxdec.c
- @@ -46,6 +46,11 @@
- #include "internal.h"
- #include "profiles.h"
-
- +int evnet_bufferflag;
- +int dec_out_height;
- +int dec_out_width;
- +int dec_pix_fmt;
- +
- #ifdef OMX_SKIP64BIT
- static OMX_TICKS to_omx_ticks(int64_t value)
- {
- @@ -223,7 +228,7 @@ typedef struct OMXCodecContext {
-
- int mutex_cond_inited;
-
- - int eos_sent, got_eos, first_get_outbuffer;
- + int eos_sent, got_eos, evnet_bufferflag;
-
- int extradata_sent;
-
- @@ -274,6 +279,11 @@ static OMX_ERRORTYPE event_handler(OMX_HANDLETYPE component, OMX_PTR app_data, O
- // This uses casts in the printfs, since OMX_U32 actually is a typedef for
- // unsigned long in official header versions (but there are also modified
- // versions where it is something else).
- + OMX_PARAM_PORTDEFINITIONTYPE out_port_params = { 0 };
- + OMX_PORT_PARAM_TYPE video_port_params = { 0 };
- + OMX_ERRORTYPE err;
- + int i;
- +
- switch (event) {
- case OMX_EventError:
- pthread_mutex_lock(&s->state_mutex);
- @@ -299,8 +309,36 @@ static OMX_ERRORTYPE event_handler(OMX_HANDLETYPE component, OMX_PTR app_data, O
- }
- break;
- case OMX_EventPortSettingsChanged:
- - av_log(s->avctx, AV_LOG_VERBOSE, "OMX port %"PRIu32" settings changed\n", (uint32_t) data1);
- + av_log(s->avctx, AV_LOG_ERROR, "OMX port %"PRIu32" settings changed\n", (uint32_t) data1);
- + INIT_STRUCT(video_port_params);
- + err = OMX_GetParameter(s->handle, OMX_IndexParamVideoInit, &video_port_params);
- + if(err != OMX_ErrorNone){
- + av_log(s->avctx, AV_LOG_ERROR, "err %d\n",err);
- + return AVERROR_UNKNOWN;
- + }
- +
- + for (i = 0; i < video_port_params.nPorts; i++) {
- + int port = video_port_params.nStartPortNumber + i;
- + OMX_PARAM_PORTDEFINITIONTYPE port_params = { 0 };
- + INIT_STRUCT(port_params);
- + port_params.nPortIndex = port;
- + err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &port_params);
- + if (err != OMX_ErrorNone) {
- + av_log(s->avctx, AV_LOG_WARNING, "port %d error %x\n", port, err);
- + return AVERROR_UNKNOWN;
- + }
- + if (port_params.eDir == OMX_DirOutput) {
- + out_port_params = port_params;
- + dec_out_width = out_port_params.format.video.nFrameWidth;
- + dec_out_height = out_port_params.format.video.nFrameHeight;
- + dec_pix_fmt = out_port_params.format.video.eColorFormat;
- +
- + }
- + }
- break;
- + case OMX_EventBufferFlag:
- + av_log(s->avctx, AV_LOG_VERBOSE, "OMX decoder competd set event_bufferflag\n");
- + evnet_bufferflag = 1;
- default:
- av_log(s->avctx, AV_LOG_VERBOSE, "OMX event %d %"PRIx32" %"PRIx32"\n",
- event, (uint32_t) data1, (uint32_t) data2);
- @@ -453,7 +491,7 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role)
-
- in_port_params.format.video.pNativeRender = NULL;
- in_port_params.format.video.bFlagErrorConcealment = OMX_FALSE;
- - //in_port_params.format.video.eColorFormat = s->color_format;
- + in_port_params.format.video.eColorFormat = s->color_format;
- s->stride = avctx->width;
- s->plane_size = avctx->height;
- // If specific codecs need to manually override the stride/plane_size,
- @@ -473,11 +511,10 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role)
- err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &in_port_params);
- CHECK(err);
-
- -#if 1
- s->stride = in_port_params.format.video.nStride;
- s->plane_size = in_port_params.format.video.nSliceHeight;
- s->num_in_buffers = in_port_params.nBufferCountActual;
- -#endif
- +
- err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params);
- out_port_params.bEnabled = OMX_TRUE;
- out_port_params.bPopulated = OMX_FALSE;
- @@ -645,51 +682,51 @@ static av_cold int omx_decode_init(AVCodecContext *avctx)
- if ((ret = omx_component_init(avctx, role)) < 0)
- goto fail;
-
- -#if 0
- - if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
- - while (1) {
- - buffer = get_buffer(&s->output_mutex, &s->output_cond,
- - &s->num_done_out_buffers, s->done_out_buffers, 1);
- - if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
- - if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
- - avctx->extradata_size = 0;
- - goto fail;
- - }
- - memcpy(avctx->extradata + avctx->extradata_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
- - avctx->extradata_size += buffer->nFilledLen;
- - memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- - }
- - err = OMX_FillThisBuffer(s->handle, buffer);
- - if (err != OMX_ErrorNone) {
- - append_buffer(&s->output_mutex, &s->output_cond,
- - &s->num_done_out_buffers, s->done_out_buffers, buffer);
- - av_log(avctx, AV_LOG_ERROR, "OMX_FillThisBuffer failed: %x\n", err);
- - ret = AVERROR_UNKNOWN;
- - goto fail;
- - }
- - if (avctx->codec->id == AV_CODEC_ID_H264) {
- - // For H.264, the extradata can be returned in two separate buffers
- - // (the videocore encoder on raspberry pi does this);
- - // therefore check that we have got both SPS and PPS before continuing.
- - int nals[32] = { 0 };
- - int i;
- - for (i = 0; i + 4 < avctx->extradata_size; i++) {
- - if (!avctx->extradata[i + 0] &&
- - !avctx->extradata[i + 1] &&
- - !avctx->extradata[i + 2] &&
- - avctx->extradata[i + 3] == 1) {
- - nals[avctx->extradata[i + 4] & 0x1f]++;
- - }
- - }
- - if (nals[H264_NAL_SPS] && nals[H264_NAL_PPS])
- - break;
- - } else {
- - if (avctx->extradata_size > 0)
- - break;
- - }
- - }
- - }
- -#endif
- +// #if 0
- +// if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
- +// while (1) {
- +// buffer = get_buffer(&s->output_mutex, &s->output_cond,
- +// &s->num_done_out_buffers, s->done_out_buffers, 1);
- +// if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
- +// if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
- +// avctx->extradata_size = 0;
- +// goto fail;
- +// }
- +// memcpy(avctx->extradata + avctx->extradata_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
- +// avctx->extradata_size += buffer->nFilledLen;
- +// memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- +// }
- +// err = OMX_FillThisBuffer(s->handle, buffer);
- +// if (err != OMX_ErrorNone) {
- +// append_buffer(&s->output_mutex, &s->output_cond,
- +// &s->num_done_out_buffers, s->done_out_buffers, buffer);
- +// av_log(avctx, AV_LOG_ERROR, "OMX_FillThisBuffer failed: %x\n", err);
- +// ret = AVERROR_UNKNOWN;
- +// goto fail;
- +// }
- +// if (avctx->codec->id == AV_CODEC_ID_H264) {
- +// // For H.264, the extradata can be returned in two separate buffers
- +// // (the videocore encoder on raspberry pi does this);
- +// // therefore check that we have got both SPS and PPS before continuing.
- +// int nals[32] = { 0 };
- +// int i;
- +// for (i = 0; i + 4 < avctx->extradata_size; i++) {
- +// if (!avctx->extradata[i + 0] &&
- +// !avctx->extradata[i + 1] &&
- +// !avctx->extradata[i + 2] &&
- +// avctx->extradata[i + 3] == 1) {
- +// nals[avctx->extradata[i + 4] & 0x1f]++;
- +// }
- +// }
- +// if (nals[H264_NAL_SPS] && nals[H264_NAL_PPS])
- +// break;
- +// } else {
- +// if (avctx->extradata_size > 0)
- +// break;
- +// }
- +// }
- +// }
- +// #endif
-
- return 0;
- fail:
- @@ -712,10 +749,6 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data,
- int linesize[4];
-
- if (pkt->size) {
- -
- - //VPU init and fill buffer slow, so empty buf sleep to send before get vpu fill buf.
- - if(!s->first_get_outbuffer)
- - av_usleep(100000);
-
- buffer = get_buffer(&s->input_mutex, &s->input_cond,
- &s->num_free_in_buffers, s->free_in_buffers, 1);
- @@ -726,7 +759,7 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data,
- }
-
- //cpy the extradata
- - if(!s->extradata_sent) {
- + if(!s->extradata_sent && avctx->extradata ) {
-
- memcpy(buffer->pBuffer + buffer->nOffset, avctx->extradata, avctx->extradata_size);
- memcpy(buffer->pBuffer + buffer->nOffset + avctx->extradata_size, pkt->data, pkt->size);
- @@ -746,6 +779,7 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data,
-
- buffer->pOutputPortPrivate = NULL;
- buffer->pAppPrivate = avctx->priv_data;
- + buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
-
- err = OMX_EmptyThisBuffer(s->handle, buffer);
- if (err != OMX_ErrorNone) {
- @@ -754,16 +788,19 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data,
- return AVERROR_UNKNOWN;
- }
- } else if (!s->eos_sent) {
- -
- - if(!s->first_get_outbuffer)
- - av_usleep(1000000);
-
- buffer = get_buffer(&s->input_mutex, &s->input_cond,
- &s->num_free_in_buffers, s->free_in_buffers, 1);
-
- + if(!buffer) {
- + av_log(avctx, AV_LOG_ERROR, "get_buffer NULL\n");
- + return AVERROR(ENOMEM);
- + }
- +
- buffer->nFilledLen = 0;
- buffer->nFlags = OMX_BUFFERFLAG_EOS;
- buffer->pAppPrivate = buffer->pOutputPortPrivate = NULL;
- +
- err = OMX_EmptyThisBuffer(s->handle, buffer);
- if (err != OMX_ErrorNone) {
- append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer);
- @@ -782,20 +819,26 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data,
- !pkt || had_partial);
-
- if (!buffer) {
- - /*eos is sent but fill buf still can't get then continue*/
- - if(!s->first_get_outbuffer && s->eos_sent)
- + /*eos is sent wait for vpu evnet_bufferflag to get all frames*/
- ++ if(s->eos_sent && !evnet_bufferflag){}
- continue;
- - else
- + }
- break;
- }
- //if (!buffer)
- // break;
-
- - if(!buffer->nFilledLen)
- - goto end;
- -
- - if(!s->first_get_outbuffer)
- - s->first_get_outbuffer = 1;
- + if(!buffer->nFilledLen){
- + av_log(avctx, AV_LOG_ERROR, "buffer->nFilledLen %d\n",(int)buffer->nFilledLen);
- + goto end;
- + }
- +
- + avctx->width = dec_out_width;
- + avctx->height = dec_out_height;
- + avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- + s->stride = avctx->width;
- + s->plane_size = avctx->height;
- + //avctx->pix_fmt = dec_pix_fmt;
-
- if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
- s->got_eos = 1;
- @@ -807,8 +850,11 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data,
-
- ret = av_image_fill_arrays(dst, linesize, buffer->pBuffer,
- avctx->pix_fmt, s->stride, s->plane_size, 1);
- - if (ret < 0)
- - goto end;
- + if (ret < 0){
- + av_log(avctx, AV_LOG_ERROR, "av_image_fill_arrays ret:%d\n", ret);
- + goto end;
- + }
- +
- av_image_copy(avframe->data, avframe->linesize, (const uint8_t**)dst, linesize,
- avctx->pix_fmt, avctx->width, avctx->height);
-
- --
- 2.17.1
|