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 3532646B97 for ; Mon, 4 Sep 2023 11:27:35 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C390B68C735; Mon, 4 Sep 2023 14:27:33 +0300 (EEST) Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05olkn2107.outbound.protection.outlook.com [40.92.90.107]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E97B868C07A for ; Mon, 4 Sep 2023 14:27:27 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=CKM//zPcMGfyYKptcMbW7GJMDcphRbow5O7iG+GmyUngLaisKYqRhD2FR+/ZJEurlni3Bl/FwfSAlJ6uzRYHwncxUc7CHlppJCW0hqHqLVex327Gtd9QP5DUi8fPDpplpa7z7Vt5kG/tGE311yJKqCx/e7cY1fIyV+Na1sBfrdrSs8jK50fhDxGfSVa3mA8DvwYmnHVU+EfXG1ZABRFMQ+wn9qw9VAUSICDtGy/mRTiTneudFKFvOTWbpvFZiH2z7zOdf8w6xxDKpvhN3w8bRJI4SosmmC/+lwh0uNXl3CMirYDBz/dYN/nwMvyBqC2uKi+rPbYwfUX3VmFvJdaiMw== 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=dJMtq/puR/S2ecl1rq7aQZT1jS7wb4d2/vWaQMzbrlY=; b=iNcrSgcdybacu/bL4ZxHnEokW/liFd2pw7/dHj2/ayzM/FsbFyKbjMOa77JRrhL8MB+eeUO3P7uK65I9h++eKQoHYs/9jAYtSINJnPWwLrnyXV1cGAu36p84ZvQt0hcWupEyzU3MBHj8rMFR1CUO3v9bqO4uHoa01od019DMrRLjI63ZiBrM6laZYOPFu4OtlEnS4SPquVNdP6n3S3pWQTBBj9JaDCPLkwCDmasnlUiS4sbiklIMzDFmxe1AWsFlsantxX650+ecDkPYq5l+06o5guE2pTaLuvQMY8ldY6LURc4J3gBcft6zx0+VGQWnyHFBDQO5iI9k17YavOPonw== 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=dJMtq/puR/S2ecl1rq7aQZT1jS7wb4d2/vWaQMzbrlY=; b=nwffAX4zEVgMCBHSctGNWwOxQJf55sshAdrqsw5L/cNj0CSfaX9Qz80/Zjm1yD+h+FamDO99s4PQGljzStskKA19uTOoMYUI+N1E2uI9R6oB949CcywuiLCT+Oy+j8jfXzuG3tdpU2NonUl+vlgW/z51Hj07gcz2NEKm/x+f/7Zh705pFBp/aYlf6Ht7SiwaA7qPxJK0Z7rlHgPRw9KfNoE9OolxY3/BLbaTD0K48xz1Z5M8oyR8ek7WyRI6ti0nvVPBemZpgZWNou0ELXa0OXMY9M16HpZKcqOLqXSsNVo+G7KUtsdYecQD16zBamHR9HVhusU+hwWmfN/0kHucgg== Received: from AS8P250MB0744.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:541::14) by AM8P250MB0280.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:32b::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6745.32; Mon, 4 Sep 2023 11:27:25 +0000 Received: from AS8P250MB0744.EURP250.PROD.OUTLOOK.COM ([fe80::5e01:aea5:d3a8:cafa]) by AS8P250MB0744.EURP250.PROD.OUTLOOK.COM ([fe80::5e01:aea5:d3a8:cafa%3]) with mapi id 15.20.6745.030; Mon, 4 Sep 2023 11:27:25 +0000 From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Mon, 4 Sep 2023 13:27:45 +0200 Message-ID: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: X-TMN: [WIZ3mc0+cO2W4ekSsFaCajxbsDVtuHTRSQgf+A9n1/g=] X-ClientProxiedBy: ZR2P278CA0078.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:65::13) To AS8P250MB0744.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:541::14) X-Microsoft-Original-Message-ID: <20230904112759.2652347-5-andreas.rheinhardt@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AS8P250MB0744:EE_|AM8P250MB0280:EE_ X-MS-Office365-Filtering-Correlation-Id: 5d90ad4b-18ad-4db3-bda8-08dbad39ea08 X-MS-Exchange-SLBlob-MailProps: 5R4zPSLKzf6+w+o6/UT3FLs7gZOlUbrC5EjOHMLKUWcJ+aME8QPYxpZ95lf5aeaRnKWrK0kFYaXWw76a0pnLcZ5ECA6w0QLJS62WxVVPf7WmcR7F/icA9gS9xbnppUpIBMB5PQf12uXTYw8EoeANrk43DbuaZ0OujLnlHQgPBLpVVdt4Sx+8nOR8Hnuqz8/NiIwoOqOadyGFcuM1V3SdHrOdb424ZAUB+l60ljD81cPHA/ihxGVezNtQ0IC/v/EWxIJ+gZwCfoT3Luhpd+YRGSI6kiSWKP9CBrYcjFUmLNsy6Sw7m8ggduhXWknRA04Q85J1+kceu9tFeYtiFFovMe7aqo593Pidqd9OZnNaDD3bztwcZdmLSPsRv+0LSn65oUQL5h7kmNPceWkvv9zB0atVxlxl2kWEIKzOvsX1oPNQXsQwm2wo4FcQjih2CcKgPPWBXktLMgEVAzpTkUj2u68FObIN6bVyjqY5hAc/8eWE3HEm2O/Ym9hf8ctHzDlrkQGSSSvXxFZmTwBcanBeaw/8QJ4MKgqLGmWz6sGGuqGSTMhXVQi8aaQ9Q26FAfG3oKwdN5MPXx33zCQrVzVbLeEjvQ2Wt9j1ASBfnPlj8ZtGGD1Kxwt6+Pq0IODZZBxpHiNg5NoTfJb7TNTAYenZhe8PnMLO3pv1NAJAmeE8NXTCRIZNIR4m0S01pRG3xEdmJqxqp73BI6LvrR1x69L9nnieqmfVWWgnehk+sOdtiL38H9fIToZVSErzIPDs0vz0k7xeHfJgpbQIg0nDcgKSWMCYz/T1G9+rv+nE2CCRpnZjxIK+npS4oUsc8EBRDxUuR6LbHWFxAa8oGR2Z4ffxcoyQQ+2RI+bQ X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 4M5o1Qrjn/UYMRaUue5ljbjcsz3YJlBgdAkigFmGyPUR4V6Pe0s48EWsizyHQTEyKCUU8jr7na3X/xxAHD5MJX78Ifvk2wM19W63+I3bNwDl55ECihyEZweRrUcXho32WbKphBLF7MLSMeRAclmJDaF5PwXHmrSNO5+OGPUeyp3BF9jM3IpUU6uisBGgwXHP0mWl9bRj4awSO3Ngg9paaGH6xCsgOR9++wM+/Rwu6ATUgxvi4fEqO3I6vqNZX+cG1FIGnThi5IhNuE3qlxtNhG7Hoie8uzJ6TcmB66KQGKLiZJlpnXwLUeKO1gtiUCR/f6Yb3tImd85AtYI2sX1H9pqDBTym/9jdqnGMsUwuZBoRS495gEWtaO04UYRLkGwo1zJRH7Y/VYassFfwM2aO9qDx5UL1RydHUanWtgFNye7sTmIlWwJLOR0twBOFOnDceGBP25305bu4cWzMJIgyzoZWsyEm8I93ygCrvQdKBEUYb0PhSqILVcV1SzGqAjQd9GakbmoamupC9oQWpJaKFIDT/896YkgwGlAFd8aoWQ7MqzrkBPX2LTCWhAjneBVTwTROG7eTr1jkQtrmL50k7IeOc5rE0CmwcJRuheAGDdTwz92rmHiYadJVUBgSnMLs X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?jZYiLtCWOJemol/f+DYU0PgXXmofrD5xTP8NUvyWvw4VNFVYmbRQ8IGA23d+?= =?us-ascii?Q?L3KnZi/iI0CCdkT4WFPm5Fm16Ghf3FkpNhOQDte/9E0qOYlwDIcvc8Krjeo4?= =?us-ascii?Q?mnlWy4lufJtT9LOOLYmmt/oqMZ3ug1cDhe7zrP9Xer8ksQMWf2tdR3irQXB0?= =?us-ascii?Q?BHcuP7EAY+M63hdltsI9nMVzPwlOQ727c0+TnVHaWYs3n0UGTeHvNgYWULG4?= =?us-ascii?Q?lgReFhKFNbHgSrGRutKeqNpjllfOl4Vv2TZhCs0OgSzf6u1Kw5mI4kOnc46Z?= =?us-ascii?Q?dSSFC2mAPY5da/ypB44d7OJLLCYipguFBTpPgieMBZQrFZxQDJAhhcHD72Ee?= =?us-ascii?Q?oWuLy3bN0tKXUC/sKoihc/sOiB3T0bdSrDJ1fp0LQhTNgejcgmBv2X4sL9ot?= =?us-ascii?Q?FSb58fVCB++wQ6C0ku7QZo03quuLf4eTXvVVeIwqaDCvPj2TUz2kGcsunIxl?= =?us-ascii?Q?UBcjVBzOwgrs10bekhG1GPzjM7mDJrdUArv5XW77E2gOugGvLCLAwxgong74?= =?us-ascii?Q?/p6FllU8uFVj2U5/B7g99+K7Gt3YJc65p5mmP0mz4xifQE0UzRLrwPdW08Rb?= =?us-ascii?Q?0hdDGk/Z5XTBlA19ZbKswFQbkekyA1Mv8XZ4fEA0RNG6dQyCMIv8u9OIwQBF?= =?us-ascii?Q?LAdhYR6sG4K/tZc/xjkjgokNiQr5StC4rkiQMuREJolOrRCjeR9RgVbHP30c?= =?us-ascii?Q?iHaIdmM1SELPJSYJ7Cx3uQTJHiXFTe6YwGhjq5HD1XBHFflJRs2zOFag1Ive?= =?us-ascii?Q?EG0QK6l6Z/tWewiV0heTKceZ5/TRmc2K7mwdy3gZpmf2h2Regj9zzN17vHOj?= =?us-ascii?Q?+aeLTdAbKCzwtbuzceWrmGUh8ig1q+CRxctIbQrs+EBVSSnCp3rWFx5F/KOP?= =?us-ascii?Q?ZLwoWP7MSyxZzLWfv/Xr+ogRmEIkJt6An+wgJj7WDGMaAyLi4J7aQ6QCkKnn?= =?us-ascii?Q?40qR7+3O/g6kNVjb0XvINtHdQFgVWRIrZVVLpPanvY2ucNGdY43YorHG0PGi?= =?us-ascii?Q?51QKQ350j7wl9h1CVKLjWCEuyVuf8An3gIyiMD7FMySGBPJ2+fTmTqqx3wyu?= =?us-ascii?Q?FfqwnWK4aAnj3WBch/puI0BcIEMD/Jp7XORjMWgI3KZQOEwIwiNMJdWJMTy0?= =?us-ascii?Q?ZYtxzZGHL8ZS+NdF1vGYnyFpc28WRXcIUslNMNmkgR7PMuqBHAjXtL0nCHVk?= =?us-ascii?Q?W1Vd4PmceZzUucny3Qf+g/jabavmfVuAQwqAjKBpfU1IyvoGLK2MBQmrsNlt?= =?us-ascii?Q?RpDGgYP52a1OcETtWTKM?= X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 5d90ad4b-18ad-4db3-bda8-08dbad39ea08 X-MS-Exchange-CrossTenant-AuthSource: AS8P250MB0744.EURP250.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 04 Sep 2023 11:27:25.6833 (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: AM8P250MB0280 Subject: [FFmpeg-devel] [PATCH 06/20] avformat/matroskdec: Factor audio parsing out of matroska_parse_tracks() 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 Cc: Andreas Rheinhardt 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: More exactly, factor codec-specific audio parsing out of matroska_parse_tracks(). This is intended to improve readability. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskadec.c | 424 ++++++++++++++++++++++---------------- 1 file changed, 243 insertions(+), 181 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index e1524a5943..8846e9358d 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -2501,9 +2501,241 @@ static int get_qt_codec(MatroskaTrack *track, uint32_t *fourcc, enum AVCodecID * return 0; } +/* An enum with potential return values of the functions for parsing a track. + * Apart from that all these functions can also indicate ordinary errors via + * negative return values. */ +enum { + SKIP_TRACK = 1, +}; + #define AAC_MAX_EXTRADATA_SIZE 5 #define TTA_EXTRADATA_SIZE 22 #define WAVPACK_EXTRADATA_SIZE 2 +/* Performs the codec-specific part of parsing an audio track. */ +static int mka_parse_audio_codec(MatroskaTrack *track, AVCodecParameters *par, + const MatroskaDemuxContext *matroska, + AVFormatContext *s, int *extradata_offset) +{ + uint8_t extradata[FFMAX3(AAC_MAX_EXTRADATA_SIZE, + TTA_EXTRADATA_SIZE, + WAVPACK_EXTRADATA_SIZE)]; + int extradata_size = 0; // > 0 means that the extradata buffer is used + int ret; + + if (!strcmp(track->codec_id, "A_MS/ACM") && + track->codec_priv.size >= 14 && + track->codec_priv.data) { + FFIOContext b; + int ret; + ffio_init_context(&b, track->codec_priv.data, + track->codec_priv.size, + 0, NULL, NULL, NULL, NULL); + ret = ff_get_wav_header(s, &b.pub, par, + track->codec_priv.size, 0); + if (ret < 0) + return ret; + *extradata_offset = FFMIN(track->codec_priv.size, 18); + return 0; + } else if (!strcmp(track->codec_id, "A_QUICKTIME") + /* Normally 36, but allow noncompliant private data */ + && (track->codec_priv.size >= 32) + && (track->codec_priv.data)) { + enum AVCodecID codec_id; + uint32_t fourcc; + uint16_t sample_size; + int ret = get_qt_codec(track, &fourcc, &codec_id); + if (ret < 0) + return ret; + sample_size = AV_RB16(track->codec_priv.data + 26); + if (fourcc == 0) { + if (sample_size == 8) { + fourcc = MKTAG('r','a','w',' '); + codec_id = ff_codec_get_id(ff_codec_movaudio_tags, fourcc); + } else if (sample_size == 16) { + fourcc = MKTAG('t','w','o','s'); + codec_id = ff_codec_get_id(ff_codec_movaudio_tags, fourcc); + } + } + if ((fourcc == MKTAG('t','w','o','s') || + fourcc == MKTAG('s','o','w','t')) && + sample_size == 8) + codec_id = AV_CODEC_ID_PCM_S8; + par->codec_id = codec_id; + par->codec_tag = fourcc; + return 0; + } + + switch (par->codec_id) { + case AV_CODEC_ID_PCM_S16BE: + switch (track->audio.bitdepth) { + case 8: + par->codec_id = AV_CODEC_ID_PCM_U8; + break; + case 24: + par->codec_id = AV_CODEC_ID_PCM_S24BE; + break; + case 32: + par->codec_id = AV_CODEC_ID_PCM_S32BE; + break; + } + break; + case AV_CODEC_ID_PCM_S16LE: + switch (track->audio.bitdepth) { + case 8: + par->codec_id = AV_CODEC_ID_PCM_U8; + break; + case 24: + par->codec_id = AV_CODEC_ID_PCM_S24LE; + break; + case 32: + par->codec_id = AV_CODEC_ID_PCM_S32LE; + break; + } + break; + case AV_CODEC_ID_PCM_F32LE: + if (track->audio.bitdepth == 64) + par->codec_id = AV_CODEC_ID_PCM_F64LE; + break; + case AV_CODEC_ID_AAC: + if (!track->codec_priv.size) { + int profile = matroska_aac_profile(track->codec_id); + int sri = matroska_aac_sri(track->audio.samplerate); + + extradata[0] = (profile << 3) | ((sri & 0x0E) >> 1); + extradata[1] = ((sri & 0x01) << 7) | (track->audio.channels << 3); + if (strstr(track->codec_id, "SBR")) { + sri = matroska_aac_sri(track->audio.out_samplerate); + extradata[2] = 0x56; + extradata[3] = 0xE5; + extradata[4] = 0x80 | (sri << 3); + extradata_size = 5; + } else + extradata_size = 2; + } + break; + case AV_CODEC_ID_ALAC: + if (track->codec_priv.size && track->codec_priv.size < INT_MAX - 12 - AV_INPUT_BUFFER_PADDING_SIZE) { + /* Only ALAC's magic cookie is stored in Matroska's track headers. + * Create the "atom size", "tag", and "tag version" fields the + * decoder expects manually. */ + ret = ff_alloc_extradata(par, 12 + track->codec_priv.size); + if (ret < 0) + return ret; + AV_WB32(par->extradata, par->extradata_size); + AV_WB32(&par->extradata[4], MKBETAG('a', 'l', 'a', 'c')); + AV_WB32(&par->extradata[8], 0); + memcpy(&par->extradata[12], track->codec_priv.data, + track->codec_priv.size); + } + break; + case AV_CODEC_ID_TTA: + { + uint8_t *ptr; + if (track->audio.channels > UINT16_MAX || + track->audio.bitdepth > UINT16_MAX) { + av_log(matroska->ctx, AV_LOG_WARNING, + "Too large audio channel number %"PRIu64 + " or bitdepth %"PRIu64". Skipping track.\n", + track->audio.channels, track->audio.bitdepth); + if (matroska->ctx->error_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; + else + return SKIP_TRACK; + } + if (track->audio.out_samplerate < 0 || track->audio.out_samplerate > INT_MAX) + return AVERROR_INVALIDDATA; + extradata_size = TTA_EXTRADATA_SIZE; + ptr = extradata; + bytestream_put_be32(&ptr, AV_RB32("TTA1")); + bytestream_put_le16(&ptr, 1); + bytestream_put_le16(&ptr, track->audio.channels); + bytestream_put_le16(&ptr, track->audio.bitdepth); + bytestream_put_le32(&ptr, track->audio.out_samplerate); + bytestream_put_le32(&ptr, av_rescale(matroska->duration * matroska->time_scale, + track->audio.out_samplerate, + AV_TIME_BASE * 1000)); + break; + } + case AV_CODEC_ID_RA_144: + track->audio.out_samplerate = 8000; + track->audio.channels = 1; + break; + case AV_CODEC_ID_RA_288: + case AV_CODEC_ID_COOK: + case AV_CODEC_ID_ATRAC3: + case AV_CODEC_ID_SIPR: + { + const uint8_t *ptr = track->codec_priv.data; + int flavor; + + if (!track->codec_priv.size) + break; + + if (track->codec_priv.size < 46) + return AVERROR_INVALIDDATA; + ptr += 22; + flavor = bytestream_get_be16(&ptr); + track->audio.coded_framesize = bytestream_get_be32(&ptr); + ptr += 12; + track->audio.sub_packet_h = bytestream_get_be16(&ptr); + track->audio.frame_size = bytestream_get_be16(&ptr); + track->audio.sub_packet_size = bytestream_get_be16(&ptr); + if (track->audio.coded_framesize <= 0 || + track->audio.sub_packet_h <= 0 || + track->audio.frame_size <= 0) + return AVERROR_INVALIDDATA; + + if (par->codec_id == AV_CODEC_ID_RA_288) { + if (track->audio.sub_packet_h & 1 || 2 * track->audio.frame_size + != (int64_t)track->audio.sub_packet_h * track->audio.coded_framesize) + return AVERROR_INVALIDDATA; + par->block_align = track->audio.coded_framesize; + track->codec_priv.size = 0; + } else { + if (par->codec_id == AV_CODEC_ID_SIPR) { + static const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 }; + if (flavor > 3) + return AVERROR_INVALIDDATA; + track->audio.sub_packet_size = ff_sipr_subpk_size[flavor]; + par->bit_rate = sipr_bit_rate[flavor]; + } else if (track->audio.sub_packet_size <= 0 || + track->audio.frame_size % track->audio.sub_packet_size) + return AVERROR_INVALIDDATA; + par->block_align = track->audio.sub_packet_size; + *extradata_offset = 78; + } + track->audio.buf = av_malloc_array(track->audio.sub_packet_h, + track->audio.frame_size); + if (!track->audio.buf) + return AVERROR(ENOMEM); + break; + } + case AV_CODEC_ID_FLAC: + if (track->codec_priv.size) { + ret = matroska_parse_flac(s, track, extradata_offset); + if (ret < 0) + return ret; + } + break; + case AV_CODEC_ID_WAVPACK: + if (track->codec_priv.size < 2) { + av_log(matroska->ctx, AV_LOG_INFO, "Assuming WavPack version 4.10 " + "in absence of valid CodecPrivate.\n"); + extradata_size = WAVPACK_EXTRADATA_SIZE; + AV_WL16(extradata, 0x410); + } + break; + } + + if (extradata_size > 0) { + ret = ff_alloc_extradata(par, extradata_size); + if (ret < 0) + return ret; + memcpy(par->extradata, extradata, extradata_size); + } + + return 0; +} static int matroska_parse_tracks(AVFormatContext *s) { @@ -2518,10 +2750,6 @@ static int matroska_parse_tracks(AVFormatContext *s) EbmlList *encodings_list = &track->encodings; MatroskaTrackEncoding *encodings = encodings_list->elem; AVCodecParameters *par; - uint8_t extradata[FFMAX3(AAC_MAX_EXTRADATA_SIZE, - TTA_EXTRADATA_SIZE, - WAVPACK_EXTRADATA_SIZE)]; - int extradata_size = 0; // > 0 means that the extradata buffer is used int extradata_offset = 0; uint32_t fourcc = 0; FFIOContext b; @@ -2702,6 +2930,14 @@ static int matroska_parse_tracks(AVFormatContext *s) (AVRational){ 1, 1000000000 }, st->time_base); + if (track->type == MATROSKA_TRACK_TYPE_AUDIO) { + ret = mka_parse_audio_codec(track, par, matroska, + s, &extradata_offset); + if (ret < 0) + return ret; + if (ret == SKIP_TRACK) + continue; + } else if (!strcmp(track->codec_id, "V_MS/VFW/FOURCC") && track->codec_priv.size >= 40 && track->codec_priv.data) { @@ -2714,43 +2950,6 @@ static int matroska_parse_tracks(AVFormatContext *s) par->codec_id = ff_codec_get_id(ff_codec_movvideo_tags, par->codec_tag); extradata_offset = 40; - } else if (!strcmp(track->codec_id, "A_MS/ACM") && - track->codec_priv.size >= 14 && - track->codec_priv.data) { - int ret; - ffio_init_context(&b, track->codec_priv.data, - track->codec_priv.size, - 0, NULL, NULL, NULL, NULL); - ret = ff_get_wav_header(s, &b.pub, par, - track->codec_priv.size, 0); - if (ret < 0) - return ret; - extradata_offset = FFMIN(track->codec_priv.size, 18); - } else if (!strcmp(track->codec_id, "A_QUICKTIME") - /* Normally 36, but allow noncompliant private data */ - && (track->codec_priv.size >= 32) - && (track->codec_priv.data)) { - uint32_t fourcc; - uint16_t sample_size; - int ret = get_qt_codec(track, &fourcc, &codec_id); - if (ret < 0) - return ret; - sample_size = AV_RB16(track->codec_priv.data + 26); - if (fourcc == 0) { - if (sample_size == 8) { - fourcc = MKTAG('r','a','w',' '); - codec_id = ff_codec_get_id(ff_codec_movaudio_tags, fourcc); - } else if (sample_size == 16) { - fourcc = MKTAG('t','w','o','s'); - codec_id = ff_codec_get_id(ff_codec_movaudio_tags, fourcc); - } - } - if ((fourcc == MKTAG('t','w','o','s') || - fourcc == MKTAG('s','o','w','t')) && - sample_size == 8) - codec_id = AV_CODEC_ID_PCM_S8; - par->codec_id = codec_id; - par->codec_tag = fourcc; } else if (!strcmp(track->codec_id, "V_QUICKTIME") && (track->codec_priv.size >= 21) && (track->codec_priv.data)) { @@ -2778,146 +2977,11 @@ static int matroska_parse_tracks(AVFormatContext *s) par->bits_per_coded_sample = bit_depth; } par->codec_tag = fourcc; - } else if (codec_id == AV_CODEC_ID_PCM_S16BE) { - switch (track->audio.bitdepth) { - case 8: - par->codec_id = AV_CODEC_ID_PCM_U8; - break; - case 24: - par->codec_id = AV_CODEC_ID_PCM_S24BE; - break; - case 32: - par->codec_id = AV_CODEC_ID_PCM_S32BE; - break; - } - } else if (codec_id == AV_CODEC_ID_PCM_S16LE) { - switch (track->audio.bitdepth) { - case 8: - par->codec_id = AV_CODEC_ID_PCM_U8; - break; - case 24: - par->codec_id = AV_CODEC_ID_PCM_S24LE; - break; - case 32: - par->codec_id = AV_CODEC_ID_PCM_S32LE; - break; - } - } else if (codec_id == AV_CODEC_ID_PCM_F32LE && - track->audio.bitdepth == 64) { - par->codec_id = AV_CODEC_ID_PCM_F64LE; - } else if (codec_id == AV_CODEC_ID_AAC && !track->codec_priv.size) { - int profile = matroska_aac_profile(track->codec_id); - int sri = matroska_aac_sri(track->audio.samplerate); - - extradata[0] = (profile << 3) | ((sri & 0x0E) >> 1); - extradata[1] = ((sri & 0x01) << 7) | (track->audio.channels << 3); - if (strstr(track->codec_id, "SBR")) { - sri = matroska_aac_sri(track->audio.out_samplerate); - extradata[2] = 0x56; - extradata[3] = 0xE5; - extradata[4] = 0x80 | (sri << 3); - extradata_size = 5; - } else - extradata_size = 2; - } else if (codec_id == AV_CODEC_ID_ALAC && track->codec_priv.size && track->codec_priv.size < INT_MAX - 12 - AV_INPUT_BUFFER_PADDING_SIZE) { - /* Only ALAC's magic cookie is stored in Matroska's track headers. - * Create the "atom size", "tag", and "tag version" fields the - * decoder expects manually. */ - ret = ff_alloc_extradata(par, 12 + track->codec_priv.size); - if (ret < 0) - return ret; - AV_WB32(par->extradata, par->extradata_size); - AV_WB32(&par->extradata[4], MKBETAG('a', 'l', 'a', 'c')); - AV_WB32(&par->extradata[8], 0); - memcpy(&par->extradata[12], track->codec_priv.data, - track->codec_priv.size); - } else if (codec_id == AV_CODEC_ID_TTA) { - uint8_t *ptr; - if (track->audio.channels > UINT16_MAX || - track->audio.bitdepth > UINT16_MAX) { - av_log(matroska->ctx, AV_LOG_WARNING, - "Too large audio channel number %"PRIu64 - " or bitdepth %"PRIu64". Skipping track.\n", - track->audio.channels, track->audio.bitdepth); - if (matroska->ctx->error_recognition & AV_EF_EXPLODE) - return AVERROR_INVALIDDATA; - else - continue; - } - if (track->audio.out_samplerate < 0 || track->audio.out_samplerate > INT_MAX) - return AVERROR_INVALIDDATA; - extradata_size = TTA_EXTRADATA_SIZE; - ptr = extradata; - bytestream_put_be32(&ptr, AV_RB32("TTA1")); - bytestream_put_le16(&ptr, 1); - bytestream_put_le16(&ptr, track->audio.channels); - bytestream_put_le16(&ptr, track->audio.bitdepth); - bytestream_put_le32(&ptr, track->audio.out_samplerate); - bytestream_put_le32(&ptr, av_rescale(matroska->duration * matroska->time_scale, - track->audio.out_samplerate, - AV_TIME_BASE * 1000)); } else if (codec_id == AV_CODEC_ID_RV10 || codec_id == AV_CODEC_ID_RV20 || codec_id == AV_CODEC_ID_RV30 || codec_id == AV_CODEC_ID_RV40) { extradata_offset = 26; - } else if (codec_id == AV_CODEC_ID_RA_144) { - track->audio.out_samplerate = 8000; - track->audio.channels = 1; - } else if ((codec_id == AV_CODEC_ID_RA_288 || - codec_id == AV_CODEC_ID_COOK || - codec_id == AV_CODEC_ID_ATRAC3 || - codec_id == AV_CODEC_ID_SIPR) - && track->codec_priv.data) { - const uint8_t *ptr = track->codec_priv.data; - int flavor; - - if (track->codec_priv.size < 46) - return AVERROR_INVALIDDATA; - ptr += 22; - flavor = bytestream_get_be16(&ptr); - track->audio.coded_framesize = bytestream_get_be32(&ptr); - ptr += 12; - track->audio.sub_packet_h = bytestream_get_be16(&ptr); - track->audio.frame_size = bytestream_get_be16(&ptr); - track->audio.sub_packet_size = bytestream_get_be16(&ptr); - if (track->audio.coded_framesize <= 0 || - track->audio.sub_packet_h <= 0 || - track->audio.frame_size <= 0) - return AVERROR_INVALIDDATA; - - if (codec_id == AV_CODEC_ID_RA_288) { - if (track->audio.sub_packet_h & 1 || 2 * track->audio.frame_size - != (int64_t)track->audio.sub_packet_h * track->audio.coded_framesize) - return AVERROR_INVALIDDATA; - par->block_align = track->audio.coded_framesize; - track->codec_priv.size = 0; - } else { - if (codec_id == AV_CODEC_ID_SIPR) { - static const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 }; - if (flavor > 3) - return AVERROR_INVALIDDATA; - track->audio.sub_packet_size = ff_sipr_subpk_size[flavor]; - par->bit_rate = sipr_bit_rate[flavor]; - } else if (track->audio.sub_packet_size <= 0 || - track->audio.frame_size % track->audio.sub_packet_size) - return AVERROR_INVALIDDATA; - par->block_align = track->audio.sub_packet_size; - extradata_offset = 78; - } - track->audio.buf = av_malloc_array(track->audio.sub_packet_h, - track->audio.frame_size); - if (!track->audio.buf) - return AVERROR(ENOMEM); - } else if (codec_id == AV_CODEC_ID_FLAC && track->codec_priv.size) { - ret = matroska_parse_flac(s, track, &extradata_offset); - if (ret < 0) - return ret; - } else if (codec_id == AV_CODEC_ID_WAVPACK && track->codec_priv.size < 2) { - av_log(matroska->ctx, AV_LOG_INFO, "Assuming WavPack version 4.10 " - "in absence of valid CodecPrivate.\n"); - extradata_size = WAVPACK_EXTRADATA_SIZE; - AV_WL16(extradata, 0x410); } else if (codec_id == AV_CODEC_ID_PRORES && track->codec_priv.size == 4) { par->codec_tag = AV_RL32(track->codec_priv.data); } else if (codec_id == AV_CODEC_ID_VP9) { @@ -2960,11 +3024,9 @@ static int matroska_parse_tracks(AVFormatContext *s) av_log(matroska->ctx, AV_LOG_INFO, "Unknown/unsupported AVCodecID %s.\n", track->codec_id); - if (!par->extradata && (extradata_size > 0 || track->codec_priv.size > 0)) { - const uint8_t *src = extradata_size > 0 ? extradata : - track->codec_priv.data + extradata_offset; - unsigned extra_size = extradata_size > 0 ? extradata_size : - track->codec_priv.size; + if (!par->extradata && track->codec_priv.size > 0) { + const uint8_t *src = track->codec_priv.data + extradata_offset; + unsigned extra_size = track->codec_priv.size; ret = ff_alloc_extradata(par, extra_size); if (ret < 0) return ret; -- 2.34.1 _______________________________________________ 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".