FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/mxfdec.c
Date: 2022-12-06 04:36:11
Exec Total Coverage
Lines: 1657 2279 72.7%
Functions: 85 93 91.4%
Branches: 971 1622 59.9%

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
49 #include "libavutil/aes.h"
50 #include "libavutil/avstring.h"
51 #include "libavutil/mastering_display_metadata.h"
52 #include "libavutil/mathematics.h"
53 #include "libavcodec/bytestream.h"
54 #include "libavcodec/internal.h"
55 #include "libavutil/channel_layout.h"
56 #include "libavutil/dict_internal.h"
57 #include "libavutil/intreadwrite.h"
58 #include "libavutil/parseutils.h"
59 #include "libavutil/timecode.h"
60 #include "libavutil/opt.h"
61 #include "avformat.h"
62 #include "avlanguage.h"
63 #include "demux.h"
64 #include "internal.h"
65 #include "mxf.h"
66
67 #define MXF_MAX_CHUNK_SIZE (32 << 20)
68 #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
69
70 typedef enum {
71 Header,
72 BodyPartition,
73 Footer
74 } MXFPartitionType;
75
76 typedef enum {
77 OP1a = 1,
78 OP1b,
79 OP1c,
80 OP2a,
81 OP2b,
82 OP2c,
83 OP3a,
84 OP3b,
85 OP3c,
86 OPAtom,
87 OPSONYOpt, /* FATE sample, violates the spec in places */
88 } MXFOP;
89
90 typedef enum {
91 UnknownWrapped = 0,
92 FrameWrapped,
93 ClipWrapped,
94 } MXFWrappingScheme;
95
96 typedef struct MXFPartition {
97 int closed;
98 int complete;
99 MXFPartitionType type;
100 uint64_t previous_partition;
101 int index_sid;
102 int body_sid;
103 int64_t this_partition;
104 int64_t essence_offset; ///< absolute offset of essence
105 int64_t essence_length;
106 int32_t kag_size;
107 int64_t header_byte_count;
108 int64_t index_byte_count;
109 int pack_length;
110 int64_t pack_ofs; ///< absolute offset of pack in file, including run-in
111 int64_t body_offset;
112 KLVPacket first_essence_klv;
113 } MXFPartition;
114
115 typedef struct MXFMetadataSet {
116 UID uid;
117 uint64_t partition_score;
118 enum MXFMetadataSetType type;
119 } MXFMetadataSet;
120
121 typedef struct MXFCryptoContext {
122 MXFMetadataSet meta;
123 UID source_container_ul;
124 } MXFCryptoContext;
125
126 typedef struct MXFStructuralComponent {
127 MXFMetadataSet meta;
128 UID source_package_ul;
129 UID source_package_uid;
130 UID data_definition_ul;
131 int64_t duration;
132 int64_t start_position;
133 int source_track_id;
134 } MXFStructuralComponent;
135
136 typedef struct MXFSequence {
137 MXFMetadataSet meta;
138 UID data_definition_ul;
139 UID *structural_components_refs;
140 int structural_components_count;
141 int64_t duration;
142 uint8_t origin;
143 } MXFSequence;
144
145 typedef struct MXFTimecodeComponent {
146 MXFMetadataSet meta;
147 int drop_frame;
148 int start_frame;
149 struct AVRational rate;
150 AVTimecode tc;
151 } MXFTimecodeComponent;
152
153 typedef struct {
154 MXFMetadataSet meta;
155 UID input_segment_ref;
156 } MXFPulldownComponent;
157
158 typedef struct {
159 MXFMetadataSet meta;
160 UID *structural_components_refs;
161 int structural_components_count;
162 int64_t duration;
163 } MXFEssenceGroup;
164
165 typedef struct {
166 MXFMetadataSet meta;
167 char *name;
168 char *value;
169 } MXFTaggedValue;
170
171 typedef struct {
172 MXFMetadataSet meta;
173 MXFSequence *sequence; /* mandatory, and only one */
174 UID sequence_ref;
175 int track_id;
176 char *name;
177 uint8_t track_number[4];
178 AVRational edit_rate;
179 int intra_only;
180 uint64_t sample_count;
181 int64_t original_duration; /* st->duration in SampleRate/EditRate units */
182 int index_sid;
183 int body_sid;
184 MXFWrappingScheme wrapping;
185 int edit_units_per_packet; /* how many edit units to read at a time (PCM, ClipWrapped) */
186 int require_reordering;
187 int channel_ordering[FF_SANE_NB_CHANNELS];
188 } MXFTrack;
189
190 typedef struct MXFDescriptor {
191 MXFMetadataSet meta;
192 UID essence_container_ul;
193 UID essence_codec_ul;
194 UID codec_ul;
195 AVRational sample_rate;
196 AVRational aspect_ratio;
197 int width;
198 int height; /* Field height, not frame height */
199 int frame_layout; /* See MXFFrameLayout enum */
200 int video_line_map[2];
201 #define MXF_FIELD_DOMINANCE_DEFAULT 0
202 #define MXF_FIELD_DOMINANCE_FF 1 /* coded first, displayed first */
203 #define MXF_FIELD_DOMINANCE_FL 2 /* coded first, displayed last */
204 int field_dominance;
205 int channels;
206 int bits_per_sample;
207 int64_t duration; /* ContainerDuration optional property */
208 unsigned int component_depth;
209 unsigned int black_ref_level;
210 unsigned int white_ref_level;
211 unsigned int color_range;
212 unsigned int horiz_subsampling;
213 unsigned int vert_subsampling;
214 UID *file_descriptors_refs;
215 int file_descriptors_count;
216 UID *sub_descriptors_refs;
217 int sub_descriptors_count;
218 int linked_track_id;
219 uint8_t *extradata;
220 int extradata_size;
221 enum AVPixelFormat pix_fmt;
222 UID color_primaries_ul;
223 UID color_trc_ul;
224 UID color_space_ul;
225 AVMasteringDisplayMetadata *mastering;
226 AVContentLightMetadata *coll;
227 size_t coll_size;
228 } MXFDescriptor;
229
230 typedef struct MXFMCASubDescriptor {
231 MXFMetadataSet meta;
232 UID uid;
233 UID mca_link_id;
234 UID soundfield_group_link_id;
235 UID *group_of_soundfield_groups_link_id_refs;
236 int group_of_soundfield_groups_link_id_count;
237 UID mca_label_dictionary_id;
238 int mca_channel_id;
239 char *language;
240 } MXFMCASubDescriptor;
241
242 typedef struct MXFFFV1SubDescriptor {
243 MXFMetadataSet meta;
244 uint8_t *extradata;
245 int extradata_size;
246 } MXFFFV1SubDescriptor;
247
248 typedef struct MXFIndexTableSegment {
249 MXFMetadataSet meta;
250 int edit_unit_byte_count;
251 int index_sid;
252 int body_sid;
253 AVRational index_edit_rate;
254 uint64_t index_start_position;
255 uint64_t index_duration;
256 int8_t *temporal_offset_entries;
257 int *flag_entries;
258 uint64_t *stream_offset_entries;
259 int nb_index_entries;
260 } MXFIndexTableSegment;
261
262 typedef struct MXFPackage {
263 MXFMetadataSet meta;
264 UID package_uid;
265 UID package_ul;
266 UID *tracks_refs;
267 int tracks_count;
268 MXFDescriptor *descriptor; /* only one */
269 UID descriptor_ref;
270 char *name;
271 UID *comment_refs;
272 int comment_count;
273 } MXFPackage;
274
275 typedef struct MXFEssenceContainerData {
276 MXFMetadataSet meta;
277 UID package_uid;
278 UID package_ul;
279 int index_sid;
280 int body_sid;
281 } MXFEssenceContainerData;
282
283 /* decoded index table */
284 typedef struct MXFIndexTable {
285 int index_sid;
286 int body_sid;
287 int nb_ptses; /* number of PTSes or total duration of index */
288 int64_t first_dts; /* DTS = EditUnit + first_dts */
289 int64_t *ptses; /* maps EditUnit -> PTS */
290 int nb_segments;
291 MXFIndexTableSegment **segments; /* sorted by IndexStartPosition */
292 AVIndexEntry *fake_index; /* used for calling ff_index_search_timestamp() */
293 int8_t *offsets; /* temporal offsets for display order to stored order conversion */
294 } MXFIndexTable;
295
296 typedef struct MXFContext {
297 const AVClass *class; /**< Class for private options. */
298 MXFPartition *partitions;
299 unsigned partitions_count;
300 MXFOP op;
301 UID *packages_refs;
302 int packages_count;
303 UID *essence_container_data_refs;
304 int essence_container_data_count;
305 MXFMetadataSet **metadata_sets;
306 int metadata_sets_count;
307 AVFormatContext *fc;
308 struct AVAES *aesc;
309 uint8_t *local_tags;
310 int local_tags_count;
311 uint64_t footer_partition;
312 KLVPacket current_klv_data;
313 int run_in;
314 MXFPartition *current_partition;
315 int parsing_backward;
316 int64_t last_forward_tell;
317 int last_forward_partition;
318 int nb_index_tables;
319 MXFIndexTable *index_tables;
320 int eia608_extract;
321 } MXFContext;
322
323 /* NOTE: klv_offset is not set (-1) for local keys */
324 typedef int MXFMetadataReadFunc(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset);
325
326 typedef struct MXFMetadataReadTableEntry {
327 const UID key;
328 MXFMetadataReadFunc *read;
329 int ctx_size;
330 enum MXFMetadataSetType type;
331 } MXFMetadataReadTableEntry;
332
333 /* partial keys to match */
334 static const uint8_t mxf_header_partition_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 };
335 static const uint8_t mxf_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 };
336 static const uint8_t mxf_avid_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0e,0x04,0x03,0x01 };
337 static const uint8_t mxf_canopus_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x0a,0x0e,0x0f,0x03,0x01 };
338 static const uint8_t mxf_system_item_key_cp[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x03,0x01,0x04 };
339 static const uint8_t mxf_system_item_key_gc[] = { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x03,0x01,0x14 };
340 static const uint8_t mxf_klv_key[] = { 0x06,0x0e,0x2b,0x34 };
341 static const uint8_t mxf_apple_coll_prefix[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01 };
342
343 /* complete keys to match */
344 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 };
345 static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
346 static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 };
347 static const uint8_t mxf_sony_mpeg4_extradata[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 };
348 static const uint8_t mxf_ffv1_extradata[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x0c,0x01,0x00,0x00,0x00 }; // FFV1InitializationMetadata
349 static const uint8_t mxf_avid_project_name[] = { 0xa5,0xfb,0x7b,0x25,0xf6,0x15,0x94,0xb9,0x62,0xfc,0x37,0x17,0x49,0x2d,0x42,0xbf };
350 static const uint8_t mxf_jp2k_rsiz[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x01,0x00,0x00,0x00 };
351 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 };
352 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 };
353 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 };
354 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 };
355
356 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 };
357 static const uint8_t mxf_mca_tag_symbol[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x02,0x00,0x00,0x00 };
358 static const uint8_t mxf_mca_tag_name[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x03,0x00,0x00,0x00 };
359 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 };
360 static const uint8_t mxf_mca_link_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x07,0x01,0x05,0x00,0x00,0x00 };
361 static const uint8_t mxf_mca_channel_id[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x01,0x03,0x04,0x0a,0x00,0x00,0x00,0x00 };
362 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 };
363 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 };
364
365 static const uint8_t mxf_sub_descriptor[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x04,0x06,0x10,0x00,0x00 };
366
367 static const uint8_t mxf_mastering_display_prefix[13] = { FF_MXF_MasteringDisplay_PREFIX };
368 static const uint8_t mxf_mastering_display_uls[4][16] = {
369 FF_MXF_MasteringDisplayPrimaries,
370 FF_MXF_MasteringDisplayWhitePointChromaticity,
371 FF_MXF_MasteringDisplayMaximumLuminance,
372 FF_MXF_MasteringDisplayMinimumLuminance,
373 };
374
375 #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
376
377 2910 static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx)
378 {
379 MXFIndexTableSegment *seg;
380
8/10
✓ Branch 0 taken 319 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 682 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 221 times.
✓ Branch 6 taken 105 times.
✓ Branch 7 taken 682 times.
✓ Branch 8 taken 110 times.
✓ Branch 9 taken 789 times.
2910 switch ((*ctx)->type) {
381 319 case Descriptor:
382 case MultipleDescriptor:
383 319 av_freep(&((MXFDescriptor *)*ctx)->extradata);
384 319 av_freep(&((MXFDescriptor *)*ctx)->mastering);
385 319 av_freep(&((MXFDescriptor *)*ctx)->coll);
386 319 av_freep(&((MXFDescriptor *)*ctx)->file_descriptors_refs);
387 319 av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs);
388 319 break;
389 case FFV1SubDescriptor:
390 av_freep(&((MXFFFV1SubDescriptor *)*ctx)->extradata);
391 break;
392 case AudioChannelLabelSubDescriptor:
393 case SoundfieldGroupLabelSubDescriptor:
394 case GroupOfSoundfieldGroupsLabelSubDescriptor:
395 av_freep(&((MXFMCASubDescriptor *)*ctx)->language);
396 av_freep(&((MXFMCASubDescriptor *)*ctx)->group_of_soundfield_groups_link_id_refs);
397 break;
398 682 case Sequence:
399 682 av_freep(&((MXFSequence *)*ctx)->structural_components_refs);
400 682 break;
401 2 case EssenceGroup:
402 2 av_freep(&((MXFEssenceGroup *)*ctx)->structural_components_refs);
403 2 break;
404 221 case SourcePackage:
405 case MaterialPackage:
406 221 av_freep(&((MXFPackage *)*ctx)->tracks_refs);
407 221 av_freep(&((MXFPackage *)*ctx)->name);
408 221 av_freep(&((MXFPackage *)*ctx)->comment_refs);
409 221 break;
410 105 case TaggedValue:
411 105 av_freep(&((MXFTaggedValue *)*ctx)->name);
412 105 av_freep(&((MXFTaggedValue *)*ctx)->value);
413 105 break;
414 682 case Track:
415 682 av_freep(&((MXFTrack *)*ctx)->name);
416 682 break;
417 110 case IndexTableSegment:
418 110 seg = (MXFIndexTableSegment *)*ctx;
419 110 av_freep(&seg->temporal_offset_entries);
420 110 av_freep(&seg->flag_entries);
421 110 av_freep(&seg->stream_offset_entries);
422 899 default:
423 899 break;
424 }
425
1/2
✓ Branch 0 taken 2910 times.
✗ Branch 1 not taken.
2910 if (freectx) {
426 2910 av_freep(ctx);
427 }
428 2910 }
429
430 27333 static int64_t klv_decode_ber_length(AVIOContext *pb)
431 {
432 27333 uint64_t size = avio_r8(pb);
433
2/2
✓ Branch 0 taken 25358 times.
✓ Branch 1 taken 1975 times.
27333 if (size & 0x80) { /* long form */
434 25358 int bytes_num = size & 0x7f;
435 /* SMPTE 379M 5.3.4 guarantee that bytes_num must not exceed 8 bytes */
436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25358 times.
25358 if (bytes_num > 8)
437 return AVERROR_INVALIDDATA;
438 25358 size = 0;
439
2/2
✓ Branch 0 taken 99919 times.
✓ Branch 1 taken 25358 times.
125277 while (bytes_num--)
440 99919 size = size << 8 | avio_r8(pb);
441 }
442
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27333 times.
27333 if (size > INT64_MAX)
443 return AVERROR_INVALIDDATA;
444 27333 return size;
445 }
446
447 27671 static int mxf_read_sync(AVIOContext *pb, const uint8_t *key, unsigned size)
448 {
449 int i, b;
450
4/4
✓ Branch 0 taken 171759 times.
✓ Branch 1 taken 27439 times.
✓ Branch 3 taken 171527 times.
✓ Branch 4 taken 232 times.
199198 for (i = 0; i < size && !avio_feof(pb); i++) {
451 171527 b = avio_r8(pb);
452
2/2
✓ Branch 0 taken 27592 times.
✓ Branch 1 taken 143935 times.
171527 if (b == key[0])
453 27592 i = 0;
454
2/2
✓ Branch 0 taken 60558 times.
✓ Branch 1 taken 83377 times.
143935 else if (b != key[i])
455 60558 i = -1;
456 }
457 27671 return i == size;
458 }
459
460 27565 static int klv_read_packet(KLVPacket *klv, AVIOContext *pb)
461 {
462 int64_t length, pos;
463
2/2
✓ Branch 1 taken 232 times.
✓ Branch 2 taken 27333 times.
27565 if (!mxf_read_sync(pb, mxf_klv_key, 4))
464 232 return AVERROR_INVALIDDATA;
465 27333 klv->offset = avio_tell(pb) - 4;
466 27333 memcpy(klv->key, mxf_klv_key, 4);
467 27333 avio_read(pb, klv->key + 4, 12);
468 27333 length = klv_decode_ber_length(pb);
469
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27333 times.
27333 if (length < 0)
470 return length;
471 27333 klv->length = length;
472 27333 pos = avio_tell(pb);
473
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27333 times.
27333 if (pos > INT64_MAX - length)
474 return AVERROR_INVALIDDATA;
475 27333 klv->next_klv = pos + length;
476 27333 return 0;
477 }
478
479 5350 static int mxf_get_stream_index(AVFormatContext *s, KLVPacket *klv, int body_sid)
480 {
481 int i;
482
483
1/2
✓ Branch 0 taken 8644 times.
✗ Branch 1 not taken.
8644 for (i = 0; i < s->nb_streams; i++) {
484 8644 MXFTrack *track = s->streams[i]->priv_data;
485 /* SMPTE 379M 7.3 */
486
7/10
✓ Branch 0 taken 8617 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 8617 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8617 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8617 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5350 times.
✓ Branch 9 taken 3267 times.
8644 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)))
487 5350 return i;
488 }
489 /* return 0 if only one stream, for OP Atom files with 0 as track number */
490 return s->nb_streams == 1 && s->streams[0]->priv_data ? 0 : -1;
491 }
492
493 5350 static int find_body_sid_by_absolute_offset(MXFContext *mxf, int64_t offset)
494 {
495 // we look for partition where the offset is placed
496 int a, b, m;
497 int64_t pack_ofs;
498
499 5350 a = -1;
500 5350 b = mxf->partitions_count;
501
502
2/2
✓ Branch 0 taken 10615 times.
✓ Branch 1 taken 5350 times.
15965 while (b - a > 1) {
503 10615 m = (a + b) >> 1;
504 10615 pack_ofs = mxf->partitions[m].pack_ofs;
505
2/2
✓ Branch 0 taken 5350 times.
✓ Branch 1 taken 5265 times.
10615 if (pack_ofs <= offset)
506 5350 a = m;
507 else
508 5265 b = m;
509 }
510
511
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5350 times.
5350 if (a == -1)
512 return 0;
513 5350 return mxf->partitions[a].body_sid;
514 }
515
516 static int mxf_get_eia608_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt, int64_t length)
517 {
518 int count = avio_rb16(s->pb);
519 int cdp_identifier, cdp_length, cdp_footer_id, ccdata_id, cc_count;
520 int line_num, sample_coding, sample_count;
521 int did, sdid, data_length;
522 int i, ret;
523
524 if (count > 1)
525 av_log(s, AV_LOG_WARNING, "unsupported multiple ANC packets (%d) per KLV packet\n", count);
526
527 for (i = 0; i < count; i++) {
528 if (length < 6) {
529 av_log(s, AV_LOG_ERROR, "error reading s436m packet %"PRId64"\n", length);
530 return AVERROR_INVALIDDATA;
531 }
532 line_num = avio_rb16(s->pb);
533 avio_r8(s->pb); // wrapping type
534 sample_coding = avio_r8(s->pb);
535 sample_count = avio_rb16(s->pb);
536 length -= 6 + 8 + sample_count;
537 if (line_num != 9 && line_num != 11)
538 continue;
539 if (sample_coding == 7 || sample_coding == 8 || sample_coding == 9) {
540 av_log(s, AV_LOG_WARNING, "unsupported s436m 10 bit sample coding\n");
541 continue;
542 }
543 if (length < 0)
544 return AVERROR_INVALIDDATA;
545
546 avio_rb32(s->pb); // array count
547 avio_rb32(s->pb); // array elem size
548 did = avio_r8(s->pb);
549 sdid = avio_r8(s->pb);
550 data_length = avio_r8(s->pb);
551 if (did != 0x61 || sdid != 1) {
552 av_log(s, AV_LOG_WARNING, "unsupported did or sdid: %x %x\n", did, sdid);
553 continue;
554 }
555 cdp_identifier = avio_rb16(s->pb); // cdp id
556 if (cdp_identifier != 0x9669) {
557 av_log(s, AV_LOG_ERROR, "wrong cdp identifier %x\n", cdp_identifier);
558 return AVERROR_INVALIDDATA;
559 }
560 cdp_length = avio_r8(s->pb);
561 avio_r8(s->pb); // cdp_frame_rate
562 avio_r8(s->pb); // cdp_flags
563 avio_rb16(s->pb); // cdp_hdr_sequence_cntr
564 ccdata_id = avio_r8(s->pb); // ccdata_id
565 if (ccdata_id != 0x72) {
566 av_log(s, AV_LOG_ERROR, "wrong cdp data section %x\n", ccdata_id);
567 return AVERROR_INVALIDDATA;
568 }
569 cc_count = avio_r8(s->pb) & 0x1f;
570 ret = av_get_packet(s->pb, pkt, cc_count * 3);
571 if (ret < 0)
572 return ret;
573 if (cdp_length - 9 - 4 < cc_count * 3) {
574 av_log(s, AV_LOG_ERROR, "wrong cdp size %d cc count %d\n", cdp_length, cc_count);
575 return AVERROR_INVALIDDATA;
576 }
577 avio_skip(s->pb, data_length - 9 - 4 - cc_count * 3);
578 cdp_footer_id = avio_r8(s->pb);
579 if (cdp_footer_id != 0x74) {
580 av_log(s, AV_LOG_ERROR, "wrong cdp footer section %x\n", cdp_footer_id);
581 return AVERROR_INVALIDDATA;
582 }
583 avio_rb16(s->pb); // cdp_ftr_sequence_cntr
584 avio_r8(s->pb); // packet_checksum
585 break;
586 }
587
588 return 0;
589 }
590
591 /* XXX: use AVBitStreamFilter */
592 924 static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt, int64_t length)
593 {
594 const uint8_t *buf_ptr, *end_ptr;
595 uint8_t *data_ptr;
596 int i;
597
598
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 924 times.
924 if (length > 61444) /* worst case PAL 1920 samples 8 channels */
599 return AVERROR_INVALIDDATA;
600 924 length = av_get_packet(pb, pkt, length);
601
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 924 times.
924 if (length < 0)
602 return length;
603 924 data_ptr = pkt->data;
604 924 end_ptr = pkt->data + length;
605 924 buf_ptr = pkt->data + 4; /* skip SMPTE 331M header */
606
607
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 924 times.
924 if (st->codecpar->ch_layout.nb_channels > 8)
608 return AVERROR_INVALIDDATA;
609
610
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; ) {
611
2/2
✓ Branch 0 taken 3824640 times.
✓ Branch 1 taken 1774080 times.
5598720 for (i = 0; i < st->codecpar->ch_layout.nb_channels; i++) {
612 3824640 uint32_t sample = bytestream_get_le32(&buf_ptr);
613
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3824640 times.
3824640 if (st->codecpar->bits_per_coded_sample == 24)
614 bytestream_put_le24(&data_ptr, (sample >> 4) & 0xffffff);
615 else
616 3824640 bytestream_put_le16(&data_ptr, (sample >> 12) & 0xffff);
617 }
618 // always 8 channels stored SMPTE 331M
619 1774080 buf_ptr += 32 - st->codecpar->ch_layout.nb_channels * 4;
620 }
621 924 av_shrink_packet(pkt, data_ptr - pkt->data);
622 924 return 0;
623 }
624
625 static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv)
626 {
627 static const uint8_t checkv[16] = {0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b};
628 MXFContext *mxf = s->priv_data;
629 AVIOContext *pb = s->pb;
630 int64_t end = avio_tell(pb) + klv->length;
631 int64_t size;
632 uint64_t orig_size;
633 uint64_t plaintext_size;
634 uint8_t ivec[16];
635 uint8_t tmpbuf[16];
636 int index;
637 int body_sid;
638
639 if (!mxf->aesc && s->key && s->keylen == 16) {
640 mxf->aesc = av_aes_alloc();
641 if (!mxf->aesc)
642 return AVERROR(ENOMEM);
643 av_aes_init(mxf->aesc, s->key, 128, 1);
644 }
645 // crypto context
646 size = klv_decode_ber_length(pb);
647 if (size < 0)
648 return size;
649 avio_skip(pb, size);
650 // plaintext offset
651 klv_decode_ber_length(pb);
652 plaintext_size = avio_rb64(pb);
653 // source klv key
654 klv_decode_ber_length(pb);
655 avio_read(pb, klv->key, 16);
656 if (!IS_KLV_KEY(klv, mxf_essence_element_key))
657 return AVERROR_INVALIDDATA;
658
659 body_sid = find_body_sid_by_absolute_offset(mxf, klv->offset);
660 index = mxf_get_stream_index(s, klv, body_sid);
661 if (index < 0)
662 return AVERROR_INVALIDDATA;
663 // source size
664 klv_decode_ber_length(pb);
665 orig_size = avio_rb64(pb);
666 if (orig_size < plaintext_size)
667 return AVERROR_INVALIDDATA;
668 // enc. code
669 size = klv_decode_ber_length(pb);
670 if (size < 32 || size - 32 < orig_size || (int)orig_size != orig_size)
671 return AVERROR_INVALIDDATA;
672 avio_read(pb, ivec, 16);
673 avio_read(pb, tmpbuf, 16);
674 if (mxf->aesc)
675 av_aes_crypt(mxf->aesc, tmpbuf, tmpbuf, 1, ivec, 1);
676 if (memcmp(tmpbuf, checkv, 16))
677 av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n");
678 size -= 32;
679 size = av_get_packet(pb, pkt, size);
680 if (size < 0)
681 return size;
682 else if (size < plaintext_size)
683 return AVERROR_INVALIDDATA;
684 size -= plaintext_size;
685 if (mxf->aesc)
686 av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size],
687 &pkt->data[plaintext_size], size >> 4, ivec, 1);
688 av_shrink_packet(pkt, orig_size);
689 pkt->stream_index = index;
690 avio_skip(pb, end - avio_tell(pb));
691 return 0;
692 }
693
694 107 static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
695 {
696 107 MXFContext *mxf = arg;
697 107 int item_num = avio_rb32(pb);
698 107 int item_len = avio_rb32(pb);
699
700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 107 times.
107 if (item_len != 18) {
701 avpriv_request_sample(pb, "Primer pack item length %d", item_len);
702 return AVERROR_PATCHWELCOME;
703 }
704
2/4
✓ Branch 0 taken 107 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 107 times.
107 if (item_num > 65536 || item_num < 0) {
705 av_log(mxf->fc, AV_LOG_ERROR, "item_num %d is too large\n", item_num);
706 return AVERROR_INVALIDDATA;
707 }
708
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 106 times.
107 if (mxf->local_tags)
709 1 av_log(mxf->fc, AV_LOG_VERBOSE, "Multiple primer packs\n");
710 107 av_free(mxf->local_tags);
711 107 mxf->local_tags_count = 0;
712 107 mxf->local_tags = av_calloc(item_num, item_len);
713
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 107 times.
107 if (!mxf->local_tags)
714 return AVERROR(ENOMEM);
715 107 mxf->local_tags_count = item_num;
716 107 avio_read(pb, mxf->local_tags, item_num*item_len);
717 107 return 0;
718 }
719
720 265 static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
721 {
722 265 MXFContext *mxf = arg;
723 265 AVFormatContext *s = mxf->fc;
724 MXFPartition *partition, *tmp_part;
725 UID op;
726 uint64_t footer_partition;
727 uint32_t nb_essence_containers;
728
729
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 265 times.
265 if (mxf->partitions_count >= INT_MAX / 2)
730 return AVERROR_INVALIDDATA;
731
732 265 tmp_part = av_realloc_array(mxf->partitions, mxf->partitions_count + 1, sizeof(*mxf->partitions));
733
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 265 times.
265 if (!tmp_part)
734 return AVERROR(ENOMEM);
735 265 mxf->partitions = tmp_part;
736
737
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 162 times.
265 if (mxf->parsing_backward) {
738 /* insert the new partition pack in the middle
739 * this makes the entries in mxf->partitions sorted by offset */
740 103 memmove(&mxf->partitions[mxf->last_forward_partition+1],
741 103 &mxf->partitions[mxf->last_forward_partition],
742 103 (mxf->partitions_count - mxf->last_forward_partition)*sizeof(*mxf->partitions));
743 103 partition = mxf->current_partition = &mxf->partitions[mxf->last_forward_partition];
744 } else {
745 162 mxf->last_forward_partition++;
746 162 partition = mxf->current_partition = &mxf->partitions[mxf->partitions_count];
747 }
748
749 265 memset(partition, 0, sizeof(*partition));
750 265 mxf->partitions_count++;
751 265 partition->pack_length = avio_tell(pb) - klv_offset + size;
752 265 partition->pack_ofs = klv_offset;
753
754
3/4
✓ Branch 0 taken 106 times.
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 99 times.
✗ Branch 3 not taken.
265 switch(uid[13]) {
755 106 case 2:
756 106 partition->type = Header;
757 106 break;
758 60 case 3:
759 60 partition->type = BodyPartition;
760 60 break;
761 99 case 4:
762 99 partition->type = Footer;
763 99 break;
764 default:
765 av_log(mxf->fc, AV_LOG_ERROR, "unknown partition type %i\n", uid[13]);
766 return AVERROR_INVALIDDATA;
767 }
768
769 /* consider both footers to be closed (there is only Footer and CompleteFooter) */
770
4/4
✓ Branch 0 taken 166 times.
✓ Branch 1 taken 99 times.
✓ Branch 2 taken 165 times.
✓ Branch 3 taken 1 times.
265 partition->closed = partition->type == Footer || !(uid[14] & 1);
771 265 partition->complete = uid[14] > 2;
772 265 avio_skip(pb, 4);
773 265 partition->kag_size = avio_rb32(pb);
774 265 partition->this_partition = avio_rb64(pb);
775 265 partition->previous_partition = avio_rb64(pb);
776 265 footer_partition = avio_rb64(pb);
777 265 partition->header_byte_count = avio_rb64(pb);
778 265 partition->index_byte_count = avio_rb64(pb);
779 265 partition->index_sid = avio_rb32(pb);
780 265 partition->body_offset = avio_rb64(pb);
781 265 partition->body_sid = avio_rb32(pb);
782
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 265 times.
265 if (avio_read(pb, op, sizeof(UID)) != sizeof(UID)) {
783 av_log(mxf->fc, AV_LOG_ERROR, "Failed reading UID\n");
784 return AVERROR_INVALIDDATA;
785 }
786 265 nb_essence_containers = avio_rb32(pb);
787
788
2/2
✓ Branch 0 taken 106 times.
✓ Branch 1 taken 159 times.
265 if (partition->type == Header) {
789 char str[36];
790 106 snprintf(str, sizeof(str), "%08x.%08x.%08x.%08x", AV_RB32(&op[0]), AV_RB32(&op[4]), AV_RB32(&op[8]), AV_RB32(&op[12]));
791 106 av_dict_set(&s->metadata, "operational_pattern_ul", str, 0);
792 }
793
794
2/2
✓ Branch 0 taken 159 times.
✓ Branch 1 taken 106 times.
265 if (partition->this_partition &&
795
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 159 times.
159 partition->previous_partition == partition->this_partition) {
796 av_log(mxf->fc, AV_LOG_ERROR,
797 "PreviousPartition equal to ThisPartition %"PRIx64"\n",
798 partition->previous_partition);
799 /* override with the actual previous partition offset */
800 if (!mxf->parsing_backward && mxf->last_forward_partition > 1) {
801 MXFPartition *prev =
802 mxf->partitions + mxf->last_forward_partition - 2;
803 partition->previous_partition = prev->this_partition;
804 }
805 /* if no previous body partition are found point to the header
806 * partition */
807 if (partition->previous_partition == partition->this_partition)
808 partition->previous_partition = 0;
809 av_log(mxf->fc, AV_LOG_ERROR,
810 "Overriding PreviousPartition with %"PRIx64"\n",
811 partition->previous_partition);
812 }
813
814 /* some files don't have FooterPartition set in every partition */
815
2/2
✓ Branch 0 taken 247 times.
✓ Branch 1 taken 18 times.
265 if (footer_partition) {
816
3/4
✓ Branch 0 taken 243 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 243 times.
247 if (mxf->footer_partition && mxf->footer_partition != footer_partition) {
817 av_log(mxf->fc, AV_LOG_ERROR,
818 "inconsistent FooterPartition value: %"PRIu64" != %"PRIu64"\n",
819 mxf->footer_partition, footer_partition);
820 } else {
821 247 mxf->footer_partition = footer_partition;
822 }
823 }
824
825 265 av_log(mxf->fc, AV_LOG_TRACE,
826 "PartitionPack: ThisPartition = 0x%"PRIX64
827 ", PreviousPartition = 0x%"PRIX64", "
828 "FooterPartition = 0x%"PRIX64", IndexSID = %i, BodySID = %i\n",
829 partition->this_partition,
830 partition->previous_partition, footer_partition,
831 partition->index_sid, partition->body_sid);
832
833 /* sanity check PreviousPartition if set */
834 //NOTE: this isn't actually enough, see mxf_seek_to_previous_partition()
835
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 205 times.
265 if (partition->previous_partition &&
836
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 mxf->run_in + partition->previous_partition >= klv_offset) {
837 av_log(mxf->fc, AV_LOG_ERROR,
838 "PreviousPartition points to this partition or forward\n");
839 return AVERROR_INVALIDDATA;
840 }
841
842
3/4
✓ Branch 0 taken 227 times.
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 227 times.
✗ Branch 3 not taken.
265 if (op[12] == 1 && op[13] == 1) mxf->op = OP1a;
843
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;
844
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;
845
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;
846
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;
847
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;
848
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;
849
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;
850
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;
851
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;
852
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 else if (op[12] == 0x10) {
853 /* SMPTE 390m: "There shall be exactly one essence container"
854 * The following block deals with files that violate this, namely:
855 * 2011_DCPTEST_24FPS.V.mxf - two ECs, OP1a
856 * abcdefghiv016f56415e.mxf - zero ECs, OPAtom, output by Avid AirSpeed */
857
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 33 times.
36 if (nb_essence_containers != 1) {
858
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 MXFOP op = nb_essence_containers ? OP1a : OPAtom;
859
860 /* only nag once */
861
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (!mxf->op)
862
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 av_log(mxf->fc, AV_LOG_WARNING,
863 "\"OPAtom\" with %"PRIu32" ECs - assuming %s\n",
864 nb_essence_containers,
865 op == OP1a ? "OP1a" : "OPAtom");
866
867 3 mxf->op = op;
868 } else
869 33 mxf->op = OPAtom;
870 } else {
871 av_log(mxf->fc, AV_LOG_ERROR, "unknown operational pattern: %02xh %02xh - guessing OP1a\n", op[12], op[13]);
872 mxf->op = OP1a;
873 }
874
875
3/4
✓ Branch 0 taken 263 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 263 times.
265 if (partition->kag_size <= 0 || partition->kag_size > (1 << 20)) {
876 2 av_log(mxf->fc, AV_LOG_WARNING, "invalid KAGSize %"PRId32" - guessing ",
877 partition->kag_size);
878
879
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (mxf->op == OPSONYOpt)
880 2 partition->kag_size = 512;
881 else
882 partition->kag_size = 1;
883
884 2 av_log(mxf->fc, AV_LOG_WARNING, "%"PRId32"\n", partition->kag_size);
885 }
886
887 265 return 0;
888 }
889
890 2908 static uint64_t partition_score(MXFPartition *p)
891 {
892 uint64_t score;
893
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2908 times.
2908 if (!p)
894 return 0;
895
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 2780 times.
2908 if (p->type == Footer)
896 128 score = 5;
897
2/2
✓ Branch 0 taken 2555 times.
✓ Branch 1 taken 225 times.
2780 else if (p->complete)
898 2555 score = 4;
899
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 75 times.
225 else if (p->closed)
900 150 score = 3;
901 else
902 75 score = 1;
903 2908 return (score << 60) | ((uint64_t)p->this_partition >> 4);
904 }
905
906 2910 static int mxf_add_metadata_set(MXFContext *mxf, MXFMetadataSet **metadata_set)
907 {
908 MXFMetadataSet **tmp;
909 2910 enum MXFMetadataSetType type = (*metadata_set)->type;
910
911 // Index Table is special because it might be added manually without
912 // partition and we iterate thorugh all instances of them. Also some files
913 // use the same Instance UID for different index tables...
914
2/2
✓ Branch 0 taken 2802 times.
✓ Branch 1 taken 108 times.
2910 if (type != IndexTableSegment) {
915
2/2
✓ Branch 0 taken 45134 times.
✓ Branch 1 taken 2802 times.
47936 for (int i = 0; i < mxf->metadata_sets_count; i++) {
916
3/4
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 45059 times.
✓ Branch 2 taken 75 times.
✗ Branch 3 not taken.
45134 if (!memcmp((*metadata_set)->uid, mxf->metadata_sets[i]->uid, 16) && type == mxf->metadata_sets[i]->type) {
917 75 uint64_t old_s = mxf->metadata_sets[i]->partition_score;
918 75 uint64_t new_s = (*metadata_set)->partition_score;
919
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 75 times.
75 if (old_s > new_s) {
920 mxf_free_metadataset(metadata_set, 1);
921 return 0;
922 }
923 }
924 }
925 }
926 2910 tmp = av_realloc_array(mxf->metadata_sets, mxf->metadata_sets_count + 1, sizeof(*mxf->metadata_sets));
927
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2910 times.
2910 if (!tmp) {
928 mxf_free_metadataset(metadata_set, 1);
929 return AVERROR(ENOMEM);
930 }
931 2910 mxf->metadata_sets = tmp;
932 2910 mxf->metadata_sets[mxf->metadata_sets_count] = *metadata_set;
933 2910 mxf->metadata_sets_count++;
934 2910 return 0;
935 }
936
937 static int mxf_read_cryptographic_context(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
938 {
939 MXFCryptoContext *cryptocontext = arg;
940 if (size != 16)
941 return AVERROR_INVALIDDATA;
942 if (IS_KLV_KEY(uid, mxf_crypto_source_container_ul))
943 avio_read(pb, cryptocontext->source_container_ul, 16);
944 return 0;
945 }
946
947 1228 static int mxf_read_strong_ref_array(AVIOContext *pb, UID **refs, int *count)
948 {
949 int64_t ret;
950 1228 unsigned c = avio_rb32(pb);
951
952 //avio_read() used int
953
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1228 times.
1228 if (c > INT_MAX / sizeof(UID))
954 return AVERROR_PATCHWELCOME;
955 1228 *count = c;
956
957 1228 av_free(*refs);
958 1228 *refs = av_malloc_array(*count, sizeof(UID));
959
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1228 times.
1228 if (!*refs) {
960 *count = 0;
961 return AVERROR(ENOMEM);
962 }
963 1228 avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */
964 1228 ret = avio_read(pb, (uint8_t *)*refs, *count * sizeof(UID));
965
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1228 times.
1228 if (ret != *count * sizeof(UID)) {
966 *count = ret < 0 ? 0 : ret / sizeof(UID);
967 return ret < 0 ? ret : AVERROR_INVALIDDATA;
968 }
969
970 1228 return 0;
971 }
972
973 static inline int mxf_read_us_ascii_string(AVIOContext *pb, int size, char** str)
974 {
975 int ret;
976 size_t buf_size;
977
978 if (size < 0 || size > INT_MAX - 1)
979 return AVERROR(EINVAL);
980
981 buf_size = size + 1;
982 av_free(*str);
983 *str = av_malloc(buf_size);
984 if (!*str)
985 return AVERROR(ENOMEM);
986
987 ret = avio_get_str(pb, size, *str, buf_size);
988
989 if (ret < 0) {
990 av_freep(str);
991 return ret;
992 }
993
994 return ret;
995 }
996
997 627 static inline int mxf_read_utf16_string(AVIOContext *pb, int size, char** str, int be)
998 {
999 int ret;
1000 size_t buf_size;
1001
1002
2/4
✓ Branch 0 taken 627 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 627 times.
627 if (size < 0 || size > INT_MAX/2)
1003 return AVERROR(EINVAL);
1004
1005 627 buf_size = size + size / 2 + 1;
1006 627 av_free(*str);
1007 627 *str = av_malloc(buf_size);
1008
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 627 times.
627 if (!*str)
1009 return AVERROR(ENOMEM);
1010
1011
2/2
✓ Branch 0 taken 588 times.
✓ Branch 1 taken 39 times.
627 if (be)
1012 588 ret = avio_get_str16be(pb, size, *str, buf_size);
1013 else
1014 39 ret = avio_get_str16le(pb, size, *str, buf_size);
1015
1016
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 627 times.
627 if (ret < 0) {
1017 av_freep(str);
1018 return ret;
1019 }
1020
1021 627 return ret;
1022 }
1023
1024 #define READ_STR16(type, big_endian) \
1025 static int mxf_read_utf16 ## type ##_string(AVIOContext *pb, int size, char** str) \
1026 { \
1027 return mxf_read_utf16_string(pb, size, str, big_endian); \
1028 }
1029 588 READ_STR16(be, 1)
1030 39 READ_STR16(le, 0)
1031 #undef READ_STR16
1032
1033 321 static int mxf_read_content_storage(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1034 {
1035 321 MXFContext *mxf = arg;
1036
3/3
✓ Branch 0 taken 107 times.
✓ Branch 1 taken 107 times.
✓ Branch 2 taken 107 times.
321 switch (tag) {
1037 107 case 0x1901:
1038
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 106 times.
107 if (mxf->packages_refs)
1039 1 av_log(mxf->fc, AV_LOG_VERBOSE, "Multiple packages_refs\n");
1040 107 return mxf_read_strong_ref_array(pb, &mxf->packages_refs, &mxf->packages_count);
1041 107 case 0x1902:
1042 107 return mxf_read_strong_ref_array(pb, &mxf->essence_container_data_refs, &mxf->essence_container_data_count);
1043 }
1044 107 return 0;
1045 }
1046
1047 2380 static int mxf_read_source_clip(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1048 {
1049 2380 MXFStructuralComponent *source_clip = arg;
1050
5/5
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 476 times.
✓ Branch 2 taken 476 times.
✓ Branch 3 taken 476 times.
✓ Branch 4 taken 476 times.
2380 switch(tag) {
1051 476 case 0x0202:
1052 476 source_clip->duration = avio_rb64(pb);
1053 476 break;
1054 476 case 0x1201:
1055 476 source_clip->start_position = avio_rb64(pb);
1056 476 break;
1057 476 case 0x1101:
1058 /* UMID, only get last 16 bytes */
1059 476 avio_read(pb, source_clip->source_package_ul, 16);
1060 476 avio_read(pb, source_clip->source_package_uid, 16);
1061 476 break;
1062 476 case 0x1102:
1063 476 source_clip->source_track_id = avio_rb32(pb);
1064 476 break;
1065 }
1066 2380 return 0;
1067 }
1068
1069 1025 static int mxf_read_timecode_component(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1070 {
1071 1025 MXFTimecodeComponent *mxf_timecode = arg;
1072
4/4
✓ Branch 0 taken 205 times.
✓ Branch 1 taken 205 times.
✓ Branch 2 taken 205 times.
✓ Branch 3 taken 410 times.
1025 switch(tag) {
1073 205 case 0x1501:
1074 205 mxf_timecode->start_frame = avio_rb64(pb);
1075 205 break;
1076 205 case 0x1502:
1077 205 mxf_timecode->rate = (AVRational){avio_rb16(pb), 1};
1078 205 break;
1079 205 case 0x1503:
1080 205 mxf_timecode->drop_frame = avio_r8(pb);
1081 205 break;
1082 }
1083 1025 return 0;
1084 }
1085
1086 6 static int mxf_read_pulldown_component(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1087 {
1088 6 MXFPulldownComponent *mxf_pulldown = arg;
1089
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 switch(tag) {
1090 1 case 0x0d01:
1091 1 avio_read(pb, mxf_pulldown->input_segment_ref, 16);
1092 1 break;
1093 }
1094 6 return 0;
1095 }
1096
1097 3454 static int mxf_read_track(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1098 {
1099 3454 MXFTrack *track = arg;
1100
6/6
✓ Branch 0 taken 682 times.
✓ Branch 1 taken 682 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 680 times.
✓ Branch 4 taken 682 times.
✓ Branch 5 taken 680 times.
3454 switch(tag) {
1101 682 case 0x4801:
1102 682 track->track_id = avio_rb32(pb);
1103 682 break;
1104 682 case 0x4804:
1105 682 avio_read(pb, track->track_number, 4);
1106 682 break;
1107 48 case 0x4802:
1108 48 mxf_read_utf16be_string(pb, size, &track->name);
1109 48 break;
1110 680 case 0x4b01:
1111 680 track->edit_rate.num = avio_rb32(pb);
1112 680 track->edit_rate.den = avio_rb32(pb);
1113 680 break;
1114 682 case 0x4803:
1115 682 avio_read(pb, track->sequence_ref, 16);
1116 682 break;
1117 }
1118 3454 return 0;
1119 }
1120
1121 2044 static int mxf_read_sequence(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1122 {
1123 2044 MXFSequence *sequence = arg;
1124
3/5
✓ Branch 0 taken 680 times.
✓ Branch 1 taken 682 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 682 times.
✗ Branch 4 not taken.
2044 switch(tag) {
1125 680 case 0x0202:
1126 680 sequence->duration = avio_rb64(pb);
1127 680 break;
1128 682 case 0x0201:
1129 682 avio_read(pb, sequence->data_definition_ul, 16);
1130 682 break;
1131 case 0x4b02:
1132 sequence->origin = avio_r8(pb);
1133 break;
1134 682 case 0x1001:
1135 682 return mxf_read_strong_ref_array(pb, &sequence->structural_components_refs,
1136 &sequence->structural_components_count);
1137 }
1138 1362 return 0;
1139 }
1140
1141 8 static int mxf_read_essence_group(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1142 {
1143 8 MXFEssenceGroup *essence_group = arg;
1144
3/3
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
8 switch (tag) {
1145 2 case 0x0202:
1146 2 essence_group->duration = avio_rb64(pb);
1147 2 break;
1148 2 case 0x0501:
1149 2 return mxf_read_strong_ref_array(pb, &essence_group->structural_components_refs,
1150 &essence_group->structural_components_count);
1151 }
1152 6 return 0;
1153 }
1154
1155 1059 static int mxf_read_package(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1156 {
1157 1059 MXFPackage *package = arg;
1158
6/6
✓ Branch 0 taken 221 times.
✓ Branch 1 taken 221 times.
✓ Branch 2 taken 114 times.
✓ Branch 3 taken 25 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 468 times.
1059 switch(tag) {
1159 221 case 0x4403:
1160 221 return mxf_read_strong_ref_array(pb, &package->tracks_refs,
1161 &package->tracks_count);
1162 221 case 0x4401:
1163 /* UMID */
1164 221 avio_read(pb, package->package_ul, 16);
1165 221 avio_read(pb, package->package_uid, 16);
1166 221 break;
1167 114 case 0x4701:
1168 114 avio_read(pb, package->descriptor_ref, 16);
1169 114 break;
1170 25 case 0x4402:
1171 25 return mxf_read_utf16be_string(pb, size, &package->name);
1172 10 case 0x4406:
1173 10 return mxf_read_strong_ref_array(pb, &package->comment_refs,
1174 &package->comment_count);
1175 }
1176 803 return 0;
1177 }
1178
1179 325 static int mxf_read_essence_container_data(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1180 {
1181 325 MXFEssenceContainerData *essence_data = arg;
1182
4/4
✓ Branch 0 taken 107 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 107 times.
✓ Branch 3 taken 6 times.
325 switch(tag) {
1183 107 case 0x2701:
1184 /* linked package umid UMID */
1185 107 avio_read(pb, essence_data->package_ul, 16);
1186 107 avio_read(pb, essence_data->package_uid, 16);
1187 107 break;
1188 105 case 0x3f06:
1189 105 essence_data->index_sid = avio_rb32(pb);
1190 105 break;
1191 107 case 0x3f07:
1192 107 essence_data->body_sid = avio_rb32(pb);
1193 107 break;
1194 }
1195 325 return 0;
1196 }
1197
1198 56 static int mxf_read_index_entry_array(AVIOContext *pb, MXFIndexTableSegment *segment)
1199 {
1200 int i, length;
1201
1202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if (segment->temporal_offset_entries)
1203 return AVERROR_INVALIDDATA;
1204
1205 56 segment->nb_index_entries = avio_rb32(pb);
1206
1207 56 length = avio_rb32(pb);
1208
3/4
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 53 times.
56 if(segment->nb_index_entries && length < 11)
1209 return AVERROR_INVALIDDATA;
1210
1211
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 if (!FF_ALLOC_TYPED_ARRAY(segment->temporal_offset_entries, segment->nb_index_entries) ||
1212
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 !FF_ALLOC_TYPED_ARRAY(segment->flag_entries , segment->nb_index_entries) ||
1213
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
56 !FF_ALLOC_TYPED_ARRAY(segment->stream_offset_entries , segment->nb_index_entries)) {
1214 av_freep(&segment->temporal_offset_entries);
1215 av_freep(&segment->flag_entries);
1216 return AVERROR(ENOMEM);
1217 }
1218
1219
2/2
✓ Branch 0 taken 1368 times.
✓ Branch 1 taken 56 times.
1424 for (i = 0; i < segment->nb_index_entries; i++) {
1220
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1368 times.
1368 if(avio_feof(pb))
1221 return AVERROR_INVALIDDATA;
1222 1368 segment->temporal_offset_entries[i] = avio_r8(pb);
1223 1368 avio_r8(pb); /* KeyFrameOffset */
1224 1368 segment->flag_entries[i] = avio_r8(pb);
1225 1368 segment->stream_offset_entries[i] = avio_rb64(pb);
1226 1368 avio_skip(pb, length - 11);
1227 }
1228 56 return 0;
1229 }
1230
1231 906 static int mxf_read_index_table_segment(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1232 {
1233 906 MXFIndexTableSegment *segment = arg;
1234
8/8
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 108 times.
✓ Branch 3 taken 56 times.
✓ Branch 4 taken 108 times.
✓ Branch 5 taken 108 times.
✓ Branch 6 taken 108 times.
✓ Branch 7 taken 202 times.
906 switch(tag) {
1235 108 case 0x3F05:
1236 108 segment->edit_unit_byte_count = avio_rb32(pb);
1237 108 av_log(NULL, AV_LOG_TRACE, "EditUnitByteCount %d\n", segment->edit_unit_byte_count);
1238 108 break;
1239 108 case 0x3F06:
1240 108 segment->index_sid = avio_rb32(pb);
1241 108 av_log(NULL, AV_LOG_TRACE, "IndexSID %d\n", segment->index_sid);
1242 108 break;
1243 108 case 0x3F07:
1244 108 segment->body_sid = avio_rb32(pb);
1245 108 av_log(NULL, AV_LOG_TRACE, "BodySID %d\n", segment->body_sid);
1246 108 break;
1247 56 case 0x3F0A:
1248 56 av_log(NULL, AV_LOG_TRACE, "IndexEntryArray found\n");
1249 56 return mxf_read_index_entry_array(pb, segment);
1250 108 case 0x3F0B:
1251 108 segment->index_edit_rate.num = avio_rb32(pb);
1252 108 segment->index_edit_rate.den = avio_rb32(pb);
1253 108 av_log(NULL, AV_LOG_TRACE, "IndexEditRate %d/%d\n", segment->index_edit_rate.num,
1254 segment->index_edit_rate.den);
1255 108 break;
1256 108 case 0x3F0C:
1257 108 segment->index_start_position = avio_rb64(pb);
1258 108 av_log(NULL, AV_LOG_TRACE, "IndexStartPosition %"PRId64"\n", segment->index_start_position);
1259 108 break;
1260 108 case 0x3F0D:
1261 108 segment->index_duration = avio_rb64(pb);
1262 108 av_log(NULL, AV_LOG_TRACE, "IndexDuration %"PRId64"\n", segment->index_duration);
1263 108 break;
1264 }
1265 850 return 0;
1266 }
1267
1268 2 static void mxf_read_pixel_layout(AVIOContext *pb, MXFDescriptor *descriptor)
1269 {
1270 2 int code, value, ofs = 0;
1271 2 char layout[16] = {0}; /* not for printing, may end up not terminated on purpose */
1272
1273 do {
1274 6 code = avio_r8(pb);
1275 6 value = avio_r8(pb);
1276 6 av_log(NULL, AV_LOG_TRACE, "pixel layout: code %#x\n", code);
1277
1278
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (ofs <= 14) {
1279 6 layout[ofs++] = code;
1280 6 layout[ofs++] = value;
1281 } else
1282 break; /* don't read byte by byte on sneaky files filled with lots of non-zeroes */
1283
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 } while (code != 0); /* SMPTE 377M E.2.46 */
1284
1285 2 ff_mxf_decode_pixel_layout(layout, &descriptor->pix_fmt);
1286 2 }
1287
1288 4492 static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1289 {
1290 4492 MXFDescriptor *descriptor = arg;
1291 int entry_count, entry_size;
1292
1293
27/27
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 319 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 220 times.
✓ Branch 5 taken 101 times.
✓ Branch 6 taken 102 times.
✓ Branch 7 taken 102 times.
✓ Branch 8 taken 102 times.
✓ Branch 9 taken 101 times.
✓ Branch 10 taken 102 times.
✓ Branch 11 taken 23 times.
✓ Branch 12 taken 45 times.
✓ Branch 13 taken 9 times.
✓ Branch 14 taken 8 times.
✓ Branch 15 taken 99 times.
✓ Branch 16 taken 99 times.
✓ Branch 17 taken 62 times.
✓ Branch 18 taken 62 times.
✓ Branch 19 taken 62 times.
✓ Branch 20 taken 98 times.
✓ Branch 21 taken 124 times.
✓ Branch 22 taken 14 times.
✓ Branch 23 taken 124 times.
✓ Branch 24 taken 124 times.
✓ Branch 25 taken 2 times.
✓ Branch 26 taken 2269 times.
4492 switch(tag) {
1294 92 case 0x3F01:
1295 92 return mxf_read_strong_ref_array(pb, &descriptor->file_descriptors_refs,
1296 &descriptor->file_descriptors_count);
1297 21 case 0x3002: /* ContainerDuration */
1298 21 descriptor->duration = avio_rb64(pb);
1299 21 break;
1300 319 case 0x3004:
1301 319 avio_read(pb, descriptor->essence_container_ul, 16);
1302 319 break;
1303 6 case 0x3005:
1304 6 avio_read(pb, descriptor->codec_ul, 16);
1305 6 break;
1306 220 case 0x3006:
1307 220 descriptor->linked_track_id = avio_rb32(pb);
1308 220 break;
1309 101 case 0x3201: /* PictureEssenceCoding */
1310 101 avio_read(pb, descriptor->essence_codec_ul, 16);
1311 101 break;
1312 102 case 0x3203:
1313 102 descriptor->width = avio_rb32(pb);
1314 102 break;
1315 102 case 0x3202:
1316 102 descriptor->height = avio_rb32(pb);
1317 102 break;
1318 102 case 0x320C:
1319 102 descriptor->frame_layout = avio_r8(pb);
1320 102 break;
1321 101 case 0x320D:
1322 101 entry_count = avio_rb32(pb);
1323 101 entry_size = avio_rb32(pb);
1324
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 if (entry_size == 4) {
1325
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 if (entry_count > 0)
1326 101 descriptor->video_line_map[0] = avio_rb32(pb);
1327 else
1328 descriptor->video_line_map[0] = 0;
1329
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 3 times.
101 if (entry_count > 1)
1330 98 descriptor->video_line_map[1] = avio_rb32(pb);
1331 else
1332 3 descriptor->video_line_map[1] = 0;
1333 } else
1334 av_log(NULL, AV_LOG_WARNING, "VideoLineMap element size %d currently not supported\n", entry_size);
1335 101 break;
1336 102 case 0x320E:
1337 102 descriptor->aspect_ratio.num = avio_rb32(pb);
1338 102 descriptor->aspect_ratio.den = avio_rb32(pb);
1339 102 break;
1340 23 case 0x3210:
1341 23 avio_read(pb, descriptor->color_trc_ul, 16);
1342 23 break;
1343 45 case 0x3212:
1344 45 descriptor->field_dominance = avio_r8(pb);
1345 45 break;
1346 9 case 0x3219:
1347 9 avio_read(pb, descriptor->color_primaries_ul, 16);
1348 9 break;
1349 8 case 0x321A:
1350 8 avio_read(pb, descriptor->color_space_ul, 16);
1351 8 break;
1352 99 case 0x3301:
1353 99 descriptor->component_depth = avio_rb32(pb);
1354 99 break;
1355 99 case 0x3302:
1356 99 descriptor->horiz_subsampling = avio_rb32(pb);
1357 99 break;
1358 62 case 0x3304:
1359 62 descriptor->black_ref_level = avio_rb32(pb);
1360 62 break;
1361 62 case 0x3305:
1362 62 descriptor->white_ref_level = avio_rb32(pb);
1363 62 break;
1364 62 case 0x3306:
1365 62 descriptor->color_range = avio_rb32(pb);
1366 62 break;
1367 98 case 0x3308:
1368 98 descriptor->vert_subsampling = avio_rb32(pb);
1369 98 break;
1370 124 case 0x3D03:
1371 124 descriptor->sample_rate.num = avio_rb32(pb);
1372 124 descriptor->sample_rate.den = avio_rb32(pb);
1373 124 break;
1374 14 case 0x3D06: /* SoundEssenceCompression */
1375 14 avio_read(pb, descriptor->essence_codec_ul, 16);
1376 14 break;
1377 124 case 0x3D07:
1378 124 descriptor->channels = avio_rb32(pb);
1379 124 break;
1380 124 case 0x3D01:
1381 124 descriptor->bits_per_sample = avio_rb32(pb);
1382 124 break;
1383 2 case 0x3401:
1384 2 mxf_read_pixel_layout(pb, descriptor);
1385 2 break;
1386 2269 default:
1387 /* Private uid used by SONY C0023S01.mxf */
1388
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2268 times.
2269 if (IS_KLV_KEY(uid, mxf_sony_mpeg4_extradata)) {
1389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (descriptor->extradata)
1390 av_log(NULL, AV_LOG_WARNING, "Duplicate sony_mpeg4_extradata\n");
1391 1 av_free(descriptor->extradata);
1392 1 descriptor->extradata_size = 0;
1393 1 descriptor->extradata = av_malloc(size);
1394
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!descriptor->extradata)
1395 return AVERROR(ENOMEM);
1396 1 descriptor->extradata_size = size;
1397 1 avio_read(pb, descriptor->extradata, size);
1398 }
1399
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2269 times.
2269 if (IS_KLV_KEY(uid, mxf_jp2k_rsiz)) {
1400 uint32_t rsiz = avio_rb16(pb);
1401 if (rsiz == FF_PROFILE_JPEG2000_DCINEMA_2K ||
1402 rsiz == FF_PROFILE_JPEG2000_DCINEMA_4K)
1403 descriptor->pix_fmt = AV_PIX_FMT_XYZ12;
1404 }
1405
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 2249 times.
2269 if (IS_KLV_KEY(uid, mxf_mastering_display_prefix)) {
1406
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
20 if (!descriptor->mastering) {
1407 5 descriptor->mastering = av_mastering_display_metadata_alloc();
1408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!descriptor->mastering)
1409 return AVERROR(ENOMEM);
1410 }
1411
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
20 if (IS_KLV_KEY(uid, mxf_mastering_display_uls[0])) {
1412
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 5 times.
20 for (int i = 0; i < 3; i++) {
1413 /* Order: large x, large y, other (i.e. RGB) */
1414 15 descriptor->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
1415 15 descriptor->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
1416 }
1417 /* Check we have seen mxf_mastering_display_white_point_chromaticity */
1418
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (descriptor->mastering->white_point[0].den != 0)
1419 descriptor->mastering->has_primaries = 1;
1420 }
1421
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
20 if (IS_KLV_KEY(uid, mxf_mastering_display_uls[1])) {
1422 5 descriptor->mastering->white_point[0] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
1423 5 descriptor->mastering->white_point[1] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
1424 /* Check we have seen mxf_mastering_display_primaries */
1425
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (descriptor->mastering->display_primaries[0][0].den != 0)
1426 5 descriptor->mastering->has_primaries = 1;
1427 }
1428
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
20 if (IS_KLV_KEY(uid, mxf_mastering_display_uls[2])) {
1429 5 descriptor->mastering->max_luminance = av_make_q(avio_rb32(pb), FF_MXF_MASTERING_LUMA_DEN);
1430 /* Check we have seen mxf_mastering_display_minimum_luminance */
1431
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (descriptor->mastering->min_luminance.den != 0)
1432 descriptor->mastering->has_luminance = 1;
1433 }
1434
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
20 if (IS_KLV_KEY(uid, mxf_mastering_display_uls[3])) {
1435 5 descriptor->mastering->min_luminance = av_make_q(avio_rb32(pb), FF_MXF_MASTERING_LUMA_DEN);
1436 /* Check we have seen mxf_mastering_display_maximum_luminance */
1437
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (descriptor->mastering->max_luminance.den != 0)
1438 5 descriptor->mastering->has_luminance = 1;
1439 }
1440 }
1441
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2263 times.
2269 if (IS_KLV_KEY(uid, mxf_apple_coll_prefix)) {
1442
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (!descriptor->coll) {
1443 3 descriptor->coll = av_content_light_metadata_alloc(&descriptor->coll_size);
1444
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!descriptor->coll)
1445 return AVERROR(ENOMEM);
1446 }
1447
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (IS_KLV_KEY(uid, mxf_apple_coll_max_cll)) {
1448 3 descriptor->coll->MaxCLL = avio_rb16(pb);
1449 }
1450
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (IS_KLV_KEY(uid, mxf_apple_coll_max_fall)) {
1451 3 descriptor->coll->MaxFALL = avio_rb16(pb);
1452 }
1453 }
1454
1455
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2262 times.
2269 if (IS_KLV_KEY(uid, mxf_sub_descriptor))
1456 7 return mxf_read_strong_ref_array(pb, &descriptor->sub_descriptors_refs, &descriptor->sub_descriptors_count);
1457
1458 2262 break;
1459 }
1460 4393 return 0;
1461 }
1462
1463 static int mxf_read_mca_sub_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1464 {
1465 MXFMCASubDescriptor *mca_sub_descriptor = arg;
1466
1467 if (IS_KLV_KEY(uid, mxf_mca_label_dictionary_id))
1468 avio_read(pb, mca_sub_descriptor->mca_label_dictionary_id, 16);
1469
1470 if (IS_KLV_KEY(uid, mxf_mca_link_id))
1471 avio_read(pb, mca_sub_descriptor->mca_link_id, 16);
1472
1473 if (IS_KLV_KEY(uid, mxf_soundfield_group_link_id))
1474 avio_read(pb, mca_sub_descriptor->soundfield_group_link_id, 16);
1475
1476 if (IS_KLV_KEY(uid, mxf_group_of_soundfield_groups_link_id))
1477 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);
1478
1479 if (IS_KLV_KEY(uid, mxf_mca_channel_id))
1480 mca_sub_descriptor->mca_channel_id = avio_rb32(pb);
1481
1482 if (IS_KLV_KEY(uid, mxf_mca_rfc5646_spoken_language))
1483 return mxf_read_us_ascii_string(pb, size, &mca_sub_descriptor->language);
1484
1485 return 0;
1486 }
1487
1488 static int mxf_read_ffv1_sub_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1489 {
1490 MXFFFV1SubDescriptor *ffv1_sub_descriptor = arg;
1491
1492 if (IS_KLV_KEY(uid, mxf_ffv1_extradata) && size <= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE ) {
1493 if (ffv1_sub_descriptor->extradata)
1494 av_log(NULL, AV_LOG_WARNING, "Duplicate ffv1_extradata\n");
1495 av_free(ffv1_sub_descriptor->extradata);
1496 ffv1_sub_descriptor->extradata_size = 0;
1497 ffv1_sub_descriptor->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
1498 if (!ffv1_sub_descriptor->extradata)
1499 return AVERROR(ENOMEM);
1500 ffv1_sub_descriptor->extradata_size = size;
1501 avio_read(pb, ffv1_sub_descriptor->extradata, size);
1502 }
1503
1504 return 0;
1505 }
1506
1507 105 static int mxf_read_indirect_value(void *arg, AVIOContext *pb, int size)
1508 {
1509 105 MXFTaggedValue *tagged_value = arg;
1510 uint8_t key[17];
1511
1512
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 105 times.
105 if (size <= 17)
1513 return 0;
1514
1515 105 avio_read(pb, key, 17);
1516 /* TODO: handle other types of of indirect values */
1517
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 66 times.
105 if (memcmp(key, mxf_indirect_value_utf16le, 17) == 0) {
1518 39 return mxf_read_utf16le_string(pb, size - 17, &tagged_value->value);
1519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 } else if (memcmp(key, mxf_indirect_value_utf16be, 17) == 0) {
1520 return mxf_read_utf16be_string(pb, size - 17, &tagged_value->value);
1521 }
1522 66 return 0;
1523 }
1524
1525 232 static int mxf_read_tagged_value(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
1526 {
1527 232 MXFTaggedValue *tagged_value = arg;
1528
3/3
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 22 times.
232 switch (tag){
1529 105 case 0x5001:
1530 105 return mxf_read_utf16be_string(pb, size, &tagged_value->name);
1531 105 case 0x5003:
1532 105 return mxf_read_indirect_value(tagged_value, pb, size);
1533 }
1534 22 return 0;
1535 }
1536
1537 /*
1538 * Match an uid independently of the version byte and up to len common bytes
1539 * Returns: boolean
1540 */
1541 43325 static int mxf_match_uid(const UID key, const UID uid, int len)
1542 {
1543 int i;
1544
2/2
✓ Branch 0 taken 233288 times.
✓ Branch 1 taken 840 times.
234128 for (i = 0; i < len; i++) {
1545
4/4
✓ Branch 0 taken 227830 times.
✓ Branch 1 taken 5458 times.
✓ Branch 2 taken 42485 times.
✓ Branch 3 taken 185345 times.
233288 if (i != 7 && key[i] != uid[i])
1546 42485 return 0;
1547 }
1548 840 return 1;
1549 }
1550
1551 1524 static const MXFCodecUL *mxf_get_codec_ul(const MXFCodecUL *uls, UID *uid)
1552 {
1553
2/2
✓ Branch 0 taken 15991 times.
✓ Branch 1 taken 686 times.
16677 while (uls->uid[0]) {
1554
2/2
✓ Branch 1 taken 838 times.
✓ Branch 2 taken 15153 times.
15991 if(mxf_match_uid(uls->uid, *uid, uls->matching_len))
1555 838 break;
1556 15153 uls++;
1557 }
1558 1524 return uls;
1559 }
1560
1561 4700 static void *mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMetadataSetType type)
1562 {
1563 int i;
1564
1565
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4700 times.
4700 if (!strong_ref)
1566 return NULL;
1567
2/2
✓ Branch 0 taken 94285 times.
✓ Branch 1 taken 1031 times.
95316 for (i = mxf->metadata_sets_count - 1; i >= 0; i--) {
1568
4/4
✓ Branch 0 taken 4719 times.
✓ Branch 1 taken 89566 times.
✓ Branch 2 taken 4047 times.
✓ Branch 3 taken 672 times.
94285 if (!memcmp(*strong_ref, mxf->metadata_sets[i]->uid, 16) &&
1569
2/2
✓ Branch 0 taken 2997 times.
✓ Branch 1 taken 1050 times.
4047 (type == AnyType || mxf->metadata_sets[i]->type == type)) {
1570 3669 return mxf->metadata_sets[i];
1571 }
1572 }
1573 1031 return NULL;
1574 }
1575
1576 static const MXFCodecUL mxf_picture_essence_container_uls[] = {
1577 // video essence container uls
1578 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0c,0x01,0x00 }, 14, AV_CODEC_ID_JPEG2000, NULL, 14, J2KWrap },
1579 { { 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 */
1580 { { 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 */
1581 { { 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 */
1582 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x14,0x01,0x00 }, 14, AV_CODEC_ID_TIFF, NULL, 14 }, /* TIFF */
1583 { { 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 */
1584 { { 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 */
1585 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x1c,0x01,0x00 }, 14, AV_CODEC_ID_PRORES, NULL, 14 }, /* ProRes */
1586 { { 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 */
1587 { { 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 */
1588 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x0d,0x01,0x03,0x01,0x02,0x23,0x01,0x00 }, 14, AV_CODEC_ID_FFV1, NULL, 14 },
1589 { { 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 */
1590 { { 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 */
1591 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0a,0x0e,0x0f,0x03,0x01,0x02,0x20,0x01,0x01 }, 15, AV_CODEC_ID_HQ_HQA },
1592 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0a,0x0e,0x0f,0x03,0x01,0x02,0x20,0x02,0x01 }, 15, AV_CODEC_ID_HQX },
1593 { { 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 */
1594 { { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0xff,0x4b,0x46,0x41,0x41,0x00,0x0d,0x4d,0x4f }, 14, AV_CODEC_ID_RAWVIDEO }, /* Legacy ?? Uncompressed Picture */
1595 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
1596 };
1597
1598 /* EC ULs for intra-only formats */
1599 static const MXFCodecUL mxf_intra_only_essence_container_uls[] = {
1600 { { 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 */
1601 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
1602 };
1603
1604 /* intra-only PictureEssenceCoding ULs, where no corresponding EC UL exists */
1605 static const MXFCodecUL mxf_intra_only_picture_essence_coding_uls[] = {
1606 { { 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 */
1607 { { 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 */
1608 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
1609 };
1610
1611 /* actual coded width for AVC-Intra to allow selecting correct SPS/PPS */
1612 static const MXFCodecUL mxf_intra_only_picture_coded_width[] = {
1613 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x01 }, 16, 1440 },
1614 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x02 }, 16, 1440 },
1615 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x03 }, 16, 1440 },
1616 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x04 }, 16, 1440 },
1617 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, 0 },
1618 };
1619
1620 static const MXFCodecUL mxf_sound_essence_container_uls[] = {
1621 // sound essence container uls
1622 { { 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 */
1623 { { 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 */
1624 { { 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 */
1625 { { 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 */
1626 { { 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) */
1627 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
1628 };
1629
1630 static const MXFCodecUL mxf_data_essence_container_uls[] = {
1631 { { 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 },
1632 { { 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 },
1633 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x13,0x01,0x01 }, 16, AV_CODEC_ID_TTML },
1634 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
1635 };
1636
1637 typedef struct MXFChannelOrderingUL {
1638 UID uid;
1639 uint64_t layout_mask;
1640 enum AVAudioServiceType service_type;
1641 } MXFChannelOrderingUL;
1642
1643 static const MXFChannelOrderingUL mxf_channel_ordering[] = {
1644 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left
1645 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x02,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right
1646 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x03,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center
1647 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x04,0x00,0x00,0x00,0x00 }, AV_CH_LOW_FREQUENCY, AV_AUDIO_SERVICE_TYPE_MAIN }, // Low Frequency Effects
1648 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x05,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Surround
1649 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x06,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Surround
1650 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x07,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Side Surround
1651 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x08,0x00,0x00,0x00,0x00 }, AV_CH_SIDE_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Side Surround
1652 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x09,0x00,0x00,0x00,0x00 }, AV_CH_BACK_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Rear Surround
1653 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0a,0x00,0x00,0x00,0x00 }, AV_CH_BACK_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Rear Surround
1654 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0b,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_LEFT_OF_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Center
1655 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0c,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_RIGHT_OF_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Center
1656 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0d,0x00,0x00,0x00,0x00 }, AV_CH_BACK_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Surround
1657 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0e,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, // Hearing impaired audio channel
1658 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x0f,0x00,0x00,0x00,0x00 }, AV_CH_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED }, // Visually impaired narrative audio channel
1659 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x20,0x03,0x00,0x00,0x00 }, AV_CH_STEREO_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Total
1660 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x20,0x04,0x00,0x00,0x00 }, AV_CH_STEREO_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Total
1661 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x01,0x00,0x00 }, AV_CH_TOP_FRONT_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Height
1662 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x02,0x00,0x00 }, AV_CH_TOP_FRONT_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Height
1663 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x03,0x00,0x00 }, AV_CH_TOP_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Height
1664 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x04,0x00,0x00 }, AV_CH_TOP_SIDE_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Surround Height
1665 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x05,0x00,0x00 }, AV_CH_TOP_SIDE_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Surround Height
1666 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x06,0x00,0x00 }, AV_CH_TOP_SIDE_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Side Surround Height
1667 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x07,0x00,0x00 }, AV_CH_TOP_SIDE_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Side Surround Height
1668 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x08,0x00,0x00 }, AV_CH_TOP_BACK_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Rear Surround Height
1669 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x09,0x00,0x00 }, AV_CH_TOP_BACK_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Rear Surround Height
1670 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0a,0x00,0x00 }, AV_CH_TOP_SIDE_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Top Surround
1671 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0b,0x00,0x00 }, AV_CH_TOP_SIDE_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Top Surround
1672 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0c,0x00,0x00 }, AV_CH_TOP_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Top Surround
1673 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0d,0x00,0x00 }, AV_CH_LOW_FREQUENCY, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Front Subwoofer
1674 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0e,0x00,0x00 }, AV_CH_LOW_FREQUENCY_2, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Front Subwoofer
1675 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x0f,0x00,0x00 }, AV_CH_TOP_BACK_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Rear Height
1676 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x10,0x00,0x00 }, AV_CH_BACK_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Rear
1677 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x11,0x00,0x00 }, AV_CH_BOTTOM_FRONT_LEFT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Left Below
1678 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x12,0x00,0x00 }, AV_CH_BOTTOM_FRONT_RIGHT, AV_AUDIO_SERVICE_TYPE_MAIN }, // Right Below
1679 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x03,0x02,0x01,0x30,0x01,0x13,0x00,0x00 }, AV_CH_BOTTOM_FRONT_CENTER, AV_AUDIO_SERVICE_TYPE_MAIN }, // Center Below
1680 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_AUDIO_SERVICE_TYPE_NB },
1681 };
1682
1683 207 static MXFWrappingScheme mxf_get_wrapping_kind(UID *essence_container_ul)
1684 {
1685 int val;
1686 const MXFCodecUL *codec_ul;
1687
1688 207 codec_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
1689
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 135 times.
207 if (!codec_ul->uid[0])
1690 72 codec_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
1691
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 202 times.
207 if (!codec_ul->uid[0])
1692 5 codec_ul = mxf_get_codec_ul(mxf_data_essence_container_uls, essence_container_ul);
1693
3/4
✓ Branch 0 taken 203 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 203 times.
207 if (!codec_ul->uid[0] || !codec_ul->wrapping_indicator_pos)
1694 4 return UnknownWrapped;
1695
1696 203 val = (*essence_container_ul)[codec_ul->wrapping_indicator_pos];
1697
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
✓ Branch 2 taken 82 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 52 times.
203 switch (codec_ul->wrapping_indicator_type) {
1698 case RawVWrap:
1699 val = val % 4;
1700 break;
1701 67 case RawAWrap:
1702
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 67 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
67 if (val == 0x03 || val == 0x04)
1703 67 val -= 0x02;
1704 67 break;
1705 82 case D10D11Wrap:
1706
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82 times.
82 if (val == 0x02)
1707 val = 0x01;
1708 82 break;
1709 2 case J2KWrap:
1710
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (val != 0x02)
1711 2 val = 0x01;
1712 2 break;
1713 }
1714
2/2
✓ Branch 0 taken 202 times.
✓ Branch 1 taken 1 times.
203 if (val == 0x01)
1715 202 return FrameWrapped;
1716
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (val == 0x02)
1717 return ClipWrapped;
1718 1 return UnknownWrapped;
1719 }
1720
1721 106 static int mxf_get_sorted_table_segments(MXFContext *mxf, int *nb_sorted_segments, MXFIndexTableSegment ***sorted_segments)
1722 {
1723 106 int i, j, nb_segments = 0;
1724 MXFIndexTableSegment **unsorted_segments;
1725 106 int last_body_sid = -1, last_index_sid = -1, last_index_start = -1;
1726
1727 /* count number of segments, allocate arrays and copy unsorted segments */
1728
2/2
✓ Branch 0 taken 2910 times.
✓ Branch 1 taken 106 times.
3016 for (i = 0; i < mxf->metadata_sets_count; i++)
1729
2/2
✓ Branch 0 taken 110 times.
✓ Branch 1 taken 2800 times.
2910 if (mxf->metadata_sets[i]->type == IndexTableSegment)
1730 110 nb_segments++;
1731
1732
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 106 times.
106 if (!nb_segments)
1733 return AVERROR_INVALIDDATA;
1734
1735
1/2
✓ Branch 1 taken 106 times.
✗ Branch 2 not taken.
106 if (!(unsorted_segments = av_calloc(nb_segments, sizeof(*unsorted_segments))) ||
1736
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 106 times.
106 !(*sorted_segments = av_calloc(nb_segments, sizeof(**sorted_segments)))) {
1737 av_freep(sorted_segments);
1738 av_free(unsorted_segments);
1739 return AVERROR(ENOMEM);
1740 }
1741
1742
2/2
✓ Branch 0 taken 2910 times.
✓ Branch 1 taken 106 times.
3016 for (i = nb_segments = 0; i < mxf->metadata_sets_count; i++) {
1743
2/2
✓ Branch 0 taken 110 times.
✓ Branch 1 taken 2800 times.
2910 if (mxf->metadata_sets[i]->type == IndexTableSegment) {
1744 110 MXFIndexTableSegment *s = (MXFIndexTableSegment*)mxf->metadata_sets[i];
1745
3/4
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 53 times.
✗ Branch 3 not taken.
110 if (s->edit_unit_byte_count || s->nb_index_entries)
1746 110 unsorted_segments[nb_segments++] = s;
1747 else
1748 av_log(mxf->fc, AV_LOG_WARNING, "IndexSID %i segment at %"PRId64" missing EditUnitByteCount and IndexEntryArray\n",
1749 s->index_sid, s->index_start_position);
1750 }
1751 }
1752
1753
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 106 times.
106 if (!nb_segments) {
1754 av_freep(sorted_segments);
1755 av_free(unsorted_segments);
1756 return AVERROR_INVALIDDATA;
1757 }
1758
1759 106 *nb_sorted_segments = 0;
1760
1761 /* sort segments by {BodySID, IndexSID, IndexStartPosition}, remove duplicates while we're at it */
1762
2/2
✓ Branch 0 taken 110 times.
✓ Branch 1 taken 103 times.
213 for (i = 0; i < nb_segments; i++) {
1763 110 int best = -1, best_body_sid = -1, best_index_sid = -1, best_index_start = -1;
1764 110 uint64_t best_index_duration = 0;
1765
1766
2/2
✓ Branch 0 taken 118 times.
✓ Branch 1 taken 110 times.
228 for (j = 0; j < nb_segments; j++) {
1767 118 MXFIndexTableSegment *s = unsorted_segments[j];
1768
1769 /* Require larger BosySID, IndexSID or IndexStartPosition then the previous entry. This removes duplicates.
1770 * We want the smallest values for the keys than what we currently have, unless this is the first such entry this time around.
1771 * If we come across an entry with the same IndexStartPosition but larger IndexDuration, then we'll prefer it over the one we currently have.
1772 */
1773
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 110 times.
118 if ((i == 0 ||
1774
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 s->body_sid > last_body_sid ||
1775
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 ||
1776
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 107 times.
118 s->body_sid == last_body_sid && s->index_sid == last_index_sid && s->index_start_position > last_index_start) &&
1777 4 (best == -1 ||
1778
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 s->body_sid < best_body_sid ||
1779
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 ||
1780
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 ||
1781
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)) {
1782 107 best = j;
1783 107 best_body_sid = s->body_sid;
1784 107 best_index_sid = s->index_sid;
1785 107 best_index_start = s->index_start_position;
1786 107 best_index_duration = s->index_duration;
1787 }
1788 }
1789
1790 /* no suitable entry found -> we're done */
1791
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 107 times.
110 if (best == -1)
1792 3 break;
1793
1794 107 (*sorted_segments)[(*nb_sorted_segments)++] = unsorted_segments[best];
1795 107 last_body_sid = best_body_sid;
1796 107 last_index_sid = best_index_sid;
1797 107 last_index_start = best_index_start;
1798 }
1799
1800 106 av_free(unsorted_segments);
1801
1802 106 return 0;
1803 }
1804
1805 /**
1806 * Computes the absolute file offset of the given essence container offset
1807 */
1808 5921 static int mxf_absolute_bodysid_offset(MXFContext *mxf, int body_sid, int64_t offset, int64_t *offset_out, MXFPartition **partition_out)
1809 {
1810 5921 MXFPartition *last_p = NULL;
1811 int a, b, m, m0;
1812
1813
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5921 times.
5921 if (offset < 0)
1814 return AVERROR(EINVAL);
1815
1816 5921 a = -1;
1817 5921 b = mxf->partitions_count;
1818
1819
2/2
✓ Branch 0 taken 11757 times.
✓ Branch 1 taken 5921 times.
17678 while (b - a > 1) {
1820 11757 m0 = m = (a + b) >> 1;
1821
1822
4/4
✓ Branch 0 taken 11785 times.
✓ Branch 1 taken 5836 times.
✓ Branch 2 taken 5864 times.
✓ Branch 3 taken 5921 times.
17621 while (m < b && mxf->partitions[m].body_sid != body_sid)
1823 5864 m++;
1824
1825
3/4
✓ Branch 0 taken 5921 times.
✓ Branch 1 taken 5836 times.
✓ Branch 2 taken 5921 times.
✗ Branch 3 not taken.
11757 if (m < b && mxf->partitions[m].body_offset <= offset)
1826 5921 a = m;
1827 else
1828 5836 b = m0;
1829 }
1830
1831
1/2
✓ Branch 0 taken 5921 times.
✗ Branch 1 not taken.
5921 if (a >= 0)
1832 5921 last_p = &mxf->partitions[a];
1833
1834
5/6
✓ Branch 0 taken 5921 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5836 times.
✓ Branch 3 taken 85 times.
✓ Branch 4 taken 5835 times.
✓ Branch 5 taken 1 times.
5921 if (last_p && (!last_p->essence_length || last_p->essence_length > (offset - last_p->body_offset))) {
1835 5920 *offset_out = last_p->essence_offset + (offset - last_p->body_offset);
1836
2/2
✓ Branch 0 taken 207 times.
✓ Branch 1 taken 5713 times.
5920 if (partition_out)
1837 207 *partition_out = last_p;
1838 5920 return 0;
1839 }
1840
1841 1 av_log(mxf->fc, AV_LOG_ERROR,
1842 "failed to find absolute offset of %"PRIX64" in BodySID %i - partial file?\n",
1843 offset, body_sid);
1844
1845 1 return AVERROR_INVALIDDATA;
1846 }
1847
1848 /**
1849 * Returns the end position of the essence container with given BodySID, or zero if unknown
1850 */
1851 325 static int64_t mxf_essence_container_end(MXFContext *mxf, int body_sid)
1852 {
1853
1/2
✓ Branch 0 taken 656 times.
✗ Branch 1 not taken.
656 for (int x = mxf->partitions_count - 1; x >= 0; x--) {
1854 656 MXFPartition *p = &mxf->partitions[x];
1855
1856
2/2
✓ Branch 0 taken 331 times.
✓ Branch 1 taken 325 times.
656 if (p->body_sid != body_sid)
1857 331 continue;
1858
1859
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 if (!p->essence_length)
1860 return 0;
1861
1862 325 return p->essence_offset + p->essence_length;
1863 }
1864
1865 return 0;
1866 }
1867
1868 /* EditUnit -> absolute offset */
1869 6245 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)
1870 {
1871 int i;
1872 6245 int64_t offset_temp = 0;
1873
1874 6245 edit_unit = av_rescale_q(edit_unit, index_table->segments[0]->index_edit_rate, edit_rate);
1875
1876
2/2
✓ Branch 0 taken 6245 times.
✓ Branch 1 taken 324 times.
6569 for (i = 0; i < index_table->nb_segments; i++) {
1877 6245 MXFIndexTableSegment *s = index_table->segments[i];
1878
1879 6245 edit_unit = FFMAX(edit_unit, s->index_start_position); /* clamp if trying to seek before start */
1880
1881
2/2
✓ Branch 0 taken 5921 times.
✓ Branch 1 taken 324 times.
6245 if (edit_unit < s->index_start_position + s->index_duration) {
1882 5921