FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/mxfdec.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 1703 2314 73.6%
Functions: 86 93 92.5%
Branches: 1002 1658 60.4%

Line Branch Exec Source
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 * SMPTE 2067-21 Interoperable Master Format — Application #2E
32 *
33 * Principle
34 * Search for Track numbers which will identify essence element KLV packets.
35 * Search for SourcePackage which define tracks which contains Track numbers.
36 * Material Package contains tracks with reference to SourcePackage tracks.
37 * Search for Descriptors (Picture, Sound) which contains codec info and parameters.
38 * Assign Descriptors to correct Tracks.
39 *
40 * Metadata reading functions read Local Tags, get InstanceUID(0x3C0A) then add MetaDataSet to MXFContext.
41 * Metadata parsing resolves Strong References to objects.
42 *
43 * Simple demuxer, only OP1A supported and some files might not work at all.
44 * Only tracks with associated descriptors will be decoded. "Highly Desirable" SMPTE 377M D.1
45 */
46
47 #include <inttypes.h>
48 #include <time.h>
49
50 #include "libavutil/aes.h"
51 #include "libavutil/avstring.h"
52 #include "libavutil/mastering_display_metadata.h"
53 #include "libavutil/mathematics.h"
54 #include "libavutil/mem.h"
55 #include "libavcodec/bytestream.h"
56 #include "libavcodec/defs.h"
57 #include "libavcodec/internal.h"
58 #include "libavutil/channel_layout.h"
59 #include "libavutil/dict_internal.h"
60 #include "libavutil/intreadwrite.h"
61 #include "libavutil/parseutils.h"
62 #include "libavutil/timecode.h"
63 #include "libavutil/opt.h"
64 #include "avformat.h"
65 #include "avlanguage.h"
66 #include "demux.h"
67 #include "internal.h"
68 #include "mxf.h"
69
70 #define MXF_MAX_CHUNK_SIZE (32 << 20)
71 #define RUN_IN_MAX (65535+1) // S377m-2004 section 5.5 and S377-1-2009 section 6.5, the +1 is to be slightly more tolerant
72
73 typedef enum {
74 Header,
75 BodyPartition,
76 Footer
77 } MXFPartitionType;
78
79 typedef enum {
80 OP1a = 1,
81 OP1b,
82 OP1c,
83 OP2a,
84 OP2b,
85 OP2c,
86 OP3a,
87 OP3b,
88 OP3c,
89 OPAtom,
90 OPSONYOpt, /* FATE sample, violates the spec in places */
91 } MXFOP;
92
93 typedef enum {
94 UnknownWrapped = 0,
95 FrameWrapped,
96 ClipWrapped,
97 } MXFWrappingScheme;
98
99 typedef struct MXFPartition {
100 int closed;
101 int complete;
102 MXFPartitionType type;
103 uint64_t previous_partition;
104 int index_sid;
105 int body_sid;
106 int64_t essence_offset; ///< absolute offset of essence
107 int64_t essence_length;
108 int32_t kag_size;
109 int64_t header_byte_count;
110 int64_t index_byte_count;
111 int pack_length;
112 int64_t pack_ofs; ///< absolute offset of pack in file, including run-in
113 int64_t body_offset;
114 KLVPacket first_essence_klv;
115 } MXFPartition;
116
117 typedef struct MXFMetadataSet {
118 UID uid;
119 uint64_t partition_score;
120 } MXFMetadataSet;
121
122 typedef struct MXFMetadataSetGroup {
123 MXFMetadataSet **metadata_sets;
124 int metadata_sets_count;
125 } MXFMetadataSetGroup;
126
127 typedef struct MXFCryptoContext {
128 MXFMetadataSet meta;
129 UID source_container_ul;
130 } MXFCryptoContext;
131
132 typedef struct MXFStructuralComponent {
133 MXFMetadataSet meta;
134 UID source_package_ul;
135 UID source_package_uid;
136 UID data_definition_ul;
137 int64_t duration;
138 int64_t start_position;
139 int source_track_id;
140 } MXFStructuralComponent;
141
142 typedef struct MXFSequence {
143 MXFMetadataSet meta;
144 UID data_definition_ul;
145 UID *structural_components_refs;
146 int structural_components_count;
147 int64_t duration;
148 uint8_t origin;
149 } MXFSequence;
150
151 typedef struct MXFTimecodeComponent {
152 MXFMetadataSet meta;
153 int drop_frame;
154 int start_frame;
155 struct AVRational rate;
156 AVTimecode tc;
157 } MXFTimecodeComponent;
158
159 typedef struct {
160 MXFMetadataSet meta;
161 UID input_segment_ref;
162 } MXFPulldownComponent;
163
164 typedef struct {
165 MXFMetadataSet meta;
166 UID *structural_components_refs;
167 int structural_components_count;
168 int64_t duration;
169 } MXFEssenceGroup;
170
171 typedef struct {
172 MXFMetadataSet meta;
173 char *name;
174 char *value;
175 } MXFTaggedValue;
176
177 typedef struct {
178 MXFMetadataSet meta;
179 MXFSequence *sequence; /* mandatory, and only one */
180 UID sequence_ref;
181 int track_id;
182 char *name;
183 uint8_t track_number[4];
184 AVRational edit_rate;
185 int intra_only;
186 uint64_t sample_count;
187 int64_t original_duration; /* st->duration in SampleRate/EditRate units */
188 int index_sid;
189 int body_sid;
190 MXFWrappingScheme wrapping;
191 int edit_units_per_packet; /* how many edit units to read at a time (PCM, ClipWrapped) */
192 } MXFTrack;
193
194 typedef struct MXFDescriptor {
195 MXFMetadataSet meta;
196 UID essence_container_ul;
197 UID essence_codec_ul;
198 UID codec_ul;
199 AVRational sample_rate;
200 AVRational aspect_ratio;
201 int width;
202 int height; /* Field height, not frame height */
203 int frame_layout; /* See MXFFrameLayout enum */
204 int video_line_map[2];
205 #define MXF_FIELD_DOMINANCE_DEFAULT 0
206 #define MXF_FIELD_DOMINANCE_FF 1 /* coded first, displayed first */
207 #define MXF_FIELD_DOMINANCE_FL 2 /* coded first, displayed last */
208 int field_dominance;
209 int channels;
210 int bits_per_sample;
211 int64_t duration; /* ContainerDuration optional property */
212 unsigned int component_depth;
213 unsigned int black_ref_level;
214 unsigned int white_ref_level;
215 unsigned int color_range;
216 unsigned int horiz_subsampling;
217 unsigned int vert_subsampling;
218 UID *file_descriptors_refs;
219 int file_descriptors_count;
220 UID *sub_descriptors_refs;
221 int sub_descriptors_count;
222 int linked_track_id;
223 uint8_t *extradata;
224 int extradata_size;
225 enum AVPixelFormat pix_fmt;
226 UID color_primaries_ul;
227 UID color_trc_ul;
228 UID color_space_ul;
229 AVMasteringDisplayMetadata *mastering;
230 size_t mastering_size;
231 AVContentLightMetadata *coll;
232 size_t coll_size;
233 } MXFDescriptor;
234
235 typedef struct MXFMCASubDescriptor {
236 MXFMetadataSet meta;
237 UID uid;
238 UID mca_link_id;
239 UID soundfield_group_link_id;
240 UID *group_of_soundfield_groups_link_id_refs;
241 int group_of_soundfield_groups_link_id_count;
242 UID mca_label_dictionary_id;
243 int mca_channel_id;
244 char *language;
245 } MXFMCASubDescriptor;
246
247 typedef struct MXFFFV1SubDescriptor {
248 MXFMetadataSet meta;
249 uint8_t *extradata;
250 int extradata_size;
251 } MXFFFV1SubDescriptor;
252
253 typedef struct MXFIndexTableSegment {
254 MXFMetadataSet meta;
255 unsigned edit_unit_byte_count;
256 int index_sid;
257 int body_sid;
258 AVRational index_edit_rate;
259 uint64_t index_start_position;
260 uint64_t index_duration;
261 int8_t *temporal_offset_entries;
262 int *flag_entries;
263 uint64_t *stream_offset_entries;
264 int nb_index_entries;
265 int64_t offset;
266 } MXFIndexTableSegment;
267
268 typedef struct MXFPackage {
269 MXFMetadataSet meta;
270 UID package_uid;
271 UID package_ul;
272 UID *tracks_refs;
273 int tracks_count;
274 UID descriptor_ref;
275 char *name;
276 UID *comment_refs;
277 int comment_count;
278 } MXFPackage;
279
280 typedef struct MXFEssenceContainerData {
281 MXFMetadataSet meta;
282 UID package_uid;
283 UID package_ul;
284 int index_sid;
285 int body_sid;
286 } MXFEssenceContainerData;
287
288 /* decoded index table */
289 typedef struct MXFIndexTable {
290 int index_sid;
291 int body_sid;
292 int nb_ptses; /* number of PTSes or total duration of index */
293 int64_t first_dts; /* DTS = EditUnit + first_dts */
294 int64_t *ptses; /* maps EditUnit -> PTS */
295 int nb_segments;
296 MXFIndexTableSegment **segments; /* sorted by IndexStartPosition */
297 AVIndexEntry *fake_index; /* used for calling ff_index_search_timestamp() */
298 int8_t *offsets; /* temporal offsets for display order to stored order conversion */
299 } MXFIndexTable;
300
301 typedef struct MXFContext {
302 const AVClass *class; /**< Class for private options. */
303 MXFPartition *partitions;
304 unsigned partitions_count;
305 MXFOP op;
306 UID *packages_refs;
307 int packages_count;
308 UID *essence_container_data_refs;
309 int essence_container_data_count;
310 MXFMetadataSetGroup metadata_set_groups[MetadataSetTypeNB];
311 AVFormatContext *fc;
312 struct AVAES *aesc;
313 uint8_t *local_tags;
314 int local_tags_count;
315 uint64_t footer_partition;
316 KLVPacket current_klv_data;
317 int run_in;
318 MXFPartition *current_partition;
319 int parsing_backward;
320 int64_t last_forward_tell;
321 int last_forward_partition;
322 int nb_index_tables;
323 MXFIndexTable *index_tables;
324 int eia608_extract;
325 } MXFContext;
326
327 /* NOTE: klv_offset is not set (-1) for local keys */
328 typedef int MXFMetadataReadFunc(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset);
329
330 typedef struct MXFMetadataReadTableEntry {
331 const UID key;
332 MXFMetadataReadFunc *read; /* if NULL then skip KLV */
333 int ctx_size;
334 enum MXFMetadataSetType type;
335 } MXFMetadataReadTableEntry;
336
337 /* partial keys to match */
338 static const uint8_t mxf_header_partition_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 };
339 static const uint8_t mxf_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 };
340 static const uint8_t mxf_avid_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0e,0x04,0x03,0x01 };
341 static const uint8_t mxf_canopus_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x0a,0x0e,0x0f,0x03,0x01 };
342 static const uint8_t mxf_system_item_key_cp[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x03,0x01,0x04 };
343 static const uint8_t mxf_system_item_key_gc[] = { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x03,0x01,0x14 };
344 static const uint8_t mxf_klv_key[] = { 0x06,0x0e,0x2b,0x34 };
345 static const uint8_t mxf_apple_coll_prefix[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01 };
346
347 /* complete keys to match */
348 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 };
349 static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
350 static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 };
351 static const uint8_t mxf_sony_mpeg4_extradata[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 };
352 static const uint8_t mxf_ffv1_extradata[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x0c,0x01,0x00,0x00,0x00 }; // FFV1InitializationMetadata
353 static const uint8_t mxf_avid_project_name[] = { 0xa5,0xfb,0x7b,0x25,0xf6,0x15,0x94,0xb9,0x62,0xfc,0x37,0x17,0x49,0x2d,0x42,0xbf };
354 static const uint8_t mxf_jp2k_rsiz[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x01,0x00,0x00,0x00 };
355 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 };
356 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 };
357 static const uint8_t mxf_apple_coll_max_cll[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x01 };
358 static const uint8_t mxf_apple_coll_max_fall[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x02 };
359
360 static const uint8_t mxf_mca_label_dictionary_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x01,0x00,0x00,0x00 };
361 static const uint8_t mxf_mca_tag_symbol[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x02,0x00,0x00,0x00 };
362 static const uint8_t mxf_mca_tag_name[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x03,0x00,0x00,0x00 };
363 static const uint8_t mxf_group_of_soundfield_groups_link_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x04,0x00,0x00,0x00 };
364 static const uint8_t mxf_mca_link_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x05,0x00,0x00,0x00 };
365 static const uint8_t mxf_mca_channel_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x04,0x0a,0x00,0x00,0x00,0x00 };
366 static const uint8_t mxf_soundfield_group_link_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x06,0x00,0x00,0x00 };
367 static const uint8_t mxf_mca_rfc5646_spoken_language[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0d,0x03,0x01,0x01,0x02,0x03,0x15,0x00,0x00 };
368
369 static const uint8_t mxf_sub_descriptor[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x04,0x06,0x10,0x00,0x00 };
370
371 static const uint8_t mxf_mastering_display_prefix[13] = { FF_MXF_MasteringDisplay_PREFIX };
372 static const uint8_t mxf_mastering_display_uls[4][16] = {
373 FF_MXF_MasteringDisplayPrimaries,
374 FF_MXF_MasteringDisplayWhitePointChromaticity,
375 FF_MXF_MasteringDisplayMaximumLuminance,
376 FF_MXF_MasteringDisplayMinimumLuminance,
377 };
378
379 #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
380
381 2953 static void mxf_free_metadataset(MXFMetadataSet **ctx, enum MXFMetadataSetType type)
382 {
383 MXFIndexTableSegment *seg;
384
9/10
✓ Branch 0 taken 323 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 692 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 225 times.
✓ Branch 6 taken 105 times.
✓ Branch 7 taken 692 times.
✓ Branch 8 taken 112 times.
✓ Branch 9 taken 801 times.
2953 switch (type) {
385 323 case Descriptor:
386 case MultipleDescriptor:
387 323 av_freep(&((MXFDescriptor *)*ctx)->extradata);
388 323 av_freep(&((MXFDescriptor *)*ctx)->mastering);
389 323 av_freep(&((MXFDescriptor *)*ctx)->coll);
390 323 av_freep(&((MXFDescriptor *)*ctx)->file_descriptors_refs);
391 323 av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs);
392 323 break;
393 1 case FFV1SubDescriptor:
394 1 av_freep(&((MXFFFV1SubDescriptor *)*ctx)->extradata);
395 1 break;
396 case AudioChannelLabelSubDescriptor:
397 case SoundfieldGroupLabelSubDescriptor:
398 case GroupOfSoundfieldGroupsLabelSubDescriptor:
399 av_freep(&((MXFMCASubDescriptor *)*ctx)->language);
400 av_freep(&((MXFMCASubDescriptor *)*ctx)->group_of_soundfield_groups_link_id_refs);
401 break;
402 692 case Sequence:
403 692 av_freep(&((MXFSequence *)*ctx)->structural_components_refs);
404 692 break;
405 2 case EssenceGroup:
406 2 av_freep(&((MXFEssenceGroup *)*ctx)->structural_components_refs);
407 2 break;
408 225 case SourcePackage:
409 case MaterialPackage:
410 225 av_freep(&((MXFPackage *)*ctx)->tracks_refs);
411 225 av_freep(&((MXFPackage *)*ctx)->name);
412 225 av_freep(&((MXFPackage *)*ctx)->comment_refs);
413 225 break;
414 105 case TaggedValue:
415 105 av_freep(&((MXFTaggedValue *)*ctx)->name);
416 105 av_freep(&((MXFTaggedValue *)*ctx)->value);
417 105 break;
418 692 case Track:
419 692 av_freep(&((MXFTrack *)*ctx)->name);
420 692 break;
421 112 case IndexTableSegment:
422 112 seg = (MXFIndexTableSegment *)*ctx;
423 112 av_freep(&seg->temporal_offset_entries);
424 112 av_freep(&seg->flag_entries);
425 112 av_freep(&seg->stream_offset_entries);
426 913 default:
427 913 break;
428 }
429 2953 av_freep(ctx);
430 2953 }
431
432 26911 static int64_t klv_decode_ber_length(AVIOContext *pb, int *llen)
433 {
434 26911 uint64_t size = avio_r8(pb);
435
2/2
✓ Branch 0 taken 24898 times.
✓ Branch 1 taken 2013 times.
26911 if (size & 0x80) { /* long form */
436 24898 int bytes_num = size & 0x7f;
437 /* SMPTE 379M 5.3.4 guarantee that bytes_num must not exceed 8 bytes */
438
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24898 times.
24898 if (bytes_num > 8)
439 return AVERROR_INVALIDDATA;
440
1/2
✓ Branch 0 taken 24898 times.
✗ Branch 1 not taken.
24898 if (llen)
441 24898 *llen = bytes_num + 1;
442 24898 size = 0;
443
2/2
✓ Branch 0 taken 98523 times.
✓ Branch 1 taken 24898 times.
123421 while (bytes_num--)
444 98523 size = size << 8 | avio_r8(pb);
445
1/2
✓ Branch 0 taken 2013 times.
✗ Branch 1 not taken.
2013 } else if (llen) {
446 2013 *llen = 1;
447 }
448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26911 times.
26911 if (size > INT64_MAX)
449 return AVERROR_INVALIDDATA;
450 26911 return size;
451 }
452
453 108 static int mxf_read_sync(AVIOContext *pb, const uint8_t *key, unsigned size)
454 {
455 int i, b;
456
3/4
✓ Branch 0 taken 1520 times.
✓ Branch 1 taken 108 times.
✓ Branch 3 taken 1520 times.
✗ Branch 4 not taken.
1628 for (i = 0; i < size && !avio_feof(pb); i++) {
457 1520 b = avio_r8(pb);
458
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 1412 times.
1520 if (b == key[0])
459 108 i = 0;
460
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1404 times.
1412 else if (b != key[i])
461 8 i = -1;
462 }
463 108 return i == size;
464 }
465
466 // special case of mxf_read_sync for mxf_klv_key
467 27045 static int mxf_read_sync_klv(AVIOContext *pb)
468 {
469 27045 uint32_t key = avio_rb32(pb);
470 // key will never match mxf_klv_key on EOF
471
2/2
✓ Branch 0 taken 26903 times.
✓ Branch 1 taken 142 times.
27045 if (key == AV_RB32(mxf_klv_key))
472 26903 return 1;
473
474
2/2
✓ Branch 1 taken 60493 times.
✓ Branch 2 taken 134 times.
60627 while (!avio_feof(pb)) {
475 60493 key = (key << 8) | avio_r8(pb);
476
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 60485 times.
60493 if (key == AV_RB32(mxf_klv_key))
477 8 return 1;
478 }
479 134 return 0;
480 }
481
482 27045 static int klv_read_packet(MXFContext *mxf, KLVPacket *klv, AVIOContext *pb)
483 {
484 int64_t length, pos;
485 int llen;
486
487
2/2
✓ Branch 1 taken 134 times.
✓ Branch 2 taken 26911 times.
27045 if (!mxf_read_sync_klv(pb))
488 134 return AVERROR_INVALIDDATA;
489 26911 klv->offset = avio_tell(pb) - 4;
490
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26911 times.
26911 if (klv->offset < mxf->run_in)
491 return AVERROR_INVALIDDATA;
492
493 26911 memcpy(klv->key, mxf_klv_key, 4);
494 26911 avio_read(pb, klv->key + 4, 12);
495 26911 length = klv_decode_ber_length(pb, &llen);
496
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26911 times.
26911 if (length < 0)
497 return length;
498 26911 klv->length = length;
499 26911 pos = klv->offset + 16 + llen;
500
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26911 times.
26911 if (pos > INT64_MAX - length)
501 return AVERROR_INVALIDDATA;
502 26911 klv->next_klv = pos + length;
503 26911 return 0;
504 }
505
506 5201 static int mxf_get_stream_index(AVFormatContext *s, KLVPacket *klv, int body_sid)
507 {
508
1/2
✓ Branch 0 taken 8408 times.
✗ Branch 1 not taken.
8408 for (int i = 0; i < s->nb_streams; i++) {
509 8408 MXFTrack *track = s->streams[i]->priv_data;
510 /* SMPTE 379M 7.3 */
511
7/10
✓ Branch 0 taken 8381 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 8381 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8381 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8381 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5201 times.
✓ Branch 9 taken 3180 times.
8408 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)))
512 5201 return i;
513 }
514 /* return 0 if only one stream, for OP Atom files with 0 as track number */
515 return s->nb_streams == 1 && s->streams[0]->priv_data ? 0 : -1;
516 }
517
518 5201 static int find_body_sid_by_absolute_offset(MXFContext *mxf, int64_t offset)
519 {
520 // we look for partition where the offset is placed
521 int a, b, m;
522 int64_t pack_ofs;
523
524 5201 a = -1;
525 5201 b = mxf->partitions_count;
526
527
2/2
✓ Branch 0 taken 10317 times.
✓ Branch 1 taken 5201 times.
15518 while (b - a > 1) {
528 10317 m = (a + b) >> 1;
529 10317 pack_ofs = mxf->partitions[m].pack_ofs;
530
2/2
✓ Branch 0 taken 5201 times.
✓ Branch 1 taken 5116 times.
10317 if (pack_ofs <= offset)
531 5201 a = m;
532 else
533 5116 b = m;
534 }
535
536
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5201 times.
5201 if (a == -1)
537 return 0;
538 5201 return mxf->partitions[a].body_sid;
539 }
540
541 static int mxf_get_eia608_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt, int64_t length)
542 {
543 int count = avio_rb16(s->pb);
544 int cdp_identifier, cdp_length, cdp_footer_id, ccdata_id, cc_count;
545 int line_num, sample_coding, sample_count;
546 int did, sdid, data_length;
547 int ret;
548
549 if (count > 1)
550 av_log(s, AV_LOG_WARNING, "unsupported multiple ANC packets (%d) per KLV packet\n", count);
551
552 for (int i = 0; i < count; i++) {
553 if (length < 6) {
554 av_log(s, AV_LOG_ERROR, "error reading s436m packet %"PRId64"\n", length);
555 return AVERROR_INVALIDDATA;
556 }
557 line_num = avio_rb16(s->pb);
558 avio_r8(s->pb); // wrapping type
559 sample_coding = avio_r8(s->pb);
560 sample_count = avio_rb16(s->pb);
561 length -= 6 + 8 + sample_count;
562 if (line_num != 9 && line_num != 11)
563 continue;
564 if (sample_coding == 7 || sample_coding == 8 || sample_coding == 9) {
565 av_log(s, AV_LOG_WARNING, "unsupported s436m 10 bit sample coding\n");
566 continue;
567 }
568 if (length < 0)
569 return AVERROR_INVALIDDATA;
570
571 avio_rb32(s->pb); // array count
572 avio_rb32(s->pb); // array elem size
573 did = avio_r8(s->pb);
574 sdid = avio_r8(s->pb);
575 data_length = avio_r8(s->pb);
576 if (did != 0x61 || sdid != 1) {
577 av_log(s, AV_LOG_WARNING, "unsupported did or sdid: %x %x\n", did, sdid);
578 continue;
579 }
580 cdp_identifier = avio_rb16(s->pb); // cdp id
581 if (cdp_identifier != 0x9669) {
582 av_log(s, AV_LOG_ERROR, "wrong cdp identifier %x\n", cdp_identifier);
583 return AVERROR_INVALIDDATA;
584 }
585 cdp_length = avio_r8(s->pb);
586 avio_r8(s->pb); // cdp_frame_rate
587 avio_r8(s->pb); // cdp_flags
588 avio_rb16(s->pb); // cdp_hdr_sequence_cntr
589 ccdata_id = avio_r8(s->pb); // ccdata_id
590 if (ccdata_id != 0x72) {
591 av_log(s, AV_LOG_ERROR, "wrong cdp data section %x\n", ccdata_id);
592 return AVERROR_INVALIDDATA;
593 }
594 cc_count = avio_r8(s->pb) & 0x1f;
595 ret = av_get_packet(s->pb, pkt, cc_count * 3);
596 if (ret < 0)
597 return ret;
598 if (cdp_length - 9 - 4 < cc_count * 3) {
599 av_log(s, AV_LOG_ERROR, "wrong cdp size %d cc count %d\n", cdp_length, cc_count);
600 return AVERROR_INVALIDDATA;
601 }
602 avio_skip(s->pb, data_length - 9 - 4 - cc_count * 3);
603 cdp_footer_id = avio_r8(s->pb);
604 if (cdp_footer_id != 0x74) {
605 av_log(s, AV_LOG_ERROR, "wrong cdp footer section %x\n", cdp_footer_id);
606 return AVERROR_INVALIDDATA;
607 }
608 avio_rb16(s->pb); // cdp_ftr_sequence_cntr
609 avio_r8(s->pb); // packet_checksum
610 break;
611 }
612
613 return 0;
614 }
615
616 /* XXX: use AVBitStreamFilter */
617 924 static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt, int64_t length)
618 {
619 const uint8_t *buf_ptr, *end_ptr;
620 uint8_t *data_ptr;
621
622
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 924 times.
924 if (length > 61444) /* worst case PAL 1920 samples 8 channels */
623 return AVERROR_INVALIDDATA;
624 924 length = av_get_packet(pb, pkt, length);
625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 924 times.
924 if (length < 0)
626 return length;
627 924 data_ptr = pkt->data;
628 924 end_ptr = pkt->data + length;
629 924 buf_ptr = pkt->data + 4; /* skip SMPTE 331M header */
630
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 924 times.
924 if (st->codecpar->ch_layout.nb_channels > 8)
632 return AVERROR_INVALIDDATA;
633
634
2/2
✓ Branch 0 taken 1774080 times.
✓ Branch 1 taken 924 times.
1775004 for (; end_ptr - buf_ptr >= st->codecpar->ch_layout.nb_channels * 4; ) {
635
2/2
✓ Branch 0 taken 3824640 times.
✓ Branch 1 taken 1774080 times.
5598720 for (int i = 0; i < st->codecpar->ch_layout.nb_channels; i++) {
636 3824640 uint32_t sample = bytestream_get_le32(&buf_ptr);
637
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3824640 times.
3824640 if (st->codecpar->bits_per_coded_sample == 24)
638 bytestream_put_le24(&data_ptr, (sample >> 4) & 0xffffff);
639 else
640 3824640 bytestream_put_le16(&data_ptr, (sample >> 12) & 0xffff);
641 }
642 // always 8 channels stored SMPTE 331M
643 1774080 buf_ptr += 32 - st->codecpar->ch_layout.nb_channels * 4;
644 }
645 924 av_shrink_packet(pkt, data_ptr - pkt->data);
646 924 return 0;
647 }
648
649 static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv)
650 {
651 static const uint8_t checkv[16] = {0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b};
652 MXFContext *mxf = s->priv_data;
653 AVIOContext *pb = s->pb;
654 int64_t end = avio_tell(pb) + klv->length;
655 int64_t size;
656 uint64_t orig_size;
657 uint64_t plaintext_size;
658 uint8_t ivec[16];
659 uint8_t tmpbuf[16];
660 int index;
661 int body_sid;
662
663 if (!mxf->aesc && s->key && s->keylen == 16) {
664 mxf->aesc = av_aes_alloc();
665 if (!mxf->aesc)
666 return AVERROR(ENOMEM);
667 av_aes_init(mxf->aesc, s->key, 128, 1);
668 }
669 // crypto context
670 size = klv_decode_ber_length(pb, NULL);
671 if (size < 0)
672 return size;
673 avio_skip(pb, size);
674 // plaintext offset
675 klv_decode_ber_length(pb ,NULL);
676 plaintext_size = avio_rb64(pb);
677 // source klv key
678 klv_decode_ber_length(pb, NULL);
679 avio_read(pb, klv->key, 16);
680 if (!IS_KLV_KEY(klv, mxf_essence_element_key))
681 return AVERROR_INVALIDDATA;
682
683 body_sid = find_body_sid_by_absolute_offset(mxf, klv->offset);
684 index = mxf_get_stream_index(s, klv, body_sid);
685 if (index < 0)
686 return AVERROR_INVALIDDATA;
687 // source size
688 klv_decode_ber_length(pb, NULL);
689 orig_size = avio_rb64(pb);
690 if (orig_size < plaintext_size)
691 return AVERROR_INVALIDDATA;
692 // enc. code
693 size = klv_decode_ber_length(pb, NULL);
694 if (size < 32 || size - 32 < orig_size || (int)orig_size != orig_size)
695 return AVERROR_INVALIDDATA;
696 avio_read(pb, ivec, 16);
697 avio_read(pb, tmpbuf, 16);
698 if (mxf->aesc)
699 av_aes_crypt(mxf->aesc, tmpbuf, tmpbuf, 1, ivec, 1);
700 if (memcmp(tmpbuf, checkv, 16))
701 av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n");
702 size -= 32;
703 size = av_get_packet(pb, pkt, size);
704 if (size < 0)
705 return size;
706 else if (size < plaintext_size)
707 return AVERROR_INVALIDDATA;
708 size -= plaintext_size;
709 if (mxf->aesc)
710 av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size],
711 &pkt->data[plaintext_size], size >> 4, ivec, 1);
712 av_shrink_packet(pkt, orig_size);
713 pkt->stream_index = index;
714 avio_skip(pb, end - avio_tell(pb));
715 return 0;
716 }
717
718 109 static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
719 {
720 109 MXFContext *mxf = arg;
721 109 int item_num = avio_rb32(pb);
722 109 int item_len = avio_rb32(pb);
723
724
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 109 times.
109 if (item_len != 18) {
725 avpriv_request_sample(pb, "Primer pack item length %d", item_len);
726 return AVERROR_PATCHWELCOME;
727 }
728
2/4
✓ Branch 0 taken 109 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 109 times.
109 if (item_num > 65536 || item_num < 0) {
729 av_log(mxf->fc, AV_LOG_ERROR, "item_num %d is too large\n", item_num);
730 return AVERROR_INVALIDDATA;
731 }
732
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 108 times.
109 if (mxf->local_tags)
733 1 av_log(mxf->fc, AV_LOG_VERBOSE, "Multiple primer packs\n");
734 109 av_free(mxf->local_tags);
735 109 mxf->local_tags_count = 0;
736 109 mxf->local_tags = av_calloc(item_num, item_len);
737
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 109 times.
109 if (!mxf->local_tags)
738 return AVERROR(ENOMEM);
739 109 mxf->local_tags_count = item_num;
740 109 avio_read(pb, mxf->local_tags, item_num*item_len);
741 109 return 0;
742 }
743
744 270 static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
745 {
746 270 MXFContext *mxf = arg;
747 270 AVFormatContext *s = mxf->fc;
748 MXFPartition *partition, *tmp_part;
749 UID op;
750 uint64_t footer_partition;
751 uint32_t nb_essence_containers;
752 uint64_t this_partition;
753
754
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 270 times.
270 if (mxf->partitions_count >= INT_MAX / 2)
755 return AVERROR_INVALIDDATA;
756
757
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 270 times.
270 av_assert0(klv_offset >= mxf->run_in);
758
759 270 tmp_part = av_realloc_array(mxf->partitions, mxf->partitions_count + 1, sizeof(*mxf->partitions));
760
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 270 times.
270 if (!tmp_part)
761 return AVERROR(ENOMEM);
762 270 mxf->partitions = tmp_part;
763
764
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 165 times.
270 if (mxf->parsing_backward) {
765 /* insert the new partition pack in the middle
766 * this makes the entries in mxf->partitions sorted by offset */
767 105 memmove(&mxf->partitions[mxf->last_forward_partition+1],
768 105 &mxf->partitions[mxf->last_forward_partition],
769 105 (mxf->partitions_count - mxf->last_forward_partition)*sizeof(*mxf->partitions));
770 105 partition = mxf->current_partition = &mxf->partitions[mxf->last_forward_partition];
771 } else {
772 165 mxf->last_forward_partition++;
773 165 partition = mxf->current_partition = &mxf->partitions[mxf->partitions_count];
774 }
775
776 270 memset(partition, 0, sizeof(*partition));
777 270 mxf->partitions_count++;
778 270 partition->pack_length = avio_tell(pb) - klv_offset + size;
779 270 partition->pack_ofs = klv_offset;
780
781
3/4
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 61 times.
✓ Branch 2 taken 101 times.
✗ Branch 3 not taken.
270 switch(uid[13]) {
782 108 case 2:
783 108 partition->type = Header;
784 108 break;
785 61 case 3:
786 61 partition->type = BodyPartition;
787 61 break;
788 101 case 4:
789 101 partition->type = Footer;
790 101 break;
791 default:
792 av_log(mxf->fc, AV_LOG_ERROR, "unknown partition type %i\n", uid[13]);
793 return AVERROR_INVALIDDATA;
794 }
795
796 /* consider both footers to be closed (there is only Footer and CompleteFooter) */
797
4/4
✓ Branch 0 taken 169 times.
✓ Branch 1 taken 101 times.
✓ Branch 2 taken 168 times.
✓ Branch 3 taken 1 times.
270 partition->closed = partition->type == Footer || !(uid[14] & 1);
798 270 partition->complete = uid[14] > 2;
799 270 avio_skip(pb, 4);
800 270 partition->kag_size = avio_rb32(pb);
801 270 this_partition = avio_rb64(pb);
802
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 270 times.
270 if (this_partition != klv_offset - mxf->run_in) {
803 av_log(mxf->fc, AV_LOG_ERROR,
804 "this_partition %"PRId64" mismatches %"PRId64"\n",
805 this_partition, klv_offset - mxf->run_in);
806 return AVERROR_INVALIDDATA;
807 }
808 270 partition->previous_partition = avio_rb64(pb);
809 270 footer_partition = avio_rb64(pb);
810 270 partition->header_byte_count = avio_rb64(pb);
811 270 partition->index_byte_count = avio_rb64(pb);
812 270 partition->index_sid = avio_rb32(pb);
813 270 partition->body_offset = avio_rb64(pb);
814 270 partition->body_sid = avio_rb32(pb);
815
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 270 times.
270 if (partition->body_offset < 0)
816 return AVERROR_INVALIDDATA;
817
818
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 270 times.
270 if (avio_read(pb, op, sizeof(UID)) != sizeof(UID)) {
819 av_log(mxf->fc, AV_LOG_ERROR, "Failed reading UID\n");
820 return AVERROR_INVALIDDATA;
821 }
822 270 nb_essence_containers = avio_rb32(pb);
823
824
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 162 times.
270 if (partition->type == Header) {
825 char str[36];
826 108 snprintf(str, sizeof(str), "%08x.%08x.%08x.%08x", AV_RB32(&op[0]), AV_RB32(&op[4]), AV_RB32(&op[8]), AV_RB32(&op[12]));
827 108 av_dict_set(&s->metadata, "operational_pattern_ul", str, 0);
828 }
829
830
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 108 times.
270 if (this_partition &&
831
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 162 times.
162 partition->previous_partition == this_partition) {
832 av_log(mxf->fc, AV_LOG_ERROR,
833 "PreviousPartition equal to ThisPartition %"PRIx64"\n",
834 partition->previous_partition);
835 /* override with the actual previous partition offset */
836 if (!mxf->parsing_backward && mxf->last_forward_partition > 1) {
837 MXFPartition *prev =
838 mxf->partitions + mxf->last_forward_partition - 2;
839 partition->previous_partition = prev->pack_ofs - mxf->run_in;
840 }
841 /* if no previous body partition are found point to the header
842 * partition */
843 if (partition->previous_partition == this_partition)
844 partition->previous_partition = 0;
845 av_log(mxf->fc, AV_LOG_ERROR,
846 "Overriding PreviousPartition with %"PRIx64"\n",
847 partition->previous_partition);
848 }
849
850 /* some files don't have FooterPartition set in every partition */
851
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 18 times.
270 if (footer_partition) {
852
3/4
✓ Branch 0 taken 248 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 248 times.
252 if (mxf->footer_partition && mxf->footer_partition != footer_partition) {
853 av_log(mxf->fc, AV_LOG_ERROR,
854 "inconsistent FooterPartition value: %"PRIu64" != %"PRIu64"\n",
855 mxf->footer_partition, footer_partition);
856 } else {
857 252 mxf->footer_partition = footer_partition;
858 }
859 }
860
861 270 av_log(mxf->fc, AV_LOG_TRACE,
862 "PartitionPack: ThisPartition = 0x%"PRIX64
863 ", PreviousPartition = 0x%"PRIX64", "
864 "FooterPartition = 0x%"PRIX64", IndexSID = %i, BodySID = %i\n",
865 this_partition,
866 partition->previous_partition, footer_partition,
867 partition->index_sid, partition->body_sid);
868
869 /* sanity check PreviousPartition if set */
870 //NOTE: this isn't actually enough, see mxf_seek_to_previous_partition()
871
2/2
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 209 times.
270 if (partition->previous_partition &&
872
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
61 mxf->run_in + partition->previous_partition >= klv_offset) {
873 av_log(mxf->fc, AV_LOG_ERROR,
874 "PreviousPartition points to this partition or forward\n");
875 return AVERROR_INVALIDDATA;
876 }
877
878
3/4
✓ Branch 0 taken 232 times.
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 232 times.
✗ Branch 3 not taken.
270 if (op[12] == 1 && op[13] == 1) mxf->op = OP1a;
879
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
38 else if (op[12] == 1 && op[13] == 2) mxf->op = OP1b;
880
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
38 else if (op[12] == 1 && op[13] == 3) mxf->op = OP1c;
881
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
38 else if (op[12] == 2 && op[13] == 1) mxf->op = OP2a;
882
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
38 else if (op[12] == 2 && op[13] == 2) mxf->op = OP2b;
883
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
38 else if (op[12] == 2 && op[13] == 3) mxf->op = OP2c;
884
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
38 else if (op[12] == 3 && op[13] == 1) mxf->op = OP3a;
885
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
38 else if (op[12] == 3 && op[13] == 2) mxf->op = OP3b;
886
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
38 else if (op[12] == 3 && op[13] == 3) mxf->op = OP3c;
887
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
38 else if (op[12] == 64&& op[13] == 1) mxf->op = OPSONYOpt;
888
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 else if (op[12] == 0x10) {
889 /* SMPTE 390m: "There shall be exactly one essence container"
890 * The following block deals with files that violate this, namely:
891 * 2011_DCPTEST_24FPS.V.mxf - two ECs, OP1a
892 * abcdefghiv016f56415e.mxf - zero ECs, OPAtom, output by Avid AirSpeed */
893
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 33 times.
36 if (nb_essence_containers != 1) {
894
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 MXFOP mxfop = nb_essence_containers ? OP1a : OPAtom;
895
896 /* only nag once */
897
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (!mxf->op)
898
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 av_log(mxf->fc, AV_LOG_WARNING,
899 "\"OPAtom\" with %"PRIu32" ECs - assuming %s\n",
900 nb_essence_containers,
901 mxfop == OP1a ? "OP1a" : "OPAtom");
902
903 3 mxf->op = mxfop;
904 } else
905 33 mxf->op = OPAtom;
906 } else {
907 av_log(mxf->fc, AV_LOG_ERROR, "unknown operational pattern: %02xh %02xh - guessing OP1a\n", op[12], op[13]);
908 mxf->op = OP1a;
909 }
910
911
3/4
✓ Branch 0 taken 268 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 268 times.
270 if (partition->kag_size <= 0 || partition->kag_size > (1 << 20)) {
912 2 av_log(mxf->fc, AV_LOG_WARNING, "invalid KAGSize %"PRId32" - guessing ",
913 partition->kag_size);
914
915
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (mxf->op == OPSONYOpt)
916 2 partition->kag_size = 512;
917 else
918 partition->kag_size = 1;
919
920 2 av_log(mxf->fc, AV_LOG_WARNING, "%"PRId32"\n", partition->kag_size);
921 }
922
923 270 return 0;
924 }
925
926 2951 static uint64_t partition_score(MXFPartition *p)
927 {
928 uint64_t score;
929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2951 times.
2951 if (!p)
930 return 0;
931
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 2822 times.
2951 if (p->type == Footer)
932 129 score = 5;
933
2/2
✓ Branch 0 taken 2597 times.
✓ Branch 1 taken 225 times.
2822 else if (p->complete)
934 2597 score = 4;
935
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 75 times.
225 else if (p->closed)
936 150 score = 3;
937 else
938 75 score = 1;
939 2951 return (score << 60) | ((uint64_t)p->pack_ofs >> 4);
940 }
941
942 2953 static int mxf_add_metadata_set(MXFContext *mxf, MXFMetadataSet **metadata_set, enum MXFMetadataSetType type)
943 {
944 2953 MXFMetadataSetGroup *mg = &mxf->metadata_set_groups[type];
945 int ret;
946
947 // Index Table is special because it might be added manually without
948 // partition and we iterate thorugh all instances of them. Also some files
949 // use the same Instance UID for different index tables...
950
2/2
✓ Branch 0 taken 2841 times.
✓ Branch 1 taken 112 times.
2953 if (type != IndexTableSegment) {
951
2/2
✓ Branch 0 taken 7752 times.
✓ Branch 1 taken 2841 times.
10593 for (int i = 0; i < mg->metadata_sets_count; i++) {
952
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 7677 times.
7752 if (!memcmp((*metadata_set)->uid, mg->metadata_sets[i]->uid, 16)) {
953 75 uint64_t old_s = mg->metadata_sets[i]->partition_score;
954 75 uint64_t new_s = (*metadata_set)->partition_score;
955
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 75 times.
75 if (old_s > new_s) {
956 mxf_free_metadataset(metadata_set, type);
957 return 0;
958 }
959 }
960 }
961 }
962
963 2953 ret = av_dynarray_add_nofree(&mg->metadata_sets, &mg->metadata_sets_count, *metadata_set);
964
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2953 times.
2953 if (ret < 0) {
965 mxf_free_metadataset(metadata_set, type);
966 return ret;
967 }
968 2953 return 0;
969 }
970
971 static int mxf_read_cryptographic_context(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
972 {
973 MXFCryptoContext *cryptocontext = arg;
974 if (size != 16)
975 return AVERROR_INVALIDDATA;
976 if (IS_KLV_KEY(uid, mxf_crypto_source_container_ul))
977 avio_read(pb, cryptocontext->source_container_ul, 16);
978 return 0;
979 }
980
981 1248 static int mxf_read_strong_ref_array(AVIOContext *pb, UID **refs, int *count)
982 {
983 int64_t ret;
984 1248 unsigned c = avio_rb32(pb);
985
986 //avio_read() used int
987
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1248 times.
1248 if (c > INT_MAX / sizeof(UID))
988 return AVERROR_PATCHWELCOME;
989 1248 *count = c;
990
991 1248 av_free(*refs);
992 1248 *refs = av_malloc_array(*count, sizeof(UID));
993
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1248 times.
1248 if (!*refs) {
994 *count = 0;
995 return AVERROR(ENOMEM);
996 }
997 1248 avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */
998 1248 ret = avio_read(pb, (uint8_t *)*refs, *count * sizeof(UID));
999
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1248 times.
1248 if (ret != *count * sizeof(UID)) {
1000 *count = ret < 0 ? 0 : ret / sizeof(UID);
1001 return ret < 0 ? ret : AVERROR_INVALIDDATA;
1002 }
1003
1004 1248 return 0;
1005 }
1006
1007 static inline int mxf_read_us_ascii_string(AVIOContext *pb, int size, char** str)
1008 {
1009 int ret;
1010 size_t buf_size;
1011
1012 if (size < 0 || size > INT_MAX - 1)
1013 return AVERROR(EINVAL);
1014
1015 buf_size = size + 1;
1016 av_free(*str);
1017 *str = av_malloc(buf_size);
1018 if (!*str)
1019 return AVERROR(ENOMEM);
1020
1021 ret = avio_get_str(pb, size, *str, buf_size);
1022
1023 if (ret < 0) {
1024 av_freep(str);
1025 return ret;
1026 }
1027
1028 return ret;
1029 }
1030
1031 635 static inline int mxf_read_utf16_string(AVIOContext *pb, int size, char** str, int be)
1032 {
1033 int ret;
1034 size_t buf_size;
1035
1036
2/4
✓ Branch 0 taken 635 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 635 times.
635 if (size < 0 || size > INT_MAX/2)
1037 return AVERROR(EINVAL);
1038
1039 635 buf_size = size + size / 2 + 1;
1040 635 av_free(*str);
1041 635 *str = av_malloc(buf_size);
1042
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 635 times.
635 if (!*str)
1043 return AVERROR(ENOMEM);
1044
1045
2/2
✓ Branch 0 taken 596 times.
✓ Branch 1 taken 39 times.
635 if (be)
1046 596 ret = avio_get_str16be(pb, size, *str, buf_size);
1047 else
1048 39 ret = avio_get_str16le(pb, size, *str, buf_size);
1049
1050
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 635 times.
635 if (ret < 0) {
1051 av_freep(str);
1052 return ret;
1053 }
1054
1055 635 return ret;
1056 }
1057
1058 #define READ_STR16(type, big_endian) \
1059 static int mxf_read_utf16 ## type ##_string(AVIOContext *pb, int size, char** str) \
1060 { \
1061 return mxf_read_utf16_string(pb, size, str, big_endian); \
1062 }
1063 596 READ_STR16(be, 1)
1064 39 READ_STR16(le, 0)
1065 #undef READ_STR16
1066
1067 327 static int mxf_read_content_storage(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1068 {
1069 327 MXFContext *mxf = arg;
1070
3/3
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 109 times.
✓ Branch 2 taken 109 times.
327 switch (tag) {
1071 109 case 0x1901:
1072
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 108 times.
109 if (mxf->packages_refs)
1073 1 av_log(mxf->fc, AV_LOG_VERBOSE, "Multiple packages_refs\n");
1074 109 return mxf_read_strong_ref_array(pb, &mxf->packages_refs, &mxf->packages_count);
1075 109 case 0x1902:
1076 109 return mxf_read_strong_ref_array(pb, &mxf->essence_container_data_refs, &mxf->essence_container_data_count);
1077 }
1078 109 return 0;
1079 }
1080
1081 2410 static int mxf_read_source_clip(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1082 {
1083 2410 MXFStructuralComponent *source_clip = arg;
1084
5/5
✓ Branch 0 taken 482 times.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 482 times.
✓ Branch 3 taken 482 times.
✓ Branch 4 taken 482 times.
2410 switch(tag) {
1085 482 case 0x0202:
1086 482 source_clip->duration = avio_rb64(pb);
1087 482 break;
1088 482 case 0x1201:
1089 482 source_clip->start_position = avio_rb64(pb);
1090 482 break;
1091 482 case 0x1101:
1092 /* UMID, only get last 16 bytes */
1093 482 avio_read(pb, source_clip->source_package_ul, 16);
1094 482 avio_read(pb, source_clip->source_package_uid, 16);
1095 482 break;
1096 482 case 0x1102:
1097 482 source_clip->source_track_id = avio_rb32(pb);
1098 482 break;
1099 }
1100 2410 return 0;
1101 }
1102
1103 1045 static int mxf_read_timecode_component(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1104 {
1105 1045 MXFTimecodeComponent *mxf_timecode = arg;
1106
4/4
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 209 times.
✓ Branch 2 taken 209 times.
✓ Branch 3 taken 418 times.
1045 switch(tag) {
1107 209 case 0x1501:
1108 209 mxf_timecode->start_frame = avio_rb64(pb);
1109 209 break;
1110 209 case 0x1502:
1111 209 mxf_timecode->rate = (AVRational){avio_rb16(pb), 1};
1112 209 break;
1113 209 case 0x1503:
1114 209 mxf_timecode->drop_frame = avio_r8(pb);
1115 209 break;
1116 }
1117 1045 return 0;
1118 }
1119
1120 6 static int mxf_read_pulldown_component(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1121 {
1122 6 MXFPulldownComponent *mxf_pulldown = arg;
1123
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 switch(tag) {
1124 1 case 0x0d01:
1125 1 avio_read(pb, mxf_pulldown->input_segment_ref, 16);
1126 1 break;
1127 }
1128 6 return 0;
1129 }
1130
1131 3504 static int mxf_read_track(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1132 {
1133 3504 MXFTrack *track = arg;
1134
6/6
✓ Branch 0 taken 692 times.
✓ Branch 1 taken 692 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 690 times.
✓ Branch 4 taken 692 times.
✓ Branch 5 taken 690 times.
3504 switch(tag) {
1135 692 case 0x4801:
1136 692 track->track_id = avio_rb32(pb);
1137 692 break;
1138 692 case 0x4804:
1139 692 avio_read(pb, track->track_number, 4);
1140 692 break;
1141 48 case 0x4802:
1142 48 mxf_read_utf16be_string(pb, size, &track->name);
1143 48 break;
1144 690 case 0x4b01:
1145 690 track->edit_rate.num = avio_rb32(pb);
1146 690 track->edit_rate.den = avio_rb32(pb);
1147 690 break;
1148 692 case 0x4803:
1149 692 avio_read(pb, track->sequence_ref, 16);
1150 692 break;
1151 }
1152 3504 return 0;
1153 }
1154
1155 2074 static int mxf_read_sequence(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1156 {
1157 2074 MXFSequence *sequence = arg;
1158
3/5
✓ Branch 0 taken 690 times.
✓ Branch 1 taken 692 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 692 times.
✗ Branch 4 not taken.
2074 switch(tag) {
1159 690 case 0x0202:
1160 690 sequence->duration = avio_rb64(pb);
1161 690 break;
1162 692 case 0x0201:
1163 692 avio_read(pb, sequence->data_definition_ul, 16);
1164 692 break;
1165 case 0x4b02:
1166 sequence->origin = avio_r8(pb);
1167 break;
1168 692 case 0x1001:
1169 692 return mxf_read_strong_ref_array(pb, &sequence->structural_components_refs,
1170 &sequence->structural_components_count);
1171 }
1172 1382 return 0;
1173 }
1174
1175 8 static int mxf_read_essence_group(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1176 {
1177 8 MXFEssenceGroup *essence_group = arg;
1178
3/3
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
8 switch (tag) {
1179 2 case 0x0202:
1180 2 essence_group->duration = avio_rb64(pb);
1181 2 break;
1182 2 case 0x0501:
1183 2 return mxf_read_strong_ref_array(pb, &essence_group->structural_components_refs,
1184 &essence_group->structural_components_count);
1185 }
1186 6 return 0;
1187 }
1188
1189 1077 static int mxf_read_package(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1190 {
1191 1077 MXFPackage *package = arg;
1192
6/6
✓ Branch 0 taken 225 times.
✓ Branch 1 taken 225 times.
✓ Branch 2 taken 116 times.
✓ Branch 3 taken 25 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 476 times.
1077 switch(tag) {
1193 225 case 0x4403:
1194 225 return mxf_read_strong_ref_array(pb, &package->tracks_refs,
1195 &package->tracks_count);
1196 225 case 0x4401:
1197 /* UMID */
1198 225 avio_read(pb, package->package_ul, 16);
1199 225 avio_read(pb, package->package_uid, 16);
1200 225 break;
1201 116 case 0x4701:
1202 116 avio_read(pb, package->descriptor_ref, 16);
1203 116 break;
1204 25 case 0x4402:
1205 25 return mxf_read_utf16be_string(pb, size, &package->name);
1206 10 case 0x4406:
1207 10 return mxf_read_strong_ref_array(pb, &package->comment_refs,
1208 &package->comment_count);
1209 }
1210 817 return 0;
1211 }
1212
1213 331 static int mxf_read_essence_container_data(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1214 {
1215 331 MXFEssenceContainerData *essence_data = arg;
1216
4/4
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 107 times.
✓ Branch 2 taken 109 times.
✓ Branch 3 taken 6 times.
331 switch(tag) {
1217 109 case 0x2701:
1218 /* linked package umid UMID */
1219 109 avio_read(pb, essence_data->package_ul, 16);
1220 109 avio_read(pb, essence_data->package_uid, 16);
1221 109 break;
1222 107 case 0x3f06:
1223 107 essence_data->index_sid = avio_rb32(pb);
1224 107 break;
1225 109 case 0x3f07:
1226 109 essence_data->body_sid = avio_rb32(pb);
1227 109 break;
1228 }
1229 331 return 0;
1230 }
1231
1232 57 static int mxf_read_index_entry_array(AVIOContext *pb, MXFIndexTableSegment *segment)
1233 {
1234 int i, length;
1235 uint32_t nb_index_entries;
1236
1237
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if (segment->temporal_offset_entries)
1238 return AVERROR_INVALIDDATA;
1239
1240 57 nb_index_entries = avio_rb32(pb);
1241
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if (nb_index_entries > INT_MAX)
1242 return AVERROR_INVALIDDATA;
1243 57 segment->nb_index_entries = nb_index_entries;
1244
1245 57 length = avio_rb32(pb);
1246
3/4
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 54 times.
57 if(segment->nb_index_entries && length < 11)
1247 return AVERROR_INVALIDDATA;
1248
1249
1/2
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
57 if (!FF_ALLOC_TYPED_ARRAY(segment->temporal_offset_entries, segment->nb_index_entries) ||
1250
1/2
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
57 !FF_ALLOC_TYPED_ARRAY(segment->flag_entries , segment->nb_index_entries) ||
1251
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 57 times.
57 !FF_ALLOC_TYPED_ARRAY(segment->stream_offset_entries , segment->nb_index_entries)) {
1252 av_freep(&segment->temporal_offset_entries);
1253 av_freep(&segment->flag_entries);
1254 return AVERROR(ENOMEM);
1255 }
1256
1257
2/2
✓ Branch 0 taken 1393 times.
✓ Branch 1 taken 57 times.
1450 for (i = 0; i < segment->nb_index_entries; i++) {
1258
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1393 times.
1393 if(avio_feof(pb))
1259 return AVERROR_INVALIDDATA;
1260 1393 segment->temporal_offset_entries[i] = avio_r8(pb);
1261 1393 avio_r8(pb); /* KeyFrameOffset */
1262 1393 segment->flag_entries[i] = avio_r8(pb);
1263 1393 segment->stream_offset_entries[i] = avio_rb64(pb);
1264 1393 avio_skip(pb, length - 11);
1265 }
1266 57 return 0;
1267 }
1268
1269 923 static int mxf_read_index_table_segment(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1270 {
1271 923 MXFIndexTableSegment *segment = arg;
1272
8/8
✓ Branch 0 taken 110 times.
✓ Branch 1 taken 110 times.
✓ Branch 2 taken 110 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 110 times.
✓ Branch 5 taken 110 times.
✓ Branch 6 taken 110 times.
✓ Branch 7 taken 206 times.
923 switch(tag) {
1273 110 case 0x3F05:
1274 110 segment->edit_unit_byte_count = avio_rb32(pb);
1275 110 av_log(NULL, AV_LOG_TRACE, "EditUnitByteCount %d\n", segment->edit_unit_byte_count);
1276 110 break;
1277 110 case 0x3F06:
1278 110 segment->index_sid = avio_rb32(pb);
1279 110 av_log(NULL, AV_LOG_TRACE, "IndexSID %d\n", segment->index_sid);
1280 110 break;
1281 110 case 0x3F07:
1282 110 segment->body_sid = avio_rb32(pb);
1283 110 av_log(NULL, AV_LOG_TRACE, "BodySID %d\n", segment->body_sid);
1284 110 break;
1285 57 case 0x3F0A:
1286 57 av_log(NULL, AV_LOG_TRACE, "IndexEntryArray found\n");
1287 57 return mxf_read_index_entry_array(pb, segment);
1288 110 case 0x3F0B:
1289 110 segment->index_edit_rate.num = avio_rb32(pb);
1290 110 segment->index_edit_rate.den = avio_rb32(pb);
1291
1/2
✓ Branch 0 taken 110 times.
✗ Branch 1 not taken.
110 if (segment->index_edit_rate.num <= 0 ||
1292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 110 times.
110 segment->index_edit_rate.den <= 0)
1293 return AVERROR_INVALIDDATA;
1294 110 av_log(NULL, AV_LOG_TRACE, "IndexEditRate %d/%d\n", segment->index_edit_rate.num,
1295 segment->index_edit_rate.den);
1296 110 break;
1297 110 case 0x3F0C:
1298 110 segment->index_start_position = avio_rb64(pb);
1299 110 av_log(NULL, AV_LOG_TRACE, "IndexStartPosition %"PRId64"\n", segment->index_start_position);
1300 110 break;
1301 110 case 0x3F0D:
1302 110 segment->index_duration = avio_rb64(pb);
1303 110 av_log(NULL, AV_LOG_TRACE, "IndexDuration %"PRId64"\n", segment->index_duration);
1304 110 break;
1305 }
1306 866 return 0;
1307 }
1308
1309 2 static void mxf_read_pixel_layout(AVIOContext *pb, MXFDescriptor *descriptor)
1310 {
1311 2 int code, value, ofs = 0;
1312 2 char layout[16] = {0}; /* not for printing, may end up not terminated on purpose */
1313
1314 do {
1315 6 code = avio_r8(pb);
1316 6 value = avio_r8(pb);
1317 6 av_log(NULL, AV_LOG_TRACE, "pixel layout: code %#x\n", code);
1318
1319
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (ofs <= 14) {
1320 6 layout[ofs++] = code;
1321 6 layout[ofs++] = value;
1322 } else
1323 break; /* don't read byte by byte on sneaky files filled with lots of non-zeroes */
1324
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 } while (code != 0); /* SMPTE 377M E.2.46 */
1325
1326 2 ff_mxf_decode_pixel_layout(layout, &descriptor->pix_fmt);
1327 2 }
1328
1329 4664 static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1330 {
1331 4664 MXFDescriptor *descriptor = arg;
1332 int entry_count, entry_size;
1333
1334
27/27
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 323 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 223 times.
✓ Branch 5 taken 103 times.
✓ Branch 6 taken 104 times.
✓ Branch 7 taken 104 times.
✓ Branch 8 taken 104 times.
✓ Branch 9 taken 103 times.
✓ Branch 10 taken 104 times.
✓ Branch 11 taken 23 times.
✓ Branch 12 taken 45 times.
✓ Branch 13 taken 9 times.
✓ Branch 14 taken 8 times.
✓ Branch 15 taken 101 times.
✓ Branch 16 taken 101 times.
✓ Branch 17 taken 100 times.
✓ Branch 18 taken 100 times.
✓ Branch 19 taken 100 times.
✓ Branch 20 taken 100 times.
✓ Branch 21 taken 125 times.
✓ Branch 22 taken 14 times.
✓ Branch 23 taken 125 times.
✓ Branch 24 taken 125 times.
✓ Branch 25 taken 2 times.
✓ Branch 26 taken 2298 times.
4664 switch(tag) {
1335 93 case 0x3F01:
1336 93 return mxf_read_strong_ref_array(pb, &descriptor->file_descriptors_refs,
1337 &descriptor->file_descriptors_count);
1338 21 case 0x3002: /* ContainerDuration */
1339 21 descriptor->duration = avio_rb64(pb);
1340 21 break;
1341 323 case 0x3004:
1342 323 avio_read(pb, descriptor->essence_container_ul, 16);
1343 323 break;
1344 6 case 0x3005:
1345 6 avio_read(pb, descriptor->codec_ul, 16);
1346 6 break;
1347 223 case 0x3006:
1348 223 descriptor->linked_track_id = avio_rb32(pb);
1349 223 break;
1350 103 case 0x3201: /* PictureEssenceCoding */
1351 103 avio_read(pb, descriptor->essence_codec_ul, 16);
1352 103 break;
1353 104 case 0x3203:
1354 104 descriptor->width = avio_rb32(pb);
1355 104 break;
1356 104 case 0x3202:
1357 104 descriptor->height = avio_rb32(pb);
1358 104 break;
1359 104 case 0x320C:
1360 104 descriptor->frame_layout = avio_r8(pb);
1361 104 break;
1362 103 case 0x320D:
1363 103 entry_count = avio_rb32(pb);
1364 103 entry_size = avio_rb32(pb);
1365
1/2
✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
103 if (entry_size == 4) {
1366
1/2
✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
103 if (entry_count > 0)
1367 103 descriptor->video_line_map[0] = avio_rb32(pb);
1368 else
1369 descriptor->video_line_map[0] = 0;
1370
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 3 times.
103 if (entry_count > 1)
1371 100 descriptor->video_line_map[1] = avio_rb32(pb);
1372 else
1373 3 descriptor->video_line_map[1] = 0;
1374 } else
1375 av_log(NULL, AV_LOG_WARNING, "VideoLineMap element size %d currently not supported\n", entry_size);
1376 103 break;
1377 104 case 0x320E:
1378 104 descriptor->aspect_ratio.num = avio_rb32(pb);
1379 104 descriptor->aspect_ratio.den = avio_rb32(pb);
1380 104 break;
1381 23 case 0x3210:
1382 23 avio_read(pb, descriptor->color_trc_ul, 16);
1383 23 break;
1384 45 case 0x3212:
1385 45 descriptor->field_dominance = avio_r8(pb);
1386 45 break;
1387 9 case 0x3219:
1388 9 avio_read(pb, descriptor->color_primaries_ul, 16);
1389 9 break;
1390 8 case 0x321A:
1391 8 avio_read(pb, descriptor->color_space_ul, 16);
1392 8 break;
1393 101 case 0x3301:
1394 101 descriptor->component_depth = avio_rb32(pb);
1395 101 break;
1396 101 case 0x3302:
1397 101 descriptor->horiz_subsampling = avio_rb32(pb);
1398 101 break;
1399 100 case 0x3304:
1400 100 descriptor->black_ref_level = avio_rb32(pb);
1401 100 break;
1402 100 case 0x3305:
1403 100 descriptor->white_ref_level = avio_rb32(pb);
1404 100 break;
1405 100 case 0x3306:
1406 100 descriptor->color_range = avio_rb32(pb);
1407 100 break;
1408 100 case 0x3308:
1409 100 descriptor->vert_subsampling = avio_rb32(pb);
1410 100 break;
1411 125 case 0x3D03:
1412 125 descriptor->sample_rate.num = avio_rb32(pb);
1413 125 descriptor->sample_rate.den = avio_rb32(pb);
1414 125 break;
1415 14 case 0x3D06: /* SoundEssenceCompression */
1416 14 avio_read(pb, descriptor->essence_codec_ul, 16);
1417 14 break;
1418 125 case 0x3D07:
1419 125 descriptor->channels = avio_rb32(pb);
1420 125 break;
1421 125 case 0x3D01:
1422 125 descriptor->bits_per_sample = avio_rb32(pb);
1423 125 break;
1424 2 case 0x3401:
1425 2 mxf_read_pixel_layout(pb, descriptor);
1426 2 break;
1427 2298 default:
1428 /* Private uid used by SONY C0023S01.mxf */
1429
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2297 times.
2298 if (IS_KLV_KEY(uid, mxf_sony_mpeg4_extradata)) {
1430
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (descriptor->extradata)
1431 av_log(NULL, AV_LOG_WARNING, "Duplicate sony_mpeg4_extradata\n");
1432 1 av_free(descriptor->extradata);
1433 1 descriptor->extradata_size = 0;
1434 1 descriptor->extradata = av_malloc(size);
1435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!descriptor->extradata)
1436 return AVERROR(ENOMEM);
1437 1 descriptor->extradata_size = size;
1438 1 avio_read(pb, descriptor->extradata, size);
1439 }
1440
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2298 times.
2298 if (IS_KLV_KEY(uid, mxf_jp2k_rsiz)) {
1441 uint32_t rsiz = avio_rb16(pb);
1442 if (rsiz == AV_PROFILE_JPEG2000_DCINEMA_2K ||
1443 rsiz == AV_PROFILE_JPEG2000_DCINEMA_4K)
1444 descriptor->pix_fmt = AV_PIX_FMT_XYZ12;
1445 }
1446
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 2278 times.
2298 if (IS_KLV_KEY(uid, mxf_mastering_display_prefix)) {
1447
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
20 if (!descriptor->mastering) {
1448 5 descriptor->mastering = av_mastering_display_metadata_alloc_size(&descriptor->mastering_size);
1449
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!descriptor->mastering)
1450 return AVERROR(ENOMEM);
1451 }
1452
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
20 if (IS_KLV_KEY(uid, mxf_mastering_display_uls[0])) {
1453
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 5 times.
20 for (int i = 0; i < 3; i++) {
1454 /* Order: large x, large y, other (i.e. RGB) */
1455 15 descriptor->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
1456 15 descriptor->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
1457 }
1458 /* Check we have seen mxf_mastering_display_white_point_chromaticity */
1459
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (descriptor->mastering->white_point[0].den != 0)
1460 5 descriptor->mastering->has_primaries = 1;
1461 }
1462
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
20 if (IS_KLV_KEY(uid, mxf_mastering_display_uls[1])) {
1463 5 descriptor->mastering->white_point[0] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
1464 5 descriptor->mastering->white_point[1] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
1465 /* Check we have seen mxf_mastering_display_primaries */
1466
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (descriptor->mastering->display_primaries[0][0].den != 0)
1467 5 descriptor->mastering->has_primaries = 1;
1468 }
1469
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
20 if (IS_KLV_KEY(uid, mxf_mastering_display_uls[2])) {
1470 5 descriptor->mastering->max_luminance = av_make_q(avio_rb32(pb), FF_MXF_MASTERING_LUMA_DEN);
1471 /* Check we have seen mxf_mastering_display_minimum_luminance */
1472
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (descriptor->mastering->min_luminance.den != 0)
1473 5 descriptor->mastering->has_luminance = 1;
1474 }
1475
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
20 if (IS_KLV_KEY(uid, mxf_mastering_display_uls[3])) {
1476 5 descriptor->mastering->min_luminance = av_make_q(avio_rb32(pb), FF_MXF_MASTERING_LUMA_DEN);
1477 /* Check we have seen mxf_mastering_display_maximum_luminance */
1478
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (descriptor->mastering->max_luminance.den != 0)
1479 5 descriptor->mastering->has_luminance = 1;
1480 }
1481 }
1482
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2292 times.
2298 if (IS_KLV_KEY(uid, mxf_apple_coll_prefix)) {
1483
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (!descriptor->coll) {
1484 3 descriptor->coll = av_content_light_metadata_alloc(&descriptor->coll_size);
1485
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!descriptor->coll)
1486 return AVERROR(ENOMEM);
1487 }
1488
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (IS_KLV_KEY(uid, mxf_apple_coll_max_cll)) {
1489 3 descriptor->coll->MaxCLL = avio_rb16(pb);
1490 }
1491
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (IS_KLV_KEY(uid, mxf_apple_coll_max_fall)) {
1492 3 descriptor->coll->MaxFALL = avio_rb16(pb);
1493 }
1494 }
1495
1496
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2290 times.
2298 if (IS_KLV_KEY(uid, mxf_sub_descriptor))
1497 8 return mxf_read_strong_ref_array(pb, &descriptor->sub_descriptors_refs, &descriptor->sub_descriptors_count);
1498
1499 2290 break;
1500 }
1501 4563 return 0;
1502 }
1503
1504 static int mxf_read_mca_sub_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1505 {
1506 MXFMCASubDescriptor *mca_sub_descriptor = arg;
1507
1508 if (IS_KLV_KEY(uid, mxf_mca_label_dictionary_id))
1509 avio_read(pb, mca_sub_descriptor->mca_label_dictionary_id, 16);
1510
1511 if (IS_KLV_KEY(uid, mxf_mca_link_id))
1512 avio_read(pb, mca_sub_descriptor->mca_link_id, 16);
1513
1514 if (IS_KLV_KEY(uid, mxf_soundfield_group_link_id))
1515 avio_read(pb, mca_sub_descriptor->soundfield_group_link_id, 16);
1516
1517 if (IS_KLV_KEY(uid, mxf_group_of_soundfield_groups_link_id))
1518 return mxf_read_strong_ref_array(pb, &mca_sub_descriptor->group_of_soundfield_groups_link_id_refs, &mca_sub_descriptor->group_of_soundfield_groups_link_id_count);
1519
1520 if (IS_KLV_KEY(uid, mxf_mca_channel_id))
1521 mca_sub_descriptor->mca_channel_id = avio_rb32(pb);
1522
1523 if (IS_KLV_KEY(uid, mxf_mca_rfc5646_spoken_language))
1524 return mxf_read_us_ascii_string(pb, size, &mca_sub_descriptor->language);
1525
1526 return 0;
1527 }
1528
1529 3 static int mxf_read_ffv1_sub_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1530 {
1531 3 MXFFFV1SubDescriptor *ffv1_sub_descriptor = arg;
1532
1533
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
3 if (IS_KLV_KEY(uid, mxf_ffv1_extradata) && size <= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE ) {
1534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ffv1_sub_descriptor->extradata)
1535 av_log(NULL, AV_LOG_WARNING, "Duplicate ffv1_extradata\n");
1536 1 av_free(ffv1_sub_descriptor->extradata);
1537 1 ffv1_sub_descriptor->extradata_size = 0;
1538 1 ffv1_sub_descriptor->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
1539
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!ffv1_sub_descriptor->extradata)
1540 return AVERROR(ENOMEM);
1541 1 ffv1_sub_descriptor->extradata_size = size;
1542 1 avio_read(pb, ffv1_sub_descriptor->extradata, size);
1543 }
1544
1545 3 return 0;
1546 }
1547
1548 105 static int mxf_read_indirect_value(void *arg, AVIOContext *pb, int size)
1549 {
1550 105 MXFTaggedValue *tagged_value = arg;
1551 uint8_t key[17];
1552
1553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 105 times.
105 if (size <= 17)
1554 return 0;
1555
1556 105 avio_read(pb, key, 17);
1557 /* TODO: handle other types of of indirect values */
1558
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 66 times.
105 if (memcmp(key, mxf_indirect_value_utf16le, 17) == 0) {
1559 39 return mxf_read_utf16le_string(pb, size - 17, &tagged_value->value);
1560
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 } else if (memcmp(key, mxf_indirect_value_utf16be, 17) == 0) {
1561 return mxf_read_utf16be_string(pb, size - 17, &tagged_value->value);
1562 }
1563 66 return 0;
1564 }
1565
1566 232 static int mxf_read_tagged_value(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1567 {
1568 232 MXFTaggedValue *tagged_value = arg;
1569
3/3
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 22 times.
232 switch (tag){
1570 105 case 0x5001:
1571 105 return mxf_read_utf16be_string(pb, size, &tagged_value->name);
1572 105 case 0x5003:
1573 105 return mxf_read_indirect_value(tagged_value, pb, size);
1574 }
1575 22 return 0;
1576 }
1577
1578 /*
1579 * Match an uid independently of the version byte and up to len common bytes
1580 * Returns: boolean
1581 */
1582 44062 static int mxf_match_uid(const UID key, const uint8_t uid_prefix[], int len)
1583 {
1584 int i;
1585
2/2
✓ Branch 0 taken 237788 times.
✓ Branch 1 taken 851 times.
238639 for (i = 0; i < len; i++) {
1586
4/4
✓ Branch 0 taken 231855 times.
✓ Branch 1 taken 5933 times.
✓ Branch 2 taken 43211 times.
✓ Branch 3 taken 188644 times.
237788 if (i != 7 && key[i] != uid_prefix[i])
1587 43211 return 0;
1588 }
1589 851 return 1;
1590 }
1591
1592 1548 static const MXFCodecUL *mxf_get_codec_ul(const MXFCodecUL *uls, UID *uid)
1593 {
1594
2/2
✓ Branch 0 taken 17248 times.
✓ Branch 1 taken 699 times.
17947 while (uls->uid[0]) {
1595
2/2
✓ Branch 1 taken 849 times.
✓ Branch 2 taken 16399 times.
17248 if(mxf_match_uid(uls->uid, *uid, uls->matching_len))
1596 849 break;
1597 16399 uls++;
1598 }
1599 1548 return uls;
1600 }
1601
1602 5187 static void *mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMetadataSetType type)
1603 {
1604 5187 MXFMetadataSetGroup *mg = &mxf->metadata_set_groups[type];
1605
1606
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5187 times.
5187 if (!strong_ref)
1607 return NULL;
1608
2/2
✓ Branch 0 taken 13157 times.
✓ Branch 1 taken 1675 times.
14832 for (int i = mg->metadata_sets_count - 1; i >= 0; i--)
1609
2/2
✓ Branch 0 taken 3512 times.
✓ Branch 1 taken 9645 times.
13157 if (!memcmp(*strong_ref, mg->metadata_sets[i]->uid, 16))
1610 3512 return mg->metadata_sets[i];
1611
1612 1675 return NULL;
1613 }
1614
1615 static const MXFCodecUL mxf_picture_essence_container_uls[] = {
1616 // video essence container uls
1617 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0c,0x01,0x00 }, 14, AV_CODEC_ID_JPEG2000, NULL, 14, J2KWrap },
1618 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x10,0x60,0x01 }, 14, AV_CODEC_ID_H264, NULL, 15 }, /* H.264 */
1619 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, 14, AV_CODEC_ID_DNXHD, NULL, 14 }, /* VC-3 */
1620 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x0d,0x01,0x03,0x01,0x02,0x1e,0x01,0x00 }, 14, AV_CODEC_ID_DNXUC, NULL, 14 }, /* DNxUncompressed / SMPTE RDD 50 */
1621 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x12,0x01,0x00 }, 14, AV_CODEC_ID_VC1, NULL, 14 }, /* VC-1 */
1622 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x14,0x01,0x00 }, 14, AV_CODEC_ID_TIFF, NULL, 14 }, /* TIFF */
1623 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x15,0x01,0x00 }, 14, AV_CODEC_ID_DIRAC, NULL, 14 }, /* VC-2 */
1624 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x1b,0x01,0x00 }, 14, AV_CODEC_ID_CFHD, NULL, 14 }, /* VC-5 */
1625 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x1c,0x01,0x00 }, 14, AV_CODEC_ID_PRORES, NULL, 14 }, /* ProRes */
1626 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO, NULL, 15 }, /* MPEG-ES */
1627 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x04,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO, NULL, 15, D10D11Wrap }, /* SMPTE D-10 mapping */
1628 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x0d,0x01,0x03,0x01,0x02,0x23,0x01,0x00 }, 14, AV_CODEC_ID_FFV1, NULL, 14 },
1629 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14, AV_CODEC_ID_DVVIDEO, NULL, 15 }, /* DV 625 25mbps */
1630 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x05,0x00,0x00 }, 14, AV_CODEC_ID_RAWVIDEO, NULL, 15, RawVWrap }, /* uncompressed picture */
1631 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0a,0x0e,0x0f,0x03,0x01,0x02,0x20,0x01,0x01 }, 15, AV_CODEC_ID_HQ_HQA },
1632 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0a,0x0e,0x0f,0x03,0x01,0x02,0x20,0x02,0x01 }, 15, AV_CODEC_ID_HQX },
1633 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0a,0x0e,0x15,0x00,0x04,0x02,0x10,0x00,0x01 }, 16, AV_CODEC_ID_HEVC, NULL, 15 }, /* Canon XF-HEVC */
1634 { { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0xff,0x4b,0x46,0x41,0x41,0x00,0x0d,0x4d,0x4f }, 14, AV_CODEC_ID_RAWVIDEO }, /* Legacy ?? Uncompressed Picture */
1635 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
1636 };
1637
1638 /* EC ULs for intra-only formats */
1639 static const MXFCodecUL mxf_intra_only_essence_container_uls[] = {
1640 { { 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 */
1641 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
1642 };
1643
1644 /* intra-only PictureEssenceCoding ULs, where no corresponding EC UL exists */
1645 static const MXFCodecUL mxf_intra_only_picture_essence_coding_uls[] = {
1646 { { 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 */
1647 { { 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 */
1648 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
1649 };
1650
1651 /* actual coded width for AVC-Intra to allow selecting correct SPS/PPS */
1652 static const MXFCodecUL mxf_intra_only_picture_coded_width[] = {
1653 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x01 }, 16, 1440 },
1654 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x02 }, 16, 1440 },
1655 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x03 }, 16, 1440 },
1656 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x04 }, 16, 1440 },
1657 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, 0 },
1658 };
1659
1660 static const MXFCodecUL mxf_sound_essence_container_uls[] = {
1661 // sound essence container uls
1662 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, 14, AV_CODEC_ID_PCM_S16LE, NULL, 14, RawAWrap }, /* BWF */
1663 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x40,0x01 }, 14, AV_CODEC_ID_MP2, NULL, 15 }, /* MPEG-ES */
1664 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, 14, AV_CODEC_ID_PCM_S16LE, NULL, 13 }, /* D-10 Mapping 50Mbps PAL Extended Template */
1665 { { 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 */
1666 { { 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) */
1667 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x0d,0x01,0x03,0x01,0x02,0x16,0x00,0x00 }, 14, AV_CODEC_ID_AAC, NULL, 14 }, /* AAC ADIF (SMPTE 381-4) */
1668 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x0d,0x01,0x03,0x01,0x02,0x17,0x00,0x00 }, 14, AV_CODEC_ID_AAC, NULL, 14 }, /* AAC ADTS (SMPTE 381-4) */
1669 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x0d,0x01,0x03,0x01,0x02,0x18,0x00,0x00 }, 14, AV_CODEC_ID_AAC, NULL, 14 }, /* AAC LATM/LOAS (SMPTE 381-4) */
1670 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
1671 };
1672
1673 static const MXFCodecUL mxf_data_essence_container_uls[] = {
1674 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x0d,0x00,0x00 }, 16, AV_CODEC_ID_NONE, "vbi_smpte_436M", 11 },
1675 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x0e,0x00,0x00 }, 16, AV_CODEC_ID_NONE, "vbi_vanc_smpte_436M", 11 },
1676 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x13,0x01,0x01 }, 16, AV_CODEC_ID_TTML },
1677 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
1678 };
1679
1680 typedef struct MXFChannelOrderingUL {
1681 UID uid;
1682 enum AVChannel channel;
1683 enum AVAudioServiceType service_type;
1684 } MXFChannelOrderingUL;
1685
1686 static const MXFChannelOrderingUL mxf_channel_ordering[] = {
1687 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00 }, AV_CHAN_FRONT_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left
1688 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x02,0x00,0x00,0x00,0x00 }, AV_CHAN_FRONT_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right
1689 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x03,0x00,0x00,0x00,0x00 }, AV_CHAN_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center
1690 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x04,0x00,0x00,0x00,0x00 }, AV_CHAN_LOW_FREQUENCY, AV_AUDIO_SERVICE_TYPE_MAIN }, // Low Frequency Effects
1691 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x05,0x00,0x00,0x00,0x00 }, AV_CHAN_SIDE_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Surround
1692 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x06,0x00,0x00,0x00,0x00 }, AV_CHAN_SIDE_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Surround
1693 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x07,0x00,0x00,0x00,0x00 }, AV_CHAN_SIDE_SURROUND_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Side Surround
1694 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x08,0x00,0x00,0x00,0x00 }, AV_CHAN_SIDE_SURROUND_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Side Surround
1695 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x09,0x00,0x00,0x00,0x00 }, AV_CHAN_BACK_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Rear Surround
1696 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0a,0x00,0x00,0x00,0x00 }, AV_CHAN_BACK_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Rear Surround
1697 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0b,0x00,0x00,0x00,0x00 }, AV_CHAN_FRONT_LEFT_OF_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Center
1698 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0c,0x00,0x00,0x00,0x00 }, AV_CHAN_FRONT_RIGHT_OF_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Center
1699 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0d,0x00,0x00,0x00,0x00 }, AV_CHAN_BACK_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Surround
1700 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0e,0x00,0x00,0x00,0x00 }, AV_CHAN_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, // Hearing impaired audio channel
1701 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0f,0x00,0x00,0x00,0x00 }, AV_CHAN_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED }, // Visually impaired narrative audio channel
1702 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x20,0x03,0x00,0x00,0x00 }, AV_CHAN_STEREO_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Total
1703 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x20,0x04,0x00,0x00,0x00 }, AV_CHAN_STEREO_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Total
1704 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x01,0x00,0x00 }, AV_CHAN_TOP_FRONT_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Height
1705 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x02,0x00,0x00 }, AV_CHAN_TOP_FRONT_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Height
1706 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x03,0x00,0x00 }, AV_CHAN_TOP_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Height
1707 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x04,0x00,0x00 }, AV_CHAN_TOP_SURROUND_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Surround Height
1708 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x05,0x00,0x00 }, AV_CHAN_TOP_SURROUND_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Surround Height
1709 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x06,0x00,0x00 }, AV_CHAN_TOP_SIDE_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Side Surround Height
1710 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x07,0x00,0x00 }, AV_CHAN_TOP_SIDE_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Side Surround Height
1711 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x08,0x00,0x00 }, AV_CHAN_TOP_BACK_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Rear Surround Height
1712 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x09,0x00,0x00 }, AV_CHAN_TOP_BACK_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Rear Surround Height
1713 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0a,0x00,0x00 }, AV_CHAN_TOP_SIDE_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Top Surround
1714 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0b,0x00,0x00 }, AV_CHAN_TOP_SIDE_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Top Surround
1715 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0c,0x00,0x00 }, AV_CHAN_TOP_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Top Surround
1716 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0d,0x00,0x00 }, AV_CHAN_LOW_FREQUENCY, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Front Subwoofer
1717 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0e,0x00,0x00 }, AV_CHAN_LOW_FREQUENCY_2, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Front Subwoofer
1718 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0f,0x00,0x00 }, AV_CHAN_TOP_BACK_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Rear Height
1719 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x10,0x00,0x00 }, AV_CHAN_BACK_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Rear
1720 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x11,0x00,0x00 }, AV_CHAN_BOTTOM_FRONT_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Below
1721 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x12,0x00,0x00 }, AV_CHAN_BOTTOM_FRONT_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Below
1722 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x13,0x00,0x00 }, AV_CHAN_BOTTOM_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Below
1723 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_AUDIO_SERVICE_TYPE_NB },
1724 };
1725
1726 210 static MXFWrappingScheme mxf_get_wrapping_kind(UID *essence_container_ul)
1727 {
1728 int val;
1729 const MXFCodecUL *codec_ul;
1730
1731 210 codec_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
1732
2/2
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 137 times.
210 if (!codec_ul->uid[0])
1733 73 codec_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
1734
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 205 times.
210 if (!codec_ul->uid[0])
1735 5 codec_ul = mxf_get_codec_ul(mxf_data_essence_container_uls, essence_container_ul);
1736
3/4
✓ Branch 0 taken 206 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 206 times.
210 if (!codec_ul->uid[0] || !codec_ul->wrapping_indicator_pos)
1737 4 return UnknownWrapped;
1738
1739 206 val = (*essence_container_ul)[codec_ul->wrapping_indicator_pos];
1740
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 68 times.
✓ Branch 2 taken 82 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 54 times.
206 switch (codec_ul->wrapping_indicator_type) {
1741 case RawVWrap:
1742 val = val % 4;
1743 break;
1744 68 case RawAWrap:
1745
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
68 if (val == 0x03 || val == 0x04)
1746 68 val -= 0x02;
1747 68 break;
1748 82 case D10D11Wrap:
1749
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82 times.
82 if (val == 0x02)
1750 val = 0x01;
1751 82 break;
1752 2 case J2KWrap:
1753
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (val != 0x02)
1754 2 val = 0x01;
1755 2 break;
1756 }
1757
2/2
✓ Branch 0 taken 205 times.
✓ Branch 1 taken 1 times.
206 if (val == 0x01)
1758 205 return FrameWrapped;
1759
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (val == 0x02)
1760 return ClipWrapped;
1761 1 return UnknownWrapped;
1762 }
1763
1764 108 static int mxf_get_sorted_table_segments(MXFContext *mxf, int *nb_sorted_segments, MXFIndexTableSegment ***sorted_segments)
1765 {
1766 108 int i, j, nb_segments = 0;
1767 MXFIndexTableSegment **unsorted_segments;
1768 108 int last_body_sid = -1, last_index_sid = -1, last_index_start = -1;
1769 108 MXFMetadataSetGroup *mg = &mxf->metadata_set_groups[IndexTableSegment];
1770
1771 /* count number of segments, allocate arrays and copy unsorted segments */
1772 108 nb_segments = mg->metadata_sets_count;
1773
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if (!nb_segments)
1774 return AVERROR_INVALIDDATA;
1775
1776
1/2
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
108 if (!(unsorted_segments = av_calloc(nb_segments, sizeof(*unsorted_segments))) ||
1777
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 108 times.
108 !(*sorted_segments = av_calloc(nb_segments, sizeof(**sorted_segments)))) {
1778 av_freep(sorted_segments);
1779 av_free(unsorted_segments);
1780 return AVERROR(ENOMEM);
1781 }
1782
1783
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 108 times.
220 for (i = nb_segments = 0; i < mg->metadata_sets_count; i++) {
1784 112 MXFIndexTableSegment *s = (MXFIndexTableSegment*)mg->metadata_sets[i];
1785
3/4
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 58 times.
✓ Branch 2 taken 54 times.
✗ Branch 3 not taken.
112 if (s->edit_unit_byte_count || s->nb_index_entries)
1786 112 unsorted_segments[nb_segments++] = s;
1787 else
1788 av_log(mxf->fc, AV_LOG_WARNING, "IndexSID %i segment at %"PRId64" missing EditUnitByteCount and IndexEntryArray\n",
1789 s->index_sid, s->index_start_position);
1790 }
1791
1792
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if (!nb_segments) {
1793 av_freep(sorted_segments);
1794 av_free(unsorted_segments);
1795 return AVERROR_INVALIDDATA;
1796 }
1797
1798 108 *nb_sorted_segments = 0;
1799
1800 /* sort segments by {BodySID, IndexSID, IndexStartPosition}, remove duplicates while we're at it */
1801
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 105 times.
217 for (i = 0; i < nb_segments; i++) {
1802 112 int best = -1, best_body_sid = -1, best_index_sid = -1, best_index_start = -1;
1803 112 uint64_t best_index_duration = 0;
1804
1805
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 112 times.
232 for (j = 0; j < nb_segments; j++) {
1806 120 MXFIndexTableSegment *s = unsorted_segments[j];
1807
1808 /* Require larger BosySID, IndexSID or IndexStartPosition then the previous entry. This removes duplicates.
1809 * We want the smallest values for the keys than what we currently have, unless this is the first such entry this time around.
1810 * If we come across an entry with the same IndexStartPosition but larger IndexDuration, then we'll prefer it over the one we currently have.
1811 */
1812
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 112 times.
120 if ((i == 0 ||
1813
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 s->body_sid > last_body_sid ||
1814
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 s->body_sid == last_body_sid && s->index_sid > last_index_sid ||
1815
6/8
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 109 times.
120 s->body_sid == last_body_sid && s->index_sid == last_index_sid && s->index_start_position > last_index_start) &&
1816 4 (best == -1 ||
1817
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 s->body_sid < best_body_sid ||
1818
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 s->body_sid == best_body_sid && s->index_sid < best_index_sid ||
1819
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 s->body_sid == best_body_sid && s->index_sid == best_index_sid && s->index_start_position < best_index_start ||
1820
5/8
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
4 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)) {
1821 109 best = j;
1822 109 best_body_sid = s->body_sid;
1823 109 best_index_sid = s->index_sid;
1824 109 best_index_start = s->index_start_position;
1825 109 best_index_duration = s->index_duration;
1826 }
1827 }
1828
1829 /* no suitable entry found -> we're done */
1830
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 109 times.
112 if (best == -1)
1831 3 break;
1832
1833 109 (*sorted_segments)[(*nb_sorted_segments)++] = unsorted_segments[best];
1834 109 last_body_sid = best_body_sid;
1835 109 last_index_sid = best_index_sid;
1836 109 last_index_start = best_index_start;
1837 }
1838
1839 108 av_free(unsorted_segments);
1840
1841 108 return 0;
1842 }
1843
1844 /**
1845 * Computes the absolute file offset of the given essence container offset
1846 */
1847 5798 static int mxf_absolute_bodysid_offset(MXFContext *mxf, int body_sid, int64_t offset, int64_t *offset_out, MXFPartition **partition_out)
1848 {
1849 5798 MXFPartition *last_p = NULL;
1850 int a, b, m, m0;
1851
1852
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5798 times.
5798 if (offset < 0)
1853 return AVERROR(EINVAL);
1854
1855 5798 a = -1;
1856 5798 b = mxf->partitions_count;
1857
1858
2/2
✓ Branch 0 taken 11559 times.
✓ Branch 1 taken 5798 times.
17357 while (b - a > 1) {
1859 11559 m0 = m = (a + b) >> 1;
1860
1861
4/4
✓ Branch 0 taken 11587 times.
✓ Branch 1 taken 5761 times.
✓ Branch 2 taken 5789 times.
✓ Branch 3 taken 5798 times.
17348 while (m < b && mxf->partitions[m].body_sid != body_sid)
1862 5789 m++;
1863
1864
3/4
✓ Branch 0 taken 5798 times.
✓ Branch 1 taken 5761 times.
✓ Branch 2 taken 5798 times.
✗ Branch 3 not taken.
11559 if (m < b && mxf->partitions[m].body_offset <= offset)
1865 5798 a = m;
1866 else
1867 5761 b = m0;
1868 }
1869
1870
1/2
✓ Branch 0 taken 5798 times.
✗ Branch 1 not taken.
5798 if (a >= 0)
1871 5798 last_p = &mxf->partitions[a];
1872
1873
5/6
✓ Branch 0 taken 5798 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5761 times.
✓ Branch 3 taken 37 times.
✓ Branch 4 taken 5760 times.
✓ Branch 5 taken 1 times.
5798 if (last_p && (!last_p->essence_length || last_p->essence_length > (offset - last_p->body_offset))) {
1874 5797 *offset_out = last_p->essence_offset + (offset - last_p->body_offset);
1875
2/2
✓ Branch 0 taken 207 times.
✓ Branch 1 taken 5590 times.
5797 if (partition_out)
1876 207 *partition_out = last_p;
1877 5797 return 0;
1878 }
1879
1880 1 av_log(mxf->fc, AV_LOG_ERROR,
1881 "failed to find absolute offset of %"PRIX64" in BodySID %i - partial file?\n",
1882 offset, body_sid);
1883
1884 1 return AVERROR_INVALIDDATA;
1885 }
1886
1887 /**
1888 * Returns the end position of the essence container with given BodySID, or zero if unknown
1889 */
1890 299 static int64_t mxf_essence_container_end(MXFContext *mxf, int body_sid)
1891 {
1892
1/2
✓ Branch 0 taken 556 times.
✗ Branch 1 not taken.
556 for (int x = mxf->partitions_count - 1; x >= 0; x--) {
1893 556 MXFPartition *p = &mxf->partitions[x];
1894
1895
2/2
✓ Branch 0 taken 257 times.
✓ Branch 1 taken 299 times.
556 if (p->body_sid != body_sid)
1896 257 continue;
1897
1898
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 251 times.
299 if (!p->essence_length)
1899 48 return 0;
1900
1901 251 return p->essence_offset + p->essence_length;
1902 }
1903
1904 return 0;
1905 }
1906
1907 /* EditUnit -> absolute offset */
1908 6096 static int mxf_edit_unit_absolute_offset(MXFContext *mxf, MXFIndexTable *index_table, int64_t edit_unit, AVRational edit_rate, int64_t *edit_unit_out, int64_t *offset_out, MXFPartition **partition_out, int nag)
1909 {
1910 6096 int i = 0, dir = 0;
1911 int64_t index_duration, index_end;
1912 MXFIndexTableSegment *first_segment, *last_segment;
1913
1914
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6096 times.
6096 if (!index_table->nb_segments) {
1915 av_log(mxf->fc, AV_LOG_ERROR, "no index table segments\n");
1916 return AVERROR_INVALIDDATA;
1917 }
1918
1919 6096 edit_unit = av_rescale_q(edit_unit, index_table->segments[0]->index_edit_rate, edit_rate);
1920
1921 6096 first_segment = index_table->segments[0];
1922 6096 last_segment = index_table->segments[index_table->nb_segments - 1];
1923
1924 // clamp to actual range of index
1925 6096 index_end = av_sat_add64(last_segment->index_start_position, last_segment->index_duration);
1926 6096 edit_unit = FFMAX(FFMIN(edit_unit, index_end), first_segment->index_start_position);
1927
1928 // guess which table segment this edit unit is in
1929 // saturation is fine since it's just a guess
1930 // if the guess is wrong we revert to a linear search
1931 6096 index_duration = av_sat_sub64(index_end, first_segment->index_start_position);
1932
1933 // compute the guess, taking care not to cause overflow or division by zero
1934
3/4
✓ Branch 0 taken 6048 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 6048 times.
✗ Branch 3 not taken.
6096 if (index_duration > 0 && edit_unit <= INT64_MAX / index_table->nb_segments) {
1935 // a simple linear guesstimate
1936 // this is accurate to within +-1 when partitions are generated at a constant rate like mxfenc does
1937 6048 int64_t i64 = index_table->nb_segments * edit_unit / index_duration;
1938 // clamp and downcast to 32-bit
1939 6048 i = FFMAX(0, FFMIN(index_table->nb_segments - 1, i64));
1940 }
1941
1942
3/4
✓ Branch 0 taken 6394 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6096 times.
✓ Branch 3 taken 298 times.
6394 for (; i >= 0 && i < index_table->nb_segments; i += dir) {
1943 6096 MXFIndexTableSegment *s = index_table->segments[i];
1944
1945
3/4
✓ Branch 0 taken 6096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5798 times.
✓ Branch 3 taken 298 times.
6096 if (s->index_start_position <= edit_unit && edit_unit < s->index_start_position + s->index_duration) {
1946 5798 int64_t index = edit_unit - s->index_start_position;
1947 5798 int64_t offset_temp = s->offset;
1948
1949
2/2
✓ Branch 0 taken 2970 times.
✓ Branch 1 taken 2828 times.
5798 if (s->edit_unit_byte_count) {
1950
1/2
✓ Branch 0 taken 2970 times.
✗ Branch 1 not taken.
2970 if (index > INT64_MAX / s->edit_unit_byte_count ||
1951
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2970 times.
2970 s->edit_unit_byte_count * index > INT64_MAX - offset_temp)
1952 return AVERROR_INVALIDDATA;
1953
1954 2970 offset_temp += s->edit_unit_byte_count * index;
1955 } else {
1956
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2828 times.
2828 if (s->nb_index_entries == 2 * s->index_duration + 1)
1957 index *= 2; /* Avid index */
1958
1959
2/4
✓ Branch 0 taken 2828 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2828 times.
2828 if (index < 0 || index >= s->nb_index_entries) {
1960 av_log(mxf->fc, AV_LOG_ERROR, "IndexSID %i segment at %"PRId64" IndexEntryArray too small\n",
1961 index_table->index_sid, s->index_start_position);
1962 return AVERROR_INVALIDDATA;
1963 }
1964
1965 2828 offset_temp = s->stream_offset_entries[index];
1966 }
1967
1968
2/2
✓ Branch 0 taken 207 times.
✓ Branch 1 taken 5591 times.
5798 if (edit_unit_out)
1969 207 *edit_unit_out = av_rescale_q(edit_unit, edit_rate, s->index_edit_rate);
1970
1971 5798 return mxf_absolute_bodysid_offset(mxf, index_table->body_sid, offset_temp, offset_out, partition_out);
1972
1/2
✓ Branch 0 taken 298 times.
✗ Branch 1 not taken.
298 } else if (dir == 0) {
1973 // scan backwards if the segment is earlier than the current IndexStartPosition
1974 // else scan forwards
1975
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 298 times.
298 if (edit_unit < s->index_start_position) {
1976 dir = -1;
1977 } else {
1978 298 dir = 1;
1979 }
1980 }
1981 }
1982
1983
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 298 times.
298 if (nag)
1984 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);
1985
1986 298 return AVERROR_INVALIDDATA;
1987 }
1988
1989 108 static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_table)
1990 {
1991 int i, j, x;
1992 108 int8_t max_temporal_offset = -128;
1993 uint8_t *flags;
1994
1995 /* first compute how many entries we have */
1996
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 50 times.
159 for (i = 0; i < index_table->nb_segments; i++) {
1997 109 MXFIndexTableSegment *s = index_table->segments[i];
1998
1999
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 51 times.
109 if (!s->nb_index_entries) {
2000 58 index_table->nb_ptses = 0;
2001 58 return 0; /* no TemporalOffsets */
2002 }
2003
2004
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if (s->index_duration > INT_MAX - index_table->nb_ptses) {
2005 index_table->nb_ptses = 0;
2006 av_log(mxf->fc, AV_LOG_ERROR, "ignoring IndexSID %d, duration is too large\n", s->index_sid);
2007 return 0;
2008 }
2009
2010
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if (s->nb_index_entries != s->index_duration &&
2011 s->nb_index_entries != s->index_duration + 1 && /* Avid index */
2012 s->nb_index_entries != s->index_duration * 2 + 1) {
2013 index_table->nb_ptses = 0;
2014 av_log(mxf->fc, AV_LOG_ERROR, "ignoring IndexSID %d, duration does not match nb_index_entries\n", s->index_sid);
2015 return 0;
2016 }
2017
2018 51 index_table->nb_ptses += s->index_duration;
2019 }
2020
2021 /* paranoid check */
2022
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
50 if (index_table->nb_ptses <= 0)
2023 return 0;
2024
2025
1/2
✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
50 if (!(index_table->ptses = av_malloc_array(index_table->nb_ptses, sizeof(int64_t))) ||
2026
1/2
✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
50 !(index_table->fake_index = av_calloc(index_table->nb_ptses, sizeof(AVIndexEntry))) ||
2027
1/2
✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
50 !(index_table->offsets = av_malloc_array(index_table->nb_ptses, sizeof(int8_t))) ||
2028
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
50 !(flags = av_malloc_array(index_table->nb_ptses, sizeof(uint8_t)))) {
2029 av_freep(&index_table->ptses);
2030 av_freep(&index_table->fake_index);
2031 av_freep(&index_table->offsets);
2032 return AVERROR(ENOMEM);
2033 }
2034
2035 /* we may have a few bad TemporalOffsets
2036 * make sure the corresponding PTSes don't have the bogus value 0 */
2037
2/2
✓ Branch 0 taken 1378 times.
✓ Branch 1 taken 50 times.
1428 for (x = 0; x < index_table->nb_ptses; x++)
2038 1378 index_table->ptses[x] = AV_NOPTS_VALUE;
2039
2040 /**
2041 * We have this:
2042 *
2043 * x TemporalOffset
2044 * 0: 0
2045 * 1: 1
2046 * 2: 1
2047 * 3: -2
2048 * 4: 1
2049 * 5: 1
2050 * 6: -2
2051 *
2052 * We want to transform it into this:
2053 *
2054 * x DTS PTS
2055 * 0: -1 0
2056 * 1: 0 3
2057 * 2: 1 1
2058 * 3: 2 2
2059 * 4: 3 6
2060 * 5: 4 4
2061 * 6: 5 5
2062 *
2063 * We do this by bucket sorting x by x+TemporalOffset[x] into mxf->ptses,
2064 * then settings ffstream(mxf)->first_dts = -max(TemporalOffset[x]).
2065 * The latter makes DTS <= PTS.
2066 */
2067
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 50 times.
101 for (i = x = 0; i < index_table->nb_segments; i++) {
2068 51 MXFIndexTableSegment *s = index_table->segments[i];
2069 51 int index_delta = 1;
2070 51 int n = s->nb_index_entries;
2071
2072
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if (s->nb_index_entries == 2 * s->index_duration + 1)
2073 index_delta = 2; /* Avid index */
2074
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if (s->nb_index_entries == index_delta * s->index_duration + 1)
2075 /* ignore the last entry - it's the size of the essence container in Avid */
2076 n--;
2077
2078
2/2
✓ Branch 0 taken 1378 times.
✓ Branch 1 taken 51 times.
1429 for (j = 0; j < n; j += index_delta, x++) {
2079 1378 int offset = s->temporal_offset_entries[j] / index_delta;
2080 1378 int index = x + offset;
2081
2082
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1378 times.
1378 if (x >= index_table->nb_ptses) {
2083 av_log(mxf->fc, AV_LOG_ERROR,
2084 "x >= nb_ptses - IndexEntryCount %i < IndexDuration %"PRId64"?\n",
2085 s->nb_index_entries, s->index_duration);
2086 break;
2087 }
2088
2089 1378 flags[x] = !(s->flag_entries[j] & 0x30) ? AVINDEX_KEYFRAME : 0;
2090
2091
2/4
✓ Branch 0 taken 1378 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1378 times.
1378 if (index < 0 || index >= index_table->nb_ptses) {
2092 av_log(mxf->fc, AV_LOG_ERROR,
2093 "index entry %i + TemporalOffset %i = %i, which is out of bounds\n",
2094 x, offset, index);
2095 continue;
2096 }
2097
2098 1378 index_table->offsets[x] = offset;
2099 1378 index_table->ptses[index] = x;
2100 1378 max_temporal_offset = FFMAX(max_temporal_offset, offset);
2101 }
2102 }
2103
2104 /* calculate the fake index table in display order */
2105
2/2
✓ Branch 0 taken 1378 times.
✓ Branch 1 taken 50 times.
1428 for (x = 0; x < index_table->nb_ptses; x++) {
2106 1378 index_table->fake_index[x].timestamp = x;
2107
1/2
✓ Branch 0 taken 1378 times.
✗ Branch 1 not taken.
1378 if (index_table->ptses[x] != AV_NOPTS_VALUE)
2108 1378 index_table->fake_index[index_table->ptses[x]].flags = flags[x];
2109 }
2110 50 av_freep(&flags);
2111
2112 50 index_table->first_dts = -max_temporal_offset;
2113
2114 50 return 0;
2115 }
2116
2117 /**
2118 * Sorts and collects index table segments into index tables.
2119 * Also computes PTSes if possible.
2120 */
2121 108 static int mxf_compute_index_tables(MXFContext *mxf)
2122 {
2123 int ret, nb_sorted_segments;
2124 108 MXFIndexTableSegment **sorted_segments = NULL;
2125
2126
1/2
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
108 if ((ret = mxf_get_sorted_table_segments(mxf, &nb_sorted_segments, &sorted_segments)) ||
2127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 nb_sorted_segments <= 0) {
2128 av_log(mxf->fc, AV_LOG_WARNING, "broken or empty index\n");
2129 return 0;
2130 }
2131
2132 /* sanity check and count unique BodySIDs/IndexSIDs */
2133
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 108 times.
217 for (int i = 0; i < nb_sorted_segments; i++) {
2134
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
109 if (i == 0 || sorted_segments[i-1]->index_sid != sorted_segments[i]->index_sid)
2135 108 mxf->nb_index_tables++;
2136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 else if (sorted_segments[i-1]->body_sid != sorted_segments[i]->body_sid) {
2137 av_log(mxf->fc, AV_LOG_ERROR, "found inconsistent BodySID\n");
2138 ret = AVERROR_INVALIDDATA;
2139 goto finish_decoding_index;
2140 }
2141 }
2142
2143 108 mxf->index_tables = av_calloc(mxf->nb_index_tables,
2144 sizeof(*mxf->index_tables));
2145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if (!mxf->index_tables) {
2146 av_log(mxf->fc, AV_LOG_ERROR, "failed to allocate index tables\n");
2147 ret = AVERROR(ENOMEM);
2148 goto finish_decoding_index;
2149 }
2150
2151 /* distribute sorted segments to index tables */
2152
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 108 times.
217 for (int i = 0, j = 0; i < nb_sorted_segments; i++) {
2153
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
109 if (i != 0 && sorted_segments[i-1]->index_sid != sorted_segments[i]->index_sid) {
2154 /* next IndexSID */
2155 j++;
2156 }
2157
2158 109 mxf->index_tables[j].nb_segments++;
2159 }
2160
2161
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 108 times.
216 for (int i = 0, j = 0; j < mxf->nb_index_tables; i += mxf->index_tables[j++].nb_segments) {
2162 108 MXFIndexTable *t = &mxf->index_tables[j];
2163 108 MXFTrack *mxf_track = NULL;
2164 108 int64_t offset_temp = 0;
2165
2166 108 t->segments = av_calloc(t->nb_segments, sizeof(*t->segments));
2167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if (!t->segments) {
2168 av_log(mxf->fc, AV_LOG_ERROR, "failed to allocate IndexTableSegment"
2169 " pointer array\n");
2170 ret = AVERROR(ENOMEM);
2171 goto finish_decoding_index;
2172 }
2173
2174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if (sorted_segments[i]->index_start_position)
2175 av_log(mxf->fc, AV_LOG_WARNING, "IndexSID %i starts at EditUnit %"PRId64" - seeking may not work as expected\n",
2176 sorted_segments[i]->index_sid, sorted_segments[i]->index_start_position);
2177
2178 108 memcpy(t->segments, &sorted_segments[i], t->nb_segments * sizeof(MXFIndexTableSegment*));
2179 108 t->index_sid = sorted_segments[i]->index_sid;
2180 108 t->body_sid = sorted_segments[i]->body_sid;
2181
2182
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 108 times.
108 if ((ret = mxf_compute_ptses_fake_index(mxf, t)) < 0)
2183 goto finish_decoding_index;
2184
2185
1/2
✓ Branch 0 taken 117 times.
✗ Branch 1 not taken.
117 for (int k = 0; k < mxf->fc->nb_streams; k++) {
2186 117 MXFTrack *track = mxf->fc->streams[k]->priv_data;
2187
3/4
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 108 times.
✗ Branch 3 not taken.
117 if (track && track->index_sid == t->index_sid) {
2188 108 mxf_track = track;
2189 108 break;
2190 }
2191 }
2192
2193 /* fix zero IndexDurations and compute segment offsets */
2194
2/2
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 54 times.
163 for (int k = 0; k < t->nb_segments; k++) {
2195 109 MXFIndexTableSegment *s = t->segments[k];
2196
2197
2/4
✓ Branch 0 taken 109 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 109 times.
109 if (!t->segments[k]->index_edit_rate.num || !t->segments[k]->index_edit_rate.den) {
2198 av_log(mxf->fc, AV_LOG_WARNING, "IndexSID %i segment %i has invalid IndexEditRate\n",
2199 t->index_sid, k);
2200 if (mxf_track)
2201 t->segments[k]->index_edit_rate = mxf_track->edit_rate;
2202 }
2203
2204 109 s->offset = offset_temp;
2205
2206 /* EditUnitByteCount == 0 for VBR indexes, which is fine since they use explicit StreamOffsets */
2207
3/4
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 51 times.
✓ Branch 2 taken 58 times.
✗ Branch 3 not taken.
109 if (s->edit_unit_byte_count && (s->index_duration > INT64_MAX / s->edit_unit_byte_count ||
2208
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 s->edit_unit_byte_count * s->index_duration > INT64_MAX - offset_temp)) {
2209 ret = AVERROR_INVALIDDATA;
2210 goto finish_decoding_index;
2211 }
2212
2213 109 offset_temp += t->segments[k]->edit_unit_byte_count * t->segments[k]->index_duration;
2214
2215
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 54 times.
109 if (t->segments[k]->index_duration)
2216 55 continue;
2217
2218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 if (t->nb_segments > 1)
2219 av_log(mxf->fc, AV_LOG_WARNING, "IndexSID %i segment %i has zero IndexDuration and there's more than one segment\n",
2220 t->index_sid, k);
2221
2222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 if (!mxf_track) {
2223 av_log(mxf->fc, AV_LOG_WARNING, "no streams?\n");
2224 break;
2225 }
2226
2227 /* assume the first stream's duration is reasonable
2228 * leave index_duration = 0 on further segments in case we have any (unlikely)
2229 */
2230 54 t->segments[k]->index_duration = mxf_track->original_duration;
2231 54 break;
2232 }
2233 }
2234
2235 108 ret = 0;
2236 108 finish_decoding_index:
2237 108 av_free(sorted_segments);
2238 108 return ret;
2239 }
2240
2241 103 static int mxf_is_st_422(const UID *essence_container_ul) {
2242 static const uint8_t st_422_essence_container_ul[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0c };
2243
2244
3/4
✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 101 times.
103 return essence_container_ul && mxf_match_uid(*essence_container_ul, st_422_essence_container_ul,
2245 sizeof(st_422_essence_container_ul));
2246 }
2247
2248 103 static int mxf_is_intra_only(MXFDescriptor *descriptor)
2249 {
2250 103 return mxf_get_codec_ul(mxf_intra_only_essence_container_uls,
2251
2/2
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 42 times.
164 &descriptor->essence_container_ul)->id != AV_CODEC_ID_NONE ||
2252 61 mxf_get_codec_ul(mxf_intra_only_picture_essence_coding_uls,
2253
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 59 times.
61 &descriptor->essence_codec_ul)->id != AV_CODEC_ID_NONE;
2254 }
2255
2256 348 static void mxf_umid_to_str(const UID ul, const UID uid,
2257 char str[2 + sizeof(UID) * 4 + 1])
2258 {
2259 348 snprintf(str, 2 + sizeof(UID) * 4 + 1, "0x");
2260 348 ff_data_to_hex(str + 2, ul, sizeof(UID), 0);
2261 348 ff_data_to_hex(str + 2 + 2 * sizeof(UID), uid, sizeof(UID), 0);
2262 348 }
2263
2264 189 static int mxf_version_to_str(uint16_t major, uint16_t minor, uint16_t tertiary,
2265 uint16_t patch, uint16_t release, char **str)
2266 {
2267 189 *str = av_asprintf("%d.%d.%d.%d.%d", major, minor, tertiary, patch, release);
2268
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 189 times.
189 if (!*str)
2269 return AVERROR(ENOMEM);
2270 189 return 0;
2271 }
2272
2273 348 static int mxf_add_umid_metadata(AVDictionary **pm, const char *key, MXFPackage* package)
2274 {
2275 char str[2 + 4 * sizeof(UID) + 1];
2276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 348 times.
348 if (!package)
2277 return 0;
2278 348 mxf_umid_to_str(package->package_ul, package->package_uid, str);
2279 348 av_dict_set(pm, key, str, 0);
2280 348 return 0;
2281 }
2282
2283 107 static int mxf_add_timecode_metadata(AVDictionary **pm, const char *key, AVTimecode *tc)
2284 {
2285 char buf[AV_TIMECODE_STR_SIZE];
2286 107 av_dict_set(pm, key, av_timecode_make_string(tc, buf, 0), 0);
2287
2288 107 return 0;
2289 }
2290
2291 14 static MXFTimecodeComponent* mxf_resolve_timecode_component(MXFContext *mxf, UID *strong_ref)
2292 {
2293 MXFTimecodeComponent *timecode;
2294 MXFPulldownComponent *pulldown;
2295
2296 14 timecode = mxf_resolve_strong_ref(mxf, strong_ref, TimecodeComponent);
2297
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8 times.
14 if (timecode)
2298 6 return timecode;
2299
2300 8 pulldown = mxf_resolve_strong_ref(mxf, strong_ref, PulldownComponent);
2301
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (pulldown)
2302 1 return mxf_resolve_strong_ref(mxf, &pulldown->input_segment_ref, TimecodeComponent);
2303
2304 7 return NULL;
2305 }
2306
2307 458 static MXFPackage* mxf_resolve_source_package(MXFContext *mxf, UID package_ul, UID package_uid)
2308 {
2309 458 MXFPackage *package = NULL;
2310 int i;
2311
2312
2/2
✓ Branch 0 taken 935 times.
✓ Branch 1 taken 229 times.
1164 for (i = 0; i < mxf->packages_count; i++) {
2313 935 package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], SourcePackage);
2314
2/2
✓ Branch 0 taken 455 times.
✓ Branch 1 taken 480 times.
935 if (!package)
2315 455 continue;
2316
2317
4/4
✓ Branch 0 taken 266 times.
✓ Branch 1 taken 214 times.
✓ Branch 2 taken 229 times.
✓ Branch 3 taken 37 times.
480 if (!memcmp(package->package_ul, package_ul, 16) && !memcmp(package->package_uid, package_uid, 16))
2318 229 return package;
2319 }
2320 229 return NULL;
2321 }
2322
2323 221 static MXFDescriptor* mxf_resolve_descriptor(MXFContext *mxf, UID *strong_ref, int track_id)
2324 {
2325 221 MXFDescriptor *descriptor = mxf_resolve_strong_ref(mxf, strong_ref, Descriptor);
2326
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 205 times.
221 if (descriptor)
2327 16 return descriptor;
2328
2329 205 descriptor = mxf_resolve_strong_ref(mxf, strong_ref, MultipleDescriptor);
2330
1/2
✓ Branch 0 taken 205 times.
✗ Branch 1 not taken.
205 if (descriptor) {
2331
1/2
✓ Branch 0 taken 369 times.
✗ Branch 1 not taken.
369 for (int i = 0; i < descriptor->file_descriptors_count; i++) {
2332 369 MXFDescriptor *file_descriptor = mxf_resolve_strong_ref(mxf, &descriptor->file_descriptors_refs[i], Descriptor);
2333
2334
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 369 times.
369 if (!file_descriptor) {
2335 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve file descriptor strong ref\n");
2336 continue;
2337 }
2338
2/2
✓ Branch 0 taken 205 times.
✓ Branch 1 taken 164 times.
369 if (file_descriptor->linked_track_id == track_id) {
2339 205 return file_descriptor;
2340 }
2341 }
2342 }
2343
2344 return NULL;
2345 }
2346
2347 454 static MXFStructuralComponent* mxf_resolve_sourceclip(MXFContext *mxf, UID *strong_ref)
2348 {
2349 454 MXFStructuralComponent *component = NULL;
2350 454 MXFPackage *package = NULL;
2351 454 MXFDescriptor *descriptor = NULL;
2352 MXFEssenceGroup *essence_group;
2353 int i;
2354
2355 454 component = mxf_resolve_strong_ref(mxf, strong_ref, SourceClip);
2356
2/2
✓ Branch 0 taken 244 times.
✓ Branch 1 taken 210 times.
454 if (component)
2357 244 return component;
2358
2359 210 essence_group = mxf_resolve_strong_ref(mxf, strong_ref, EssenceGroup);
2360
2/2
✓ Branch 0 taken 207 times.
✓ Branch 1 taken 3 times.
210 if (!essence_group)
2361 207 return NULL;
2362
2363 /* essence groups contains multiple representations of the same media,
2364 this return the first components with a valid Descriptor typically index 0 */
2365
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for (i =0; i < essence_group->structural_components_count; i++){
2366 4 component = mxf_resolve_strong_ref(mxf, &essence_group->structural_components_refs[i], SourceClip);
2367
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!component)
2368 continue;
2369
2370
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
4 if (!(package = mxf_resolve_source_package(mxf, component->source_package_ul, component->source_package_uid)))
2371 3 continue;
2372
2373 1 descriptor = mxf_resolve_strong_ref(mxf, &package->descriptor_ref, Descriptor);
2374
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (descriptor)
2375 1 return component;
2376 }
2377
2378 2 return NULL;
2379 }
2380
2381 108 static int mxf_parse_package_comments(MXFContext *mxf, AVDictionary **pm, MXFPackage *package)
2382 {
2383 MXFTaggedValue *tag;
2384 int i;
2385 108 char *key = NULL;
2386
2387
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 108 times.
122 for (i = 0; i < package->comment_count; i++) {
2388 14 tag = mxf_resolve_strong_ref(mxf, &package->comment_refs[i], TaggedValue);
2389
3/6
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 14 times.
14 if (!tag || !tag->name || !tag->value)
2390 continue;
2391
2392 14 key = av_asprintf("comment_%s", tag->name);
2393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (!key)
2394 return AVERROR(ENOMEM);
2395
2396 14 av_dict_set(pm, key, tag->value, AV_DICT_DONT_STRDUP_KEY);
2397 }
2398 108 return 0;
2399 }
2400
2401 221 static int mxf_parse_physical_source_package(MXFContext *mxf, MXFTrack *source_track, AVStream *st)
2402 {
2403 221 MXFPackage *physical_package = NULL;
2404 221 MXFTrack *physical_track = NULL;
2405 221 MXFStructuralComponent *sourceclip = NULL;
2406 221 MXFTimecodeComponent *mxf_tc = NULL;
2407 int i, j, k;
2408 AVTimecode tc;
2409 int flags;
2410 int64_t start_position;
2411
2412
1/2
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
221 for (i = 0; i < source_track->sequence->structural_components_count; i++) {
2413 221 sourceclip = mxf_resolve_strong_ref(mxf, &source_track->sequence->structural_components_refs[i], SourceClip);
2414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
221 if (!sourceclip)
2415 continue;
2416
2417
2/2
✓ Branch 1 taken 214 times.
✓ Branch 2 taken 7 times.
221 if (!(physical_package = mxf_resolve_source_package(mxf, sourceclip->source_package_ul, sourceclip->source_package_uid)))
2418 214 break;
2419
2420 7 mxf_add_umid_metadata(&st->metadata, "reel_umid", physical_package);
2421
2422 /* the name of physical source package is name of the reel or tape */
2423
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 if (physical_package->name && physical_package->name[0])
2424 7 av_dict_set(&st->metadata, "reel_name", physical_package->name, 0);
2425
2426 /* the source timecode is calculated by adding the start_position of the sourceclip from the file source package track
2427 * to the start_frame of the timecode component located on one of the tracks of the physical source package.
2428 */
2429
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 for (j = 0; j < physical_package->tracks_count; j++) {
2430
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
14 if (!(physical_track = mxf_resolve_strong_ref(mxf, &physical_package->tracks_refs[j], Track))) {
2431 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n");
2432 continue;
2433 }
2434
2435
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
14 if (!(physical_track->sequence = mxf_resolve_strong_ref(mxf, &physical_track->sequence_ref, Sequence))) {
2436 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n");
2437 continue;
2438 }
2439
2440
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 if (physical_track->edit_rate.num <= 0 ||
2441
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 physical_track->edit_rate.den <= 0) {
2442 av_log(mxf->fc, AV_LOG_WARNING,
2443 "Invalid edit rate (%d/%d) found on structural"
2444 " component #%d, defaulting to 25/1\n",
2445 physical_track->edit_rate.num,
2446 physical_track->edit_rate.den, i);
2447 physical_track->edit_rate = (AVRational){25, 1};
2448 }
2449
2450
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 7 times.
21 for (k = 0; k < physical_track->sequence->structural_components_count; k++) {
2451
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 7 times.
14 if (!(mxf_tc = mxf_resolve_timecode_component(mxf, &physical_track->sequence->structural_components_refs[k])))
2452 7 continue;
2453
2454 7 flags = mxf_tc->drop_frame == 1 ? AV_TIMECODE_FLAG_DROPFRAME : 0;
2455 /* scale sourceclip start_position to match physical track edit rate */
2456 7 start_position = av_rescale_q(sourceclip->start_position,
2457 physical_track->edit_rate,
2458 source_track->edit_rate);
2459
2460
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 if (av_sat_add64(start_position, mxf_tc->start_frame) != start_position + (uint64_t)mxf_tc->start_frame)
2461 return AVERROR_INVALIDDATA;
2462
2463
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 if (av_timecode_init(&tc, mxf_tc->rate, flags, start_position + mxf_tc->start_frame, mxf->fc) == 0) {
2464 7 mxf_add_timecode_metadata(&st->metadata, "timecode", &tc);
2465 7 return 0;
2466 }
2467 }
2468 }
2469 }
2470
2471 214 return 0;
2472 }
2473
2474 114 static int mxf_add_metadata_stream(MXFContext *mxf, MXFTrack *track)
2475 {
2476 114 MXFStructuralComponent *component = NULL;
2477 114 const MXFCodecUL *codec_ul = NULL;
2478 MXFPackage tmp_package;
2479 AVStream *st;
2480 int j;
2481
2482
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 102 times.
216 for (j = 0; j < track->sequence->structural_components_count; j++) {
2483 114 component = mxf_resolve_sourceclip(mxf, &track->sequence->structural_components_refs[j]);
2484
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 12 times.
114 if (!component)
2485 102 continue;
2486 12 break;
2487 }
2488
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 12 times.
114 if (!component)
2489 102 return 0;
2490
2491 12 st = avformat_new_stream(mxf->fc, NULL);
2492
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (!st) {
2493 av_log(mxf->fc, AV_LOG_ERROR, "could not allocate metadata stream\n");
2494 return AVERROR(ENOMEM);
2495 }
2496
2497 12 st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
2498 12 st->codecpar->codec_id = AV_CODEC_ID_NONE;
2499 12 st->id = track->track_id;
2500
2501 12 memcpy(&tmp_package.package_ul, component->source_package_ul, 16);
2502 12 memcpy(&tmp_package.package_uid, component->source_package_uid, 16);
2503 12 mxf_add_umid_metadata(&st->metadata, "file_package_umid", &tmp_package);
2504
3/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
12 if (track->name && track->name[0])
2505 6 av_dict_set(&st->metadata, "track_name", track->name, 0);
2506
2507 12 codec_ul = mxf_get_codec_ul(ff_mxf_data_definition_uls, &track->sequence->data_definition_ul);
2508 12 av_dict_set(&st->metadata, "data_type", av_get_media_type_string(codec_ul->id), 0);
2509 12 return 0;
2510 }
2511
2512 103 static enum AVColorRange mxf_get_color_range(MXFContext *mxf, MXFDescriptor *descriptor)
2513 {
2514
4/6
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 99 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
103 if (descriptor->black_ref_level || descriptor->white_ref_level || descriptor->color_range) {
2515 /* CDCI range metadata */
2516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 99 times.
99 if (!descriptor->component_depth)
2517 return AVCOL_RANGE_UNSPECIFIED;
2518
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
99 if (descriptor->black_ref_level == 0 && descriptor->component_depth < 31 &&
2519 descriptor->white_ref_level == ((1<<descriptor->component_depth) - 1) &&
2520 (descriptor->color_range == (1<<descriptor->component_depth) ||
2521 descriptor->color_range == ((1<<descriptor->component_depth) - 1)))
2522 return AVCOL_RANGE_JPEG;
2523
2/4
✓ Branch 0 taken 99 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 99 times.
✗ Branch 3 not taken.
99 if (descriptor->component_depth >= 8 && descriptor->component_depth < 31 &&
2524
1/2
✓ Branch 0 taken 99 times.
✗ Branch 1 not taken.
99 descriptor->black_ref_level == (1 <<(descriptor->component_depth - 4)) &&
2525
1/2
✓ Branch 0 taken 99 times.
✗ Branch 1 not taken.
99 descriptor->white_ref_level == (235<<(descriptor->component_depth - 8)) &&
2526
1/2
✓ Branch 0 taken 99 times.
✗ Branch 1 not taken.
99 descriptor->color_range == ((14<<(descriptor->component_depth - 4)) + 1))
2527 99 return AVCOL_RANGE_MPEG;
2528 avpriv_request_sample(mxf->fc, "Unrecognized CDCI color range (color diff range %d, b %d, w %d, depth %d)",
2529 descriptor->color_range, descriptor->black_ref_level,
2530 descriptor->white_ref_level, descriptor->component_depth);
2531 }
2532
2533 4 return AVCOL_RANGE_UNSPECIFIED;
2534 }
2535
2536 7 static int is_pcm(enum AVCodecID codec_id)
2537 {
2538 /* we only care about "normal" PCM codecs until we get samples */
2539
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 return codec_id >= AV_CODEC_ID_PCM_S16LE && codec_id < AV_CODEC_ID_PCM_S24DAUD;
2540 }
2541
2542 static int set_language(AVFormatContext *s, const char *rfc5646, AVDictionary **met)
2543 {
2544 // language abbr should contain at least 2 chars
2545 if (rfc5646 && strlen(rfc5646) > 1) {
2546 char primary_tag[4] =
2547 {rfc5646[0], rfc5646[1], rfc5646[2] != '-' ? rfc5646[2] : '\0', '\0'};
2548
2549 const char *iso6392 = ff_convert_lang_to(primary_tag,
2550 AV_LANG_ISO639_2_BIBL);
2551 if (iso6392)
2552 return(av_dict_set(met, "language", iso6392, 0));
2553 }
2554 return 0;
2555 }
2556
2557 static MXFMCASubDescriptor *find_mca_link_id(MXFContext *mxf, enum MXFMetadataSetType type, UID *mca_link_id)
2558 {
2559 MXFMetadataSetGroup *mg = &mxf->metadata_set_groups[type];
2560 for (int k = 0; k < mg->metadata_sets_count; k++) {
2561 MXFMCASubDescriptor *group = (MXFMCASubDescriptor*)mg->metadata_sets[k];
2562 if (!memcmp(&group->mca_link_id, mca_link_id, 16))
2563 return group;
2564 }
2565 return NULL;
2566 }
2567
2568 220 static void parse_ffv1_sub_descriptor(MXFContext *mxf, MXFTrack *source_track, MXFDescriptor *descriptor, AVStream *st)
2569 {
2570
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 219 times.
223 for (int i = 0; i < descriptor->sub_descriptors_count; i++) {
2571 4 MXFFFV1SubDescriptor *ffv1_sub_descriptor = mxf_resolve_strong_ref(mxf, &descriptor->sub_descriptors_refs[i], FFV1SubDescriptor);
2572
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if (ffv1_sub_descriptor == NULL)
2573 3 continue;
2574
2575 1 descriptor->extradata = ffv1_sub_descriptor->extradata;
2576 1 descriptor->extradata_size = ffv1_sub_descriptor->extradata_size;
2577 1 ffv1_sub_descriptor->extradata = NULL;
2578 1 ffv1_sub_descriptor->extradata_size = 0;
2579 1 break;
2580 }
2581 220 }
2582
2583 117 static int parse_mca_labels(MXFContext *mxf, MXFTrack *source_track, MXFDescriptor *descriptor, AVStream *st)
2584 {
2585 117 AVChannelLayout *ch_layout = &st->codecpar->ch_layout;
2586 117 char *language = NULL;
2587 117 int ambigous_language = 0;
2588 117 enum AVAudioServiceType service_type = AV_AUDIO_SERVICE_TYPE_NB;
2589 117 int ambigous_service_type = 0;
2590 int ret;
2591
2592
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
117 for (int i = 0; i < descriptor->sub_descriptors_count; i++) {
2593 char *channel_language;
2594
2595 MXFMCASubDescriptor *label = mxf_resolve_strong_ref(mxf, &descriptor->sub_descriptors_refs[i], AudioChannelLabelSubDescriptor);
2596 if (label == NULL)
2597 continue;
2598
2599 if (ch_layout->order == AV_CHANNEL_ORDER_UNSPEC) {
2600 av_channel_layout_uninit(ch_layout);
2601 ret = av_channel_layout_custom_init(ch_layout, descriptor->channels);
2602 if (ret < 0)
2603 return ret;
2604 }
2605
2606 for (const MXFChannelOrderingUL* channel_ordering = mxf_channel_ordering; channel_ordering->uid[0]; channel_ordering++) {
2607 if (IS_KLV_KEY(channel_ordering->uid, label->mca_label_dictionary_id)) {
2608 int target_channel = label->mca_channel_id;
2609 if (target_channel == 0 && descriptor->channels == 1)
2610 target_channel = 1;
2611 if (target_channel <= 0 || target_channel > descriptor->channels) {
2612 av_log(mxf->fc, AV_LOG_ERROR, "AudioChannelLabelSubDescriptor has invalid MCA channel ID %d\n", target_channel);
2613 return AVERROR_INVALIDDATA;
2614 }
2615 ch_layout->u.map[target_channel - 1].id = channel_ordering->channel;
2616 if (service_type == AV_AUDIO_SERVICE_TYPE_NB)
2617 service_type = channel_ordering->service_type;
2618 else if (service_type != channel_ordering->service_type)
2619 ambigous_service_type = 1;
2620 break;
2621 }
2622 }
2623
2624 channel_language = label->language;
2625 if (!channel_language) {
2626 MXFMCASubDescriptor *group = find_mca_link_id(mxf, SoundfieldGroupLabelSubDescriptor, &label->soundfield_group_link_id);
2627 if (group) {
2628 channel_language = group->language;
2629 if (!channel_language && group->group_of_soundfield_groups_link_id_count) {
2630 MXFMCASubDescriptor *supergroup = find_mca_link_id(mxf, GroupOfSoundfieldGroupsLabelSubDescriptor,
2631 group->group_of_soundfield_groups_link_id_refs);
2632 if (supergroup)
2633 channel_language = supergroup->language;
2634 }
2635 }
2636 }
2637 if (channel_language) {
2638 if (language && strcmp(language, channel_language))
2639 ambigous_language = 1;
2640 else
2641 language = channel_language;
2642 }
2643 }
2644
2645
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
117 if (language && !ambigous_language) {
2646 ret = set_language(mxf->fc, language, &st->metadata);
2647 if (ret < 0)
2648 return ret;
2649 }
2650
2651
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
117 if (service_type != AV_AUDIO_SERVICE_TYPE_NB && service_type != AV_AUDIO_SERVICE_TYPE_MAIN && !ambigous_service_type) {
2652 enum AVAudioServiceType *ast;
2653 AVPacketSideData *side_data = av_packet_side_data_new(&st->codecpar->coded_side_data,
2654 &st->codecpar->nb_coded_side_data,
2655 AV_PKT_DATA_AUDIO_SERVICE_TYPE,
2656 sizeof(*ast), 0);
2657 if (!side_data)
2658 return AVERROR(ENOMEM);
2659 ast = (enum AVAudioServiceType*)side_data->data;
2660 *ast = service_type;
2661 }
2662
2663 117 ret = av_channel_layout_retype(ch_layout, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
2664
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
117 if (ret < 0)
2665 return ret;
2666
2667 117 return 0;
2668 }
2669
2670 108 static int mxf_parse_structural_metadata(MXFContext *mxf)
2671 {
2672 108 MXFPackage *material_package = NULL;
2673 int k, ret;
2674
2675 /* TODO: handle multiple material packages (OP3x) */
2676
1/2
✓ Branch 0 taken 110 times.
✗ Branch 1 not taken.
110 for (int i = 0; i < mxf->packages_count; i++) {
2677 110 material_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], MaterialPackage);
2678
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 2 times.
110 if (material_package) break;
2679 }
2680
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if (!material_package) {
2681 av_log(mxf->fc, AV_LOG_ERROR, "no material package found\n");
2682 return AVERROR_INVALIDDATA;
2683 }
2684
2685 108 mxf_add_umid_metadata(&mxf->fc->metadata, "material_package_umid", material_package);
2686
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 99 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
108 if (material_package->name && material_package->name[0])
2687 9 av_dict_set(&mxf->fc->metadata, "material_package_name", material_package->name, 0);
2688 108 mxf_parse_package_comments(mxf, &mxf->fc->metadata, material_package);
2689
2690
2/2
✓ Branch 0 taken 335 times.
✓ Branch 1 taken 108 times.
443 for (int i = 0; i < material_package->tracks_count; i++) {
2691 335 MXFPackage *source_package = NULL;
2692 335 MXFTrack *material_track = NULL;
2693 335 MXFTrack *source_track = NULL;
2694 335 MXFTrack *temp_track = NULL;
2695 335 MXFDescriptor *descriptor = NULL;
2696 335 MXFStructuralComponent *component = NULL;
2697 335 MXFTimecodeComponent *mxf_tc = NULL;
2698 335 UID *essence_container_ul = NULL;
2699 335 const MXFCodecUL *codec_ul = NULL;
2700 335 const MXFCodecUL *container_ul = NULL;
2701 335 const MXFCodecUL *pix_fmt_ul = NULL;
2702 AVStream *st;
2703 FFStream *sti;
2704 AVTimecode tc;
2705 int flags;
2706
2707
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 335 times.
335 if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) {
2708 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n");
2709 114 continue;
2710 }
2711
2712
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 335 times.
335 if ((component = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, TimecodeComponent))) {
2713 mxf_tc = (MXFTimecodeComponent*)component;
2714 flags = mxf_tc->drop_frame == 1 ? AV_TIMECODE_FLAG_DROPFRAME : 0;
2715 if (av_timecode_init(&tc, mxf_tc->rate, flags, mxf_tc->start_frame, mxf->fc) == 0) {
2716 mxf_add_timecode_metadata(&mxf->fc->metadata, "timecode", &tc);
2717 }
2718 }
2719
2720
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 335 times.
335 if (!(material_track->sequence = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, Sequence))) {
2721 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track sequence strong ref\n");
2722 continue;
2723 }
2724
2725
2/2
✓ Branch 0 taken 343 times.
✓ Branch 1 taken 235 times.
578 for (int j = 0; j < material_track->sequence->structural_components_count; j++) {
2726 343 component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], TimecodeComponent);
2727
2/2
✓ Branch 0 taken 243 times.
✓ Branch 1 taken 100 times.
343 if (!component)
2728 243 continue;
2729
2730 100 mxf_tc = (MXFTimecodeComponent*)component;
2731 100 flags = mxf_tc->drop_frame == 1 ? AV_TIMECODE_FLAG_DROPFRAME : 0;
2732
1/2
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
100 if (av_timecode_init(&tc, mxf_tc->rate, flags, mxf_tc->start_frame, mxf->fc) == 0) {
2733 100 mxf_add_timecode_metadata(&mxf->fc->metadata, "timecode", &tc);
2734 100 break;
2735 }
2736 }
2737
2738 /* TODO: handle multiple source clips, only finds first valid source clip */
2739
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 327 times.
335 if(material_track->sequence->structural_components_count > 1)
2740 8 av_log(mxf->fc, AV_LOG_WARNING, "material track %d: has %d components\n",
2741 8 material_track->track_id, material_track->sequence->structural_components_count);
2742
2743
2/2
✓ Branch 0 taken 340 times.
✓ Branch 1 taken 114 times.
454 for (int j = 0; j < material_track->sequence->structural_components_count; j++) {
2744 340 component = mxf_resolve_sourceclip(mxf, &material_track->sequence->structural_components_refs[j]);
2745
2/2
✓ Branch 0 taken 107 times.
✓ Branch 1 taken 233 times.
340 if (!component)
2746 107 continue;
2747
2748 233 source_package = mxf_resolve_source_package(mxf, component->source_package_ul, component->source_package_uid);
2749
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 221 times.
233 if (!source_package) {
2750 12 av_log(mxf->fc, AV_LOG_TRACE, "material track %d: no corresponding source package found\n", material_track->track_id);
2751 12 continue;
2752 }
2753
1/2
✓ Branch 0 taken 598 times.
✗ Branch 1 not taken.
598 for (k = 0; k < source_package->tracks_count; k++) {
2754
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 598 times.
598 if (!(temp_track = mxf_resolve_strong_ref(mxf, &source_package->tracks_refs[k], Track))) {
2755 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n");
2756 ret = AVERROR_INVALIDDATA;
2757 goto fail_and_free;
2758 }
2759
2/2
✓ Branch 0 taken 221 times.
✓ Branch 1 taken 377 times.
598 if (temp_track->track_id == component->source_track_id) {
2760 221 source_track = temp_track;
2761 221 break;
2762 }
2763 }
2764
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
221 if (!source_track) {
2765 av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source track found\n", material_track->track_id);
2766 break;
2767 }
2768
2769
1/2
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
221 for (k = 0; k < mxf->essence_container_data_count; k++) {
2770 MXFEssenceContainerData *essence_data;
2771
2772
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 221 times.
221 if (!(essence_data = mxf_resolve_strong_ref(mxf, &mxf->essence_container_data_refs[k], EssenceContainerData))) {
2773 av_log(mxf->fc, AV_LOG_TRACE, "could not resolve essence container data strong ref\n");
2774 continue;
2775 }
2776
2/4
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 221 times.
✗ Branch 3 not taken.
221 if (!memcmp(component->source_package_ul, essence_data->package_ul, sizeof(UID)) && !memcmp(component->source_package_uid, essence_data->package_uid, sizeof(UID))) {
2777 221 source_track->body_sid = essence_data->body_sid;
2778 221 source_track->index_sid = essence_data->index_sid;
2779 221 break;
2780 }
2781 }
2782
2783
2/4
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 221 times.
✗ Branch 3 not taken.
221 if(source_track && component)
2784 221 break;
2785 }
2786
4/6
✓ Branch 0 taken 221 times.
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 221 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 221 times.
335 if (!source_track || !component || !source_package) {
2787
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 114 times.
114 if((ret = mxf_add_metadata_stream(mxf, material_track)))
2788 goto fail_and_free;
2789 114 continue;
2790 }
2791
2792
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 221 times.
221 if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) {
2793 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n");
2794 ret = AVERROR_INVALIDDATA;
2795 goto fail_and_free;
2796 }
2797
2798 /* 0001GL00.MXF.A1.mxf_opatom.mxf has the same SourcePackageID as 0001GL.MXF.V1.mxf_opatom.mxf
2799 * This would result in both files appearing to have two streams. Work around this by sanity checking DataDefinition */
2800
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
221 if (memcmp(material_track->sequence->data_definition_ul, source_track->sequence->data_definition_ul, 16)) {
2801 av_log(mxf->fc, AV_LOG_ERROR, "material track %d: DataDefinition mismatch\n", material_track->track_id);
2802 continue;
2803 }
2804
2805 221 st = avformat_new_stream(mxf->fc, NULL);
2806
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
221 if (!st) {
2807 av_log(mxf->fc, AV_LOG_ERROR, "could not allocate stream\n");
2808 ret = AVERROR(ENOMEM);
2809 goto fail_and_free;
2810 }
2811 221 sti = ffstream(st);
2812 221 st->id = material_track->track_id;
2813 221 st->priv_data = source_track;
2814
2815 221 descriptor = mxf_resolve_descriptor(mxf, &source_package->descriptor_ref, source_track->track_id);
2816
2817 /* A SourceClip from a EssenceGroup may only be a single frame of essence data. The clips duration is then how many
2818 * frames its suppose to repeat for. Descriptor->duration, if present, contains the real duration of the essence data */
2819
3/4
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 200 times.
221 if (descriptor && descriptor->duration != AV_NOPTS_VALUE)
2820 21 source_track->original_duration = st->duration = FFMIN(descriptor->duration, component->duration);
2821 else
2822 200 source_track->original_duration = st->duration = component->duration;
2823
2824
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 209 times.
221 if (st->duration == -1)
2825 12 st->duration = AV_NOPTS_VALUE;
2826 221 st->start_time = component->start_position;
2827
1/2
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
221 if (material_track->edit_rate.num <= 0 ||
2828
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
221 material_track->edit_rate.den <= 0) {
2829 av_log(mxf->fc, AV_LOG_WARNING,
2830 "Invalid edit rate (%d/%d) found on stream #%d, "
2831 "defaulting to 25/1\n",
2832 material_track->edit_rate.num,
2833 material_track->edit_rate.den, st->index);
2834 material_track->edit_rate = (AVRational){25, 1};
2835 }
2836 221 avpriv_set_pts_info(st, 64, material_track->edit_rate.den, material_track->edit_rate.num);
2837
2838 /* ensure SourceTrack EditRate == MaterialTrack EditRate since only
2839 * the former is accessible via st->priv_data */
2840 221 source_track->edit_rate = material_track->edit_rate;
2841
2842 PRINT_KEY(mxf->fc, "data definition ul", source_track->sequence->data_definition_ul);
2843 221 codec_ul = mxf_get_codec_ul(ff_mxf_data_definition_uls, &source_track->sequence->data_definition_ul);
2844 221 st->codecpar->codec_type = codec_ul->id;
2845
2846
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
221 if (!descriptor) {
2847 av_log(mxf->fc, AV_LOG_INFO, "source track %d: stream %d, no descriptor found\n", source_track->track_id, st->index);
2848 continue;
2849 }
2850 PRINT_KEY(mxf->fc, "essence codec ul", descriptor->essence_codec_ul);
2851 PRINT_KEY(mxf->fc, "essence container ul", descriptor->essence_container_ul);
2852 221 essence_container_ul = &descriptor->essence_container_ul;
2853
2/2
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 11 times.
221 source_track->wrapping = (mxf->op == OPAtom) ? ClipWrapped : mxf_get_wrapping_kind(essence_container_ul);
2854
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 216 times.
221 if (source_track->wrapping == UnknownWrapped)
2855 5 av_log(mxf->fc, AV_LOG_INFO, "wrapping of stream %d is unknown\n", st->index);
2856 /* HACK: replacing the original key with mxf_encrypted_essence_container
2857 * is not allowed according to s429-6, try to find correct information anyway */
2858
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
221 if (IS_KLV_KEY(essence_container_ul, mxf_encrypted_essence_container)) {
2859 MXFMetadataSetGroup *mg = &mxf->metadata_set_groups[CryptoContext];
2860 av_log(mxf->fc, AV_LOG_INFO, "broken encrypted mxf file\n");
2861 if (mg->metadata_sets_count) {
2862 MXFMetadataSet *metadata = mg->metadata_sets[0];
2863 essence_container_ul = &((MXFCryptoContext *)metadata)->source_container_ul;
2864 }
2865 }
2866
2867 /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
2868 221 codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->essence_codec_ul);
2869 221 st->codecpar->codec_id = (enum AVCodecID)codec_ul->id;
2870
2/2
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 110 times.
221 if (st->codecpar->codec_id == AV_CODEC_ID_NONE) {
2871 111 codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->codec_ul);
2872 111 st->codecpar->codec_id = (enum AVCodecID)codec_ul->id;
2873 }
2874
2875 221 av_log(mxf->fc, AV_LOG_VERBOSE, "%s: Universal Label: ",
2876 221 avcodec_get_name(st->codecpar->codec_id));
2877
2/2
✓ Branch 0 taken 3536 times.
✓ Branch 1 taken 221 times.
3757 for (k = 0; k < 16; k++) {
2878 3536 av_log(mxf->fc, AV_LOG_VERBOSE, "%.2x",
2879 3536 descriptor->essence_codec_ul[k]);
2880
4/4
✓ Branch 0 taken 2873 times.
✓ Branch 1 taken 663 times.
✓ Branch 2 taken 221 times.
✓ Branch 3 taken 2652 times.
3536 if (!(k+1 & 19) || k == 5)
2881 884 av_log(mxf->fc, AV_LOG_VERBOSE, ".");
2882 }
2883 221 av_log(mxf->fc, AV_LOG_VERBOSE, "\n");
2884
2885 221 mxf_add_umid_metadata(&st->metadata, "file_package_umid", source_package);
2886
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 212 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
221 if (source_package->name && source_package->name[0])
2887 9 av_dict_set(&st->metadata, "file_package_name", source_package->name, 0);
2888
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 212 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3 times.
221 if (material_track->name && material_track->name[0])
2889 6 av_dict_set(&st->metadata, "track_name", material_track->name, 0);
2890
2891 221 mxf_parse_physical_source_package(mxf, source_track, st);
2892
2893
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 118 times.
221 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
2894 103 source_track->intra_only = mxf_is_intra_only(descriptor);
2895 103 container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
2896
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 100 times.
103 if (st->codecpar->codec_id == AV_CODEC_ID_NONE)
2897 3 st->codecpar->codec_id = container_ul->id;
2898 103 st->codecpar->width = descriptor->width;
2899 103 st->codecpar->height = descriptor->height; /* Field height, not frame height */
2900
2/6
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
103 switch (descriptor->frame_layout) {
2901 54 case FullFrame:
2902 54 st->codecpar->field_order = AV_FIELD_PROGRESSIVE;
2903 54 break;
2904 case OneField:
2905 /* Every other line is stored and needs to be duplicated. */
2906 av_log(mxf->fc, AV_LOG_INFO, "OneField frame layout isn't currently supported\n");
2907 break; /* The correct thing to do here is fall through, but by breaking we might be
2908 able to decode some streams at half the vertical resolution, rather than not al all.
2909 It's also for compatibility with the old behavior. */
2910 case MixedFields:
2911 break;
2912 case SegmentedFrame:
2913 st->codecpar->field_order = AV_FIELD_PROGRESSIVE;
2914 49 case SeparateFields:
2915 49 av_log(mxf->fc, AV_LOG_DEBUG, "video_line_map: (%d, %d), field_dominance: %d\n",
2916 descriptor->video_line_map[0], descriptor->video_line_map[1],
2917 descriptor->field_dominance);
2918
2/4
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 if ((descriptor->video_line_map[0] > 0) && (descriptor->video_line_map[1] > 0)) {
2919 /* Detect coded field order from VideoLineMap:
2920 * (even, even) => bottom field coded first
2921 * (even, odd) => top field coded first
2922 * (odd, even) => top field coded first
2923 * (odd, odd) => bottom field coded first
2924 */
2925
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 6 times.
49 if ((descriptor->video_line_map[0] + descriptor->video_line_map[1]) % 2) {
2926
1/3
✓ Branch 0 taken 43 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
43 switch (descriptor->field_dominance) {
2927 43 case MXF_FIELD_DOMINANCE_DEFAULT:
2928 case MXF_FIELD_DOMINANCE_FF:
2929 43 st->codecpar->field_order = AV_FIELD_TT;
2930 43 break;
2931 case MXF_FIELD_DOMINANCE_FL:
2932 st->codecpar->field_order = AV_FIELD_TB;
2933 break;
2934 default:
2935 avpriv_request_sample(mxf->fc,
2936 "Field dominance %d support",
2937 descriptor->field_dominance);
2938 }
2939 } else {
2940
1/3
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
6 switch (descriptor->field_dominance) {
2941 6 case MXF_FIELD_DOMINANCE_DEFAULT:
2942 case MXF_FIELD_DOMINANCE_FF:
2943 6 st->codecpar->field_order = AV_FIELD_BB;
2944 6 break;
2945 case MXF_FIELD_DOMINANCE_FL:
2946 st->codecpar->field_order = AV_FIELD_BT;
2947 break;
2948 default:
2949 avpriv_request_sample(mxf->fc,
2950 "Field dominance %d support",
2951 descriptor->field_dominance);
2952 }
2953 }
2954 }
2955 /* Turn field height into frame height. */
2956 49 st->codecpar->height *= 2;
2957 49 break;
2958 default:
2959 av_log(mxf->fc, AV_LOG_INFO, "Unknown frame layout type: %d\n", descriptor->frame_layout);
2960 }
2961
2962
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 101 times.
103 if (mxf_is_st_422(essence_container_ul)) {
2963
2/3
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
2 switch ((*essence_container_ul)[14]) {
2964 1 case 2: /* Cn: Clip- wrapped Picture Element */
2965 case 3: /* I1: Interlaced Frame, 1 field/KLV */
2966 case 4: /* I2: Interlaced Frame, 2 fields/KLV */
2967 case 6: /* P1: Frame- wrapped Picture Element */
2968 1 st->avg_frame_rate = source_track->edit_rate;
2969 1 st->r_frame_rate = st->avg_frame_rate;
2970 1 break;
2971 case 5: /* F1: Field-wrapped Picture Element */
2972 st->avg_frame_rate = av_mul_q(av_make_q(2, 1), source_track->edit_rate);
2973 st->r_frame_rate = st->avg_frame_rate;
2974 break;
2975 1 default:
2976 1 break;
2977 }
2978 }
2979
2980
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 98 times.
103 if (st->codecpar->codec_id == AV_CODEC_ID_PRORES) {
2981
1/7
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
5 switch (descriptor->essence_codec_ul[14]) {
2982 5 case 1: st->codecpar->codec_tag = MKTAG('a','p','c','o'); break;
2983 case 2: st->codecpar->codec_tag = MKTAG('a','p','c','s'); break;
2984 case 3: st->codecpar->codec_tag = MKTAG('a','p','c','n'); break;
2985 case 4: st->codecpar->codec_tag = MKTAG('a','p','c','h'); break;
2986 case 5: st->codecpar->codec_tag = MKTAG('a','p','4','h'); break;
2987 case 6: st->codecpar->codec_tag = MKTAG('a','p','4','x'); break;
2988 }
2989 }
2990
2991
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 102 times.
103 if (st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO) {
2992 1 st->codecpar->format = descriptor->pix_fmt;
2993
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (st->codecpar->format == AV_PIX_FMT_NONE) {
2994 pix_fmt_ul = mxf_get_codec_ul(ff_mxf_pixel_format_uls,
2995 &descriptor->essence_codec_ul);
2996 st->codecpar->format = (enum AVPixelFormat)pix_fmt_ul->id;
2997 if (st->codecpar->format== AV_PIX_FMT_NONE) {
2998 st->codecpar->codec_tag = mxf_get_codec_ul(ff_mxf_codec_tag_uls,
2999 &descriptor->essence_codec_ul)->id;
3000 if (!st->codecpar->codec_tag) {
3001 /* support files created before RP224v10 by defaulting to UYVY422
3002 if subsampling is 4:2:2 and component depth is 8-bit */
3003 if (descriptor->horiz_subsampling == 2 &&
3004 descriptor->vert_subsampling == 1 &&
3005 descriptor->component_depth == 8) {
3006 st->codecpar->format = AV_PIX_FMT_UYVY422;
3007 }
3008 }
3009 }
3010 }
3011 }
3012 103 sti->need_parsing = AVSTREAM_PARSE_HEADERS;
3013
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 103 times.
103 if (material_track->sequence->origin) {
3014 av_dict_set_int(&st->metadata, "material_track_origin", material_track->sequence->origin, 0);
3015 }
3016
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 103 times.
103 if (source_track->sequence->origin) {
3017 av_dict_set_int(&st->metadata, "source_track_origin", source_track->sequence->origin, 0);
3018 }
3019
2/4
✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103 times.
✗ Branch 3 not taken.
103 if (descriptor->aspect_ratio.num && descriptor->aspect_ratio.den)
3020 103 sti->display_aspect_ratio = descriptor->aspect_ratio;
3021 103 st->codecpar->color_range = mxf_get_color_range(mxf, descriptor);
3022 103 st->codecpar->color_primaries = mxf_get_codec_ul(ff_mxf_color_primaries_uls, &descriptor->color_primaries_ul)->id;
3023 103 st->codecpar->color_trc = mxf_get_codec_ul(ff_mxf_color_trc_uls, &descriptor->color_trc_ul)->id;
3024 103 st->codecpar->color_space = mxf_get_codec_ul(ff_mxf_color_space_uls, &descriptor->color_space_ul)->id;
3025
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 98 times.
103 if (descriptor->mastering) {
3026
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!av_packet_side_data_add(&st->codecpar->coded_side_data, &st->codecpar->nb_coded_side_data,
3027 AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
3028 5 (uint8_t *)descriptor->mastering, descriptor->mastering_size, 0)) {
3029 ret = AVERROR(ENOMEM);
3030 goto fail_and_free;
3031 }
3032 5 descriptor->mastering = NULL;
3033 }
3034
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 100 times.
103 if (descriptor->coll) {
3035
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!av_packet_side_data_add(&st->codecpar->coded_side_data, &st->codecpar->nb_coded_side_data,
3036 AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
3037 3 (uint8_t *)descriptor->coll, descriptor->coll_size, 0)) {
3038 ret = AVERROR(ENOMEM);
3039 goto fail_and_free;
3040 }
3041 3 descriptor->coll = NULL;
3042 }
3043
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 1 times.
118 } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
3044 117 container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
3045 /* Only overwrite existing codec ID if it is unset or A-law, which is the default according to SMPTE RP 224. */
3046
5/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 107 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
117 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))
3047 107 st->codecpar->codec_id = (enum AVCodecID)container_ul->id;
3048 117 st->codecpar->ch_layout.nb_channels = descriptor->channels;
3049
3050
1/2
✓ Branch 0 taken 117 times.
✗ Branch 1 not taken.
117 if (descriptor->sample_rate.den > 0) {
3051 117 st->codecpar->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den;
3052 117 avpriv_set_pts_info(st, 64, descriptor->sample_rate.den, descriptor->sample_rate.num);
3053 } else {
3054 av_log(mxf->fc, AV_LOG_WARNING, "invalid sample rate (%d/%d) "
3055 "found for stream #%d, time base forced to 1/48000\n",
3056 descriptor->sample_rate.num, descriptor->sample_rate.den,
3057 st->index);
3058 avpriv_set_pts_info(st, 64, 1, 48000);
3059 }
3060
3061 /* if duration is set, rescale it from EditRate to SampleRate */
3062
2/2
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 6 times.
117 if (st->duration != AV_NOPTS_VALUE)
3063 111 st->duration = av_rescale_q(st->duration,
3064 av_inv_q(material_track->edit_rate),
3065 st->time_base);
3066
3067 /* TODO: implement AV_CODEC_ID_RAWAUDIO */
3068
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 4 times.
117 if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S16LE) {
3069
3/4
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
113 if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24)
3070 23 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24LE;
3071
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 90 times.
90 else if (descriptor->bits_per_sample == 32)
3072 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;
3073
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 } else if (st->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE) {
3074 if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24)
3075 st->codecpar->codec_id = AV_CODEC_ID_PCM_S24BE;
3076 else if (descriptor->bits_per_sample == 32)
3077 st->codecpar->codec_id = AV_CODEC_ID_PCM_S32BE;
3078
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 } else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) {
3079 sti->need_parsing = AVSTREAM_PARSE_FULL;
3080
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 } else if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
3081 sti->need_parsing = AVSTREAM_PARSE_FULL;
3082 }
3083 117 st->codecpar->bits_per_coded_sample = av_get_bits_per_sample(st->codecpar->codec_id);
3084
3085
2/4
✓ Branch 0 taken 117 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 117 times.
117 if (descriptor->channels <= 0 || descriptor->channels >= FF_SANE_NB_CHANNELS) {
3086 av_log(mxf->fc, AV_LOG_ERROR, "Invalid number of channels %d, must be less than %d\n", descriptor->channels, FF_SANE_NB_CHANNELS);
3087 return AVERROR_INVALIDDATA;
3088 }
3089
3090 117 ret = parse_mca_labels(mxf, source_track, descriptor, st);
3091
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
117 if (ret < 0)
3092 return ret;
3093
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
3094 enum AVMediaType type;
3095 1 container_ul = mxf_get_codec_ul(mxf_data_essence_container_uls, essence_container_ul);
3096
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (st->codecpar->codec_id == AV_CODEC_ID_NONE)
3097 1 st->codecpar->codec_id = container_ul->id;
3098 1 type = avcodec_get_type(st->codecpar->codec_id);
3099
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (type == AVMEDIA_TYPE_SUBTITLE)
3100 st->codecpar->codec_type = type;
3101
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (container_ul->desc)
3102 1 av_dict_set(&st->metadata, "data_type", container_ul->desc, 0);
3103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (mxf->eia608_extract &&
3104 container_ul->desc &&
3105 !strcmp(container_ul->desc, "vbi_vanc_smpte_436M")) {
3106 st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
3107 st->codecpar->codec_id = AV_CODEC_ID_EIA_608;
3108 }
3109 }
3110
2/2
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 1 times.
221 if (!descriptor->extradata)
3111 220 parse_ffv1_sub_descriptor(mxf, source_track, descriptor, st);
3112
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 219 times.
221 if (descriptor->extradata) {
3113
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!ff_alloc_extradata(st->codecpar, descriptor->extradata_size)) {
3114 2 memcpy(st->codecpar->extradata, descriptor->extradata, descriptor->extradata_size);
3115 }
3116
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 218 times.
219 } else if (st->codecpar->codec_id == AV_CODEC_ID_H264) {
3117 1 int coded_width = mxf_get_codec_ul(mxf_intra_only_picture_coded_width,
3118 &descriptor->essence_codec_ul)->id;
3119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (coded_width)
3120 st->codecpar->width = coded_width;
3121 1 ret = ff_generate_avci_extradata(st);
3122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
3123 return ret;
3124 }
3125
4/4
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 204 times.
221 if (st->codecpar->codec_type != AVMEDIA_TYPE_DATA && source_track->wrapping != FrameWrapped) {
3126 /* TODO: decode timestamps */
3127 16 sti->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
3128 }
3129 }
3130
3131
2/2
✓ Branch 0 taken 233 times.
✓ Branch 1 taken 108 times.
341 for (int i = 0; i < mxf->fc->nb_streams; i++) {
3132 233 MXFTrack *track1 = mxf->fc->streams[i]->priv_data;
3133
3/4
✓ Branch 0 taken 221 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 221 times.
✗ Branch 3 not taken.
233 if (track1 && track1->body_sid) {
3134
2/2
✓ Branch 0 taken 167 times.
✓ Branch 1 taken 221 times.
388 for (int j = i + 1; j < mxf->fc->nb_streams; j++) {
3135 167 MXFTrack *track2 = mxf->fc->streams[j]->priv_data;
3136
4/6
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 164 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 164 times.
167 if (track2 && track1->body_sid == track2->body_sid && track1->wrapping != track2->wrapping) {
3137 if (track1->wrapping == UnknownWrapped)
3138 track1->wrapping = track2->wrapping;
3139 else if (track2->wrapping == UnknownWrapped)
3140 track2->wrapping = track1->wrapping;
3141 else
3142 av_log(mxf->fc, AV_LOG_ERROR, "stream %d and stream %d have the same BodySID (%d) "
3143 "with different wrapping\n", i, j, track1->body_sid);
3144 }
3145 }
3146 }
3147 }
3148
3149 108 ret = 0;
3150 108 fail_and_free:
3151 108 return ret;
3152 }
3153
3154 20 static int64_t mxf_timestamp_to_int64(uint64_t timestamp)
3155 {
3156 20 struct tm time = { 0 };
3157 int msecs;
3158 20 time.tm_year = (timestamp >> 48) - 1900;
3159 20 time.tm_mon = (timestamp >> 40 & 0xFF) - 1;
3160 20 time.tm_mday = (timestamp >> 32 & 0xFF);
3161 20 time.tm_hour = (timestamp >> 24 & 0xFF);
3162 20 time.tm_min = (timestamp >> 16 & 0xFF);
3163 20 time.tm_sec = (timestamp >> 8 & 0xFF);
3164 20 msecs = (timestamp & 0xFF) * 4;
3165
3166 /* Clip values for legacy reasons. Maybe we should return error instead? */
3167 20 time.tm_mon = av_clip(time.tm_mon, 0, 11);
3168 20 time.tm_mday = av_clip(time.tm_mday, 1, 31);
3169 20 time.tm_hour = av_clip(time.tm_hour, 0, 23);
3170 20 time.tm_min = av_clip(time.tm_min, 0, 59);
3171 20 time.tm_sec = av_clip(time.tm_sec, 0, 59);
3172 20 msecs = av_clip(msecs, 0, 999);
3173
3174 20 return (int64_t)av_timegm(&time) * 1000000 + msecs * 1000;
3175 }
3176
3177 #define SET_STR_METADATA(pb, name, str) do { \
3178 if ((ret = mxf_read_utf16be_string(pb, size, &str)) < 0) \
3179 return ret; \
3180 av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \
3181 } while (0)
3182
3183 #define SET_VERSION_METADATA(pb, name, major, minor, tertiary, patch, release, str) do { \
3184 major = avio_rb16(pb); \
3185 minor = avio_rb16(pb); \
3186 tertiary = avio_rb16(pb); \
3187 patch = avio_rb16(pb); \
3188 release = avio_rb16(pb); \
3189 if ((ret = mxf_version_to_str(major, minor, tertiary, patch, release, &str)) < 0) \
3190 return ret; \
3191 av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \
3192 } while (0)
3193
3194 #define SET_UID_METADATA(pb, name, var, str) do { \
3195 char uuid_str[2 * AV_UUID_LEN + 4 + 1]; \
3196 avio_read(pb, var, 16); \
3197 av_uuid_unparse(uid, uuid_str); \
3198 av_dict_set(&s->metadata, name, uuid_str, 0); \
3199 } while (0)
3200
3201 #define SET_TS_METADATA(pb, name, var, str) do { \
3202 var = avio_rb64(pb); \
3203 if (var && (ret = avpriv_dict_set_timestamp(&s->metadata, name, mxf_timestamp_to_int64(var))) < 0) \
3204 return ret; \
3205 } while (0)
3206
3207 1032 static int mxf_read_identification_metadata(void *arg, AVIOContext *pb, int tag, int size, UID _uid, int64_t klv_offset)
3208 {
3209 1032 MXFContext *mxf = arg;
3210 1032 AVFormatContext *s = mxf->fc;
3211 int ret;
3212 1032 UID uid = { 0 };
3213 1032 char *str = NULL;
3214 uint64_t ts;
3215 uint16_t major, minor, tertiary, patch, release;
3216
11/11
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 92 times.
✓ Branch 3 taken 105 times.
✓ Branch 4 taken 105 times.
✓ Branch 5 taken 105 times.
✓ Branch 6 taken 97 times.
✓ Branch 7 taken 96 times.
✓ Branch 8 taken 109 times.
✓ Branch 9 taken 109 times.
✓ Branch 10 taken 4 times.
1032 switch (tag) {
3217 105 case 0x3C01:
3218
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 105 times.
105 SET_STR_METADATA(pb, "company_name", str);
3219 105 break;
3220 105 case 0x3C02:
3221
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 105 times.
105 SET_STR_METADATA(pb, "product_name", str);
3222 105 break;
3223 92 case 0x3C03:
3224
1/2
✗ Branch 6 not taken.
✓ Branch 7 taken 92 times.
92 SET_VERSION_METADATA(pb, "product_version_num", major, minor, tertiary, patch, release, str);
3225 92 break;
3226 105 case 0x3C04:
3227
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 105 times.
105 SET_STR_METADATA(pb, "product_version", str);
3228 105 break;
3229 105 case 0x3C05:
3230 105 SET_UID_METADATA(pb, "product_uid", uid, str);
3231 105 break;
3232 105 case 0x3C06:
3233
3/4
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 85 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20 times.
105 SET_TS_METADATA(pb, "modification_date", ts, str);
3234 105 break;
3235 97 case 0x3C07:
3236
1/2
✗ Branch 6 not taken.
✓ Branch 7 taken 97 times.
97 SET_VERSION_METADATA(pb, "toolkit_version_num", major, minor, tertiary, patch, release, str);
3237 97 break;
3238 96 case 0x3C08:
3239
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 96 times.
96 SET_STR_METADATA(pb, "application_platform", str);
3240 96 break;
3241 109 case 0x3C09:
3242 109 SET_UID_METADATA(pb, "generation_uid", uid, str);
3243 109 break;
3244 109 case 0x3C0A:
3245 109 SET_UID_METADATA(pb, "uid", uid, str);
3246 109 break;
3247 }
3248 1032 return 0;
3249 }
3250
3251 1013 static int mxf_read_preface_metadata(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
3252 {
3253 1013 MXFContext *mxf = arg;
3254 1013 AVFormatContext *s = mxf->fc;
3255 int ret;
3256 1013 char *str = NULL;
3257
3258
4/4
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 982 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 24 times.
1013 if (tag >= 0x8000 && (IS_KLV_KEY(uid, mxf_avid_project_name))) {
3259
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 SET_STR_METADATA(pb, "project_name", str);
3260 }
3261 1013 return 0;
3262 }
3263
3264 static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
3265 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }, mxf_read_primer_pack },
3266 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }, mxf_read_partition_pack },
3267 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x02,0x00 }, mxf_read_partition_pack },
3268 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x03,0x00 }, mxf_read_partition_pack },
3269 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }, mxf_read_partition_pack },
3270 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x01,0x00 }, mxf_read_partition_pack },
3271 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x02,0x00 }, mxf_read_partition_pack },
3272 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x03,0x00 }, mxf_read_partition_pack },
3273 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x04,0x00 }, mxf_read_partition_pack },
3274 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x02,0x00 }, mxf_read_partition_pack },
3275 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }, mxf_read_partition_pack },
3276 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x2f,0x00 }, mxf_read_preface_metadata },
3277 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x30,0x00 }, mxf_read_identification_metadata },
3278 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_content_storage },
3279 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_package, sizeof(MXFPackage), SourcePackage },
3280 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_package, sizeof(MXFPackage), MaterialPackage },
3281 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0f,0x00 }, mxf_read_sequence, sizeof(MXFSequence), Sequence },
3282 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x05,0x00 }, mxf_read_essence_group, sizeof(MXFEssenceGroup), EssenceGroup},
3283 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_source_clip, sizeof(MXFStructuralComponent), SourceClip },
3284 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3f,0x00 }, mxf_read_tagged_value, sizeof(MXFTaggedValue), TaggedValue },
3285 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x44,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), MultipleDescriptor },
3286 { { 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 */
3287 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x28,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* CDCI */
3288 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x29,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* RGBA */
3289 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Wave */
3290 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* AES3 */
3291 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG2VideoDescriptor */
3292 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5b,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* VBI - SMPTE 436M */
3293 { { 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 */
3294 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5e,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG2AudioDescriptor */
3295 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x64,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* DC Timed Text Descriptor */
3296 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6b,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), AudioChannelLabelSubDescriptor },
3297 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6c,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), SoundfieldGroupLabelSubDescriptor },
3298 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6d,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), GroupOfSoundfieldGroupsLabelSubDescriptor },
3299 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x81,0x03 }, mxf_read_ffv1_sub_descriptor, sizeof(MXFFFV1SubDescriptor), FFV1SubDescriptor },
3300 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Static Track */
3301 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Generic Track */
3302 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x14,0x00 }, mxf_read_timecode_component, sizeof(MXFTimecodeComponent), TimecodeComponent },
3303 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0c,0x00 }, mxf_read_pulldown_component, sizeof(MXFPulldownComponent), PulldownComponent },
3304 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 }, mxf_read_cryptographic_context, sizeof(MXFCryptoContext), CryptoContext },
3305 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 }, mxf_read_index_table_segment, sizeof(MXFIndexTableSegment), IndexTableSegment },
3306 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x23,0x00 }, mxf_read_essence_container_data, sizeof(MXFEssenceContainerData), EssenceContainerData },
3307 { { 0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x10,0x01,0x00,0x00,0x00 } }, /* KLV fill, skip */
3308 };
3309
3310 2951 static int mxf_metadataset_init(MXFMetadataSet *ctx, enum MXFMetadataSetType type, MXFPartition *partition)
3311 {
3312 2951 ctx->partition_score = partition_score(partition);
3313
2/2
✓ Branch 0 taken 323 times.
✓ Branch 1 taken 2628 times.
2951 switch (type){
3314 323 case MultipleDescriptor:
3315 case Descriptor:
3316 323 ((MXFDescriptor*)ctx)->pix_fmt = AV_PIX_FMT_NONE;
3317 323 ((MXFDescriptor*)ctx)->duration = AV_NOPTS_VALUE;
3318 323 break;
3319 2628 default:
3320 2628 break;
3321 }
3322 2951 return 0;
3323 }
3324
3325 3278 static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadFunc *read_child, int ctx_size, enum MXFMetadataSetType type)
3326 {
3327 3278 AVIOContext *pb = mxf->fc->pb;
3328 3278 uint64_t klv_end = avio_tell(pb) + klv->length;
3329 MXFMetadataSet *meta;
3330 void *ctx;
3331
3332
2/2
✓ Branch 0 taken 2951 times.
✓ Branch 1 taken 327 times.
3278 if (ctx_size) {
3333 2951 meta = av_mallocz(ctx_size);
3334
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2951 times.
2951 if (!meta)
3335 return AVERROR(ENOMEM);
3336 2951 ctx = meta;
3337 2951 mxf_metadataset_init(meta, type, mxf->current_partition);
3338 } else {
3339 327 meta = NULL;
3340 327 ctx = mxf;
3341 }
3342
3/4
✓ Branch 1 taken 21600 times.
✓ Branch 2 taken 3278 times.
✓ Branch 4 taken 21600 times.
✗ Branch 5 not taken.
24878 while (avio_tell(pb) + 4ULL < klv_end && !avio_feof(pb)) {
3343 int ret;
3344 21600 int tag = avio_rb16(pb);
3345 21600 int size = avio_rb16(pb); /* KLV specified by 0x53 */
3346 21600 int64_t next = avio_tell(pb);
3347 21600 UID uid = {0};
3348
2/4
✓ Branch 0 taken 21600 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 21600 times.
21600 if (next < 0 || next > INT64_MAX - size) {
3349 if (meta) {
3350 mxf_free_metadataset(&meta, type);
3351 }
3352 return next < 0 ? next : AVERROR_INVALIDDATA;
3353 }
3354 21600 next += size;
3355
3356 21600 av_log(mxf->fc, AV_LOG_TRACE, "local tag %#04x size %d\n", tag, size);
3357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21600 times.
21600 if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */
3358 av_log(mxf->fc, AV_LOG_ERROR, "local tag %#04x with 0 size\n", tag);
3359 continue;
3360 }
3361
2/2
✓ Branch 0 taken 385 times.
✓ Branch 1 taken 21215 times.
21600 if (tag > 0x7FFF) { /* dynamic tag */
3362 int i;
3363
2/2
✓ Branch 0 taken 56987 times.
✓ Branch 1 taken 385 times.
57372 for (i = 0; i < mxf->local_tags_count; i++) {
3364 56987 int local_tag = AV_RB16(mxf->local_tags+i*18);
3365
2/2
✓ Branch 0 taken 385 times.
✓ Branch 1 taken 56602 times.
56987 if (local_tag == tag) {
3366 385 memcpy(uid, mxf->local_tags+i*18+2, 16);
3367 385 av_log(mxf->fc, AV_LOG_TRACE, "local tag %#04x\n", local_tag);
3368 PRINT_KEY(mxf->fc, "uid", uid);
3369 }
3370 }
3371 }
3372
4/4
✓ Branch 0 taken 19228 times.
✓ Branch 1 taken 2372 times.
✓ Branch 2 taken 2951 times.
✓ Branch 3 taken 16277 times.
21600 if (meta && tag == 0x3C0A) {
3373 2951 avio_read(pb, meta->uid, 16);
3374
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 18649 times.
18649 } else if ((ret = read_child(ctx, pb, tag, size, uid, -1)) < 0) {
3375 if (meta) {
3376 mxf_free_metadataset(&meta, type);
3377 }
3378 return ret;
3379 }
3380
3381 /* Accept the 64k local set limit being exceeded (Avid). Don't accept
3382 * it extending past the end of the KLV though (zzuf5.mxf). */
3383
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 21600 times.
21600 if (avio_tell(pb) > klv_end) {
3384 if (meta) {
3385 mxf_free_metadataset(&meta, type);
3386 }
3387
3388 av_log(mxf->fc, AV_LOG_ERROR,
3389 "local tag %#04x extends past end of local set @ %#"PRIx64"\n",
3390 tag, klv->offset);
3391 return AVERROR_INVALIDDATA;
3392
2/2
✓ Branch 1 taken 21596 times.
✓ Branch 2 taken 4 times.
21600 } else if (avio_tell(pb) <= next) /* only seek forward, else this can loop for a long time */
3393 21596 avio_seek(pb, next, SEEK_SET);
3394 }
3395
2/2
✓ Branch 0 taken 2951 times.
✓ Branch 1 taken 327 times.
3278 return meta ? mxf_add_metadata_set(mxf, &meta, type) : 0;
3396 }
3397
3398 /**
3399 * Matches any partition pack key, in other words:
3400 * - HeaderPartition
3401 * - BodyPartition
3402 * - FooterPartition
3403 * @return non-zero if the key is a partition pack key, zero otherwise
3404 */
3405 8709 static int mxf_is_partition_pack_key(UID key)
3406 {
3407 //NOTE: this is a little lax since it doesn't constraint key[14]
3408 9092 return !memcmp(key, mxf_header_partition_pack_key, 13) &&
3409
5/6
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 8326 times.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 274 times.
✓ Branch 5 taken 109 times.
8709 key[13] >= 2 && key[13] <= 4;
3410 }
3411
3412 /**
3413 * Parses a metadata KLV
3414 * @return <0 on error, 0 otherwise
3415 */
3416 3657 static int mxf_parse_klv(MXFContext *mxf, KLVPacket klv, MXFMetadataReadFunc *read,
3417 int ctx_size, enum MXFMetadataSetType type)
3418 {
3419 3657 AVFormatContext *s = mxf->fc;
3420 int res;
3421
2/2
✓ Branch 0 taken 3278 times.
✓ Branch 1 taken 379 times.
3657 if (klv.key[5] == 0x53) {
3422 3278 res = mxf_read_local_tags(mxf, &klv, read, ctx_size, type);
3423 } else {
3424 379 uint64_t next = avio_tell(s->pb) + klv.length;
3425 379 res = read(mxf, s->pb, 0, klv.length, klv.key, klv.offset);
3426
3427 /* only seek forward, else this can loop for a long time */
3428
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 379 times.
379 if (avio_tell(s->pb) > next) {
3429 av_log(s, AV_LOG_ERROR, "read past end of KLV @ %#"PRIx64"\n",
3430 klv.offset);
3431 return AVERROR_INVALIDDATA;
3432 }
3433
3434 379 avio_seek(s->pb, next, SEEK_SET);
3435 }
3436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3657 times.
3657 if (res < 0) {
3437 av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
3438 return res;
3439 }
3440 3657 return 0;
3441 }
3442
3443 /**
3444 * Seeks to the previous partition and parses it, if possible
3445 * @return <= 0 if we should stop parsing, > 0 if we should keep going
3446 */
3447 106 static int mxf_seek_to_previous_partition(MXFContext *mxf)
3448 {
3449 106 AVIOContext *pb = mxf->fc->pb;
3450 KLVPacket klv;
3451 int64_t current_partition_ofs;
3452 int ret;
3453
3454
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 1 times.
106 if (!mxf->current_partition ||
3455
2/2
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 4 times.
105 mxf->run_in + mxf->current_partition->previous_partition <= mxf->last_forward_tell)
3456 102 return 0; /* we've parsed all partitions */
3457
3458 /* seek to previous partition */
3459 4 current_partition_ofs = mxf->current_partition->pack_ofs; //includes run-in
3460 4 avio_seek(pb, mxf->run_in + mxf->current_partition->previous_partition, SEEK_SET);
3461 4 mxf->current_partition = NULL;
3462
3463 4 av_log(mxf->fc, AV_LOG_TRACE, "seeking to previous partition\n");
3464
3465 /* Make sure this is actually a PartitionPack, and if so parse it.
3466 * See deadlock2.mxf
3467 */
3468
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if ((ret = klv_read_packet(mxf, &klv, pb)) < 0) {
3469 av_log(mxf->fc, AV_LOG_ERROR, "failed to read PartitionPack KLV\n");
3470 return ret;
3471 }
3472
3473
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (!mxf_is_partition_pack_key(klv.key)) {
3474 av_log(mxf->fc, AV_LOG_ERROR, "PreviousPartition @ %" PRIx64 " isn't a PartitionPack\n", klv.offset);
3475 return AVERROR_INVALIDDATA;
3476 }
3477
3478 /* We can't just check ofs >= current_partition_ofs because PreviousPartition
3479 * can point to just before the current partition, causing klv_read_packet()
3480 * to sync back up to it. See deadlock3.mxf
3481 */
3482
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (klv.offset >= current_partition_ofs) {
3483 av_log(mxf->fc, AV_LOG_ERROR, "PreviousPartition for PartitionPack @ %"
3484 PRIx64 " indirectly points to itself\n", current_partition_ofs);
3485 return AVERROR_INVALIDDATA;
3486 }
3487
3488
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if ((ret = mxf_parse_klv(mxf, klv, mxf_read_partition_pack, 0, 0)) < 0)
3489 return ret;
3490
3491 4 return 1;
3492 }
3493
3494 /**
3495 * Called when essence is encountered
3496 * @return <= 0 if we should stop parsing, > 0 if we should keep going
3497 */
3498 108 static int mxf_parse_handle_essence(MXFContext *mxf)
3499 {
3500 108 AVIOContext *pb = mxf->fc->pb;
3501 int64_t ret;
3502
3503
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if (mxf->parsing_backward) {
3504 return mxf_seek_to_previous_partition(mxf);
3505 } else {
3506
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 102 times.
108 if (!mxf->footer_partition) {
3507 6 av_log(mxf->fc, AV_LOG_TRACE, "no FooterPartition\n");
3508 6 return 0;
3509 }
3510
3511 102 av_log(mxf->fc, AV_LOG_TRACE, "seeking to FooterPartition\n");
3512
3513 /* remember where we were so we don't end up seeking further back than this */
3514 102 mxf->last_forward_tell = avio_tell(pb);
3515
3516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
102 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) {
3517 av_log(mxf->fc, AV_LOG_INFO, "file is not seekable - not parsing FooterPartition\n");
3518 return -1;
3519 }
3520
3521 /* seek to FooterPartition and parse backward */
3522
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 102 times.
102 if ((ret = avio_seek(pb, mxf->run_in + mxf->footer_partition, SEEK_SET)) < 0) {
3523 av_log(mxf->fc, AV_LOG_ERROR,
3524 "failed to seek to FooterPartition @ 0x%" PRIx64
3525 " (%"PRId64") - partial file?\n",
3526 mxf->run_in + mxf->footer_partition, ret);
3527 return ret;
3528 }
3529
3530 102 mxf->current_partition = NULL;
3531 102 mxf->parsing_backward = 1;
3532 }
3533
3534 102 return 1;
3535 }
3536
3537 /**
3538 * Called when the next partition or EOF is encountered
3539 * @return <= 0 if we should stop parsing, > 0 if we should keep going
3540 */
3541 163 static int mxf_parse_handle_partition_or_eof(MXFContext *mxf)
3542 {
3543
2/2
✓ Branch 0 taken 106 times.
✓ Branch 1 taken 57 times.
163 return mxf->parsing_backward ? mxf_seek_to_previous_partition(mxf) : 1;
3544 }
3545
3546 97 static MXFWrappingScheme mxf_get_wrapping_by_body_sid(AVFormatContext *s, int body_sid)
3547 {
3548
2/2
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 1 times.
102 for (int i = 0; i < s->nb_streams; i++) {
3549 101 MXFTrack *track = s->streams[i]->priv_data;
3550
4/6
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 96 times.
✓ Branch 5 taken 5 times.
101 if (track && track->body_sid == body_sid && track->wrapping != UnknownWrapped)
3551 96 return track->wrapping;
3552 }
3553 1 return UnknownWrapped;
3554 }
3555
3556 /**
3557 * Figures out the proper offset and length of the essence container in each partition
3558 */
3559 108 static void mxf_compute_essence_containers(AVFormatContext *s)
3560 {
3561 108 MXFContext *mxf = s->priv_data;
3562 int x;
3563
3564
2/2
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 108 times.
378 for (x = 0; x < mxf->partitions_count; x++) {
3565 270 MXFPartition *p = &mxf->partitions[x];
3566 MXFWrappingScheme wrapping;
3567
3568
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 108 times.
270 if (!p->body_sid)
3569 162 continue; /* BodySID == 0 -> no essence */
3570
3571 /* for clip wrapped essences we point essence_offset after the KL (usually klv.offset + 20 or 25)
3572 * otherwise we point essence_offset at the key of the first essence KLV.
3573 */
3574
3575
2/2
✓ Branch 0 taken 97 times.
✓ Branch 1 taken 11 times.
108 wrapping = (mxf->op == OPAtom) ? ClipWrapped : mxf_get_wrapping_by_body_sid(s, p->body_sid);
3576
3577
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 97 times.
108 if (wrapping == ClipWrapped) {
3578 11 p->essence_offset = p->first_essence_klv.next_klv - p->first_essence_klv.length;
3579 11 p->essence_length = p->first_essence_klv.length;
3580 } else {
3581 97 p->essence_offset = p->first_essence_klv.offset;
3582
3583 /* essence container spans to the next partition */
3584
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 7 times.
97 if (x < mxf->partitions_count - 1)
3585 90 p->essence_length = mxf->partitions[x+1].pack_ofs - mxf->run_in - p->essence_offset;
3586
3587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
97 if (p->essence_length < 0) {
3588 /* next ThisPartition < essence_offset */
3589 p->essence_length = 0;
3590 av_log(mxf->fc, AV_LOG_ERROR,
3591 "partition %i: bad ThisPartition = %"PRIX64"\n",
3592 x+1, mxf->partitions[x+1].pack_ofs - mxf->run_in);
3593 }
3594 }
3595 }
3596 108 }
3597
3598 7945 static MXFIndexTable *mxf_find_index_table(MXFContext *mxf, int index_sid)
3599 {
3600 int i;
3601
1/2
✓ Branch 0 taken 7945 times.
✗ Branch 1 not taken.
7945 for (i = 0; i < mxf->nb_index_tables; i++)
3602
1/2
✓ Branch 0 taken 7945 times.
✗ Branch 1 not taken.
7945 if (mxf->index_tables[i].index_sid == index_sid)
3603 7945 return &mxf->index_tables[i];
3604 return NULL;
3605 }
3606
3607 /**
3608 * Deal with the case where for some audio atoms EditUnitByteCount is
3609 * very small (2, 4..). In those cases we should read more than one
3610 * sample per call to mxf_read_packet().
3611 */
3612 233 static void mxf_compute_edit_units_per_packet(MXFContext *mxf, AVStream *st)
3613 {
3614 233 MXFTrack *track = st->priv_data;
3615 MXFIndexTable *t;
3616
3617
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 221 times.
233 if (!track)
3618 12 return;
3619 221 track->edit_units_per_packet = 1;
3620
2/2
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 11 times.
221 if (track->wrapping != ClipWrapped)
3621 210 return;
3622
3623 11 t = mxf_find_index_table(mxf, track->index_sid);
3624
3625 /* expect PCM with exactly one index table segment and a small (< 32) EUBC */
3626
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
16 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
3627
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
10 !is_pcm(st->codecpar->codec_id) ||
3628 5 !t ||
3629
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 t->nb_segments != 1 ||
3630
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 t->segments[0]->edit_unit_byte_count >= 32)
3631 6 return;
3632
3633 /* arbitrarily default to 48 kHz PAL audio frame size */
3634 /* TODO: We could compute this from the ratio between the audio
3635 * and video edit rates for 48 kHz NTSC we could use the
3636 * 1802-1802-1802-1802-1801 pattern. */
3637
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 track->edit_units_per_packet = FFMAX(1, track->edit_rate.num / track->edit_rate.den / 25);
3638 }
3639
3640 /**
3641 * Deal with the case where ClipWrapped essences does not have any IndexTableSegments.
3642 */
3643 233 static int mxf_handle_missing_index_segment(MXFContext *mxf, AVStream *st)
3644 {
3645 233 MXFTrack *track = st->priv_data;
3646 233 MXFIndexTableSegment *segment = NULL;
3647 233 MXFPartition *p = NULL;
3648 233 int essence_partition_count = 0;
3649 233 int edit_unit_byte_count = 0;
3650 int i, ret;
3651 233 MXFMetadataSetGroup *mg = &mxf->metadata_set_groups[IndexTableSegment];
3652
3653
4/4
✓ Branch 0 taken 221 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 210 times.
✓ Branch 3 taken 11 times.
233 if (!track || track->wrapping != ClipWrapped)
3654 222 return 0;
3655
3656 /* check if track already has an IndexTableSegment */
3657
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
11 for (i = 0; i < mg->metadata_sets_count; i++) {
3658 9 MXFIndexTableSegment *s = (MXFIndexTableSegment*)mg->metadata_sets[i];
3659
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (s->body_sid == track->body_sid)
3660 9 return 0;
3661 }
3662
3663 /* find the essence partition */
3664
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 for (i = 0; i < mxf->partitions_count; i++) {
3665 /* BodySID == 0 -> no essence */
3666
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 if (mxf->partitions[i].body_sid != track->body_sid)
3667 4 continue;
3668
3669 2 p = &mxf->partitions[i];
3670 2 essence_partition_count++;
3671 }
3672
3673 /* only handle files with a single essence partition */
3674
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (essence_partition_count != 1)
3675 return 0;
3676
3677
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && is_pcm(st->codecpar->codec_id)) {
3678 2 edit_unit_byte_count = (av_get_bits_per_sample(st->codecpar->codec_id) *
3679 2 st->codecpar->ch_layout.nb_channels) >> 3;
3680 } else if (st->duration > 0 && p->first_essence_klv.length > 0 && p->first_essence_klv.length % st->duration == 0) {
3681 edit_unit_byte_count = p->first_essence_klv.length / st->duration;
3682 }
3683
3684
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (edit_unit_byte_count <= 0)
3685 return 0;
3686
3687 2 av_log(mxf->fc, AV_LOG_WARNING, "guessing index for stream %d using edit unit byte count %d\n", st->index, edit_unit_byte_count);
3688
3689
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!(segment = av_mallocz(sizeof(*segment))))
3690 return AVERROR(ENOMEM);
3691
3692
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if ((ret = mxf_add_metadata_set(mxf, (MXFMetadataSet**)&segment, IndexTableSegment)))
3693 return ret;
3694
3695 /* Make sure we have nonzero unique index_sid, body_sid will be ok, because
3696 * using the same SID for index is forbidden in MXF. */
3697
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!track->index_sid)
3698 2 track->index_sid = track->body_sid;
3699
3700 /* stream will be treated as small EditUnitByteCount */
3701 2 segment->edit_unit_byte_count = edit_unit_byte_count;
3702 2 segment->index_start_position = 0;
3703 2 segment->index_duration = st->duration;
3704 2 segment->index_edit_rate = av_inv_q(st->time_base);
3705 2 segment->index_sid = track->index_sid;
3706 2 segment->body_sid = p->body_sid;
3707 2 return 0;
3708 }
3709
3710 108 static void mxf_read_random_index_pack(AVFormatContext *s)
3711 {
3712 108 MXFContext *mxf = s->priv_data;
3713 uint32_t length;
3714 int64_t file_size, max_rip_length, min_rip_length;
3715 KLVPacket klv;
3716
3717
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
3718 return;
3719
3720 108 file_size = avio_size(s->pb);
3721
3722 /* S377m says to check the RIP length for "silly" values, without defining "silly".
3723 * The limit below assumes a file with nothing but partition packs and a RIP.
3724 * Before changing this, consider that a muxer may place each sample in its own partition.
3725 *
3726 * 105 is the size of the smallest possible PartitionPack
3727 * 12 is the size of each RIP entry
3728 * 28 is the size of the RIP header and footer, assuming an 8-byte BER
3729 */
3730 108 max_rip_length = ((file_size - mxf->run_in) / 105) * 12 + 28;
3731 108 max_rip_length = FFMIN(max_rip_length, INT_MAX); //2 GiB and up is also silly
3732
3733 /* We're only interested in RIPs with at least two entries.. */
3734 108 min_rip_length = 16+1+24+4;
3735
3736 /* See S377m section 11 */
3737 108 avio_seek(s->pb, file_size - 4, SEEK_SET);
3738 108 length = avio_rb32(s->pb);
3739
3740
4/4
✓ Branch 0 taken 99 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 98 times.
108 if (length < min_rip_length || length > max_rip_length)
3741 10 goto end;
3742 98 avio_seek(s->pb, file_size - length, SEEK_SET);
3743
1/2
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
98 if (klv_read_packet(mxf, &klv, s->pb) < 0 ||
3744
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 98 times.
98 !IS_KLV_KEY(klv.key, ff_mxf_random_index_pack_key))
3745 goto end;
3746
3/6
✓ Branch 0 taken 98 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 98 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 98 times.
98 if (klv.next_klv != file_size || klv.length <= 4 || (klv.length - 4) % 12) {
3747 av_log(s, AV_LOG_WARNING, "Invalid RIP KLV length\n");
3748 goto end;
3749 }
3750
3751 98 avio_skip(s->pb, klv.length - 12);
3752 98 mxf->footer_partition = avio_rb64(s->pb);
3753
3754 /* sanity check */
3755
1/2
✓ Branch 0 taken 98 times.
✗ Branch 1 not taken.
98 if (mxf->run_in + mxf->footer_partition >= file_size) {
3756 av_log(s, AV_LOG_WARNING, "bad FooterPartition in RIP - ignoring\n");
3757 mxf->footer_partition = 0;
3758 }
3759
3760 98 end:
3761 108 avio_seek(s->pb, mxf->run_in, SEEK_SET);
3762 }
3763
3764 108 static int mxf_read_header(AVFormatContext *s)
3765 {
3766 108 MXFContext *mxf = s->priv_data;
3767 KLVPacket klv;
3768 108 int64_t essence_offset = 0;
3769 int ret;
3770 int64_t run_in;
3771
3772 108 mxf->last_forward_tell = INT64_MAX;
3773
3774
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 108 times.
108 if (!mxf_read_sync(s->pb, mxf_header_partition_pack_key, 14)) {
3775 av_log(s, AV_LOG_ERROR, "could not find header partition pack key\n");
3776 return AVERROR_INVALIDDATA;
3777 }
3778 108 avio_seek(s->pb, -14, SEEK_CUR);
3779 108 mxf->fc = s;
3780 108 run_in = avio_tell(s->pb);
3781
2/4
✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 108 times.
108 if (run_in < 0 || run_in > RUN_IN_MAX)
3782 return AVERROR_INVALIDDATA;
3783 108 mxf->run_in = run_in;
3784
3785 108 mxf_read_random_index_pack(s);
3786
3787
1/2
✓ Branch 1 taken 8915 times.
✗ Branch 2 not taken.
8915 while (!avio_feof(s->pb)) {
3788 size_t x;
3789
3790 8915 ret = klv_read_packet(mxf, &klv, s->pb);
3791
4/4
✓ Branch 0 taken 8911 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 98 times.
✓ Branch 3 taken 8813 times.
8915 if (ret < 0 || IS_KLV_KEY(klv.key, ff_mxf_random_index_pack_key)) {
3792
3/4
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 98 times.
102 if (ret >= 0 && avio_size(s->pb) > klv.next_klv)
3793 av_log(s, AV_LOG_WARNING, "data after the RandomIndexPack, assuming end of file\n");
3794 /* EOF - seek to previous partition or stop */
3795
2/2
✓ Branch 1 taken 98 times.
✓ Branch 2 taken 4 times.
102 if(mxf_parse_handle_partition_or_eof(mxf) <= 0)
3796 98 break;
3797 else
3798 4 continue;
3799 }
3800
3801 PRINT_KEY(s, "read header", klv.key);
3802 8813 av_log(s, AV_LOG_TRACE, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset);
3803
1/2
✓ Branch 1 taken 8813 times.
✗ Branch 2 not taken.
8813 if (mxf_match_uid(klv.key, mxf_encrypted_triplet_key, sizeof(mxf_encrypted_triplet_key)) ||
3804
2/2
✓ Branch 0 taken 8798 times.
✓ Branch 1 taken 15 times.
8813 IS_KLV_KEY(klv.key, mxf_essence_element_key) ||
3805
1/2
✓ Branch 0 taken 8798 times.
✗ Branch 1 not taken.
8798 IS_KLV_KEY(klv.key, mxf_canopus_essence_element_key) ||
3806
2/2
✓ Branch 0 taken 8797 times.
✓ Branch 1 taken 1 times.
8798 IS_KLV_KEY(klv.key, mxf_avid_essence_element_key) ||
3807
2/2
✓ Branch 0 taken 8706 times.
✓ Branch 1 taken 91 times.
8797 IS_KLV_KEY(klv.key, mxf_system_item_key_cp) ||
3808
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8705 times.
8706 IS_KLV_KEY(klv.key, mxf_system_item_key_gc)) {
3809
3810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if (!mxf->current_partition) {
3811 av_log(mxf->fc, AV_LOG_ERROR, "found essence prior to first PartitionPack\n");
3812 return AVERROR_INVALIDDATA;
3813 }
3814
3815
1/2
✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
108 if (!mxf->current_partition->first_essence_klv.offset)
3816 108 mxf->current_partition->first_essence_klv = klv;
3817
3818
1/2
✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
108 if (!essence_offset)
3819 108 essence_offset = klv.offset;
3820
3821 /* seek to footer, previous partition or stop */
3822
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 102 times.
108 if (mxf_parse_handle_essence(mxf) <= 0)
3823 6 break;
3824 102 continue;
3825
4/4
✓ Branch 1 taken 270 times.
✓ Branch 2 taken 8435 times.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 209 times.
8705 } else if (mxf_is_partition_pack_key(klv.key) && mxf->current_partition) {
3826 /* next partition pack - keep going, seek to previous partition or stop */
3827
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 57 times.
61 if(mxf_parse_handle_partition_or_eof(mxf) <= 0)
3828 4 break;
3829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 else if (mxf->parsing_backward)
3830 continue;
3831 /* we're still parsing forward. proceed to parsing this partition pack */
3832 }
3833
3834
2/2
✓ Branch 0 taken 300423 times.
✓ Branch 1 taken 4572 times.
304995 for (x = 0; x < FF_ARRAY_ELEMS(mxf_metadata_read_table); x++) {
3835 300423 const MXFMetadataReadTableEntry *metadata = &mxf_metadata_read_table[x];
3836
2/2
✓ Branch 0 taken 4129 times.
✓ Branch 1 taken 296294 times.
300423 if (IS_KLV_KEY(klv.key, metadata->key)) {
3837
2/2
✓ Branch 0 taken 3653 times.
✓ Branch 1 taken 476 times.
4129 if (metadata->read) {
3838
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3653 times.
3653 if ((ret = mxf_parse_klv(mxf, klv, metadata->read, metadata->ctx_size, metadata->type)) < 0)
3839 return ret;
3840 } else {
3841 476 avio_skip(s->pb, klv.length);
3842 }
3843 4129 break;
3844 }
3845 }
3846
2/2
✓ Branch 0 taken 4572 times.
✓ Branch 1 taken 4129 times.
8701 if (x >= FF_ARRAY_ELEMS(mxf_metadata_read_table)) {
3847 4572 av_log(s, AV_LOG_VERBOSE, "Dark key " PRIxUID "\n",
3848 4572 UID_ARG(klv.key));
3849 4572 avio_skip(s->pb, klv.length);
3850 }
3851 }
3852 /* FIXME avoid seek */
3853
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if (!essence_offset) {
3854 av_log(s, AV_LOG_ERROR, "no essence\n");
3855 return AVERROR_INVALIDDATA;
3856 }
3857 108 avio_seek(s->pb, essence_offset, SEEK_SET);
3858
3859 /* we need to do this before computing the index tables
3860 * to be able to fill in zero IndexDurations with st->duration */
3861
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 108 times.
108 if ((ret = mxf_parse_structural_metadata(mxf)) < 0)
3862 return ret;
3863
3864
2/2
✓ Branch 0 taken 233 times.
✓ Branch 1 taken 108 times.
341 for (int i = 0; i < s->nb_streams; i++)
3865 233 mxf_handle_missing_index_segment(mxf, s->streams[i]);
3866
3867
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 108 times.
108 if ((ret = mxf_compute_index_tables(mxf)) < 0)
3868 return ret;
3869
3870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if (mxf->nb_index_tables > 1) {
3871 /* TODO: look up which IndexSID to use via EssenceContainerData */
3872 av_log(mxf->fc, AV_LOG_INFO, "got %i index tables - only the first one (IndexSID %i) will be used\n",
3873 mxf->nb_index_tables, mxf->index_tables[0].index_sid);
3874
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
108 } else if (mxf->nb_index_tables == 0 && mxf->op == OPAtom && (s->error_recognition & AV_EF_EXPLODE)) {
3875 av_log(mxf->fc, AV_LOG_ERROR, "cannot demux OPAtom without an index\n");
3876 return AVERROR_INVALIDDATA;
3877 }
3878
3879 108 mxf_compute_essence_containers(s);
3880
3881
2/2
✓ Branch 0 taken 233 times.
✓ Branch 1 taken 108 times.
341 for (int i = 0; i < s->nb_streams; i++)
3882 233 mxf_compute_edit_units_per_packet(mxf, s->streams[i]);
3883
3884 108 return 0;
3885 }
3886
3887 /* Get the edit unit of the next packet from current_offset in a track. The returned edit unit can be original_duration as well! */
3888 155 static int mxf_get_next_track_edit_unit(MXFContext *mxf, MXFTrack *track, int64_t current_offset, int64_t *edit_unit_out)
3889 {
3890 int64_t a, b, m, offset;
3891 155 MXFIndexTable *t = mxf_find_index_table(mxf, track->index_sid);
3892
3893
2/4
✓ Branch 0 taken 155 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
155 if (!t || track->original_duration <= 0)
3894 return -1;
3895
3896 155 a = -1;
3897 155 b = track->original_duration;
3898
2/2
✓ Branch 0 taken 719 times.
✓ Branch 1 taken 155 times.
874 while (b - 1 > a) {
3899 719 m = (a + (uint64_t)b) >> 1;
3900
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 719 times.
719 if (mxf_edit_unit_absolute_offset(mxf, t, m, track->edit_rate, NULL, &offset, NULL, 0) < 0)
3901 return -1;
3902
2/2
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 375 times.
719 if (offset < current_offset)
3903 344 a = m;
3904 else
3905 375 b = m;
3906 }
3907
3908 155 *edit_unit_out = b;
3909
3910 155 return 0;
3911 }
3912
3913 362 static int64_t mxf_compute_sample_count(MXFContext *mxf, AVStream *st,
3914 int64_t edit_unit)
3915 {
3916 362 MXFTrack *track = st->priv_data;
3917 362 AVRational time_base = av_inv_q(track->edit_rate);
3918 362 AVRational sample_rate = av_inv_q(st->time_base);
3919
3920 // For non-audio sample_count equals current edit unit
3921
2/2
✓ Branch 0 taken 181 times.
✓ Branch 1 taken 181 times.
362 if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
3922 181 return edit_unit;
3923
3924
1/2
✓ Branch 0 taken 181 times.
✗ Branch 1 not taken.
181 if ((sample_rate.num / sample_rate.den) == 48000) {
3925 181 return av_rescale_q(edit_unit, sample_rate, track->edit_rate);
3926 } else {
3927 int64_t remainder = (sample_rate.num * (int64_t) time_base.num) %
3928 ( time_base.den * (int64_t)sample_rate.den);
3929 if (remainder)
3930 av_log(mxf->fc, AV_LOG_WARNING,
3931 "seeking detected on stream #%d with time base (%d/%d) and "
3932 "sample rate (%d/%d), audio pts won't be accurate.\n",
3933 st->index, time_base.num, time_base.den,
3934 sample_rate.num, sample_rate.den);
3935 return av_rescale_q(edit_unit, sample_rate, track->edit_rate);
3936 }
3937 }
3938
3939 /**
3940 * Make sure track->sample_count is correct based on what offset we're currently at.
3941 * Also determine the next edit unit (or packet) offset.
3942 * @return next_ofs if OK, <0 on error
3943 */
3944 5177 static int64_t mxf_set_current_edit_unit(MXFContext *mxf, AVStream *st, int64_t current_offset, int resync)
3945 {
3946 5177 int64_t next_ofs = -1;
3947 5177 MXFTrack *track = st->priv_data;
3948 5177 int64_t edit_unit = av_rescale_q(track->sample_count, st->time_base, av_inv_q(track->edit_rate));
3949 int64_t new_edit_unit;
3950 5177 MXFIndexTable *t = mxf_find_index_table(mxf, track->index_sid);
3951
3952
3/4
✓ Branch 0 taken 5177 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 5170 times.
5177 if (!t || track->wrapping == UnknownWrapped)
3953 7 return -1;
3954
3955
2/2
✓ Branch 1 taken 299 times.
✓ Branch 2 taken 4871 times.
5170 if (mxf_edit_unit_absolute_offset(mxf, t, edit_unit + track->edit_units_per_packet, track->edit_rate, NULL, &next_ofs, NULL, 0) < 0 &&
3956
2/2
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 251 times.
299 (next_ofs = mxf_essence_container_end(mxf, t->body_sid)) <= 0) {
3957 48 av_log(mxf->fc, AV_LOG_ERROR, "unable to compute the size of the last packet\n");
3958 48 return -1;
3959 }
3960
3961 /* check if the next edit unit offset (next_ofs) starts ahead of current_offset */
3962
1/2
✓ Branch 0 taken 5122 times.
✗ Branch 1 not taken.
5122 if (next_ofs > current_offset)
3963 5122 return next_ofs;
3964
3965 if (!resync) {
3966 av_log(mxf->fc, AV_LOG_ERROR, "cannot find current edit unit for stream %d, invalid index?\n", st->index);
3967 return -1;
3968 }
3969
3970 if (mxf_get_next_track_edit_unit(mxf, track, current_offset + 1, &new_edit_unit) < 0 || new_edit_unit <= 0) {
3971 av_log(mxf->fc, AV_LOG_ERROR, "failed to find next track edit unit in stream %d\n", st->index);
3972 return -1;
3973 }
3974
3975 new_edit_unit--;
3976 track->sample_count = mxf_compute_sample_count(mxf, st, new_edit_unit);
3977 av_log(mxf->fc, AV_LOG_WARNING, "edit unit sync lost on stream %d, jumping from %"PRId64" to %"PRId64"\n", st->index, edit_unit, new_edit_unit);
3978
3979 return mxf_set_current_edit_unit(mxf, st, current_offset, 0);
3980 }
3981
3982 2569 static int mxf_set_audio_pts(MXFContext *mxf, AVCodecParameters *par,
3983 AVPacket *pkt)
3984 {
3985 2569 AVStream *st = mxf->fc->streams[pkt->stream_index];
3986 2569 MXFTrack *track = st->priv_data;
3987 2569 int64_t bits_per_sample = par->bits_per_coded_sample;
3988
3989
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2569 times.
2569 if (!bits_per_sample)
3990 bits_per_sample = av_get_bits_per_sample(par->codec_id);
3991
3992 2569 pkt->pts = track->sample_count;
3993
3994
2/4
✓ Branch 0 taken 2569 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2569 times.
✗ Branch 3 not taken.
2569 if (par->ch_layout.nb_channels <= 0 ||
3995 2569 bits_per_sample <= 0 ||
3996
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2569 times.
2569 par->ch_layout.nb_channels * (int64_t)bits_per_sample < 8)
3997 track->sample_count = mxf_compute_sample_count(mxf, st, av_rescale_q(track->sample_count, st->time_base, av_inv_q(track->edit_rate)) + 1);
3998 else
3999 2569 track->sample_count += pkt->size / (par->ch_layout.nb_channels * (int64_t)bits_per_sample / 8);
4000
4001 2569 return 0;
4002 }
4003
4004 5177 static int mxf_set_pts(MXFContext *mxf, AVStream *st, AVPacket *pkt)
4005 {
4006 5177 AVCodecParameters *par = st->codecpar;
4007 5177 MXFTrack *track = st->priv_data;
4008
4009
2/2
✓ Branch 0 taken 2602 times.
✓ Branch 1 taken 2575 times.
5177 if (par->codec_type == AVMEDIA_TYPE_VIDEO) {
4010 /* see if we have an index table to derive timestamps from */
4011 2602 MXFIndexTable *t = mxf_find_index_table(mxf, track->index_sid);
4012
4013
3/4
✓ Branch 0 taken 2602 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1279 times.
✓ Branch 3 taken 1323 times.
2602 if (t && track->sample_count < t->nb_ptses) {
4014 1279 pkt->dts = track->sample_count + t->first_dts;
4015 1279 pkt->pts = t->ptses[track->sample_count];
4016
2/2
✓ Branch 0 taken 1025 times.
✓ Branch 1 taken 298 times.
1323 } else if (track->intra_only) {
4017 /* intra-only -> PTS = EditUnit.
4018 * let utils.c figure out DTS since it can be < PTS if low_delay = 0 (Sony IMX30) */
4019 1025 pkt->pts = track->sample_count;
4020 }
4021 2602 track->sample_count++;
4022
2/2
✓ Branch 0 taken 2569 times.
✓ Branch 1 taken 6 times.
2575 } else if (par->codec_type == AVMEDIA_TYPE_AUDIO) {
4023 2569 int ret = mxf_set_audio_pts(mxf, par, pkt);
4024
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2569 times.
2569 if (ret < 0)
4025 return ret;
4026
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 } else if (track) {
4027 6 pkt->dts = pkt->pts = track->sample_count;
4028 6 pkt->duration = 1;
4029 6 track->sample_count++;
4030 }
4031 5177 return 0;
4032 }
4033
4034 5307 static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
4035 {
4036 KLVPacket klv;
4037 5307 MXFContext *mxf = s->priv_data;
4038 int ret;
4039
4040 12856 while (1) {
4041 int64_t max_data_size;
4042 18163 int64_t pos = avio_tell(s->pb);
4043
4044
3/4
✓ Branch 0 taken 18163 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18028 times.
✓ Branch 3 taken 135 times.
36061 if (pos < mxf->current_klv_data.next_klv - mxf->current_klv_data.length || pos >= mxf->current_klv_data.next_klv) {
4045 18028 mxf->current_klv_data = (KLVPacket){{0}};
4046 18028 ret = klv_read_packet(mxf, &klv, s->pb);
4047
2/2
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 17898 times.
18028 if (ret < 0)
4048 130 break;
4049 // klv.key[0..3] == mxf_klv_key from here forward
4050 17898 max_data_size = klv.length;
4051 17898 pos = klv.next_klv - klv.length;
4052 PRINT_KEY(s, "read packet", klv.key);
4053 17898 av_log(s, AV_LOG_TRACE, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset);
4054
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 17898 times.
17898 if (mxf_match_uid(klv.key, mxf_encrypted_triplet_key, sizeof(mxf_encrypted_triplet_key))) {
4055 ret = mxf_decrypt_triplet(s, pkt, &klv);
4056 if (ret < 0) {
4057 av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");
4058 return ret;
4059 }
4060 return 0;
4061 }
4062 } else {
4063 135 klv = mxf->current_klv_data;
4064 135 max_data_size = klv.next_klv - pos;
4065 }
4066
2/2
✓ Branch 0 taken 12833 times.
✓ Branch 1 taken 5200 times.
18033 if (IS_KLV_KEY(klv.key, mxf_essence_element_key) ||
4067
1/2
✓ Branch 0 taken 12833 times.
✗ Branch 1 not taken.
12833 IS_KLV_KEY(klv.key, mxf_canopus_essence_element_key) ||
4068
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 12832 times.
12833 IS_KLV_KEY(klv.key, mxf_avid_essence_element_key)) {
4069 5201 int body_sid = find_body_sid_by_absolute_offset(mxf, klv.offset);
4070 5201 int index = mxf_get_stream_index(s, &klv, body_sid);
4071 int64_t next_ofs;
4072 AVStream *st;
4073 MXFTrack *track;
4074
4075
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5201 times.
5201 if (index < 0) {
4076 av_log(s, AV_LOG_ERROR,
4077 "error getting stream index %"PRIu32"\n",
4078 AV_RB32(klv.key + 12));
4079 goto skip;
4080 }
4081
4082 5201 st = s->streams[index];
4083 5201 track = st->priv_data;
4084
4085
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 5177 times.
5201 if (s->streams[index]->discard == AVDISCARD_ALL)
4086 24 goto skip;
4087
4088 5177 next_ofs = mxf_set_current_edit_unit(mxf, st, pos, 1);
4089
4090
2/2
✓ Branch 0 taken 151 times.
✓ Branch 1 taken 5026 times.
5177 if (track->wrapping != FrameWrapped) {
4091 int64_t size;
4092
4093
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 144 times.
151 if (next_ofs <= 0) {
4094 // If we have no way to packetize the data, then return it in chunks...
4095
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 if (klv.next_klv - klv.length == pos && max_data_size > MXF_MAX_CHUNK_SIZE) {
4096 ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL;
4097 avpriv_request_sample(s, "Huge KLV without proper index in non-frame wrapped essence");
4098 }
4099 7 size = FFMIN(max_data_size, MXF_MAX_CHUNK_SIZE);
4100 } else {
4101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
144 if ((size = next_ofs - pos) <= 0) {
4102 av_log(s, AV_LOG_ERROR, "bad size: %"PRId64"\n", size);
4103 mxf->current_klv_data = (KLVPacket){{0}};
4104 return AVERROR_INVALIDDATA;
4105 }
4106 // We must not overread, because the next edit unit might be in another KLV
4107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
144 if (size > max_data_size)
4108 size = max_data_size;
4109 }
4110
4111 151 mxf->current_klv_data = klv;
4112 151 klv.offset = pos;
4113 151 klv.length = size;
4114 151 klv.next_klv = klv.offset + klv.length;
4115 }
4116
4117 /* check for 8 channels AES3 element */
4118
4/6
✓ Branch 0 taken 924 times.
✓ Branch 1 taken 4253 times.
✓ Branch 2 taken 924 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 924 times.
✗ Branch 5 not taken.
5177 if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) {
4119 924 ret = mxf_get_d10_aes3_packet(s->pb, s->streams[index],
4120 924 pkt, klv.length);
4121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 924 times.
924 if (ret < 0) {
4122 av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
4123 mxf->current_klv_data = (KLVPacket){{0}};
4124 return ret;
4125 }
4126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4253 times.
4253 } else if (mxf->eia608_extract &&
4127 s->streams[index]->codecpar->codec_id == AV_CODEC_ID_EIA_608) {
4128 ret = mxf_get_eia608_packet(s, s->streams[index], pkt, klv.length);
4129 if (ret < 0) {
4130 mxf->current_klv_data = (KLVPacket){{0}};
4131 return ret;
4132 }
4133 } else {
4134 4253 ret = av_get_packet(s->pb, pkt, klv.length);
4135
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4253 times.
4253 if (ret < 0) {
4136 mxf->current_klv_data = (KLVPacket){{0}};
4137 return ret;
4138 }
4139 }
4140 5177 pkt->stream_index = index;
4141 5177 pkt->pos = klv.offset;
4142
4143 5177 ret = mxf_set_pts(mxf, st, pkt);
4144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5177 times.
5177 if (ret < 0) {
4145 mxf->current_klv_data = (KLVPacket){{0}};
4146 return ret;
4147 }
4148
4149 /* seek for truncated packets */
4150 5177 avio_seek(s->pb, klv.next_klv, SEEK_SET);
4151
4152 5177 return 0;
4153 } else {
4154 12832 skip:
4155 12856 avio_skip(s->pb, max_data_size);
4156 12856 mxf->current_klv_data = (KLVPacket){{0}};
4157 }
4158 }
4159
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 130 times.
130 return avio_feof(s->pb) ? AVERROR_EOF : ret;
4160 }
4161
4162 108 static int mxf_read_close(AVFormatContext *s)
4163 {
4164 108 MXFContext *mxf = s->priv_data;
4165
4166 108 av_freep(&mxf->packages_refs);
4167 108 av_freep(&mxf->essence_container_data_refs);
4168
4169
2/2
✓ Branch 0 taken 233 times.
✓ Branch 1 taken 108 times.
341 for (int i = 0; i < s->nb_streams; i++)
4170 233 s->streams[i]->priv_data = NULL;
4171
4172
2/2
✓ Branch 0 taken 2808 times.
✓ Branch 1 taken 108 times.
2916 for (int type = 0; type < FF_ARRAY_ELEMS(mxf->metadata_set_groups); type++) {
4173 2808 MXFMetadataSetGroup *mg = &mxf->metadata_set_groups[type];
4174
2/2
✓ Branch 0 taken 2953 times.
✓ Branch 1 taken 2808 times.
5761 for (int i = 0; i < mg->metadata_sets_count; i++)
4175 2953 mxf_free_metadataset(mg->metadata_sets + i, type);
4176 2808 mg->metadata_sets_count = 0;
4177 2808 av_freep(&mg->metadata_sets);
4178 }
4179 108 av_freep(&mxf->partitions);
4180 108 av_freep(&mxf->aesc);
4181 108 av_freep(&mxf->local_tags);
4182
4183
1/2
✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
108 if (mxf->index_tables) {
4184
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 108 times.
216 for (int i = 0; i < mxf->nb_index_tables; i++) {
4185 108 av_freep(&mxf->index_tables[i].segments);
4186 108 av_freep(&mxf->index_tables[i].ptses);
4187 108 av_freep(&mxf->index_tables[i].fake_index);
4188 108 av_freep(&mxf->index_tables[i].offsets);
4189 }
4190 }
4191 108 av_freep(&mxf->index_tables);
4192
4193 108 return 0;
4194 }
4195
4196 7186 static int mxf_probe(const AVProbeData *p) {
4197 7186 const uint8_t *bufp = p->buf;
4198
2/2
✓ Branch 0 taken 6186 times.
✓ Branch 1 taken 1000 times.
7186 const uint8_t *end = p->buf + FFMIN(p->buf_size, RUN_IN_MAX + 1 + sizeof(mxf_header_partition_pack_key));
4199
4200
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7186 times.
7186 if (p->buf_size < sizeof(mxf_header_partition_pack_key))
4201 return 0;
4202
4203 /* Must skip Run-In Sequence and search for MXF header partition pack key SMPTE 377M 5.5 */
4204 7186 end -= sizeof(mxf_header_partition_pack_key);
4205
4206
2/2
✓ Branch 0 taken 13369148 times.
✓ Branch 1 taken 7085 times.
13376233 for (; bufp < end;) {
4207
2/2
✓ Branch 0 taken 562481 times.
✓ Branch 1 taken 12806667 times.
13369148 if (!((bufp[13] - 1) & 0xF2)){
4208
2/2
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 562380 times.
562481 if (AV_RN32(bufp ) == AV_RN32(mxf_header_partition_pack_key ) &&
4209
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 AV_RN32(bufp+ 4) == AV_RN32(mxf_header_partition_pack_key+ 4) &&
4210
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 AV_RN32(bufp+ 8) == AV_RN32(mxf_header_partition_pack_key+ 8) &&
4211
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 AV_RN16(bufp+12) == AV_RN16(mxf_header_partition_pack_key+12))
4212
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 1 times.
101 return bufp == p->buf ? AVPROBE_SCORE_MAX : AVPROBE_SCORE_MAX - 1;
4213 562380 bufp ++;
4214 } else
4215 12806667 bufp += 10;
4216 }
4217
4218 7085 return 0;
4219 }
4220
4221 /* rudimentary byte seek */
4222 /* XXX: use MXF Index */
4223 212 static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
4224 {
4225 212 AVStream *st = s->streams[stream_index];
4226 int64_t seconds;
4227 212 MXFContext* mxf = s->priv_data;
4228 int64_t seekpos;
4229 int ret;
4230 MXFIndexTable *t;
4231 212 MXFTrack *source_track = st->priv_data;
4232
4233
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 212 times.
212 if (!source_track)
4234 return 0;
4235
4236 /* if audio then truncate sample_time to EditRate */
4237
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 154 times.
212 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
4238 58 sample_time = av_rescale_q(sample_time, st->time_base,
4239 av_inv_q(source_track->edit_rate));
4240
4241
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 212 times.
212 if (mxf->nb_index_tables <= 0) {
4242 if (!s->bit_rate)
4243 return AVERROR_INVALIDDATA;
4244 if (sample_time < 0)
4245 sample_time = 0;
4246 seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den);
4247
4248 seekpos = avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET);
4249 if (seekpos < 0)
4250 return seekpos;
4251
4252 avpriv_update_cur_dts(s, st, sample_time);
4253 mxf->current_klv_data = (KLVPacket){{0}};
4254 } else {
4255 MXFPartition *partition;
4256
4257 212 t = &mxf->index_tables[0];
4258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 212 times.
212 if (t->index_sid != source_track->index_sid) {
4259 int i;
4260 /* If the first index table does not belong to the stream, then find a stream which does belong to the index table */
4261 for (i = 0; i < s->nb_streams; i++) {
4262 MXFTrack *new_source_track = s->streams[i]->priv_data;
4263 if (new_source_track && new_source_track->index_sid == t->index_sid) {
4264 sample_time = av_rescale_q(sample_time, new_source_track->edit_rate, source_track->edit_rate);
4265 source_track = new_source_track;
4266 st = s->streams[i];
4267 break;
4268 }
4269 }
4270 if (i == s->nb_streams)
4271 5 return AVERROR_INVALIDDATA;
4272 }
4273
4274 /* clamp above zero, else ff_index_search_timestamp() returns negative
4275 * this also means we allow seeking before the start */
4276 212 sample_time = FFMAX(sample_time, 0);
4277
4278
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 158 times.
212 if (t->fake_index) {
4279 /* The first frames may not be keyframes in presentation order, so
4280 * we have to advance the target to be able to find the first
4281 * keyframe backwards... */
4282
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 if (!(flags & AVSEEK_FLAG_ANY) &&
4283
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 13 times.
54 (flags & AVSEEK_FLAG_BACKWARD) &&
4284
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 t->ptses[0] != AV_NOPTS_VALUE &&
4285
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 sample_time < t->ptses[0] &&
4286 (t->fake_index[t->ptses[0]].flags & AVINDEX_KEYFRAME))
4287 sample_time = t->ptses[0];
4288
4289 /* behave as if we have a proper index */
4290
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 49 times.
54 if ((sample_time = ff_index_search_timestamp(t->fake_index, t->nb_ptses, sample_time, flags)) < 0)
4291 5 return sample_time;
4292 /* get the stored order index from the display order index */
4293 49 sample_time += t->offsets[sample_time];
4294 } else {
4295 /* no IndexEntryArray (one or more CBR segments)
4296 * make sure we don't seek past the end */
4297
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 98 times.
158 sample_time = FFMIN(sample_time, source_track->original_duration - 1);
4298 }
4299
4300
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207 times.
207 if (source_track->wrapping == UnknownWrapped)
4301 av_log(mxf->fc, AV_LOG_WARNING, "attempted seek in an UnknownWrapped essence\n");
4302
4303
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 207 times.
207 if ((ret = mxf_edit_unit_absolute_offset(mxf, t, sample_time, source_track->edit_rate, &sample_time, &seekpos, &partition, 1)) < 0)
4304 return ret;
4305
4306 207 avpriv_update_cur_dts(s, st, sample_time);
4307
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 155 times.
207 if (source_track->wrapping == ClipWrapped) {
4308 52 KLVPacket klv = partition->first_essence_klv;
4309
2/4
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 52 times.
52 if (seekpos < klv.next_klv - klv.length || seekpos >= klv.next_klv) {
4310 av_log(mxf->fc, AV_LOG_ERROR, "attempted seek out of clip wrapped KLV\n");
4311 return AVERROR_INVALIDDATA;
4312 }
4313 52 mxf->current_klv_data = klv;
4314 } else {
4315 155 mxf->current_klv_data = (KLVPacket){{0}};
4316 }
4317 207 avio_seek(s->pb, seekpos, SEEK_SET);
4318 }
4319
4320 // Update all tracks sample count
4321
2/2
✓ Branch 0 taken 362 times.
✓ Branch 1 taken 207 times.
569 for (int i = 0; i < s->nb_streams; i++) {
4322 362 AVStream *cur_st = s->streams[i];
4323 362 MXFTrack *cur_track = cur_st->priv_data;
4324
1/2
✓ Branch 0 taken 362 times.
✗ Branch 1 not taken.
362 if (cur_track) {
4325 362 int64_t track_edit_unit = sample_time;
4326
2/2
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 207 times.
362 if (st != cur_st)
4327 155 mxf_get_next_track_edit_unit(mxf, cur_track, seekpos, &track_edit_unit);
4328 362 cur_track->sample_count = mxf_compute_sample_count(mxf, cur_st, track_edit_unit);
4329 }
4330 }
4331 207 return 0;
4332 }
4333
4334 static const AVOption options[] = {
4335 { "eia608_extract", "extract eia 608 captions from s436m track",
4336 offsetof(MXFContext, eia608_extract), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
4337 AV_OPT_FLAG_DECODING_PARAM },
4338 { NULL },
4339 };
4340
4341 static const AVClass demuxer_class = {
4342 .class_name = "mxf",
4343 .item_name = av_default_item_name,
4344 .option = options,
4345 .version = LIBAVUTIL_VERSION_INT,
4346 .category = AV_CLASS_CATEGORY_DEMUXER,
4347 };
4348
4349 const FFInputFormat ff_mxf_demuxer = {
4350 .p.name = "mxf",
4351 .p.long_name = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format)"),
4352 .p.flags = AVFMT_SEEK_TO_PTS | AVFMT_NOGENSEARCH,
4353 .p.priv_class = &demuxer_class,
4354 .priv_data_size = sizeof(MXFContext),
4355 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
4356 .read_probe = mxf_probe,
4357 .read_header = mxf_read_header,
4358 .read_packet = mxf_read_packet,
4359 .read_close = mxf_read_close,
4360 .read_seek = mxf_read_seek,
4361 };
4362