FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/mxfdec.c
Date: 2025-03-08 20:38:41
Exec Total Coverage
Lines: 1706 2320 73.5%
Functions: 86 93 92.5%
Branches: 1006 1668 60.3%

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