From patchwork Sun Jul 14 22:40:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: fumoboy007 X-Patchwork-Id: 13945 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 9BF744488EE for ; Mon, 15 Jul 2019 01:41:11 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7825568AC66; Mon, 15 Jul 2019 01:41:11 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from st43p00im-ztbu10063601.me.com (st43p00im-ztbu10063601.me.com [17.58.63.174]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1B7C568AAF2 for ; Mon, 15 Jul 2019 01:41:05 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=me.com; s=04042017; t=1563144063; bh=xB631xr5bkqhyHOY9iKDXX2rM2l+6mP2VM7oCpBWQME=; h=From:To:Subject:Date:Message-Id; b=eR7LeAvp0RR/lEOEmh9Q40mxVRyEgcafoVy7VM+BCCzSgeHySU3YO4xSkC5GRhAhn SutzpxaIObjT8pm/tDhjo3IWS8xrK5F5n/pJT2wKRBiVJYNU+CcJmvo7gujTmjEH3W m3CzvioIx/FIkW3QJpXaENcdFNHydrB0kcqGKMcHWS/q+xY/QzuoIFAEjZDwgkVzBa TaRaJl2dCyDf/bDNVjb4CHvE/peGtBM/DuB8oW5NgpqO0FcuTTL7vut6XrKQrAklHN euDnhsh/i+WgiKmRR7/QIzKA06bf6ipktow0rkFlGEdeT0zmqcgO5m+/khKt6dOW0x t5XfggAptcuJQ== Received: from localhost.localdomain (CPE6c709fd393be-CMf0f2498e5070.cpe.net.cable.rogers.com [99.240.152.179]) by st43p00im-ztbu10063601.me.com (Postfix) with ESMTPSA id 7C79D7007B6; Sun, 14 Jul 2019 22:41:03 +0000 (UTC) From: fumoboy007@me.com To: ffmpeg-devel@ffmpeg.org Date: Sun, 14 Jul 2019 18:40:35 -0400 Message-Id: <20190714224035.39526-1-fumoboy007@me.com> X-Mailer: git-send-email 2.21.0 MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-07-14_07:, , signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=552 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1812120000 definitions=main-1907140284 Subject: [FFmpeg-devel] [PATCH] avcodec/decode: Fix missing PTS/DTS for decoders like wmapro 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: fumoboy007@me.com Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: fumoboy007 Added back comment (deleted in 061a0c14bb5767bca72e3a7227ca400de439ba09) explaining that some audio decoders like wmapro may consume partial data without returning a frame. For these cases, `decode_simple_internal` will be called several times before the frame is complete. Due to a bug that this commit fixes, the PTS/DTS that was set on the first call would be reset to AV_NOPTS_VALUE on the subsequent calls. --- libavcodec/decode.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 6c31166ec2..c4722fa09b 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -603,16 +603,25 @@ FF_ENABLE_DEPRECATION_WARNINGS if (ret >= pkt->size || ret < 0) { av_packet_unref(pkt); + avci->last_pkt_props->pts = AV_NOPTS_VALUE; + avci->last_pkt_props->dts = AV_NOPTS_VALUE; } else { int consumed = ret; - pkt->data += consumed; pkt->size -= consumed; avci->last_pkt_props->size -= consumed; // See extract_packet_props() comment. - pkt->pts = AV_NOPTS_VALUE; - pkt->dts = AV_NOPTS_VALUE; - avci->last_pkt_props->pts = AV_NOPTS_VALUE; - avci->last_pkt_props->dts = AV_NOPTS_VALUE; + + if (got_frame) { + // TODO: Do the same for video and subtitles before introducing decoders of those types + // that have AV_CODEC_CAP_SUBFRAMES set. (We need a robust way to get the duration of a + // video or subtitle frame before we can do this.) + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { + int64_t frame_duration = av_rescale_q(frame->nb_samples, + (AVRational){1, avctx->sample_rate}, + avctx->pkt_timebase); + avci->last_pkt_props->pts += frame_duration; + } + } } if (got_frame) @@ -625,6 +634,10 @@ static int decode_simple_receive_frame(AVCodecContext *avctx, AVFrame *frame) { int ret; + // Some audio decoders may consume partial data without returning + // a frame (e.g. wmapro). There is no way to make the caller call + // avcodec_receive_frame() again without returning a frame, so try + // to decode more in these cases. while (!frame->buf[0]) { ret = decode_simple_internal(avctx, frame); if (ret < 0)