1 /*
2 * MXF muxer
3 * Copyright (c) 2008 GUCAS, Zhentan Feng <spyfeng at gmail dot com>
4 * Copyright (c) 2008 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /*
24 * References
25 * SMPTE 336M KLV Data Encoding Protocol Using Key-Length-Value
26 * SMPTE 377M MXF File Format Specifications
27 * SMPTE 379M MXF Generic Container
28 * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container
29 * SMPTE RP210: SMPTE Metadata Dictionary
30 * SMPTE RP224: Registry of SMPTE Universal Labels
31 */
32
33 #include <inttypes.h>
34 #include <math.h>
36
48 #include "config.h"
49
51
52 #define EDIT_UNITS_PER_BODY 250
54
59
66
70 int index;
///< index in mxf_essence_container_uls table
72 int order;
///< interleaving order if dts are equal
78 int closed_gop;
///< gop is closed, used in mpeg-2 frame parsing
81
88
89 static const struct {
99 };
100
106
108 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 },
109 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
110 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x00,0x00,0x00 },
112 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x03,0x00 },
113 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x03,0x00 },
114 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
116 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 },
117 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x01,0x00 },
118 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
120 // D-10 625/50 PAL 50mb/s
121 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 },
122 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
123 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 },
125 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 },
126 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
127 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
129 // D-10 525/60 NTSC 50mb/s
130 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 },
131 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
132 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x02 },
134 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 },
135 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
136 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
138 // D-10 625/50 PAL 40mb/s
139 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 },
140 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
141 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x03 },
143 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 },
144 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
145 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
147 // D-10 525/60 NTSC 40mb/s
148 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 },
149 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
150 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x04 },
152 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 },
153 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
154 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
156 // D-10 625/50 PAL 30mb/s
157 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 },
158 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
159 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x05 },
161 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 },
162 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
163 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
165 // D-10 525/60 NTSC 30mb/s
166 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 },
167 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
168 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x06 },
170 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 },
171 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
172 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
174 // DV Unknown
175 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x7F,0x01 },
176 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
177 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x00,0x00,0x00 },
179 // DV25 525/60
180 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x40,0x01 },
181 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
182 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x01,0x00 },
184 // DV25 625/50
185 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,0x01 },
186 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
187 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x02,0x00 },
189 // DV50 525/60
190 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x50,0x01 },
191 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
192 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x03,0x00 },
194 // DV50 625/50
195 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x51,0x01 },
196 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
197 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x04,0x00 },
199 // DV100 1080/60
200 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x60,0x01 },
201 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
202 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x05,0x00 },
204 // DV100 1080/50
205 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x61,0x01 },
206 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
207 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x06,0x00 },
209 // DV100 720/60
210 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x62,0x01 },
211 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
212 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x07,0x00 },
214 // DV100 720/50
215 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x63,0x01 },
216 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
217 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x08,0x00 },
219 // DNxHD 1080p 10bit high
220 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
221 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
222 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x01,0x00,0x00 },
224 // DNxHD 1080p 8bit medium
225 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
226 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
227 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x03,0x00,0x00 },
229 // DNxHD 1080p 8bit high
230 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
231 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
232 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x04,0x00,0x00 },
234 // DNxHD 1080i 10bit high
235 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
236 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
237 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x07,0x00,0x00 },
239 // DNxHD 1080i 8bit medium
240 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
241 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
242 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x08,0x00,0x00 },
244 // DNxHD 1080i 8bit high
245 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
246 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
247 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x09,0x00,0x00 },
249 // DNxHD 720p 10bit
250 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
251 { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
252 { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x10,0x00,0x00 },
254 // DNxHD 720p 8bit high
255 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
256 { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
257 { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x11,0x00,0x00 },
259 // DNxHD 720p 8bit medium
260 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
261 { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
262 { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x12,0x00,0x00 },
264 // DNxHD 720p 8bit low
265 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
266 { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
267 { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x13,0x00,0x00 },
269 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
270 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
271 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
272 NULL },
273 };
274
283 uint64_t
timestamp;
///< timestamp, as year(16),month(8),day(8),hour(8),minutes(8),msec/4(8)
298
299 static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd };
300 static const uint8_t umid_ul[] = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13 };
301
302 /**
303 * complete key for operation pattern, partitions, and primer pack
304 */
305 static const uint8_t op1a_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x01,0x09,0x00 };
306 static const uint8_t footer_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x04,0x04,0x00 };
// ClosedComplete
307 static const uint8_t primer_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x05,0x01,0x00 };
308 static const uint8_t index_table_segment_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 };
309 static const uint8_t random_index_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x11,0x01,0x00 };
310 static const uint8_t header_open_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x01,0x00 };
// OpenIncomplete
311 static const uint8_t header_closed_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x04,0x00 };
// ClosedComplete
312 static const uint8_t klv_fill_key[] = { 0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x03,0x01,0x02,0x10,0x01,0x00,0x00,0x00 };
313 static const uint8_t body_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x03,0x04,0x00 };
// ClosedComplete
314
315 /**
316 * partial key for header metadata
317 */
318 static const uint8_t header_metadata_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01 };
319 static const uint8_t multiple_desc_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x0D,0x01,0x03,0x01,0x02,0x7F,0x01,0x00 };
320
321 /**
322 * SMPTE RP210 http://www.smpte-ra.org/mdd/index.html
323 */
325 // preface set
326 { 0x3C0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x02,0x00,0x00,0x00,0x00}}, /* Instance UID */
327 { 0x3B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x04,0x00,0x00}}, /* Last Modified Date */
328 { 0x3B05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x05,0x00,0x00,0x00}}, /* Version */
329 { 0x3B06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x04,0x00,0x00}}, /* Identifications reference */
330 { 0x3B03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x01,0x00,0x00}}, /* Content Storage reference */
331 { 0x3B09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x03,0x00,0x00,0x00,0x00}}, /* Operational Pattern UL */
332 { 0x3B0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x01,0x00,0x00}}, /* Essence Containers UL batch */
333 { 0x3B0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x02,0x00,0x00}}, /* DM Schemes UL batch */
334 // Identification
335 { 0x3C09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x01,0x00,0x00,0x00}}, /* This Generation UID */
336 { 0x3C01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x02,0x01,0x00,0x00}}, /* Company Name */
337 { 0x3C02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x03,0x01,0x00,0x00}}, /* Product Name */
338 { 0x3C04, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x05,0x01,0x00,0x00}}, /* Version String */
339 { 0x3C05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x07,0x00,0x00,0x00}}, /* Product ID */
340 { 0x3C06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x03,0x00,0x00}}, /* Modification Date */
341 // Content Storage
342 { 0x1901, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x01,0x00,0x00}}, /* Package strong reference batch */
343 { 0x1902, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x02,0x00,0x00}}, /* Package strong reference batch */
344 // Essence Container Data
345 { 0x2701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x06,0x01,0x00,0x00,0x00}}, /* Linked Package UID */
346 { 0x3F07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x04,0x00,0x00,0x00,0x00}}, /* BodySID */
347 // Package
348 { 0x4401, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x10,0x00,0x00,0x00,0x00}}, /* Package UID */
349 { 0x4405, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x01,0x03,0x00,0x00}}, /* Package Creation Date */
350 { 0x4404, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x05,0x00,0x00}}, /* Package Modified Date */
351 { 0x4403, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x05,0x00,0x00}}, /* Tracks Strong reference array */
352 { 0x4701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x03,0x00,0x00}}, /* Descriptor */
353 // Track
354 { 0x4801, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x07,0x01,0x01,0x00,0x00,0x00,0x00}}, /* Track ID */
355 { 0x4804, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x04,0x01,0x03,0x00,0x00,0x00,0x00}}, /* Track Number */
356 { 0x4B01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x30,0x04,0x05,0x00,0x00,0x00,0x00}}, /* Edit Rate */
357 { 0x4B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x03,0x00,0x00}}, /* Origin */
358 { 0x4803, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x04,0x00,0x00}}, /* Sequence reference */
359 // Sequence
360 { 0x0201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x07,0x01,0x00,0x00,0x00,0x00,0x00}}, /* Data Definition UL */
361 { 0x0202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x02,0x01,0x01,0x03,0x00,0x00}}, /* Duration */
362 { 0x1001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x09,0x00,0x00}}, /* Structural Components reference array */
363 // Source Clip
364 { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x04,0x00,0x00}}, /* Start position */
365 { 0x1101, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x01,0x00,0x00,0x00}}, /* SourcePackageID */
366 { 0x1102, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x02,0x00,0x00,0x00}}, /* SourceTrackID */
367 // Timecode Component
368 { 0x1501, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x05,0x00,0x00}}, /* Start Time Code */
369 { 0x1502, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x04,0x01,0x01,0x02,0x06,0x00,0x00}}, /* Rounded Time Code Base */
370 { 0x1503, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x04,0x01,0x01,0x05,0x00,0x00,0x00}}, /* Drop Frame */
371 // File Descriptor
372 { 0x3F01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x04,0x06,0x0B,0x00,0x00}}, /* Sub Descriptors reference array */
373 { 0x3006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x06,0x01,0x01,0x03,0x05,0x00,0x00,0x00}}, /* Linked Track ID */
374 { 0x3001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x00,0x00,0x00,0x00}}, /* SampleRate */
375 { 0x3004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x02,0x00,0x00}}, /* Essence Container */
376 // Generic Picture Essence Descriptor
377 { 0x320C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Frame Layout */
378 { 0x320D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x02,0x05,0x00,0x00,0x00}}, /* Video Line Map */
379 { 0x3203, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x02,0x00,0x00,0x00}}, /* Stored Width */
380 { 0x3202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00}}, /* Stored Height */
381 { 0x3209, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0C,0x00,0x00,0x00}}, /* Display Width */
382 { 0x3208, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0B,0x00,0x00,0x00}}, /* Display Height */
383 { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, /* Aspect Ratio */
384 { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Picture Essence Coding */
385 { 0x3212, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x01,0x06,0x00,0x00,0x00}}, /* Field Dominance (Opt) */
386 // CDCI Picture Essence Descriptor
387 { 0x3301, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x03,0x0A,0x00,0x00,0x00}}, /* Component Depth */
388 { 0x3302, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x05,0x00,0x00,0x00}}, /* Horizontal Subsampling */
389 // Generic Sound Essence Descriptor
390 { 0x3D02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Locked/Unlocked */
391 { 0x3D03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x01,0x01,0x01,0x00,0x00}}, /* Audio sampling rate */
392 { 0x3D07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x01,0x01,0x04,0x00,0x00,0x00}}, /* ChannelCount */
393 { 0x3D01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x03,0x04,0x00,0x00,0x00}}, /* Quantization bits */
394 { 0x3D06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x02,0x04,0x02,0x00,0x00,0x00,0x00}}, /* Sound Essence Compression */
395 // Index Table Segment
396 { 0x3F0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x05,0x30,0x04,0x06,0x00,0x00,0x00,0x00}}, /* Index Edit Rate */
397 { 0x3F0C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x01,0x03,0x01,0x0A,0x00,0x00}}, /* Index Start Position */
398 { 0x3F0D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x02,0x01,0x01,0x02,0x00,0x00}}, /* Index Duration */
399 { 0x3F05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x06,0x02,0x01,0x00,0x00,0x00,0x00}}, /* Edit Unit Byte Count */
400 { 0x3F06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x05,0x00,0x00,0x00,0x00}}, /* IndexSID */
401 { 0x3F08, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x04,0x04,0x01,0x01,0x00,0x00,0x00}}, /* Slice Count */
402 { 0x3F09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x01,0x06,0x00,0x00,0x00}}, /* Delta Entry Array */
403 { 0x3F0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x02,0x05,0x00,0x00,0x00}}, /* Index Entry Array */
404 // MPEG video Descriptor
405 { 0x8000, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0B,0x00,0x00}}, /* BitRate */
406 { 0x8007, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0A,0x00,0x00}}, /* ProfileAndLevel */
407 // Wave Audio Essence Descriptor
408 { 0x3D09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x03,0x05,0x00,0x00,0x00}}, /* Average Bytes Per Second */
409 { 0x3D0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x02,0x01,0x00,0x00,0x00}}, /* Block Align */
410 };
411
413 {
417 }
418
420 {
426 }
427
429 {
432 }
433
435 {
436 if (len < 128)
437 return 1;
438 else
439 return (
av_log2(len) >> 3) + 2;
440 }
441
443 {
444 // Determine the best BER size
446 if (len < 128) {
447 //short form
449 return 1;
450 }
451
452 size = (
av_log2(len) >> 3) + 1;
453
454 // long form
456 while(size) {
457 size--;
458 avio_w8(pb, len >> 8 * size & 0xff);
459 }
460 return 0;
461 }
462
464 {
467 }
468
469 /*
470 * Get essence container ul index
471 */
473 {
474 int i;
478 return -1;
479 }
480
482 {
484 int local_tag_number, i = 0;
485
487
490
491 avio_wb32(pb, local_tag_number);
// local_tag num
492 avio_wb32(pb, 18);
// item size, always 18 according to the specs
493
494 for (i = 0; i < local_tag_number; i++) {
495 avio_wb16(pb, mxf_local_tag_batch[i].local_tag);
496 avio_write(pb, mxf_local_tag_batch[i].uid, 16);
497 }
498 }
499
501 {
504 }
505
507 {
510 }
511
513 {
514 int i;
515
519 }
520 }
521
523 {
525 while (uls->
uid[0]) {
527 break;
528 uls++;
529 }
530 return uls;
531 }
532
533 //one EC -> one descriptor. N ECs -> MultipleDescriptor + N descriptors
534 #define DESCRIPTOR_COUNT(essence_container_count) \
535 (essence_container_count > 1 ? essence_container_count + 1 : essence_container_count)
536
538 {
541 int i;
542
548 }
549
552 }
553
555 {
558
562
563 // write preface set uid
567
568 // last modified date
571
572 // write version
575
576 // write identification_refs
580
581 // write content_storage_refs
584
585 // operational pattern
588
589 // write essence_container_refs
592
593 // write dm_scheme_refs
596 }
597
598 /*
599 * Write a local tag containing an ascii string as utf-16
600 */
602 {
603 int i,
size = strlen(value);
605 for (i = 0; i <
size; i++)
607 }
608
610 {
613 const char *company = "FFmpeg";
614 const char *product = "OP1a Muxer";
617
620
623 length = 84 + (strlen(company)+strlen(product)+strlen(version))*2; // utf-16
625
626 // write uid
630
631 // write generation uid
634
638
639 // write product uid
642
643 // modification date
646 }
647
649 {
651
655
656 // write uid
660
661 // write package reference
666
667 // write essence container data
671 }
672
674 {
678
682
683 // write track uid
687
688 // write track id
691
692 // write track number
695 avio_wb32(pb, 0);
// track number of material package is 0
696 else
698
702
703 // write origin
706
707 // write sequence refs
710 }
711
712 static const uint8_t smpte_12m_timecode_track_data_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x01,0x01,0x00,0x00,0x00 };
713
715 {
718
719 // find data define uls
723 else {
726 }
727
728 // write duration
731 }
732
734 {
738
742
745
748
749 // write structural component
754 else
759 }
760
762 {
765
768
769 // UID
773
775
776 // Start Time Code
779
780 // Rounded Time Code Base
783
784 // Drop Frame
787 }
788
790 {
792 int i;
793
797
798 // write uid
801
804
805 // write start_position
808
809 // write source package uid, end of the reference
812 for (i = 0; i < 4; i++)
814 } else
816
817 // write source track id
821 else
823 }
824
826 {
830 int i;
831
835
839
840 // write sample rate
844
845 // write essence container ul
849 else {
852 }
854
855 // write sub descriptor refs
860 }
861
863 {
867
870
873
876
880
883 }
884
885 static const UID mxf_mpegvideo_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 };
886 static const UID mxf_wav_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 };
887 static const UID mxf_aes3_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 };
888 static const UID mxf_cdci_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x28,0x00 };
889 static const UID mxf_generic_sound_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x42,0x00 };
890
892 {
896 int display_height;
897 int f1, f2;
898 unsigned desc_size = size+8+8+8+8+8+8+5+16+sc->
interlaced*4+12+20;
900 desc_size += 5;
901
903
906
909
912
914 display_height = 576;
916 display_height = 486;
917 else
919
922
923 // component depth
926
927 // horizontal subsampling
930
931 // frame layout
934
935 // video line map
938 case 608: f1 = 7; f2 = 320; break;
940 case 512: f1 = 7; f2 = 270; break;
941 case 720: f1 = 26; f2 = 0; break; // progressive
942 case 1080: f1 = 21; f2 = 584; break;
943 default: f1 = 0; f2 = 0; break;
944 }
945
947 f2 = 0;
948 f1 *= 2;
949 }
950
957
961
964
968 }
969
970 }
971
973 {
975 }
976
978 {
982
984
985 // bit rate
988
989 // profile and level
992 profile_and_level |= 0x80; // escape bit
993 avio_w8(pb, profile_and_level);
994 }
995
997 {
999
1001
1002 // audio locked
1005
1006 // write audio sampling rate
1010
1013
1016 }
1017
1019 {
1021
1023
1026
1027 // avg bytes per sec
1030 }
1031
1033 {
1035 }
1036
1038 {
1040 }
1041
1043 {
1045 }
1046
1048 {
1052
1057 } else {
1061 }
1062
1063 // write uid
1068
1069 // write package umid
1073
1074 // package creation date
1077
1078 // package modified date
1081
1082 // write track refs
1089
1090 // write multiple descriptor reference
1096 } else
1098 }
1099
1100 // write timecode track
1104
1110
1114 }
1115 }
1116 }
1117
1119 {
1121
1124
1127
1130
1133
1136
1137 return 0;
1138 }
1139
1141 {
1148 return 0;
1149 }
1150
1152 {
1154 if (pad < 20) // smallest fill item possible
1156 else
1157 return pad & (KAG_SIZE-1);
1158 }
1159
1161 {
1164 int i, j, temporal_reordering = 0;
1166
1168
1170 return;
1171
1173
1176 } else {
1179 }
1180
1181 // instance id
1184
1185 // index edit rate
1189
1190 // index start position
1193
1194 // index duration
1197 avio_wb64(pb, 0);
// index table covers whole container
1198 else
1200
1201 // edit unit byte count
1204
1205 // index sid
1208
1209 // body sid
1212
1214 // real slice count - 1
1217
1218 // delta entry array
1222 // write system item delta entry
1224 avio_w8(pb, 0);
// slice entry
1231 temporal_reordering = 1;
1232 if (i == 0) { // video track
1233 avio_w8(pb, 0);
// slice number
1235 } else { // audio track
1239 avio_wb32(pb, (i-1)*audio_frame_size);
// element delta
1240 }
1241 }
1242
1246
1248 int temporal_offset = 0;
1249
1252 key_index = i;
1253 }
1254
1255 if (temporal_reordering) {
1256 int pic_num_in_gop = i - key_index;
1260 break;
1261 }
1264 temporal_offset = j - key_index - pic_num_in_gop;
1265 }
1266 }
1268
1271 } else {
1272 avio_w8(pb, key_index - i);
// key frame offset
1275 }
1276
1281 // stream offset
1285 }
1286
1290 }
1291 }
1292
1294 {
1296 if (pad) {
1298 pad -= 16 + 4;
1302 }
1303 }
1304
1306 int indexsid,
1308 {
1311 int64_t header_byte_count_offset;
1312 unsigned index_byte_count = 0;
1313 uint64_t partition_offset =
avio_tell(pb);
1314 int err;
1315
1317 index_byte_count = 85 + 12+(s->
nb_streams+1)*6 +
1320 index_byte_count = 80;
1321
1322 if (index_byte_count) {
1323 // add encoded ber length
1326 }
1327
1332 return err;
1333 }
1335 }
1336
1337 // write klv
1340
1341 // write partition value
1345
1346 avio_wb64(pb, partition_offset);
// ThisPartition
1347
1352 else
1354
1356
1357 // set offset
1358 header_byte_count_offset =
avio_tell(pb);
1359 avio_wb64(pb, 0);
// headerByteCount, update later
1360
1361 // indexTable
1362 avio_wb64(pb, index_byte_count);
// indexByteCount
1363 avio_wb32(pb, index_byte_count ? indexsid : 0);
// indexSID
1364
1365 // BodyOffset
1368 } else
1370
1372
1373 // operational pattern
1375
1376 // essence container
1378
1379 if (write_metadata) {
1380 // mark the start of the headermetadata and calculate metadata size
1382 unsigned header_byte_count;
1383
1390
1391 // update header_byte_count
1392 avio_seek(pb, header_byte_count_offset, SEEK_SET);
1395 }
1396
1398
1399 return 0;
1400 }
1401
1404 {
1407 int i, cid;
1410
1412 return 1;
1413
1415 return -1;
1416
1417 header_cid = pkt->
data + 0x28;
1418 cid = header_cid[0] << 24 | header_cid[1] << 16 | header_cid[2] << 8 | header_cid[3];
1419
1421 return -1;
1422
1423 switch (cid) {
1424 case 1235:
1427 break;
1428 case 1237:
1430 break;
1431 case 1238:
1433 break;
1434 case 1241:
1437 break;
1438 case 1242:
1440 break;
1441 case 1243:
1443 break;
1444 case 1250:
1447 break;
1448 case 1251:
1450 break;
1451 case 1252:
1453 break;
1454 case 1253:
1456 break;
1457 default:
1458 return -1;
1459 }
1460
1463
1474 }
1475 }
1476
1477 return 1;
1478 }
1479
1481 {
1486
1488 return 1;
1489
1490 // Check for minimal frame size
1491 if (pkt->
size < 120000)
1492 return -1;
1493
1494 vs_pack = pkt->
data + 80*5 + 48;
1495 vsc_pack = pkt->
data + 80*5 + 53;
1496 stype = vs_pack[3] & 0x1f;
1497 pal = (vs_pack[3] >> 5) & 0x1;
1498
1499 if ((vs_pack[2] & 0x07) == 0x02)
1501 else
1503
1505 // TODO: fix dv encoder to set proper FF/FS value in VSC pack
1506 // and set field dominance accordingly
1507 // av_log(s, AV_LOG_DEBUG, "DV vsc pack ff/ss = %x\n", vsc_pack[2] >> 6);
1508
1509 switch (stype) {
1510 case 0x18: // DV100 720p
1511 ul_index = 6 + pal;
1512 frame_size = pal ? 288000 : 240000;
1514 av_log(s,
AV_LOG_ERROR,
"source marked as interlaced but codec profile is progressive\n");
1516 }
1517 break;
1518 case 0x14: // DV100 1080i
1519 ul_index = 4 + pal;
1520 frame_size = pal ? 576000 : 480000;
1521 break;
1522 case 0x04: // DV50
1523 ul_index = 2 + pal;
1524 frame_size = pal ? 288000 : 240000;
1525 break;
1526 default: // DV25
1527 ul_index = 0 + pal;
1528 frame_size = pal ? 144000 : 120000;
1529 }
1530
1531 sc->
index = ul_index + 16;
1533
1544 }
1545 }
1546
1547 return 1;
1548 }
1549
1551 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x10,0x00 }, // MP-ML I-Frame
1552 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, // MP-ML Long GOP
1553 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x02,0x00 }, // 422P-ML I-Frame
1554 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x03,0x00 }, // 422P-ML Long GOP
1555 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x02,0x00 }, // MP-HL I-Frame
1556 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, // MP-HL Long GOP
1557 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, // 422P-HL I-Frame
1558 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x03,0x00 }, // 422P-HL Long GOP
1559 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x02,0x00 }, // MP@H-14 I-Frame
1560 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x03,0x00 }, // MP@H-14 Long GOP
1561 };
1562
1564 {
1566
1567 if (avctx->
profile == 4) {
// Main
1568 if (avctx->
level == 8)
// Main
1570 else if (avctx->
level == 4)
// High
1572 else if (avctx->
level == 6)
// High 14
1574 }
else if (avctx->
profile == 0) {
// 422
1575 if (avctx->
level == 5)
// Main
1577 else if (avctx->
level == 2)
// High
1579 }
1580 return NULL;
1581 }
1582
1585 {
1588 int i;
1589
1590 for(i = 0; i < pkt->
size - 4; i++) {
1591 c = (c<<8) + pkt->
data[i];
1593 if ((pkt->
data[i+1] & 0xf0) == 0x10) {
// seq ext
1596 }
else if (i + 5 < pkt->
size && (pkt->
data[i+1] & 0xf0) == 0x80) {
// pict coding ext
1600 break;
1601 }
1602 } else if (c == 0x1b8) { // gop
1603 if (pkt->
data[i+4]>>6 & 0x01) {
// closed
1605 if (e->
flags & 0x40)
// sequence header present
1606 e->
flags |= 0x80;
// random access
1607 }
1608 } else if (c == 0x1b3) { // seq
1610 switch ((pkt->
data[i+4]>>4) & 0xf) {
1614 default:
1617 }
1618 } else if (c == 0x100) { // pic
1619 int pict_type = (pkt->
data[i+2]>>3) & 0x07;
1621 if (pict_type == 2) { // P frame
1623 sc->
closed_gop = 0;
// reset closed gop, don't matter anymore
1624 } else if (pict_type == 3) { // B frame
1626 e->
flags |= 0x13;
// only backward prediction
1627 else
1630 } else if (!pict_type) {
1632 return 0;
1633 }
1634 }
1635 }
1636 if (s->
oformat != &ff_mxf_d10_muxer)
1639 }
1640
1642 {
1643 struct tm *time = gmtime(×tamp);
1644 if (!time)
1645 return 0;
1646 return (uint64_t)(time->tm_year+1900) << 48 |
1647 (uint64_t)(time->tm_mon+1) << 40 |
1648 (uint64_t) time->tm_mday << 32 |
1649 time->tm_hour << 24 |
1650 time->tm_min << 16 |
1651 time->tm_sec << 8;
1652 }
1653
1655 {
1658 uint64_t umid = seed + 0x5294713400000000LL;
1659
1662
1664 }
1665
1667 {
1673 int64_t timestamp = 0;
1675
1677 return -1;
1678
1682 if (!sc)
1685
1687 av_log(s,
AV_LOG_ERROR,
"there must be exactly one video stream and it must be the first one\n");
1688 return -1;
1689 }
1690
1693 // Default component depth to 8
1697 if (!spf) {
1701 }
1705 if (!tcr)
1707 if (tcr)
1709 else
1711 if (ret < 0)
1714 if (s->
oformat == &ff_mxf_d10_muxer) {
1723 else sc->
index = 13;
1724 } else {
1726 return -1;
1727 }
1728
1735 }
1739 return -1;
1740 }
1742 if (s->
oformat == &ff_mxf_d10_muxer) {
1743 if (st->
index != 1) {
1745 return -1;
1746 }
1750 }
1752 } else
1754 }
1755
1758 if (sc->
index == -1) {
1760 "codec not currently supported in container\n", i);
1761 return -1;
1762 }
1763 }
1764
1766
1770
1771 if (!present[sc->
index])
1773 present[sc->
index]++;
1774 }
1775
1776 if (s->
oformat == &ff_mxf_d10_muxer) {
1778 }
1779
1782
1785 // update element count
1789 else
1791 }
1792
1795 if (timestamp)
1798
1806
1807 if (!spf)
1809
1811 return -1;
1812
1813 return 0;
1814 }
1815
1816 static const uint8_t system_metadata_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x01,0x00 };
1817 static const uint8_t system_metadata_package_set_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x43,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x02,0x01 };
1818
1820 {
1824 uint32_t time_code;
1825
1827
1828 // write system metadata pack
1831 avio_w8(pb, 0x5c);
// UL, user date/time stamp, picture and sound item present
1832 avio_w8(pb, 0x04);
// content package rate
1833 avio_w8(pb, 0x00);
// content package type
1835 avio_wb16(pb, (mxf->
tc.
start + frame) & 0xFFFF);
// continuity count, supposed to overflow
1838 else {
1841 }
1844 avio_wb64(pb, 0);
// creation date/time stamp
1845
1846 avio_w8(pb, 0x81);
// SMPTE 12M time code
1851
1852 // write system metadata package set
1858 }
1859
1861 {
1867 int pad;
1868
1869 packet_size += 16 + 4;
1871
1874
1875 // ensure CBR muxing by padding to correct video frame size
1876 pad = packet_size - pkt->
size - 16 - 4;
1877 if (pad > 20) {
1879 pad -= 16 + 4;
1883 } else {
1886 }
1887 }
1888
1890 {
1896 int i;
1897
1899
1903
1904 while (samples < end) {
1908 sample =
AV_RL24(samples)<< 4;
1909 samples += 3;
1910 } else {
1911 sample =
AV_RL16(samples)<<12;
1912 samples += 2;
1913 }
1915 }
1916 for (; i < 8; i++)
1918 }
1919 }
1920
1922 {
1928 int err;
1929
1935 return err;
1936 }
1937 }
1938
1942 return -1;
1943 }
1947 return -1;
1948 }
1952 return -1;
1953 }
1954 }
1955
1959 return err;
1962 } else {
1964 return err;
1965 }
1967 }
1968
1969 if (st->
index == 0) {
1972 !(ie.
flags & 0x33)) {
// I frame, Gop start
1975 return err;
1978 }
1979
1982
1988 }
1993 }
1994
1997 if (s->
oformat == &ff_mxf_d10_muxer) {
2000 else
2002 } else {
2006 }
2007
2009
2010 return 0;
2011 }
2012
2014 {
2018 int i;
2019
2022
2024 avio_wb32(pb, 1);
// BodySID of header partition
2025 else
2027 avio_wb64(pb, 0);
// offset of header partition
2028
2032 }
2033
2034 avio_wb32(pb, 0);
// BodySID of footer partition
2036
2038 }
2039
2041 {
2044 int err;
2045
2047
2052 return err;
2053 } else {
2055 return err;
2058 }
2059
2062
2067 return err;
2070 } else {
2072 return err;
2073 }
2074 }
2075
2077
2082
2084
2085 return 0;
2086 }
2087
2089 {
2090 int i, stream_count = 0;
2091
2094
2095 if (stream_count && (s->
nb_streams == stream_count || flush)) {
2099 // find last packet in edit unit
2100 while (pktl) {
2102 break;
2103 last = pktl;
2105 stream_count--;
2106 }
2107 // purge packet queue
2108 while (pktl) {
2110
2115 pktl = next;
2116 }
2117 if (last)
2119 else {
2123 }
2125 }
2126
2128 av_dlog(s,
"out st:%d dts:%"PRId64
"\n", (*out).stream_index, (*out).dts);
2135 return 1;
2136 } else {
2137 out:
2139 return 0;
2140 }
2141 }
2142
2144 {
2147
2148 return next->
dts > pkt->
dts ||
2150 }
2151
2153 {
2156 }
2157
2161 .mime_type = "application/mxf",
2162 .extensions = "mxf",
2171 };
2172
2176 .mime_type = "application/mxf",
2185 };