mxfinfo 0.0.3.6 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +3 -0
- data/Gemfile +0 -6
- data/LICENSE +3 -2
- data/README.md +3 -3
- data/Rakefile +3 -5
- data/ext/mxfinfo/avid_mxf_info.c +1507 -0
- data/ext/mxfinfo/avid_mxf_info.h +194 -0
- data/ext/mxfinfo/extconf.rb +12 -0
- data/ext/mxfinfo/mxfinfo.c +313 -0
- data/lib/mxfinfo/version.rb +2 -2
- data/lib/mxfinfo.rb +24 -117
- data/mxfinfo.gemspec +13 -10
- data/spec/info_object_spec.rb +42 -0
- data/spec/mxfinfo_spec.rb +20 -70
- data/spec/spec_helper.rb +0 -18
- metadata +49 -48
- data/lib/mxfinfo/attr_readers.rb +0 -61
- data/lib/mxfinfo/string.rb +0 -25
- data/spec/alert_error_spec.rb +0 -10
- data/spec/fixtures/ALERT01.ERROR.info +0 -8
- data/spec/fixtures/IMG_0395.MOV.A14DC7130D.mxf.info +0 -44
- data/spec/fixtures/center_smooth.info +0 -29
- data/spec/fixtures/color_correction.info +0 -29
- data/spec/fixtures/crystal.info +0 -29
- data/spec/fixtures/flip-flop.info +0 -29
- data/spec/fixtures/fluidblur.info +0 -29
- data/spec/fixtures/left_box.info +0 -29
- data/spec/fixtures/luma_key.info +0 -29
- data/spec/fixtures/mosaic_effect.info +0 -29
- data/spec/fixtures/stabilize.info +0 -29
- data/spec/fixtures/timecode_burn-in.info +0 -29
- data/spec/img_0395.mov.a14dc7130d_spec.rb +0 -116
- data/spec/render_files_spec.rb +0 -25
@@ -0,0 +1,1507 @@
|
|
1
|
+
/*
|
2
|
+
* Parse metadata from an Avid MXF file
|
3
|
+
*
|
4
|
+
* Copyright (C) 2008, British Broadcasting Corporation
|
5
|
+
* All Rights Reserved.
|
6
|
+
*
|
7
|
+
* Author: Philip de Nier
|
8
|
+
*
|
9
|
+
* Redistribution and use in source and binary forms, with or without
|
10
|
+
* modification, are permitted provided that the following conditions are met:
|
11
|
+
*
|
12
|
+
* * Redistributions of source code must retain the above copyright notice,
|
13
|
+
* this list of conditions and the following disclaimer.
|
14
|
+
* * Redistributions in binary form must reproduce the above copyright
|
15
|
+
* notice, this list of conditions and the following disclaimer in the
|
16
|
+
* documentation and/or other materials provided with the distribution.
|
17
|
+
* * Neither the name of the British Broadcasting Corporation nor the names
|
18
|
+
* of its contributors may be used to endorse or promote products derived
|
19
|
+
* from this software without specific prior written permission.
|
20
|
+
*
|
21
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
22
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
23
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
24
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
25
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
26
|
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
27
|
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
28
|
+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
29
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
30
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
31
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
32
|
+
*/
|
33
|
+
|
34
|
+
#ifdef HAVE_CONFIG_H
|
35
|
+
#include "config.h"
|
36
|
+
#endif
|
37
|
+
|
38
|
+
#include <stdio.h>
|
39
|
+
#include <stdlib.h>
|
40
|
+
#include <string.h>
|
41
|
+
#include <assert.h>
|
42
|
+
|
43
|
+
#include <mxf/mxf.h>
|
44
|
+
#include <mxf/mxf_avid.h>
|
45
|
+
#include <mxf/mxf_uu_metadata.h>
|
46
|
+
#include <mxf/mxf_macros.h>
|
47
|
+
|
48
|
+
#include "avid_mxf_info.h"
|
49
|
+
|
50
|
+
|
51
|
+
#define DEBUG_PRINT_ERROR(cmd) \
|
52
|
+
if (printDebugError) \
|
53
|
+
{ \
|
54
|
+
; \
|
55
|
+
}
|
56
|
+
|
57
|
+
#define CHECK(cmd, ecode) \
|
58
|
+
if (!(cmd)) \
|
59
|
+
{ \
|
60
|
+
DEBUG_PRINT_ERROR(cmd); \
|
61
|
+
errorCode = ecode; \
|
62
|
+
goto fail; \
|
63
|
+
}
|
64
|
+
|
65
|
+
#define DCHECK(cmd) \
|
66
|
+
if (!(cmd)) \
|
67
|
+
{ \
|
68
|
+
DEBUG_PRINT_ERROR(cmd); \
|
69
|
+
errorCode = -1; \
|
70
|
+
goto fail; \
|
71
|
+
}
|
72
|
+
|
73
|
+
#define FCHECK(cmd) \
|
74
|
+
if (!(cmd)) \
|
75
|
+
{ \
|
76
|
+
DEBUG_PRINT_ERROR(cmd); \
|
77
|
+
goto fail; \
|
78
|
+
}
|
79
|
+
|
80
|
+
|
81
|
+
typedef struct
|
82
|
+
{
|
83
|
+
uint32_t first;
|
84
|
+
uint32_t last;
|
85
|
+
} TrackNumberRange;
|
86
|
+
|
87
|
+
|
88
|
+
/* keep this in sync with AvidEssenceType in the header file */
|
89
|
+
static const char* ESSENCE_TYPE_STRINGS[] =
|
90
|
+
{
|
91
|
+
"not recognized",
|
92
|
+
"MPEG 30",
|
93
|
+
"MPEG 40",
|
94
|
+
"MPEG 50",
|
95
|
+
"DV 25 411",
|
96
|
+
"DV 25 420",
|
97
|
+
"DV 50",
|
98
|
+
"DV 100",
|
99
|
+
"20:1",
|
100
|
+
"2:1s",
|
101
|
+
"4:1s",
|
102
|
+
"15:1s",
|
103
|
+
"10:1",
|
104
|
+
"10:1m",
|
105
|
+
"4:1m",
|
106
|
+
"3:1",
|
107
|
+
"2:1",
|
108
|
+
"1:1",
|
109
|
+
"1:1 10b",
|
110
|
+
"35:1p",
|
111
|
+
"28:1p",
|
112
|
+
"14:1p",
|
113
|
+
"3:1p",
|
114
|
+
"2:1p",
|
115
|
+
"3:1m",
|
116
|
+
"8:1m",
|
117
|
+
"DNxHD 1235",
|
118
|
+
"DNxHD 1237",
|
119
|
+
"DNxHD 1238",
|
120
|
+
"DNxHD 1241",
|
121
|
+
"DNxHD 1242",
|
122
|
+
"DNxHD 1243",
|
123
|
+
"DNxHD 1250",
|
124
|
+
"DNxHD 1251",
|
125
|
+
"DNxHD 1252",
|
126
|
+
"DNxHD 1253",
|
127
|
+
"MPEG-4",
|
128
|
+
"XDCAM HD",
|
129
|
+
"AVC-Intra 100",
|
130
|
+
"AVC-Intra 50",
|
131
|
+
"PCM"
|
132
|
+
};
|
133
|
+
|
134
|
+
|
135
|
+
typedef struct
|
136
|
+
{
|
137
|
+
AvidEssenceType essenceType;
|
138
|
+
mxfRational editRate;
|
139
|
+
const char *name;
|
140
|
+
} DNxHDTypeString;
|
141
|
+
|
142
|
+
static const DNxHDTypeString DNXHD_TYPE_STRINGS[] =
|
143
|
+
{
|
144
|
+
/* 23.976 fps */
|
145
|
+
{DNXHD_1235_ESSENCE_TYPE, {24000, 1001}, "DNxHD 175x (1235)"},
|
146
|
+
{DNXHD_1237_ESSENCE_TYPE, {24000, 1001}, "DNxHD 115 (1237)"},
|
147
|
+
{DNXHD_1238_ESSENCE_TYPE, {24000, 1001}, "DNxHD 175 (1238)"},
|
148
|
+
{DNXHD_1250_ESSENCE_TYPE, {24000, 1001}, "DNxHD 90x (1250)"},
|
149
|
+
{DNXHD_1251_ESSENCE_TYPE, {24000, 1001}, "DNxHD 90 (1251)"},
|
150
|
+
{DNXHD_1252_ESSENCE_TYPE, {24000, 1001}, "DNxHD 60 (1252)"},
|
151
|
+
{DNXHD_1253_ESSENCE_TYPE, {24000, 1001}, "DNxHD 36 (1253)"},
|
152
|
+
|
153
|
+
/* 24 fps */
|
154
|
+
{DNXHD_1235_ESSENCE_TYPE, {24, 1}, "DNxHD 175x (1235)"},
|
155
|
+
{DNXHD_1237_ESSENCE_TYPE, {24, 1}, "DNxHD 115 (1237)"},
|
156
|
+
{DNXHD_1238_ESSENCE_TYPE, {24, 1}, "DNxHD 175 (1238)"},
|
157
|
+
{DNXHD_1253_ESSENCE_TYPE, {24, 1}, "DNxHD 36 (1253)"},
|
158
|
+
|
159
|
+
/* 25 fps */
|
160
|
+
{DNXHD_1235_ESSENCE_TYPE, {25, 1}, "DNxHD 185x (1235)"},
|
161
|
+
{DNXHD_1237_ESSENCE_TYPE, {25, 1}, "DNxHD 120 (1237)"},
|
162
|
+
{DNXHD_1238_ESSENCE_TYPE, {25, 1}, "DNxHD 185 (1238)"},
|
163
|
+
{DNXHD_1241_ESSENCE_TYPE, {25, 1}, "DNxHD 185x (1241)"},
|
164
|
+
{DNXHD_1242_ESSENCE_TYPE, {25, 1}, "DNxHD 120 (1242)"},
|
165
|
+
{DNXHD_1243_ESSENCE_TYPE, {25, 1}, "DNxHD 185 (1243)"},
|
166
|
+
{DNXHD_1250_ESSENCE_TYPE, {25, 1}, "DNxHD 90x (1250)"},
|
167
|
+
{DNXHD_1251_ESSENCE_TYPE, {25, 1}, "DNxHD 90 (1251)"},
|
168
|
+
{DNXHD_1252_ESSENCE_TYPE, {25, 1}, "DNxHD 60 (1252)"},
|
169
|
+
{DNXHD_1253_ESSENCE_TYPE, {25, 1}, "DNxHD 36 (1253)"},
|
170
|
+
|
171
|
+
/* 29.97 fps */
|
172
|
+
{DNXHD_1235_ESSENCE_TYPE, {30000, 1001}, "DNxHD 220x (1235)"},
|
173
|
+
{DNXHD_1237_ESSENCE_TYPE, {30000, 1001}, "DNxHD 145 (1237)"},
|
174
|
+
{DNXHD_1238_ESSENCE_TYPE, {30000, 1001}, "DNxHD 220 (1238)"},
|
175
|
+
{DNXHD_1241_ESSENCE_TYPE, {30000, 1001}, "DNxHD 220x (1241)"},
|
176
|
+
{DNXHD_1242_ESSENCE_TYPE, {30000, 1001}, "DNxHD 145 (1242)"},
|
177
|
+
{DNXHD_1243_ESSENCE_TYPE, {30000, 1001}, "DNxHD 220 (1243)"},
|
178
|
+
{DNXHD_1250_ESSENCE_TYPE, {30000, 1001}, "DNxHD 110x (1250)"},
|
179
|
+
{DNXHD_1251_ESSENCE_TYPE, {30000, 1001}, "DNxHD 110 (1251)"},
|
180
|
+
{DNXHD_1252_ESSENCE_TYPE, {30000, 1001}, "DNxHD 75 (1252)"},
|
181
|
+
{DNXHD_1253_ESSENCE_TYPE, {30000, 1001}, "DNxHD 45 (1253)"},
|
182
|
+
|
183
|
+
/* 50 fps */
|
184
|
+
{DNXHD_1250_ESSENCE_TYPE, {50, 1}, "DNxHD 175x (1250)"},
|
185
|
+
{DNXHD_1251_ESSENCE_TYPE, {50, 1}, "DNxHD 175 (1251)"},
|
186
|
+
{DNXHD_1252_ESSENCE_TYPE, {50, 1}, "DNxHD 115 (1252)"},
|
187
|
+
|
188
|
+
/* 59.94 fps */
|
189
|
+
{DNXHD_1250_ESSENCE_TYPE, {60000, 1001}, "DNxHD 220x (1250)"},
|
190
|
+
{DNXHD_1251_ESSENCE_TYPE, {60000, 1001}, "DNxHD 220 (1251)"},
|
191
|
+
{DNXHD_1252_ESSENCE_TYPE, {60000, 1001}, "DNxHD 145 (1252)"},
|
192
|
+
};
|
193
|
+
|
194
|
+
|
195
|
+
typedef struct
|
196
|
+
{
|
197
|
+
AvidEssenceType essenceType;
|
198
|
+
int checkPictureCodingLabel;
|
199
|
+
const mxfUL *essenceContainerLabel;
|
200
|
+
const mxfUL *pictureCodingLabel;
|
201
|
+
int32_t avidResolutionID;
|
202
|
+
} EssenceTypeMap;
|
203
|
+
|
204
|
+
static const EssenceTypeMap ESSENCE_TYPE_MAP[] =
|
205
|
+
{
|
206
|
+
{MPEG_30_ESSENCE_TYPE, 0, &MXF_EC_L(D10_30_625_50_picture_only), &MXF_CMDEF_L(D10_30_625_50), 0},
|
207
|
+
{MPEG_30_ESSENCE_TYPE, 0, &MXF_EC_L(D10_30_525_60_picture_only), &MXF_CMDEF_L(D10_30_525_60), 0},
|
208
|
+
{MPEG_40_ESSENCE_TYPE, 0, &MXF_EC_L(D10_40_625_50_picture_only), &MXF_CMDEF_L(D10_40_625_50), 0},
|
209
|
+
{MPEG_40_ESSENCE_TYPE, 0, &MXF_EC_L(D10_40_525_60_picture_only), &MXF_CMDEF_L(D10_40_525_60), 0},
|
210
|
+
{MPEG_50_ESSENCE_TYPE, 0, &MXF_EC_L(D10_50_625_50_picture_only), &MXF_CMDEF_L(D10_50_625_50), 0},
|
211
|
+
{MPEG_50_ESSENCE_TYPE, 0, &MXF_EC_L(D10_50_525_60_picture_only), &MXF_CMDEF_L(D10_50_525_60), 0},
|
212
|
+
|
213
|
+
{DV_25_411_ESSENCE_TYPE, 0, &MXF_EC_L(IECDV_25_525_60_ClipWrapped), &MXF_CMDEF_L(IECDV_25_525_60), 0},
|
214
|
+
{DV_25_420_ESSENCE_TYPE, 0, &MXF_EC_L(IECDV_25_625_50_ClipWrapped), &MXF_CMDEF_L(IECDV_25_625_50), 0},
|
215
|
+
{DV_25_411_ESSENCE_TYPE, 0, &MXF_EC_L(DVBased_25_525_60_ClipWrapped), &MXF_CMDEF_L(DVBased_25_525_60), 0},
|
216
|
+
{DV_25_411_ESSENCE_TYPE, 0, &MXF_EC_L(DVBased_25_625_50_ClipWrapped), &MXF_CMDEF_L(DVBased_25_625_50), 0},
|
217
|
+
{DV_50_ESSENCE_TYPE, 0, &MXF_EC_L(DVBased_50_525_60_ClipWrapped), &MXF_CMDEF_L(DVBased_50_525_60), 0},
|
218
|
+
{DV_50_ESSENCE_TYPE, 0, &MXF_EC_L(DVBased_50_625_50_ClipWrapped), &MXF_CMDEF_L(DVBased_50_625_50), 0},
|
219
|
+
{DV_100_ESSENCE_TYPE, 0, &MXF_EC_L(DVBased_100_720_50_P_ClipWrapped), &MXF_CMDEF_L(DVBased_100_720_50_P), 0},
|
220
|
+
{DV_100_ESSENCE_TYPE, 0, &MXF_EC_L(DVBased_100_720_60_P_ClipWrapped), &MXF_CMDEF_L(DVBased_100_720_60_P), 0},
|
221
|
+
{DV_100_ESSENCE_TYPE, 0, &MXF_EC_L(DVBased_100_1080_50_I_ClipWrapped), &MXF_CMDEF_L(DVBased_100_1080_50_I), 0},
|
222
|
+
{DV_100_ESSENCE_TYPE, 0, &MXF_EC_L(DVBased_100_1080_60_I_ClipWrapped), &MXF_CMDEF_L(DVBased_100_1080_60_I), 0},
|
223
|
+
|
224
|
+
{MJPEG_10_1_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG101_PAL), 0x4b},
|
225
|
+
{MJPEG_10_1_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG101_NTSC), 0x4b},
|
226
|
+
{MJPEG_2_1_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG21_PAL), 0x4c},
|
227
|
+
{MJPEG_2_1_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG21_NTSC), 0x4c},
|
228
|
+
{MJPEG_3_1_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG31_PAL), 0x4d},
|
229
|
+
{MJPEG_3_1_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG31_NTSC), 0x4d},
|
230
|
+
{MJPEG_15_1_S_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG151s_PAL), 0x4e},
|
231
|
+
{MJPEG_15_1_S_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG151s_NTSC), 0x4e},
|
232
|
+
{MJPEG_4_1_S_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG41s_PAL), 0x4f},
|
233
|
+
{MJPEG_4_1_S_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG41s_NTSC), 0x4f},
|
234
|
+
{MJPEG_2_1_S_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG21s_PAL), 0x50},
|
235
|
+
{MJPEG_2_1_S_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG21s_NTSC), 0x50},
|
236
|
+
{MJPEG_20_1_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG201_PAL), 0x52},
|
237
|
+
{MJPEG_20_1_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG201_NTSC), 0x52},
|
238
|
+
{MJPEG_3_1_P_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG31p_PAL), 0x61},
|
239
|
+
{MJPEG_3_1_P_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG31p_NTSC), 0x61},
|
240
|
+
{MJPEG_2_1_P_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG21p_PAL), 0x62},
|
241
|
+
{MJPEG_2_1_P_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG21p_NTSC), 0x62},
|
242
|
+
{MJPEG_35_1_P_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG351p_PAL), 0x66},
|
243
|
+
{MJPEG_35_1_P_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG351p_NTSC), 0x66},
|
244
|
+
{MJPEG_14_1_P_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG141p_PAL), 0x67},
|
245
|
+
{MJPEG_14_1_P_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG141p_NTSC), 0x67},
|
246
|
+
{MJPEG_28_1_P_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG281p_PAL), 0x68},
|
247
|
+
{MJPEG_28_1_P_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG281p_NTSC), 0x68},
|
248
|
+
{MJPEG_10_1_M_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG101m_PAL), 0x6e},
|
249
|
+
{MJPEG_10_1_M_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG101m_NTSC), 0x6e},
|
250
|
+
{MJPEG_4_1_M_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), 0, 0x6f},
|
251
|
+
{MJPEG_8_1_M_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG81m_PAL), 0x70},
|
252
|
+
{MJPEG_8_1_M_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG81m_NTSC), 0x70},
|
253
|
+
{MJPEG_3_1_M_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG31m_PAL), 0x71},
|
254
|
+
{MJPEG_3_1_M_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMJPEGClipWrapped), &MXF_CMDEF_L(AvidMJPEG31m_NTSC), 0x71},
|
255
|
+
|
256
|
+
{UNC_1_1_ESSENCE_TYPE, 0, &MXF_EC_L(SD_Unc_625_50i_422_135_ClipWrapped), 0, 0xaa},
|
257
|
+
{UNC_1_1_ESSENCE_TYPE, 0, &MXF_EC_L(SD_Unc_525_5994i_422_135_ClipWrapped), 0, 0xaa},
|
258
|
+
{UNC_1_1_ESSENCE_TYPE, 0, &MXF_EC_L(HD_Unc_1080_50i_422_ClipWrapped), 0, 0},
|
259
|
+
{UNC_1_1_ESSENCE_TYPE, 0, &MXF_EC_L(HD_Unc_1080_5994i_422_ClipWrapped), 0, 0},
|
260
|
+
{UNC_1_1_ESSENCE_TYPE, 0, &MXF_EC_L(HD_Unc_720_50p_422_ClipWrapped), 0, 0},
|
261
|
+
{UNC_1_1_ESSENCE_TYPE, 0, &MXF_EC_L(HD_Unc_720_5994p_422_ClipWrapped), 0, 0},
|
262
|
+
/* Avid Media Composer 5.03 wrongly used this label for 720_50p */
|
263
|
+
{UNC_1_1_ESSENCE_TYPE, 0, &MXF_EC_L(HD_Unc_720_60p_422_ClipWrapped), 0, 0},
|
264
|
+
|
265
|
+
{UNC_1_1_10B_ESSENCE_TYPE, 0, &MXF_EC_L(AvidUnc10Bit625ClipWrapped), &MXF_CMDEF_L(AvidUncSD10Bit), 0x07e6},
|
266
|
+
{UNC_1_1_10B_ESSENCE_TYPE, 0, &MXF_EC_L(AvidUnc10Bit525ClipWrapped), &MXF_CMDEF_L(AvidUncSD10Bit), 0x07e5},
|
267
|
+
{UNC_1_1_10B_ESSENCE_TYPE, 0, &MXF_EC_L(AvidUnc10Bit1080iClipWrapped), &MXF_CMDEF_L(AvidUncHD10Bit), 0x07d0},
|
268
|
+
{UNC_1_1_10B_ESSENCE_TYPE, 0, &MXF_EC_L(AvidUnc10Bit720pClipWrapped), &MXF_CMDEF_L(AvidUncHD10Bit), 0x07d4},
|
269
|
+
|
270
|
+
{DNXHD_1235_ESSENCE_TYPE, 0, &MXF_EC_L(DNxHD1080p1235ClipWrapped), &MXF_CMDEF_L(VC3_1080P_1235), 1235},
|
271
|
+
{DNXHD_1237_ESSENCE_TYPE, 0, &MXF_EC_L(DNxHD1080p1237ClipWrapped), &MXF_CMDEF_L(VC3_1080P_1237), 1237},
|
272
|
+
{DNXHD_1238_ESSENCE_TYPE, 0, &MXF_EC_L(DNxHD1080p1238ClipWrapped), &MXF_CMDEF_L(VC3_1080P_1238), 1238},
|
273
|
+
{DNXHD_1241_ESSENCE_TYPE, 0, &MXF_EC_L(DNxHD1080i1241ClipWrapped), &MXF_CMDEF_L(VC3_1080I_1241), 1241},
|
274
|
+
{DNXHD_1242_ESSENCE_TYPE, 0, &MXF_EC_L(DNxHD1080i1242ClipWrapped), &MXF_CMDEF_L(VC3_1080I_1242), 1242},
|
275
|
+
{DNXHD_1243_ESSENCE_TYPE, 0, &MXF_EC_L(DNxHD1080i1243ClipWrapped), &MXF_CMDEF_L(VC3_1080I_1243), 1243},
|
276
|
+
{DNXHD_1250_ESSENCE_TYPE, 0, &MXF_EC_L(DNxHD720p1250ClipWrapped), &MXF_CMDEF_L(VC3_720P_1250), 1250},
|
277
|
+
{DNXHD_1251_ESSENCE_TYPE, 0, &MXF_EC_L(DNxHD720p1251ClipWrapped), &MXF_CMDEF_L(VC3_720P_1251), 1251},
|
278
|
+
{DNXHD_1252_ESSENCE_TYPE, 0, &MXF_EC_L(DNxHD720p1252ClipWrapped), &MXF_CMDEF_L(VC3_720P_1252), 1252},
|
279
|
+
{DNXHD_1253_ESSENCE_TYPE, 0, &MXF_EC_L(DNxHD1080p1253ClipWrapped), &MXF_CMDEF_L(VC3_1080P_1253), 1253},
|
280
|
+
|
281
|
+
{MPEG4_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMPEGClipWrapped), &MXF_CMDEF_L(MP4AdvancedRealTimeSimpleL4), 0},
|
282
|
+
|
283
|
+
{XDCAM_HD_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMPEGClipWrapped), &MXF_CMDEF_L(MPEG2_422P_HL_LONGGOP), 0},
|
284
|
+
{XDCAM_HD_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMPEGClipWrapped), &MXF_CMDEF_L(MPEG2_MP_HL_LONGGOP), 0},
|
285
|
+
{XDCAM_HD_ESSENCE_TYPE, 1, &MXF_EC_L(AvidMPEGClipWrapped), &MXF_CMDEF_L(MPEG2_MP_H14_LONGGOP), 0},
|
286
|
+
|
287
|
+
{AVCINTRA_100_ESSENCE_TYPE, 1, &MXF_EC_L(AVCIClipWrapped), &MXF_CMDEF_L(AVCI_100_1080_60_I), 0},
|
288
|
+
{AVCINTRA_100_ESSENCE_TYPE, 1, &MXF_EC_L(AVCIClipWrapped), &MXF_CMDEF_L(AVCI_100_1080_50_I), 0},
|
289
|
+
{AVCINTRA_100_ESSENCE_TYPE, 1, &MXF_EC_L(AVCIClipWrapped), &MXF_CMDEF_L(AVCI_100_1080_30_P), 0},
|
290
|
+
{AVCINTRA_100_ESSENCE_TYPE, 1, &MXF_EC_L(AVCIClipWrapped), &MXF_CMDEF_L(AVCI_100_1080_25_P), 0},
|
291
|
+
{AVCINTRA_100_ESSENCE_TYPE, 1, &MXF_EC_L(AVCIClipWrapped), &MXF_CMDEF_L(AVCI_100_720_60_P), 0},
|
292
|
+
{AVCINTRA_100_ESSENCE_TYPE, 1, &MXF_EC_L(AVCIClipWrapped), &MXF_CMDEF_L(AVCI_100_720_50_P), 0},
|
293
|
+
|
294
|
+
{AVCINTRA_50_ESSENCE_TYPE, 1, &MXF_EC_L(AVCIClipWrapped), &MXF_CMDEF_L(AVCI_50_1080_60_I), 0},
|
295
|
+
{AVCINTRA_50_ESSENCE_TYPE, 1, &MXF_EC_L(AVCIClipWrapped), &MXF_CMDEF_L(AVCI_50_1080_50_I), 0},
|
296
|
+
{AVCINTRA_50_ESSENCE_TYPE, 1, &MXF_EC_L(AVCIClipWrapped), &MXF_CMDEF_L(AVCI_50_1080_30_P), 0},
|
297
|
+
{AVCINTRA_50_ESSENCE_TYPE, 1, &MXF_EC_L(AVCIClipWrapped), &MXF_CMDEF_L(AVCI_50_1080_25_P), 0},
|
298
|
+
{AVCINTRA_50_ESSENCE_TYPE, 1, &MXF_EC_L(AVCIClipWrapped), &MXF_CMDEF_L(AVCI_50_720_60_P), 0},
|
299
|
+
{AVCINTRA_50_ESSENCE_TYPE, 1, &MXF_EC_L(AVCIClipWrapped), &MXF_CMDEF_L(AVCI_50_720_50_P), 0},
|
300
|
+
|
301
|
+
{PCM_ESSENCE_TYPE, 0, &MXF_EC_L(BWFClipWrapped), 0, 0},
|
302
|
+
{PCM_ESSENCE_TYPE, 0, &MXF_EC_L(AES3ClipWrapped), 0, 0},
|
303
|
+
};
|
304
|
+
|
305
|
+
|
306
|
+
static const char *FRAME_LAYOUT_STRINGS[] =
|
307
|
+
{
|
308
|
+
"unknown layout",
|
309
|
+
"full frame",
|
310
|
+
"separate fields",
|
311
|
+
"single field",
|
312
|
+
"mixed field",
|
313
|
+
"segmented frame",
|
314
|
+
};
|
315
|
+
|
316
|
+
|
317
|
+
|
318
|
+
static AvidEssenceType get_essence_type(mxfUL *essenceContainerLabel, mxfUL *pictureCodingLabel,
|
319
|
+
int32_t avidResolutionID)
|
320
|
+
{
|
321
|
+
/* Note: using mxf_equals_ul_mod_regver function below because some Avid labels (e.g. D10)
|
322
|
+
use a different registry version byte */
|
323
|
+
|
324
|
+
int match_ec, match_pc, match_resid;
|
325
|
+
int null_in_ec, null_in_pc;
|
326
|
+
int null_resid, null_ec, null_pc;
|
327
|
+
size_t i;
|
328
|
+
|
329
|
+
null_in_ec = mxf_equals_ul(essenceContainerLabel, &g_Null_UL);
|
330
|
+
null_in_pc = mxf_equals_ul(pictureCodingLabel, &g_Null_UL);
|
331
|
+
|
332
|
+
for (i = 0; i < ARRAY_SIZE(ESSENCE_TYPE_MAP); i++)
|
333
|
+
{
|
334
|
+
null_ec = null_in_ec || !ESSENCE_TYPE_MAP[i].essenceContainerLabel;
|
335
|
+
null_pc = null_in_pc || !ESSENCE_TYPE_MAP[i].pictureCodingLabel;
|
336
|
+
null_resid = avidResolutionID == 0 || ESSENCE_TYPE_MAP[i].avidResolutionID == 0;
|
337
|
+
|
338
|
+
match_ec = !null_ec &&
|
339
|
+
mxf_equals_ul_mod_regver(essenceContainerLabel, ESSENCE_TYPE_MAP[i].essenceContainerLabel);
|
340
|
+
match_pc = !null_pc &&
|
341
|
+
mxf_equals_ul_mod_regver(pictureCodingLabel, ESSENCE_TYPE_MAP[i].pictureCodingLabel);
|
342
|
+
match_resid = !null_resid &&
|
343
|
+
avidResolutionID == ESSENCE_TYPE_MAP[i].avidResolutionID;
|
344
|
+
|
345
|
+
if (match_ec &&
|
346
|
+
(!ESSENCE_TYPE_MAP[i].checkPictureCodingLabel || match_pc) &&
|
347
|
+
(null_resid || match_resid))
|
348
|
+
{
|
349
|
+
return ESSENCE_TYPE_MAP[i].essenceType;
|
350
|
+
}
|
351
|
+
else if (match_ec &&
|
352
|
+
ESSENCE_TYPE_MAP[i].checkPictureCodingLabel &&
|
353
|
+
!ESSENCE_TYPE_MAP[i].pictureCodingLabel &&
|
354
|
+
match_resid)
|
355
|
+
{
|
356
|
+
return ESSENCE_TYPE_MAP[i].essenceType;
|
357
|
+
}
|
358
|
+
else if (null_ec && match_pc && (null_resid || match_resid))
|
359
|
+
{
|
360
|
+
return ESSENCE_TYPE_MAP[i].essenceType;
|
361
|
+
}
|
362
|
+
}
|
363
|
+
|
364
|
+
return UNKNOWN_ESSENCE_TYPE;
|
365
|
+
}
|
366
|
+
|
367
|
+
static const char* get_dnxhd_type_string(AvidEssenceType essenceType, mxfRational editRate)
|
368
|
+
{
|
369
|
+
size_t i;
|
370
|
+
for (i = 0; i < ARRAY_SIZE(DNXHD_TYPE_STRINGS); i++) {
|
371
|
+
if (essenceType == DNXHD_TYPE_STRINGS[i].essenceType &&
|
372
|
+
memcmp(&editRate, &DNXHD_TYPE_STRINGS[i].editRate, sizeof(editRate)) == 0)
|
373
|
+
{
|
374
|
+
return DNXHD_TYPE_STRINGS[i].name;
|
375
|
+
}
|
376
|
+
}
|
377
|
+
|
378
|
+
return ESSENCE_TYPE_STRINGS[essenceType];
|
379
|
+
}
|
380
|
+
|
381
|
+
const char* get_essence_type_string(AvidEssenceType essenceType, mxfRational editRate)
|
382
|
+
{
|
383
|
+
assert(essenceType < ARRAY_SIZE(ESSENCE_TYPE_STRINGS));
|
384
|
+
assert(PCM_ESSENCE_TYPE + 1 == ARRAY_SIZE(ESSENCE_TYPE_STRINGS));
|
385
|
+
|
386
|
+
if (essenceType == DNXHD_1235_ESSENCE_TYPE ||
|
387
|
+
essenceType == DNXHD_1237_ESSENCE_TYPE ||
|
388
|
+
essenceType == DNXHD_1238_ESSENCE_TYPE ||
|
389
|
+
essenceType == DNXHD_1241_ESSENCE_TYPE ||
|
390
|
+
essenceType == DNXHD_1242_ESSENCE_TYPE ||
|
391
|
+
essenceType == DNXHD_1243_ESSENCE_TYPE ||
|
392
|
+
essenceType == DNXHD_1250_ESSENCE_TYPE ||
|
393
|
+
essenceType == DNXHD_1251_ESSENCE_TYPE ||
|
394
|
+
essenceType == DNXHD_1252_ESSENCE_TYPE ||
|
395
|
+
essenceType == DNXHD_1253_ESSENCE_TYPE)
|
396
|
+
{
|
397
|
+
return get_dnxhd_type_string(essenceType, editRate);
|
398
|
+
}
|
399
|
+
|
400
|
+
return ESSENCE_TYPE_STRINGS[essenceType];
|
401
|
+
}
|
402
|
+
|
403
|
+
static const char* frame_layout_string(uint8_t frameLayout)
|
404
|
+
{
|
405
|
+
if ((size_t)frameLayout + 1 < ARRAY_SIZE(FRAME_LAYOUT_STRINGS))
|
406
|
+
{
|
407
|
+
return FRAME_LAYOUT_STRINGS[frameLayout + 1];
|
408
|
+
}
|
409
|
+
|
410
|
+
return FRAME_LAYOUT_STRINGS[0];
|
411
|
+
}
|
412
|
+
|
413
|
+
static void print_umid(const mxfUMID *umid)
|
414
|
+
{
|
415
|
+
printf("%02x%02x%02x%02x%02x%02x%02x%02x"
|
416
|
+
"%02x%02x%02x%02x%02x%02x%02x%02x"
|
417
|
+
"%02x%02x%02x%02x%02x%02x%02x%02x"
|
418
|
+
"%02x%02x%02x%02x%02x%02x%02x%02x",
|
419
|
+
umid->octet0, umid->octet1, umid->octet2, umid->octet3,
|
420
|
+
umid->octet4, umid->octet5, umid->octet6, umid->octet7,
|
421
|
+
umid->octet8, umid->octet9, umid->octet10, umid->octet11,
|
422
|
+
umid->octet12, umid->octet13, umid->octet14, umid->octet15,
|
423
|
+
umid->octet16, umid->octet17, umid->octet18, umid->octet19,
|
424
|
+
umid->octet20, umid->octet21, umid->octet22, umid->octet23,
|
425
|
+
umid->octet24, umid->octet25, umid->octet26, umid->octet27,
|
426
|
+
umid->octet28, umid->octet29, umid->octet30, umid->octet31);
|
427
|
+
}
|
428
|
+
|
429
|
+
static void print_timestamp(const mxfTimestamp *timestamp)
|
430
|
+
{
|
431
|
+
printf("%d-%02u-%02u %02u:%02u:%02u.%03u",
|
432
|
+
timestamp->year, timestamp->month, timestamp->day,
|
433
|
+
timestamp->hour, timestamp->min, timestamp->sec, timestamp->qmsec * 4);
|
434
|
+
}
|
435
|
+
|
436
|
+
static void print_label(const mxfUL *label)
|
437
|
+
{
|
438
|
+
printf("%02x%02x%02x%02x%02x%02x%02x%02x"
|
439
|
+
"%02x%02x%02x%02x%02x%02x%02x%02x",
|
440
|
+
label->octet0, label->octet1, label->octet2, label->octet3,
|
441
|
+
label->octet4, label->octet5, label->octet6, label->octet7,
|
442
|
+
label->octet8, label->octet9, label->octet10, label->octet11,
|
443
|
+
label->octet12, label->octet13, label->octet14, label->octet15);
|
444
|
+
}
|
445
|
+
|
446
|
+
static void print_timecode(int64_t timecode, const mxfRational *sampleRate)
|
447
|
+
{
|
448
|
+
int hour, min, sec, frame;
|
449
|
+
int roundedTimecodeBase = (int)(sampleRate->numerator / (double)sampleRate->denominator + 0.5);
|
450
|
+
|
451
|
+
hour = (int)( timecode / (60 * 60 * roundedTimecodeBase));
|
452
|
+
min = (int)(( timecode % (60 * 60 * roundedTimecodeBase)) / (60 * roundedTimecodeBase));
|
453
|
+
sec = (int)(((timecode % (60 * 60 * roundedTimecodeBase)) % (60 * roundedTimecodeBase)) / roundedTimecodeBase);
|
454
|
+
frame = (int)(((timecode % (60 * 60 * roundedTimecodeBase)) % (60 * roundedTimecodeBase)) % roundedTimecodeBase);
|
455
|
+
|
456
|
+
printf("%02d:%02d:%02d:%02d", hour, min, sec, frame);
|
457
|
+
}
|
458
|
+
|
459
|
+
static int convert_string(const mxfUTF16Char *utf16Str, char **str, int printDebugError)
|
460
|
+
{
|
461
|
+
size_t utf8Len;
|
462
|
+
|
463
|
+
utf8Len = mxf_utf16_to_utf8(0, utf16Str, 0);
|
464
|
+
FCHECK(utf8Len != (size_t)(-1));
|
465
|
+
FCHECK((*str = malloc(utf8Len + 1)) != NULL);
|
466
|
+
mxf_utf16_to_utf8(*str, utf16Str, utf8Len + 1);
|
467
|
+
|
468
|
+
return 1;
|
469
|
+
|
470
|
+
fail:
|
471
|
+
return 0;
|
472
|
+
}
|
473
|
+
|
474
|
+
static void free_avid_tagged_values(AvidTaggedValue *value, int numValues)
|
475
|
+
{
|
476
|
+
int i, j;
|
477
|
+
|
478
|
+
if (value == NULL)
|
479
|
+
{
|
480
|
+
return;
|
481
|
+
}
|
482
|
+
|
483
|
+
for (i = 0; i < numValues; i++)
|
484
|
+
{
|
485
|
+
SAFE_FREE(value[i].name);
|
486
|
+
SAFE_FREE(value[i].value);
|
487
|
+
for (j = 0; j < value[i].numAttributes; j++)
|
488
|
+
{
|
489
|
+
SAFE_FREE(value[i].attributes[j].name);
|
490
|
+
SAFE_FREE(value[i].attributes[j].value);
|
491
|
+
}
|
492
|
+
SAFE_FREE(value[i].attributes);
|
493
|
+
}
|
494
|
+
|
495
|
+
free(value);
|
496
|
+
}
|
497
|
+
|
498
|
+
static int get_string_value(MXFMetadataSet *set, const mxfKey *itemKey, char **str, int printDebugError)
|
499
|
+
{
|
500
|
+
uint16_t utf16Size;
|
501
|
+
mxfUTF16Char *utf16Str = NULL;
|
502
|
+
|
503
|
+
FCHECK(mxf_get_utf16string_item_size(set, itemKey, &utf16Size));
|
504
|
+
FCHECK((utf16Str = malloc(utf16Size * sizeof(mxfUTF16Char))) != NULL);
|
505
|
+
FCHECK(mxf_get_utf16string_item(set, itemKey, utf16Str));
|
506
|
+
|
507
|
+
FCHECK(convert_string(utf16Str, str, printDebugError));
|
508
|
+
|
509
|
+
SAFE_FREE(utf16Str);
|
510
|
+
return 1;
|
511
|
+
|
512
|
+
fail:
|
513
|
+
SAFE_FREE(utf16Str);
|
514
|
+
return 0;
|
515
|
+
}
|
516
|
+
|
517
|
+
static int get_package_tagged_values(MXFMetadataSet *packageSet, const mxfKey *itemKey, int *numValues,
|
518
|
+
AvidTaggedValue **values, int printDebugError)
|
519
|
+
{
|
520
|
+
MXFMetadataSet *taggedValueSet;
|
521
|
+
uint32_t count;
|
522
|
+
uint32_t i;
|
523
|
+
uint8_t *element;
|
524
|
+
mxfUTF16Char *taggedValueName = NULL;
|
525
|
+
mxfUTF16Char *taggedValueValue = NULL;
|
526
|
+
AvidTaggedValue *newValues = NULL;
|
527
|
+
int index;
|
528
|
+
MXFListIterator namesIter;
|
529
|
+
MXFListIterator valuesIter;
|
530
|
+
MXFList *taggedValueNames = NULL;
|
531
|
+
MXFList *taggedValueValues = NULL;
|
532
|
+
|
533
|
+
FCHECK(mxf_have_item(packageSet, itemKey));
|
534
|
+
|
535
|
+
CHK_OFAIL(mxf_get_array_item_count(packageSet, itemKey, &count));
|
536
|
+
|
537
|
+
FCHECK((newValues = (AvidTaggedValue*)malloc(count * sizeof(AvidTaggedValue))) != NULL);
|
538
|
+
memset(newValues, 0, count * sizeof(AvidTaggedValue));
|
539
|
+
|
540
|
+
for (i = 0; i < count; i++)
|
541
|
+
{
|
542
|
+
CHK_OFAIL(mxf_get_array_item_element(packageSet, itemKey, i, &element));
|
543
|
+
CHK_OFAIL(mxf_get_strongref(packageSet->headerMetadata, element, &taggedValueSet));
|
544
|
+
|
545
|
+
CHK_OFAIL(mxf_avid_read_string_tagged_value(taggedValueSet, &taggedValueName, &taggedValueValue));
|
546
|
+
|
547
|
+
FCHECK(convert_string(taggedValueName, &newValues[i].name, printDebugError));
|
548
|
+
FCHECK(convert_string(taggedValueValue, &newValues[i].value, printDebugError));
|
549
|
+
SAFE_FREE(taggedValueName);
|
550
|
+
SAFE_FREE(taggedValueValue);
|
551
|
+
|
552
|
+
/* Check for any attributes */
|
553
|
+
if (mxf_have_item(taggedValueSet, &MXF_ITEM_K(TaggedValue, TaggedValueAttributeList)))
|
554
|
+
{
|
555
|
+
CHK_OFAIL(mxf_avid_read_string_tagged_values(taggedValueSet, &MXF_ITEM_K(TaggedValue, TaggedValueAttributeList),
|
556
|
+
&taggedValueNames, &taggedValueValues));
|
557
|
+
newValues[i].numAttributes = (int)mxf_get_list_length(taggedValueNames);
|
558
|
+
|
559
|
+
FCHECK((newValues[i].attributes = (AvidNameValuePair*)malloc(newValues[i].numAttributes * sizeof(AvidNameValuePair))) != NULL);
|
560
|
+
memset(newValues[i].attributes, 0, newValues[i].numAttributes * sizeof(AvidNameValuePair));
|
561
|
+
|
562
|
+
index = 0;
|
563
|
+
mxf_initialise_list_iter(&namesIter, taggedValueNames);
|
564
|
+
mxf_initialise_list_iter(&valuesIter, taggedValueValues);
|
565
|
+
while (mxf_next_list_iter_element(&namesIter) && mxf_next_list_iter_element(&valuesIter))
|
566
|
+
{
|
567
|
+
FCHECK(convert_string(mxf_get_iter_element(&namesIter), &newValues[i].attributes[index].name, printDebugError));
|
568
|
+
FCHECK(convert_string(mxf_get_iter_element(&valuesIter), &newValues[i].attributes[index].value, printDebugError));
|
569
|
+
|
570
|
+
index++;
|
571
|
+
}
|
572
|
+
|
573
|
+
mxf_free_list(&taggedValueNames);
|
574
|
+
mxf_free_list(&taggedValueValues);
|
575
|
+
}
|
576
|
+
}
|
577
|
+
|
578
|
+
*values = newValues;
|
579
|
+
*numValues = count;
|
580
|
+
|
581
|
+
return 1;
|
582
|
+
|
583
|
+
fail:
|
584
|
+
free_avid_tagged_values(newValues, count);
|
585
|
+
SAFE_FREE(taggedValueName);
|
586
|
+
SAFE_FREE(taggedValueValue);
|
587
|
+
mxf_free_list(&taggedValueNames);
|
588
|
+
mxf_free_list(&taggedValueValues);
|
589
|
+
return 0;
|
590
|
+
}
|
591
|
+
|
592
|
+
static int get_single_track_component(MXFMetadataSet *trackSet, const mxfKey *componentSetKey,
|
593
|
+
MXFMetadataSet **componentSet, int printDebugError)
|
594
|
+
{
|
595
|
+
MXFMetadataSet *sequenceSet = NULL;
|
596
|
+
MXFMetadataSet *cSet = NULL;
|
597
|
+
uint32_t componentCount;
|
598
|
+
uint8_t *arrayElementValue;
|
599
|
+
|
600
|
+
/* get the single component in the sequence which is a subclass of componentSetKey */
|
601
|
+
FCHECK(mxf_get_strongref_item(trackSet, &MXF_ITEM_K(GenericTrack, Sequence), &sequenceSet));
|
602
|
+
if (mxf_set_is_subclass_of(sequenceSet, &MXF_SET_K(Sequence)))
|
603
|
+
{
|
604
|
+
/* is a sequence, so we get the first component */
|
605
|
+
FCHECK(mxf_get_array_item_count(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &componentCount));
|
606
|
+
if (componentCount != 1)
|
607
|
+
{
|
608
|
+
/* empty sequence or > 1 are not what we expect */
|
609
|
+
return 0;
|
610
|
+
}
|
611
|
+
|
612
|
+
/* get first component */
|
613
|
+
FCHECK(mxf_get_array_item_element(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), 0, &arrayElementValue));
|
614
|
+
if (!mxf_get_strongref(trackSet->headerMetadata, arrayElementValue, &cSet))
|
615
|
+
{
|
616
|
+
/* reference to a dark set and we assume it isn't something we're interested in */
|
617
|
+
return 0;
|
618
|
+
}
|
619
|
+
}
|
620
|
+
else
|
621
|
+
{
|
622
|
+
/* something other than a sequence */
|
623
|
+
cSet = sequenceSet;
|
624
|
+
}
|
625
|
+
|
626
|
+
if (!mxf_set_is_subclass_of(cSet, componentSetKey))
|
627
|
+
{
|
628
|
+
/* not a componentSetKey component */
|
629
|
+
return 0;
|
630
|
+
}
|
631
|
+
|
632
|
+
*componentSet = cSet;
|
633
|
+
return 1;
|
634
|
+
|
635
|
+
fail:
|
636
|
+
return 0;
|
637
|
+
}
|
638
|
+
|
639
|
+
static int64_t convert_length(const mxfRational *targetEditRate, const mxfRational *editRate, int64_t length)
|
640
|
+
{
|
641
|
+
return (int64_t)(length *
|
642
|
+
targetEditRate->numerator * editRate->denominator /
|
643
|
+
(double)(targetEditRate->denominator * editRate->numerator) + 0.5);
|
644
|
+
}
|
645
|
+
|
646
|
+
static int64_t compare_length(const mxfRational *editRateA, int64_t lengthA, const mxfRational *editRateB, int64_t lengthB)
|
647
|
+
{
|
648
|
+
return lengthA - convert_length(editRateA, editRateB, lengthB);
|
649
|
+
}
|
650
|
+
|
651
|
+
static void insert_track_number(TrackNumberRange *trackNumbers, uint32_t trackNumber, int *numTrackNumberRanges)
|
652
|
+
{
|
653
|
+
int i;
|
654
|
+
int j;
|
655
|
+
|
656
|
+
for (i = 0; i < *numTrackNumberRanges; i++)
|
657
|
+
{
|
658
|
+
if (trackNumber < trackNumbers[i].first - 1)
|
659
|
+
{
|
660
|
+
/* insert new track range */
|
661
|
+
for (j = *numTrackNumberRanges - 1; j >= i; j--)
|
662
|
+
{
|
663
|
+
trackNumbers[j + 1] = trackNumbers[j];
|
664
|
+
}
|
665
|
+
trackNumbers[i].first = trackNumber;
|
666
|
+
trackNumbers[i].last = trackNumber;
|
667
|
+
|
668
|
+
(*numTrackNumberRanges)++;
|
669
|
+
return;
|
670
|
+
}
|
671
|
+
else if (trackNumber == trackNumbers[i].first - 1)
|
672
|
+
{
|
673
|
+
/* extend range back one */
|
674
|
+
trackNumbers[i].first = trackNumber;
|
675
|
+
return;
|
676
|
+
}
|
677
|
+
else if (trackNumber == trackNumbers[i].last + 1)
|
678
|
+
{
|
679
|
+
if (i + 1 < *numTrackNumberRanges &&
|
680
|
+
trackNumber == trackNumbers[i + 1].first - 1)
|
681
|
+
{
|
682
|
+
/* merge range forwards */
|
683
|
+
trackNumbers[i + 1].first = trackNumbers[i].first;
|
684
|
+
for (j = i; j < *numTrackNumberRanges - 1; j++)
|
685
|
+
{
|
686
|
+
trackNumbers[j] = trackNumbers[j + 1];
|
687
|
+
}
|
688
|
+
(*numTrackNumberRanges)--;
|
689
|
+
}
|
690
|
+
else
|
691
|
+
{
|
692
|
+
/* extend range forward one */
|
693
|
+
trackNumbers[i].last = trackNumber;
|
694
|
+
}
|
695
|
+
|
696
|
+
return;
|
697
|
+
}
|
698
|
+
else if (trackNumber == trackNumbers[i].first ||
|
699
|
+
trackNumber == trackNumbers[i].last)
|
700
|
+
{
|
701
|
+
/* duplicate */
|
702
|
+
return;
|
703
|
+
}
|
704
|
+
}
|
705
|
+
|
706
|
+
|
707
|
+
/* append new track range */
|
708
|
+
trackNumbers[i].first = trackNumber;
|
709
|
+
trackNumbers[i].last = trackNumber;
|
710
|
+
|
711
|
+
(*numTrackNumberRanges)++;
|
712
|
+
return;
|
713
|
+
}
|
714
|
+
|
715
|
+
static size_t get_range_string(char *buffer, size_t maxSize, int isFirst, int isVideo, const TrackNumberRange *range)
|
716
|
+
{
|
717
|
+
size_t strLen = 0;
|
718
|
+
|
719
|
+
if (isFirst)
|
720
|
+
{
|
721
|
+
mxf_snprintf(buffer, maxSize, "%s", (isVideo) ? "V" : "A");
|
722
|
+
strLen = strlen(buffer);
|
723
|
+
buffer += strLen;
|
724
|
+
maxSize -= strLen;
|
725
|
+
}
|
726
|
+
else
|
727
|
+
{
|
728
|
+
mxf_snprintf(buffer, maxSize, ",");
|
729
|
+
strLen = strlen(buffer);
|
730
|
+
buffer += strLen;
|
731
|
+
maxSize -= strLen;
|
732
|
+
}
|
733
|
+
|
734
|
+
|
735
|
+
if (range->first == range->last)
|
736
|
+
{
|
737
|
+
mxf_snprintf(buffer, maxSize, "%d", range->first);
|
738
|
+
strLen += strlen(buffer);
|
739
|
+
}
|
740
|
+
else
|
741
|
+
{
|
742
|
+
mxf_snprintf(buffer, maxSize, "%d-%d", range->first, range->last);
|
743
|
+
strLen += strlen(buffer);
|
744
|
+
}
|
745
|
+
|
746
|
+
return strLen;
|
747
|
+
}
|
748
|
+
|
749
|
+
|
750
|
+
int ami_read_info(const char *filename, AvidMXFInfo *info, int printDebugError)
|
751
|
+
{
|
752
|
+
int errorCode = -1;
|
753
|
+
mxfKey key;
|
754
|
+
uint8_t llen;
|
755
|
+
uint64_t len;
|
756
|
+
uint32_t sequenceComponentCount;
|
757
|
+
uint32_t choicesCount;
|
758
|
+
uint8_t *arrayElement;
|
759
|
+
MXFList *list = NULL;
|
760
|
+
MXFListIterator listIter;
|
761
|
+
MXFArrayItemIterator arrayIter;
|
762
|
+
MXFFile *mxfFile = NULL;
|
763
|
+
MXFPartition *headerPartition = NULL;
|
764
|
+
MXFDataModel *dataModel = NULL;
|
765
|
+
MXFHeaderMetadata *headerMetadata = NULL;
|
766
|
+
MXFMetadataSet *set = NULL;
|
767
|
+
MXFMetadataSet *prefaceSet = NULL;
|
768
|
+
MXFMetadataSet *fileSourcePackageSet = NULL;
|
769
|
+
MXFMetadataSet *materialPackageSet = NULL;
|
770
|
+
MXFMetadataSet *descriptorSet = NULL;
|
771
|
+
MXFMetadataSet *locatorSet = NULL;
|
772
|
+
MXFMetadataSet *physicalSourcePackageSet = NULL;
|
773
|
+
MXFMetadataSet *materialPackageTrackSet = NULL;
|
774
|
+
MXFMetadataSet *trackSet = NULL;
|
775
|
+
MXFMetadataSet *sourceClipSet = NULL;
|
776
|
+
MXFMetadataSet *sequenceSet = NULL;
|
777
|
+
MXFMetadataSet *timecodeComponentSet = NULL;
|
778
|
+
MXFMetadataSet *refSourcePackageSet = NULL;
|
779
|
+
MXFMetadataSet *essenceGroupSet = NULL;
|
780
|
+
mxfUMID packageUID;
|
781
|
+
MXFList *taggedValueNames = NULL;
|
782
|
+
MXFList *taggedValueValues = NULL;
|
783
|
+
const mxfUTF16Char *taggedValue;
|
784
|
+
mxfUL dataDef;
|
785
|
+
mxfUMID sourcePackageID;
|
786
|
+
MXFArrayItemIterator iter3;
|
787
|
+
int64_t filePackageStartPosition;
|
788
|
+
int64_t startPosition;
|
789
|
+
mxfRational filePackageEditRate;
|
790
|
+
int64_t startTimecode;
|
791
|
+
uint16_t roundedTimecodeBase;
|
792
|
+
int haveStartTimecode;
|
793
|
+
mxfRational editRate;
|
794
|
+
int64_t trackDuration;
|
795
|
+
int64_t segmentDuration;
|
796
|
+
int64_t segmentOffset;
|
797
|
+
mxfRational maxEditRate = {25, 1};
|
798
|
+
int64_t maxDuration = 0;
|
799
|
+
int32_t avidResolutionID = 0x00;
|
800
|
+
TrackNumberRange videoTrackNumberRanges[64];
|
801
|
+
int numVideoTrackNumberRanges = 0;
|
802
|
+
TrackNumberRange audioTrackNumberRanges[64];
|
803
|
+
int numAudioTrackNumberRanges = 0;
|
804
|
+
uint32_t trackNumber;
|
805
|
+
char tracksString[256] = {0};
|
806
|
+
int i, j;
|
807
|
+
size_t remSize;
|
808
|
+
char *tracksStringPtr;
|
809
|
+
size_t strLen;
|
810
|
+
uint32_t arrayElementLen;
|
811
|
+
uint16_t fpRoundedTimecodeBase;
|
812
|
+
|
813
|
+
memset(info, 0, sizeof(AvidMXFInfo));
|
814
|
+
info->frameLayout = 0xff; /* unknown (0 is known) */
|
815
|
+
|
816
|
+
|
817
|
+
/* open file */
|
818
|
+
|
819
|
+
CHECK(mxf_disk_file_open_read(filename, &mxfFile), -2);
|
820
|
+
|
821
|
+
|
822
|
+
/* read header partition pack */
|
823
|
+
|
824
|
+
CHECK(mxf_read_header_pp_kl(mxfFile, &key, &llen, &len), -3);
|
825
|
+
CHECK(mxf_read_partition(mxfFile, &key, &headerPartition), -3);
|
826
|
+
|
827
|
+
|
828
|
+
/* check is OP-Atom */
|
829
|
+
|
830
|
+
CHECK(mxf_is_op_atom(&headerPartition->operationalPattern), -4);
|
831
|
+
|
832
|
+
|
833
|
+
/* read the header metadata (filter out meta-dictionary and dictionary except data defs) */
|
834
|
+
|
835
|
+
DCHECK(mxf_load_data_model(&dataModel));
|
836
|
+
DCHECK(mxf_avid_load_extensions(dataModel));
|
837
|
+
|
838
|
+
DCHECK(mxf_finalise_data_model(dataModel));
|
839
|
+
|
840
|
+
DCHECK(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len));
|
841
|
+
DCHECK(mxf_is_header_metadata(&key));
|
842
|
+
DCHECK(mxf_create_header_metadata(&headerMetadata, dataModel));
|
843
|
+
DCHECK(mxf_avid_read_filtered_header_metadata(mxfFile, 0, headerMetadata, headerPartition->headerByteCount, &key, llen, len));
|
844
|
+
|
845
|
+
|
846
|
+
/* get the preface and info */
|
847
|
+
|
848
|
+
DCHECK(mxf_find_singular_set_by_key(headerMetadata, &MXF_SET_K(Preface), &prefaceSet));
|
849
|
+
if (mxf_have_item(prefaceSet, &MXF_ITEM_K(Preface, ProjectName)))
|
850
|
+
{
|
851
|
+
DCHECK(get_string_value(prefaceSet, &MXF_ITEM_K(Preface, ProjectName), &info->projectName, printDebugError));
|
852
|
+
}
|
853
|
+
if (mxf_have_item(prefaceSet, &MXF_ITEM_K(Preface, ProjectEditRate)))
|
854
|
+
{
|
855
|
+
DCHECK(mxf_get_rational_item(prefaceSet, &MXF_ITEM_K(Preface, ProjectEditRate), &info->projectEditRate));
|
856
|
+
}
|
857
|
+
|
858
|
+
|
859
|
+
/* get the material package and info */
|
860
|
+
|
861
|
+
DCHECK(mxf_find_singular_set_by_key(headerMetadata, &MXF_SET_K(MaterialPackage), &materialPackageSet));
|
862
|
+
DCHECK(mxf_get_umid_item(materialPackageSet, &MXF_ITEM_K(GenericPackage, PackageUID), &info->materialPackageUID));
|
863
|
+
if (mxf_have_item(materialPackageSet, &MXF_ITEM_K(GenericPackage, Name)))
|
864
|
+
{
|
865
|
+
DCHECK(get_string_value(materialPackageSet, &MXF_ITEM_K(GenericPackage, Name), &info->clipName, printDebugError));
|
866
|
+
}
|
867
|
+
if (mxf_have_item(materialPackageSet, &MXF_ITEM_K(GenericPackage, PackageCreationDate)))
|
868
|
+
{
|
869
|
+
DCHECK(mxf_get_timestamp_item(materialPackageSet, &MXF_ITEM_K(GenericPackage, PackageCreationDate), &info->clipCreated));
|
870
|
+
}
|
871
|
+
|
872
|
+
|
873
|
+
/* get the material package project name tagged value if not already set */
|
874
|
+
|
875
|
+
if (info->projectName == NULL &&
|
876
|
+
mxf_have_item(materialPackageSet, &MXF_ITEM_K(GenericPackage, MobAttributeList)))
|
877
|
+
{
|
878
|
+
DCHECK(mxf_avid_read_string_mob_attributes(materialPackageSet, &taggedValueNames, &taggedValueValues));
|
879
|
+
if (mxf_avid_get_mob_attribute(L"_PJ", taggedValueNames, taggedValueValues, &taggedValue))
|
880
|
+
{
|
881
|
+
DCHECK(convert_string(taggedValue, &info->projectName, printDebugError));
|
882
|
+
}
|
883
|
+
}
|
884
|
+
mxf_free_list(&taggedValueNames);
|
885
|
+
mxf_free_list(&taggedValueValues);
|
886
|
+
|
887
|
+
|
888
|
+
/* get the material package user comments */
|
889
|
+
if (mxf_have_item(materialPackageSet, &MXF_ITEM_K(GenericPackage, UserComments)))
|
890
|
+
{
|
891
|
+
DCHECK(get_package_tagged_values(materialPackageSet, &MXF_ITEM_K(GenericPackage, UserComments), &info->numUserComments, &info->userComments, printDebugError));
|
892
|
+
}
|
893
|
+
|
894
|
+
/* get the material package attributes */
|
895
|
+
if (mxf_have_item(materialPackageSet, &MXF_ITEM_K(GenericPackage, MobAttributeList)))
|
896
|
+
{
|
897
|
+
DCHECK(get_package_tagged_values(materialPackageSet, &MXF_ITEM_K(GenericPackage, MobAttributeList), &info->numMaterialPackageAttributes, &info->materialPackageAttributes, printDebugError));
|
898
|
+
}
|
899
|
+
|
900
|
+
/* get the top level file source package and info */
|
901
|
+
|
902
|
+
DCHECK(mxf_uu_get_top_file_package(headerMetadata, &fileSourcePackageSet));
|
903
|
+
DCHECK(mxf_get_umid_item(fileSourcePackageSet, &MXF_ITEM_K(GenericPackage, PackageUID), &info->fileSourcePackageUID));
|
904
|
+
|
905
|
+
|
906
|
+
/* get the file source package essence descriptor info */
|
907
|
+
|
908
|
+
DCHECK(mxf_get_strongref_item(fileSourcePackageSet, &MXF_ITEM_K(SourcePackage, Descriptor), &descriptorSet));
|
909
|
+
if (mxf_is_subclass_of(dataModel, &descriptorSet->key, &MXF_SET_K(GenericPictureEssenceDescriptor)))
|
910
|
+
{
|
911
|
+
/* image aspect ratio */
|
912
|
+
if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, AspectRatio)))
|
913
|
+
{
|
914
|
+
DCHECK(mxf_get_rational_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, AspectRatio), &info->aspectRatio));
|
915
|
+
}
|
916
|
+
|
917
|
+
/* frame layout */
|
918
|
+
if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, FrameLayout)))
|
919
|
+
{
|
920
|
+
DCHECK(mxf_get_uint8_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, FrameLayout), &info->frameLayout));
|
921
|
+
}
|
922
|
+
|
923
|
+
/* stored width and height */
|
924
|
+
if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, StoredWidth)))
|
925
|
+
{
|
926
|
+
DCHECK(mxf_get_uint32_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, StoredWidth), &info->storedWidth));
|
927
|
+
}
|
928
|
+
if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, StoredHeight)))
|
929
|
+
{
|
930
|
+
DCHECK(mxf_get_uint32_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, StoredHeight), &info->storedHeight));
|
931
|
+
}
|
932
|
+
|
933
|
+
/* display width and height */
|
934
|
+
if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, DisplayWidth)))
|
935
|
+
{
|
936
|
+
DCHECK(mxf_get_uint32_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, DisplayWidth), &info->displayWidth));
|
937
|
+
}
|
938
|
+
if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, DisplayHeight)))
|
939
|
+
{
|
940
|
+
DCHECK(mxf_get_uint32_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, DisplayHeight), &info->displayHeight));
|
941
|
+
}
|
942
|
+
|
943
|
+
/* Avid resolution Id */
|
944
|
+
if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, ResolutionID)))
|
945
|
+
{
|
946
|
+
DCHECK(mxf_get_int32_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, ResolutionID), &avidResolutionID));
|
947
|
+
}
|
948
|
+
|
949
|
+
/* picture essence coding label */
|
950
|
+
if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, PictureEssenceCoding)))
|
951
|
+
{
|
952
|
+
DCHECK(mxf_get_ul_item(descriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, PictureEssenceCoding), &info->pictureCodingLabel));
|
953
|
+
}
|
954
|
+
}
|
955
|
+
else if (mxf_is_subclass_of(dataModel, &descriptorSet->key, &MXF_SET_K(GenericSoundEssenceDescriptor)))
|
956
|
+
{
|
957
|
+
/* audio sampling rate */
|
958
|
+
if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericSoundEssenceDescriptor, AudioSamplingRate)))
|
959
|
+
{
|
960
|
+
DCHECK(mxf_get_rational_item(descriptorSet, &MXF_ITEM_K(GenericSoundEssenceDescriptor, AudioSamplingRate), &info->audioSamplingRate));
|
961
|
+
}
|
962
|
+
/* quantization bits */
|
963
|
+
if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericSoundEssenceDescriptor, QuantizationBits)))
|
964
|
+
{
|
965
|
+
DCHECK(mxf_get_uint32_item(descriptorSet, &MXF_ITEM_K(GenericSoundEssenceDescriptor, QuantizationBits), &info->quantizationBits));
|
966
|
+
}
|
967
|
+
/* channel count */
|
968
|
+
if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericSoundEssenceDescriptor, ChannelCount)))
|
969
|
+
{
|
970
|
+
DCHECK(mxf_get_uint32_item(descriptorSet, &MXF_ITEM_K(GenericSoundEssenceDescriptor, ChannelCount), &info->channelCount));
|
971
|
+
}
|
972
|
+
}
|
973
|
+
|
974
|
+
|
975
|
+
/* get the material track referencing the file source package and info */
|
976
|
+
/* get the clip duration ( = duration of the longest track) */
|
977
|
+
|
978
|
+
DCHECK(mxf_uu_get_package_tracks(materialPackageSet, &arrayIter));
|
979
|
+
while (mxf_uu_next_track(headerMetadata, &arrayIter, &materialPackageTrackSet))
|
980
|
+
{
|
981
|
+
DCHECK(mxf_uu_get_track_datadef(materialPackageTrackSet, &dataDef));
|
982
|
+
|
983
|
+
/* some Avid files have a weak reference to a DataDefinition instead of a UL */
|
984
|
+
if (!mxf_is_picture(&dataDef) && !mxf_is_sound(&dataDef) && !mxf_is_timecode(&dataDef))
|
985
|
+
{
|
986
|
+
if (!mxf_avid_get_data_def(headerMetadata, (mxfUUID*)&dataDef, &dataDef))
|
987
|
+
{
|
988
|
+
continue;
|
989
|
+
}
|
990
|
+
}
|
991
|
+
|
992
|
+
/* skip non-video and audio tracks */
|
993
|
+
if (!mxf_is_picture(&dataDef) && !mxf_is_sound(&dataDef))
|
994
|
+
{
|
995
|
+
continue;
|
996
|
+
}
|
997
|
+
|
998
|
+
/* track counts */
|
999
|
+
if (mxf_is_picture(&dataDef))
|
1000
|
+
{
|
1001
|
+
info->numVideoTracks++;
|
1002
|
+
}
|
1003
|
+
else
|
1004
|
+
{
|
1005
|
+
info->numAudioTracks++;
|
1006
|
+
}
|
1007
|
+
|
1008
|
+
/* track number */
|
1009
|
+
if (mxf_have_item(materialPackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackNumber)))
|
1010
|
+
{
|
1011
|
+
DCHECK(mxf_get_uint32_item(materialPackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackNumber), &trackNumber));
|
1012
|
+
if (mxf_is_picture(&dataDef))
|
1013
|
+
{
|
1014
|
+
insert_track_number(videoTrackNumberRanges, trackNumber, &numVideoTrackNumberRanges);
|
1015
|
+
}
|
1016
|
+
else
|
1017
|
+
{
|
1018
|
+
insert_track_number(audioTrackNumberRanges, trackNumber, &numAudioTrackNumberRanges);
|
1019
|
+
}
|
1020
|
+
}
|
1021
|
+
else
|
1022
|
+
{
|
1023
|
+
trackNumber = 0;
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
/* edit rate */
|
1027
|
+
DCHECK(mxf_get_rational_item(materialPackageTrackSet, &MXF_ITEM_K(Track, EditRate), &editRate));
|
1028
|
+
|
1029
|
+
/* track duration */
|
1030
|
+
DCHECK(mxf_uu_get_track_duration(materialPackageTrackSet, &trackDuration));
|
1031
|
+
|
1032
|
+
/* get max duration for the clip duration */
|
1033
|
+
if (compare_length(&maxEditRate, maxDuration, &editRate, trackDuration) <= 0)
|
1034
|
+
{
|
1035
|
+
maxEditRate = editRate;
|
1036
|
+
maxDuration = trackDuration;
|
1037
|
+
}
|
1038
|
+
|
1039
|
+
/* assume the project edit rate equals the video edit rate if not set */
|
1040
|
+
if (memcmp(&info->projectEditRate, &g_Null_Rational, sizeof(g_Null_Rational)) == 0 &&
|
1041
|
+
mxf_is_picture(&dataDef))
|
1042
|
+
{
|
1043
|
+
info->projectEditRate = editRate;
|
1044
|
+
}
|
1045
|
+
|
1046
|
+
/* get info from this track if it references the file source package through a source clip */
|
1047
|
+
packageUID = g_Null_UMID;
|
1048
|
+
segmentOffset = 0;
|
1049
|
+
CHK_ORET(mxf_get_strongref_item(materialPackageTrackSet, &MXF_ITEM_K(GenericTrack, Sequence), &sequenceSet));
|
1050
|
+
if (!mxf_is_subclass_of(sequenceSet->headerMetadata->dataModel, &sequenceSet->key, &MXF_SET_K(SourceClip)))
|
1051
|
+
{
|
1052
|
+
/* iterate through sequence components */
|
1053
|
+
CHK_ORET(mxf_get_array_item_count(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &sequenceComponentCount));
|
1054
|
+
for (i = 0; i < (int)sequenceComponentCount; i++)
|
1055
|
+
{
|
1056
|
+
CHK_ORET(mxf_get_array_item_element(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), i, &arrayElement));
|
1057
|
+
if (!mxf_get_strongref(sequenceSet->headerMetadata, arrayElement, &sourceClipSet))
|
1058
|
+
{
|
1059
|
+
/* dark set not registered in the dictionary */
|
1060
|
+
continue;
|
1061
|
+
}
|
1062
|
+
|
1063
|
+
CHK_ORET(mxf_get_length_item(sourceClipSet, &MXF_ITEM_K(StructuralComponent, Duration), &segmentDuration));
|
1064
|
+
|
1065
|
+
if (mxf_is_subclass_of(sourceClipSet->headerMetadata->dataModel, &sourceClipSet->key, &MXF_SET_K(EssenceGroup)))
|
1066
|
+
{
|
1067
|
+
/* is an essence group - iterate through choices */
|
1068
|
+
essenceGroupSet = sourceClipSet;
|
1069
|
+
CHK_ORET(mxf_get_array_item_count(essenceGroupSet, &MXF_ITEM_K(EssenceGroup, Choices), &choicesCount));
|
1070
|
+
for (j = 0; j < (int)choicesCount; j++)
|
1071
|
+
{
|
1072
|
+
CHK_ORET(mxf_get_array_item_element(essenceGroupSet, &MXF_ITEM_K(EssenceGroup, Choices), j, &arrayElement));
|
1073
|
+
if (!mxf_get_strongref(essenceGroupSet->headerMetadata, arrayElement, &sourceClipSet))
|
1074
|
+
{
|
1075
|
+
/* dark set not registered in the dictionary */
|
1076
|
+
continue;
|
1077
|
+
}
|
1078
|
+
|
1079
|
+
if (mxf_is_subclass_of(sourceClipSet->headerMetadata->dataModel, &sourceClipSet->key, &MXF_SET_K(SourceClip)))
|
1080
|
+
{
|
1081
|
+
CHK_ORET(mxf_get_umid_item(sourceClipSet, &MXF_ITEM_K(SourceClip, SourcePackageID), &packageUID));
|
1082
|
+
if (mxf_equals_umid(&info->fileSourcePackageUID, &packageUID))
|
1083
|
+
{
|
1084
|
+
/* found source clip referencing file source package */
|
1085
|
+
break;
|
1086
|
+
}
|
1087
|
+
}
|
1088
|
+
}
|
1089
|
+
if (j < (int)choicesCount)
|
1090
|
+
{
|
1091
|
+
/* found source clip referencing file source package */
|
1092
|
+
break;
|
1093
|
+
}
|
1094
|
+
}
|
1095
|
+
else if (mxf_is_subclass_of(sourceClipSet->headerMetadata->dataModel, &sourceClipSet->key, &MXF_SET_K(SourceClip)))
|
1096
|
+
{
|
1097
|
+
CHK_ORET(mxf_get_umid_item(sourceClipSet, &MXF_ITEM_K(SourceClip, SourcePackageID), &packageUID));
|
1098
|
+
if (mxf_equals_umid(&info->fileSourcePackageUID, &packageUID))
|
1099
|
+
{
|
1100
|
+
/* found source clip referencing file source package */
|
1101
|
+
break;
|
1102
|
+
}
|
1103
|
+
}
|
1104
|
+
|
1105
|
+
segmentOffset += segmentDuration;
|
1106
|
+
}
|
1107
|
+
}
|
1108
|
+
else
|
1109
|
+
{
|
1110
|
+
/* track sequence is a source clip */
|
1111
|
+
sourceClipSet = sequenceSet;
|
1112
|
+
CHK_ORET(mxf_get_umid_item(sourceClipSet, &MXF_ITEM_K(SourceClip, SourcePackageID), &packageUID));
|
1113
|
+
CHK_ORET(mxf_get_length_item(sourceClipSet, &MXF_ITEM_K(StructuralComponent, Duration), &segmentDuration));
|
1114
|
+
segmentOffset = 0;
|
1115
|
+
}
|
1116
|
+
|
1117
|
+
if (mxf_equals_umid(&info->fileSourcePackageUID, &packageUID))
|
1118
|
+
{
|
1119
|
+
info->isVideo = mxf_is_picture(&dataDef);
|
1120
|
+
info->editRate = editRate;
|
1121
|
+
info->trackDuration = trackDuration;
|
1122
|
+
info->trackNumber = trackNumber;
|
1123
|
+
info->segmentDuration = segmentDuration;
|
1124
|
+
info->segmentOffset = segmentOffset;
|
1125
|
+
}
|
1126
|
+
}
|
1127
|
+
|
1128
|
+
|
1129
|
+
info->clipDuration = convert_length(&info->projectEditRate, &maxEditRate, maxDuration);
|
1130
|
+
|
1131
|
+
|
1132
|
+
|
1133
|
+
/* construct the tracks string */
|
1134
|
+
|
1135
|
+
remSize = sizeof(tracksString);
|
1136
|
+
tracksStringPtr = tracksString;
|
1137
|
+
for (i = 0; i < numVideoTrackNumberRanges; i++)
|
1138
|
+
{
|
1139
|
+
if (remSize < 4)
|
1140
|
+
{
|
1141
|
+
break;
|
1142
|
+
}
|
1143
|
+
|
1144
|
+
strLen = get_range_string(tracksStringPtr, remSize, i == 0, 1, &videoTrackNumberRanges[i]);
|
1145
|
+
|
1146
|
+
tracksStringPtr += strLen;
|
1147
|
+
remSize -= strLen;
|
1148
|
+
}
|
1149
|
+
if (numVideoTrackNumberRanges > 0 && numAudioTrackNumberRanges > 0)
|
1150
|
+
{
|
1151
|
+
mxf_snprintf(tracksStringPtr, remSize, " ");
|
1152
|
+
strLen = strlen(tracksStringPtr);
|
1153
|
+
tracksStringPtr += strLen;
|
1154
|
+
remSize -= strLen;
|
1155
|
+
}
|
1156
|
+
for (i = 0; i < numAudioTrackNumberRanges; i++)
|
1157
|
+
{
|
1158
|
+
if (remSize < 4)
|
1159
|
+
{
|
1160
|
+
break;
|
1161
|
+
}
|
1162
|
+
strLen = get_range_string(tracksStringPtr, remSize, i == 0, 0, &audioTrackNumberRanges[i]);
|
1163
|
+
|
1164
|
+
tracksStringPtr += strLen;
|
1165
|
+
remSize -= strLen;
|
1166
|
+
}
|
1167
|
+
|
1168
|
+
DCHECK((info->tracksString = strdup(tracksString)) != NULL);
|
1169
|
+
|
1170
|
+
|
1171
|
+
|
1172
|
+
/* get the physical source package and info */
|
1173
|
+
|
1174
|
+
DCHECK(mxf_find_set_by_key(headerMetadata, &MXF_SET_K(SourcePackage), &list));
|
1175
|
+
mxf_initialise_list_iter(&listIter, list);
|
1176
|
+
while (mxf_next_list_iter_element(&listIter))
|
1177
|
+
{
|
1178
|
+
set = (MXFMetadataSet*)mxf_get_iter_element(&listIter);
|
1179
|
+
|
1180
|
+
/* the physical source package is the source package that references a physical descriptor */
|
1181
|
+
if (mxf_have_item(set, &MXF_ITEM_K(SourcePackage, Descriptor)))
|
1182
|
+
{
|
1183
|
+
if (mxf_get_strongref_item(set, &MXF_ITEM_K(SourcePackage, Descriptor), &descriptorSet))
|
1184
|
+
{
|
1185
|
+
/* Get first physical package network locator */
|
1186
|
+
if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericDescriptor, Locators)))
|
1187
|
+
{
|
1188
|
+
DCHECK(mxf_initialise_array_item_iterator(descriptorSet, &MXF_ITEM_K(GenericDescriptor, Locators), &arrayIter));
|
1189
|
+
while (mxf_next_array_item_element(&arrayIter, &arrayElement, &arrayElementLen))
|
1190
|
+
{
|
1191
|
+
DCHECK(mxf_get_strongref(headerMetadata, arrayElement, &locatorSet));
|
1192
|
+
if (mxf_is_subclass_of(headerMetadata->dataModel, &locatorSet->key, &MXF_SET_K(NetworkLocator)))
|
1193
|
+
{
|
1194
|
+
DCHECK(get_string_value(locatorSet, &MXF_ITEM_K(NetworkLocator, URLString), &info->physicalPackageLocator, printDebugError));
|
1195
|
+
break;
|
1196
|
+
}
|
1197
|
+
}
|
1198
|
+
}
|
1199
|
+
|
1200
|
+
/* NOTE/TODO: some descriptors could be dark and so we don't assume we can dereference */
|
1201
|
+
if (mxf_is_subclass_of(dataModel, &descriptorSet->key, &MXF_SET_K(PhysicalDescriptor)))
|
1202
|
+
{
|
1203
|
+
if (mxf_is_subclass_of(dataModel, &descriptorSet->key, &MXF_SET_K(TapeDescriptor)))
|
1204
|
+
{
|
1205
|
+
info->physicalPackageType = TAPE_PHYS_TYPE;
|
1206
|
+
}
|
1207
|
+
else if (mxf_is_subclass_of(dataModel, &descriptorSet->key, &MXF_SET_K(ImportDescriptor)))
|
1208
|
+
{
|
1209
|
+
info->physicalPackageType = IMPORT_PHYS_TYPE;
|
1210
|
+
}
|
1211
|
+
else if (mxf_is_subclass_of(dataModel, &descriptorSet->key, &MXF_SET_K(RecordingDescriptor)))
|
1212
|
+
{
|
1213
|
+
info->physicalPackageType = RECORDING_PHYS_TYPE;
|
1214
|
+
}
|
1215
|
+
else
|
1216
|
+
{
|
1217
|
+
info->physicalPackageType = UNKNOWN_PHYS_TYPE;
|
1218
|
+
}
|
1219
|
+
physicalSourcePackageSet = set;
|
1220
|
+
|
1221
|
+
DCHECK(mxf_get_umid_item(physicalSourcePackageSet, &MXF_ITEM_K(GenericPackage, PackageUID), &info->physicalSourcePackageUID));
|
1222
|
+
if (mxf_have_item(physicalSourcePackageSet, &MXF_ITEM_K(GenericPackage, Name)))
|
1223
|
+
{
|
1224
|
+
DCHECK(get_string_value(physicalSourcePackageSet, &MXF_ITEM_K(GenericPackage, Name), &info->physicalPackageName, printDebugError));
|
1225
|
+
}
|
1226
|
+
|
1227
|
+
break;
|
1228
|
+
}
|
1229
|
+
}
|
1230
|
+
}
|
1231
|
+
}
|
1232
|
+
mxf_free_list(&list);
|
1233
|
+
|
1234
|
+
|
1235
|
+
/* get the start timecode */
|
1236
|
+
|
1237
|
+
/* the source timecode is calculated using the SourceClip::StartPosition in the file source package
|
1238
|
+
in conjunction with the TimecodeComponent in the referenced physical source package */
|
1239
|
+
|
1240
|
+
haveStartTimecode = 0;
|
1241
|
+
DCHECK(mxf_uu_get_package_tracks(fileSourcePackageSet, &arrayIter));
|
1242
|
+
while (!haveStartTimecode && mxf_uu_next_track(headerMetadata, &arrayIter, &trackSet))
|
1243
|
+
{
|
1244
|
+
/* skip tracks that are not picture or sound */
|
1245
|
+
DCHECK(mxf_uu_get_track_datadef(trackSet, &dataDef));
|
1246
|
+
|
1247
|
+
/* some Avid files have a weak reference to a DataDefinition instead of a UL */
|
1248
|
+
if (!mxf_is_picture(&dataDef) && !mxf_is_sound(&dataDef) && !mxf_is_timecode(&dataDef))
|
1249
|
+
{
|
1250
|
+
if (!mxf_avid_get_data_def(headerMetadata, (mxfUUID*)&dataDef, &dataDef))
|
1251
|
+
{
|
1252
|
+
continue;
|
1253
|
+
}
|
1254
|
+
}
|
1255
|
+
|
1256
|
+
|
1257
|
+
if (!mxf_is_picture(&dataDef) && !mxf_is_sound(&dataDef))
|
1258
|
+
{
|
1259
|
+
continue;
|
1260
|
+
}
|
1261
|
+
|
1262
|
+
|
1263
|
+
/* get the source clip */
|
1264
|
+
if (!get_single_track_component(trackSet, &MXF_SET_K(SourceClip), &sourceClipSet, printDebugError))
|
1265
|
+
{
|
1266
|
+
continue;
|
1267
|
+
}
|
1268
|
+
|
1269
|
+
/* get the start position and edit rate for the file source package source clip */
|
1270
|
+
DCHECK(mxf_get_rational_item(trackSet, &MXF_ITEM_K(Track, EditRate), &filePackageEditRate));
|
1271
|
+
DCHECK(mxf_get_position_item(sourceClipSet, &MXF_ITEM_K(SourceClip, StartPosition), &filePackageStartPosition));
|
1272
|
+
|
1273
|
+
|
1274
|
+
/* get the package referenced by the source clip */
|
1275
|
+
DCHECK(mxf_get_umid_item(sourceClipSet, &MXF_ITEM_K(SourceClip, SourcePackageID), &sourcePackageID));
|
1276
|
+
if (mxf_equals_umid(&g_Null_UMID, &sourcePackageID) ||
|
1277
|
+
!mxf_uu_get_referenced_package(sourceClipSet->headerMetadata, &sourcePackageID, &refSourcePackageSet))
|
1278
|
+
{
|
1279
|
+
/* either at the end of chain or don't have the referenced package */
|
1280
|
+
continue;
|
1281
|
+
}
|
1282
|
+
|
1283
|
+
/* find the timecode component in the physical source package and calculate the start timecode */
|
1284
|
+
DCHECK(mxf_uu_get_package_tracks(refSourcePackageSet, &iter3));
|
1285
|
+
while (mxf_uu_next_track(headerMetadata, &iter3, &trackSet))
|
1286
|
+
{
|
1287
|
+
/* skip non-timecode tracks */
|
1288
|
+
DCHECK(mxf_uu_get_track_datadef(trackSet, &dataDef));
|
1289
|
+
|
1290
|
+
/* some Avid files have a weak reference to a DataDefinition instead of a UL */
|
1291
|
+
if (!mxf_is_picture(&dataDef) && !mxf_is_sound(&dataDef) && !mxf_is_timecode(&dataDef))
|
1292
|
+
{
|
1293
|
+
if (!mxf_avid_get_data_def(headerMetadata, (mxfUUID*)&dataDef, &dataDef))
|
1294
|
+
{
|
1295
|
+
continue;
|
1296
|
+
}
|
1297
|
+
}
|
1298
|
+
|
1299
|
+
if (!mxf_is_timecode(&dataDef))
|
1300
|
+
{
|
1301
|
+
continue;
|
1302
|
+
}
|
1303
|
+
|
1304
|
+
/* get the timecode component */
|
1305
|
+
if (!get_single_track_component(trackSet, &MXF_SET_K(TimecodeComponent), &timecodeComponentSet, printDebugError))
|
1306
|
+
{
|
1307
|
+
continue;
|
1308
|
+
}
|
1309
|
+
|
1310
|
+
/* get the start timecode and rounded timecode base for the timecode component */
|
1311
|
+
DCHECK(mxf_get_position_item(timecodeComponentSet, &MXF_ITEM_K(TimecodeComponent, StartTimecode), &startTimecode));
|
1312
|
+
DCHECK(mxf_get_uint16_item(timecodeComponentSet, &MXF_ITEM_K(TimecodeComponent, RoundedTimecodeBase), &roundedTimecodeBase));
|
1313
|
+
|
1314
|
+
/* convert the physical package start timecode to a start position in the file source package */
|
1315
|
+
startPosition = filePackageStartPosition;
|
1316
|
+
if (startTimecode > 0) {
|
1317
|
+
fpRoundedTimecodeBase = (uint16_t)(filePackageEditRate.numerator / (double)filePackageEditRate.denominator + 0.5);
|
1318
|
+
if (fpRoundedTimecodeBase == roundedTimecodeBase)
|
1319
|
+
{
|
1320
|
+
startPosition += startTimecode;
|
1321
|
+
}
|
1322
|
+
else if (fpRoundedTimecodeBase == 2 * roundedTimecodeBase)
|
1323
|
+
{
|
1324
|
+
startPosition += 2 * startTimecode;
|
1325
|
+
}
|
1326
|
+
else
|
1327
|
+
{
|
1328
|
+
// mxf_log_warn("Ignoring non-zero TimecodeComponent::StartTimecode because edit rate combination not supported\n");
|
1329
|
+
/* TODO: complete support for different timecode and track edit rates */
|
1330
|
+
}
|
1331
|
+
}
|
1332
|
+
|
1333
|
+
/* convert the start position to material package track edit rate units */
|
1334
|
+
info->startTimecode = (int64_t)(startPosition *
|
1335
|
+
info->editRate.numerator * filePackageEditRate.denominator /
|
1336
|
+
(double)(info->editRate.denominator * filePackageEditRate.numerator) + 0.5);
|
1337
|
+
|
1338
|
+
haveStartTimecode = 1;
|
1339
|
+
break;
|
1340
|
+
}
|
1341
|
+
}
|
1342
|
+
|
1343
|
+
|
1344
|
+
/* get the essence type */
|
1345
|
+
|
1346
|
+
/* using the header partition's essence container label because the label in the FileDescriptor
|
1347
|
+
is sometimes a weak reference to a ContainerDefinition in Avid files and the ContainerDefinition
|
1348
|
+
is not of much use */
|
1349
|
+
if (mxf_get_list_length(&headerPartition->essenceContainers) > 0)
|
1350
|
+
info->essenceContainerLabel = *(mxfUL*)mxf_get_list_element(&headerPartition->essenceContainers, 0);
|
1351
|
+
|
1352
|
+
info->essenceType = get_essence_type(&info->essenceContainerLabel, &info->pictureCodingLabel, avidResolutionID);
|
1353
|
+
|
1354
|
+
|
1355
|
+
|
1356
|
+
/* clean up */
|
1357
|
+
|
1358
|
+
mxf_file_close(&mxfFile);
|
1359
|
+
mxf_free_header_metadata(&headerMetadata);
|
1360
|
+
mxf_free_data_model(&dataModel);
|
1361
|
+
mxf_free_partition(&headerPartition);
|
1362
|
+
mxf_free_list(&list);
|
1363
|
+
mxf_free_list(&taggedValueNames);
|
1364
|
+
mxf_free_list(&taggedValueValues);
|
1365
|
+
|
1366
|
+
return 0;
|
1367
|
+
|
1368
|
+
|
1369
|
+
fail:
|
1370
|
+
|
1371
|
+
mxf_file_close(&mxfFile);
|
1372
|
+
mxf_free_header_metadata(&headerMetadata);
|
1373
|
+
mxf_free_data_model(&dataModel);
|
1374
|
+
mxf_free_partition(&headerPartition);
|
1375
|
+
mxf_free_list(&list);
|
1376
|
+
mxf_free_list(&taggedValueNames);
|
1377
|
+
mxf_free_list(&taggedValueValues);
|
1378
|
+
|
1379
|
+
ami_free_info(info);
|
1380
|
+
|
1381
|
+
return errorCode;
|
1382
|
+
}
|
1383
|
+
|
1384
|
+
void ami_free_info(AvidMXFInfo *info)
|
1385
|
+
{
|
1386
|
+
SAFE_FREE(info->clipName);
|
1387
|
+
SAFE_FREE(info->projectName);
|
1388
|
+
SAFE_FREE(info->physicalPackageName);
|
1389
|
+
SAFE_FREE(info->tracksString);
|
1390
|
+
SAFE_FREE(info->physicalPackageLocator);
|
1391
|
+
|
1392
|
+
if (info->userComments != NULL)
|
1393
|
+
{
|
1394
|
+
free_avid_tagged_values(info->userComments, info->numUserComments);
|
1395
|
+
}
|
1396
|
+
|
1397
|
+
if (info->materialPackageAttributes != NULL)
|
1398
|
+
{
|
1399
|
+
free_avid_tagged_values(info->materialPackageAttributes, info->numMaterialPackageAttributes);
|
1400
|
+
}
|
1401
|
+
}
|
1402
|
+
|
1403
|
+
void ami_print_info(AvidMXFInfo *info)
|
1404
|
+
{
|
1405
|
+
int i, j;
|
1406
|
+
|
1407
|
+
printf("Project name = %s\n", (info->projectName == NULL) ? "": info->projectName);
|
1408
|
+
printf("Project edit rate = %d/%d\n", info->projectEditRate.numerator, info->projectEditRate.denominator);
|
1409
|
+
printf("Clip name = %s\n", (info->clipName == NULL) ? "": info->clipName);
|
1410
|
+
printf("Clip created = ");
|
1411
|
+
print_timestamp(&info->clipCreated);
|
1412
|
+
printf("\n");
|
1413
|
+
printf("Clip edit rate = %d/%d\n", info->projectEditRate.numerator, info->projectEditRate.denominator);
|
1414
|
+
printf("Clip duration = %"PRId64" samples (", info->clipDuration);
|
1415
|
+
print_timecode(info->clipDuration, &info->projectEditRate);
|
1416
|
+
printf(")\n");
|
1417
|
+
printf("Clip video tracks = %d\n", info->numVideoTracks);
|
1418
|
+
printf("Clip audio tracks = %d\n", info->numAudioTracks);
|
1419
|
+
printf("Clip track string = %s\n", (info->tracksString == NULL) ? "" : info->tracksString);
|
1420
|
+
printf("%s essence\n", info->isVideo ? "Video": "Audio");
|
1421
|
+
printf("Essence type = %s\n", get_essence_type_string(info->essenceType, info->projectEditRate));
|
1422
|
+
printf("Essence container label = ");
|
1423
|
+
print_label(&info->essenceContainerLabel);
|
1424
|
+
printf("\n");
|
1425
|
+
printf("Track number = %d\n", info->trackNumber);
|
1426
|
+
printf("Edit rate = %d/%d\n", info->editRate.numerator, info->editRate.denominator);
|
1427
|
+
printf("Track duration = %"PRId64" samples (", info->trackDuration);
|
1428
|
+
print_timecode(convert_length(&info->projectEditRate, &info->editRate, info->trackDuration), &info->projectEditRate);
|
1429
|
+
printf(")\n");
|
1430
|
+
printf("Track segment duration = %"PRId64" samples (", info->segmentDuration);
|
1431
|
+
print_timecode(convert_length(&info->projectEditRate, &info->editRate, info->segmentDuration), &info->projectEditRate);
|
1432
|
+
printf(")\n");
|
1433
|
+
printf("Track segment offset = %"PRId64" samples (", info->segmentOffset);
|
1434
|
+
print_timecode(convert_length(&info->projectEditRate, &info->editRate, info->segmentOffset), &info->projectEditRate);
|
1435
|
+
printf(")\n");
|
1436
|
+
printf("Start timecode = %"PRId64" samples (", info->startTimecode);
|
1437
|
+
print_timecode(convert_length(&info->projectEditRate, &info->editRate, info->startTimecode), &info->projectEditRate);
|
1438
|
+
printf(")\n");
|
1439
|
+
if (info->isVideo)
|
1440
|
+
{
|
1441
|
+
printf("Picture coding label = ");
|
1442
|
+
print_label(&info->pictureCodingLabel);
|
1443
|
+
printf("\n");
|
1444
|
+
printf("Image aspect ratio = %d/%d\n", info->aspectRatio.numerator, info->aspectRatio.denominator);
|
1445
|
+
printf("Stored WxH = %dx%d (%s)\n", info->storedWidth, info->storedHeight, frame_layout_string(info->frameLayout));
|
1446
|
+
printf("Display WxH = %dx%d (%s)\n", info->storedWidth, info->storedHeight, frame_layout_string(info->frameLayout));
|
1447
|
+
}
|
1448
|
+
else
|
1449
|
+
{
|
1450
|
+
printf("Audio sampling rate = %d/%d\n", info->audioSamplingRate.numerator, info->audioSamplingRate.denominator);
|
1451
|
+
printf("Channel count = %d\n", info->channelCount);
|
1452
|
+
printf("Quantization bits = %d\n", info->quantizationBits);
|
1453
|
+
}
|
1454
|
+
if (info->userComments != NULL)
|
1455
|
+
{
|
1456
|
+
printf("User comments:\n");
|
1457
|
+
for (i = 0; i < info->numUserComments; i++)
|
1458
|
+
{
|
1459
|
+
printf(" %s = %s\n", info->userComments[i].name, info->userComments[i].value);
|
1460
|
+
for (j = 0; j < info->userComments[i].numAttributes; j++)
|
1461
|
+
{
|
1462
|
+
printf(" %s = %s\n", info->userComments[i].attributes[j].name, info->userComments[i].attributes[j].value);
|
1463
|
+
}
|
1464
|
+
}
|
1465
|
+
}
|
1466
|
+
if (info->materialPackageAttributes != NULL)
|
1467
|
+
{
|
1468
|
+
printf("Material package attributes:\n");
|
1469
|
+
for (i = 0; i < info->numMaterialPackageAttributes; i++)
|
1470
|
+
{
|
1471
|
+
printf(" %s = %s\n", info->materialPackageAttributes[i].name, info->materialPackageAttributes[i].value);
|
1472
|
+
for (j = 0; j < info->materialPackageAttributes[i].numAttributes; j++)
|
1473
|
+
{
|
1474
|
+
printf(" %s = %s\n", info->materialPackageAttributes[i].attributes[j].name, info->materialPackageAttributes[i].attributes[j].value);
|
1475
|
+
}
|
1476
|
+
}
|
1477
|
+
}
|
1478
|
+
printf("Material package UID = ");
|
1479
|
+
print_umid(&info->materialPackageUID);
|
1480
|
+
printf("\n");
|
1481
|
+
printf("File package UID = ");
|
1482
|
+
print_umid(&info->fileSourcePackageUID);
|
1483
|
+
printf("\n");
|
1484
|
+
printf("Physical package UID = ");
|
1485
|
+
print_umid(&info->physicalSourcePackageUID);
|
1486
|
+
printf("\n");
|
1487
|
+
printf("Physical package type = ");
|
1488
|
+
switch (info->physicalPackageType)
|
1489
|
+
{
|
1490
|
+
case TAPE_PHYS_TYPE:
|
1491
|
+
printf("Tape");
|
1492
|
+
break;
|
1493
|
+
case IMPORT_PHYS_TYPE:
|
1494
|
+
printf("Import");
|
1495
|
+
break;
|
1496
|
+
case RECORDING_PHYS_TYPE:
|
1497
|
+
printf("Recording");
|
1498
|
+
break;
|
1499
|
+
case UNKNOWN_PHYS_TYPE:
|
1500
|
+
default:
|
1501
|
+
break;
|
1502
|
+
}
|
1503
|
+
printf("\n");
|
1504
|
+
printf("Physical package name = %s\n", (info->physicalPackageName == NULL) ? "": info->physicalPackageName);
|
1505
|
+
printf("Physical package locator = %s\n", (info->physicalPackageLocator == NULL) ? "": info->physicalPackageLocator);
|
1506
|
+
}
|
1507
|
+
|