From patchwork Sat Sep 11 19:49:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 30149 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp2638871iov; Sat, 11 Sep 2021 12:49:20 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy+cYL1txepqRjfhu1/632AIBIDKr7zFYvNEtMfotyXR3Uh9+1FEZdEXQVNOVjqXvq2+Aua X-Received: by 2002:a17:906:850b:: with SMTP id i11mr4237981ejx.84.1631389760559; Sat, 11 Sep 2021 12:49:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631389760; cv=none; d=google.com; s=arc-20160816; b=mkqu0/YzPsD2bWOMuvhcECsSf20Ssh6Po/i6rxpYzj8H8Ikk8IABGt3tm2z538ziWm UXjxVbUDv1gF2gtEYUBpGgyTRU8zs/wiAq9gUKIDv8JUcCAPiZwNh0yfuH+mSFolXri1 zuM/qXa3TkSlNfCAxPyoszsj28ubZDJklxforZwJRxL4go5hbX+W4SuozCiE7OCLt30Z mfbQEIw2UityfuYiGk8Orgy0xryjDrlAtA6zRyvzL8AOEz/AbnlxtkcYgr0qHaBXpOxS R55dePkvOAosheckyiCtQVZcNztssNIxLdSngZMvN4dWWYBCJiZSFIZKcSJ3KarURYHF ieUA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:dkim-signature :delivered-to; bh=e5bs6yIUfcmytzoqfL7LOzVaePShlZwOIgfHYY7Fy2w=; b=FUr5M1zeXGmWfU0bzy8q7t8y0esxfLGUNDFpGxuHgFOt/DZCTA9q8/e45Fvc5Ryq6o JMUKhvxKRcWb/N9DKUcWzswtKH3h0uN6y/C2L0zJS6RS6momJKLg7mDQGEgnpBNUuSdU /R7mOjZ4krljIq7vVVmX7bM/76LSpg5nueTvvFQ50M4iEhrcuAWiD1KndntIM0rhnBox 5TdmvIESUJctAEhnZuQ5XymNXLr1hrSQLtwe0en9DaGhPi36+6ZWNcMQNDUtEsp25ICZ 4dqQn/V/rbtdz/SWpKNYWtW1NkumCP22NJx8cRmWNmx1Cvpd6VxCCHDdvtmewu4RAAO1 DPow== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=ZMNUvvDS; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id c3si2902677ejj.775.2021.09.11.12.49.19; Sat, 11 Sep 2021 12:49: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; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=ZMNUvvDS; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 61F9A68A799; Sat, 11 Sep 2021 22:49:16 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ej1-f43.google.com (mail-ej1-f43.google.com [209.85.218.43]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 45C8B689965 for ; Sat, 11 Sep 2021 22:49:10 +0300 (EEST) Received: by mail-ej1-f43.google.com with SMTP id i21so11600000ejd.2 for ; Sat, 11 Sep 2021 12:49:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id; bh=hGqj/2I1oTyRW4b0Z+x/bkb/h+k9UDAu7QbMIvgGLfQ=; b=ZMNUvvDSPhzP4gHKd6HFv+nmGSL5ZNfQDkrdCco2TKk6kyImScV6j4JM0qCXtpedcr c5EaXEUd3KI54hELjYBNfZAux5w3VRaYicM85cX2jvE3os0r/9oC5MYrAC6olbeeJPvA pZXJ8F2LR/DXNTnsbEhk6PVz2gY0ic/GwCVnmGEFVfnUfnDYpA8Ye2kD05vbtxaLceo+ ZhgGg2WvjEerqguojyn518f0nk/gQnbV1RTy79wBHHTFdR42/NvWvkSmD1LahO4kXwTf ldMT5c/W8qD5L0vnffQnYVi1AHHtgsXUhQgbN2Gfyk1famKmZCod7PkN4pFUiz9kTrNK JC8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id; bh=hGqj/2I1oTyRW4b0Z+x/bkb/h+k9UDAu7QbMIvgGLfQ=; b=y0EFPQvYHdMIX40hQlSiz+1bOlvkkzvC9/mugK7qHjS08/t46pGYMuvmL97NvVuWSO erchYU1TXjtvlDLPNyhEiprkOaTlUzBgaHMipsUOLstnrz7VnpGvQ79SweUDtQN7EXT4 3zP98ZhzaL132DOddf5QVBzHZpMx4/MaHwofDrC9IQgnB6mG4tWQ+5S6IH5bVxSGF6Mm 25lQZtZFW4I4eNodqv3eCZ9vD9Vx8QYujur1q9SNpzt0EHE0lhlblwDAEG1jykO371lq f51+cyZnhVMFm4GP3GHKMtSADnlaUA4MjF7dE+suD7JXyK4Z9Vl7UY6A4WFBAHJM4odY VlOQ== X-Gm-Message-State: AOAM532jtVvzGkBi00QoHvl+rzkujeD2yvmReWA4vOsEhVtjc1E7jX8H KEjsaztRZMY+dcMcyqOXNdip6m/nLOw= X-Received: by 2002:a17:906:d789:: with SMTP id pj9mr4072502ejb.134.1631389749652; Sat, 11 Sep 2021 12:49:09 -0700 (PDT) Received: from localhost.localdomain ([95.168.120.44]) by smtp.gmail.com with ESMTPSA id l7sm1358979edb.26.2021.09.11.12.49.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Sep 2021 12:49:09 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Sat, 11 Sep 2021 21:49:00 +0200 Message-Id: <20210911194900.17480-1-onemda@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [PATCH] avcodec/wmadec: fix WMA gapless playback X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: SPltf/aGiJsR From: bnnm Fixes trac issue #7473. Removes encoder delay (skip samples) and writes remaining frame samples after EOF to get correct sample count. Output is now accurate vs players that use Microsoft's codecs (Windows Media Format Runtime). Tested vs encode>decode WMAv2 with MS's codecs and most sample rate/bit rate/channel/mode combinations in ASF/XWMA. WMAv1 appears to use the same delay, from FFmpeg samples. Signed-off-by: bnnm Signed-off-by: Paul B Mahol --- libavcodec/wma.h | 2 ++ libavcodec/wmadec.c | 22 ++++++++++++++++++++-- tests/fate/wma.mak | 8 ++++---- tests/ref/fate/flcl1905 | 3 +-- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/libavcodec/wma.h b/libavcodec/wma.h index aea7ba28ab..80e52687fd 100644 --- a/libavcodec/wma.h +++ b/libavcodec/wma.h @@ -135,6 +135,8 @@ typedef struct WMACodecContext { float lsp_pow_m_table2[(1 << LSP_POW_BITS)]; AVFloatDSPContext *fdsp; + int eof_done; /* decode flag to output remaining samples after EOF */ + #ifdef TRACE int frame_count; #endif /* TRACE */ diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index cc67244344..9955aaa7d6 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -135,6 +135,8 @@ static av_cold int wma_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; + avctx->internal->skip_samples = s->frame_len * 2; + return 0; } @@ -829,7 +831,20 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, ff_tlog(avctx, "***decode_superframe:\n"); if (buf_size == 0) { + if (s->eof_done) + return 0; + + frame->nb_samples = s->frame_len; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + + for (i = 0; i < s->avctx->channels; i++) + memcpy(frame->extended_data[i], &s->frame_out[i][0], + frame->nb_samples * sizeof(s->frame_out[i][0])); + s->last_superframe_len = 0; + s->eof_done = 1; + *got_frame_ptr = 1; return 0; } if (buf_size < avctx->block_align) { @@ -975,6 +990,9 @@ static av_cold void flush(AVCodecContext *avctx) s->last_bitoffset = s->last_superframe_len = 0; + + s->eof_done = 0; + avctx->internal->skip_samples = s->frame_len * 2; } #if CONFIG_WMAV1_DECODER @@ -988,7 +1006,7 @@ const AVCodec ff_wmav1_decoder = { .close = ff_wma_end, .decode = wma_decode_superframe, .flush = flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, @@ -1005,7 +1023,7 @@ const AVCodec ff_wmav2_decoder = { .close = ff_wma_end, .decode = wma_decode_superframe, .flush = flush, - .capabilities = AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, diff --git a/tests/fate/wma.mak b/tests/fate/wma.mak index bc530998e8..c13874ebfc 100644 --- a/tests/fate/wma.mak +++ b/tests/fate/wma.mak @@ -40,14 +40,14 @@ fate-wmavoice: $(FATE_WMAVOICE-yes) FATE_WMA_ENCODE-$(call ENCDEC, WMAV1, ASF) += fate-wmav1-encode fate-wmav1-encode: CMD = enc_dec_pcm asf wav s16le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c:a wmav1 -b:a 128k -fate-wmav1-encode: CMP_SHIFT = -8192 -fate-wmav1-encode: CMP_TARGET = 291.06 +fate-wmav1-encode: CMP_SHIFT = 8192 +fate-wmav1-encode: CMP_TARGET = 299.99 fate-wmav1-encode: SIZE_TOLERANCE = 4632 FATE_WMA_ENCODE-$(call ENCDEC, WMAV2, ASF) += fate-wmav2-encode fate-wmav2-encode: CMD = enc_dec_pcm asf wav s16le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c:a wmav2 -b:a 128k -fate-wmav2-encode: CMP_SHIFT = -8192 -fate-wmav2-encode: CMP_TARGET = 258.32 +fate-wmav2-encode: CMP_SHIFT = 8192 +fate-wmav2-encode: CMP_TARGET = 267.92 fate-wmav2-encode: SIZE_TOLERANCE = 4632 $(FATE_WMA_ENCODE-yes): CMP = stddev diff --git a/tests/ref/fate/flcl1905 b/tests/ref/fate/flcl1905 index 5f5245ebcf..d702139db8 100644 --- a/tests/ref/fate/flcl1905 +++ b/tests/ref/fate/flcl1905 @@ -1,6 +1,4 @@ packet|codec_type=audio|stream_index=0|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=22528|duration_time=0.510839|size=4092|pos=56|flags=K_ -frame|media_type=audio|stream_index=0|key_frame=1|pts=0|pts_time=0.000000|pkt_dts=0|pkt_dts_time=0.000000|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=56|pkt_size=4092|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown -frame|media_type=audio|stream_index=0|key_frame=1|pts=N/A|pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=56|pkt_size=3720|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pts=N/A|pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=56|pkt_size=3348|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pts=N/A|pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=56|pkt_size=2976|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pts=N/A|pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=56|pkt_size=2604|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown @@ -191,3 +189,4 @@ frame|media_type=audio|stream_index=0|key_frame=1|pts=N/A|pts_time=N/A|pkt_dts=N frame|media_type=audio|stream_index=0|key_frame=1|pts=N/A|pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=61436|pkt_size=744|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown frame|media_type=audio|stream_index=0|key_frame=1|pts=N/A|pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=22528|pkt_duration_time=0.510839|pkt_pos=61436|pkt_size=372|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown packet|codec_type=audio|stream_index=0|pts=360448|pts_time=8.173424|dts=360448|dts_time=8.173424|duration=44|duration_time=0.000998|size=8|pos=65528|flags=K_ +frame|media_type=audio|stream_index=0|key_frame=1|pts=N/A|pts_time=N/A|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=N/A|best_effort_timestamp_time=N/A|pkt_duration=N/A|pkt_duration_time=N/A|pkt_pos=N/A|pkt_size=0|sample_fmt=fltp|nb_samples=2048|channels=2|channel_layout=unknown