LCOV - code coverage report
Current view: top level - libavformat - mxfdec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1452 1838 79.0 %
Date: 2018-05-20 11:54:08 Functions: 81 83 97.6 %

          Line data    Source code
       1             : /*
       2             :  * MXF demuxer.
       3             :  * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : /*
      23             :  * References
      24             :  * SMPTE 336M KLV Data Encoding Protocol Using Key-Length-Value
      25             :  * SMPTE 377M MXF File Format Specifications
      26             :  * SMPTE 378M Operational Pattern 1a
      27             :  * SMPTE 379M MXF Generic Container
      28             :  * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container
      29             :  * SMPTE 382M Mapping AES3 and Broadcast Wave Audio into the MXF Generic Container
      30             :  * SMPTE 383M Mapping DV-DIF Data to the MXF Generic Container
      31             :  *
      32             :  * Principle
      33             :  * Search for Track numbers which will identify essence element KLV packets.
      34             :  * Search for SourcePackage which define tracks which contains Track numbers.
      35             :  * Material Package contains tracks with reference to SourcePackage tracks.
      36             :  * Search for Descriptors (Picture, Sound) which contains codec info and parameters.
      37             :  * Assign Descriptors to correct Tracks.
      38             :  *
      39             :  * Metadata reading functions read Local Tags, get InstanceUID(0x3C0A) then add MetaDataSet to MXFContext.
      40             :  * Metadata parsing resolves Strong References to objects.
      41             :  *
      42             :  * Simple demuxer, only OP1A supported and some files might not work at all.
      43             :  * Only tracks with associated descriptors will be decoded. "Highly Desirable" SMPTE 377M D.1
      44             :  */
      45             : 
      46             : #include <inttypes.h>
      47             : 
      48             : #include "libavutil/aes.h"
      49             : #include "libavutil/avassert.h"
      50             : #include "libavutil/mathematics.h"
      51             : #include "libavcodec/bytestream.h"
      52             : #include "libavutil/intreadwrite.h"
      53             : #include "libavutil/parseutils.h"
      54             : #include "libavutil/timecode.h"
      55             : #include "avformat.h"
      56             : #include "internal.h"
      57             : #include "mxf.h"
      58             : 
      59             : typedef enum {
      60             :     Header,
      61             :     BodyPartition,
      62             :     Footer
      63             : } MXFPartitionType;
      64             : 
      65             : typedef enum {
      66             :     OP1a = 1,
      67             :     OP1b,
      68             :     OP1c,
      69             :     OP2a,
      70             :     OP2b,
      71             :     OP2c,
      72             :     OP3a,
      73             :     OP3b,
      74             :     OP3c,
      75             :     OPAtom,
      76             :     OPSONYOpt,  /* FATE sample, violates the spec in places */
      77             : } MXFOP;
      78             : 
      79             : typedef struct MXFPartition {
      80             :     int closed;
      81             :     int complete;
      82             :     MXFPartitionType type;
      83             :     uint64_t previous_partition;
      84             :     int index_sid;
      85             :     int body_sid;
      86             :     int64_t this_partition;
      87             :     int64_t essence_offset;         ///< absolute offset of essence
      88             :     int64_t essence_length;
      89             :     int32_t kag_size;
      90             :     int64_t header_byte_count;
      91             :     int64_t index_byte_count;
      92             :     int pack_length;
      93             :     int64_t pack_ofs;               ///< absolute offset of pack in file, including run-in
      94             :     int64_t body_offset;
      95             : } MXFPartition;
      96             : 
      97             : typedef struct MXFCryptoContext {
      98             :     UID uid;
      99             :     enum MXFMetadataSetType type;
     100             :     UID source_container_ul;
     101             : } MXFCryptoContext;
     102             : 
     103             : typedef struct MXFStructuralComponent {
     104             :     UID uid;
     105             :     enum MXFMetadataSetType type;
     106             :     UID source_package_ul;
     107             :     UID source_package_uid;
     108             :     UID data_definition_ul;
     109             :     int64_t duration;
     110             :     int64_t start_position;
     111             :     int source_track_id;
     112             : } MXFStructuralComponent;
     113             : 
     114             : typedef struct MXFSequence {
     115             :     UID uid;
     116             :     enum MXFMetadataSetType type;
     117             :     UID data_definition_ul;
     118             :     UID *structural_components_refs;
     119             :     int structural_components_count;
     120             :     int64_t duration;
     121             :     uint8_t origin;
     122             : } MXFSequence;
     123             : 
     124             : typedef struct MXFTrack {
     125             :     UID uid;
     126             :     enum MXFMetadataSetType type;
     127             :     int drop_frame;
     128             :     int start_frame;
     129             :     struct AVRational rate;
     130             :     AVTimecode tc;
     131             : } MXFTimecodeComponent;
     132             : 
     133             : typedef struct {
     134             :     UID uid;
     135             :     enum MXFMetadataSetType type;
     136             :     UID input_segment_ref;
     137             : } MXFPulldownComponent;
     138             : 
     139             : typedef struct {
     140             :     UID uid;
     141             :     enum MXFMetadataSetType type;
     142             :     UID *structural_components_refs;
     143             :     int structural_components_count;
     144             :     int64_t duration;
     145             : } MXFEssenceGroup;
     146             : 
     147             : typedef struct {
     148             :     UID uid;
     149             :     enum MXFMetadataSetType type;
     150             :     char *name;
     151             :     char *value;
     152             : } MXFTaggedValue;
     153             : 
     154             : typedef struct {
     155             :     UID uid;
     156             :     enum MXFMetadataSetType type;
     157             :     MXFSequence *sequence; /* mandatory, and only one */
     158             :     UID sequence_ref;
     159             :     int track_id;
     160             :     char *name;
     161             :     uint8_t track_number[4];
     162             :     AVRational edit_rate;
     163             :     int intra_only;
     164             :     uint64_t sample_count;
     165             :     int64_t original_duration; /* st->duration in SampleRate/EditRate units */
     166             :     int index_sid;
     167             :     int body_sid;
     168             : } MXFTrack;
     169             : 
     170             : typedef struct MXFDescriptor {
     171             :     UID uid;
     172             :     enum MXFMetadataSetType type;
     173             :     UID essence_container_ul;
     174             :     UID essence_codec_ul;
     175             :     UID codec_ul;
     176             :     AVRational sample_rate;
     177             :     AVRational aspect_ratio;
     178             :     int width;
     179             :     int height; /* Field height, not frame height */
     180             :     int frame_layout; /* See MXFFrameLayout enum */
     181             :     int video_line_map[2];
     182             : #define MXF_FIELD_DOMINANCE_DEFAULT 0
     183             : #define MXF_FIELD_DOMINANCE_FF 1 /* coded first, displayed first */
     184             : #define MXF_FIELD_DOMINANCE_FL 2 /* coded first, displayed last */
     185             :     int field_dominance;
     186             :     int channels;
     187             :     int bits_per_sample;
     188             :     int64_t duration; /* ContainerDuration optional property */
     189             :     unsigned int component_depth;
     190             :     unsigned int horiz_subsampling;
     191             :     unsigned int vert_subsampling;
     192             :     UID *sub_descriptors_refs;
     193             :     int sub_descriptors_count;
     194             :     int linked_track_id;
     195             :     uint8_t *extradata;
     196             :     int extradata_size;
     197             :     enum AVPixelFormat pix_fmt;
     198             : } MXFDescriptor;
     199             : 
     200             : typedef struct MXFIndexTableSegment {
     201             :     UID uid;
     202             :     enum MXFMetadataSetType type;
     203             :     int edit_unit_byte_count;
     204             :     int index_sid;
     205             :     int body_sid;
     206             :     AVRational index_edit_rate;
     207             :     uint64_t index_start_position;
     208             :     uint64_t index_duration;
     209             :     int8_t *temporal_offset_entries;
     210             :     int *flag_entries;
     211             :     uint64_t *stream_offset_entries;
     212             :     int nb_index_entries;
     213             : } MXFIndexTableSegment;
     214             : 
     215             : typedef struct MXFPackage {
     216             :     UID uid;
     217             :     enum MXFMetadataSetType type;
     218             :     UID package_uid;
     219             :     UID package_ul;
     220             :     UID *tracks_refs;
     221             :     int tracks_count;
     222             :     MXFDescriptor *descriptor; /* only one */
     223             :     UID descriptor_ref;
     224             :     char *name;
     225             :     UID *comment_refs;
     226             :     int comment_count;
     227             : } MXFPackage;
     228             : 
     229             : typedef struct MXFEssenceContainerData {
     230             :     UID uid;
     231             :     enum MXFMetadataSetType type;
     232             :     UID package_uid;
     233             :     UID package_ul;
     234             :     int index_sid;
     235             :     int body_sid;
     236             : } MXFEssenceContainerData;
     237             : 
     238             : typedef struct MXFMetadataSet {
     239             :     UID uid;
     240             :     enum MXFMetadataSetType type;
     241             : } MXFMetadataSet;
     242             : 
     243             : /* decoded index table */
     244             : typedef struct MXFIndexTable {
     245             :     int index_sid;
     246             :     int body_sid;
     247             :     int nb_ptses;               /* number of PTSes or total duration of index */
     248             :     int64_t first_dts;          /* DTS = EditUnit + first_dts */
     249             :     int64_t *ptses;             /* maps EditUnit -> PTS */
     250             :     int nb_segments;
     251             :     MXFIndexTableSegment **segments;    /* sorted by IndexStartPosition */
     252             :     AVIndexEntry *fake_index;   /* used for calling ff_index_search_timestamp() */
     253             :     int8_t *offsets;            /* temporal offsets for display order to stored order conversion */
     254             : } MXFIndexTable;
     255             : 
     256             : typedef struct MXFContext {
     257             :     MXFPartition *partitions;
     258             :     unsigned partitions_count;
     259             :     MXFOP op;
     260             :     UID *packages_refs;
     261             :     int packages_count;
     262             :     UID *essence_container_data_refs;
     263             :     int essence_container_data_count;
     264             :     MXFMetadataSet **metadata_sets;
     265             :     int metadata_sets_count;
     266             :     AVFormatContext *fc;
     267             :     struct AVAES *aesc;
     268             :     uint8_t *local_tags;
     269             :     int local_tags_count;
     270             :     uint64_t footer_partition;
     271             :     KLVPacket current_klv_data;
     272             :     int current_klv_index;
     273             :     int run_in;
     274             :     MXFPartition *current_partition;
     275             :     int parsing_backward;
     276             :     int64_t last_forward_tell;
     277             :     int last_forward_partition;
     278             :     int64_t current_edit_unit;
     279             :     int nb_index_tables;
     280             :     MXFIndexTable *index_tables;
     281             :     int edit_units_per_packet;      ///< how many edit units to read at a time (PCM, OPAtom)
     282             : } MXFContext;
     283             : 
     284             : enum MXFWrappingScheme {
     285             :     Frame,
     286             :     Clip,
     287             : };
     288             : 
     289             : /* NOTE: klv_offset is not set (-1) for local keys */
     290             : typedef int MXFMetadataReadFunc(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset);
     291             : 
     292             : typedef struct MXFMetadataReadTableEntry {
     293             :     const UID key;
     294             :     MXFMetadataReadFunc *read;
     295             :     int ctx_size;
     296             :     enum MXFMetadataSetType type;
     297             : } MXFMetadataReadTableEntry;
     298             : 
     299             : static int mxf_read_close(AVFormatContext *s);
     300             : 
     301             : /* partial keys to match */
     302             : static const uint8_t mxf_header_partition_pack_key[]       = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 };
     303             : static const uint8_t mxf_essence_element_key[]             = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 };
     304             : static const uint8_t mxf_avid_essence_element_key[]        = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0e,0x04,0x03,0x01 };
     305             : static const uint8_t mxf_canopus_essence_element_key[]     = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x0a,0x0e,0x0f,0x03,0x01 };
     306             : static const uint8_t mxf_system_item_key_cp[]              = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x03,0x01,0x04 };
     307             : static const uint8_t mxf_system_item_key_gc[]              = { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x03,0x01,0x14 };
     308             : static const uint8_t mxf_klv_key[]                         = { 0x06,0x0e,0x2b,0x34 };
     309             : /* complete keys to match */
     310             : 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 };
     311             : static const uint8_t mxf_encrypted_triplet_key[]           = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
     312             : static const uint8_t mxf_encrypted_essence_container[]     = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 };
     313             : static const uint8_t mxf_random_index_pack_key[]           = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x11,0x01,0x00 };
     314             : static const uint8_t mxf_sony_mpeg4_extradata[]            = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 };
     315             : static const uint8_t mxf_avid_project_name[]               = { 0xa5,0xfb,0x7b,0x25,0xf6,0x15,0x94,0xb9,0x62,0xfc,0x37,0x17,0x49,0x2d,0x42,0xbf };
     316             : static const uint8_t mxf_jp2k_rsiz[]                       = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x01,0x00 };
     317             : static const uint8_t mxf_indirect_value_utf16le[]          = { 0x4c,0x00,0x02,0x10,0x01,0x00,0x00,0x00,0x00,0x06,0x0e,0x2b,0x34,0x01,0x04,0x01,0x01 };
     318             : static const uint8_t mxf_indirect_value_utf16be[]          = { 0x42,0x01,0x10,0x02,0x00,0x00,0x00,0x00,0x00,0x06,0x0e,0x2b,0x34,0x01,0x04,0x01,0x01 };
     319             : 
     320             : #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
     321             : 
     322        2383 : static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx)
     323             : {
     324             :     MXFIndexTableSegment *seg;
     325        2383 :     switch ((*ctx)->type) {
     326         179 :     case Descriptor:
     327         179 :         av_freep(&((MXFDescriptor *)*ctx)->extradata);
     328         179 :         break;
     329          80 :     case MultipleDescriptor:
     330          80 :         av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs);
     331          80 :         break;
     332         554 :     case Sequence:
     333         554 :         av_freep(&((MXFSequence *)*ctx)->structural_components_refs);
     334         554 :         break;
     335           2 :     case EssenceGroup:
     336           2 :         av_freep(&((MXFEssenceGroup *)*ctx)->structural_components_refs);
     337           2 :         break;
     338         188 :     case SourcePackage:
     339             :     case MaterialPackage:
     340         188 :         av_freep(&((MXFPackage *)*ctx)->tracks_refs);
     341         188 :         av_freep(&((MXFPackage *)*ctx)->name);
     342         188 :         av_freep(&((MXFPackage *)*ctx)->comment_refs);
     343         188 :         break;
     344          87 :     case TaggedValue:
     345          87 :         av_freep(&((MXFTaggedValue *)*ctx)->name);
     346          87 :         av_freep(&((MXFTaggedValue *)*ctx)->value);
     347          87 :         break;
     348         554 :     case Track:
     349         554 :         av_freep(&((MXFTrack *)*ctx)->name);
     350         554 :         break;
     351          92 :     case IndexTableSegment:
     352          92 :         seg = (MXFIndexTableSegment *)*ctx;
     353          92 :         av_freep(&seg->temporal_offset_entries);
     354          92 :         av_freep(&seg->flag_entries);
     355          92 :         av_freep(&seg->stream_offset_entries);
     356         739 :     default:
     357         739 :         break;
     358             :     }
     359        2383 :     if (freectx)
     360        2383 :     av_freep(ctx);
     361        2383 : }
     362             : 
     363       24764 : static int64_t klv_decode_ber_length(AVIOContext *pb)
     364             : {
     365       24764 :     uint64_t size = avio_r8(pb);
     366       24764 :     if (size & 0x80) { /* long form */
     367       22728 :         int bytes_num = size & 0x7f;
     368             :         /* SMPTE 379M 5.3.4 guarantee that bytes_num must not exceed 8 bytes */
     369       22728 :         if (bytes_num > 8)
     370           0 :             return AVERROR_INVALIDDATA;
     371       22728 :         size = 0;
     372      133494 :         while (bytes_num--)
     373       88038 :             size = size << 8 | avio_r8(pb);
     374             :     }
     375       24764 :     return size;
     376             : }
     377             : 
     378       25054 : static int mxf_read_sync(AVIOContext *pb, const uint8_t *key, unsigned size)
     379             : {
     380             :     int i, b;
     381      176636 :     for (i = 0; i < size && !avio_feof(pb); i++) {
     382      151582 :         b = avio_r8(pb);
     383      151582 :         if (b == key[0])
     384       24992 :             i = 0;
     385      126590 :         else if (b != key[i])
     386       51115 :             i = -1;
     387             :     }
     388       25054 :     return i == size;
     389             : }
     390             : 
     391       24963 : static int klv_read_packet(KLVPacket *klv, AVIOContext *pb)
     392             : {
     393       24963 :     if (!mxf_read_sync(pb, mxf_klv_key, 4))
     394         199 :         return AVERROR_INVALIDDATA;
     395       24764 :     klv->offset = avio_tell(pb) - 4;
     396       24764 :     memcpy(klv->key, mxf_klv_key, 4);
     397       24764 :     avio_read(pb, klv->key + 4, 12);
     398       24764 :     klv->length = klv_decode_ber_length(pb);
     399       24764 :     return klv->length == -1 ? -1 : 0;
     400             : }
     401             : 
     402        4833 : static int mxf_get_stream_index(AVFormatContext *s, KLVPacket *klv, int body_sid)
     403             : {
     404             :     int i;
     405             : 
     406        7310 :     for (i = 0; i < s->nb_streams; i++) {
     407        7310 :         MXFTrack *track = s->streams[i]->priv_data;
     408             :         /* SMPTE 379M 7.3 */
     409        7310 :         if (track && (!body_sid || !track->body_sid || track->body_sid == body_sid) && !memcmp(klv->key + sizeof(mxf_essence_element_key), track->track_number, sizeof(track->track_number)))
     410        4833 :             return i;
     411             :     }
     412             :     /* return 0 if only one stream, for OP Atom files with 0 as track number */
     413           0 :     return s->nb_streams == 1 ? 0 : -1;
     414             : }
     415             : 
     416        4833 : static int find_body_sid_by_offset(MXFContext *mxf, int64_t offset)
     417             : {
     418             :     // we look for partition where the offset is placed
     419             :     int a, b, m;
     420             :     int64_t this_partition;
     421             : 
     422        4833 :     a = -1;
     423        4833 :     b = mxf->partitions_count;
     424             : 
     425       19279 :     while (b - a > 1) {
     426        9613 :         m         = (a + b) >> 1;
     427        9613 :         this_partition = mxf->partitions[m].this_partition;
     428        9613 :         if (this_partition <= offset)
     429        4833 :             a = m;
     430             :         else
     431        4780 :             b = m;
     432             :     }
     433             : 
     434        4833 :     if (a == -1)
     435           0 :         return 0;
     436        4833 :     return mxf->partitions[a].body_sid;
     437             : }
     438             : 
     439             : /* XXX: use AVBitStreamFilter */
     440         908 : static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt, int64_t length)
     441             : {
     442             :     const uint8_t *buf_ptr, *end_ptr;
     443             :     uint8_t *data_ptr;
     444             :     int i;
     445             : 
     446         908 :     if (length > 61444) /* worst case PAL 1920 samples 8 channels */
     447           0 :         return AVERROR_INVALIDDATA;
     448         908 :     length = av_get_packet(pb, pkt, length);
     449         908 :     if (length < 0)
     450           0 :         return length;
     451         908 :     data_ptr = pkt->data;
     452         908 :     end_ptr = pkt->data + length;
     453         908 :     buf_ptr = pkt->data + 4; /* skip SMPTE 331M header */
     454     1745176 :     for (; end_ptr - buf_ptr >= st->codecpar->channels * 4; ) {
     455     5322240 :         for (i = 0; i < st->codecpar->channels; i++) {
     456     3578880 :             uint32_t sample = bytestream_get_le32(&buf_ptr);
     457     3578880 :             if (st->codecpar->bits_per_coded_sample == 24)
     458           0 :                 bytestream_put_le24(&data_ptr, (sample >> 4) & 0xffffff);
     459             :             else
     460     3578880 :                 bytestream_put_le16(&data_ptr, (sample >> 12) & 0xffff);
     461             :         }
     462     1743360 :         buf_ptr += 32 - st->codecpar->channels*4; // always 8 channels stored SMPTE 331M
     463             :     }
     464         908 :     av_shrink_packet(pkt, data_ptr - pkt->data);
     465         908 :     return 0;
     466             : }
     467             : 
     468           0 : static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv)
     469             : {
     470             :     static const uint8_t checkv[16] = {0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b};
     471           0 :     MXFContext *mxf = s->priv_data;
     472           0 :     AVIOContext *pb = s->pb;
     473           0 :     int64_t end = avio_tell(pb) + klv->length;
     474             :     int64_t size;
     475             :     uint64_t orig_size;
     476             :     uint64_t plaintext_size;
     477             :     uint8_t ivec[16];
     478             :     uint8_t tmpbuf[16];
     479             :     int index;
     480             :     int body_sid;
     481             : 
     482           0 :     if (!mxf->aesc && s->key && s->keylen == 16) {
     483           0 :         mxf->aesc = av_aes_alloc();
     484           0 :         if (!mxf->aesc)
     485           0 :             return AVERROR(ENOMEM);
     486           0 :         av_aes_init(mxf->aesc, s->key, 128, 1);
     487             :     }
     488             :     // crypto context
     489           0 :     avio_skip(pb, klv_decode_ber_length(pb));
     490             :     // plaintext offset
     491           0 :     klv_decode_ber_length(pb);
     492           0 :     plaintext_size = avio_rb64(pb);
     493             :     // source klv key
     494           0 :     klv_decode_ber_length(pb);
     495           0 :     avio_read(pb, klv->key, 16);
     496           0 :     if (!IS_KLV_KEY(klv, mxf_essence_element_key))
     497           0 :         return AVERROR_INVALIDDATA;
     498             : 
     499           0 :     body_sid = find_body_sid_by_offset(mxf, klv->offset);
     500           0 :     index = mxf_get_stream_index(s, klv, body_sid);
     501           0 :     if (index < 0)
     502           0 :         return AVERROR_INVALIDDATA;
     503             :     // source size
     504           0 :     klv_decode_ber_length(pb);
     505           0 :     orig_size = avio_rb64(pb);
     506           0 :     if (orig_size < plaintext_size)
     507           0 :         return AVERROR_INVALIDDATA;
     508             :     // enc. code
     509           0 :     size = klv_decode_ber_length(pb);
     510           0 :     if (size < 32 || size - 32 < orig_size)
     511           0 :         return AVERROR_INVALIDDATA;
     512           0 :     avio_read(pb, ivec, 16);
     513           0 :     avio_read(pb, tmpbuf, 16);
     514           0 :     if (mxf->aesc)
     515           0 :         av_aes_crypt(mxf->aesc, tmpbuf, tmpbuf, 1, ivec, 1);
     516           0 :     if (memcmp(tmpbuf, checkv, 16))
     517           0 :         av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n");
     518           0 :     size -= 32;
     519           0 :     size = av_get_packet(pb, pkt, size);
     520           0 :     if (size < 0)
     521           0 :         return size;
     522           0 :     else if (size < plaintext_size)
     523           0 :         return AVERROR_INVALIDDATA;
     524           0 :     size -= plaintext_size;
     525           0 :     if (mxf->aesc)
     526           0 :         av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size],
     527           0 :                      &pkt->data[plaintext_size], size >> 4, ivec, 1);
     528           0 :     av_shrink_packet(pkt, orig_size);
     529           0 :     pkt->stream_index = index;
     530           0 :     avio_skip(pb, end - avio_tell(pb));
     531           0 :     return 0;
     532             : }
     533             : 
     534          91 : static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
     535             : {
     536          91 :     MXFContext *mxf = arg;
     537          91 :     int item_num = avio_rb32(pb);
     538          91 :     int item_len = avio_rb32(pb);
     539             : 
     540          91 :     if (item_len != 18) {
     541           0 :         avpriv_request_sample(pb, "Primer pack item length %d", item_len);
     542           0 :         return AVERROR_PATCHWELCOME;
     543             :     }
     544          91 :     if (item_num > 65536 || item_num < 0) {
     545           0 :         av_log(mxf->fc, AV_LOG_ERROR, "item_num %d is too large\n", item_num);
     546           0 :         return AVERROR_INVALIDDATA;
     547             :     }
     548          91 :     if (mxf->local_tags)
     549           0 :         av_log(mxf->fc, AV_LOG_VERBOSE, "Multiple primer packs\n");
     550          91 :     av_free(mxf->local_tags);
     551          91 :     mxf->local_tags_count = 0;
     552          91 :     mxf->local_tags = av_calloc(item_num, item_len);
     553          91 :     if (!mxf->local_tags)
     554           0 :         return AVERROR(ENOMEM);
     555          91 :     mxf->local_tags_count = item_num;
     556          91 :     avio_read(pb, mxf->local_tags, item_num*item_len);
     557          91 :     return 0;
     558             : }
     559             : 
     560         227 : static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
     561             : {
     562         227 :     MXFContext *mxf = arg;
     563             :     MXFPartition *partition, *tmp_part;
     564             :     UID op;
     565             :     uint64_t footer_partition;
     566             :     uint32_t nb_essence_containers;
     567             : 
     568         227 :     if (mxf->partitions_count >= INT_MAX / 2)
     569           0 :         return AVERROR_INVALIDDATA;
     570             : 
     571         227 :     tmp_part = av_realloc_array(mxf->partitions, mxf->partitions_count + 1, sizeof(*mxf->partitions));
     572         227 :     if (!tmp_part)
     573           0 :         return AVERROR(ENOMEM);
     574         227 :     mxf->partitions = tmp_part;
     575             : 
     576         227 :     if (mxf->parsing_backward) {
     577             :         /* insert the new partition pack in the middle
     578             :          * this makes the entries in mxf->partitions sorted by offset */
     579         176 :         memmove(&mxf->partitions[mxf->last_forward_partition+1],
     580          88 :                 &mxf->partitions[mxf->last_forward_partition],
     581          88 :                 (mxf->partitions_count - mxf->last_forward_partition)*sizeof(*mxf->partitions));
     582          88 :         partition = mxf->current_partition = &mxf->partitions[mxf->last_forward_partition];
     583             :     } else {
     584         139 :         mxf->last_forward_partition++;
     585         139 :         partition = mxf->current_partition = &mxf->partitions[mxf->partitions_count];
     586             :     }
     587             : 
     588         227 :     memset(partition, 0, sizeof(*partition));
     589         227 :     mxf->partitions_count++;
     590         227 :     partition->pack_length = avio_tell(pb) - klv_offset + size;
     591         227 :     partition->pack_ofs    = klv_offset;
     592             : 
     593         227 :     switch(uid[13]) {
     594          91 :     case 2:
     595          91 :         partition->type = Header;
     596          91 :         break;
     597          48 :     case 3:
     598          48 :         partition->type = BodyPartition;
     599          48 :         break;
     600          88 :     case 4:
     601          88 :         partition->type = Footer;
     602          88 :         break;
     603           0 :     default:
     604           0 :         av_log(mxf->fc, AV_LOG_ERROR, "unknown partition type %i\n", uid[13]);
     605           0 :         return AVERROR_INVALIDDATA;
     606             :     }
     607             : 
     608             :     /* consider both footers to be closed (there is only Footer and CompleteFooter) */
     609         227 :     partition->closed = partition->type == Footer || !(uid[14] & 1);
     610         227 :     partition->complete = uid[14] > 2;
     611         227 :     avio_skip(pb, 4);
     612         227 :     partition->kag_size = avio_rb32(pb);
     613         227 :     partition->this_partition = avio_rb64(pb);
     614         227 :     partition->previous_partition = avio_rb64(pb);
     615         227 :     footer_partition = avio_rb64(pb);
     616         227 :     partition->header_byte_count = avio_rb64(pb);
     617         227 :     partition->index_byte_count = avio_rb64(pb);
     618         227 :     partition->index_sid = avio_rb32(pb);
     619         227 :     partition->body_offset = avio_rb64(pb);
     620         227 :     partition->body_sid = avio_rb32(pb);
     621         227 :     if (avio_read(pb, op, sizeof(UID)) != sizeof(UID)) {
     622           0 :         av_log(mxf->fc, AV_LOG_ERROR, "Failed reading UID\n");
     623           0 :         return AVERROR_INVALIDDATA;
     624             :     }
     625         227 :     nb_essence_containers = avio_rb32(pb);
     626             : 
     627         363 :     if (partition->this_partition &&
     628         136 :         partition->previous_partition == partition->this_partition) {
     629           0 :         av_log(mxf->fc, AV_LOG_ERROR,
     630             :                "PreviousPartition equal to ThisPartition %"PRIx64"\n",
     631             :                partition->previous_partition);
     632             :         /* override with the actual previous partition offset */
     633           0 :         if (!mxf->parsing_backward && mxf->last_forward_partition > 1) {
     634           0 :             MXFPartition *prev =
     635           0 :                 mxf->partitions + mxf->last_forward_partition - 2;
     636           0 :             partition->previous_partition = prev->this_partition;
     637             :         }
     638             :         /* if no previous body partition are found point to the header
     639             :          * partition */
     640           0 :         if (partition->previous_partition == partition->this_partition)
     641           0 :             partition->previous_partition = 0;
     642           0 :         av_log(mxf->fc, AV_LOG_ERROR,
     643             :                "Overriding PreviousPartition with %"PRIx64"\n",
     644             :                partition->previous_partition);
     645             :     }
     646             : 
     647             :     /* some files don't have FooterPartition set in every partition */
     648         227 :     if (footer_partition) {
     649         187 :         if (mxf->footer_partition && mxf->footer_partition != footer_partition) {
     650           0 :             av_log(mxf->fc, AV_LOG_ERROR,
     651             :                    "inconsistent FooterPartition value: %"PRIu64" != %"PRIu64"\n",
     652             :                    mxf->footer_partition, footer_partition);
     653             :         } else {
     654         187 :             mxf->footer_partition = footer_partition;
     655             :         }
     656             :     }
     657             : 
     658         227 :     av_log(mxf->fc, AV_LOG_TRACE,
     659             :             "PartitionPack: ThisPartition = 0x%"PRIX64
     660             :             ", PreviousPartition = 0x%"PRIX64", "
     661             :             "FooterPartition = 0x%"PRIX64", IndexSID = %i, BodySID = %i\n",
     662             :             partition->this_partition,
     663             :             partition->previous_partition, footer_partition,
     664             :             partition->index_sid, partition->body_sid);
     665             : 
     666             :     /* sanity check PreviousPartition if set */
     667             :     //NOTE: this isn't actually enough, see mxf_seek_to_previous_partition()
     668         275 :     if (partition->previous_partition &&
     669          48 :         mxf->run_in + partition->previous_partition >= klv_offset) {
     670           0 :         av_log(mxf->fc, AV_LOG_ERROR,
     671             :                "PreviousPartition points to this partition or forward\n");
     672           0 :         return AVERROR_INVALIDDATA;
     673             :     }
     674             : 
     675         227 :     if      (op[12] == 1 && op[13] == 1) mxf->op = OP1a;
     676          35 :     else if (op[12] == 1 && op[13] == 2) mxf->op = OP1b;
     677          35 :     else if (op[12] == 1 && op[13] == 3) mxf->op = OP1c;
     678          35 :     else if (op[12] == 2 && op[13] == 1) mxf->op = OP2a;
     679          35 :     else if (op[12] == 2 && op[13] == 2) mxf->op = OP2b;
     680          35 :     else if (op[12] == 2 && op[13] == 3) mxf->op = OP2c;
     681          35 :     else if (op[12] == 3 && op[13] == 1) mxf->op = OP3a;
     682          35 :     else if (op[12] == 3 && op[13] == 2) mxf->op = OP3b;
     683          35 :     else if (op[12] == 3 && op[13] == 3) mxf->op = OP3c;
     684          35 :     else if (op[12] == 64&& op[13] == 1) mxf->op = OPSONYOpt;
     685          33 :     else if (op[12] == 0x10) {
     686             :         /* SMPTE 390m: "There shall be exactly one essence container"
     687             :          * The following block deals with files that violate this, namely:
     688             :          * 2011_DCPTEST_24FPS.V.mxf - two ECs, OP1a
     689             :          * abcdefghiv016f56415e.mxf - zero ECs, OPAtom, output by Avid AirSpeed */
     690          33 :         if (nb_essence_containers != 1) {
     691           3 :             MXFOP op = nb_essence_containers ? OP1a : OPAtom;
     692             : 
     693             :             /* only nag once */
     694           3 :             if (!mxf->op)
     695           1 :                 av_log(mxf->fc, AV_LOG_WARNING,
     696             :                        "\"OPAtom\" with %"PRIu32" ECs - assuming %s\n",
     697             :                        nb_essence_containers,
     698             :                        op == OP1a ? "OP1a" : "OPAtom");
     699             : 
     700           3 :             mxf->op = op;
     701             :         } else
     702          30 :             mxf->op = OPAtom;
     703             :     } else {
     704           0 :         av_log(mxf->fc, AV_LOG_ERROR, "unknown operational pattern: %02xh %02xh - guessing OP1a\n", op[12], op[13]);
     705           0 :         mxf->op = OP1a;
     706             :     }
     707             : 
     708         227 :     if (partition->kag_size <= 0 || partition->kag_size > (1 << 20)) {
     709           2 :         av_log(mxf->fc, AV_LOG_WARNING, "invalid KAGSize %"PRId32" - guessing ",
     710             :                partition->kag_size);
     711             : 
     712           2 :         if (mxf->op == OPSONYOpt)
     713           2 :             partition->kag_size = 512;
     714             :         else
     715           0 :             partition->kag_size = 1;
     716             : 
     717           2 :         av_log(mxf->fc, AV_LOG_WARNING, "%"PRId32"\n", partition->kag_size);
     718             :     }
     719             : 
     720         227 :     return 0;
     721             : }
     722             : 
     723        2383 : static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set)
     724             : {
     725             :     MXFMetadataSet **tmp;
     726             : 
     727        2383 :     tmp = av_realloc_array(mxf->metadata_sets, mxf->metadata_sets_count + 1, sizeof(*mxf->metadata_sets));
     728        2383 :     if (!tmp)
     729           0 :         return AVERROR(ENOMEM);
     730        2383 :     mxf->metadata_sets = tmp;
     731        2383 :     mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set;
     732        2383 :     mxf->metadata_sets_count++;
     733        2383 :     return 0;
     734             : }
     735             : 
     736           0 : static int mxf_read_cryptographic_context(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
     737             : {
     738           0 :     MXFCryptoContext *cryptocontext = arg;
     739           0 :     if (size != 16)
     740           0 :         return AVERROR_INVALIDDATA;
     741           0 :     if (IS_KLV_KEY(uid, mxf_crypto_source_container_ul))
     742           0 :         avio_read(pb, cryptocontext->source_container_ul, 16);
     743           0 :     return 0;
     744             : }
     745             : 
     746        1011 : static int mxf_read_strong_ref_array(AVIOContext *pb, UID **refs, int *count)
     747             : {
     748        1011 :     *count = avio_rb32(pb);
     749        1011 :     *refs = av_calloc(*count, sizeof(UID));
     750        1011 :     if (!*refs) {
     751           0 :         *count = 0;
     752           0 :         return AVERROR(ENOMEM);
     753             :     }
     754        1011 :     avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */
     755        1011 :     avio_read(pb, (uint8_t *)*refs, *count * sizeof(UID));
     756        1011 :     return 0;
     757             : }
     758             : 
     759         465 : static inline int mxf_read_utf16_string(AVIOContext *pb, int size, char** str, int be)
     760             : {
     761             :     int ret;
     762             :     size_t buf_size;
     763             : 
     764         465 :     if (size < 0 || size > INT_MAX/2)
     765           0 :         return AVERROR(EINVAL);
     766             : 
     767         465 :     buf_size = size + size / 2 + 1;
     768         465 :     *str = av_malloc(buf_size);
     769         465 :     if (!*str)
     770           0 :         return AVERROR(ENOMEM);
     771             : 
     772         465 :     if (be)
     773         435 :         ret = avio_get_str16be(pb, size, *str, buf_size);
     774             :     else
     775          30 :         ret = avio_get_str16le(pb, size, *str, buf_size);
     776             : 
     777         465 :     if (ret < 0) {
     778           0 :         av_freep(str);
     779           0 :         return ret;
     780             :     }
     781             : 
     782         465 :     return ret;
     783             : }
     784             : 
     785             : #define READ_STR16(type, big_endian)                                               \
     786             : static int mxf_read_utf16 ## type ##_string(AVIOContext *pb, int size, char** str) \
     787             : {                                                                                  \
     788             : return mxf_read_utf16_string(pb, size, str, big_endian);                           \
     789             : }
     790         435 : READ_STR16(be, 1)
     791          30 : READ_STR16(le, 0)
     792             : #undef READ_STR16
     793             : 
     794         273 : static int mxf_read_content_storage(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
     795             : {
     796         273 :     MXFContext *mxf = arg;
     797         273 :     switch (tag) {
     798          91 :     case 0x1901:
     799          91 :         if (mxf->packages_refs)
     800           0 :             av_log(mxf->fc, AV_LOG_VERBOSE, "Multiple packages_refs\n");
     801          91 :         av_free(mxf->packages_refs);
     802          91 :         return mxf_read_strong_ref_array(pb, &mxf->packages_refs, &mxf->packages_count);
     803          91 :     case 0x1902:
     804          91 :         av_free(mxf->essence_container_data_refs);
     805          91 :         return mxf_read_strong_ref_array(pb, &mxf->essence_container_data_refs, &mxf->essence_container_data_count);
     806             :     }
     807          91 :     return 0;
     808             : }
     809             : 
     810        1895 : static int mxf_read_source_clip(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
     811             : {
     812        1895 :     MXFStructuralComponent *source_clip = arg;
     813        1895 :     switch(tag) {
     814         379 :     case 0x0202:
     815         379 :         source_clip->duration = avio_rb64(pb);
     816         379 :         break;
     817         379 :     case 0x1201:
     818         379 :         source_clip->start_position = avio_rb64(pb);
     819         379 :         break;
     820         379 :     case 0x1101:
     821             :         /* UMID, only get last 16 bytes */
     822         379 :         avio_read(pb, source_clip->source_package_ul, 16);
     823         379 :         avio_read(pb, source_clip->source_package_uid, 16);
     824         379 :         break;
     825         379 :     case 0x1102:
     826         379 :         source_clip->source_track_id = avio_rb32(pb);
     827         379 :         break;
     828             :     }
     829        1895 :     return 0;
     830             : }
     831             : 
     832         880 : static int mxf_read_timecode_component(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
     833             : {
     834         880 :     MXFTimecodeComponent *mxf_timecode = arg;
     835         880 :     switch(tag) {
     836         176 :     case 0x1501:
     837         176 :         mxf_timecode->start_frame = avio_rb64(pb);
     838         176 :         break;
     839         176 :     case 0x1502:
     840         176 :         mxf_timecode->rate = (AVRational){avio_rb16(pb), 1};
     841         176 :         break;
     842         176 :     case 0x1503:
     843         176 :         mxf_timecode->drop_frame = avio_r8(pb);
     844         176 :         break;
     845             :     }
     846         880 :     return 0;
     847             : }
     848             : 
     849           6 : static int mxf_read_pulldown_component(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
     850             : {
     851           6 :     MXFPulldownComponent *mxf_pulldown = arg;
     852           6 :     switch(tag) {
     853           1 :     case 0x0d01:
     854           1 :         avio_read(pb, mxf_pulldown->input_segment_ref, 16);
     855           1 :         break;
     856             :     }
     857           6 :     return 0;
     858             : }
     859             : 
     860        2812 : static int mxf_read_track(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
     861             : {
     862        2812 :     MXFTrack *track = arg;
     863        2812 :     switch(tag) {
     864         554 :     case 0x4801:
     865         554 :         track->track_id = avio_rb32(pb);
     866         554 :         break;
     867         554 :     case 0x4804:
     868         554 :         avio_read(pb, track->track_number, 4);
     869         554 :         break;
     870          42 :     case 0x4802:
     871          42 :         mxf_read_utf16be_string(pb, size, &track->name);
     872          42 :         break;
     873         554 :     case 0x4b01:
     874         554 :         track->edit_rate.num = avio_rb32(pb);
     875         554 :         track->edit_rate.den = avio_rb32(pb);
     876         554 :         break;
     877         554 :     case 0x4803:
     878         554 :         avio_read(pb, track->sequence_ref, 16);
     879         554 :         break;
     880             :     }
     881        2812 :     return 0;
     882             : }
     883             : 
     884        1662 : static int mxf_read_sequence(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
     885             : {
     886        1662 :     MXFSequence *sequence = arg;
     887        1662 :     switch(tag) {
     888         554 :     case 0x0202:
     889         554 :         sequence->duration = avio_rb64(pb);
     890         554 :         break;
     891         554 :     case 0x0201:
     892         554 :         avio_read(pb, sequence->data_definition_ul, 16);
     893         554 :         break;
     894           0 :         case 0x4b02:
     895           0 :         sequence->origin = avio_r8(pb);
     896           0 :         break;
     897         554 :     case 0x1001:
     898         554 :         return mxf_read_strong_ref_array(pb, &sequence->structural_components_refs,
     899             :                                              &sequence->structural_components_count);
     900             :     }
     901        1108 :     return 0;
     902             : }
     903             : 
     904           8 : static int mxf_read_essence_group(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
     905             : {
     906           8 :     MXFEssenceGroup *essence_group = arg;
     907           8 :     switch (tag) {
     908           2 :     case 0x0202:
     909           2 :         essence_group->duration = avio_rb64(pb);
     910           2 :         break;
     911           2 :     case 0x0501:
     912           2 :         return mxf_read_strong_ref_array(pb, &essence_group->structural_components_refs,
     913             :                                              &essence_group->structural_components_count);
     914             :     }
     915           6 :     return 0;
     916             : }
     917             : 
     918         896 : static int mxf_read_package(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
     919             : {
     920         896 :     MXFPackage *package = arg;
     921         896 :     switch(tag) {
     922         188 :     case 0x4403:
     923         188 :         return mxf_read_strong_ref_array(pb, &package->tracks_refs,
     924             :                                              &package->tracks_count);
     925         188 :     case 0x4401:
     926             :         /* UMID */
     927         188 :         avio_read(pb, package->package_ul, 16);
     928         188 :         avio_read(pb, package->package_uid, 16);
     929         188 :         break;
     930          97 :     case 0x4701:
     931          97 :         avio_read(pb, package->descriptor_ref, 16);
     932          97 :         break;
     933          20 :     case 0x4402:
     934          20 :         return mxf_read_utf16be_string(pb, size, &package->name);
     935           5 :     case 0x4406:
     936           5 :         return mxf_read_strong_ref_array(pb, &package->comment_refs,
     937             :                                              &package->comment_count);
     938             :     }
     939         683 :     return 0;
     940             : }
     941             : 
     942         272 : static int mxf_read_essence_container_data(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
     943             : {
     944         272 :     MXFEssenceContainerData *essence_data = arg;
     945         272 :     switch(tag) {
     946          91 :         case 0x2701:
     947             :             /* linked package umid UMID */
     948          91 :             avio_read(pb, essence_data->package_ul, 16);
     949          91 :             avio_read(pb, essence_data->package_uid, 16);
     950          91 :             break;
     951          90 :         case 0x3f06:
     952          90 :             essence_data->index_sid = avio_rb32(pb);
     953          90 :             break;
     954          91 :         case 0x3f07:
     955          91 :             essence_data->body_sid = avio_rb32(pb);
     956          91 :             break;
     957             :     }
     958         272 :     return 0;
     959             : }
     960             : 
     961          45 : static int mxf_read_index_entry_array(AVIOContext *pb, MXFIndexTableSegment *segment)
     962             : {
     963             :     int i, length;
     964             : 
     965          45 :     segment->nb_index_entries = avio_rb32(pb);
     966             : 
     967          45 :     length = avio_rb32(pb);
     968          45 :     if(segment->nb_index_entries && length < 11)
     969           0 :         return AVERROR_INVALIDDATA;
     970             : 
     971          90 :     if (!(segment->temporal_offset_entries=av_calloc(segment->nb_index_entries, sizeof(*segment->temporal_offset_entries))) ||
     972          90 :         !(segment->flag_entries          = av_calloc(segment->nb_index_entries, sizeof(*segment->flag_entries))) ||
     973          45 :         !(segment->stream_offset_entries = av_calloc(segment->nb_index_entries, sizeof(*segment->stream_offset_entries)))) {
     974           0 :         av_freep(&segment->temporal_offset_entries);
     975           0 :         av_freep(&segment->flag_entries);
     976           0 :         return AVERROR(ENOMEM);
     977             :     }
     978             : 
     979        1331 :     for (i = 0; i < segment->nb_index_entries; i++) {
     980        1286 :         if(avio_feof(pb))
     981           0 :             return AVERROR_INVALIDDATA;
     982        1286 :         segment->temporal_offset_entries[i] = avio_r8(pb);
     983        1286 :         avio_r8(pb);                                        /* KeyFrameOffset */
     984        1286 :         segment->flag_entries[i] = avio_r8(pb);
     985        1286 :         segment->stream_offset_entries[i] = avio_rb64(pb);
     986        1286 :         avio_skip(pb, length - 11);
     987             :     }
     988          45 :     return 0;
     989             : }
     990             : 
     991         681 : static int mxf_read_index_table_segment(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
     992             : {
     993         681 :     MXFIndexTableSegment *segment = arg;
     994         681 :     switch(tag) {
     995          91 :     case 0x3F05:
     996          91 :         segment->edit_unit_byte_count = avio_rb32(pb);
     997          91 :         av_log(NULL, AV_LOG_TRACE, "EditUnitByteCount %d\n", segment->edit_unit_byte_count);
     998          91 :         break;
     999          91 :     case 0x3F06:
    1000          91 :         segment->index_sid = avio_rb32(pb);
    1001          91 :         av_log(NULL, AV_LOG_TRACE, "IndexSID %d\n", segment->index_sid);
    1002          91 :         break;
    1003          91 :     case 0x3F07:
    1004          91 :         segment->body_sid = avio_rb32(pb);
    1005          91 :         av_log(NULL, AV_LOG_TRACE, "BodySID %d\n", segment->body_sid);
    1006          91 :         break;
    1007          45 :     case 0x3F0A:
    1008          45 :         av_log(NULL, AV_LOG_TRACE, "IndexEntryArray found\n");
    1009          45 :         return mxf_read_index_entry_array(pb, segment);
    1010          91 :     case 0x3F0B:
    1011          91 :         segment->index_edit_rate.num = avio_rb32(pb);
    1012          91 :         segment->index_edit_rate.den = avio_rb32(pb);
    1013          91 :         av_log(NULL, AV_LOG_TRACE, "IndexEditRate %d/%d\n", segment->index_edit_rate.num,
    1014             :                 segment->index_edit_rate.den);
    1015          91 :         break;
    1016          91 :     case 0x3F0C:
    1017          91 :         segment->index_start_position = avio_rb64(pb);
    1018          91 :         av_log(NULL, AV_LOG_TRACE, "IndexStartPosition %"PRId64"\n", segment->index_start_position);
    1019          91 :         break;
    1020          91 :     case 0x3F0D:
    1021          91 :         segment->index_duration = avio_rb64(pb);
    1022          91 :         av_log(NULL, AV_LOG_TRACE, "IndexDuration %"PRId64"\n", segment->index_duration);
    1023          91 :         break;
    1024             :     }
    1025         636 :     return 0;
    1026             : }
    1027             : 
    1028           1 : static void mxf_read_pixel_layout(AVIOContext *pb, MXFDescriptor *descriptor)
    1029             : {
    1030           1 :     int code, value, ofs = 0;
    1031           1 :     char layout[16] = {0}; /* not for printing, may end up not terminated on purpose */
    1032             : 
    1033             :     do {
    1034           2 :         code = avio_r8(pb);
    1035           2 :         value = avio_r8(pb);
    1036           2 :         av_log(NULL, AV_LOG_TRACE, "pixel layout: code %#x\n", code);
    1037             : 
    1038           2 :         if (ofs <= 14) {
    1039           2 :             layout[ofs++] = code;
    1040           2 :             layout[ofs++] = value;
    1041             :         } else
    1042           0 :             break;  /* don't read byte by byte on sneaky files filled with lots of non-zeroes */
    1043           2 :     } while (code != 0); /* SMPTE 377M E.2.46 */
    1044             : 
    1045           1 :     ff_mxf_decode_pixel_layout(layout, &descriptor->pix_fmt);
    1046           1 : }
    1047             : 
    1048        3322 : static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
    1049             : {
    1050        3322 :     MXFDescriptor *descriptor = arg;
    1051             :     int entry_count, entry_size;
    1052             : 
    1053        3322 :     switch(tag) {
    1054          80 :     case 0x3F01:
    1055          80 :         return mxf_read_strong_ref_array(pb, &descriptor->sub_descriptors_refs,
    1056             :                                              &descriptor->sub_descriptors_count);
    1057          10 :     case 0x3002: /* ContainerDuration */
    1058          10 :         descriptor->duration = avio_rb64(pb);
    1059          10 :         break;
    1060         259 :     case 0x3004:
    1061         259 :         avio_read(pb, descriptor->essence_container_ul, 16);
    1062         259 :         break;
    1063           0 :     case 0x3005:
    1064           0 :         avio_read(pb, descriptor->codec_ul, 16);
    1065           0 :         break;
    1066         173 :     case 0x3006:
    1067         173 :         descriptor->linked_track_id = avio_rb32(pb);
    1068         173 :         break;
    1069          86 :     case 0x3201: /* PictureEssenceCoding */
    1070          86 :         avio_read(pb, descriptor->essence_codec_ul, 16);
    1071          86 :         break;
    1072          87 :     case 0x3203:
    1073          87 :         descriptor->width = avio_rb32(pb);
    1074          87 :         break;
    1075          87 :     case 0x3202:
    1076          87 :         descriptor->height = avio_rb32(pb);
    1077          87 :         break;
    1078          87 :     case 0x320C:
    1079          87 :         descriptor->frame_layout = avio_r8(pb);
    1080          87 :         break;
    1081          86 :     case 0x320D:
    1082          86 :         entry_count = avio_rb32(pb);
    1083          86 :         entry_size = avio_rb32(pb);
    1084          86 :         if (entry_size == 4) {
    1085          86 :             if (entry_count > 0)
    1086          86 :                 descriptor->video_line_map[0] = avio_rb32(pb);
    1087             :             else
    1088           0 :                 descriptor->video_line_map[0] = 0;
    1089          86 :             if (entry_count > 1)
    1090          83 :                 descriptor->video_line_map[1] = avio_rb32(pb);
    1091             :             else
    1092           3 :                 descriptor->video_line_map[1] = 0;
    1093             :         } else
    1094           0 :             av_log(NULL, AV_LOG_WARNING, "VideoLineMap element size %d currently not supported\n", entry_size);
    1095          86 :         break;
    1096          87 :     case 0x320E:
    1097          87 :         descriptor->aspect_ratio.num = avio_rb32(pb);
    1098          87 :         descriptor->aspect_ratio.den = avio_rb32(pb);
    1099          87 :         break;
    1100          38 :     case 0x3212:
    1101          38 :         descriptor->field_dominance = avio_r8(pb);
    1102          38 :         break;
    1103          85 :     case 0x3301:
    1104          85 :         descriptor->component_depth = avio_rb32(pb);
    1105          85 :         break;
    1106          85 :     case 0x3302:
    1107          85 :         descriptor->horiz_subsampling = avio_rb32(pb);
    1108          85 :         break;
    1109          84 :     case 0x3308:
    1110          84 :         descriptor->vert_subsampling = avio_rb32(pb);
    1111          84 :         break;
    1112          91 :     case 0x3D03:
    1113          91 :         descriptor->sample_rate.num = avio_rb32(pb);
    1114          91 :         descriptor->sample_rate.den = avio_rb32(pb);
    1115          91 :         break;
    1116           8 :     case 0x3D06: /* SoundEssenceCompression */
    1117           8 :         avio_read(pb, descriptor->essence_codec_ul, 16);
    1118           8 :         break;
    1119          91 :     case 0x3D07:
    1120          91 :         descriptor->channels = avio_rb32(pb);
    1121          91 :         break;
    1122          91 :     case 0x3D01:
    1123          91 :         descriptor->bits_per_sample = avio_rb32(pb);
    1124          91 :         break;
    1125           1 :     case 0x3401:
    1126           1 :         mxf_read_pixel_layout(pb, descriptor);
    1127           1 :         break;
    1128        1706 :     default:
    1129             :         /* Private uid used by SONY C0023S01.mxf */
    1130        1706 :         if (IS_KLV_KEY(uid, mxf_sony_mpeg4_extradata)) {
    1131           1 :             if (descriptor->extradata)
    1132           0 :                 av_log(NULL, AV_LOG_WARNING, "Duplicate sony_mpeg4_extradata\n");
    1133           1 :             av_free(descriptor->extradata);
    1134           1 :             descriptor->extradata_size = 0;
    1135           1 :             descriptor->extradata = av_malloc(size);
    1136           1 :             if (!descriptor->extradata)
    1137           0 :                 return AVERROR(ENOMEM);
    1138           1 :             descriptor->extradata_size = size;
    1139           1 :             avio_read(pb, descriptor->extradata, size);
    1140             :         }
    1141        1706 :         if (IS_KLV_KEY(uid, mxf_jp2k_rsiz)) {
    1142           0 :             uint32_t rsiz = avio_rb16(pb);
    1143           0 :             if (rsiz == FF_PROFILE_JPEG2000_DCINEMA_2K ||
    1144             :                 rsiz == FF_PROFILE_JPEG2000_DCINEMA_4K)
    1145           0 :                 descriptor->pix_fmt = AV_PIX_FMT_XYZ12;
    1146             :         }
    1147        1706 :         break;
    1148             :     }
    1149        3242 :     return 0;
    1150             : }
    1151             : 
    1152          87 : static int mxf_read_indirect_value(void *arg, AVIOContext *pb, int size)
    1153             : {
    1154          87 :     MXFTaggedValue *tagged_value = arg;
    1155             :     uint8_t key[17];
    1156             : 
    1157          87 :     if (size <= 17)
    1158           0 :         return 0;
    1159             : 
    1160          87 :     avio_read(pb, key, 17);
    1161             :     /* TODO: handle other types of of indirect values */
    1162          87 :     if (memcmp(key, mxf_indirect_value_utf16le, 17) == 0) {
    1163          30 :         return mxf_read_utf16le_string(pb, size - 17, &tagged_value->value);
    1164          57 :     } else if (memcmp(key, mxf_indirect_value_utf16be, 17) == 0) {
    1165           0 :         return mxf_read_utf16be_string(pb, size - 17, &tagged_value->value);
    1166             :     }
    1167          57 :     return 0;
    1168             : }
    1169             : 
    1170         193 : static int mxf_read_tagged_value(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
    1171             : {
    1172         193 :     MXFTaggedValue *tagged_value = arg;
    1173         193 :     switch (tag){
    1174          87 :     case 0x5001:
    1175          87 :         return mxf_read_utf16be_string(pb, size, &tagged_value->name);
    1176          87 :     case 0x5003:
    1177          87 :         return mxf_read_indirect_value(tagged_value, pb, size);
    1178             :     }
    1179          19 :     return 0;
    1180             : }
    1181             : 
    1182             : /*
    1183             :  * Match an uid independently of the version byte and up to len common bytes
    1184             :  * Returns: boolean
    1185             :  */
    1186        7626 : static int mxf_match_uid(const UID key, const UID uid, int len)
    1187             : {
    1188             :     int i;
    1189       27770 :     for (i = 0; i < len; i++) {
    1190       27284 :         if (i != 7 && key[i] != uid[i])
    1191        7140 :             return 0;
    1192             :     }
    1193         486 :     return 1;
    1194             : }
    1195             : 
    1196         778 : static const MXFCodecUL *mxf_get_codec_ul(const MXFCodecUL *uls, UID *uid)
    1197             : {
    1198        8696 :     while (uls->uid[0]) {
    1199        7626 :         if(mxf_match_uid(uls->uid, *uid, uls->matching_len))
    1200         486 :             break;
    1201        7140 :         uls++;
    1202             :     }
    1203         778 :     return uls;
    1204             : }
    1205             : 
    1206        3852 : static void *mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMetadataSetType type)
    1207             : {
    1208             :     int i;
    1209             : 
    1210        3852 :     if (!strong_ref)
    1211           0 :         return NULL;
    1212       66196 :     for (i = 0; i < mxf->metadata_sets_count; i++) {
    1213       65341 :         if (!memcmp(*strong_ref, mxf->metadata_sets[i]->uid, 16) &&
    1214        3273 :             (type == AnyType || mxf->metadata_sets[i]->type == type)) {
    1215        2997 :             return mxf->metadata_sets[i];
    1216             :         }
    1217             :     }
    1218         855 :     return NULL;
    1219             : }
    1220             : 
    1221             : static const MXFCodecUL mxf_picture_essence_container_uls[] = {
    1222             :     // video essence container uls
    1223             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0c,0x01,0x00 }, 14,   AV_CODEC_ID_JPEG2000 },
    1224             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x10,0x60,0x01 }, 14,       AV_CODEC_ID_H264 }, /* H.264 frame wrapped */
    1225             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x12,0x01,0x00 }, 14,        AV_CODEC_ID_VC1 }, /* VC-1 frame wrapped */
    1226             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* MPEG-ES frame wrapped */
    1227             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x04,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* Type D-10 mapping of 40Mbps 525/60-I */
    1228             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14,    AV_CODEC_ID_DVVIDEO }, /* DV 625 25mbps */
    1229             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x05,0x00,0x00 }, 14,   AV_CODEC_ID_RAWVIDEO }, /* uncompressed picture */
    1230             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0a,0x0e,0x0f,0x03,0x01,0x02,0x20,0x01,0x01 }, 15,     AV_CODEC_ID_HQ_HQA },
    1231             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0a,0x0e,0x0f,0x03,0x01,0x02,0x20,0x02,0x01 }, 15,        AV_CODEC_ID_HQX },
    1232             :     { { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0xff,0x4b,0x46,0x41,0x41,0x00,0x0d,0x4d,0x4f }, 14,   AV_CODEC_ID_RAWVIDEO }, /* Legacy ?? Uncompressed Picture */
    1233             :     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,      AV_CODEC_ID_NONE },
    1234             : };
    1235             : 
    1236             : /* EC ULs for intra-only formats */
    1237             : static const MXFCodecUL mxf_intra_only_essence_container_uls[] = {
    1238             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x00,0x00 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* MXF-GC SMPTE D-10 mappings */
    1239             :     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,       AV_CODEC_ID_NONE },
    1240             : };
    1241             : 
    1242             : /* intra-only PictureEssenceCoding ULs, where no corresponding EC UL exists */
    1243             : static const MXFCodecUL mxf_intra_only_picture_essence_coding_uls[] = {
    1244             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x00,0x00 }, 14,       AV_CODEC_ID_H264 }, /* H.264/MPEG-4 AVC Intra Profiles */
    1245             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14,   AV_CODEC_ID_JPEG2000 }, /* JPEG 2000 code stream */
    1246             :     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,       AV_CODEC_ID_NONE },
    1247             : };
    1248             : 
    1249             : /* actual coded width for AVC-Intra to allow selecting correct SPS/PPS */
    1250             : static const MXFCodecUL mxf_intra_only_picture_coded_width[] = {
    1251             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x01 }, 16, 1440 },
    1252             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x02 }, 16, 1440 },
    1253             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x03 }, 16, 1440 },
    1254             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x04 }, 16, 1440 },
    1255             :     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,    0 },
    1256             : };
    1257             : 
    1258             : static const MXFCodecUL mxf_sound_essence_container_uls[] = {
    1259             :     // sound essence container uls
    1260             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, 14, AV_CODEC_ID_PCM_S16LE }, /* BWF Frame wrapped */
    1261             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x40,0x01 }, 14,       AV_CODEC_ID_MP2 }, /* MPEG-ES Frame wrapped, 0x40 ??? stream id */
    1262             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, 14, AV_CODEC_ID_PCM_S16LE }, /* D-10 Mapping 50Mbps PAL Extended Template */
    1263             :     { { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0xff,0x4b,0x46,0x41,0x41,0x00,0x0d,0x4d,0x4F }, 14, AV_CODEC_ID_PCM_S16LE }, /* 0001GL00.MXF.A1.mxf_opatom.mxf */
    1264             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x03,0x04,0x02,0x02,0x02,0x03,0x03,0x01,0x00 }, 14,       AV_CODEC_ID_AAC }, /* MPEG-2 AAC ADTS (legacy) */
    1265             :     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,      AV_CODEC_ID_NONE },
    1266             : };
    1267             : 
    1268             : static const MXFCodecUL mxf_data_essence_container_uls[] = {
    1269             :     { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x0e,0x00,0x00 }, 16, 0 },
    1270             :     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0, AV_CODEC_ID_NONE },
    1271             : };
    1272             : 
    1273             : static const char * const mxf_data_essence_descriptor[] = {
    1274             :     "vbi_vanc_smpte_436M",
    1275             : };
    1276             : 
    1277          91 : static int mxf_get_sorted_table_segments(MXFContext *mxf, int *nb_sorted_segments, MXFIndexTableSegment ***sorted_segments)
    1278             : {
    1279          91 :     int i, j, nb_segments = 0;
    1280             :     MXFIndexTableSegment **unsorted_segments;
    1281          91 :     int last_body_sid = -1, last_index_sid = -1, last_index_start = -1;
    1282             : 
    1283             :     /* count number of segments, allocate arrays and copy unsorted segments */
    1284        2474 :     for (i = 0; i < mxf->metadata_sets_count; i++)
    1285        2383 :         if (mxf->metadata_sets[i]->type == IndexTableSegment)
    1286          92 :             nb_segments++;
    1287             : 
    1288          91 :     if (!nb_segments)
    1289           0 :         return AVERROR_INVALIDDATA;
    1290             : 
    1291         182 :     if (!(unsorted_segments = av_calloc(nb_segments, sizeof(*unsorted_segments))) ||
    1292          91 :         !(*sorted_segments  = av_calloc(nb_segments, sizeof(**sorted_segments)))) {
    1293           0 :         av_freep(sorted_segments);
    1294           0 :         av_free(unsorted_segments);
    1295           0 :         return AVERROR(ENOMEM);
    1296             :     }
    1297             : 
    1298        2474 :     for (i = j = 0; i < mxf->metadata_sets_count; i++)
    1299        2383 :         if (mxf->metadata_sets[i]->type == IndexTableSegment)
    1300          92 :             unsorted_segments[j++] = (MXFIndexTableSegment*)mxf->metadata_sets[i];
    1301             : 
    1302          91 :     *nb_sorted_segments = 0;
    1303             : 
    1304             :     /* sort segments by {BodySID, IndexSID, IndexStartPosition}, remove duplicates while we're at it */
    1305         183 :     for (i = 0; i < nb_segments; i++) {
    1306          92 :         int best = -1, best_body_sid = -1, best_index_sid = -1, best_index_start = -1;
    1307          92 :         uint64_t best_index_duration = 0;
    1308             : 
    1309         186 :         for (j = 0; j < nb_segments; j++) {
    1310          94 :             MXFIndexTableSegment *s = unsorted_segments[j];
    1311             : 
    1312             :             /* Require larger BosySID, IndexSID or IndexStartPosition then the previous entry. This removes duplicates.
    1313             :              * We want the smallest values for the keys than what we currently have, unless this is the first such entry this time around.
    1314             :              * If we come across an entry with the same IndexStartPosition but larger IndexDuration, then we'll prefer it over the one we currently have.
    1315             :              */
    1316          96 :             if ((i == 0 ||
    1317           4 :                  s->body_sid >  last_body_sid ||
    1318           6 :                  s->body_sid == last_body_sid && s->index_sid >  last_index_sid ||
    1319           4 :                  s->body_sid == last_body_sid && s->index_sid == last_index_sid && s->index_start_position > last_index_start) &&
    1320           1 :                 (best == -1 ||
    1321           2 :                  s->body_sid <  best_body_sid ||
    1322           3 :                  s->body_sid == best_body_sid && s->index_sid <  best_index_sid ||
    1323           3 :                  s->body_sid == best_body_sid && s->index_sid == best_index_sid && s->index_start_position <  best_index_start ||
    1324           2 :                  s->body_sid == best_body_sid && s->index_sid == best_index_sid && s->index_start_position == best_index_start && s->index_duration > best_index_duration)) {
    1325          92 :                 best             = j;
    1326          92 :                 best_body_sid    = s->body_sid;
    1327          92 :                 best_index_sid   = s->index_sid;
    1328          92 :                 best_index_start = s->index_start_position;
    1329          92 :                 best_index_duration = s->index_duration;
    1330             :             }
    1331             :         }
    1332             : 
    1333             :         /* no suitable entry found -> we're done */
    1334          92 :         if (best == -1)
    1335           0 :             break;
    1336             : 
    1337          92 :         (*sorted_segments)[(*nb_sorted_segments)++] = unsorted_segments[best];
    1338          92 :         last_body_sid    = best_body_sid;
    1339          92 :         last_index_sid   = best_index_sid;
    1340          92 :         last_index_start = best_index_start;
    1341             :     }
    1342             : 
    1343          91 :     av_free(unsorted_segments);
    1344             : 
    1345          91 :     return 0;
    1346             : }
    1347             : 
    1348             : /**
    1349             :  * Computes the absolute file offset of the given essence container offset
    1350             :  */
    1351        7876 : static int mxf_absolute_bodysid_offset(MXFContext *mxf, int body_sid, int64_t offset, int64_t *offset_out)
    1352             : {
    1353        7876 :     MXFPartition *last_p = NULL;
    1354             :     int a, b, m, m0;
    1355             : 
    1356        7876 :     if (offset < 0)
    1357           0 :         return AVERROR(EINVAL);
    1358             : 
    1359        7876 :     a = -1;
    1360        7876 :     b = mxf->partitions_count;
    1361             : 
    1362       31439 :     while (b - a > 1) {
    1363       15687 :         m0 = m = (a + b) >> 1;
    1364             : 
    1365       39185 :         while (m < b && mxf->partitions[m].body_sid != body_sid)
    1366        7811 :             m++;
    1367             : 
    1368       15687 :         if (m < b && mxf->partitions[m].body_offset <= offset)
    1369        7876 :             a = m;
    1370             :         else
    1371        7811 :             b = m0;
    1372             :     }
    1373             : 
    1374        7876 :     if (a >= 0)
    1375        7876 :         last_p = &mxf->partitions[a];
    1376             : 
    1377        7876 :     if (last_p && (!last_p->essence_length || last_p->essence_length > (offset - last_p->body_offset))) {
    1378        7872 :         *offset_out = last_p->essence_offset + (offset - last_p->body_offset);
    1379        7872 :         return 0;
    1380             :     }
    1381             : 
    1382           4 :     av_log(mxf->fc, AV_LOG_ERROR,
    1383             :            "failed to find absolute offset of %"PRIX64" in BodySID %i - partial file?\n",
    1384             :            offset, body_sid);
    1385             : 
    1386           4 :     return AVERROR_INVALIDDATA;
    1387             : }
    1388             : 
    1389             : /**
    1390             :  * Returns the end position of the essence container with given BodySID, or zero if unknown
    1391             :  */
    1392          32 : static int64_t mxf_essence_container_end(MXFContext *mxf, int body_sid)
    1393             : {
    1394             :     int x;
    1395          32 :     int64_t ret = 0;
    1396             : 
    1397         128 :     for (x = 0; x < mxf->partitions_count; x++) {
    1398          96 :         MXFPartition *p = &mxf->partitions[x];
    1399             : 
    1400          96 :         if (p->body_sid != body_sid)
    1401          64 :             continue;
    1402             : 
    1403          32 :         if (!p->essence_length)
    1404           0 :             return 0;
    1405             : 
    1406          32 :         ret = p->essence_offset + p->essence_length;
    1407             :     }
    1408             : 
    1409          32 :     return ret;
    1410             : }
    1411             : 
    1412             : /* EditUnit -> absolute offset */
    1413        8117 : static int mxf_edit_unit_absolute_offset(MXFContext *mxf, MXFIndexTable *index_table, int64_t edit_unit, int64_t *edit_unit_out, int64_t *offset_out, int nag)
    1414             : {
    1415             :     int i;
    1416        8117 :     int64_t offset_temp = 0;
    1417             : 
    1418        8358 :     for (i = 0; i < index_table->nb_segments; i++) {
    1419        8117 :         MXFIndexTableSegment *s = index_table->segments[i];
    1420             : 
    1421        8117 :         edit_unit = FFMAX(edit_unit, s->index_start_position);  /* clamp if trying to seek before start */
    1422             : 
    1423        8117 :         if (edit_unit < s->index_start_position + s->index_duration) {
    1424        7876 :             int64_t index = edit_unit - s->index_start_position;
    1425             : 
    1426        7876 :             if (s->edit_unit_byte_count)
    1427        3842 :                 offset_temp += s->edit_unit_byte_count * index;
    1428        4034 :             else if (s->nb_index_entries) {
    1429        4034 :                 if (s->nb_index_entries == 2 * s->index_duration + 1)
    1430           0 :                     index *= 2;     /* Avid index */
    1431             : 
    1432        4034 :                 if (index < 0 || index >= s->nb_index_entries) {
    1433           0 :                     av_log(mxf->fc, AV_LOG_ERROR, "IndexSID %i segment at %"PRId64" IndexEntryArray too small\n",
    1434             :                            index_table->index_sid, s->index_start_position);
    1435           0 :                     return AVERROR_INVALIDDATA;
    1436             :                 }
    1437             : 
    1438        4034 :                 offset_temp = s->stream_offset_entries[index];
    1439             :             } else {
    1440           0 :                 av_log(mxf->fc, AV_LOG_ERROR, "IndexSID %i segment at %"PRId64" missing EditUnitByteCount and IndexEntryArray\n",
    1441             :                        index_table->index_sid, s->index_start_position);
    1442           0 :                 return AVERROR_INVALIDDATA;
    1443             :             }
    1444             : 
    1445        7876 :             if (edit_unit_out)
    1446         207 :                 *edit_unit_out = edit_unit;
    1447             : 
    1448        7876 :             return mxf_absolute_bodysid_offset(mxf, index_table->body_sid, offset_temp, offset_out);
    1449             :         } else {
    1450             :             /* EditUnitByteCount == 0 for VBR indexes, which is fine since they use explicit StreamOffsets */
    1451         241 :             offset_temp += s->edit_unit_byte_count * s->index_duration;
    1452             :         }
    1453             :     }
    1454             : 
    1455         241 :     if (nag)
    1456           0 :         av_log(mxf->fc, AV_LOG_ERROR, "failed to map EditUnit %"PRId64" in IndexSID %i to an offset\n", edit_unit, index_table->index_sid);
    1457             : 
    1458         241 :     return AVERROR_INVALIDDATA;
    1459             : }
    1460             : 
    1461          91 : static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_table)
    1462             : {
    1463             :     int i, j, x;
    1464          91 :     int8_t max_temporal_offset = -128;
    1465             :     uint8_t *flags;
    1466             : 
    1467             :     /* first compute how many entries we have */
    1468         134 :     for (i = 0; i < index_table->nb_segments; i++) {
    1469          92 :         MXFIndexTableSegment *s = index_table->segments[i];
    1470             : 
    1471          92 :         if (!s->nb_index_entries) {
    1472          49 :             index_table->nb_ptses = 0;
    1473          49 :             return 0;                               /* no TemporalOffsets */
    1474             :         }
    1475             : 
    1476          43 :         index_table->nb_ptses += s->index_duration;
    1477             :     }
    1478             : 
    1479             :     /* paranoid check */
    1480          42 :     if (index_table->nb_ptses <= 0)
    1481           0 :         return 0;
    1482             : 
    1483          84 :     if (!(index_table->ptses      = av_calloc(index_table->nb_ptses, sizeof(int64_t))) ||
    1484          84 :         !(index_table->fake_index = av_calloc(index_table->nb_ptses, sizeof(AVIndexEntry))) ||
    1485          84 :         !(index_table->offsets    = av_calloc(index_table->nb_ptses, sizeof(int8_t))) ||
    1486          42 :         !(flags                   = av_calloc(index_table->nb_ptses, sizeof(uint8_t)))) {
    1487           0 :         av_freep(&index_table->ptses);
    1488           0 :         av_freep(&index_table->fake_index);
    1489           0 :         av_freep(&index_table->offsets);
    1490           0 :         return AVERROR(ENOMEM);
    1491             :     }
    1492             : 
    1493             :     /* we may have a few bad TemporalOffsets
    1494             :      * make sure the corresponding PTSes don't have the bogus value 0 */
    1495        1328 :     for (x = 0; x < index_table->nb_ptses; x++)
    1496        1286 :         index_table->ptses[x] = AV_NOPTS_VALUE;
    1497             : 
    1498             :     /**
    1499             :      * We have this:
    1500             :      *
    1501             :      * x  TemporalOffset
    1502             :      * 0:  0
    1503             :      * 1:  1
    1504             :      * 2:  1
    1505             :      * 3: -2
    1506             :      * 4:  1
    1507             :      * 5:  1
    1508             :      * 6: -2
    1509             :      *
    1510             :      * We want to transform it into this:
    1511             :      *
    1512             :      * x  DTS PTS
    1513             :      * 0: -1   0
    1514             :      * 1:  0   3
    1515             :      * 2:  1   1
    1516             :      * 3:  2   2
    1517             :      * 4:  3   6
    1518             :      * 5:  4   4
    1519             :      * 6:  5   5
    1520             :      *
    1521             :      * We do this by bucket sorting x by x+TemporalOffset[x] into mxf->ptses,
    1522             :      * then settings mxf->first_dts = -max(TemporalOffset[x]).
    1523             :      * The latter makes DTS <= PTS.
    1524             :      */
    1525          85 :     for (i = x = 0; i < index_table->nb_segments; i++) {
    1526          43 :         MXFIndexTableSegment *s = index_table->segments[i];
    1527          43 :         int index_delta = 1;
    1528          43 :         int n = s->nb_index_entries;
    1529             : 
    1530          43 :         if (s->nb_index_entries == 2 * s->index_duration + 1) {
    1531           0 :             index_delta = 2;    /* Avid index */
    1532             :             /* ignore the last entry - it's the size of the essence container */
    1533           0 :             n--;
    1534             :         }
    1535             : 
    1536        1329 :         for (j = 0; j < n; j += index_delta, x++) {
    1537        1286 :             int offset = s->temporal_offset_entries[j] / index_delta;
    1538        1286 :             int index  = x + offset;
    1539             : 
    1540        1286 :             if (x >= index_table->nb_ptses) {
    1541           0 :                 av_log(mxf->fc, AV_LOG_ERROR,
    1542             :                        "x >= nb_ptses - IndexEntryCount %i < IndexDuration %"PRId64"?\n",
    1543             :                        s->nb_index_entries, s->index_duration);
    1544           0 :                 break;
    1545             :             }
    1546             : 
    1547        1286 :             flags[x] = !(s->flag_entries[j] & 0x30) ? AVINDEX_KEYFRAME : 0;
    1548             : 
    1549        1286 :             if (index < 0 || index >= index_table->nb_ptses) {
    1550           0 :                 av_log(mxf->fc, AV_LOG_ERROR,
    1551             :                        "index entry %i + TemporalOffset %i = %i, which is out of bounds\n",
    1552             :                        x, offset, index);
    1553           0 :                 continue;
    1554             :             }
    1555             : 
    1556        1286 :             index_table->offsets[x] = offset;
    1557        1286 :             index_table->ptses[index] = x;
    1558        1286 :             max_temporal_offset = FFMAX(max_temporal_offset, offset);
    1559             :         }
    1560             :     }
    1561             : 
    1562             :     /* calculate the fake index table in display order */
    1563        1328 :     for (x = 0; x < index_table->nb_ptses; x++) {
    1564        1286 :         index_table->fake_index[x].timestamp = x;
    1565        1286 :         if (index_table->ptses[x] != AV_NOPTS_VALUE)
    1566        1286 :             index_table->fake_index[index_table->ptses[x]].flags = flags[x];
    1567             :     }
    1568          42 :     av_freep(&flags);
    1569             : 
    1570          42 :     index_table->first_dts = -max_temporal_offset;
    1571             : 
    1572          42 :     return 0;
    1573             : }
    1574             : 
    1575             : /**
    1576             :  * Sorts and collects index table segments into index tables.
    1577             :  * Also computes PTSes if possible.
    1578             :  */
    1579          91 : static int mxf_compute_index_tables(MXFContext *mxf)
    1580             : {
    1581             :     int i, j, k, ret, nb_sorted_segments;
    1582          91 :     MXFIndexTableSegment **sorted_segments = NULL;
    1583             : 
    1584         182 :     if ((ret = mxf_get_sorted_table_segments(mxf, &nb_sorted_segments, &sorted_segments)) ||
    1585          91 :         nb_sorted_segments <= 0) {
    1586           0 :         av_log(mxf->fc, AV_LOG_WARNING, "broken or empty index\n");
    1587           0 :         return 0;
    1588             :     }
    1589             : 
    1590             :     /* sanity check and count unique BodySIDs/IndexSIDs */
    1591         183 :     for (i = 0; i < nb_sorted_segments; i++) {
    1592          92 :         if (i == 0 || sorted_segments[i-1]->index_sid != sorted_segments[i]->index_sid)
    1593          91 :             mxf->nb_index_tables++;
    1594           1 :         else if (sorted_segments[i-1]->body_sid != sorted_segments[i]->body_sid) {
    1595           0 :             av_log(mxf->fc, AV_LOG_ERROR, "found inconsistent BodySID\n");
    1596           0 :             ret = AVERROR_INVALIDDATA;
    1597           0 :             goto finish_decoding_index;
    1598             :         }
    1599             :     }
    1600             : 
    1601          91 :     mxf->index_tables = av_mallocz_array(mxf->nb_index_tables,
    1602             :                                          sizeof(*mxf->index_tables));
    1603          91 :     if (!mxf->index_tables) {
    1604           0 :         av_log(mxf->fc, AV_LOG_ERROR, "failed to allocate index tables\n");
    1605           0 :         ret = AVERROR(ENOMEM);
    1606           0 :         goto finish_decoding_index;
    1607             :     }
    1608             : 
    1609             :     /* distribute sorted segments to index tables */
    1610         183 :     for (i = j = 0; i < nb_sorted_segments; i++) {
    1611          92 :         if (i != 0 && sorted_segments[i-1]->index_sid != sorted_segments[i]->index_sid) {
    1612             :             /* next IndexSID */
    1613           0 :             j++;
    1614             :         }
    1615             : 
    1616          92 :         mxf->index_tables[j].nb_segments++;
    1617             :     }
    1618             : 
    1619         182 :     for (i = j = 0; j < mxf->nb_index_tables; i += mxf->index_tables[j++].nb_segments) {
    1620          91 :         MXFIndexTable *t = &mxf->index_tables[j];
    1621          91 :         MXFTrack *mxf_track = NULL;
    1622             : 
    1623          91 :         t->segments = av_mallocz_array(t->nb_segments,
    1624             :                                        sizeof(*t->segments));
    1625             : 
    1626          91 :         if (!t->segments) {
    1627           0 :             av_log(mxf->fc, AV_LOG_ERROR, "failed to allocate IndexTableSegment"
    1628             :                    " pointer array\n");
    1629           0 :             ret = AVERROR(ENOMEM);
    1630           0 :             goto finish_decoding_index;
    1631             :         }
    1632             : 
    1633          91 :         if (sorted_segments[i]->index_start_position)
    1634           0 :             av_log(mxf->fc, AV_LOG_WARNING, "IndexSID %i starts at EditUnit %"PRId64" - seeking may not work as expected\n",
    1635           0 :                    sorted_segments[i]->index_sid, sorted_segments[i]->index_start_position);
    1636             : 
    1637          91 :         memcpy(t->segments, &sorted_segments[i], t->nb_segments * sizeof(MXFIndexTableSegment*));
    1638          91 :         t->index_sid = sorted_segments[i]->index_sid;
    1639          91 :         t->body_sid = sorted_segments[i]->body_sid;
    1640             : 
    1641          91 :         if ((ret = mxf_compute_ptses_fake_index(mxf, t)) < 0)
    1642           0 :             goto finish_decoding_index;
    1643             : 
    1644         100 :         for (k = 0; k < mxf->fc->nb_streams; k++) {
    1645         100 :             MXFTrack *track = mxf->fc->streams[k]->priv_data;
    1646         100 :             if (track && track->index_sid == t->index_sid) {
    1647          91 :                 mxf_track = track;
    1648          91 :                 break;
    1649             :             }
    1650             :         }
    1651             : 
    1652             :         /* fix zero IndexDurations */
    1653         274 :         for (k = 0; k < t->nb_segments; k++) {
    1654          92 :             if (t->segments[k]->index_duration)
    1655          46 :                 continue;
    1656             : 
    1657          46 :             if (t->nb_segments > 1)
    1658           0 :                 av_log(mxf->fc, AV_LOG_WARNING, "IndexSID %i segment %i has zero IndexDuration and there's more than one segment\n",
    1659             :                        t->index_sid, k);
    1660             : 
    1661          46 :             if (!mxf_track) {
    1662           0 :                 av_log(mxf->fc, AV_LOG_WARNING, "no streams?\n");
    1663           0 :                 break;
    1664             :             }
    1665             : 
    1666             :             /* assume the first stream's duration is reasonable
    1667             :              * leave index_duration = 0 on further segments in case we have any (unlikely)
    1668             :              */
    1669          46 :             t->segments[k]->index_duration = mxf_track->original_duration;
    1670          46 :             break;
    1671             :         }
    1672             :     }
    1673             : 
    1674          91 :     ret = 0;
    1675          91 : finish_decoding_index:
    1676          91 :     av_free(sorted_segments);
    1677          91 :     return ret;
    1678             : }
    1679             : 
    1680          87 : static int mxf_is_intra_only(MXFDescriptor *descriptor)
    1681             : {
    1682          87 :     return mxf_get_codec_ul(mxf_intra_only_essence_container_uls,
    1683         138 :                             &descriptor->essence_container_ul)->id != AV_CODEC_ID_NONE ||
    1684          51 :            mxf_get_codec_ul(mxf_intra_only_picture_essence_coding_uls,
    1685          51 :                             &descriptor->essence_codec_ul)->id     != AV_CODEC_ID_NONE;
    1686             : }
    1687             : 
    1688         273 : static int mxf_uid_to_str(UID uid, char **str)
    1689             : {
    1690             :     int i;
    1691             :     char *p;
    1692         273 :     p = *str = av_mallocz(sizeof(UID) * 2 + 4 + 1);
    1693         273 :     if (!p)
    1694           0 :         return AVERROR(ENOMEM);
    1695        4641 :     for (i = 0; i < sizeof(UID); i++) {
    1696        4368 :         snprintf(p, 2 + 1, "%.2x", uid[i]);
    1697        4368 :         p += 2;
    1698        4368 :         if (i == 3 || i == 5 || i == 7 || i == 9) {
    1699        1092 :             snprintf(p, 1 + 1, "-");
    1700        1092 :             p++;
    1701             :         }
    1702             :     }
    1703         273 :     return 0;
    1704             : }
    1705             : 
    1706         288 : static int mxf_umid_to_str(UID ul, UID uid, char **str)
    1707             : {
    1708             :     int i;
    1709             :     char *p;
    1710         288 :     p = *str = av_mallocz(sizeof(UID) * 4 + 2 + 1);
    1711         288 :     if (!p)
    1712           0 :         return AVERROR(ENOMEM);
    1713         288 :     snprintf(p, 2 + 1, "0x");
    1714         288 :     p += 2;
    1715        4896 :     for (i = 0; i < sizeof(UID); i++) {
    1716        4608 :         snprintf(p, 2 + 1, "%.2X", ul[i]);
    1717        4608 :         p += 2;
    1718             : 
    1719             :     }
    1720        4896 :     for (i = 0; i < sizeof(UID); i++) {
    1721        4608 :         snprintf(p, 2 + 1, "%.2X", uid[i]);
    1722        4608 :         p += 2;
    1723             :     }
    1724         288 :     return 0;
    1725             : }
    1726             : 
    1727         288 : static int mxf_add_umid_metadata(AVDictionary **pm, const char *key, MXFPackage* package)
    1728             : {
    1729             :     char *str;
    1730             :     int ret;
    1731         288 :     if (!package)
    1732           0 :         return 0;
    1733         288 :     if ((ret = mxf_umid_to_str(package->package_ul, package->package_uid, &str)) < 0)
    1734           0 :         return ret;
    1735         288 :     av_dict_set(pm, key, str, AV_DICT_DONT_STRDUP_VAL);
    1736         288 :     return 0;
    1737             : }
    1738             : 
    1739          91 : static int mxf_add_timecode_metadata(AVDictionary **pm, const char *key, AVTimecode *tc)
    1740             : {
    1741             :     char buf[AV_TIMECODE_STR_SIZE];
    1742          91 :     av_dict_set(pm, key, av_timecode_make_string(tc, buf, 0), 0);
    1743             : 
    1744          91 :     return 0;
    1745             : }
    1746             : 
    1747          12 : static MXFTimecodeComponent* mxf_resolve_timecode_component(MXFContext *mxf, UID *strong_ref)
    1748             : {
    1749          12 :     MXFStructuralComponent *component = NULL;
    1750          12 :     MXFPulldownComponent *pulldown = NULL;
    1751             : 
    1752          12 :     component = mxf_resolve_strong_ref(mxf, strong_ref, AnyType);
    1753          12 :     if (!component)
    1754           0 :         return NULL;
    1755             : 
    1756          12 :     switch (component->type) {
    1757           5 :     case TimecodeComponent:
    1758           5 :         return (MXFTimecodeComponent*)component;
    1759           1 :     case PulldownComponent: /* timcode component may be located on a pulldown component */
    1760           1 :         pulldown = (MXFPulldownComponent*)component;
    1761           1 :         return mxf_resolve_strong_ref(mxf, &pulldown->input_segment_ref, TimecodeComponent);
    1762           6 :     default:
    1763           6 :         break;
    1764             :     }
    1765           6 :     return NULL;
    1766             : }
    1767             : 
    1768         374 : static MXFPackage* mxf_resolve_source_package(MXFContext *mxf, UID package_ul, UID package_uid)
    1769             : {
    1770         374 :     MXFPackage *package = NULL;
    1771             :     int i;
    1772             : 
    1773         955 :     for (i = 0; i < mxf->packages_count; i++) {
    1774         767 :         package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], SourcePackage);
    1775         767 :         if (!package)
    1776         372 :             continue;
    1777             : 
    1778         395 :         if (!memcmp(package->package_ul, package_ul, 16) && !memcmp(package->package_uid, package_uid, 16))
    1779         186 :             return package;
    1780             :     }
    1781         188 :     return NULL;
    1782             : }
    1783             : 
    1784         179 : static MXFDescriptor* mxf_resolve_multidescriptor(MXFContext *mxf, MXFDescriptor *descriptor, int track_id)
    1785             : {
    1786         179 :     MXFDescriptor *sub_descriptor = NULL;
    1787             :     int i;
    1788             : 
    1789         179 :     if (!descriptor)
    1790           0 :         return NULL;
    1791             : 
    1792         179 :     if (descriptor->type == MultipleDescriptor) {
    1793         273 :         for (i = 0; i < descriptor->sub_descriptors_count; i++) {
    1794         273 :             sub_descriptor = mxf_resolve_strong_ref(mxf, &descriptor->sub_descriptors_refs[i], Descriptor);
    1795             : 
    1796         273 :             if (!sub_descriptor) {
    1797           0 :                 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve sub descriptor strong ref\n");
    1798           0 :                 continue;
    1799             :             }
    1800         273 :             if (sub_descriptor->linked_track_id == track_id) {
    1801         168 :                 return sub_descriptor;
    1802             :             }
    1803             :         }
    1804          11 :     } else if (descriptor->type == Descriptor)
    1805          11 :         return descriptor;
    1806             : 
    1807           0 :     return NULL;
    1808             : }
    1809             : 
    1810           3 : static MXFStructuralComponent* mxf_resolve_essence_group_choice(MXFContext *mxf, MXFEssenceGroup *essence_group)
    1811             : {
    1812           3 :     MXFStructuralComponent *component = NULL;
    1813           3 :     MXFPackage *package = NULL;
    1814           3 :     MXFDescriptor *descriptor = NULL;
    1815             :     int i;
    1816             : 
    1817           3 :     if (!essence_group || !essence_group->structural_components_count)
    1818           0 :         return NULL;
    1819             : 
    1820             :     /* essence groups contains multiple representations of the same media,
    1821             :        this return the first components with a valid Descriptor typically index 0 */
    1822           6 :     for (i =0; i < essence_group->structural_components_count; i++){
    1823           4 :         component = mxf_resolve_strong_ref(mxf, &essence_group->structural_components_refs[i], SourceClip);
    1824           4 :         if (!component)
    1825           0 :             continue;
    1826             : 
    1827           4 :         if (!(package = mxf_resolve_source_package(mxf, component->source_package_ul, component->source_package_uid)))
    1828           3 :             continue;
    1829             : 
    1830           1 :         descriptor = mxf_resolve_strong_ref(mxf, &package->descriptor_ref, Descriptor);
    1831           1 :         if (descriptor)
    1832           1 :             return component;
    1833             :     }
    1834           2 :     return NULL;
    1835             : }
    1836             : 
    1837         380 : static MXFStructuralComponent* mxf_resolve_sourceclip(MXFContext *mxf, UID *strong_ref)
    1838             : {
    1839         380 :     MXFStructuralComponent *component = NULL;
    1840             : 
    1841         380 :     component = mxf_resolve_strong_ref(mxf, strong_ref, AnyType);
    1842         380 :     if (!component)
    1843           5 :         return NULL;
    1844         375 :     switch (component->type) {
    1845         202 :         case SourceClip:
    1846         202 :             return component;
    1847           3 :         case EssenceGroup:
    1848           3 :             return mxf_resolve_essence_group_choice(mxf, (MXFEssenceGroup*) component);
    1849         170 :         default:
    1850         170 :             break;
    1851             :     }
    1852         170 :     return NULL;
    1853             : }
    1854             : 
    1855          91 : static int mxf_parse_package_comments(MXFContext *mxf, AVDictionary **pm, MXFPackage *package)
    1856             : {
    1857             :     MXFTaggedValue *tag;
    1858             :     int size, i;
    1859          91 :     char *key = NULL;
    1860             : 
    1861         100 :     for (i = 0; i < package->comment_count; i++) {
    1862           9 :         tag = mxf_resolve_strong_ref(mxf, &package->comment_refs[i], TaggedValue);
    1863           9 :         if (!tag || !tag->name || !tag->value)
    1864           0 :             continue;
    1865             : 
    1866           9 :         size = strlen(tag->name) + 8 + 1;
    1867           9 :         key = av_mallocz(size);
    1868           9 :         if (!key)
    1869           0 :             return AVERROR(ENOMEM);
    1870             : 
    1871           9 :         snprintf(key, size, "comment_%s", tag->name);
    1872           9 :         av_dict_set(pm, key, tag->value, AV_DICT_DONT_STRDUP_KEY);
    1873             :     }
    1874          91 :     return 0;
    1875             : }
    1876             : 
    1877         179 : static int mxf_parse_physical_source_package(MXFContext *mxf, MXFTrack *source_track, AVStream *st)
    1878             : {
    1879         179 :     MXFPackage *physical_package = NULL;
    1880         179 :     MXFTrack *physical_track = NULL;
    1881         179 :     MXFStructuralComponent *sourceclip = NULL;
    1882         179 :     MXFTimecodeComponent *mxf_tc = NULL;
    1883             :     int i, j, k;
    1884             :     AVTimecode tc;
    1885             :     int flags;
    1886             :     int64_t start_position;
    1887             : 
    1888         179 :     for (i = 0; i < source_track->sequence->structural_components_count; i++) {
    1889         179 :         sourceclip = mxf_resolve_strong_ref(mxf, &source_track->sequence->structural_components_refs[i], SourceClip);
    1890         179 :         if (!sourceclip)
    1891           0 :             continue;
    1892             : 
    1893         179 :         if (!(physical_package = mxf_resolve_source_package(mxf, sourceclip->source_package_ul, sourceclip->source_package_uid)))
    1894         173 :             break;
    1895             : 
    1896           6 :         mxf_add_umid_metadata(&st->metadata, "reel_umid", physical_package);
    1897             : 
    1898             :         /* the name of physical source package is name of the reel or tape */
    1899           6 :         if (physical_package->name && physical_package->name[0])
    1900           6 :             av_dict_set(&st->metadata, "reel_name", physical_package->name, 0);
    1901             : 
    1902             :         /* the source timecode is calculated by adding the start_position of the sourceclip from the file source package track
    1903             :          * to the start_frame of the timecode component located on one of the tracks of the physical source package.
    1904             :          */
    1905          12 :         for (j = 0; j < physical_package->tracks_count; j++) {
    1906          12 :             if (!(physical_track = mxf_resolve_strong_ref(mxf, &physical_package->tracks_refs[j], Track))) {
    1907           0 :                 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n");
    1908           0 :                 continue;
    1909             :             }
    1910             : 
    1911          12 :             if (!(physical_track->sequence = mxf_resolve_strong_ref(mxf, &physical_track->sequence_ref, Sequence))) {
    1912           0 :                 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n");
    1913           0 :                 continue;
    1914             :             }
    1915             : 
    1916          24 :         if (physical_track->edit_rate.num <= 0 ||
    1917          12 :             physical_track->edit_rate.den <= 0) {
    1918           0 :             av_log(mxf->fc, AV_LOG_WARNING,
    1919             :                    "Invalid edit rate (%d/%d) found on structural"
    1920             :                    " component #%d, defaulting to 25/1\n",
    1921             :                    physical_track->edit_rate.num,
    1922             :                    physical_track->edit_rate.den, i);
    1923           0 :             physical_track->edit_rate = (AVRational){25, 1};
    1924             :         }
    1925             : 
    1926          18 :             for (k = 0; k < physical_track->sequence->structural_components_count; k++) {
    1927          12 :                 if (!(mxf_tc = mxf_resolve_timecode_component(mxf, &physical_track->sequence->structural_components_refs[k])))
    1928           6 :                     continue;
    1929             : 
    1930           6 :                 flags = mxf_tc->drop_frame == 1 ? AV_TIMECODE_FLAG_DROPFRAME : 0;
    1931             :                 /* scale sourceclip start_position to match physical track edit rate */
    1932           6 :                 start_position = av_rescale_q(sourceclip->start_position,
    1933             :                                               physical_track->edit_rate,
    1934             :                                               source_track->edit_rate);
    1935             : 
    1936           6 :                 if (av_timecode_init(&tc, mxf_tc->rate, flags, start_position + mxf_tc->start_frame, mxf->fc) == 0) {
    1937           6 :                     mxf_add_timecode_metadata(&st->metadata, "timecode", &tc);
    1938           6 :                     return 0;
    1939             :                 }
    1940             :             }
    1941             :         }
    1942             :     }
    1943             : 
    1944         173 :     return 0;
    1945             : }
    1946             : 
    1947          98 : static int mxf_add_metadata_stream(MXFContext *mxf, MXFTrack *track)
    1948             : {
    1949          98 :     MXFStructuralComponent *component = NULL;
    1950          98 :     const MXFCodecUL *codec_ul = NULL;
    1951             :     MXFPackage tmp_package;
    1952             :     AVStream *st;
    1953             :     int j;
    1954             : 
    1955         368 :     for (j = 0; j < track->sequence->structural_components_count; j++) {
    1956          98 :         component = mxf_resolve_sourceclip(mxf, &track->sequence->structural_components_refs[j]);
    1957          98 :         if (!component)
    1958          86 :             continue;
    1959          12 :         break;
    1960             :     }
    1961          98 :     if (!component)
    1962          86 :         return 0;
    1963             : 
    1964          12 :     st = avformat_new_stream(mxf->fc, NULL);
    1965          12 :     if (!st) {
    1966           0 :         av_log(mxf->fc, AV_LOG_ERROR, "could not allocate metadata stream\n");
    1967           0 :         return AVERROR(ENOMEM);
    1968             :     }
    1969             : 
    1970          12 :     st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
    1971          12 :     st->codecpar->codec_id = AV_CODEC_ID_NONE;
    1972          12 :     st->id = track->track_id;
    1973             : 
    1974          12 :     memcpy(&tmp_package.package_ul, component->source_package_ul, 16);
    1975          12 :     memcpy(&tmp_package.package_uid, component->source_package_uid, 16);
    1976          12 :     mxf_add_umid_metadata(&st->metadata, "file_package_umid", &tmp_package);
    1977          12 :     if (track->name && track->name[0])
    1978           6 :         av_dict_set(&st->metadata, "track_name", track->name, 0);
    1979             : 
    1980          12 :     codec_ul = mxf_get_codec_ul(ff_mxf_data_definition_uls, &track->sequence->data_definition_ul);
    1981          12 :     av_dict_set(&st->metadata, "data_type", av_get_media_type_string(codec_ul->id), 0);
    1982          12 :     return 0;
    1983             : }
    1984             : 
    1985          91 : static int mxf_parse_structural_metadata(MXFContext *mxf)
    1986             : {
    1987          91 :     MXFPackage *material_package = NULL;
    1988             :     int i, j, k, ret;
    1989             : 
    1990          91 :     av_log(mxf->fc, AV_LOG_TRACE, "metadata sets count %d\n", mxf->metadata_sets_count);
    1991             :     /* TODO: handle multiple material packages (OP3x) */
    1992          92 :     for (i = 0; i < mxf->packages_count; i++) {
    1993          92 :         material_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], MaterialPackage);
    1994          92 :         if (material_package) break;
    1995             :     }
    1996          91 :     if (!material_package) {
    1997           0 :         av_log(mxf->fc, AV_LOG_ERROR, "no material package found\n");
    1998           0 :         return AVERROR_INVALIDDATA;
    1999             :     }
    2000             : 
    2001          91 :     mxf_add_umid_metadata(&mxf->fc->metadata, "material_package_umid", material_package);
    2002          91 :     if (material_package->name && material_package->name[0])
    2003           7 :         av_dict_set(&mxf->fc->metadata, "material_package_name", material_package->name, 0);
    2004          91 :     mxf_parse_package_comments(mxf, &mxf->fc->metadata, material_package);
    2005             : 
    2006         368 :     for (i = 0; i < material_package->tracks_count; i++) {
    2007         277 :         MXFPackage *source_package = NULL;
    2008         277 :         MXFTrack *material_track = NULL;
    2009         277 :         MXFTrack *source_track = NULL;
    2010         277 :         MXFTrack *temp_track = NULL;
    2011         277 :         MXFDescriptor *descriptor = NULL;
    2012         277 :         MXFStructuralComponent *component = NULL;
    2013         277 :         MXFTimecodeComponent *mxf_tc = NULL;
    2014         277 :         UID *essence_container_ul = NULL;
    2015         277 :         const MXFCodecUL *codec_ul = NULL;
    2016         277 :         const MXFCodecUL *container_ul = NULL;
    2017         277 :         const MXFCodecUL *pix_fmt_ul = NULL;
    2018             :         AVStream *st;
    2019             :         AVTimecode tc;
    2020             :         int flags;
    2021             : 
    2022         277 :         if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) {
    2023           0 :             av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n");
    2024          98 :             continue;
    2025             :         }
    2026             : 
    2027         277 :         if ((component = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, TimecodeComponent))) {
    2028           0 :             mxf_tc = (MXFTimecodeComponent*)component;
    2029           0 :             flags = mxf_tc->drop_frame == 1 ? AV_TIMECODE_FLAG_DROPFRAME : 0;
    2030           0 :             if (av_timecode_init(&tc, mxf_tc->rate, flags, mxf_tc->start_frame, mxf->fc) == 0) {
    2031           0 :                 mxf_add_timecode_metadata(&mxf->fc->metadata, "timecode", &tc);
    2032             :             }
    2033             :         }
    2034             : 
    2035         277 :         if (!(material_track->sequence = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, Sequence))) {
    2036           0 :             av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track sequence strong ref\n");
    2037           0 :             continue;
    2038             :         }
    2039             : 
    2040         477 :         for (j = 0; j < material_track->sequence->structural_components_count; j++) {
    2041         285 :             component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], TimecodeComponent);
    2042         285 :             if (!component)
    2043         200 :                 continue;
    2044             : 
    2045          85 :             mxf_tc = (MXFTimecodeComponent*)component;
    2046          85 :             flags = mxf_tc->drop_frame == 1 ? AV_TIMECODE_FLAG_DROPFRAME : 0;
    2047          85 :             if (av_timecode_init(&tc, mxf_tc->rate, flags, mxf_tc->start_frame, mxf->fc) == 0) {
    2048          85 :                 mxf_add_timecode_metadata(&mxf->fc->metadata, "timecode", &tc);
    2049          85 :                 break;
    2050             :             }
    2051             :         }
    2052             : 
    2053             :         /* TODO: handle multiple source clips, only finds first valid source clip */
    2054         277 :         if(material_track->sequence->structural_components_count > 1)
    2055           8 :             av_log(mxf->fc, AV_LOG_WARNING, "material track %d: has %d components\n",
    2056           8 :                        material_track->track_id, material_track->sequence->structural_components_count);
    2057             : 
    2058         380 :         for (j = 0; j < material_track->sequence->structural_components_count; j++) {
    2059         282 :             component = mxf_resolve_sourceclip(mxf, &material_track->sequence->structural_components_refs[j]);
    2060         282 :             if (!component)
    2061          91 :                 continue;
    2062             : 
    2063         191 :             source_package = mxf_resolve_source_package(mxf, component->source_package_ul, component->source_package_uid);
    2064         191 :             if (!source_package) {
    2065          12 :                 av_log(mxf->fc, AV_LOG_TRACE, "material track %d: no corresponding source package found\n", material_track->track_id);
    2066          12 :                 continue;
    2067             :             }
    2068         457 :             for (k = 0; k < source_package->tracks_count; k++) {
    2069         457 :                 if (!(temp_track = mxf_resolve_strong_ref(mxf, &source_package->tracks_refs[k], Track))) {
    2070           0 :                     av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n");
    2071           0 :                     ret = AVERROR_INVALIDDATA;
    2072           0 :                     goto fail_and_free;
    2073             :                 }
    2074         457 :                 if (temp_track->track_id == component->source_track_id) {
    2075         179 :                     source_track = temp_track;
    2076         179 :                     break;
    2077             :                 }
    2078             :             }
    2079         179 :             if (!source_track) {
    2080           0 :                 av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source track found\n", material_track->track_id);
    2081           0 :                 break;
    2082             :             }
    2083             : 
    2084         179 :             for (k = 0; k < mxf->essence_container_data_count; k++) {
    2085             :                 MXFEssenceContainerData *essence_data;
    2086             : 
    2087         179 :                 if (!(essence_data = mxf_resolve_strong_ref(mxf, &mxf->essence_container_data_refs[k], EssenceContainerData))) {
    2088           0 :                     av_log(mxf, AV_LOG_TRACE, "could not resolve essence container data strong ref\n");
    2089           0 :                     continue;
    2090             :                 }
    2091         179 :                 if (!memcmp(component->source_package_ul, essence_data->package_ul, sizeof(UID)) && !memcmp(component->source_package_uid, essence_data->package_uid, sizeof(UID))) {
    2092         179 :                     source_track->body_sid = essence_data->body_sid;
    2093         179 :                     source_track->index_sid = essence_data->index_sid;
    2094         179 :                     break;
    2095             :                 }
    2096             :             }
    2097             : 
    2098         179 :             if(source_track && component)
    2099         179 :                 break;
    2100             :         }
    2101         277 :         if (!source_track || !component || !source_package) {
    2102          98 :             if((ret = mxf_add_metadata_stream(mxf, material_track)))
    2103           0 :                 goto fail_and_free;
    2104          98 :             continue;
    2105             :         }
    2106             : 
    2107         179 :         if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) {
    2108           0 :             av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n");
    2109           0 :             ret = AVERROR_INVALIDDATA;
    2110           0 :             goto fail_and_free;
    2111             :         }
    2112             : 
    2113             :         /* 0001GL00.MXF.A1.mxf_opatom.mxf has the same SourcePackageID as 0001GL.MXF.V1.mxf_opatom.mxf
    2114             :          * This would result in both files appearing to have two streams. Work around this by sanity checking DataDefinition */
    2115         179 :         if (memcmp(material_track->sequence->data_definition_ul, source_track->sequence->data_definition_ul, 16)) {
    2116           0 :             av_log(mxf->fc, AV_LOG_ERROR, "material track %d: DataDefinition mismatch\n", material_track->track_id);
    2117           0 :             continue;
    2118             :         }
    2119             : 
    2120         179 :         st = avformat_new_stream(mxf->fc, NULL);
    2121         179 :         if (!st) {
    2122           0 :             av_log(mxf->fc, AV_LOG_ERROR, "could not allocate stream\n");
    2123           0 :             ret = AVERROR(ENOMEM);
    2124           0 :             goto fail_and_free;
    2125             :         }
    2126         179 :         st->id = material_track->track_id;
    2127         179 :         st->priv_data = source_track;
    2128             : 
    2129         179 :         source_package->descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor_ref, AnyType);
    2130         179 :         descriptor = mxf_resolve_multidescriptor(mxf, source_package->descriptor, source_track->track_id);
    2131             : 
    2132             :         /* A SourceClip from a EssenceGroup may only be a single frame of essence data. The clips duration is then how many
    2133             :          * frames its suppose to repeat for. Descriptor->duration, if present, contains the real duration of the essence data */
    2134         179 :         if (descriptor && descriptor->duration != AV_NOPTS_VALUE)
    2135          10 :             source_track->original_duration = st->duration = FFMIN(descriptor->duration, component->duration);
    2136             :         else
    2137         169 :             source_track->original_duration = st->duration = component->duration;
    2138             : 
    2139         179 :         if (st->duration == -1)
    2140           4 :             st->duration = AV_NOPTS_VALUE;
    2141         179 :         st->start_time = component->start_position;
    2142         358 :         if (material_track->edit_rate.num <= 0 ||
    2143         179 :             material_track->edit_rate.den <= 0) {
    2144           0 :             av_log(mxf->fc, AV_LOG_WARNING,
    2145             :                    "Invalid edit rate (%d/%d) found on stream #%d, "
    2146             :                    "defaulting to 25/1\n",
    2147             :                    material_track->edit_rate.num,
    2148             :                    material_track->edit_rate.den, st->index);
    2149           0 :             material_track->edit_rate = (AVRational){25, 1};
    2150             :         }
    2151         179 :         avpriv_set_pts_info(st, 64, material_track->edit_rate.den, material_track->edit_rate.num);
    2152             : 
    2153             :         /* ensure SourceTrack EditRate == MaterialTrack EditRate since only
    2154             :          * the former is accessible via st->priv_data */
    2155         179 :         source_track->edit_rate = material_track->edit_rate;
    2156             : 
    2157             :         PRINT_KEY(mxf->fc, "data definition   ul", source_track->sequence->data_definition_ul);
    2158         179 :         codec_ul = mxf_get_codec_ul(ff_mxf_data_definition_uls, &source_track->sequence->data_definition_ul);
    2159         179 :         st->codecpar->codec_type = codec_ul->id;
    2160             : 
    2161         179 :         if (!descriptor) {
    2162           0 :             av_log(mxf->fc, AV_LOG_INFO, "source track %d: stream %d, no descriptor found\n", source_track->track_id, st->index);
    2163           0 :             continue;
    2164             :         }
    2165             :         PRINT_KEY(mxf->fc, "essence codec     ul", descriptor->essence_codec_ul);
    2166             :         PRINT_KEY(mxf->fc, "essence container ul", descriptor->essence_container_ul);
    2167         179 :         essence_container_ul = &descriptor->essence_container_ul;
    2168             :         /* HACK: replacing the original key with mxf_encrypted_essence_container
    2169             :          * is not allowed according to s429-6, try to find correct information anyway */
    2170         179 :         if (IS_KLV_KEY(essence_container_ul, mxf_encrypted_essence_container)) {
    2171           0 :             av_log(mxf->fc, AV_LOG_INFO, "broken encrypted mxf file\n");
    2172           0 :             for (k = 0; k < mxf->metadata_sets_count; k++) {
    2173           0 :                 MXFMetadataSet *metadata = mxf->metadata_sets[k];
    2174           0 :                 if (metadata->type == CryptoContext) {
    2175           0 :                     essence_container_ul = &((MXFCryptoContext *)metadata)->source_container_ul;
    2176           0 :                     break;
    2177             :                 }
    2178             :             }
    2179             :         }
    2180             : 
    2181             :         /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
    2182         179 :         codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->essence_codec_ul);
    2183         179 :         st->codecpar->codec_id = (enum AVCodecID)codec_ul->id;
    2184         179 :         if (st->codecpar->codec_id == AV_CODEC_ID_NONE) {
    2185          90 :             codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->codec_ul);
    2186          90 :             st->codecpar->codec_id = (enum AVCodecID)codec_ul->id;
    2187             :         }
    2188             : 
    2189         179 :         av_log(mxf->fc, AV_LOG_VERBOSE, "%s: Universal Label: ",
    2190         179 :                avcodec_get_name(st->codecpar->codec_id));
    2191        3043 :         for (k = 0; k < 16; k++) {
    2192        2864 :             av_log(mxf->fc, AV_LOG_VERBOSE, "%.2x",
    2193        2864 :                    descriptor->essence_codec_ul[k]);
    2194        2864 :             if (!(k+1 & 19) || k == 5)
    2195         716 :                 av_log(mxf->fc, AV_LOG_VERBOSE, ".");
    2196             :         }
    2197         179 :         av_log(mxf->fc, AV_LOG_VERBOSE, "\n");
    2198             : 
    2199         179 :         mxf_add_umid_metadata(&st->metadata, "file_package_umid", source_package);
    2200         179 :         if (source_package->name && source_package->name[0])
    2201           7 :             av_dict_set(&st->metadata, "file_package_name", source_package->name, 0);
    2202         179 :         if (material_track->name && material_track->name[0])
    2203           4 :             av_dict_set(&st->metadata, "track_name", material_track->name, 0);
    2204             : 
    2205         179 :         mxf_parse_physical_source_package(mxf, source_track, st);
    2206             : 
    2207         179 :         if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
    2208          87 :             source_track->intra_only = mxf_is_intra_only(descriptor);
    2209          87 :             container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
    2210          87 :             if (st->codecpar->codec_id == AV_CODEC_ID_NONE)
    2211           2 :                 st->codecpar->codec_id = container_ul->id;
    2212          87 :             st->codecpar->width = descriptor->width;
    2213          87 :             st->codecpar->height = descriptor->height; /* Field height, not frame height */
    2214          87 :             switch (descriptor->frame_layout) {
    2215          45 :                 case FullFrame:
    2216          45 :                     st->codecpar->field_order = AV_FIELD_PROGRESSIVE;
    2217          45 :                     break;
    2218           0 :                 case OneField:
    2219             :                     /* Every other line is stored and needs to be duplicated. */
    2220           0 :                     av_log(mxf->fc, AV_LOG_INFO, "OneField frame layout isn't currently supported\n");
    2221           0 :                     break; /* The correct thing to do here is fall through, but by breaking we might be
    2222             :                               able to decode some streams at half the vertical resolution, rather than not al all.
    2223             :                               It's also for compatibility with the old behavior. */
    2224           0 :                 case MixedFields:
    2225           0 :                     break;
    2226           0 :                 case SegmentedFrame:
    2227           0 :                     st->codecpar->field_order = AV_FIELD_PROGRESSIVE;
    2228          42 :                 case SeparateFields:
    2229          42 :                     av_log(mxf->fc, AV_LOG_DEBUG, "video_line_map: (%d, %d), field_dominance: %d\n",
    2230             :                            descriptor->video_line_map[0], descriptor->video_line_map[1],
    2231             :                            descriptor->field_dominance);
    2232          84 :                     if ((descriptor->video_line_map[0] > 0) && (descriptor->video_line_map[1] > 0)) {
    2233             :                         /* Detect coded field order from VideoLineMap:
    2234             :                          *  (even, even) => bottom field coded first
    2235             :                          *  (even, odd)  => top field coded first
    2236             :                          *  (odd, even)  => top field coded first
    2237             :                          *  (odd, odd)   => bottom field coded first
    2238             :                          */
    2239          42 :                         if ((descriptor->video_line_map[0] + descriptor->video_line_map[1]) % 2) {
    2240          37 :                             switch (descriptor->field_dominance) {
    2241          37 :                                 case MXF_FIELD_DOMINANCE_DEFAULT:
    2242             :                                 case MXF_FIELD_DOMINANCE_FF:
    2243          37 :                                     st->codecpar->field_order = AV_FIELD_TT;
    2244          37 :                                     break;
    2245           0 :                                 case MXF_FIELD_DOMINANCE_FL:
    2246           0 :                                     st->codecpar->field_order = AV_FIELD_TB;
    2247           0 :                                     break;
    2248           0 :                                 default:
    2249           0 :                                     avpriv_request_sample(mxf->fc,
    2250             :                                                           "Field dominance %d support",
    2251             :                                                           descriptor->field_dominance);
    2252             :                             }
    2253             :                         } else {
    2254           5 :                             switch (descriptor->field_dominance) {
    2255           5 :                                 case MXF_FIELD_DOMINANCE_DEFAULT:
    2256             :                                 case MXF_FIELD_DOMINANCE_FF:
    2257           5 :                                     st->codecpar->field_order = AV_FIELD_BB;
    2258           5 :                                     break;
    2259           0 :                                 case MXF_FIELD_DOMINANCE_FL:
    2260           0 :                                     st->codecpar->field_order = AV_FIELD_BT;
    2261           0 :                                     break;
    2262           0 :                                 default:
    2263           0 :                                     avpriv_request_sample(mxf->fc,
    2264             :                                                           "Field dominance %d support",
    2265             :                                                           descriptor->field_dominance);
    2266             :                             }
    2267           0 :                         }
    2268             :                     }
    2269             :                     /* Turn field height into frame height. */
    2270          42 :                     st->codecpar->height *= 2;
    2271          42 :                     break;
    2272           0 :                 default:
    2273           0 :                     av_log(mxf->fc, AV_LOG_INFO, "Unknown frame layout type: %d\n", descriptor->frame_layout);
    2274             :             }
    2275          87 :             if (st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO) {
    2276           1 :                 st->codecpar->format = descriptor->pix_fmt;
    2277           1 :                 if (st->codecpar->format == AV_PIX_FMT_NONE) {
    2278           0 :                     pix_fmt_ul = mxf_get_codec_ul(ff_mxf_pixel_format_uls,
    2279             :                                                   &descriptor->essence_codec_ul);
    2280           0 :                     st->codecpar->format = (enum AVPixelFormat)pix_fmt_ul->id;
    2281           0 :                     if (st->codecpar->format== AV_PIX_FMT_NONE) {
    2282           0 :                         st->codecpar->codec_tag = mxf_get_codec_ul(ff_mxf_codec_tag_uls,
    2283           0 :                                                                    &descriptor->essence_codec_ul)->id;
    2284           0 :                         if (!st->codecpar->codec_tag) {
    2285             :                             /* support files created before RP224v10 by defaulting to UYVY422
    2286             :                                if subsampling is 4:2:2 and component depth is 8-bit */
    2287           0 :                             if (descriptor->horiz_subsampling == 2 &&
    2288           0 :                                 descriptor->vert_subsampling == 1 &&
    2289           0 :                                 descriptor->component_depth == 8) {
    2290           0 :                                 st->codecpar->format = AV_PIX_FMT_UYVY422;
    2291             :                             }
    2292             :                         }
    2293             :                     }
    2294             :                 }
    2295             :             }
    2296          87 :             st->need_parsing = AVSTREAM_PARSE_HEADERS;
    2297          87 :             if (material_track->sequence->origin) {
    2298           0 :                 av_dict_set_int(&st->metadata, "material_track_origin", material_track->sequence->origin, 0);
    2299             :             }
    2300          87 :             if (source_track->sequence->origin) {
    2301           0 :                 av_dict_set_int(&st->metadata, "source_track_origin", source_track->sequence->origin, 0);
    2302             :             }
    2303          87 :             if (descriptor->aspect_ratio.num && descriptor->aspect_ratio.den)
    2304          87 :                 st->display_aspect_ratio = descriptor->aspect_ratio;
    2305          92 :         } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
    2306          91 :             container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
    2307             :             /* Only overwrite existing codec ID if it is unset or A-law, which is the default according to SMPTE RP 224. */
    2308          91 :             if (st->codecpar->codec_id == AV_CODEC_ID_NONE || (st->codecpar->codec_id == AV_CODEC_ID_PCM_ALAW && (enum AVCodecID)container_ul->id != AV_CODEC_ID_NONE))
    2309          87 :                 st->codecpar->codec_id = (enum AVCodecID)container_ul->id;
    2310          91 :             st->codecpar->channels = descriptor->channels;
    2311          91 :             st->codecpar->bits_per_coded_sample = descriptor->bits_per_sample;
    2312             : 
    2313          91 :             if (descriptor->sample_rate.den > 0) {
    2314          91 :                 st->codecpar->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den;
    2315          91 :                 avpriv_set_pts_info(st, 64, descriptor->sample_rate.den, descriptor->sample_rate.num);
    2316             :             } else {
    2317           0 :                 av_log(mxf->fc, AV_LOG_WARNING, "invalid sample rate (%d/%d) "
    2318             :                        "found for stream #%d, time base forced to 1/48000\n",
    2319             :                        descriptor->sample_rate.num, descriptor->sample_rate.den,
    2320             :                        st->index);
    2321           0 :                 avpriv_set_pts_info(st, 64, 1, 48000);
    2322             :             }
    2323             : 
    2324             :             /* if duration is set, rescale it from EditRate to SampleRate */
    2325          91 :             if (st->duration != AV_NOPTS_VALUE)
    2326          89 :                 st->duration = av_rescale_q(st->duration,
    2327             :                                             av_inv_q(material_track->edit_rate),
    2328             :                                             st->time_base);
    2329             : 
    2330             :             /* TODO: implement AV_CODEC_ID_RAWAUDIO */
    2331          91 :             if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S16LE) {
    2332          87 :                 if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24)
    2333           5 :                     st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
    2334          82 :                 else if (descriptor->bits_per_sample == 32)
    2335           0 :                     st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
    2336           4 :             } else if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE) {
    2337           0 :                 if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24)
    2338           0 :                     st->codecpar->codec_id = AV_CODEC_ID_PCM_S24BE;
    2339           0 :                 else if (descriptor->bits_per_sample == 32)
    2340           0 :                     st->codecpar->codec_id = AV_CODEC_ID_PCM_S32BE;
    2341           4 :             } else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) {
    2342           0 :                 st->need_parsing = AVSTREAM_PARSE_FULL;
    2343             :             }
    2344           1 :         } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
    2345           1 :             int codec_id = mxf_get_codec_ul(mxf_data_essence_container_uls,
    2346             :                                             essence_container_ul)->id;
    2347           1 :             if (codec_id >= 0 &&
    2348             :                 codec_id < FF_ARRAY_ELEMS(mxf_data_essence_descriptor)) {
    2349           1 :                 av_dict_set(&st->metadata, "data_type",
    2350             :                             mxf_data_essence_descriptor[codec_id], 0);
    2351             :             }
    2352             :         }
    2353         179 :         if (descriptor->extradata) {
    2354           1 :             if (!ff_alloc_extradata(st->codecpar, descriptor->extradata_size)) {
    2355           1 :                 memcpy(st->codecpar->extradata, descriptor->extradata, descriptor->extradata_size);
    2356             :             }
    2357         178 :         } else if (st->codecpar->codec_id == AV_CODEC_ID_H264) {
    2358           1 :             int coded_width = mxf_get_codec_ul(mxf_intra_only_picture_coded_width,
    2359             :                                                &descriptor->essence_codec_ul)->id;
    2360           1 :             if (coded_width)
    2361           0 :                 st->codecpar->width = coded_width;
    2362           1 :             ret = ff_generate_avci_extradata(st);
    2363           1 :             if (ret < 0)
    2364           0 :                 return ret;
    2365             :         }
    2366         179 :         if (st->codecpar->codec_type != AVMEDIA_TYPE_DATA && (*essence_container_ul)[15] > 0x01) {
    2367             :             /* TODO: decode timestamps */
    2368           4 :             st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
    2369             :         }
    2370             :     }
    2371             : 
    2372          91 :     ret = 0;
    2373          91 : fail_and_free:
    2374          91 :     return ret;
    2375             : }
    2376             : 
    2377          91 : static int64_t mxf_timestamp_to_int64(uint64_t timestamp)
    2378             : {
    2379          91 :     struct tm time = { 0 };
    2380          91 :     time.tm_year = (timestamp >> 48) - 1900;
    2381          91 :     time.tm_mon  = (timestamp >> 40 & 0xFF) - 1;
    2382          91 :     time.tm_mday = (timestamp >> 32 & 0xFF);
    2383          91 :     time.tm_hour = (timestamp >> 24 & 0xFF);
    2384          91 :     time.tm_min  = (timestamp >> 16 & 0xFF);
    2385          91 :     time.tm_sec  = (timestamp >> 8  & 0xFF);
    2386             : 
    2387             :     /* msvcrt versions of strftime calls the invalid parameter handler
    2388             :      * (aborting the process if one isn't set) if the parameters are out
    2389             :      * of range. */
    2390          91 :     time.tm_mon  = av_clip(time.tm_mon,  0, 11);
    2391          91 :     time.tm_mday = av_clip(time.tm_mday, 1, 31);
    2392          91 :     time.tm_hour = av_clip(time.tm_hour, 0, 23);
    2393          91 :     time.tm_min  = av_clip(time.tm_min,  0, 59);
    2394          91 :     time.tm_sec  = av_clip(time.tm_sec,  0, 59);
    2395             : 
    2396          91 :     return (int64_t)av_timegm(&time) * 1000000;
    2397             : }
    2398             : 
    2399             : #define SET_STR_METADATA(pb, name, str) do { \
    2400             :     if ((ret = mxf_read_utf16be_string(pb, size, &str)) < 0) \
    2401             :         return ret; \
    2402             :     av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \
    2403             : } while (0)
    2404             : 
    2405             : #define SET_UID_METADATA(pb, name, var, str) do { \
    2406             :     avio_read(pb, var, 16); \
    2407             :     if ((ret = mxf_uid_to_str(var, &str)) < 0) \
    2408             :         return ret; \
    2409             :     av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \
    2410             : } while (0)
    2411             : 
    2412             : #define SET_TS_METADATA(pb, name, var, str) do { \
    2413             :     var = avio_rb64(pb); \
    2414             :     if ((ret = avpriv_dict_set_timestamp(&s->metadata, name, mxf_timestamp_to_int64(var)) < 0)) \
    2415             :         return ret; \
    2416             : } while (0)
    2417             : 
    2418         816 : static int mxf_read_identification_metadata(void *arg, AVIOContext *pb, int tag, int size, UID _uid, int64_t klv_offset)
    2419             : {
    2420         816 :     MXFContext *mxf = arg;
    2421         816 :     AVFormatContext *s = mxf->fc;
    2422             :     int ret;
    2423         816 :     UID uid = { 0 };
    2424         816 :     char *str = NULL;
    2425             :     uint64_t ts;
    2426         816 :     switch (tag) {
    2427          91 :     case 0x3C01:
    2428          91 :         SET_STR_METADATA(pb, "company_name", str);
    2429          91 :         break;
    2430          91 :     case 0x3C02:
    2431          91 :         SET_STR_METADATA(pb, "product_name", str);
    2432          91 :         break;
    2433          91 :     case 0x3C04:
    2434          91 :         SET_STR_METADATA(pb, "product_version", str);
    2435          91 :         break;
    2436          91 :     case 0x3C05:
    2437          91 :         SET_UID_METADATA(pb, "product_uid", uid, str);
    2438          91 :         break;
    2439          91 :     case 0x3C06:
    2440          91 :         SET_TS_METADATA(pb, "modification_date", ts, str);
    2441          91 :         break;
    2442           7 :     case 0x3C08:
    2443           7 :         SET_STR_METADATA(pb, "application_platform", str);
    2444           7 :         break;
    2445          91 :     case 0x3C09:
    2446          91 :         SET_UID_METADATA(pb, "generation_uid", uid, str);
    2447          91 :         break;
    2448          91 :     case 0x3C0A:
    2449          91 :         SET_UID_METADATA(pb, "uid", uid, str);
    2450          91 :         break;
    2451             :     }
    2452         816 :     return 0;
    2453             : }
    2454             : 
    2455         851 : static int mxf_read_preface_metadata(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
    2456             : {
    2457         851 :     MXFContext *mxf = arg;
    2458         851 :     AVFormatContext *s = mxf->fc;
    2459             :     int ret;
    2460         851 :     char *str = NULL;
    2461             : 
    2462         851 :     if (tag >= 0x8000 && (IS_KLV_KEY(uid, mxf_avid_project_name))) {
    2463           6 :         SET_STR_METADATA(pb, "project_name", str);
    2464             :     }
    2465         851 :     return 0;
    2466             : }
    2467             : 
    2468             : static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
    2469             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }, mxf_read_primer_pack },
    2470             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }, mxf_read_partition_pack },
    2471             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x02,0x00 }, mxf_read_partition_pack },
    2472             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x03,0x00 }, mxf_read_partition_pack },
    2473             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }, mxf_read_partition_pack },
    2474             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x01,0x00 }, mxf_read_partition_pack },
    2475             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x02,0x00 }, mxf_read_partition_pack },
    2476             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x03,0x00 }, mxf_read_partition_pack },
    2477             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x04,0x00 }, mxf_read_partition_pack },
    2478             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x02,0x00 }, mxf_read_partition_pack },
    2479             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }, mxf_read_partition_pack },
    2480             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x2f,0x00 }, mxf_read_preface_metadata },
    2481             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x30,0x00 }, mxf_read_identification_metadata },
    2482             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_content_storage, 0, AnyType },
    2483             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_package, sizeof(MXFPackage), SourcePackage },
    2484             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_package, sizeof(MXFPackage), MaterialPackage },
    2485             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0f,0x00 }, mxf_read_sequence, sizeof(MXFSequence), Sequence },
    2486             :     { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x05,0x00 }, mxf_read_essence_group, sizeof(MXFEssenceGroup), EssenceGroup},
    2487             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_source_clip, sizeof(MXFStructuralComponent), SourceClip },
    2488             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3f,0x00 }, mxf_read_tagged_value, sizeof(MXFTaggedValue), TaggedValue },
    2489             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x44,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), MultipleDescriptor },
    2490             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x42,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Generic Sound */
    2491             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x28,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* CDCI */
    2492             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x29,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* RGBA */
    2493             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Wave */
    2494             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* AES3 */
    2495             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG2VideoDescriptor */
    2496             :     { { 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 */
    2497             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5e,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG2AudioDescriptor */
    2498             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Static Track */
    2499             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Generic Track */
    2500             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x14,0x00 }, mxf_read_timecode_component, sizeof(MXFTimecodeComponent), TimecodeComponent },
    2501             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0c,0x00 }, mxf_read_pulldown_component, sizeof(MXFPulldownComponent), PulldownComponent },
    2502             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 }, mxf_read_cryptographic_context, sizeof(MXFCryptoContext), CryptoContext },
    2503             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 }, mxf_read_index_table_segment, sizeof(MXFIndexTableSegment), IndexTableSegment },
    2504             :     { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x23,0x00 }, mxf_read_essence_container_data, sizeof(MXFEssenceContainerData), EssenceContainerData },
    2505             :     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType },
    2506             : };
    2507             : 
    2508        2655 : static int mxf_metadataset_init(MXFMetadataSet *ctx, enum MXFMetadataSetType type)
    2509             : {
    2510        2655 :     switch (type){
    2511         259 :     case MultipleDescriptor:
    2512             :     case Descriptor:
    2513         259 :         ((MXFDescriptor*)ctx)->pix_fmt = AV_PIX_FMT_NONE;
    2514         259 :         ((MXFDescriptor*)ctx)->duration = AV_NOPTS_VALUE;
    2515         259 :         break;
    2516        2396 :     default:
    2517        2396 :         break;
    2518             :     }
    2519        2655 :     return 0;
    2520             : }
    2521             : 
    2522        2655 : static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadFunc *read_child, int ctx_size, enum MXFMetadataSetType type)
    2523             : {
    2524        2655 :     AVIOContext *pb = mxf->fc->pb;
    2525        2655 :     MXFMetadataSet *ctx = ctx_size ? av_mallocz(ctx_size) : mxf;
    2526        2655 :     uint64_t klv_end = avio_tell(pb) + klv->length;
    2527             : 
    2528        2655 :     if (!ctx)
    2529           0 :         return AVERROR(ENOMEM);
    2530        2655 :     mxf_metadataset_init(ctx, type);
    2531        2655 :     while (avio_tell(pb) + 4 < klv_end && !avio_feof(pb)) {
    2532             :         int ret;
    2533       16949 :         int tag = avio_rb16(pb);
    2534       16949 :         int size = avio_rb16(pb); /* KLV specified by 0x53 */
    2535       16949 :         uint64_t next = avio_tell(pb) + size;
    2536       16949 :         UID uid = {0};
    2537             : 
    2538       16949 :         av_log(mxf->fc, AV_LOG_TRACE, "local tag %#04x size %d\n", tag, size);
    2539       16949 :         if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */
    2540           0 :             av_log(mxf->fc, AV_LOG_ERROR, "local tag %#04x with 0 size\n", tag);
    2541           0 :             continue;
    2542             :         }
    2543       16949 :         if (tag > 0x7FFF) { /* dynamic tag */
    2544             :             int i;
    2545       32775 :             for (i = 0; i < mxf->local_tags_count; i++) {
    2546       32610 :                 int local_tag = AV_RB16(mxf->local_tags+i*18);
    2547       32610 :                 if (local_tag == tag) {
    2548         165 :                     memcpy(uid, mxf->local_tags+i*18+2, 16);
    2549         165 :                     av_log(mxf->fc, AV_LOG_TRACE, "local tag %#04x\n", local_tag);
    2550             :                     PRINT_KEY(mxf->fc, "uid", uid);
    2551             :                 }
    2552             :             }
    2553             :         }
    2554       16949 :         if (ctx_size && tag == 0x3C0A) {
    2555        2382 :             avio_read(pb, ctx->uid, 16);
    2556       14567 :         } else if ((ret = read_child(ctx, pb, tag, size, uid, -1)) < 0) {
    2557           0 :             mxf_free_metadataset(&ctx, !!ctx_size);
    2558           0 :             return ret;
    2559             :         }
    2560             : 
    2561             :         /* Accept the 64k local set limit being exceeded (Avid). Don't accept
    2562             :          * it extending past the end of the KLV though (zzuf5.mxf). */
    2563       16949 :         if (avio_tell(pb) > klv_end) {
    2564           0 :             if (ctx_size) {
    2565           0 :                 ctx->type = type;
    2566           0 :                 mxf_free_metadataset(&ctx, !!ctx_size);
    2567             :             }
    2568             : 
    2569           0 :             av_log(mxf->fc, AV_LOG_ERROR,
    2570             :                    "local tag %#04x extends past end of local set @ %#"PRIx64"\n",
    2571             :                    tag, klv->offset);
    2572           0 :             return AVERROR_INVALIDDATA;
    2573       16949 :         } else if (avio_tell(pb) <= next)   /* only seek forward, else this can loop for a long time */
    2574       16949 :             avio_seek(pb, next, SEEK_SET);
    2575             :     }
    2576        2655 :     if (ctx_size) ctx->type = type;
    2577        2655 :     return ctx_size ? mxf_add_metadata_set(mxf, ctx) : 0;
    2578             : }
    2579             : 
    2580             : /**
    2581             :  * Matches any partition pack key, in other words:
    2582             :  * - HeaderPartition
    2583             :  * - BodyPartition
    2584             :  * - FooterPartition
    2585             :  * @return non-zero if the key is a partition pack key, zero otherwise
    2586             :  */
    2587        7400 : static int mxf_is_partition_pack_key(UID key)
    2588             : {
    2589             :     //NOTE: this is a little lax since it doesn't constraint key[14]
    2590        7804 :     return !memcmp(key, mxf_header_partition_pack_key, 13) &&
    2591        7804 :             key[13] >= 2 && key[13] <= 4;
    2592             : }
    2593             : 
    2594             : /**
    2595             :  * Parses a metadata KLV
    2596             :  * @return <0 on error, 0 otherwise
    2597             :  */
    2598        2973 : static int mxf_parse_klv(MXFContext *mxf, KLVPacket klv, MXFMetadataReadFunc *read,
    2599             :                                      int ctx_size, enum MXFMetadataSetType type)
    2600             : {
    2601        2973 :     AVFormatContext *s = mxf->fc;
    2602             :     int res;
    2603        2973 :     if (klv.key[5] == 0x53) {
    2604        2655 :         res = mxf_read_local_tags(mxf, &klv, read, ctx_size, type);
    2605             :     } else {
    2606         318 :         uint64_t next = avio_tell(s->pb) + klv.length;
    2607         318 :         res = read(mxf, s->pb, 0, klv.length, klv.key, klv.offset);
    2608             : 
    2609             :         /* only seek forward, else this can loop for a long time */
    2610         318 :         if (avio_tell(s->pb) > next) {
    2611           0 :             av_log(s, AV_LOG_ERROR, "read past end of KLV @ %#"PRIx64"\n",
    2612             :                    klv.offset);
    2613           0 :             return AVERROR_INVALIDDATA;
    2614             :         }
    2615             : 
    2616         318 :         avio_seek(s->pb, next, SEEK_SET);
    2617             :     }
    2618        2973 :     if (res < 0) {
    2619           0 :         av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
    2620           0 :         return res;
    2621             :     }
    2622        2973 :     return 0;
    2623             : }
    2624             : 
    2625             : /**
    2626             :  * Seeks to the previous partition and parses it, if possible
    2627             :  * @return <= 0 if we should stop parsing, > 0 if we should keep going
    2628             :  */
    2629          89 : static int mxf_seek_to_previous_partition(MXFContext *mxf)
    2630             : {
    2631          89 :     AVIOContext *pb = mxf->fc->pb;
    2632             :     KLVPacket klv;
    2633             :     int64_t current_partition_ofs;
    2634             :     int ret;
    2635             : 
    2636         177 :     if (!mxf->current_partition ||
    2637          88 :         mxf->run_in + mxf->current_partition->previous_partition <= mxf->last_forward_tell)
    2638          89 :         return 0;   /* we've parsed all partitions */
    2639             : 
    2640             :     /* seek to previous partition */
    2641           0 :     current_partition_ofs = mxf->current_partition->pack_ofs;   //includes run-in
    2642           0 :     avio_seek(pb, mxf->run_in + mxf->current_partition->previous_partition, SEEK_SET);
    2643           0 :     mxf->current_partition = NULL;
    2644             : 
    2645           0 :     av_log(mxf->fc, AV_LOG_TRACE, "seeking to previous partition\n");
    2646             : 
    2647             :     /* Make sure this is actually a PartitionPack, and if so parse it.
    2648             :      * See deadlock2.mxf
    2649             :      */
    2650           0 :     if ((ret = klv_read_packet(&klv, pb)) < 0) {
    2651           0 :         av_log(mxf->fc, AV_LOG_ERROR, "failed to read PartitionPack KLV\n");
    2652           0 :         return ret;
    2653             :     }
    2654             : 
    2655           0 :     if (!mxf_is_partition_pack_key(klv.key)) {
    2656           0 :         av_log(mxf->fc, AV_LOG_ERROR, "PreviousPartition @ %" PRIx64 " isn't a PartitionPack\n", klv.offset);
    2657           0 :         return AVERROR_INVALIDDATA;
    2658             :     }
    2659             : 
    2660             :     /* We can't just check ofs >= current_partition_ofs because PreviousPartition
    2661             :      * can point to just before the current partition, causing klv_read_packet()
    2662             :      * to sync back up to it. See deadlock3.mxf
    2663             :      */
    2664           0 :     if (klv.offset >= current_partition_ofs) {
    2665           0 :         av_log(mxf->fc, AV_LOG_ERROR, "PreviousPartition for PartitionPack @ %"
    2666             :                PRIx64 " indirectly points to itself\n", current_partition_ofs);
    2667           0 :         return AVERROR_INVALIDDATA;
    2668             :     }
    2669             : 
    2670           0 :     if ((ret = mxf_parse_klv(mxf, klv, mxf_read_partition_pack, 0, 0)) < 0)
    2671           0 :         return ret;
    2672             : 
    2673           0 :     return 1;
    2674             : }
    2675             : 
    2676             : /**
    2677             :  * Called when essence is encountered
    2678             :  * @return <= 0 if we should stop parsing, > 0 if we should keep going
    2679             :  */
    2680          91 : static int mxf_parse_handle_essence(MXFContext *mxf)
    2681             : {
    2682          91 :     AVIOContext *pb = mxf->fc->pb;
    2683             :     int64_t ret;
    2684             : 
    2685          91 :     if (mxf->parsing_backward) {
    2686           0 :         return mxf_seek_to_previous_partition(mxf);
    2687             :     } else {
    2688          91 :         if (!mxf->footer_partition) {
    2689           2 :             av_log(mxf->fc, AV_LOG_TRACE, "no FooterPartition\n");
    2690           2 :             return 0;
    2691             :         }
    2692             : 
    2693          89 :         av_log(mxf->fc, AV_LOG_TRACE, "seeking to FooterPartition\n");
    2694             : 
    2695             :         /* remember where we were so we don't end up seeking further back than this */
    2696          89 :         mxf->last_forward_tell = avio_tell(pb);
    2697             : 
    2698          89 :         if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) {
    2699           0 :             av_log(mxf->fc, AV_LOG_INFO, "file is not seekable - not parsing FooterPartition\n");
    2700           0 :             return -1;
    2701             :         }
    2702             : 
    2703             :         /* seek to FooterPartition and parse backward */
    2704          89 :         if ((ret = avio_seek(pb, mxf->run_in + mxf->footer_partition, SEEK_SET)) < 0) {
    2705           0 :             av_log(mxf->fc, AV_LOG_ERROR,
    2706             :                    "failed to seek to FooterPartition @ 0x%" PRIx64
    2707             :                    " (%"PRId64") - partial file?\n",
    2708           0 :                    mxf->run_in + mxf->footer_partition, ret);
    2709           0 :             return ret;
    2710             :         }
    2711             : 
    2712          89 :         mxf->current_partition = NULL;
    2713          89 :         mxf->parsing_backward = 1;
    2714             :     }
    2715             : 
    2716          89 :     return 1;
    2717             : }
    2718             : 
    2719             : /**
    2720             :  * Called when the next partition or EOF is encountered
    2721             :  * @return <= 0 if we should stop parsing, > 0 if we should keep going
    2722             :  */
    2723         137 : static int mxf_parse_handle_partition_or_eof(MXFContext *mxf)
    2724             : {
    2725         137 :     return mxf->parsing_backward ? mxf_seek_to_previous_partition(mxf) : 1;
    2726             : }
    2727             : 
    2728             : /**
    2729             :  * Figures out the proper offset and length of the essence container in each partition
    2730             :  */
    2731          91 : static void mxf_compute_essence_containers(MXFContext *mxf)
    2732             : {
    2733             :     int x;
    2734             : 
    2735             :     /* everything is already correct */
    2736          91 :     if (mxf->op == OPAtom)
    2737          10 :         return;
    2738             : 
    2739         275 :     for (x = 0; x < mxf->partitions_count; x++) {
    2740         197 :         MXFPartition *p = &mxf->partitions[x];
    2741             : 
    2742         197 :         if (!p->body_sid)
    2743         116 :             continue;       /* BodySID == 0 -> no essence */
    2744             : 
    2745          81 :         if (x >= mxf->partitions_count - 1)
    2746           3 :             break;          /* FooterPartition - can't compute length (and we don't need to) */
    2747             : 
    2748             :         /* essence container spans to the next partition */
    2749          78 :         p->essence_length = mxf->partitions[x+1].this_partition - p->essence_offset;
    2750             : 
    2751          78 :         if (p->essence_length < 0) {
    2752             :             /* next ThisPartition < essence_offset */
    2753           0 :             p->essence_length = 0;
    2754           0 :             av_log(mxf->fc, AV_LOG_ERROR,
    2755             :                    "partition %i: bad ThisPartition = %"PRIX64"\n",
    2756           0 :                    x+1, mxf->partitions[x+1].this_partition);
    2757             :         }
    2758             :     }
    2759             : }
    2760             : 
    2761         273 : static int64_t round_to_kag(int64_t position, int kag_size)
    2762             : {
    2763             :     /* TODO: account for run-in? the spec isn't clear whether KAG should account for it */
    2764             :     /* NOTE: kag_size may be any integer between 1 - 2^10 */
    2765         273 :     int64_t ret = (position / kag_size) * kag_size;
    2766         273 :     return ret == position ? ret : ret + kag_size;
    2767             : }
    2768             : 
    2769           8 : static int is_pcm(enum AVCodecID codec_id)
    2770             : {
    2771             :     /* we only care about "normal" PCM codecs until we get samples */
    2772           8 :     return codec_id >= AV_CODEC_ID_PCM_S16LE && codec_id < AV_CODEC_ID_PCM_S24DAUD;
    2773             : }
    2774             : 
    2775         353 : static AVStream* mxf_get_opatom_stream(MXFContext *mxf)
    2776             : {
    2777             :     int i;
    2778             : 
    2779         353 :     if (mxf->op != OPAtom)
    2780         162 :         return NULL;
    2781             : 
    2782         540 :     for (i = 0; i < mxf->fc->nb_streams; i++) {
    2783         270 :         if (mxf->fc->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_DATA)
    2784          79 :             continue;
    2785         191 :         return mxf->fc->streams[i];
    2786             :     }
    2787           0 :     return NULL;
    2788             : }
    2789             : 
    2790             : /**
    2791             :  * Deal with the case where for some audio atoms EditUnitByteCount is
    2792             :  * very small (2, 4..). In those cases we should read more than one
    2793             :  * sample per call to mxf_read_packet().
    2794             :  */
    2795          91 : static void mxf_handle_small_eubc(AVFormatContext *s)
    2796             : {
    2797          91 :     MXFContext *mxf = s->priv_data;
    2798             :     MXFTrack *track;
    2799             : 
    2800             :     /* assuming non-OPAtom == frame wrapped
    2801             :      * no sane writer would wrap 2 byte PCM packets with 20 byte headers.. */
    2802          91 :     AVStream *st = mxf_get_opatom_stream(mxf);
    2803          91 :     if (!st)
    2804          81 :         return;
    2805             : 
    2806             :     /* expect PCM with exactly one index table segment and a small (< 32) EUBC */
    2807          14 :     if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO         ||
    2808           8 :         !is_pcm(st->codecpar->codec_id)                        ||
    2809           8 :         mxf->nb_index_tables != 1                              ||
    2810           8 :         mxf->index_tables[0].nb_segments != 1                  ||
    2811           4 :         mxf->index_tables[0].segments[0]->edit_unit_byte_count >= 32)
    2812           6 :         return;
    2813             : 
    2814             :     /* arbitrarily default to 48 kHz PAL audio frame size */
    2815             :     /* TODO: We could compute this from the ratio between the audio
    2816             :      *       and video edit rates for 48 kHz NTSC we could use the
    2817             :      *       1802-1802-1802-1802-1801 pattern. */
    2818           4 :     track = st->priv_data;
    2819           4 :     mxf->edit_units_per_packet = FFMAX(1, track->edit_rate.num / track->edit_rate.den / 25);
    2820             : }
    2821             : 
    2822             : /**
    2823             :  * Deal with the case where OPAtom files does not have any IndexTableSegments.
    2824             :  */
    2825          91 : static int mxf_handle_missing_index_segment(MXFContext *mxf)
    2826             : {
    2827          91 :     AVFormatContext *s = mxf->fc;
    2828          91 :     AVStream *st = NULL;
    2829          91 :     MXFIndexTableSegment *segment = NULL;
    2830          91 :     MXFPartition *p = NULL;
    2831          91 :     int essence_partition_count = 0;
    2832             :     int i, ret;
    2833             : 
    2834          91 :     st = mxf_get_opatom_stream(mxf);
    2835          91 :     if (!st)
    2836          81 :         return 0;
    2837             : 
    2838             :     /* TODO: support raw video without an index if they exist */
    2839          10 :     if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO || !is_pcm(st->codecpar->codec_id))
    2840           6 :         return 0;
    2841             : 
    2842             :     /* check if file already has a IndexTableSegment */
    2843         114 :     for (i = 0; i < mxf->metadata_sets_count; i++) {
    2844         113 :         if (mxf->metadata_sets[i]->type == IndexTableSegment)
    2845           3 :             return 0;
    2846             :     }
    2847             : 
    2848             :     /* find the essence partition */
    2849           4 :     for (i = 0; i < mxf->partitions_count; i++) {
    2850             :         /* BodySID == 0 -> no essence */
    2851           3 :         if (!mxf->partitions[i].body_sid)
    2852           2 :             continue;
    2853             : 
    2854           1 :         p = &mxf->partitions[i];
    2855           1 :         essence_partition_count++;
    2856             :     }
    2857             : 
    2858             :     /* only handle files with a single essence partition */
    2859           1 :     if (essence_partition_count != 1)
    2860           0 :         return 0;
    2861             : 
    2862           1 :     if (!(segment = av_mallocz(sizeof(*segment))))
    2863           0 :         return AVERROR(ENOMEM);
    2864             : 
    2865           1 :     if ((ret = mxf_add_metadata_set(mxf, segment))) {
    2866           0 :         mxf_free_metadataset((MXFMetadataSet**)&segment, 1);
    2867           0 :         return ret;
    2868             :     }
    2869             : 
    2870           1 :     segment->type = IndexTableSegment;
    2871             :     /* stream will be treated as small EditUnitByteCount */
    2872           1 :     segment->edit_unit_byte_count = (av_get_bits_per_sample(st->codecpar->codec_id) * st->codecpar->channels) >> 3;
    2873           1 :     segment->index_start_position = 0;
    2874           1 :     segment->index_duration = s->streams[0]->duration;
    2875           1 :     segment->index_sid = p->index_sid;
    2876           1 :     segment->body_sid = p->body_sid;
    2877           1 :     return 0;
    2878             : }
    2879             : 
    2880          91 : static void mxf_read_random_index_pack(AVFormatContext *s)
    2881             : {
    2882          91 :     MXFContext *mxf = s->priv_data;
    2883             :     uint32_t length;
    2884             :     int64_t file_size, max_rip_length, min_rip_length;
    2885             :     KLVPacket klv;
    2886             : 
    2887          91 :     if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
    2888           0 :         return;
    2889             : 
    2890          91 :     file_size = avio_size(s->pb);
    2891             : 
    2892             :     /* S377m says to check the RIP length for "silly" values, without defining "silly".
    2893             :      * The limit below assumes a file with nothing but partition packs and a RIP.
    2894             :      * Before changing this, consider that a muxer may place each sample in its own partition.
    2895             :      *
    2896             :      * 105 is the size of the smallest possible PartitionPack
    2897             :      * 12 is the size of each RIP entry
    2898             :      * 28 is the size of the RIP header and footer, assuming an 8-byte BER
    2899             :      */
    2900          91 :     max_rip_length = ((file_size - mxf->run_in) / 105) * 12 + 28;
    2901          91 :     max_rip_length = FFMIN(max_rip_length, INT_MAX); //2 GiB and up is also silly
    2902             : 
    2903             :     /* We're only interested in RIPs with at least two entries.. */
    2904          91 :     min_rip_length = 16+1+24+4;
    2905             : 
    2906             :     /* See S377m section 11 */
    2907          91 :     avio_seek(s->pb, file_size - 4, SEEK_SET);
    2908          91 :     length = avio_rb32(s->pb);
    2909             : 
    2910         178 :     if (length < min_rip_length || length > max_rip_length)
    2911             :         goto end;
    2912          86 :     avio_seek(s->pb, file_size - length, SEEK_SET);
    2913         172 :     if (klv_read_packet(&klv, s->pb) < 0 ||
    2914         172 :         !IS_KLV_KEY(klv.key, mxf_random_index_pack_key) ||
    2915          86 :         klv.length != length - 20)
    2916             :         goto end;
    2917             : 
    2918           1 :     avio_skip(s->pb, klv.length - 12);
    2919           1 :     mxf->footer_partition = avio_rb64(s->pb);
    2920             : 
    2921             :     /* sanity check */
    2922           1 :     if (mxf->run_in + mxf->footer_partition >= file_size) {
    2923           0 :         av_log(s, AV_LOG_WARNING, "bad FooterPartition in RIP - ignoring\n");
    2924           0 :         mxf->footer_partition = 0;
    2925             :     }
    2926             : 
    2927         182 : end:
    2928          91 :     avio_seek(s->pb, mxf->run_in, SEEK_SET);
    2929             : }
    2930             : 
    2931          91 : static int mxf_read_header(AVFormatContext *s)
    2932             : {
    2933          91 :     MXFContext *mxf = s->priv_data;
    2934             :     KLVPacket klv;
    2935          91 :     int64_t essence_offset = 0;
    2936             :     int ret;
    2937             : 
    2938          91 :     mxf->last_forward_tell = INT64_MAX;
    2939          91 :     mxf->edit_units_per_packet = 1;
    2940             : 
    2941          91 :     if (!mxf_read_sync(s->pb, mxf_header_partition_pack_key, 14)) {
    2942           0 :         av_log(s, AV_LOG_ERROR, "could not find header partition pack key\n");
    2943           0 :         return AVERROR_INVALIDDATA;
    2944             :     }
    2945          91 :     avio_seek(s->pb, -14, SEEK_CUR);
    2946          91 :     mxf->fc = s;
    2947          91 :     mxf->run_in = avio_tell(s->pb);
    2948             : 
    2949          91 :     mxf_read_random_index_pack(s);
    2950             : 
    2951        7671 :     while (!avio_feof(s->pb)) {
    2952             :         const MXFMetadataReadTableEntry *metadata;
    2953             : 
    2954        7580 :         if (klv_read_packet(&klv, s->pb) < 0) {
    2955             :             /* EOF - seek to previous partition or stop */
    2956          89 :             if(mxf_parse_handle_partition_or_eof(mxf) <= 0)
    2957          89 :                 break;
    2958             :             else
    2959           0 :                 continue;
    2960             :         }
    2961             : 
    2962             :         PRINT_KEY(s, "read header", klv.key);
    2963        7491 :         av_log(s, AV_LOG_TRACE, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset);
    2964       14982 :         if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key) ||
    2965       14972 :             IS_KLV_KEY(klv.key, mxf_essence_element_key) ||
    2966       14961 :             IS_KLV_KEY(klv.key, mxf_avid_essence_element_key) ||
    2967       14881 :             IS_KLV_KEY(klv.key, mxf_system_item_key_cp) ||
    2968        7401 :             IS_KLV_KEY(klv.key, mxf_system_item_key_gc)) {
    2969             : 
    2970          91 :             if (!mxf->current_partition) {
    2971           0 :                 av_log(mxf->fc, AV_LOG_ERROR, "found essence prior to first PartitionPack\n");
    2972           0 :                 return AVERROR_INVALIDDATA;
    2973             :             }
    2974             : 
    2975          91 :             if (!mxf->current_partition->essence_offset) {
    2976             :                 /* for OP1a we compute essence_offset
    2977             :                  * for OPAtom we point essence_offset after the KL (usually op1a_essence_offset + 20 or 25)
    2978             :                  * TODO: for OP1a we could eliminate this entire if statement, always stopping parsing at op1a_essence_offset
    2979             :                  *       for OPAtom we still need the actual essence_offset though (the KL's length can vary)
    2980             :                  */
    2981          91 :                 int64_t op1a_essence_offset =
    2982         182 :                     mxf->current_partition->this_partition +
    2983         182 :                     round_to_kag(mxf->current_partition->pack_length,       mxf->current_partition->kag_size) +
    2984          91 :                     round_to_kag(mxf->current_partition->header_byte_count, mxf->current_partition->kag_size) +
    2985          91 :                     round_to_kag(mxf->current_partition->index_byte_count,  mxf->current_partition->kag_size);
    2986             : 
    2987          91 :                 if (mxf->op == OPAtom) {
    2988             :                     /* point essence_offset to the actual data
    2989             :                     * OPAtom has all the essence in one big KLV
    2990             :                     */
    2991          10 :                     mxf->current_partition->essence_offset = avio_tell(s->pb);
    2992          10 :                     mxf->current_partition->essence_length = klv.length;
    2993             :                 } else {
    2994             :                     /* NOTE: op1a_essence_offset may be less than to klv.offset (C0023S01.mxf)  */
    2995          81 :                     if (IS_KLV_KEY(klv.key, mxf_system_item_key_cp) || IS_KLV_KEY(klv.key, mxf_system_item_key_gc))
    2996          80 :                         mxf->current_partition->essence_offset = klv.offset;
    2997             :                     else
    2998           1 :                         mxf->current_partition->essence_offset = op1a_essence_offset;
    2999             :                 }
    3000             :             }
    3001             : 
    3002          91 :             if (!essence_offset)
    3003          91 :                 essence_offset = klv.offset;
    3004             : 
    3005             :             /* seek to footer, previous partition or stop */
    3006          91 :             if (mxf_parse_handle_essence(mxf) <= 0)
    3007           2 :                 break;
    3008          89 :             continue;
    3009        7400 :         } else if (mxf_is_partition_pack_key(klv.key) && mxf->current_partition) {
    3010             :             /* next partition pack - keep going, seek to previous partition or stop */
    3011          48 :             if(mxf_parse_handle_partition_or_eof(mxf) <= 0)
    3012           0 :                 break;
    3013          48 :             else if (mxf->parsing_backward)
    3014           0 :                 continue;
    3015             :             /* we're still parsing forward. proceed to parsing this partition pack */
    3016             :         }
    3017             : 
    3018      225957 :         for (metadata = mxf_metadata_read_table; metadata->read; metadata++) {
    3019      221530 :             if (IS_KLV_KEY(klv.key, metadata->key)) {
    3020        2973 :                 if ((ret = mxf_parse_klv(mxf, klv, metadata->read, metadata->ctx_size, metadata->type)) < 0)
    3021           0 :                     goto fail;
    3022        2973 :                 break;
    3023             :             }
    3024             :         }
    3025        7400 :         if (!metadata->read) {
    3026       70832 :             av_log(s, AV_LOG_VERBOSE, "Dark key " PRIxUID "\n",
    3027       70832 :                             UID_ARG(klv.key));
    3028        4427 :             avio_skip(s->pb, klv.length);
    3029             :         }
    3030             :     }
    3031             :     /* FIXME avoid seek */
    3032          91 :     if (!essence_offset)  {
    3033           0 :         av_log(s, AV_LOG_ERROR, "no essence\n");
    3034           0 :         ret = AVERROR_INVALIDDATA;
    3035           0 :         goto fail;
    3036             :     }
    3037          91 :     avio_seek(s->pb, essence_offset, SEEK_SET);
    3038             : 
    3039          91 :     mxf_compute_essence_containers(mxf);
    3040             : 
    3041             :     /* we need to do this before computing the index tables
    3042             :      * to be able to fill in zero IndexDurations with st->duration */
    3043          91 :     if ((ret = mxf_parse_structural_metadata(mxf)) < 0)
    3044           0 :         goto fail;
    3045             : 
    3046          91 :     mxf_handle_missing_index_segment(mxf);
    3047          91 :     if ((ret = mxf_compute_index_tables(mxf)) < 0)
    3048           0 :         goto fail;
    3049             : 
    3050          91 :     if (mxf->nb_index_tables > 1) {
    3051             :         /* TODO: look up which IndexSID to use via EssenceContainerData */
    3052           0 :         av_log(mxf->fc, AV_LOG_INFO, "got %i index tables - only the first one (IndexSID %i) will be used\n",
    3053           0 :                mxf->nb_index_tables, mxf->index_tables[0].index_sid);
    3054          91 :     } else if (mxf->nb_index_tables == 0 && mxf->op == OPAtom) {
    3055           0 :         av_log(mxf->fc, AV_LOG_ERROR, "cannot demux OPAtom without an index\n");
    3056           0 :         ret = AVERROR_INVALIDDATA;
    3057           0 :         goto fail;
    3058             :     }
    3059             : 
    3060          91 :     mxf_handle_small_eubc(s);
    3061             : 
    3062          91 :     return 0;
    3063           0 : fail:
    3064           0 :     mxf_read_close(s);
    3065             : 
    3066           0 :     return ret;
    3067             : }
    3068             : 
    3069         126 : static MXFIndexTable *mxf_find_index_table(MXFContext *mxf, int index_sid)
    3070             : {
    3071             :     int i;
    3072         126 :     for (i = 0; i < mxf->nb_index_tables; i++)
    3073         126 :         if (mxf->index_tables[i].index_sid == index_sid)
    3074         126 :             return &mxf->index_tables[i];
    3075           0 :     return NULL;
    3076             : }
    3077             : 
    3078             : /* Get the edit unit of the next packet from current_offset in a track. The returned edit unit can be original_duration as well! */
    3079         126 : static int mxf_get_next_track_edit_unit(MXFContext *mxf, MXFTrack *track, int64_t current_offset, int64_t *edit_unit_out)
    3080             : {
    3081             :     int64_t a, b, m, offset;
    3082         126 :     MXFIndexTable *t = mxf_find_index_table(mxf, track->index_sid);
    3083             : 
    3084         126 :     if (!t || track->original_duration <= 0)
    3085           0 :         return -1;
    3086             : 
    3087         126 :     a = -1;
    3088         126 :     b = track->original_duration;
    3089             : 
    3090         831 :     while (b - a > 1) {
    3091         579 :         m = (a + b) >> 1;
    3092         579 :         if (mxf_edit_unit_absolute_offset(mxf, t, m, NULL, &offset, 0) < 0)
    3093           0 :             return -1;
    3094         579 :         if (offset < current_offset)
    3095         254 :             a = m;
    3096             :         else
    3097         325 :             b = m;
    3098             :     }
    3099             : 
    3100         126 :     *edit_unit_out = b;
    3101             : 
    3102         126 :     return 0;
    3103             : }
    3104             : 
    3105             : /**
    3106             :  * Sets mxf->current_edit_unit based on what offset we're currently at.
    3107             :  * @return next_ofs if OK, <0 on error
    3108             :  */
    3109        4830 : static int64_t mxf_set_current_edit_unit(MXFContext *mxf, int64_t current_offset)
    3110             : {
    3111        4830 :     int64_t last_ofs = -1, next_ofs = -1;
    3112        4830 :     MXFIndexTable *t = &mxf->index_tables[0];
    3113             : 
    3114             :     /* this is called from the OP1a demuxing logic, which means there
    3115             :      * may be no index tables */
    3116        4830 :     if (mxf->nb_index_tables <= 0)
    3117           0 :         return -1;
    3118             : 
    3119             :     /* find mxf->current_edit_unit so that the next edit unit starts ahead of current_offset */
    3120       11839 :     while (mxf->current_edit_unit >= 0) {
    3121        7009 :         if (mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + 1, NULL, &next_ofs, 0) < 0)
    3122         213 :             return -2;
    3123             : 
    3124        6796 :         if (next_ofs <= last_ofs) {
    3125             :             /* large next_ofs didn't change or current_edit_unit wrapped
    3126             :              * around this fixes the infinite loop on zzuf3.mxf */
    3127           0 :             av_log(mxf->fc, AV_LOG_ERROR,
    3128             :                    "next_ofs didn't change. not deriving packet timestamps\n");
    3129           0 :             return -1;
    3130             :         }
    3131             : 
    3132        6796 :         if (next_ofs > current_offset)
    3133        4617 :             break;
    3134             : 
    3135        2179 :         last_ofs = next_ofs;
    3136        2179 :         mxf->current_edit_unit++;
    3137             :     }
    3138             : 
    3139             :     /* not checking mxf->current_edit_unit >= t->nb_ptses here since CBR files may lack IndexEntryArrays */
    3140        4617 :     if (mxf->current_edit_unit < 0)
    3141           0 :         return -1;
    3142             : 
    3143        4617 :     return next_ofs;
    3144             : }
    3145             : 
    3146          55 : static int mxf_compute_sample_count(MXFContext *mxf, int stream_index,
    3147             :                                     uint64_t *sample_count)
    3148             : {
    3149          55 :     int i, total = 0, size = 0;
    3150          55 :     AVStream *st = mxf->fc->streams[stream_index];
    3151          55 :     MXFTrack *track = st->priv_data;
    3152          55 :     AVRational time_base = av_inv_q(track->edit_rate);
    3153          55 :     AVRational sample_rate = av_inv_q(st->time_base);
    3154          55 :     const MXFSamplesPerFrame *spf = NULL;
    3155             : 
    3156          55 :     if ((sample_rate.num / sample_rate.den) == 48000)
    3157          55 :         spf = ff_mxf_get_samples_per_frame(mxf->fc, time_base);
    3158          55 :     if (!spf) {
    3159          52 :         int remainder = (sample_rate.num * time_base.num) %
    3160          26 :                         (time_base.den * sample_rate.den);
    3161          26 :         *sample_count = av_q2d(av_mul_q((AVRational){mxf->current_edit_unit, 1},
    3162             :                                         av_mul_q(sample_rate, time_base)));
    3163          26 :         if (remainder)
    3164           0 :             av_log(mxf->fc, AV_LOG_WARNING,
    3165             :                    "seeking detected on stream #%d with time base (%d/%d) and "
    3166             :                    "sample rate (%d/%d), audio pts won't be accurate.\n",
    3167             :                    stream_index, time_base.num, time_base.den,
    3168             :                    sample_rate.num, sample_rate.den);
    3169          26 :         return 0;
    3170             :     }
    3171             : 
    3172          87 :     while (spf->samples_per_frame[size]) {
    3173          29 :         total += spf->samples_per_frame[size];
    3174          29 :         size++;
    3175             :     }
    3176             : 
    3177             :     av_assert2(size);
    3178             : 
    3179          29 :     *sample_count = (mxf->current_edit_unit / size) * (uint64_t)total;
    3180          29 :     for (i = 0; i < mxf->current_edit_unit % size; i++) {
    3181           0 :         *sample_count += spf->samples_per_frame[i];
    3182             :     }
    3183             : 
    3184          29 :     return 0;
    3185             : }
    3186             : 
    3187        2438 : static int mxf_set_audio_pts(MXFContext *mxf, AVCodecParameters *par,
    3188             :                              AVPacket *pkt)
    3189             : {
    3190        2438 :     MXFTrack *track = mxf->fc->streams[pkt->stream_index]->priv_data;
    3191        2438 :     int64_t bits_per_sample = par->bits_per_coded_sample;
    3192             : 
    3193        2438 :     if (!bits_per_sample)
    3194           0 :         bits_per_sample = av_get_bits_per_sample(par->codec_id);
    3195             : 
    3196        2438 :     pkt->pts = track->sample_count;
    3197             : 
    3198        2438 :     if (   par->channels <= 0
    3199        2438 :         || bits_per_sample <= 0
    3200        2438 :         || par->channels * (int64_t)bits_per_sample < 8)
    3201           0 :         return AVERROR(EINVAL);
    3202        2438 :     track->sample_count += pkt->size / (par->channels * (int64_t)bits_per_sample / 8);
    3203        2438 :     return 0;
    3204             : }
    3205             : 
    3206        4991 : static int mxf_set_pts(MXFContext *mxf, AVStream *st, AVPacket *pkt, int64_t next_ofs)
    3207             : {
    3208        4991 :     AVCodecParameters *par = st->codecpar;
    3209        4991 :     MXFTrack *track = st->priv_data;
    3210             : 
    3211        7537 :     if (par->codec_type == AVMEDIA_TYPE_VIDEO && (next_ofs >= 0 || next_ofs == -2 && st->duration == mxf->current_edit_unit + 1)) {
    3212             :         /* mxf->current_edit_unit good - see if we have an
    3213             :          * index table to derive timestamps from */
    3214        2546 :         MXFIndexTable *t = &mxf->index_tables[0];
    3215             : 
    3216        2546 :         if (mxf->nb_index_tables >= 1 && mxf->current_edit_unit < t->nb_ptses) {
    3217        1340 :             pkt->dts = mxf->current_edit_unit + t->first_dts;
    3218        1340 :             pkt->pts = t->ptses[mxf->current_edit_unit];
    3219        1206 :         } else if (track && track->intra_only) {
    3220             :             /* intra-only -> PTS = EditUnit.
    3221             :              * let utils.c figure out DTS since it can be < PTS if low_delay = 0 (Sony IMX30) */
    3222         959 :             pkt->pts = mxf->current_edit_unit;
    3223             :         }
    3224        2445 :     } else if (par->codec_type == AVMEDIA_TYPE_AUDIO) {
    3225        2438 :         int ret = mxf_set_audio_pts(mxf, par, pkt);
    3226        2438 :         if (ret < 0)
    3227           0 :             return ret;
    3228             :     }
    3229        4991 :     return 0;
    3230             : }
    3231             : 
    3232        4940 : static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
    3233             : {
    3234             :     KLVPacket klv;
    3235        4940 :     MXFContext *mxf = s->priv_data;
    3236             :     int ret;
    3237             : 
    3238       22237 :     while ((ret = klv_read_packet(&klv, s->pb)) == 0) {
    3239             :         PRINT_KEY(s, "read packet", klv.key);
    3240       17187 :         av_log(s, AV_LOG_TRACE, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset);
    3241       17187 :         if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
    3242           0 :             ret = mxf_decrypt_triplet(s, pkt, &klv);
    3243           0 :             if (ret < 0) {
    3244           0 :                 av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");
    3245           0 :                 return ret;
    3246             :             }
    3247           0 :             return 0;
    3248             :         }
    3249       29541 :         if (IS_KLV_KEY(klv.key, mxf_essence_element_key) ||
    3250       24708 :             IS_KLV_KEY(klv.key, mxf_canopus_essence_element_key) ||
    3251       12354 :             IS_KLV_KEY(klv.key, mxf_avid_essence_element_key)) {
    3252        4833 :             int body_sid = find_body_sid_by_offset(mxf, klv.offset);
    3253        4833 :             int index = mxf_get_stream_index(s, &klv, body_sid);
    3254             :             int64_t next_ofs, next_klv;
    3255             :             AVStream *st;
    3256             : 
    3257        4833 :             if (index < 0) {
    3258           0 :                 av_log(s, AV_LOG_ERROR,
    3259             :                        "error getting stream index %"PRIu32"\n",
    3260           0 :                        AV_RB32(klv.key + 12));
    3261           0 :                 goto skip;
    3262             :             }
    3263             : 
    3264        4833 :             st = s->streams[index];
    3265             : 
    3266        4833 :             if (s->streams[index]->discard == AVDISCARD_ALL)
    3267           3 :                 goto skip;
    3268             : 
    3269        4830 :             next_klv = avio_tell(s->pb) + klv.length;
    3270        4830 :             next_ofs = mxf_set_current_edit_unit(mxf, klv.offset);
    3271             : 
    3272        4830 :             if (next_ofs >= 0 && next_klv > next_ofs) {
    3273             :                 /* if this check is hit then it's possible OPAtom was treated as OP1a
    3274             :                  * truncate the packet since it's probably very large (>2 GiB is common) */
    3275           0 :                 avpriv_request_sample(s,
    3276             :                                       "OPAtom misinterpreted as OP1a? "
    3277             :                                       "KLV for edit unit %"PRId64" extending into "
    3278             :                                       "next edit unit",
    3279             :                                       mxf->current_edit_unit);
    3280           0 :                 klv.length = next_ofs - avio_tell(s->pb);
    3281             :             }
    3282             : 
    3283             :             /* check for 8 channels AES3 element */
    3284        4830 :             if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) {
    3285         908 :                 ret = mxf_get_d10_aes3_packet(s->pb, s->streams[index],
    3286         908 :                                               pkt, klv.length);
    3287        1816 :                 if (ret < 0) {
    3288           0 :                     av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
    3289           0 :                     return ret;
    3290             :                 }
    3291             :             } else {
    3292        3922 :                 ret = av_get_packet(s->pb, pkt, klv.length);
    3293        3922 :                 if (ret < 0)
    3294           0 :                     return ret;
    3295             :             }
    3296        4830 :             pkt->stream_index = index;
    3297        4830 :             pkt->pos = klv.offset;
    3298             : 
    3299        4830 :             ret = mxf_set_pts(mxf, st, pkt, next_ofs);
    3300        4830 :             if (ret < 0)
    3301           0 :                 return ret;
    3302             : 
    3303             :             /* seek for truncated packets */
    3304        4830 :             avio_seek(s->pb, next_klv, SEEK_SET);
    3305             : 
    3306        4830 :             return 0;
    3307             :         } else
    3308       12354 :         skip:
    3309       12357 :             avio_skip(s->pb, klv.length);
    3310             :     }
    3311         110 :     return avio_feof(s->pb) ? AVERROR_EOF : ret;
    3312             : }
    3313             : 
    3314        5111 : static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
    3315             : {
    3316        5111 :     MXFContext *mxf = s->priv_data;
    3317             :     int ret, size;
    3318             :     int64_t ret64, pos, next_pos;
    3319             :     AVStream *st;
    3320             :     MXFIndexTable *t;
    3321             :     MXFTrack *track;
    3322             :     int edit_units;
    3323             : 
    3324        5111 :     if (mxf->op != OPAtom)
    3325        4940 :         return mxf_read_packet_old(s, pkt);
    3326             : 
    3327             :     // If we have no streams then we basically are at EOF
    3328         171 :     st = mxf_get_opatom_stream(mxf);
    3329         171 :     if (!st)
    3330           0 :         return AVERROR_EOF;
    3331             : 
    3332         171 :     track = st->priv_data;
    3333             : 
    3334             :     /* OPAtom - clip wrapped demuxing */
    3335             :     /* NOTE: mxf_read_header() makes sure nb_index_tables > 0 for OPAtom */
    3336         171 :     t = &mxf->index_tables[0];
    3337             : 
    3338         171 :     if (mxf->current_edit_unit >= track->original_duration)
    3339          10 :         return AVERROR_EOF;
    3340             : 
    3341         161 :     edit_units = FFMIN(mxf->edit_units_per_packet, track->original_duration - mxf->current_edit_unit);
    3342             : 
    3343         161 :     if ((ret = mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit, NULL, &pos, 1)) < 0)
    3344           0 :         return ret;
    3345             : 
    3346             :     /* compute size by finding the next edit unit or the end of the essence container
    3347             :      * not pretty, but it works */
    3348         193 :     if ((ret = mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + edit_units, NULL, &next_pos, 0)) < 0 &&
    3349          32 :         (next_pos = mxf_essence_container_end(mxf, t->body_sid)) <= 0) {
    3350           0 :         av_log(s, AV_LOG_ERROR, "unable to compute the size of the last packet\n");
    3351           0 :         return AVERROR_INVALIDDATA;
    3352             :     }
    3353             : 
    3354         161 :     if ((size = next_pos - pos) <= 0) {
    3355           0 :         av_log(s, AV_LOG_ERROR, "bad size: %i\n", size);
    3356           0 :         return AVERROR_INVALIDDATA;
    3357             :     }
    3358             : 
    3359         161 :     if ((ret64 = avio_seek(s->pb, pos, SEEK_SET)) < 0)
    3360           0 :         return ret64;
    3361             : 
    3362         161 :     if ((size = av_get_packet(s->pb, pkt, size)) < 0)
    3363           0 :         return size;
    3364             : 
    3365         161 :     pkt->stream_index = st->index;
    3366             : 
    3367         161 :     ret = mxf_set_pts(mxf, st, pkt, next_pos);
    3368         161 :     if (ret < 0)
    3369           0 :         return ret;
    3370             : 
    3371         161 :     mxf->current_edit_unit += edit_units;
    3372             : 
    3373         161 :     return 0;
    3374             : }
    3375             : 
    3376          91 : static int mxf_read_close(AVFormatContext *s)
    3377             : {
    3378          91 :     MXFContext *mxf = s->priv_data;
    3379             :     int i;
    3380             : 
    3381          91 :     av_freep(&mxf->packages_refs);
    3382          91 :     av_freep(&mxf->essence_container_data_refs);
    3383             : 
    3384         282 :     for (i = 0; i < s->nb_streams; i++)
    3385         191 :         s->streams[i]->priv_data = NULL;
    3386             : 
    3387        2474 :     for (i = 0; i < mxf->metadata_sets_count; i++) {
    3388        2383 :         mxf_free_metadataset(mxf->metadata_sets + i, 1);
    3389             :     }
    3390          91 :     av_freep(&mxf->partitions);
    3391          91 :     av_freep(&mxf->metadata_sets);
    3392          91 :     av_freep(&mxf->aesc);
    3393          91 :     av_freep(&mxf->local_tags);
    3394             : 
    3395          91 :     if (mxf->index_tables) {
    3396         182 :         for (i = 0; i < mxf->nb_index_tables; i++) {
    3397          91 :             av_freep(&mxf->index_tables[i].segments);
    3398          91 :             av_freep(&mxf->index_tables[i].ptses);
    3399          91 :             av_freep(&mxf->index_tables[i].fake_index);
    3400          91 :             av_freep(&mxf->index_tables[i].offsets);
    3401             :         }
    3402             :     }
    3403          91 :     av_freep(&mxf->index_tables);
    3404             : 
    3405          91 :     return 0;
    3406             : }
    3407             : 
    3408        6217 : static int mxf_probe(AVProbeData *p) {
    3409        6217 :     const uint8_t *bufp = p->buf;
    3410        6217 :     const uint8_t *end = p->buf + p->buf_size;
    3411             : 
    3412        6217 :     if (p->buf_size < sizeof(mxf_header_partition_pack_key))
    3413           0 :         return 0;
    3414             : 
    3415             :     /* Must skip Run-In Sequence and search for MXF header partition pack key SMPTE 377M 5.5 */
    3416        6217 :     end -= sizeof(mxf_header_partition_pack_key);
    3417             : 
    3418    13461260 :     for (; bufp < end;) {
    3419    13448917 :         if (!((bufp[13] - 1) & 0xF2)){
    3420      548413 :             if (AV_RN32(bufp   ) == AV_RN32(mxf_header_partition_pack_key   ) &&
    3421         182 :                 AV_RN32(bufp+ 4) == AV_RN32(mxf_header_partition_pack_key+ 4) &&
    3422         182 :                 AV_RN32(bufp+ 8) == AV_RN32(mxf_header_partition_pack_key+ 8) &&
    3423          91 :                 AV_RN16(bufp+12) == AV_RN16(mxf_header_partition_pack_key+12))
    3424          91 :                 return AVPROBE_SCORE_MAX;
    3425      548231 :             bufp ++;
    3426             :         } else
    3427    12900595 :             bufp += 10;
    3428             :     }
    3429             : 
    3430        6126 :     return 0;
    3431             : }
    3432             : 
    3433             : /* rudimentary byte seek */
    3434             : /* XXX: use MXF Index */
    3435         212 : static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
    3436             : {
    3437         212 :     AVStream *st = s->streams[stream_index];
    3438             :     int64_t seconds;
    3439         212 :     MXFContext* mxf = s->priv_data;
    3440             :     int64_t seekpos;
    3441             :     int i, ret;
    3442             :     MXFIndexTable *t;
    3443         212 :     MXFTrack *source_track = st->priv_data;
    3444             : 
    3445         212 :     if(st->codecpar->codec_type == AVMEDIA_TYPE_DATA)
    3446           0 :         return 0;
    3447             : 
    3448             :     /* if audio then truncate sample_time to EditRate */
    3449         212 :     if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
    3450          58 :         sample_time = av_rescale_q(sample_time, st->time_base,
    3451             :                                    av_inv_q(source_track->edit_rate));
    3452             : 
    3453         212 :     if (mxf->nb_index_tables <= 0) {
    3454           0 :         if (!s->bit_rate)
    3455           0 :             return AVERROR_INVALIDDATA;
    3456           0 :         if (sample_time < 0)
    3457           0 :             sample_time = 0;
    3458           0 :         seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den);
    3459             : 
    3460           0 :         seekpos = avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET);
    3461           0 :         if (seekpos < 0)
    3462           0 :             return seekpos;
    3463             : 
    3464           0 :         ff_update_cur_dts(s, st, sample_time);
    3465           0 :         mxf->current_edit_unit = sample_time;
    3466             :     } else {
    3467         212 :         t = &mxf->index_tables[0];
    3468         212 :         if (t->index_sid != source_track->index_sid) {
    3469             :             /* If the first index table does not belong to the stream, then find a stream which does belong to the index table */
    3470           0 :             for (i = 0; i < s->nb_streams; i++) {
    3471           0 :                 MXFTrack *new_source_track = s->streams[i]->priv_data;
    3472           0 :                 if (new_source_track && new_source_track->index_sid == t->index_sid) {
    3473           0 :                     sample_time = av_rescale_q(sample_time, new_source_track->edit_rate, source_track->edit_rate);
    3474           0 :                     source_track = new_source_track;
    3475           0 :                     st = s->streams[i];
    3476           0 :                     break;
    3477             :                 }
    3478             :             }
    3479           0 :             if (i == s->nb_streams)
    3480           0 :                 return AVERROR_INVALIDDATA;
    3481             :         }
    3482             : 
    3483             :         /* clamp above zero, else ff_index_search_timestamp() returns negative
    3484             :          * this also means we allow seeking before the start */
    3485         212 :         sample_time = FFMAX(sample_time, 0);
    3486             : 
    3487         212 :         if (t->fake_index) {
    3488             :             /* The first frames may not be keyframes in presentation order, so
    3489             :              * we have to advance the target to be able to find the first
    3490             :              * keyframe backwards... */
    3491         108 :             if (!(flags & AVSEEK_FLAG_ANY) &&
    3492          95 :                 (flags & AVSEEK_FLAG_BACKWARD) &&
    3493          82 :                 t->ptses[0] != AV_NOPTS_VALUE &&
    3494          41 :                 sample_time < t->ptses[0] &&
    3495           0 :                 (t->fake_index[t->ptses[0]].flags & AVINDEX_KEYFRAME))
    3496           0 :                 sample_time = t->ptses[0];
    3497             : 
    3498             :             /* behave as if we have a proper index */
    3499          54 :             if ((sample_time = ff_index_search_timestamp(t->fake_index, t->nb_ptses, sample_time, flags)) < 0)
    3500           5 :                 return sample_time;
    3501             :             /* get the stored order index from the display order index */
    3502          49 :             sample_time += t->offsets[sample_time];
    3503             :         } else {
    3504             :             /* no IndexEntryArray (one or more CBR segments)
    3505             :              * make sure we don't seek past the end */
    3506         158 :             sample_time = FFMIN(sample_time, source_track->original_duration - 1);
    3507             :         }
    3508             : 
    3509         207 :         if ((ret = mxf_edit_unit_absolute_offset(mxf, t, sample_time, &sample_time, &seekpos, 1)) < 0)
    3510           0 :             return ret;
    3511             : 
    3512         207 :         ff_update_cur_dts(s, st, sample_time);
    3513         207 :         mxf->current_edit_unit = sample_time;
    3514         207 :         avio_seek(s->pb, seekpos, SEEK_SET);
    3515             :     }
    3516             : 
    3517             :     // Update all tracks sample count
    3518         569 :     for (i = 0; i < s->nb_streams; i++) {
    3519         362 :         AVStream *cur_st = s->streams[i];
    3520         362 :         MXFTrack *cur_track = cur_st->priv_data;
    3521         362 :         if (cur_st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
    3522             :             int64_t track_edit_unit;
    3523         181 :             if (st != cur_st && mxf_get_next_track_edit_unit(mxf, cur_track, seekpos, &track_edit_unit) >= 0) {
    3524         126 :                 cur_track->sample_count = av_rescale_q(track_edit_unit,
    3525             :                                                        av_inv_q(cur_track->edit_rate),
    3526             :                                                        cur_st->time_base);
    3527             :             } else {
    3528          55 :                 uint64_t current_sample_count = 0;
    3529          55 :                 ret = mxf_compute_sample_count(mxf, i, &current_sample_count);
    3530          55 :                 if (ret < 0)
    3531           0 :                     return ret;
    3532          55 :                 cur_track->sample_count = current_sample_count;
    3533             :             }
    3534             :         }
    3535             :     }
    3536         207 :     return 0;
    3537             : }
    3538             : 
    3539             : AVInputFormat ff_mxf_demuxer = {
    3540             :     .name           = "mxf",
    3541             :     .long_name      = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format)"),
    3542             :     .flags          = AVFMT_SEEK_TO_PTS,
    3543             :     .priv_data_size = sizeof(MXFContext),
    3544             :     .read_probe     = mxf_probe,
    3545             :     .read_header    = mxf_read_header,
    3546             :     .read_packet    = mxf_read_packet,
    3547             :     .read_close     = mxf_read_close,
    3548             :     .read_seek      = mxf_read_seek,
    3549             : };

Generated by: LCOV version 1.13