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 B1F5949B03 for ; Sun, 3 Mar 2024 07:54:11 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9E96868D37F; Sun, 3 Mar 2024 09:54:08 +0200 (EET) Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-he1eur01olkn2105.outbound.protection.outlook.com [40.92.65.105]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id AF1B268CF55 for ; Sun, 3 Mar 2024 09:54:02 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=WS2DvHJaIJxOttufoNnyTWhBsebewqK0hdZ/xGm/FyfPNHKWsvh8D7FW5N9dSk1atrucy0MKYBsbwvBsA9ivUD3W5pWTXKPVnDY2XQb6qaBVbm/gEJ2O7ARrQ9XYpTk+jItHEbItVy/L00r94uXTYeSgaYHyvK1uSTzysnCdGsmL6rz9CfcjSVdw/pLHZVPNHdbu5st0t3kt0m4a480H2uXwiUlnhZe+G2UQ669oNcGXmEuZKL+aCDexHPM9B/PHlOQTTzEuU5898oU1C8fxiheAp7JwvjmkhkaJJ/6JUzzthm/rFJFYxCP+qFPMaBVoRBEpbnFKGxArS9g6+95i1A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=GtZhpCnkEhyJj/pfdycQz/S8rD5bseid1t9Ap7GsNmw=; b=iQsEW3sIJWKy8mWBz8WN3qLnin+VEKijBeyPUXa2EOwM2SG8r3L+3JcD8ws30RCi86jjmv1wbyaYIFXmYOpFl0qTi6F0ZDkzEoK4S0o+77CWWSfdWiEidUxzUrjARRlSA5OiIWMbvO6mHtPaiiFodxP3ZSl21lvBzwZqOkt4wrTSCI4ZAU/PpRw/xnCT+ZqJayBwLyCz8+kFfP28Caz5LHW4TruBDDvfbNGy3kwm2b1XLio2kjPeRAnJoGfCmEAOWlpjvtynMfSV6XQ+1ICqGxfhojpunKPJhXLKe5TQRyMty0jvOAwP/5s2c1cnPXg9RNf5W4Hk6PbKIYMDuiEvpg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=outlook.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=GtZhpCnkEhyJj/pfdycQz/S8rD5bseid1t9Ap7GsNmw=; b=BxEiKe3lJOEePHU5F0ABlt56Ccfuwi8LB4v6pQREgAR2f6UkNdBxViARwwmk5sTmbVSfIcXSZj85otAMPV8EnMuv1U6nr7JYPGPmM6EYVc8oaBNd/VrHahxENzsRl4g4cocdiaQGqkm5z2+oeGzkwfd3ov1LoVfM/m4vR/o/eU9GgewRSYGueQbiIkLXqmjiuOXmDy/RQM1xdNuajj+YTMhzFWR8kRPHJf6LaiMOh2Izy/sRuahDutqLYOGOi2CwMFUry7yStoHUUt6Xrr7s6QE+k/U/3rviKtW6rwEC/DDWh/CvJbi9XCWcZs40lbmXb7/oCwPQS7Pl7v6lMgL9MA== Received: from AS8P250MB0744.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:541::14) by DU2P250MB0062.EURP250.PROD.OUTLOOK.COM (2603:10a6:10:2b7::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7339.37; Sun, 3 Mar 2024 07:54:00 +0000 Received: from AS8P250MB0744.EURP250.PROD.OUTLOOK.COM ([fe80::65aa:deb0:a18e:d48d]) by AS8P250MB0744.EURP250.PROD.OUTLOOK.COM ([fe80::65aa:deb0:a18e:d48d%5]) with mapi id 15.20.7316.023; Sun, 3 Mar 2024 07:54:00 +0000 Message-ID: Date: Sun, 3 Mar 2024 08:55:59 +0100 User-Agent: Mozilla Thunderbird Content-Language: en-US To: ffmpeg-devel@ffmpeg.org References: <85a99241dc108fad30290ffc7524541227c7dfdd.1709422402.git.pross@xvid.org> From: Andreas Rheinhardt In-Reply-To: X-TMN: [S88y0C0rRT5/DT3fUtupEocIsE2gQHRnuOPLZRvYLRg=] X-ClientProxiedBy: FR3P281CA0205.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:a5::17) To AS8P250MB0744.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:541::14) X-Microsoft-Original-Message-ID: <2326590f-9d12-4d82-9431-2b6b1db120d6@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AS8P250MB0744:EE_|DU2P250MB0062:EE_ X-MS-Office365-Filtering-Correlation-Id: 5879f053-06f4-4a53-2c14-08dc3b57160b X-MS-Exchange-SLBlob-MailProps: Cq7lScuPrnqnx/C+6DC/TFA3H0owmKZKYlp+VwhldqvO8t79r9p0Kb1y71IupwNlvDNCsJXnXlStCEIk4AaKAlUZhA2+BU9E0nugQVEW0HO84pANpWEYrd1HEFkm7K6+AubDS5PKJPft2oQaga8OaBimggwwXmQ0CHPS0tv5P3TLQhe4p/0fKrJPyxCQjRcsUwoR6KHpttOk8CJegr9cdFofiDYJzTFe/wEzm+UoEeqN9W2Sr4jjP0CuUDUlL890s6iZ2U2HSIGK0KVAbOq8KvrlpKUOHdmfmZyqMJE9nkjqKQyAoYlZqhwkMWk1+AMj1Vf0hLLkwh0vy6QGMCfZf0Uezb87aVFZ5EVuHnC10aLXat3+9ecosY5V+/5hT0GA7SwxB3Sj2n2mgWgjab/OHvSq/G8vrw7jAH1xE+iikUPmA0stWgy87tk24fQ1u9bQYQjiacYsdElb3ia+Fx6KkbEp9V9bfzCwDWN+i0pjk5rh/KJ9qRn5IMfXP9W3xIRU9AHfN1pM/f8mShamlBVK2yldy+JuwRtLBuaIK0dkrncuma68iMg5rC6BWtyklY6HKxyxdLy86dEeELGUH+svWKL6MQAiJmwhr9v4PlfplKD5TIJw+rP6CdiWQ/IrjezG4Fole1DYiSluu7Vw8hSn63UzEXBFYzVOBZd4Qb5zqGxlWek7FahpQIIk/5SOG2VvzSMf1Vw+jcZMRFVkLBVCeoNq69bBtwSGTrrNMeHz8JFqa8351P00KmB3LIkgHSgxh1s/cfzhFfY= X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Bczk4wvZpZp53SfaZ3iQiCm+OOnswJwxGksaj/uBUyrBTXSNI6p+TD7vUxyrSrmmyz1EOIuC+vCmJHJlAo/W91R+A+wmjZWQJI2vLu24K6PWbFTib65Mqd/KOm5hbLHnmt2C8c8gupHInLKuIRNwHxsSXk9kUdbTtvQA9802wdgisZznbisVrGCZvsB58P3Z0VaJysySRm+j5i4Nt+EAeWCp8eQtPZIgKm4YgwRxgB5eqvbqMpjYzN6mxdcsJMTWRWgoVsvIt8Z34cKKnJ6+KDwta45JtGUeq2Gs1DFzaLxlpBhsWcReTWLUiwhLPNkVwFdEkgCs51ZHI+7a0Rx7AC9XLy7uINZRanT8DOprH3BSP5utOtvcatreQcVqUsb8baZFpYR0uz6AoNMICHZZ3ir/lkD54gvxN/8GUD+PBOpMHwB8kHhJNG7jFYRK4R9/xtkkZ76wfRyrb1sw9IAAK8czygRpqfdeW6qrR/VDS/l/6lD1g4qjBmfTy2GH3tjYs9RPI7ki2YzenClekd92Jc3ubEA8toC5Iq0BGjCtSxbGTSjp3zmuMM+2nAf9HMPu X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?bmlXdGZzK244UXFzWnFHdUNkTVBLSzJjMkJDNWg5NjBCbFV3cUVkSTVpNTN6?= =?utf-8?B?QkJKMTZBb2ZsWDhrQUxhaW1pUGl4VWpCeVVMNXBsZUtBaG5DemRXS1A0STlr?= =?utf-8?B?Qkk4by9vWCtJbVJxS1lEdHJmRHZOckZMQVlwZm1CaldyUkhEamFWMXdLeFNq?= =?utf-8?B?QXE5TWRBcUZGcTF5dEZUOHFSczlrK3hwRVcwbnE1M3BpSE53MDVVRlhma2hU?= =?utf-8?B?NXJ0YVNoWlF5TFAxc1pOQjA2VnArd3hUS01WaVAyOXQ3ZTZReGVuL2xqeWJJ?= =?utf-8?B?S3BMU3JJYlFGREFkbHc2cmxaeVVIUEptUmdGOEZHcVM1T3ZvRmxwUnFXQ1Q0?= =?utf-8?B?N00zN09oKzdHZEpzZWljMVdTamxtSW1JMUl2TmtCckFMZWxjeXl2L3UwTEk4?= =?utf-8?B?RXdrcFhmRFRNVndRbDVLakhCWVRHL21MOHBENTVjaFJDV25YSC8vTVZlQU9W?= =?utf-8?B?V2kwczg3WGVWQTh2cjVad1lxcDVjQ3NmekNZelNOVXJWKzlUdi91WlcyMDNU?= =?utf-8?B?dXp4VEVkbCt0ZlhDNDdaNDFUVEpuMkhUZEJ1MmNEc0k0ZG5vd3VoaE9kTTE5?= =?utf-8?B?VUk4VGhnOGNjajBrVjNvNFYvUjRaWUpaVUFnNmt5Nm9wSC9KS0pESHVDK2Q1?= =?utf-8?B?dmtjbTB4c2IyYTR1SUVBUHBxdGd4Q1FMcVh3VUJqbURIemtVL0FJYXFzM2Fp?= =?utf-8?B?Vkp3a2dzK0tyTDZZRlBtb0grbVdLenpSZFpGYVM1ditpZW5jZlhZNmpSSmhj?= =?utf-8?B?UGZFdVMrQ3ZRS1c2WThoTUlya1JGNllCdXMwU2JrakpieDgwYXVZUEMyN2dS?= =?utf-8?B?V3Yrb3MrRkQyZ3dnYm93c0YvKzJ0ZkV6NXlQN0JPUExMUkJkRGRlRUNBYVZk?= =?utf-8?B?Q3JGWU9BWXZJWkpTL0d5TFY2NnhYVXpoK3duTUEyaFk3RlpXYTZXT2NJWDNr?= =?utf-8?B?eXdQb1ZzdGJ3TlRKcnJ3WEFMdHgyNHF4UHpBc2JGRHJrdHd2bHl0aFVaRGNB?= =?utf-8?B?YWUzYVJMMmV6clFFQTQ0aytOaTFOR3UrQ3llQWV3ejZ4UDBBRTJ1QTU4ODFG?= =?utf-8?B?YVkwNStkcTQrSkdpeGhXZm51NXFDMmVFS0RTY21RTE5USEs1R3I3NXI0SE5G?= =?utf-8?B?Nm5sS0xmUmdiRG1PMmhBbWlMWWNzRWNFN3VNUUUwcXdQZmFSaWNNaXY2ZitO?= =?utf-8?B?NHhkakFlb1RPZytaak85K2ZlM2R3VXZndHcrZUpidUUwMG9uSis1bU9NWHZO?= =?utf-8?B?QjZaWXk0Vllob25TeEhWYWVGWXdjb0RiMDd1bysvd2tNa0s2MlFLbmFoWlR4?= =?utf-8?B?ZFFKVFhRYWZ2WWRFWitySitIVWJpVTJEY1k4d0VCZEZXd0k1QWNWZC9QRThQ?= =?utf-8?B?NndzUkFNbm9jNEdpclN6eXJMNXloZGdsZnFoTm5VbVN1am9JQ3NGQ2ZtVHAr?= =?utf-8?B?ZkY4VWVrWCtiU1RlblkxdnRCWVBVa1dLK1ZVS1daOHhuSUtuZHNkRHpmazgz?= =?utf-8?B?VC9ETlZmcEFpOHo0endXNWc3ZmdvbmpqTkIxcGc5WHhqZ0RtSzNqWkhWVkRI?= =?utf-8?B?OWhrOHhsUUNDNmRxWFlubTNnMzBCUVZlczVtbHVIa2RwbWp0K1Vwc1pVS3Fk?= =?utf-8?B?MktGV2FXMzcvRGljVUEvUGpOc1VVZlVLajR4OHREbXYzcFAvWmVkTkNaMUJk?= =?utf-8?B?eEduOEkxa3BsVjcwdmtoMG9RQWx4SmNHRk5jblh0Szg2SlRXVTNBVkxBPT0=?= X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 5879f053-06f4-4a53-2c14-08dc3b57160b X-MS-Exchange-CrossTenant-AuthSource: AS8P250MB0744.EURP250.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Mar 2024 07:53:59.9457 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU2P250MB0062 Subject: Re: [FFmpeg-devel] [PATCH 2/3] avcodec/rv60: RealVideo 6.0 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-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: Peter Ross: > Reviewed-by: Anton Khirnov > Reviewed-by: Andreas Rheinhardt > Signed-off-by: Peter Ross > --- > libavcodec/Makefile | 1 + > libavcodec/allcodecs.c | 1 + > libavcodec/codec_desc.c | 7 + > libavcodec/codec_id.h | 1 + > libavcodec/rv60data.h | 118 ++ > libavcodec/rv60dec.c | 2419 +++++++++++++++++++++++++++++++++++++++ > libavcodec/rv60dsp.c | 164 +++ > libavcodec/rv60dsp.h | 30 + > libavcodec/rv60vlcs.h | 2315 +++++++++++++++++++++++++++++++++++++ > libavformat/riff.c | 1 + > libavformat/rm.c | 1 + > 11 files changed, 5058 insertions(+) > create mode 100644 libavcodec/rv60data.h > create mode 100644 libavcodec/rv60dec.c > create mode 100644 libavcodec/rv60dsp.c > create mode 100644 libavcodec/rv60dsp.h > create mode 100644 libavcodec/rv60vlcs.h > > diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c > index 033344304c..2ed6ce0953 100644 > --- a/libavcodec/codec_desc.c > +++ b/libavcodec/codec_desc.c > @@ -1967,6 +1967,13 @@ static const AVCodecDescriptor codec_descriptors[] = { > .long_name = NULL_IF_CONFIG_SMALL("LEAD MCMP"), > .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, > }, > + { > + .id = AV_CODEC_ID_RV60, > + .type = AVMEDIA_TYPE_VIDEO, > + .name = "rv60", > + .long_name = NULL_IF_CONFIG_SMALL("RealVideo 6.0"), > + .props = AV_CODEC_PROP_LOSSY, Missing AV_CODEC_PROP_REORDER > + }, > > /* various PCM "codecs" */ > { > diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h > index d96e49430e..3be0dda20e 100644 > --- a/libavcodec/codec_id.h > +++ b/libavcodec/codec_id.h > @@ -325,6 +325,7 @@ enum AVCodecID { > AV_CODEC_ID_RTV1, > AV_CODEC_ID_VMIX, > AV_CODEC_ID_LEAD, > + AV_CODEC_ID_RV60, > > /* various PCM "codecs" */ > AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs > diff --git a/libavcodec/rv60data.h b/libavcodec/rv60data.h > new file mode 100644 > index 0000000000..65f9853770 > --- /dev/null > +++ b/libavcodec/rv60data.h > @@ -0,0 +1,118 @@ > +/* > + * RV60 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 > + */ > + > +#ifndef AVCODEC_RV60DATA_H > +#define AVCODEC_RV60DATA_H > + > +#include > + > +static const uint8_t rv60_candidate_intra_angles[6] = { > + 0, 1, 10, 26, 18, 2 > +}; > + > +static const uint8_t rv60_ipred_angle[9] = { > + 0, 2, 5, 9, 13, 17, 21, 26, 32 > +}; > + > +static const uint16_t rv60_ipred_inv_angle[9] = { > + 0, 4096, 1638, 910, 630, 482, 390, 315, 256 > +}; > + > +static const uint8_t rv60_avail_mask[64] = { > + 0, 1, 0, 3, 0, 1, 0, 7, 0, 1, 0, 3, 0, 1, 0, 0xF, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 > +}; > + > +static const uint8_t rv60_edge1[4] = { > + 0, 2, 2, 2 > +}; > + > +static const uint8_t rv60_edge2[4] = { > + 0, 3, 3, 3 > +}; > + > +static const uint8_t rv60_qp_to_idx[64] = { > + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, > + 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 0, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, > + 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0 > +}; > + > +static const uint16_t rv60_quants_b[32] = { > + 60, 67, 76, 85, 96, 108, 121, 136, > + 152, 171, 192, 216, 242, 272, 305, 341, > + 383, 432, 481, 544, 606, 683, 767, 854, > + 963, 1074, 1212, 1392, 1566, 1708, 1978, 2211 > +}; > + > +static const uint16_t rv60_chroma_quant_dc[32] = { > + 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, > + 14, 15, 15, 16, 17, 18, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23 > +}; > + > +static const uint16_t rv60_chroma_quant_ac[32] = { > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, > + 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25 > +}; These two tables can use uint8_t. Or given that they are only used via rv60_quants_b[rv60_chroma_quant_[ad]c[qp]] one could replace them with uint16_t arrays that avoid the indirection. ... > +static VLC cbp8_vlc[7][4]; > +static VLC cbp16_vlc[7][3][4]; > + > +typedef struct { > + VLC l0[2]; > + VLC l12[2]; > + VLC l3[2]; > + VLC esc; > +} CoeffVLCs; > + > +static CoeffVLCs intra_coeff_vlc[5]; > +static CoeffVLCs inter_coeff_vlc[7]; > + You do not need full VLC structures, only VLC.table is ever used, because all VLCs here use nine bits. So you can replace e.g. cbp8_vlc by static const VLCElem *cbp8_vlc[7][4] and switch to ff_vlc_init_tables() (replace the int offset by VLCInitState for this). > +#define MAX_VLC_SIZE 864 > +static VLCElem table_data[129148]; > + > +/* 32-bit version of rv34_gen_vlc */ > +static void gen_vlc(const uint8_t *bits, int size, VLC *vlc, int *offset) > +{ > + int counts[17] = {0}; > + uint32_t codes[18]; > + uint32_t cw[MAX_VLC_SIZE]; > + > + for (int i = 0; i < size; i++) > + counts[bits[i]]++; > + > + codes[0] = counts[0] = 0; > + for (int i = 0; i < 17; i++) > + codes[i+1] = (codes[i] + counts[i]) << 1; > + > + for (int i = 0; i < size; i++) > + cw[i] = codes[bits[i]]++; > + > + vlc->table = &table_data[*offset]; > + vlc->table_allocated = FF_ARRAY_ELEMS(table_data) - *offset; > + ff_vlc_init_sparse(vlc, 9, size, > + bits, 1, 1, > + cw, 4, 4, > + NULL, 0, 0, VLC_INIT_STATIC_OVERLONG); > + *offset += vlc->table_size; > +} > + > +static void build_coeff_vlc(const CoeffLens * lens, CoeffVLCs * vlc, int count, int * offset) > +{ > + for (int i = 0; i < count; i++) { > + for (int j = 0; j < 2; j++) { > + gen_vlc(lens[i].l0[j], 864, &vlc[i].l0[j], offset); > + gen_vlc(lens[i].l12[j], 108, &vlc[i].l12[j], offset); > + gen_vlc(lens[i].l3[j], 108, &vlc[i].l3[j], offset); > + } > + gen_vlc(lens[i].esc, 32, &vlc[i].esc, offset); > + } > +} > + > +static av_cold void rv60_init_static_data(void) > +{ > + int offset = 0; > + > + for (int i = 0; i < 7; i++) > + for (int j = 0; j < 4; j++) > + gen_vlc(rv60_cbp8_lens[i][j], 64, &cbp8_vlc[i][j], &offset); > + > + for (int i = 0; i < 7; i++) > + for (int j = 0; j < 3; j++) > + for (int k = 0; k < 4; k++) > + gen_vlc(rv60_cbp16_lens[i][j][k], 64, &cbp16_vlc[i][j][k], &offset); > + > + build_coeff_vlc(rv60_intra_lens, intra_coeff_vlc, 5, &offset); > + build_coeff_vlc(rv60_inter_lens, inter_coeff_vlc, 7, &offset); > +} > + > +typedef struct { > + int sign; > + int size; > + const uint8_t * data; > + int data_size; > +} Slice; > + > +typedef struct { > + int cu_split_pos; > + uint8_t cu_split[1+4+16+64]; > + > + uint8_t coded_blk[64]; > + > + uint8_t avg_buffer[64*64 + 32*32*2]; > + AVFrame avg_buf; Don't do this. Just store uint8_t *avg_buf[3] and int avg_buf_linesize[3] and switch the two functions using avg_buf to accept the data pointers and linesizes separately (for the output frame, not for the ref frame). > +} ThreadContext; > + > +typedef struct { > + int16_t x; > + int16_t y; > +} MV; > + > +typedef struct { > + enum MVRefEnum mvref; > + MV f_mv; > + MV b_mv; > +} MVInfo; > + > +typedef struct { > + enum IntraMode imode; > + MVInfo mv; > +} BlockInfo; > + > +typedef struct { > + enum CUType cu_type; > + enum PUType pu_type; > +} PUInfo; > + > +typedef struct RV60Context { > + AVCodecContext * avctx; > + VideoDSPContext vdsp; > + > +#define CUR_PIC 0 > +#define LAST_PIC 1 > +#define NEXT_PIC 2 > + AVFrame *last_frame[3]; > + > + int pict_type; > + int qp; > + int osvquant; > + int ts; > + int two_f_refs; > + int qp_off_type; > + int deblock; > + int deblock_chroma; > + int awidth; > + int aheight; > + int cu_width; > + int cu_height; > + > + Slice * slice; > + > + int pu_stride; > + PUInfo * pu_info; > + > + int blk_stride; > + BlockInfo * blk_info; > + > + int dblk_stride; > + uint8_t * left_str; > + uint8_t * top_str; > + > + uint64_t ref_pts[2], ts_scale; > + uint32_t ref_ts[2]; > +} RV60Context; > + > +static av_cold int rv60_decode_init(AVCodecContext * avctx) > +{ > + static AVOnce init_static_once = AV_ONCE_INIT; > + RV60Context *s = avctx->priv_data; > + int ret; > + > + s->avctx = avctx; > + > + if (avctx->active_thread_type & FF_THREAD_SLICE) { > + ret = ff_slice_thread_init_progress(avctx); > + if (ret < 0) > + return ret; > + } > + > + ff_videodsp_init(&s->vdsp, 8); Missing configure dependency for this > + > + avctx->pix_fmt = AV_PIX_FMT_YUV420P; > + > + for (int i = 0; i < 3; i++) { > + s->last_frame[i] = av_frame_alloc(); > + if (!s->last_frame[i]) > + return AVERROR(ENOMEM); > + } > + > + ff_thread_once(&init_static_once, rv60_init_static_data); > + > + return 0; > +} > + ... > + > +static int rv60_decode_frame(AVCodecContext *avctx, AVFrame * frame, > + int * got_frame, AVPacket * avpkt) > +{ > + RV60Context *s = avctx->priv_data; > + GetBitContext gb; > + int ret, header_size, width, height, ofs; > + > + if (avpkt->size == 0) { > + if (s->last_frame[NEXT_PIC]->data[0]) { > + av_frame_move_ref(frame, s->last_frame[NEXT_PIC]); > + *got_frame = 1; > + } > + return 0; > + } > + > + if (avpkt->size < 9) > + return AVERROR_INVALIDDATA; > + > + header_size = avpkt->data[0] * 8 + 9; > + if (avpkt->size < header_size) > + return AVERROR_INVALIDDATA; > + > + init_get_bits8(&gb, avpkt->data + header_size, avpkt->size - header_size); > + > + if ((ret = read_frame_header(s, &gb, &width, &height)) < 0) > + return ret; > + > + if (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B || > + avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I || > + avctx->skip_frame >= AVDISCARD_ALL) > + return avpkt->size; > + > + if (s->pict_type != AV_PICTURE_TYPE_B) > + FFSWAP(AVFrame *, s->last_frame[NEXT_PIC], s->last_frame[LAST_PIC]); > + > + if ((s->pict_type == AV_PICTURE_TYPE_P && !s->last_frame[LAST_PIC]->data[0]) || > + (s->pict_type == AV_PICTURE_TYPE_B && (!s->last_frame[LAST_PIC]->data[0] || !s->last_frame[NEXT_PIC]->data[0]))) { > + av_log(s->avctx, AV_LOG_ERROR, "missing reference frame\n"); > + return AVERROR_INVALIDDATA; > + } > + > + s->last_frame[CUR_PIC]->pict_type = s->pict_type; > + if (s->pict_type == AV_PICTURE_TYPE_I) > + s->last_frame[CUR_PIC]->flags |= AV_FRAME_FLAG_KEY; > + > + if ((ret = update_dimensions_clear_info(s, width, height)) < 0) > + return ret; > + > + if ((ret = ff_reget_buffer(avctx, s->last_frame[CUR_PIC], 0)) < 0) > + return ret; ff_reget_buffer() might have to perform a full-frame copy. Why do you use it? > + > + if ((ret = read_slice_sizes(s, &gb)) < 0) > + return ret; > + > + ofs = get_bits_count(&gb) / 8; > + > + for (int i = 0; i < s->cu_height; i++) { > + s->slice[i].data = avpkt->data + header_size + ofs; > + s->slice[i].data_size = FFMIN(s->slice[i].size, avpkt->size - header_size - ofs); > + ofs += s->slice[i].size; > + } > + > + if (ffcodec(avctx->codec)->update_thread_context) > + ff_thread_finish_setup(avctx); This seems to have been copied from VP8; but the check is always false here and ff_thread_finish_setup is unnecessary, as this decoder does not support frame threads. > + > + ret = ff_slice_thread_allocz_entries(s->avctx, s->cu_height); > + if (ret < 0) > + return ret; > + > + s->avctx->execute2(s->avctx, decode_slice, s->last_frame[CUR_PIC], NULL, s->cu_height); > + > + ret = 0; > + if (s->pict_type == AV_PICTURE_TYPE_B) > + av_frame_move_ref(frame, s->last_frame[CUR_PIC]); > + else if (s->last_frame[LAST_PIC]->data[0]) > + ret = av_frame_ref(frame, s->last_frame[LAST_PIC]); > + if (ret < 0) > + return ret; > + > + if (s->last_frame[LAST_PIC]->data[0]) Why not check for frame->data[0]? Seems clearer to me. And it would work if one implemented low-delay (i.e. where it is presumed that no b-frames are present). > + *got_frame = 1; > + > + if (s->pict_type != AV_PICTURE_TYPE_B) > + FFSWAP(AVFrame *, s->last_frame[CUR_PIC], s->last_frame[NEXT_PIC]); > + > + if (s->pict_type != AV_PICTURE_TYPE_B) { > + s->ref_pts[0] = s->ref_pts[1]; > + s->ref_pts[1] = avpkt->pts; > + > + s->ref_ts[0] = s->ref_ts[1]; > + s->ref_ts[1] = s->ts; > + > + if (s->ref_pts[1] > s->ref_pts[0] && s->ref_ts[1] > s->ref_ts[0]) > + s->ts_scale = (s->ref_pts[1] - s->ref_pts[0]) / (s->ref_ts[1] - s->ref_ts[0]); > + } else { > + frame->pts = s->ref_pts[0] + (s->ts - s->ref_ts[0]) * s->ts_scale; > + } > + > + return avpkt->size; > +} > + > +static void rv60_flush(AVCodecContext *avctx) > +{ > + RV60Context *s = avctx->priv_data; > + > + for (int i = 0; i < 3; i++) > + av_frame_unref(s->last_frame[i]); > +} > + > +static av_cold int rv60_decode_end(AVCodecContext * avctx) > +{ > + RV60Context *s = avctx->priv_data; > + > + for (int i = 0; i < 3; i++) > + av_frame_free(&s->last_frame[i]); > + > + av_freep(&s->slice); > + av_freep(&s->pu_info); > + av_freep(&s->blk_info); > + av_freep(&s->top_str); > + av_freep(&s->left_str); > + > + return 0; > +} > + > +const FFCodec ff_rv60_decoder = { > + .p.name = "rv60", > + CODEC_LONG_NAME("RealVideo 6.0"), > + .p.type = AVMEDIA_TYPE_VIDEO, > + .p.id = AV_CODEC_ID_RV60, > + .priv_data_size = sizeof(RV60Context), > + .init = rv60_decode_init, > + .close = rv60_decode_end, > + FF_CODEC_DECODE_CB(rv60_decode_frame), > + .flush = rv60_flush, > + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, > + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, > +}; _______________________________________________ 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".