FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/mxfdec.c
Date: 2025-01-20 09:27:23
Exec Total Coverage
Lines: 1706 2319 73.6%
Functions: 86 93 92.5%
Branches: 1005 1664 60.4%

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