From patchwork Thu Sep 2 10:22:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc-Antoine ARNAUD X-Patchwork-Id: 29951 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp140023iov; Thu, 2 Sep 2021 03:22:46 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyz4hl3gd3EG+YvXXqRvLR+uVD+QPFtQ1jXnu5Q/MhT8uXeSR5vN0CN1K8Dwtl+bkxn134q X-Received: by 2002:aa7:c685:: with SMTP id n5mr2780031edq.27.1630578165898; Thu, 02 Sep 2021 03:22:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1630578165; cv=none; d=google.com; s=arc-20160816; b=vPqExQ/m7LiXi/IexSJTMJR2hVGUwVWlJ835coSGkArc6abQirt36kx70CuYdAeZji JK/1QBns1vSDDzA10gt2NrJXWX09fiuIRp19wVGPkZ6piV1ycBBlIB0PSLWg5Vk8jwVy NJHe11uSLnAdD1KzwhFYHosvCn9pFZefVT8nUmRNYeXriAUTJ5IIC1GsvkbwJRNjIbry /N8KpKGxL9IGW6LCjFXk+8itiDaxiydcNKmWqnuqj4en2axpBQS6oVx0PzbPPIeGR03j 09JpwOgS4O205oFyBcTpxn9zFRtVmmTbYOy2BL/NcND3RqFIbwZhoShoy+Em4RX62LSP KnUA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=vGl/FtKv6PI4LfQbSlQ3KLCzpSSxoJ6GvRr7waMAF0E=; b=0MaxEpy8awLkg7Ho5i+ql1Es5bBex72Y4hldyaBT5FX56mTK/4orzDmbmXHWEQFCxm AYGjeF1aHOzoznMeZb8N7xw64ZVzlQVxAm001DiAF3OUWTIl3ekBGR5+3vAq2/9mobwW CMbPFlhXvZrEq9wdNwGW+kOehl+olUcNVueArodipTQfonPfvrmQl6QBCFJDnYENS55B 11sXgbU/5Bu577WG+xQRCL87EkAhcdigMpq4GPrZ8Zud2GdNEP6ycJ0p5Khn4L9btUTs 2BBwTmZ0cXQHrfNAM8O7/Rxvcbf8INRbxG5RDfLOK5VjzP5lOP6fyo20tPiY9XUZEBGh eADg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@luminvent-com.20150623.gappssmtp.com header.s=20150623 header.b=WrxdmPiA; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id r19si1568175edd.599.2021.09.02.03.22.44; Thu, 02 Sep 2021 03:22:45 -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=@luminvent-com.20150623.gappssmtp.com header.s=20150623 header.b=WrxdmPiA; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 31CEA68A1BB; Thu, 2 Sep 2021 13:22:40 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f50.google.com (mail-wr1-f50.google.com [209.85.221.50]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id F0DDE68A1BB for ; Thu, 2 Sep 2021 13:22:33 +0300 (EEST) Received: by mail-wr1-f50.google.com with SMTP id b6so2050675wrh.10 for ; Thu, 02 Sep 2021 03:22:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=luminvent-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=OITK9jfmTCMBOKszcbSkoObKJR9pyXnwcGODcMonG1c=; b=WrxdmPiAdZg1C2ETrcmFyryxoEcPyR/SRDE7l0zAq9ujDQpjCNT5rZFZXvsCNr0uhE UmV1LuexvXpnftkgZ+X4v+t5MR76AdLxMSzEKfSsH2TbMDxJ+ncVp8Vy45DHhZU5JjSq 9et8LyQjAFFCK1Bxkjq/jZ/Rm3mmknzFHZ4lgN/FhnSK01B0diqbJ3bqpqZr7GEE70YK KnaGHO5R32lJnv2fffxzYVtR2CM8UDYX2gFWt1Ja5ozLw9N34EY+hf4ZAFxcB97WrE+/ LL19jSpSTf61ZLPzFIaVjcQnT8PnIDfF+9eRZvcgl+ewqKTdGsX5dePPYiytLtwhO6S0 1bDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=OITK9jfmTCMBOKszcbSkoObKJR9pyXnwcGODcMonG1c=; b=A67V4Yvzk1jEIQ6q+uyl3d0wrE0CbEpkoyF4uYoLjYlt1ZwxDEU8ABfhKohf6CQNaa MVmN0Mk+dW2ZdIRHB9qUWkvRtQ5wf+cXdo5YLjG9hg6I9daHn462ByuFWQY8xNgHv/SO 65WOMz4+Zz4H0WMLzX+1Guu8yLeKOY5XxDCZHEGX1HoaX68QdfQ1ILalbbsT59QX8wrb 9sTb1GU0vV0/sat+LFrdW09nz/tY0UPahtzqS9uUlTpwFaHjDlF23StBWvObPaTbV4uO f1bcCjuW+JyraP9pn1cxc+4GAca4cIdvvlVxf8F7b7yjyYhMPscfJ4y8QThfeg/MuL6U Zk7w== X-Gm-Message-State: AOAM5325HOy5z5VeAEY0pKOJy93AGkfdYNVuiPgeUhd3XvOIwOAy6Ew+ mza90cOMl6LYMOojSedAMJNz6EhPzy9wJw== X-Received: by 2002:a5d:456d:: with SMTP id a13mr2809812wrc.364.1630578152755; Thu, 02 Sep 2021 03:22:32 -0700 (PDT) Received: from localhost.localdomain ([188.65.168.123]) by smtp.gmail.com with ESMTPSA id j207sm1350264wmj.40.2021.09.02.03.22.31 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Sep 2021 03:22:32 -0700 (PDT) From: Marc-Antoine Arnaud To: ffmpeg-devel@ffmpeg.org Date: Thu, 2 Sep 2021 12:22:28 +0200 Message-Id: <20210902102229.82950-1-marc-antoine.arnaud@luminvent.com> X-Mailer: git-send-email 2.33.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/2] avformat/mxf: rename sub_descriptors as file_descriptors 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: Marc-Antoine Arnaud Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: wHno4fsPTvDe --- libavformat/mxfdec.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 34cbd2cd77..c28549f6a9 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -203,8 +203,8 @@ typedef struct MXFDescriptor { unsigned int color_range; unsigned int horiz_subsampling; unsigned int vert_subsampling; - UID *sub_descriptors_refs; - int sub_descriptors_count; + UID *file_descriptors_refs; + int file_descriptors_count; int linked_track_id; uint8_t *extradata; int extradata_size; @@ -342,7 +342,7 @@ static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx) av_freep(&((MXFDescriptor *)*ctx)->extradata); av_freep(&((MXFDescriptor *)*ctx)->mastering); av_freep(&((MXFDescriptor *)*ctx)->coll); - av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs); + av_freep(&((MXFDescriptor *)*ctx)->file_descriptors_refs); break; case Sequence: av_freep(&((MXFSequence *)*ctx)->structural_components_refs); @@ -1194,8 +1194,8 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int switch(tag) { case 0x3F01: - return mxf_read_strong_ref_array(pb, &descriptor->sub_descriptors_refs, - &descriptor->sub_descriptors_count); + return mxf_read_strong_ref_array(pb, &descriptor->file_descriptors_refs, + &descriptor->file_descriptors_count); case 0x3002: /* ContainerDuration */ descriptor->duration = avio_rb64(pb); break; @@ -2066,22 +2066,22 @@ static MXFPackage* mxf_resolve_source_package(MXFContext *mxf, UID package_ul, U static MXFDescriptor* mxf_resolve_multidescriptor(MXFContext *mxf, MXFDescriptor *descriptor, int track_id) { - MXFDescriptor *sub_descriptor = NULL; + MXFDescriptor *file_descriptor = NULL; int i; if (!descriptor) return NULL; if (descriptor->meta.type == MultipleDescriptor) { - for (i = 0; i < descriptor->sub_descriptors_count; i++) { - sub_descriptor = mxf_resolve_strong_ref(mxf, &descriptor->sub_descriptors_refs[i], Descriptor); + for (i = 0; i < descriptor->file_descriptors_count; i++) { + file_descriptor = mxf_resolve_strong_ref(mxf, &descriptor->file_descriptors_refs[i], Descriptor); - if (!sub_descriptor) { - av_log(mxf->fc, AV_LOG_ERROR, "could not resolve sub descriptor strong ref\n"); + if (!file_descriptor) { + av_log(mxf->fc, AV_LOG_ERROR, "could not resolve file descriptor strong ref\n"); continue; } - if (sub_descriptor->linked_track_id == track_id) { - return sub_descriptor; + if (file_descriptor->linked_track_id == track_id) { + return file_descriptor; } } } else if (descriptor->meta.type == Descriptor) From patchwork Thu Sep 2 10:22:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc-Antoine ARNAUD X-Patchwork-Id: 29952 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp140139iov; Thu, 2 Sep 2021 03:22:57 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwAASDqxP31znigMcdLxkaigS5WjxpdQa1AqAS7dk+ueu9jZjWWFLI4z4ezvN643tiHexdu X-Received: by 2002:a17:906:e8a:: with SMTP id p10mr2914524ejf.265.1630578177803; Thu, 02 Sep 2021 03:22:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1630578177; cv=none; d=google.com; s=arc-20160816; b=0t9BVyEVjkkOpfV8eoLEH3G1FkL02mAG8DTQXUYBRlQmIeJTrFz0LOCSM7Wbx7qKY+ ALN+pJrDPPLwd71vrlyxd3kpUGEgeWqbiyhuSEFA8a2SP0feD033rNp34vfZX3+YdpbK MSxyrK9+5sdgR3MkO3IZLM/ub3C85FUjoNiz38w6Pk42mdAPlytbtyOx1uz3n+LwRYCo ceV5xieaad57AiDUjd1sfOhW5M0yETatiFLJyev7NQjr3cprqGYqzMAzCTNSzVYxMx2M hIGi4C0TC0ky4mFki/bPuUD+luBsoOlmGee/f2G38e2gARojtJGKPZc4+OcTiveYGcbt mN/A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=/deQeq8KLmS8VXxOtcN5F32co3tSAeuSeL2sp03E+KA=; b=oqyAUnX4RfGvOu9oTdFsDx2w327MV6ePK3EhFQ6Lg7db3mMkoxAJJ3thrNUHhYPcZe mtKpA7N7lZs2olq7AZD+Q8Htp3MNqBc+oRtjqDy64+Mnj8n+xpNbdGGBmW90+CafwXt4 yHi/EUTLAiKIWIHQ+pzrTheEDY5pLL87w7Ad6ukmJ+AZ3zg/aZtD+0jjyRVWIpTbmuhp 8dDRpU70xUOeyU83Yn0ULych/8n/9jkEfCwrhGYevZC00ovNu9MUvqNbFPwVPkruWI68 W973PyhTwoJR21fDAyJv7V8CFyOi1wZVyGvifuTwjI/4eE0Dmoexb0vt/AK6zQ7JG88N c+Xw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@luminvent-com.20150623.gappssmtp.com header.s=20150623 header.b=RTmEVkUj; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id gb1si1463857ejc.89.2021.09.02.03.22.54; Thu, 02 Sep 2021 03:22:57 -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=@luminvent-com.20150623.gappssmtp.com header.s=20150623 header.b=RTmEVkUj; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 36AAB68A4FE; Thu, 2 Sep 2021 13:22:42 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f50.google.com (mail-wr1-f50.google.com [209.85.221.50]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2680968A544 for ; Thu, 2 Sep 2021 13:22:36 +0300 (EEST) Received: by mail-wr1-f50.google.com with SMTP id q14so2066496wrp.3 for ; Thu, 02 Sep 2021 03:22:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=luminvent-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=v4ejU01sFLrxZXVNx5UMv3TszWf4BEjSsJTrs8Jb4kQ=; b=RTmEVkUjWpvYOqQrEfTKJf/JW07CfY/8cyYkqEwC+zhtv/VvZ8d+LNSD4OEU2N+x7X ZWmc+N5eNstcuXCNDI7HVIA+Z4ZsqYukuI+zT4ksKkamgn8AGF6W96qoRjiWH+FZ9lmC gS2OLvGkCS+IorCtEylMzPyYy24NC4VKff+vlE5vC6Vqs83V8LVLVW3W/hg80TQYKLHS tWH3loGh9adMWiERHxpXZaeSngMyqA93K3aB/DcAVMkgZ+Dpyy8xeucZhl3zTWlOyAUM t2aF/8qv08bOHXoA3hB2EWcsZ95SMEdmHI+lgaQZxp3NLObCcyRp26g1A2GIqvV5pLjO jiHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=v4ejU01sFLrxZXVNx5UMv3TszWf4BEjSsJTrs8Jb4kQ=; b=Pw+nYy8QBHYz6Cv8n7xtqn26R8QHb0J1z36PplVjAZnpMH47KsRRUf2eFAku0UqpSQ ZcVIMZei03U7Munhea4X73H9rB3De5rSsJlYO9VG8fYxdmmoqAi6Q2CFKffvA42SvRNg ut84LMfrTghnU0nCzw+QBtzxJft6JSrMiFEXDtt2p8yn943ApYi0rq8j6hoOEq3VtBFl pAhQk7dln5ZF9rPwVebmPCg04dKvLMWVXYoIL9auC30bIfieSZr78sGVxJraEM1TvmAP XLEkKe331FY7lrUNR/Rici3bjXvBAyYTo90zFSKfcvyO3fy7/B1VajRL7zChdbruQki+ xbOw== X-Gm-Message-State: AOAM531dDzH4m9T0LkzV3PmeWakeS9b7o6eyRh3M3YFK7SnhFtb5ZvpY 4dfDi3X21Y3077bhCk4pwWtfqV2ka//KYA== X-Received: by 2002:adf:c542:: with SMTP id s2mr2770093wrf.374.1630578155024; Thu, 02 Sep 2021 03:22:35 -0700 (PDT) Received: from localhost.localdomain ([188.65.168.123]) by smtp.gmail.com with ESMTPSA id j207sm1350264wmj.40.2021.09.02.03.22.34 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Sep 2021 03:22:34 -0700 (PDT) From: Marc-Antoine Arnaud To: ffmpeg-devel@ffmpeg.org Date: Thu, 2 Sep 2021 12:22:29 +0200 Message-Id: <20210902102229.82950-2-marc-antoine.arnaud@luminvent.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210902102229.82950-1-marc-antoine.arnaud@luminvent.com> References: <20210902102229.82950-1-marc-antoine.arnaud@luminvent.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/2] avformat/mxf: support MCA audio information 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: Marc-Antoine Arnaud Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: LIxUrumes4G4 --- libavformat/mxf.h | 1 + libavformat/mxfdec.c | 281 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 276 insertions(+), 6 deletions(-) diff --git a/libavformat/mxf.h b/libavformat/mxf.h index fe9c52732c..cddbcb13c9 100644 --- a/libavformat/mxf.h +++ b/libavformat/mxf.h @@ -50,6 +50,7 @@ enum MXFMetadataSetType { TaggedValue, TapeDescriptor, AVCSubDescriptor, + MCASubDescriptor, }; enum MXFFrameLayout { diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index c28549f6a9..ea1b6055d6 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -45,17 +45,21 @@ */ #include +#include #include "libavutil/aes.h" #include "libavutil/avstring.h" #include "libavutil/mastering_display_metadata.h" #include "libavutil/mathematics.h" #include "libavcodec/bytestream.h" +#include "libavcodec/internal.h" +#include "libavutil/channel_layout.h" #include "libavutil/intreadwrite.h" #include "libavutil/parseutils.h" #include "libavutil/timecode.h" #include "libavutil/opt.h" #include "avformat.h" +#include "avlanguage.h" #include "internal.h" #include "mxf.h" @@ -177,6 +181,8 @@ typedef struct { int body_sid; MXFWrappingScheme wrapping; int edit_units_per_packet; /* how many edit units to read at a time (PCM, ClipWrapped) */ + bool require_reordering; + int channel_ordering[FF_SANE_NB_CHANNELS]; } MXFTrack; typedef struct MXFDescriptor { @@ -205,6 +211,8 @@ typedef struct MXFDescriptor { unsigned int vert_subsampling; UID *file_descriptors_refs; int file_descriptors_count; + UID *sub_descriptors_refs; + int sub_descriptors_count; int linked_track_id; uint8_t *extradata; int extradata_size; @@ -217,6 +225,15 @@ typedef struct MXFDescriptor { size_t coll_size; } MXFDescriptor; +typedef struct MXFMCASubDescriptor { + MXFMetadataSet meta; + UID uid; + UID mca_link_id; + UID mca_group_link_id; + UID mca_label_dictionnary_id; + char *language; +} MXFMCASubDescriptor; + typedef struct MXFIndexTableSegment { MXFMetadataSet meta; int edit_unit_byte_count; @@ -311,6 +328,10 @@ static const uint8_t mxf_system_item_key_cp[] = { 0x06,0x0e,0x2b,0x static const uint8_t mxf_system_item_key_gc[] = { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x03,0x01,0x14 }; static const uint8_t mxf_klv_key[] = { 0x06,0x0e,0x2b,0x34 }; static const uint8_t mxf_apple_coll_prefix[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01 }; +static const uint8_t mxf_mca_prefix[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01 }; +static const uint8_t mxf_audio_channel[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01 }; +static const uint8_t mxf_soundfield_group[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02 }; + /* complete keys to match */ static const uint8_t mxf_crypto_source_container_ul[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x02,0x02,0x00,0x00,0x00 }; static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 }; @@ -323,6 +344,15 @@ static const uint8_t mxf_indirect_value_utf16be[] = { 0x42,0x01,0x10,0x static const uint8_t mxf_apple_coll_max_cll[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x01 }; static const uint8_t mxf_apple_coll_max_fall[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x02 }; +static const uint8_t mxf_mca_label_dictionnary_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x01,0x00,0x00,0x00 }; +static const uint8_t mxf_mca_tag_symbol[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x02,0x00,0x00,0x00 }; +static const uint8_t mxf_mca_tag_name[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x03,0x00,0x00,0x00 }; +static const uint8_t mxf_mca_link_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x05,0x00,0x00,0x00 }; +static const uint8_t mxf_soundfield_group_link_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x06,0x00,0x00,0x00 }; +static const uint8_t mxf_mca_rfc5646_spoken_language[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x03,0x01,0x01,0x02,0x03,0x15,0x00,0x00 }; + +static const uint8_t mxf_sub_descriptor[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x04,0x06,0x10,0x00,0x00 }; + static const uint8_t mxf_mastering_display_prefix[13] = { FF_MXF_MasteringDisplay_PREFIX }; static const uint8_t mxf_mastering_display_uls[4][16] = { FF_MXF_MasteringDisplayPrimaries, @@ -343,6 +373,11 @@ static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx) av_freep(&((MXFDescriptor *)*ctx)->mastering); av_freep(&((MXFDescriptor *)*ctx)->coll); av_freep(&((MXFDescriptor *)*ctx)->file_descriptors_refs); + av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs); + break; + case MCASubDescriptor: + if (((MXFMCASubDescriptor *)*ctx)->language) + av_freep(&((MXFMCASubDescriptor *)*ctx)->language); break; case Sequence: av_freep(&((MXFSequence *)*ctx)->structural_components_refs); @@ -899,6 +934,30 @@ static int mxf_read_strong_ref_array(AVIOContext *pb, UID **refs, int *count) return 0; } +static inline int mxf_read_us_ascii_string(AVIOContext *pb, int size, char** str) +{ + int ret; + size_t buf_size; + + if (size < 0) + return AVERROR(EINVAL); + + buf_size = size + 1; + av_free(*str); + *str = av_malloc(buf_size); + if (!*str) + return AVERROR(ENOMEM); + + ret = avio_get_str(pb, size, *str, buf_size); + + if (ret < 0) { + av_freep(str); + return ret; + } + + return ret; +} + static inline int mxf_read_utf16_string(AVIOContext *pb, int size, char** str, int be) { int ret; @@ -1353,11 +1412,45 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int descriptor->coll->MaxFALL = avio_rb16(pb); } } + + if (IS_KLV_KEY(uid, mxf_sub_descriptor)) { + mxf_read_strong_ref_array(pb, &descriptor->sub_descriptors_refs, &descriptor->sub_descriptors_count); + break; + } break; } return 0; } +static int mxf_read_mca_sub_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) +{ + MXFMCASubDescriptor *mca_sub_descriptor = arg; + + if (IS_KLV_KEY(uid, mxf_mca_prefix)) { + if (IS_KLV_KEY(uid, mxf_mca_label_dictionnary_id)) { + avio_read(pb, mca_sub_descriptor->mca_label_dictionnary_id, 16); + } + if (IS_KLV_KEY(uid, mxf_mca_link_id)) { + avio_read(pb, mca_sub_descriptor->mca_link_id, 16); + } + if (IS_KLV_KEY(uid, mxf_soundfield_group_link_id)) { + avio_read(pb, mca_sub_descriptor->mca_group_link_id, 16); + } + } + + if (IS_KLV_KEY(uid, mxf_mca_rfc5646_spoken_language)) { + char *str = NULL; + int ret = 0; + + if ((ret = mxf_read_us_ascii_string(pb, size, &str)) < 0) \ + return ret; + + mca_sub_descriptor->language = str; + } + + return 0; +} + static int mxf_read_indirect_value(void *arg, AVIOContext *pb, int size) { MXFTaggedValue *tagged_value = arg; @@ -1487,6 +1580,56 @@ static const MXFCodecUL mxf_data_essence_container_uls[] = { { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE }, }; +typedef struct MXFSoundfieldGroupUL { + UID uid; + int64_t id; +} MXFSoundfieldGroupUL; + +static const MXFSoundfieldGroupUL mxf_soundfield_groups[] = { + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, AV_CH_LAYOUT_5POINT1 }, // 5.1 + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x02,0x00,0x00,0x00,0x00 }, AV_CH_LAYOUT_7POINT1 }, // 7.1 DS + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x03,0x00,0x00,0x00,0x00 }, AV_CH_LAYOUT_7POINT1_WIDE }, // 7.1 SDS + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x04,0x00,0x00,0x00,0x00 }, AV_CH_LAYOUT_6POINT1 }, // 6.1 + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x05,0x00,0x00,0x00,0x00 }, AV_CH_LAYOUT_MONO }, // 1.0 Monoral + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x20,0x01,0x00,0x00,0x00 }, AV_CH_LAYOUT_STEREO }, // Standard stereo + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x20,0x02,0x00,0x00,0x00 }, AV_CH_LAYOUT_STEREO }, // Dual mono + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x20,0x04,0x00,0x00,0x00 }, AV_CH_LAYOUT_SURROUND }, // 3.0 + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x20,0x05,0x00,0x00,0x00 }, AV_CH_LAYOUT_4POINT0 }, // 4.0 + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x20,0x06,0x00,0x00,0x00 }, AV_CH_LAYOUT_5POINT0 }, // 5.0 + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x20,0x07,0x00,0x00,0x00 }, AV_CH_LAYOUT_6POINT0 }, // 6.0 + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x20,0x08,0x00,0x00,0x00 }, AV_CH_LAYOUT_7POINT0 }, // 7.0 + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x20,0x09,0x00,0x00,0x00 }, AV_CH_LAYOUT_STEREO }, // LrRt + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x20,0x0a,0x00,0x00,0x00 }, AV_CH_LAYOUT_5POINT1 }, // 5.1 EX + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x20,0x0b,0x00,0x00,0x00 }, AV_CH_LAYOUT_MONO }, // Hearing accessibility + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x02,0x20,0x0c,0x00,0x00,0x00 }, AV_CH_LAYOUT_MONO }, // Visual accessibility + { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0 }, +}; + +typedef struct MXFChannelOrderingUL { + UID uid; + int index; + enum AVAudioServiceType service_type; +} MXFChannelOrderingUL; + +static const MXFChannelOrderingUL mxf_channel_ordering[] = { + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00 }, 0, AV_AUDIO_SERVICE_TYPE_NB }, // Left audio channel + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x02,0x00,0x00,0x00,0x00 }, 1, AV_AUDIO_SERVICE_TYPE_NB }, // Right audio channel + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x03,0x00,0x00,0x00,0x00 }, 2, AV_AUDIO_SERVICE_TYPE_NB }, // Center audio channel + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x04,0x00,0x00,0x00,0x00 }, 5, AV_AUDIO_SERVICE_TYPE_NB }, // LFE audio channel + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x05,0x00,0x00,0x00,0x00 }, 3, AV_AUDIO_SERVICE_TYPE_NB }, // Left surround audio channel + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x06,0x00,0x00,0x00,0x00 }, 4, AV_AUDIO_SERVICE_TYPE_NB }, // Right surround audio channel + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x07,0x00,0x00,0x00,0x00 }, 3, AV_AUDIO_SERVICE_TYPE_NB }, // Left side surround audio channel + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x08,0x00,0x00,0x00,0x00 }, 4, AV_AUDIO_SERVICE_TYPE_NB }, // Right side surround audio channel + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x09,0x00,0x00,0x00,0x00 }, 6, AV_AUDIO_SERVICE_TYPE_NB }, // Left rear surround audio channel + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0a,0x00,0x00,0x00,0x00 }, 7, AV_AUDIO_SERVICE_TYPE_NB }, // Right rear surround audio channel + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0b,0x00,0x00,0x00,0x00 }, 6, AV_AUDIO_SERVICE_TYPE_NB }, // Left center audio channel + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0c,0x00,0x00,0x00,0x00 }, 7, AV_AUDIO_SERVICE_TYPE_NB }, // Right center audio channel + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0d,0x00,0x00,0x00,0x00 }, 6, AV_AUDIO_SERVICE_TYPE_NB }, // Center surround audio channel + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0e,0x00,0x00,0x00,0x00 }, 0, AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, // Hearing impaired audio channel + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0f,0x00,0x00,0x00,0x00 }, 0, AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED }, // Visually impaired narrative audio channel + { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_AUDIO_SERVICE_TYPE_NB }, +}; + static MXFWrappingScheme mxf_get_wrapping_kind(UID *essence_container_ul) { int val; @@ -2287,6 +2430,25 @@ static enum AVColorRange mxf_get_color_range(MXFContext *mxf, MXFDescriptor *des return AVCOL_RANGE_UNSPECIFIED; } +static int is_pcm(enum AVCodecID codec_id) +{ + /* we only care about "normal" PCM codecs until we get samples */ + return codec_id >= AV_CODEC_ID_PCM_S16LE && codec_id < AV_CODEC_ID_PCM_S24DAUD; +} + +static void set_language(AVFormatContext *s, const char *rfc5646, AVDictionary **met) +{ + // language abbr should contain at least 2 chars + if (rfc5646 && strlen(rfc5646) > 1) { + const char primary_tag[3] = { rfc5646[0], rfc5646[1], '\0' }; // ignore country code if any + const char *iso6392 = ff_convert_lang_to(primary_tag, + AV_LANG_ISO639_2_BIBL); + if (iso6392) + if (av_dict_set(met, "language", iso6392, 0) < 0) + av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n"); + } +} + static int mxf_parse_structural_metadata(MXFContext *mxf) { MXFPackage *material_package = NULL; @@ -2322,7 +2484,9 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) const MXFCodecUL *pix_fmt_ul = NULL; AVStream *st; AVTimecode tc; + enum AVAudioServiceType *ast; int flags; + int current_channel; if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) { av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n"); @@ -2681,6 +2845,88 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) st->internal->need_parsing = AVSTREAM_PARSE_FULL; } st->codecpar->bits_per_coded_sample = av_get_bits_per_sample(st->codecpar->codec_id); + + current_channel = 0; + + + + for (j = 0; j < FFMIN(descriptor->channels, FF_SANE_NB_CHANNELS); ++j) { + source_track->channel_ordering[j] = j; + } + + for (j = 0; j < descriptor->sub_descriptors_count; j++) { + MXFMCASubDescriptor *mca_sub_descriptor = mxf_resolve_strong_ref(mxf, &descriptor->sub_descriptors_refs[j], MCASubDescriptor); + if (mca_sub_descriptor == NULL) { + continue; + } + + // Soundfield group + if (IS_KLV_KEY(mca_sub_descriptor->mca_label_dictionnary_id, mxf_soundfield_group)) { + MXFSoundfieldGroupUL* group_ptr = (MXFSoundfieldGroupUL*)&mxf_soundfield_groups[0]; + + while (group_ptr->uid[0]) { + if (IS_KLV_KEY(group_ptr->uid, mca_sub_descriptor->mca_label_dictionnary_id)) { + st->codecpar->channel_layout = group_ptr->id; + break; + } + group_ptr++; + } + } + + // Audio channel + if (IS_KLV_KEY(mca_sub_descriptor->mca_label_dictionnary_id, mxf_audio_channel)) { + MXFChannelOrderingUL* channel_ordering_ptr = (MXFChannelOrderingUL*)&mxf_channel_ordering[0]; + + while (channel_ordering_ptr->uid[0]) { + if (IS_KLV_KEY(channel_ordering_ptr->uid, mca_sub_descriptor->mca_label_dictionnary_id)) { + if (current_channel <= FF_SANE_NB_CHANNELS) { + source_track->channel_ordering[current_channel] = channel_ordering_ptr->index; + } else { + av_log(mxf->fc, AV_LOG_WARNING, "MCA Audio mapping: will not reassign channel ordering, the maximum number of channels supported has been reached"); + } + + if(channel_ordering_ptr->service_type != AV_AUDIO_SERVICE_TYPE_NB) { + ast = (enum AVAudioServiceType*)av_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE, sizeof(*ast)); + *ast = channel_ordering_ptr->service_type; + } + + current_channel += 1; + break; + } + channel_ordering_ptr++; + } + } + + // set language from MCA spoken language information + if (mca_sub_descriptor->language) { + set_language(mxf->fc, mca_sub_descriptor->language, &st->metadata); + } + } + + // check if the mapping is not required + source_track->require_reordering = false; + for (j = 0; j < FFMIN(descriptor->channels, FF_SANE_NB_CHANNELS); ++j) { + if (source_track->channel_ordering[j] != j) { + source_track->require_reordering = true; + break; + } + } + + if (source_track->require_reordering && is_pcm(st->codecpar->codec_id)) { + current_channel = 0; + av_log(mxf->fc, AV_LOG_DEBUG, "MCA Audio mapping ("); + for(j = 0; j < descriptor->channels; ++j) { + for(int k = 0; k < descriptor->channels; ++k) { + if(source_track->channel_ordering[k] == current_channel) { + av_log(mxf->fc, AV_LOG_DEBUG, "%d -> %d", source_track->channel_ordering[k], k); + if (current_channel != descriptor->channels - 1) + av_log(mxf->fc, AV_LOG_DEBUG, ", "); + current_channel += 1; + } + } + } + av_log(mxf->fc, AV_LOG_DEBUG, ")\n"); + } } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) { enum AVMediaType type; container_ul = mxf_get_codec_ul(mxf_data_essence_container_uls, essence_container_ul); @@ -2881,6 +3127,8 @@ static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = { { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5c,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* VANC/VBI - SMPTE 436M */ { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5e,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG2AudioDescriptor */ { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x64,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* DC Timed Text Descriptor */ + { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6c,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), MCASubDescriptor }, /* Soundfield Group Label Subdescriptor */ + { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6b,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), MCASubDescriptor }, /* Audio Channel Label Subdescriptor */ { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Static Track */ { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Generic Track */ { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x14,0x00 }, mxf_read_timecode_component, sizeof(MXFTimecodeComponent), TimecodeComponent }, @@ -3180,12 +3428,6 @@ static void mxf_compute_essence_containers(AVFormatContext *s) } } -static int is_pcm(enum AVCodecID codec_id) -{ - /* we only care about "normal" PCM codecs until we get samples */ - return codec_id >= AV_CODEC_ID_PCM_S16LE && codec_id < AV_CODEC_ID_PCM_S24DAUD; -} - static MXFIndexTable *mxf_find_index_table(MXFContext *mxf, int index_sid) { int i; @@ -3612,6 +3854,27 @@ static int mxf_set_pts(MXFContext *mxf, AVStream *st, AVPacket *pkt) return 0; } +static void mxf_audio_remapping(int* channel_ordering, uint8_t* data, int size, int sample_size, int channels) +{ + int sample_offset = channels * sample_size; + int number_of_samples = size / sample_offset; + uint8_t* tmp = av_malloc(sample_offset); + uint8_t* data_ptr = data; + + for (int sample = 0; sample < number_of_samples; ++sample) { + memcpy(tmp, data_ptr, sample_offset); + + for (int channel = 0; channel < channels; ++channel) { + for (int sample_index = 0; sample_index < sample_size; ++sample_index) { + data_ptr[sample_size * channel_ordering[channel] + sample_index] = tmp[sample_size * channel + sample_index]; + } + } + + data_ptr += sample_offset; + } + av_free(tmp); +} + static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) { KLVPacket klv; @@ -3726,6 +3989,12 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) return ret; } + // for audio, process audio remapping if MCA label requires it + if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && track->require_reordering) { + int byte_per_sample = st->codecpar->bits_per_coded_sample / 8; + mxf_audio_remapping(track->channel_ordering, pkt->data, pkt->size, byte_per_sample, st->codecpar->channels); + } + /* seek for truncated packets */ avio_seek(s->pb, klv.next_klv, SEEK_SET);