From patchwork Tue Oct 16 01:36:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Fu, Linjie" X-Patchwork-Id: 10681 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id B6509440FF8 for ; Tue, 16 Oct 2018 04:36:17 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1361468A199; Tue, 16 Oct 2018 04:35:59 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9686968A103 for ; Tue, 16 Oct 2018 04:35:51 +0300 (EEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Oct 2018 18:36:13 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,386,1534834800"; d="scan'208";a="95519510" Received: from kubernetes-master.sh.intel.com ([10.239.159.155]) by fmsmga002.fm.intel.com with ESMTP; 15 Oct 2018 18:36:12 -0700 From: Linjie Fu To: ffmpeg-devel@ffmpeg.org Date: Tue, 16 Oct 2018 09:36:13 +0800 Message-Id: <20181016013613.25783-1-linjie.fu@intel.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [PATCH V2] avcodec-qsvdec-flush-the-buffered-data-before-reinit X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Zhong Li , Linjie Fu MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Flush the buffered data in libmfx before video param reinit in case the frames drop. Cache the first frame causing the reinit and decode zero-size pkt to flush the buffered pkt before reinit. After all the buffered pkts being flushed, resume to reinit and decode. Fix the issue in ticket #7399. Modified in qsvdec_other.c as well. [V2]: Move the definition of zero_pkt to where it is exactly used. Signed-off-by: Linjie Fu Signed-off-by: Zhong Li --- libavcodec/qsvdec.c | 12 ++++++++++++ libavcodec/qsvdec.h | 2 ++ libavcodec/qsvdec_h2645.c | 11 +++++++---- libavcodec/qsvdec_other.c | 10 +++++++--- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 22e7a46a85..6753e596a1 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -372,6 +372,8 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, ++q->zero_consume_run; if (q->zero_consume_run > 1) ff_qsv_print_warning(avctx, ret, "A decode call did not consume any data"); + } else if (!*sync && bs.DataOffset) { + ++q->buffered_count; } else { q->zero_consume_run = 0; } @@ -526,6 +528,16 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext *q, AV_PIX_FMT_NONE, AV_PIX_FMT_NONE }; enum AVPixelFormat qsv_format; + AVPacket zero_pkt = {0}; + + if (q->buffered_count) { + q->reinit_flag = 1; + /* decode zero-size pkt to flush the buffered pkt before reinit */ + q->buffered_count--; + return qsv_decode(avctx, q, frame, got_frame, &zero_pkt); + } + + q->reinit_flag = 0; qsv_format = ff_qsv_map_pixfmt(q->parser->format, &q->fourcc); if (qsv_format < 0) { diff --git a/libavcodec/qsvdec.h b/libavcodec/qsvdec.h index 5b7b03a48b..111536caba 100644 --- a/libavcodec/qsvdec.h +++ b/libavcodec/qsvdec.h @@ -53,6 +53,8 @@ typedef struct QSVContext { AVFifoBuffer *async_fifo; int zero_consume_run; + int buffered_count; + int reinit_flag; // the internal parser and codec context for parsing the data AVCodecParserContext *parser; diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c index d9d2318d1a..b8a78aa81b 100644 --- a/libavcodec/qsvdec_h2645.c +++ b/libavcodec/qsvdec_h2645.c @@ -146,10 +146,11 @@ static int qsv_decode_frame(AVCodecContext *avctx, void *data, /* no more data */ if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket)) return avpkt->size ? avpkt->size : ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, avpkt); - - av_packet_unref(&s->buffer_pkt); - - av_fifo_generic_read(s->packet_fifo, &s->buffer_pkt, sizeof(s->buffer_pkt), NULL); + /* in progress of reinit, no read from fifo and keep the buffer_pkt */ + if (!s->qsv.reinit_flag) { + av_packet_unref(&s->buffer_pkt); + av_fifo_generic_read(s->packet_fifo, &s->buffer_pkt, sizeof(s->buffer_pkt), NULL); + } } ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, &s->buffer_pkt); @@ -159,6 +160,8 @@ static int qsv_decode_frame(AVCodecContext *avctx, void *data, av_packet_unref(&s->buffer_pkt); return ret; } + if (s->qsv.reinit_flag) + continue; s->buffer_pkt.size -= ret; s->buffer_pkt.data += ret; diff --git a/libavcodec/qsvdec_other.c b/libavcodec/qsvdec_other.c index 993c7a8e80..b449bb21b7 100644 --- a/libavcodec/qsvdec_other.c +++ b/libavcodec/qsvdec_other.c @@ -132,9 +132,11 @@ static int qsv_decode_frame(AVCodecContext *avctx, void *data, /* no more data */ if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket)) return avpkt->size ? avpkt->size : ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, avpkt); - - av_packet_unref(&s->input_ref); - av_fifo_generic_read(s->packet_fifo, &s->input_ref, sizeof(s->input_ref), NULL); + /* in progress of reinit, no read from fifo and keep the buffer_pkt */ + if (!s->qsv.reinit_flag) { + av_packet_unref(&s->input_ref); + av_fifo_generic_read(s->packet_fifo, &s->input_ref, sizeof(s->input_ref), NULL); + } } ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, &s->input_ref); @@ -145,6 +147,8 @@ static int qsv_decode_frame(AVCodecContext *avctx, void *data, return ret; } + if (s->qsv.reinit_flag) + continue; s->input_ref.size -= ret; s->input_ref.data += ret;