From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id 790FE47900 for ; Sun, 26 Nov 2023 18:02:18 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A308C68CF1E; Sun, 26 Nov 2023 20:02:15 +0200 (EET) Received: from mail-pl1-f180.google.com (mail-pl1-f180.google.com [209.85.214.180]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E9BDB68CC0B for ; Sun, 26 Nov 2023 20:02:08 +0200 (EET) Received: by mail-pl1-f180.google.com with SMTP id d9443c01a7336-1cfc2d03b3aso1892685ad.1 for ; Sun, 26 Nov 2023 10:02:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701021726; x=1701626526; darn=ffmpeg.org; h=content-transfer-encoding:in-reply-to:autocrypt:from :content-language:subject:references:to:user-agent:mime-version:date :message-id:from:to:cc:subject:date:message-id:reply-to; bh=EBUOEjQ0YLksQv6qA29+A6B+YacrDIJmuMhFW2GQ+ro=; b=LTNUmN6dgLfFwQ12xB/u3Mzf0Ka0yuhx15nxW8Qdrblq6auY1tZFN8QrTjt8RNoudU Zo7nsGkJAiwrF1yXKXSl1rw7OvoPYaG/g3bcmJsFJQnKC724wyutKTDcCe1tVmfGQQzb R1Jomuk1l/IOBjWMsxja9TiGFWfoXHv+/6rWhzRMRnY9sNGMojPGo1jZK+ch8xyAcqsc gRojo8XHpD0EWEbnPYrIZLcODmQMiTq+Ctf/2e4pXQ+ea+N+5LApucORJmkU04jr3RDc ooaWaB+TVJMQ5tGsnjbDwf28PtxqDXTu3zjd3TvqzTvQpJeQPzk2ZuZe7f4OvSgO+F5S z8mQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701021726; x=1701626526; h=content-transfer-encoding:in-reply-to:autocrypt:from :content-language:subject:references:to:user-agent:mime-version:date :message-id:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=EBUOEjQ0YLksQv6qA29+A6B+YacrDIJmuMhFW2GQ+ro=; b=LC7aAirdhr0p8NGvZG/wsn5brjwQ4kv9SP2yVXjtwJNk2mCJl22RZI5ykdEATD8h59 LnDRCVfaPSnl558Qrs+8zHimI9ZER0nHe2jp5pSVAlO2N2YttKw82MCzXV6Td6dJ2iQs VPPkoXpHF8DRK1aADXyKzpaq3hVNLnLY5aJtod33TO7WgxT09KnvoHXDMALVePovGc/O 8rUKnd/Ey2RQo2uchBsvTKtDbNcuF7OmHrFisC/02PkyDat4ymxWBqR1aWWqldGeITYf MWn4abXGsnKeNEhqQIi3IBArRM2Y7ggu7WwTcw26Jrxayc7AUFL5bgnv/6ypuXH5kanK upsQ== X-Gm-Message-State: AOJu0YxCdhRBGavZ784EhJ4A9hnHstiXo0iM3ghwIxmaLEsuwSr9++84 31oOVJ7Wgp0SRyPfUmsDpWylVhTmAhY= X-Google-Smtp-Source: AGHT+IEQEdOkr8mDIwV35nr8Q5C1m4MA6PUTgWDA78bT1PDCDUBeNO/vsp6Elz+J7mJSztUdEFEi5A== X-Received: by 2002:a17:903:1103:b0:1ce:6312:537c with SMTP id n3-20020a170903110300b001ce6312537cmr9182675plh.10.1701021725612; Sun, 26 Nov 2023 10:02:05 -0800 (PST) Received: from [192.168.0.14] (host197.190-225-105.telecom.net.ar. [190.225.105.197]) by smtp.gmail.com with ESMTPSA id f8-20020a170902684800b001cf7bd9ade5sm6782419pln.3.2023.11.26.10.02.04 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 26 Nov 2023 10:02:05 -0800 (PST) Message-ID: <86682e9c-f605-4873-bdbe-234483af7b75@gmail.com> Date: Sun, 26 Nov 2023 15:02:24 -0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird To: ffmpeg-devel@ffmpeg.org References: <20231126164217.65B274100B2@natalya.videolan.org> Content-Language: en-US From: James Almer Autocrypt: addr=jamrial@gmail.com; keydata= xsBNBFjZtqABCADLW+vdEoZaJZDsIO6geYFTOcn1unsEHefj9zn+3oTHlDFFzO47mzHsSfbK 9JE2xpOJEVnC8FAF5Sayi/pVwV+mtQUV3n5dgVeVBYF9GUQwOGFCpK8X54RRqhkgknbunOEE 0CtgAJgmpFmmmHgq02GvEspx1h/rh4apqwQR6QX4Favb+x9+i9ytVpwVcBX94vo2toyP7h/K BWfadQmb8ltgE1kshfg+SQs/H5bTV5Z1DuEASf02ZL/1qYB/sdTgWPLv9XMUHHsRFmMY8TMx wJSkP+Af3AiYQPJYz1B1D4tt98T/NoiVdin10zATakPjV8hXaobuRmxgakkUASXudydDABEB AAHNH0phbWVzIEFsbWVyIDxqYW1yaWFsQGdtYWlsLmNvbT7CwJIEEwEIADwCGwMGCwkIBwMC BhUIAgkKCwQWAgMBAh4BAheAFiEEd1EujP2UoWlX5pp6FGMBrXN2WeAFAmJoLUUCGQEACgkQ FGMBrXN2WeAFVQf9GtGhniRs1PzNUOgJktCnv6j4BbLieaIPYPEFXKDHOgjqQE2zVMYXnoXl Jam928ii902a8OY06r9ywn/R8ApD1/3NY/v64O71CY9scz5XyH2au8wIZ6HwFy3/f7sqjdGD uctY8Qs7rjT7NkoC5lmgMu2v2k03dGtM9AAf5AK5gU+H0EUw7vmKKiXzUqt5kvBuf4CEwXvH AQT1SMJ52rIlDWB7FQFyZeUbOAK2IgY/KNedfK6nsgd/eQVnlofPd2XoddE7kP6iys7jJefw DD3g3rZyDTq7in5dyk5glaNpWZpbHGBs+9SCYLnfQ8XvWqPFOD+gj0plamKANgOvavKTxM7A TQRY2bagAQgA69YtILj8kYxmqPr/M8+MXT7wVoOWVW9lvSmPquCELaDy/NIS7D06VC5EuE/6 JlJXZMTn37NLlyWhzwOgXuXw5w2tyoQQBuvqGiXJijuXwXH7HKdzrc6rpYtAqt5w05hzNrFS KrS0izG64VpWrfproy3BsL+8TBm9brLhhNPynVRqVukbbGzlATTzNQGZ14TTi2/dL6DkMQnM qn4jX9UEe4GdGQBP50bUJSSmeiIkyNLWA+znuN2PZEz930ZwNrF9GtDVw7mzcmpCZ7spldE2 tutbpy9D1bIqxyqBrYDSezyzL2adR1qgHyOTMCHg2AYNkrIQHrSyJxKTpZ1/hqOp8wARAQAB wsBfBBgBAgAJBQJY2bagAhsMAAoJEBRjAa1zdlnghekH/0Yb0iYJ74oID2f/Fj+AJKS2ekQF P2xOr8lpGzgp/+yWUvPtqbX0A33anBJdYwxaAC0NataX3tfZ+oJkzXqfmqhIHMPYHdZesJA2 Bk9hU/33mDl5s5U66/z0uelWzwKVHoQ2O6or4+qF3HJFSJLCe9uvWJ3zXf9F342Ftj73sfx+ 3xkw/IXsN1RqbYqDlzpoEQ99SIEfY/8Jjwnd3sIPfqkuyeaYfe6GJDqKawdCEP1oRRlbXEAp TJgYz8r3nPhGv9cdHNDCk44ISbsqVuxIEnLqi4fTPZaGupiQhT+srl268TTAp2TQW7+6Ce/b NPQorMquzS/LZoyALpmsYi/miMc= In-Reply-To: <20231126164217.65B274100B2@natalya.videolan.org> Subject: Re: [FFmpeg-devel] [FFmpeg-cvslog] avcodec: add QOA decoder 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 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="us-ascii"; Format="flowed" Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: > ffmpeg | branch: master | Paul B Mahol > | Sat Sep 23 16:49:25 2023 +0200| [3609d2b78340c06920973dc46b85b517c789782f] | committer: Paul B Mahol > > avcodec: add QOA decoder > > >/http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=3609d2b78340c06920973dc46b85b517c789782f > /--- > > Changelog | 1 + > libavcodec/Makefile | 1 + > libavcodec/allcodecs.c | 1 + > libavcodec/codec_desc.c | 7 ++ > libavcodec/codec_id.h | 1 + > libavcodec/qoadec.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++++ > libavcodec/version.h | 2 +- > 7 files changed, 187 insertions(+), 1 deletion(-) > > diff --git a/Changelog b/Changelog > index 7d79be1c3e..d945904bc0 100644 > --- a/Changelog > +++ b/Changelog > @@ -5,6 +5,7 @@ version : > - LEAD MCMP decoder > - EVC decoding using external library libxevd > - EVC encoding using external library libxeve > +- QOA decoder > > version 6.1: > - libaribcaption decoder > diff --git a/libavcodec/Makefile b/libavcodec/Makefile > index a5941d1284..748806e702 100644 > --- a/libavcodec/Makefile > +++ b/libavcodec/Makefile > @@ -623,6 +623,7 @@ OBJS-$(CONFIG_QCELP_DECODER) += qcelpdec.o \ > OBJS-$(CONFIG_QDM2_DECODER) += qdm2.o > OBJS-$(CONFIG_QDMC_DECODER) += qdmc.o > OBJS-$(CONFIG_QDRAW_DECODER) += qdrw.o > +OBJS-$(CONFIG_QOA_DECODER) += qoadec.o > OBJS-$(CONFIG_QOI_DECODER) += qoidec.o > OBJS-$(CONFIG_QOI_ENCODER) += qoienc.o > OBJS-$(CONFIG_QPEG_DECODER) += qpeg.o > diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c > index 87595683f9..b0f004e15c 100644 > --- a/libavcodec/allcodecs.c > +++ b/libavcodec/allcodecs.c > @@ -522,6 +522,7 @@ extern const FFCodec ff_paf_audio_decoder; > extern const FFCodec ff_qcelp_decoder; > extern const FFCodec ff_qdm2_decoder; > extern const FFCodec ff_qdmc_decoder; > +extern const FFCodec ff_qoa_decoder; > extern const FFCodec ff_ra_144_encoder; > extern const FFCodec ff_ra_144_decoder; > extern const FFCodec ff_ra_288_decoder; > diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c > index 432a9c9ea6..033344304c 100644 > --- a/libavcodec/codec_desc.c > +++ b/libavcodec/codec_desc.c > @@ -3427,6 +3427,13 @@ static const AVCodecDescriptor codec_descriptors[] = { > .long_name = NULL_IF_CONFIG_SMALL("OSQ (Original Sound Quality)"), > .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, > }, > + { > + .id = AV_CODEC_ID_QOA, > + .type = AVMEDIA_TYPE_AUDIO, > + .name = "qoa", > + .long_name = NULL_IF_CONFIG_SMALL("QOA (Quite OK Audio)"), > + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, > + }, > > /* subtitle codecs */ > { > diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h > index 84ce8e6aa9..d96e49430e 100644 > --- a/libavcodec/codec_id.h > +++ b/libavcodec/codec_id.h > @@ -545,6 +545,7 @@ enum AVCodecID { > AV_CODEC_ID_RKA, > AV_CODEC_ID_AC4, > AV_CODEC_ID_OSQ, > + AV_CODEC_ID_QOA, > > /* subtitle codecs */ > AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. > diff --git a/libavcodec/qoadec.c b/libavcodec/qoadec.c > new file mode 100644 > index 0000000000..9b2abae833 > --- /dev/null > +++ b/libavcodec/qoadec.c > @@ -0,0 +1,175 @@ > +/* > + * QOA decoder > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include "avcodec.h" > +#include "codec_internal.h" > +#include "decode.h" > +#include "get_bits.h" > +#include "bytestream.h" > +#include "mathops.h" > + > +#define QOA_SLICE_LEN 20 > +#define QOA_LMS_LEN 4 > + > +typedef struct QOAChannel { > + int history[QOA_LMS_LEN]; > + int weights[QOA_LMS_LEN]; > +} QOAChannel; > + > +typedef struct QOAContext { > + QOAChannel *ch; > +} QOAContext; > + > +static const int16_t qoa_dequant_tab[16][8] = { > + { 1, -1, 3, -3, 5, -5, 7, -7}, > + { 5, -5, 18, -18, 32, -32, 49, -49}, > + { 16, -16, 53, -53, 95, -95, 147, -147}, > + { 34, -34, 113, -113, 203, -203, 315, -315}, > + { 63, -63, 210, -210, 378, -378, 588, -588}, > + { 104, -104, 345, -345, 621, -621, 966, -966}, > + { 158, -158, 528, -528, 950, -950, 1477, -1477}, > + { 228, -228, 760, -760, 1368, -1368, 2128, -2128}, > + { 316, -316, 1053, -1053, 1895, -1895, 2947, -2947}, > + { 422, -422, 1405, -1405, 2529, -2529, 3934, -3934}, > + { 548, -548, 1828, -1828, 3290, -3290, 5117, -5117}, > + { 696, -696, 2320, -2320, 4176, -4176, 6496, -6496}, > + { 868, -868, 2893, -2893, 5207, -5207, 8099, -8099}, > + {1064, -1064, 3548, -3548, 6386, -6386, 9933, -9933}, > + {1286, -1286, 4288, -4288, 7718, -7718, 12005, -12005}, > + {1536, -1536, 5120, -5120, 9216, -9216, 14336, -14336}, > +}; > + > +static av_cold int qoa_decode_init(AVCodecContext *avctx) > +{ > + QOAContext *s = avctx->priv_data; > + > + avctx->sample_fmt = AV_SAMPLE_FMT_S16; > + > + s->ch = av_calloc(avctx->ch_layout.nb_channels, sizeof(*s->ch)); > + if (!s->ch) > + return AVERROR(ENOMEM); > + > + return 0; > +} > + > +static int qoa_lms_predict(QOAChannel *lms) > +{ > + int prediction = 0; > + for (int i = 0; i < QOA_LMS_LEN; i++) > + prediction += lms->weights[i] * lms->history[i]; > + return prediction >> 13; > +} > + > +static void qoa_lms_update(QOAChannel *lms, int sample, int residual) > +{ > + int delta = residual >> 4; > + for (int i = 0; i < QOA_LMS_LEN; i++) > + lms->weights[i] += lms->history[i] < 0 ? -delta : delta; > + for (int i = 0; i < QOA_LMS_LEN-1; i++) > + lms->history[i] = lms->history[i+1]; > + lms->history[QOA_LMS_LEN-1] = sample; > +} > + > +static int qoa_decode_frame(AVCodecContext *avctx, AVFrame *frame, > + int *got_frame_ptr, AVPacket *avpkt) > +{ > + QOAContext *s = avctx->priv_data; > + int ret, frame_size, nb_channels; > + GetByteContext gb; > + int16_t *samples; > + > + bytestream2_init(&gb, avpkt->data, avpkt->size); > + > + nb_channels = bytestream2_get_byte(&gb); > + if (avctx->ch_layout.nb_channels != nb_channels) > + return AVERROR_INVALIDDATA; > + > + avctx->sample_rate = bytestream2_get_be24(&gb); > + frame->nb_samples = bytestream2_get_be16(&gb); > + frame_size = bytestream2_get_be16(&gb); > + if (frame_size > avpkt->size) > + return AVERROR_INVALIDDATA; > + > + if (frame_size < 8 + QOA_LMS_LEN * 4 * nb_channels + > + 8LL * frame->nb_samples * nb_channels / QOA_SLICE_LEN) > + return AVERROR_INVALIDDATA; > + > + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) > + return ret; > + samples = (int16_t *)frame->data[0]; > + > + for (int ch = 0; ch < nb_channels; ch++) { > + QOAChannel *qch = &s->ch[ch]; > + > + for (int n = 0; n < QOA_LMS_LEN; n++) > + qch->history[n] = sign_extend(bytestream2_get_be16u(&gb), 16); > + for (int n = 0; n < QOA_LMS_LEN; n++) > + qch->weights[n] = sign_extend(bytestream2_get_be16u(&gb), 16); > + } > + > + for (int sample_index = 0; sample_index < frame->nb_samples * nb_channels; > + sample_index += QOA_SLICE_LEN) { > + for (int ch = 0; ch < nb_channels; ch++) { > + QOAChannel *lms = &s->ch[ch]; > + uint64_t slice = bytestream2_get_be64u(&gb); > + int scalefactor = (slice >> 60) & 0xf; > + int slice_start = sample_index * nb_channels + ch; > + int slice_end = av_clip(sample_index + QOA_SLICE_LEN, 0, frame->nb_samples) * nb_channels + ch; > + > + for (int si = slice_start; si < slice_end; si += nb_channels) { > + int predicted = qoa_lms_predict(lms); > + int quantized = (slice >> 57) & 0x7; > + int dequantized = qoa_dequant_tab[scalefactor][quantized]; > + int reconstructed = av_clip_int16(predicted + dequantized); > + > + samples[si] = reconstructed; > + slice <<= 3; > + > + qoa_lms_update(lms, reconstructed, dequantized); > + } > + } > + } > + > + *got_frame_ptr = 1; > + > + return avpkt->size; > +} > + > +static av_cold int qoa_decode_end(AVCodecContext *avctx) > +{ > + QOAContext *s = avctx->priv_data; > + av_freep(&s->ch); > + return 0; > +} > + > +const FFCodec ff_qoa_decoder = { > + .p.name = "qoa", > + CODEC_LONG_NAME("QOA (Quite OK Audio)"), > + .p.type = AVMEDIA_TYPE_AUDIO, > + .p.id = AV_CODEC_ID_QOA, > + .priv_data_size = sizeof(QOAContext), > + .init = qoa_decode_init, > + FF_CODEC_DECODE_CB(qoa_decode_frame), > + .close = qoa_decode_end, > + .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | The decoder is not setting channel info, it's using the one set by the caller and ensuring it doesn't change between frames. So this cap is not correct. > + AV_CODEC_CAP_DR1, > + .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, > + AV_SAMPLE_FMT_NONE }, > +}; > diff --git a/libavcodec/version.h b/libavcodec/version.h > index 0ef6c991f3..1008fead27 100644 > --- a/libavcodec/version.h > +++ b/libavcodec/version.h > @@ -29,7 +29,7 @@ > > #include "version_major.h" > > -#define LIBAVCODEC_VERSION_MINOR 34 > +#define LIBAVCODEC_VERSION_MINOR 35 > #define LIBAVCODEC_VERSION_MICRO 100 > > #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".