From patchwork Wed Mar 15 02:47:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marton Balint X-Patchwork-Id: 2931 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.50.79 with SMTP id y76csp103676vsy; Tue, 14 Mar 2017 19:48:20 -0700 (PDT) X-Received: by 10.223.170.70 with SMTP id q6mr744563wrd.162.1489546100622; Tue, 14 Mar 2017 19:48:20 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id y133si2154166wmg.98.2017.03.14.19.48.19; Tue, 14 Mar 2017 19:48:20 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 67AE16882BE; Wed, 15 Mar 2017 04:47:56 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from iq.passwd.hu (iq.passwd.hu [217.27.212.140]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5B8476882AE for ; Wed, 15 Mar 2017 04:47:50 +0200 (EET) Received: from localhost (localhost [127.0.0.1]) by iq.passwd.hu (Postfix) with ESMTP id 826261016C8; Wed, 15 Mar 2017 03:48:06 +0100 (CET) X-Virus-Scanned: amavisd-new at passwd.hu Received: from iq.passwd.hu ([127.0.0.1]) by localhost (iq.passwd.hu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id D1GSmij8TJBe; Wed, 15 Mar 2017 03:48:05 +0100 (CET) Received: from bluegene.passwd.hu (localhost [127.0.0.1]) by iq.passwd.hu (Postfix) with ESMTP id 2458F100B49; Wed, 15 Mar 2017 03:48:05 +0100 (CET) From: Marton Balint To: ffmpeg-devel@ffmpeg.org Date: Wed, 15 Mar 2017 03:47:57 +0100 Message-Id: <20170315024758.8875-2-cus@passwd.hu> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20170315024758.8875-1-cus@passwd.hu> References: <20170315024758.8875-1-cus@passwd.hu> Subject: [FFmpeg-devel] [PATCH 2/3] ffplay: convert to new decode API 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: Marton Balint MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Since subtitles are not yet supported with the new API, CODEC_CAP_DELAY subtitle codecs (only libzvbi so far) may loose the last few buffered frames in the end of the stream. The impact of this is so limited, it seemded better to accept it than losing the simplification benefits of the new API. Signed-off-by: Marton Balint --- ffplay.c | 92 +++++++++++++++++++++++++++++----------------------------------- 1 file changed, 41 insertions(+), 51 deletions(-) diff --git a/ffplay.c b/ffplay.c index cf138dc..06d1d22 100644 --- a/ffplay.c +++ b/ffplay.c @@ -186,13 +186,10 @@ enum { }; typedef struct Decoder { - AVPacket pkt; - AVPacket pkt_temp; PacketQueue *queue; AVCodecContext *avctx; int pkt_serial; int finished; - int packet_pending; SDL_cond *empty_queue_cond; int64_t start_pts; AVRational start_pts_tb; @@ -551,40 +548,24 @@ static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, d->queue = queue; d->empty_queue_cond = empty_queue_cond; d->start_pts = AV_NOPTS_VALUE; + d->pkt_serial = -1; } static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) { - int got_frame = 0; + int ret = AVERROR(EAGAIN); - do { - int ret = -1; + for (;;) { + AVPacket pkt; + if (d->queue->serial == d->pkt_serial) { + do { if (d->queue->abort_request) return -1; - if (!d->packet_pending || d->queue->serial != d->pkt_serial) { - AVPacket pkt; - do { - if (d->queue->nb_packets == 0) - SDL_CondSignal(d->empty_queue_cond); - if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0) - return -1; - if (pkt.data == flush_pkt.data) { - avcodec_flush_buffers(d->avctx); - d->finished = 0; - d->next_pts = d->start_pts; - d->next_pts_tb = d->start_pts_tb; - } - } while (pkt.data == flush_pkt.data || d->queue->serial != d->pkt_serial); - av_packet_unref(&d->pkt); - d->pkt_temp = d->pkt = pkt; - d->packet_pending = 1; - } - switch (d->avctx->codec_type) { case AVMEDIA_TYPE_VIDEO: - ret = avcodec_decode_video2(d->avctx, frame, &got_frame, &d->pkt_temp); - if (got_frame) { + ret = avcodec_receive_frame(d->avctx, frame); + if (ret >= 0) { if (decoder_reorder_pts == -1) { frame->pts = av_frame_get_best_effort_timestamp(frame); } else if (!decoder_reorder_pts) { @@ -593,8 +574,8 @@ static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) { } break; case AVMEDIA_TYPE_AUDIO: - ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, &d->pkt_temp); - if (got_frame) { + ret = avcodec_receive_frame(d->avctx, frame); + if (ret >= 0) { AVRational tb = (AVRational){1, frame->sample_rate}; if (frame->pts != AV_NOPTS_VALUE) frame->pts = av_rescale_q(frame->pts, av_codec_get_pkt_timebase(d->avctx), tb); @@ -606,37 +587,46 @@ static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) { } } break; - case AVMEDIA_TYPE_SUBTITLE: - ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &d->pkt_temp); - break; + } + if (ret == AVERROR_EOF) { + d->finished = d->pkt_serial; + avcodec_flush_buffers(d->avctx); + return 0; + } + if (ret >= 0) + return 1; + } while (ret != AVERROR(EAGAIN)); } - if (ret < 0) { - d->packet_pending = 0; + do { + if (d->queue->nb_packets == 0) + SDL_CondSignal(d->empty_queue_cond); + if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0) + return -1; + } while (d->queue->serial != d->pkt_serial); + + if (pkt.data == flush_pkt.data) { + avcodec_flush_buffers(d->avctx); + d->finished = 0; + d->next_pts = d->start_pts; + d->next_pts_tb = d->start_pts_tb; } else { - d->pkt_temp.dts = - d->pkt_temp.pts = AV_NOPTS_VALUE; - if (d->pkt_temp.data) { - if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO) - ret = d->pkt_temp.size; - d->pkt_temp.data += ret; - d->pkt_temp.size -= ret; - if (d->pkt_temp.size <= 0) - d->packet_pending = 0; + if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) { + int got_frame = 0; + ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, &pkt); + if (ret < 0) + ret = AVERROR(EAGAIN); + else + ret = got_frame ? 0 : (pkt.data ? AVERROR(EAGAIN) : AVERROR_EOF); } else { - if (!got_frame) { - d->packet_pending = 0; - d->finished = d->pkt_serial; - } + av_assert0(avcodec_send_packet(d->avctx, &pkt) != AVERROR(EAGAIN)); } + av_packet_unref(&pkt); } - } while (!got_frame && !d->finished); - - return got_frame; + } } static void decoder_destroy(Decoder *d) { - av_packet_unref(&d->pkt); avcodec_free_context(&d->avctx); }