From 888f1780682a6a73b4004bec4d51c450ddaac710 Mon Sep 17 00:00:00 2001 From: "arvin.zhu" Date: Wed, 23 Nov 2022 15:08:36 +0800 Subject: [PATCH] FFmpeg:omxdec: set pts of avframe and fix some compilation warnings set pts of avframe from video container and fix some compilation warnings Signed-off-by: arvin.zhu --- libavcodec/omxdec.c | 129 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 116 insertions(+), 13 deletions(-) diff --git a/libavcodec/omxdec.c b/libavcodec/omxdec.c index 4974833..1bb08b1 100755 --- a/libavcodec/omxdec.c +++ b/libavcodec/omxdec.c @@ -96,13 +96,96 @@ typedef struct OMXContext { void (*host_init)(void); } OMXContext; -static const struct { +typedef struct OMXDecodeQueueNode { + int64_t val; + struct OMXDecodeQueueNode* next; +} OMXDecodeQueueNode; + +typedef struct OMXDecodeQueue { + OMXDecodeQueueNode* head; + OMXDecodeQueueNode* tail; +} OMXDecodeQueue; + +static av_cold void OMXDecodeQueueInit(OMXDecodeQueue* pq) +{ + assert(pq); + pq->head = pq->tail = NULL; +} + +static av_cold void OMXDecodeQueueDestory(OMXDecodeQueue* pq) +{ + OMXDecodeQueueNode* cur = pq->head; + assert(pq); + while (cur) + { + OMXDecodeQueueNode* next = cur->next; + av_free(cur); + cur = next; + } + pq->tail = pq->head = NULL; +} + +static void OMXDecodeQueuePush(OMXDecodeQueue* pq, int64_t x) +{ + OMXDecodeQueueNode* newNode = (OMXDecodeQueueNode*)malloc(sizeof(OMXDecodeQueueNode)); + if (NULL == newNode) + { + av_log(NULL, AV_LOG_ERROR, "malloc queue error\n"); + exit(-1); + } + assert(pq); + newNode->val = x; + newNode->next = NULL; + + if (pq->tail == NULL) + { + assert(pq->head == NULL); + pq->head = pq->tail = newNode; + } + else + { + pq->tail->next = newNode; + pq->tail = newNode; + } +} + +static void OMXDecodeQueuePop(OMXDecodeQueue* pq) +{ + assert(pq); + assert(pq->head && pq->tail); + if (pq->head->next == NULL) + { + av_free(pq->head); + pq->head = pq->tail = NULL; + } + else + { + OMXDecodeQueueNode* next = pq->head->next; + av_free(pq->head); + pq->head = next; + } +} + +static int OMXDecodeQueueEmpty(OMXDecodeQueue* pq) +{ + assert(pq); + + return pq->head == NULL; +} + +static int64_t OMXDecodeQueueFront(OMXDecodeQueue* pq) +{ + assert(pq); + assert(pq->head); + + return pq->head->val; +} + +static const struct { int color_format; enum AVPixelFormat pix_fmt; - } color_formats[] = { - { OMX_COLOR_FormatYUV420Planar, AV_PIX_FMT_YUV420P }, { OMX_COLOR_FormatYUV420SemiPlanar, AV_PIX_FMT_NV12 }, { OMX_COLOR_FormatYVU420SemiPlanar, AV_PIX_FMT_NV21 }, @@ -286,6 +369,8 @@ typedef struct OMXCodecContext { int h; } crop; + OMXDecodeQueue decode_pts_queue; + int decode_flag; int input_zerocopy; int profile; char *pixel_format; /**< Set by a private option. */ @@ -491,6 +576,10 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role) //OMX_VIDEO_PARAM_PORTFORMATTYPE video_port_format = { 0 }; //OMX_VIDEO_PARAM_BITRATETYPE vid_param_bitrate = { 0 }; OMX_ERRORTYPE err; + OMX_CONFIG_SCALEFACTORTYPE ScaleConfig; + OMX_CONFIG_MIRRORTYPE MirrorConfig; + OMX_CONFIG_ROTATIONTYPE RotatConfig; + OMX_CONFIG_RECTTYPE RectConfig; int i; s->version.s.nVersionMajor = 1; s->version.s.nVersionMinor = 1; @@ -594,7 +683,6 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role) /* Set Scale config setting*/ if (s->scale_width || s->scale_height) { av_log(avctx, AV_LOG_TRACE, "mjpeg decoder: scaling width: %d scaling height: %d .\n", s->scale_width, s->scale_height); - OMX_CONFIG_SCALEFACTORTYPE ScaleConfig; INIT_STRUCT(ScaleConfig); ScaleConfig.nPortIndex = 1; OMX_GetConfig(s->handle, OMX_IndexConfigCommonScale, &ScaleConfig); @@ -665,7 +753,6 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role) return AVERROR_INVALIDDATA; } av_log(avctx, AV_LOG_TRACE, "mjpeg decoder: mirror\n"); - OMX_CONFIG_MIRRORTYPE MirrorConfig; INIT_STRUCT(MirrorConfig); MirrorConfig.nPortIndex = 1; OMX_GetConfig(s->handle, OMX_IndexConfigCommonMirror, &MirrorConfig); @@ -680,7 +767,6 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role) return AVERROR_INVALIDDATA; } av_log(avctx, AV_LOG_TRACE, "mjpeg decoder: rotation\n"); - OMX_CONFIG_ROTATIONTYPE RotatConfig; INIT_STRUCT(RotatConfig); RotatConfig.nPortIndex = 1; OMX_GetConfig(s->handle, OMX_IndexConfigCommonRotate, &RotatConfig); @@ -726,7 +812,6 @@ static av_cold int omx_component_init(AVCodecContext *avctx, const char *role) return AVERROR_INVALIDDATA; } - OMX_CONFIG_RECTTYPE RectConfig; INIT_STRUCT(RectConfig); RectConfig.nPortIndex = 1; OMX_GetConfig(s->handle, OMX_IndexConfigCommonOutputCrop, &RectConfig); @@ -869,6 +954,8 @@ static av_cold void cleanup(OMXCodecContext *s) pthread_mutex_destroy(&s->output_mutex); s->mutex_cond_inited = 0; } + OMXDecodeQueueDestory(&s->decode_pts_queue); + av_freep(&s->decode_pts_queue); av_freep(&s->in_buffer_headers); av_freep(&s->out_buffer_headers); av_freep(&s->free_in_buffers); @@ -883,7 +970,10 @@ static av_cold int omx_decode_init(AVCodecContext *avctx) const char *role; //OMX_BUFFERHEADERTYPE *buffer; //OMX_ERRORTYPE err; + OMXDecodeQueueInit(&s->decode_pts_queue); + av_log(avctx, AV_LOG_VERBOSE, "avctx->time_base: %d/%d \n", avctx->time_base.num, avctx->time_base.den); + av_log(avctx, AV_LOG_VERBOSE, "avctx->framerate: %d/%d \n", avctx->framerate.num, avctx->framerate.den); s->omx_context = omx_init(avctx, s->libname, s->libprefix); if (!s->omx_context) return AVERROR_ENCODER_NOT_FOUND; @@ -898,6 +988,7 @@ static av_cold int omx_decode_init(AVCodecContext *avctx) s->avctx = avctx; s->state = OMX_StateLoaded; s->error = OMX_ErrorNone; + s->decode_flag = 0; switch (avctx->codec->id) { case AV_CODEC_ID_MPEG4: @@ -990,6 +1081,15 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data, uint8_t *dst[4]; int linesize[4]; + av_log(avctx, AV_LOG_VERBOSE, "s->decode_flag: %d\n", s->decode_flag); + av_log(avctx, AV_LOG_VERBOSE, "avctx->time_base: %d/%d \n", avctx->time_base.num, avctx->time_base.den); + av_log(avctx, AV_LOG_VERBOSE, "avctx->pkt_timebase: %d/%d \n", avctx->pkt_timebase.num, avctx->pkt_timebase.den); + av_log(avctx, AV_LOG_VERBOSE, "avctx->framerate: %d/%d \n", avctx->framerate.num, avctx->framerate.den); + av_log(avctx, AV_LOG_VERBOSE, "avpkt->size: %d avpkt->pts: %ld avpkt->dts: %ld avpkt->duration: %ld\n", + pkt->size, pkt->pts, pkt->dts, pkt->duration); + av_log(avctx, AV_LOG_VERBOSE, "avctx->pts_correction_last_pts: %ld avctx->pts_correction_last_dts: %ld\n", + avctx->pts_correction_last_pts, avctx->pts_correction_last_dts); + OMXDecodeQueuePush(&s->decode_pts_queue, pkt->dts); if (pkt->size) { //VPU init and fill buffer slow, so empty buf sleep to send before get vpu fill buf. @@ -1107,12 +1207,15 @@ static int omx_decode_frame(AVCodecContext *avctx, void *data, av_image_copy(avframe->data, avframe->linesize, (const uint8_t**)dst, linesize, avctx->pix_fmt, avctx->width, avctx->height); - - //avframe->pts = buffer->nTimeStamp; - //avframe->pkt_dts = AV_NOPTS_VALUE; - //avframe->pict_type= AV_PICTURE_TYPE_I; - //avframe->key_frame= 1; - + if (pkt->pts) { + if (OMXDecodeQueueEmpty(&s->decode_pts_queue) != 0){ + av_log(avctx, AV_LOG_ERROR, "The queue of decode pts is empty.\n"); + return AVERROR_INVALIDDATA; + } + avframe->pts = OMXDecodeQueueFront(&s->decode_pts_queue); + OMXDecodeQueuePop(&s->decode_pts_queue); + } + s->decode_flag += 1; *got_packet = 1; /* -- 2.17.1