From patchwork Sat Aug 27 00:12:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 37508 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:139a:b0:8f:1db5:eae2 with SMTP id w26csp626215pzh; Fri, 26 Aug 2022 17:12:33 -0700 (PDT) X-Google-Smtp-Source: AA6agR77tQ8WCo58TQ5Ne1IyWHGihhPD93VTLPXOFcM2N7JVYcZz9zMYqNbZj5ubSFPpG+uKVOAc X-Received: by 2002:a17:907:2895:b0:73d:ced6:453b with SMTP id em21-20020a170907289500b0073dced6453bmr6532370ejc.233.1661559153305; Fri, 26 Aug 2022 17:12:33 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id y12-20020a056402440c00b004437a9fcc07si2434827eda.361.2022.08.26.17.12.31; Fri, 26 Aug 2022 17:12:33 -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=@outlook.com header.s=selector1 header.b=lkFsvjwD; arc=fail (body hash mismatch); 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=outlook.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9B60A68BA3C; Sat, 27 Aug 2022 03:12:27 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR02-HE1-obe.outbound.protection.outlook.com (mail-oln040092068052.outbound.protection.outlook.com [40.92.68.52]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id EA4EC68B895 for ; Sat, 27 Aug 2022 03:12:20 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=gXrxrC1AzaL8k+buJ5cplnqNh5CtNgz6utmc+yaleVQLo9zjP8EHUKOp2Q0/LHNItjIp9/PO4/FhdfHP5qLVk8cRImeHO2cn7YEGQq/Aiff4Hs3Tv0ZexfyHOf8Loch2OOeGoi8qvhEEdT0771SFnTZpwDBOah9UapHFsmjO9hs7UN/0hpq5q/TcJbXRVagTfZ622EF3jxqM7ihWamGtsZBZVXeoGzF6HPlB5qUsqhtodN/PgKhE1Hq6Zvt7HllIMRFF1GTFlA2CkMbS+g4U8VGqgjqdbklCRWrmLCD50mwA+H1D5jS1J+7TKU1URl7yvtoCixRWbehjLZrCLEMZ/Q== 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=4h5UOukizgxQfQZ2jrVnSUSNQ8I8NJyLkuEN3VXl1Po=; b=CUlKCfym7XgflhEYxC+vZv5SGZq9DR/4YqQPPOKfGSApeZ/J+omf0hk8P26kE2283MwAMfpLp9PdJvlixM1j6Em/X7gGKqnnmCmFEkU5gNohOjf0zmazfLL06gLgN9NfNEx5NY6C3+XYbXSUTr6QEpehohDVGASUgjf8RCnkP/5ueGJ56XUq4W39wD4cQRmg4Z5Nns//ThCtwfrkazn9433rjhukMiOi8AsEyhz/SG09iC2m1dsMgcHm3wkQCuGL5ch3SXIj/ffm5bUmmW8Khfk+8tg0ZRtKHMIgoS3fAT1DMqTCGH0f1M4dovFrQ9kDeo+HVS+ahV0E/OpUo9ZWNA== 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=4h5UOukizgxQfQZ2jrVnSUSNQ8I8NJyLkuEN3VXl1Po=; b=lkFsvjwDph+bwFgT8PgFDRZVXrFzB0rVhIvykkcM0qr44oug8Vc44igR8LtpMzTvO6mCn4pzJl51PIJcPUEA6c5aR7Er8CU7CD7JbCalrhj1ZAQn+fLVYRI2gRSNxzvwXc5YtruF1A4sglfA4+H5IyTFz5tZ+5GFvFTCoo2/J4v3DJc5dxUqQk7OCCwLRGYKK3JFns0SfZ+cWn6JgOmxHBnA8PGuZX3oteV2TalzHc1iR0XIJ0ccn1ur8eDrD0FoMVUavGdvJn4rqTMBJpDmxcY/gJLCAXG0qZZvw0FxiJO1frSEDaSSvBuJRcFnd7m2AhMuhDTyBg0NyOSMYddOxw== Received: from DB6PR0101MB2214.eurprd01.prod.exchangelabs.com (2603:10a6:4:42::27) by VE1PR01MB5839.eurprd01.prod.exchangelabs.com (2603:10a6:803:112::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5566.15; Sat, 27 Aug 2022 00:12:18 +0000 Received: from DB6PR0101MB2214.eurprd01.prod.exchangelabs.com ([fe80::4cb9:bf7a:dbc5:fe84]) by DB6PR0101MB2214.eurprd01.prod.exchangelabs.com ([fe80::4cb9:bf7a:dbc5:fe84%7]) with mapi id 15.20.5566.016; Sat, 27 Aug 2022 00:12:18 +0000 From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Sat, 27 Aug 2022 02:12:08 +0200 Message-ID: X-Mailer: git-send-email 2.34.1 X-TMN: [kLkkvHymYgXda2bzGWMv3eHdb1bWc9oX] X-ClientProxiedBy: ZR2P278CA0041.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:47::10) To DB6PR0101MB2214.eurprd01.prod.exchangelabs.com (2603:10a6:4:42::27) X-Microsoft-Original-Message-ID: <20220827001209.2525708-1-andreas.rheinhardt@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: a53808ad-11c3-46a3-ca96-08da87c0cd8b X-MS-Exchange-SLBlob-MailProps: AZnQBsB9XmpE5Ud63VVPnzi67JlvJlcMTSenY8iM59iLisRaOn2VsZ7TIz7m277g1BHwupykfYBrbbyJ88n7MpiIEpQVrYE4yj9Cq7f7SdJODIQYuWAayZBu0BDTnEyxhqA4faY/bguvFfp1iNywtzsgz9JBR4ChHZSNuTKYtRYji9EKxiQA8uanFtwHziGFXvXD4e05pgKAz44N4bcC9lWRjQx6PHTOFRxC8q24avoFYbnmfe7Y3678lNLn9iTNNsmqN0LB3Z3bGfFHHWZOrDzBA4UOwdh4t41y1k4Nh25qnmpqZhoAzHYvnT9DJLDIq4ST4B4gI03f39FJpEkeW3+asHyad/tF9YSEz2A9CS13iPWFBupOt/auNVysZS4VMvDzCquVPNSuCNAvITnEA6kAfZmhdVw0UBI2W3HecVUJWh/mZ4iBnJKVMGoQ8+oubquIwiZMMLt5REx5b58Uvrt1Tda1vdYqbxzQ2w9ZYRG9f1pJbqZzlZSuHGMBpr90O7IT7/G5xkFeWTkQFYtvJ0K8Ge8exrpGUpkWwcbauCWP5jlIEMMaY0aN9KOJo0WfV9txoxuuJqqE/KI7f8e9HDvx6RZtk4nywouBdurfGHuqlUuiIh+476SKAqawVs+0VN+Ik2ZU/fsSw1bUzj3U2e/6/ZVGkHC4VAodKo8ACdfQnCLio31szj5ZcLyTdexxSJ5DXCckaMH8TABI8k3V9GGmEBmhZq0Es4u+4yPrdHxfIvgr/5KzRlvTXNnSpaYOo60gFna6OEw= X-MS-TrafficTypeDiagnostic: VE1PR01MB5839:EE_ X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: fQViHX12al105wJUS6lEl+tE9j8IXL8j5JNS8Dq6NSV8TCmsxgMKoDwRRQX7tpfHAWrktWalKNPaA72WvRY9Xt5jR35OhK6HgvSaakW2LdgR6hx4EddlDM3NG9jHxZZrn41mdbsDKtuVx42A8UY4pT76jca0jaXnDtmig8HGErgDpH2XVqi985sCWS89d69r4JzWj1KUSBWQG7dC5e2+wFUOOLx3qus0gNQADckEtmESYKFt8nywHUXn/7OXCLF1tEzLZ8PH6+85DdPkJMCIlL7nX4e4RwMYQYvD9s4UALGDN3t1XqRwNVeRGEkjL2ShEr1mcNy+m0+2YZE/Li2b1iq+gmUxi5BgXPEjAX2Oto6R3t+nvprhns7br5NzmBuVn66x+fnrj7JNLmX43AINd5n4/RcL7RLuQMotiQiLbe1H6tWhRoHOhLBCPO3tEeOhmARFAXj9w/0ymzhwDtyrfSyXzpd6SNeZTa3LwBVEe5Wx6RLZ2v9f4fOv4+d4mnbnfUHLSRzeJ4DQV/9WGZUZMu0h5u9IaLU+ZBjqdBWqq27wTAucNlfWOBbcODXwl/6+3lN/GHhTDF3dqoqlfY34tMPB/IwoGKOT6xLn9yVIW16Wgus/bt1gcX++i7fPXeaZ X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: rOjfjmP8PJfYTfdbFA+Yrd/qmpJomx/GNxxh2PD1hAOmihd80MCXJBUl0ojP/1R50zlPytgEH6Od43Xj5YgIMnvcY/mdKTw4PJmltEsNoztUnQWE0alF3i9j4IbQwIiCXnbRyLaNInAPdyhoyscBcc3pSyEJHYLsRlWTCYFEoqM6DkkaWGugYQ2BaGNBQ6QVb6xYNdeblj7aCwmDWBDZOIkWO9mlDEGCstDUypo7g6UfjBfZUXqUqKNNZ4bK2BXW6a0xJJkXZYzl2z1PW9Xha/DqAFq7e7F6BEUkelMeZHtTDHj87KOYhCd0jpPVeRW8RhRCj2jZSsn2/1ezzLw8KlyHRIK8RB3SFV47xuIn1jPEi44fStQOi2tuVsBlHt4dU8ITdvNVQnFs+fbm3HXwXhwT0pgPj4rw3snBDfMn7TLZ05YSNmk7wXMrHL4T9lwjcuFpMbiADoPjgD5HpPGlF/5Atkz1ANee0ALH5mmWtFhMAsoFFXFS02C899i5YsfTxi05YG6N+NuHc5wKBq9u/xjThEaE6O3dh8RUvnp2HeMjSHBND9QgD993x8a+GY3g/lcrrmsgZGxQwve3ulJSeAd78ZlObFADCylcmWrPnBk+noIN1Ss2gxf6d7BLLdxEg31dxPJkMbY5g3wewacsVWRq46xC7cyPOB8lfzrqd+066mA+HozV1xzZrM1ERBMRjKHXzNcVJzhVo/XYMuV1D3ot0PPHlWkDo8KzOy882UtEAV2V6pXaUsNGZ3pxC0ZdQrWWUE6ykHC0MkqmZaQbInRMHRejhn3mtQLhE2MZ0c+TTYAVqGrWK4hVAriuBrl1NkwHirqe8DyZEw7F9qJTzy+a6WbvoPPy1fVuFIODCkAHAP6hx0rWlHEHKIn5DatCOYMTcMw5s1/tjIKAkwZ8CROWQUx9jLHuK0ov8S2RfRnm928s2KLv5uLgIOUxBx4pKElwFaCdnmNyr3PomG9Ac5wp5x9cWCw6t1qivteBhjTGPuXdBcsRQAjU/adX2X/HG1jbINjfgzsxXWG0XmdYzeNCKjSSp6VcOuC1eaeMQStflrQt3a4Egxrw8pPjDVlLXsIKyMnNnTErrQDQtPU9xfGG3Ydac6ljgnpFBLM1een5+Fr79cNfnVSOVj3MOOGmhrDQCWvyPk37mPHGD9sF3LTNq/hIPJBAIJfP8jd9FSv6uoJNEIqh9xyZOnBEAP5L67gufxIsFG8fupgP+EegYghDjqiRJr4wA+qrNkUqsimHdGj7S/Oxgo7fpj7AxJ/W9Z9AT/2ZxnodsDNAZEQDmHZiUfRovgNS26oFvr+7c+E= X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: a53808ad-11c3-46a3-ca96-08da87c0cd8b X-MS-Exchange-CrossTenant-AuthSource: DB6PR0101MB2214.eurprd01.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Aug 2022 00:12:18.3307 (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: VE1PR01MB5839 Subject: [FFmpeg-devel] [PATCH 1/2] avformat/hevc: Fix crash on allocation failure, avoid allocations 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: jEOND0NvlvjL The HEVC code currently uses an array of arrays of NALUs; one such array contains all the SPS NALUs, one all PPS NALUs etc. The array of arrays is grown dynamically via av_reallocp_array(), but given that the latter function automatically frees its buffer upon reallocation error, it may only be used with PODs, which this case is not. Even worse: While the pointer to the arrays is reset, the counter for the number of arrays is not, leading to a segfault in hvcc_close(). Fix this by avoiding the allocations of the array of arrays altogether. This is easily possible because their number is bounded (by five). Furthermore, as a byproduct we can ensure that the code always produces the recommended ordering of VPS-SPS-PPS-SEI (which was not guaranteed before). Signed-off-by: Andreas Rheinhardt --- libavformat/hevc.c | 155 +++++++++++++++++++-------------------------- 1 file changed, 65 insertions(+), 90 deletions(-) diff --git a/libavformat/hevc.c b/libavformat/hevc.c index 37d97941d5..13951bd9f2 100644 --- a/libavformat/hevc.c +++ b/libavformat/hevc.c @@ -29,6 +29,15 @@ #define MAX_SPATIAL_SEGMENTATION 4096 // max. value of u(12) field +enum { + VPS_INDEX, + SPS_INDEX, + PPS_INDEX, + SEI_PREFIX_INDEX, + SEI_SUFFIX_INDEX, + NB_ARRAYS +}; + typedef struct HVCCNALUnitArray { uint8_t array_completeness; uint8_t NAL_unit_type; @@ -56,7 +65,7 @@ typedef struct HEVCDecoderConfigurationRecord { uint8_t temporalIdNested; uint8_t lengthSizeMinusOne; uint8_t numOfArrays; - HVCCNALUnitArray *array; + HVCCNALUnitArray arrays[NB_ARRAYS]; } HEVCDecoderConfigurationRecord; typedef struct HVCCProfileTierLevel { @@ -658,31 +667,10 @@ static void nal_unit_parse_header(GetBitContext *gb, uint8_t *nal_type) static int hvcc_array_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, uint8_t nal_type, int ps_array_completeness, - HEVCDecoderConfigurationRecord *hvcc) + HVCCNALUnitArray *array) { int ret; - uint8_t index; - uint16_t numNalus; - HVCCNALUnitArray *array; - - for (index = 0; index < hvcc->numOfArrays; index++) - if (hvcc->array[index].NAL_unit_type == nal_type) - break; - - if (index >= hvcc->numOfArrays) { - uint8_t i; - - ret = av_reallocp_array(&hvcc->array, index + 1, sizeof(HVCCNALUnitArray)); - if (ret < 0) - return ret; - - for (i = hvcc->numOfArrays; i <= index; i++) - memset(&hvcc->array[i], 0, sizeof(HVCCNALUnitArray)); - hvcc->numOfArrays = index + 1; - } - - array = &hvcc->array[index]; - numNalus = array->numNalus; + uint16_t numNalus = array->numNalus; ret = av_reallocp_array(&array->nalUnit, numNalus + 1, sizeof(uint8_t*)); if (ret < 0) @@ -711,7 +699,8 @@ static int hvcc_array_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, static int hvcc_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, int ps_array_completeness, - HEVCDecoderConfigurationRecord *hvcc) + HEVCDecoderConfigurationRecord *hvcc, + unsigned array_idx) { int ret = 0; GetBitContext gbc; @@ -736,17 +725,14 @@ static int hvcc_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, * hvcC. Perhaps the SEI playload type should be checked * and non-declarative SEI messages discarded? */ - switch (nal_type) { - case HEVC_NAL_VPS: - case HEVC_NAL_SPS: - case HEVC_NAL_PPS: - case HEVC_NAL_SEI_PREFIX: - case HEVC_NAL_SEI_SUFFIX: - ret = hvcc_array_add_nal_unit(nal_buf, nal_size, nal_type, - ps_array_completeness, hvcc); + ret = hvcc_array_add_nal_unit(nal_buf, nal_size, nal_type, + ps_array_completeness, + &hvcc->arrays[array_idx]); if (ret < 0) goto end; - else if (nal_type == HEVC_NAL_VPS) + if (hvcc->arrays[array_idx].numNalus == 1) + hvcc->numOfArrays++; + if (nal_type == HEVC_NAL_VPS) ret = hvcc_parse_vps(&gbc, hvcc); else if (nal_type == HEVC_NAL_SPS) ret = hvcc_parse_sps(&gbc, hvcc); @@ -754,11 +740,6 @@ static int hvcc_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, ret = hvcc_parse_pps(&gbc, hvcc); if (ret < 0) goto end; - break; - default: - ret = AVERROR_INVALIDDATA; - goto end; - } end: av_free(rbsp_buf); @@ -787,22 +768,17 @@ static void hvcc_init(HEVCDecoderConfigurationRecord *hvcc) static void hvcc_close(HEVCDecoderConfigurationRecord *hvcc) { - uint8_t i; - - for (i = 0; i < hvcc->numOfArrays; i++) { - hvcc->array[i].numNalus = 0; - av_freep(&hvcc->array[i].nalUnit); - av_freep(&hvcc->array[i].nalUnitLength); + for (unsigned i = 0; i < FF_ARRAY_ELEMS(hvcc->arrays); i++) { + HVCCNALUnitArray *const array = &hvcc->arrays[i]; + array->numNalus = 0; + av_freep(&array->nalUnit); + av_freep(&array->nalUnitLength); } - - hvcc->numOfArrays = 0; - av_freep(&hvcc->array); } static int hvcc_write(AVIOContext *pb, HEVCDecoderConfigurationRecord *hvcc) { - uint8_t i; - uint16_t j, vps_count = 0, sps_count = 0, pps_count = 0; + uint16_t vps_count, sps_count, pps_count; /* * We only support writing HEVCDecoderConfigurationRecord version 1. @@ -866,36 +842,31 @@ static int hvcc_write(AVIOContext *pb, HEVCDecoderConfigurationRecord *hvcc) hvcc->lengthSizeMinusOne); av_log(NULL, AV_LOG_TRACE, "numOfArrays: %"PRIu8"\n", hvcc->numOfArrays); - for (i = 0; i < hvcc->numOfArrays; i++) { + for (unsigned i = 0, j = 0; i < FF_ARRAY_ELEMS(hvcc->arrays); i++) { + const HVCCNALUnitArray *const array = &hvcc->arrays[i]; + + if (array->numNalus == 0) + continue; + av_log(NULL, AV_LOG_TRACE, "array_completeness[%"PRIu8"]: %"PRIu8"\n", - i, hvcc->array[i].array_completeness); + j, array->array_completeness); av_log(NULL, AV_LOG_TRACE, "NAL_unit_type[%"PRIu8"]: %"PRIu8"\n", - i, hvcc->array[i].NAL_unit_type); + j, array->NAL_unit_type); av_log(NULL, AV_LOG_TRACE, "numNalus[%"PRIu8"]: %"PRIu16"\n", - i, hvcc->array[i].numNalus); - for (j = 0; j < hvcc->array[i].numNalus; j++) + j, array->numNalus); + for (unsigned k = 0; k < array->numNalus; k++) av_log(NULL, AV_LOG_TRACE, "nalUnitLength[%"PRIu8"][%"PRIu16"]: %"PRIu16"\n", - i, j, hvcc->array[i].nalUnitLength[j]); + j, k, array->nalUnitLength[k]); + j++; } /* * We need at least one of each: VPS, SPS and PPS. */ - for (i = 0; i < hvcc->numOfArrays; i++) - switch (hvcc->array[i].NAL_unit_type) { - case HEVC_NAL_VPS: - vps_count += hvcc->array[i].numNalus; - break; - case HEVC_NAL_SPS: - sps_count += hvcc->array[i].numNalus; - break; - case HEVC_NAL_PPS: - pps_count += hvcc->array[i].numNalus; - break; - default: - break; - } + vps_count = hvcc->arrays[VPS_INDEX].numNalus; + sps_count = hvcc->arrays[SPS_INDEX].numNalus; + pps_count = hvcc->arrays[PPS_INDEX].numNalus; if (!vps_count || vps_count > HEVC_MAX_VPS_COUNT || !sps_count || sps_count > HEVC_MAX_SPS_COUNT || !pps_count || pps_count > HEVC_MAX_PPS_COUNT) @@ -970,25 +941,29 @@ static int hvcc_write(AVIOContext *pb, HEVCDecoderConfigurationRecord *hvcc) /* unsigned int(8) numOfArrays; */ avio_w8(pb, hvcc->numOfArrays); - for (i = 0; i < hvcc->numOfArrays; i++) { + for (unsigned i = 0; i < FF_ARRAY_ELEMS(hvcc->arrays); i++) { + const HVCCNALUnitArray *const array = &hvcc->arrays[i]; + + if (!array->numNalus) + continue; /* * bit(1) array_completeness; * unsigned int(1) reserved = 0; * unsigned int(6) NAL_unit_type; */ - avio_w8(pb, hvcc->array[i].array_completeness << 7 | - hvcc->array[i].NAL_unit_type & 0x3f); + avio_w8(pb, array->array_completeness << 7 | + array->NAL_unit_type & 0x3f); /* unsigned int(16) numNalus; */ - avio_wb16(pb, hvcc->array[i].numNalus); + avio_wb16(pb, array->numNalus); - for (j = 0; j < hvcc->array[i].numNalus; j++) { + for (unsigned j = 0; j < array->numNalus; j++) { /* unsigned int(16) nalUnitLength; */ - avio_wb16(pb, hvcc->array[i].nalUnitLength[j]); + avio_wb16(pb, array->nalUnitLength[j]); /* bit(8*nalUnitLength) nalUnit; */ - avio_write(pb, hvcc->array[i].nalUnit[j], - hvcc->array[i].nalUnitLength[j]); + avio_write(pb, array->nalUnit[j], + array->nalUnitLength[j]); } } @@ -1098,18 +1073,18 @@ int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data, buf += 4; - switch (type) { - case HEVC_NAL_VPS: - case HEVC_NAL_SPS: - case HEVC_NAL_PPS: - case HEVC_NAL_SEI_PREFIX: - case HEVC_NAL_SEI_SUFFIX: - ret = hvcc_add_nal_unit(buf, len, ps_array_completeness, &hvcc); - if (ret < 0) - goto end; - break; - default: - break; + for (unsigned i = 0; i < FF_ARRAY_ELEMS(hvcc.arrays); i++) { + static const uint8_t array_idx_to_type[] = + { HEVC_NAL_VPS, HEVC_NAL_SPS, HEVC_NAL_PPS, + HEVC_NAL_SEI_PREFIX, HEVC_NAL_SEI_SUFFIX }; + + if (type == array_idx_to_type[i]) { + ret = hvcc_add_nal_unit(buf, len, ps_array_completeness, + &hvcc, i); + if (ret < 0) + goto end; + break; + } } buf += len;