yading@11
|
1 /*
|
yading@11
|
2 * MXF muxer
|
yading@11
|
3 * Copyright (c) 2008 GUCAS, Zhentan Feng <spyfeng at gmail dot com>
|
yading@11
|
4 * Copyright (c) 2008 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
|
yading@11
|
5 *
|
yading@11
|
6 * This file is part of FFmpeg.
|
yading@11
|
7 *
|
yading@11
|
8 * FFmpeg is free software; you can redistribute it and/or
|
yading@11
|
9 * modify it under the terms of the GNU Lesser General Public
|
yading@11
|
10 * License as published by the Free Software Foundation; either
|
yading@11
|
11 * version 2.1 of the License, or (at your option) any later version.
|
yading@11
|
12 *
|
yading@11
|
13 * FFmpeg is distributed in the hope that it will be useful,
|
yading@11
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@11
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@11
|
16 * Lesser General Public License for more details.
|
yading@11
|
17 *
|
yading@11
|
18 * You should have received a copy of the GNU Lesser General Public
|
yading@11
|
19 * License along with FFmpeg; if not, write to the Free Software
|
yading@11
|
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@11
|
21 */
|
yading@11
|
22
|
yading@11
|
23 /*
|
yading@11
|
24 * References
|
yading@11
|
25 * SMPTE 336M KLV Data Encoding Protocol Using Key-Length-Value
|
yading@11
|
26 * SMPTE 377M MXF File Format Specifications
|
yading@11
|
27 * SMPTE 379M MXF Generic Container
|
yading@11
|
28 * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container
|
yading@11
|
29 * SMPTE RP210: SMPTE Metadata Dictionary
|
yading@11
|
30 * SMPTE RP224: Registry of SMPTE Universal Labels
|
yading@11
|
31 */
|
yading@11
|
32
|
yading@11
|
33 //#define DEBUG
|
yading@11
|
34
|
yading@11
|
35 #include <math.h>
|
yading@11
|
36 #include <time.h>
|
yading@11
|
37
|
yading@11
|
38 #include "libavutil/opt.h"
|
yading@11
|
39 #include "libavutil/random_seed.h"
|
yading@11
|
40 #include "libavutil/timecode.h"
|
yading@11
|
41 #include "libavutil/avassert.h"
|
yading@11
|
42 #include "libavcodec/bytestream.h"
|
yading@11
|
43 #include "libavcodec/dnxhddata.h"
|
yading@11
|
44 #include "audiointerleave.h"
|
yading@11
|
45 #include "avformat.h"
|
yading@11
|
46 #include "internal.h"
|
yading@11
|
47 #include "mxf.h"
|
yading@11
|
48 #include "config.h"
|
yading@11
|
49
|
yading@11
|
50 extern AVOutputFormat ff_mxf_d10_muxer;
|
yading@11
|
51
|
yading@11
|
52 #define EDIT_UNITS_PER_BODY 250
|
yading@11
|
53 #define KAG_SIZE 512
|
yading@11
|
54
|
yading@11
|
55 typedef struct {
|
yading@11
|
56 int local_tag;
|
yading@11
|
57 UID uid;
|
yading@11
|
58 } MXFLocalTagPair;
|
yading@11
|
59
|
yading@11
|
60 typedef struct {
|
yading@11
|
61 uint8_t flags;
|
yading@11
|
62 uint64_t offset;
|
yading@11
|
63 unsigned slice_offset; ///< offset of audio slice
|
yading@11
|
64 uint16_t temporal_ref;
|
yading@11
|
65 } MXFIndexEntry;
|
yading@11
|
66
|
yading@11
|
67 typedef struct {
|
yading@11
|
68 AudioInterleaveContext aic;
|
yading@11
|
69 UID track_essence_element_key;
|
yading@11
|
70 int index; ///< index in mxf_essence_container_uls table
|
yading@11
|
71 const UID *codec_ul;
|
yading@11
|
72 int order; ///< interleaving order if dts are equal
|
yading@11
|
73 int interlaced; ///< whether picture is interlaced
|
yading@11
|
74 int field_dominance; ///< tff=1, bff=2
|
yading@11
|
75 int component_depth;
|
yading@11
|
76 int temporal_reordering;
|
yading@11
|
77 AVRational aspect_ratio; ///< display aspect ratio
|
yading@11
|
78 int closed_gop; ///< gop is closed, used in mpeg-2 frame parsing
|
yading@11
|
79 } MXFStreamContext;
|
yading@11
|
80
|
yading@11
|
81 typedef struct {
|
yading@11
|
82 UID container_ul;
|
yading@11
|
83 UID element_ul;
|
yading@11
|
84 UID codec_ul;
|
yading@11
|
85 void (*write_desc)(AVFormatContext *, AVStream *);
|
yading@11
|
86 } MXFContainerEssenceEntry;
|
yading@11
|
87
|
yading@11
|
88 static const struct {
|
yading@11
|
89 enum AVCodecID id;
|
yading@11
|
90 int index;
|
yading@11
|
91 } mxf_essence_mappings[] = {
|
yading@11
|
92 { AV_CODEC_ID_MPEG2VIDEO, 0 },
|
yading@11
|
93 { AV_CODEC_ID_PCM_S24LE, 1 },
|
yading@11
|
94 { AV_CODEC_ID_PCM_S16LE, 1 },
|
yading@11
|
95 { AV_CODEC_ID_DVVIDEO, 15 },
|
yading@11
|
96 { AV_CODEC_ID_DNXHD, 24 },
|
yading@11
|
97 { AV_CODEC_ID_NONE }
|
yading@11
|
98 };
|
yading@11
|
99
|
yading@11
|
100 static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st);
|
yading@11
|
101 static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st);
|
yading@11
|
102 static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st);
|
yading@11
|
103 static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st);
|
yading@11
|
104 static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st);
|
yading@11
|
105
|
yading@11
|
106 static const MXFContainerEssenceEntry mxf_essence_container_uls[] = {
|
yading@11
|
107 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 },
|
yading@11
|
108 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
|
yading@11
|
109 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x00,0x00,0x00 },
|
yading@11
|
110 mxf_write_mpegvideo_desc },
|
yading@11
|
111 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x03,0x00 },
|
yading@11
|
112 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x03,0x00 },
|
yading@11
|
113 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
yading@11
|
114 mxf_write_aes3_desc },
|
yading@11
|
115 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 },
|
yading@11
|
116 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x01,0x00 },
|
yading@11
|
117 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
yading@11
|
118 mxf_write_wav_desc },
|
yading@11
|
119 // D-10 625/50 PAL 50mb/s
|
yading@11
|
120 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 },
|
yading@11
|
121 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
|
yading@11
|
122 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 },
|
yading@11
|
123 mxf_write_cdci_desc },
|
yading@11
|
124 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 },
|
yading@11
|
125 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
|
yading@11
|
126 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
yading@11
|
127 mxf_write_generic_sound_desc },
|
yading@11
|
128 // D-10 525/60 NTSC 50mb/s
|
yading@11
|
129 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 },
|
yading@11
|
130 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
|
yading@11
|
131 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x02 },
|
yading@11
|
132 mxf_write_cdci_desc },
|
yading@11
|
133 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 },
|
yading@11
|
134 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
|
yading@11
|
135 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
yading@11
|
136 mxf_write_generic_sound_desc },
|
yading@11
|
137 // D-10 625/50 PAL 40mb/s
|
yading@11
|
138 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 },
|
yading@11
|
139 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
|
yading@11
|
140 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x03 },
|
yading@11
|
141 mxf_write_cdci_desc },
|
yading@11
|
142 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 },
|
yading@11
|
143 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
|
yading@11
|
144 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
yading@11
|
145 mxf_write_generic_sound_desc },
|
yading@11
|
146 // D-10 525/60 NTSC 40mb/s
|
yading@11
|
147 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 },
|
yading@11
|
148 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
|
yading@11
|
149 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x04 },
|
yading@11
|
150 mxf_write_cdci_desc },
|
yading@11
|
151 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 },
|
yading@11
|
152 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
|
yading@11
|
153 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
yading@11
|
154 mxf_write_generic_sound_desc },
|
yading@11
|
155 // D-10 625/50 PAL 30mb/s
|
yading@11
|
156 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 },
|
yading@11
|
157 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
|
yading@11
|
158 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x05 },
|
yading@11
|
159 mxf_write_cdci_desc },
|
yading@11
|
160 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 },
|
yading@11
|
161 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
|
yading@11
|
162 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
yading@11
|
163 mxf_write_generic_sound_desc },
|
yading@11
|
164 // D-10 525/60 NTSC 30mb/s
|
yading@11
|
165 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 },
|
yading@11
|
166 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
|
yading@11
|
167 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x06 },
|
yading@11
|
168 mxf_write_cdci_desc },
|
yading@11
|
169 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 },
|
yading@11
|
170 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
|
yading@11
|
171 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
yading@11
|
172 mxf_write_generic_sound_desc },
|
yading@11
|
173 // DV Unknown
|
yading@11
|
174 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x7F,0x01 },
|
yading@11
|
175 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
|
yading@11
|
176 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x00,0x00,0x00 },
|
yading@11
|
177 mxf_write_cdci_desc },
|
yading@11
|
178 // DV25 525/60
|
yading@11
|
179 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x40,0x01 },
|
yading@11
|
180 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
|
yading@11
|
181 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x01,0x00 },
|
yading@11
|
182 mxf_write_cdci_desc },
|
yading@11
|
183 // DV25 625/50
|
yading@11
|
184 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,0x01 },
|
yading@11
|
185 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
|
yading@11
|
186 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x02,0x00 },
|
yading@11
|
187 mxf_write_cdci_desc },
|
yading@11
|
188 // DV50 525/60
|
yading@11
|
189 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x50,0x01 },
|
yading@11
|
190 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
|
yading@11
|
191 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x03,0x00 },
|
yading@11
|
192 mxf_write_cdci_desc },
|
yading@11
|
193 // DV50 625/50
|
yading@11
|
194 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x51,0x01 },
|
yading@11
|
195 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
|
yading@11
|
196 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x04,0x00 },
|
yading@11
|
197 mxf_write_cdci_desc },
|
yading@11
|
198 // DV100 1080/60
|
yading@11
|
199 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x60,0x01 },
|
yading@11
|
200 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
|
yading@11
|
201 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x05,0x00 },
|
yading@11
|
202 mxf_write_cdci_desc },
|
yading@11
|
203 // DV100 1080/50
|
yading@11
|
204 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x61,0x01 },
|
yading@11
|
205 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
|
yading@11
|
206 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x06,0x00 },
|
yading@11
|
207 mxf_write_cdci_desc },
|
yading@11
|
208 // DV100 720/60
|
yading@11
|
209 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x62,0x01 },
|
yading@11
|
210 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
|
yading@11
|
211 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x07,0x00 },
|
yading@11
|
212 mxf_write_cdci_desc },
|
yading@11
|
213 // DV100 720/50
|
yading@11
|
214 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x63,0x01 },
|
yading@11
|
215 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
|
yading@11
|
216 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x08,0x00 },
|
yading@11
|
217 mxf_write_cdci_desc },
|
yading@11
|
218 // DNxHD 1080p 10bit high
|
yading@11
|
219 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
|
yading@11
|
220 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
|
yading@11
|
221 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x01,0x00,0x00 },
|
yading@11
|
222 mxf_write_cdci_desc },
|
yading@11
|
223 // DNxHD 1080p 8bit medium
|
yading@11
|
224 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
|
yading@11
|
225 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
|
yading@11
|
226 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x03,0x00,0x00 },
|
yading@11
|
227 mxf_write_cdci_desc },
|
yading@11
|
228 // DNxHD 1080p 8bit high
|
yading@11
|
229 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
|
yading@11
|
230 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
|
yading@11
|
231 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x04,0x00,0x00 },
|
yading@11
|
232 mxf_write_cdci_desc },
|
yading@11
|
233 // DNxHD 1080i 10bit high
|
yading@11
|
234 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
|
yading@11
|
235 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
|
yading@11
|
236 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x07,0x00,0x00 },
|
yading@11
|
237 mxf_write_cdci_desc },
|
yading@11
|
238 // DNxHD 1080i 8bit medium
|
yading@11
|
239 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
|
yading@11
|
240 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
|
yading@11
|
241 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x08,0x00,0x00 },
|
yading@11
|
242 mxf_write_cdci_desc },
|
yading@11
|
243 // DNxHD 1080i 8bit high
|
yading@11
|
244 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
|
yading@11
|
245 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
|
yading@11
|
246 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x09,0x00,0x00 },
|
yading@11
|
247 mxf_write_cdci_desc },
|
yading@11
|
248 // DNxHD 720p 10bit
|
yading@11
|
249 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
|
yading@11
|
250 { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
|
yading@11
|
251 { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x10,0x00,0x00 },
|
yading@11
|
252 mxf_write_cdci_desc },
|
yading@11
|
253 // DNxHD 720p 8bit high
|
yading@11
|
254 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
|
yading@11
|
255 { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
|
yading@11
|
256 { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x11,0x00,0x00 },
|
yading@11
|
257 mxf_write_cdci_desc },
|
yading@11
|
258 // DNxHD 720p 8bit medium
|
yading@11
|
259 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
|
yading@11
|
260 { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
|
yading@11
|
261 { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x12,0x00,0x00 },
|
yading@11
|
262 mxf_write_cdci_desc },
|
yading@11
|
263 // DNxHD 720p 8bit low
|
yading@11
|
264 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
|
yading@11
|
265 { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
|
yading@11
|
266 { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x13,0x00,0x00 },
|
yading@11
|
267 mxf_write_cdci_desc },
|
yading@11
|
268 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
yading@11
|
269 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
yading@11
|
270 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
yading@11
|
271 NULL },
|
yading@11
|
272 };
|
yading@11
|
273
|
yading@11
|
274 typedef struct MXFContext {
|
yading@11
|
275 AVClass *av_class;
|
yading@11
|
276 int64_t footer_partition_offset;
|
yading@11
|
277 int essence_container_count;
|
yading@11
|
278 AVRational time_base;
|
yading@11
|
279 int header_written;
|
yading@11
|
280 MXFIndexEntry *index_entries;
|
yading@11
|
281 unsigned edit_units_count;
|
yading@11
|
282 uint64_t timestamp; ///< timestamp, as year(16),month(8),day(8),hour(8),minutes(8),msec/4(8)
|
yading@11
|
283 uint8_t slice_count; ///< index slice count minus 1 (1 if no audio, 0 otherwise)
|
yading@11
|
284 int last_indexed_edit_unit;
|
yading@11
|
285 uint64_t *body_partition_offset;
|
yading@11
|
286 unsigned body_partitions_count;
|
yading@11
|
287 int last_key_index; ///< index of last key frame
|
yading@11
|
288 uint64_t duration;
|
yading@11
|
289 AVTimecode tc; ///< timecode context
|
yading@11
|
290 AVStream *timecode_track;
|
yading@11
|
291 int timecode_base; ///< rounded time code base (25 or 30)
|
yading@11
|
292 int edit_unit_byte_count; ///< fixed edit unit byte count
|
yading@11
|
293 uint64_t body_offset;
|
yading@11
|
294 uint32_t instance_number;
|
yading@11
|
295 uint8_t umid[16]; ///< unique material identifier
|
yading@11
|
296 } MXFContext;
|
yading@11
|
297
|
yading@11
|
298 static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd };
|
yading@11
|
299 static const uint8_t umid_ul[] = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13 };
|
yading@11
|
300
|
yading@11
|
301 /**
|
yading@11
|
302 * complete key for operation pattern, partitions, and primer pack
|
yading@11
|
303 */
|
yading@11
|
304 static const uint8_t op1a_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x01,0x09,0x00 };
|
yading@11
|
305 static const uint8_t footer_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }; // ClosedComplete
|
yading@11
|
306 static const uint8_t primer_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x05,0x01,0x00 };
|
yading@11
|
307 static const uint8_t index_table_segment_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 };
|
yading@11
|
308 static const uint8_t random_index_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x11,0x01,0x00 };
|
yading@11
|
309 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
|
yading@11
|
310 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
|
yading@11
|
311 static const uint8_t klv_fill_key[] = { 0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x03,0x01,0x02,0x10,0x01,0x00,0x00,0x00 };
|
yading@11
|
312 static const uint8_t body_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x03,0x04,0x00 }; // ClosedComplete
|
yading@11
|
313
|
yading@11
|
314 /**
|
yading@11
|
315 * partial key for header metadata
|
yading@11
|
316 */
|
yading@11
|
317 static const uint8_t header_metadata_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01 };
|
yading@11
|
318 static const uint8_t multiple_desc_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x0D,0x01,0x03,0x01,0x02,0x7F,0x01,0x00 };
|
yading@11
|
319
|
yading@11
|
320 /**
|
yading@11
|
321 * SMPTE RP210 http://www.smpte-ra.org/mdd/index.html
|
yading@11
|
322 */
|
yading@11
|
323 static const MXFLocalTagPair mxf_local_tag_batch[] = {
|
yading@11
|
324 // preface set
|
yading@11
|
325 { 0x3C0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x02,0x00,0x00,0x00,0x00}}, /* Instance UID */
|
yading@11
|
326 { 0x3B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x04,0x00,0x00}}, /* Last Modified Date */
|
yading@11
|
327 { 0x3B05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x05,0x00,0x00,0x00}}, /* Version */
|
yading@11
|
328 { 0x3B06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x04,0x00,0x00}}, /* Identifications reference */
|
yading@11
|
329 { 0x3B03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x01,0x00,0x00}}, /* Content Storage reference */
|
yading@11
|
330 { 0x3B09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x03,0x00,0x00,0x00,0x00}}, /* Operational Pattern UL */
|
yading@11
|
331 { 0x3B0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x01,0x00,0x00}}, /* Essence Containers UL batch */
|
yading@11
|
332 { 0x3B0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x02,0x00,0x00}}, /* DM Schemes UL batch */
|
yading@11
|
333 // Identification
|
yading@11
|
334 { 0x3C09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x01,0x00,0x00,0x00}}, /* This Generation UID */
|
yading@11
|
335 { 0x3C01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x02,0x01,0x00,0x00}}, /* Company Name */
|
yading@11
|
336 { 0x3C02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x03,0x01,0x00,0x00}}, /* Product Name */
|
yading@11
|
337 { 0x3C04, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x05,0x01,0x00,0x00}}, /* Version String */
|
yading@11
|
338 { 0x3C05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x07,0x00,0x00,0x00}}, /* Product ID */
|
yading@11
|
339 { 0x3C06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x03,0x00,0x00}}, /* Modification Date */
|
yading@11
|
340 // Content Storage
|
yading@11
|
341 { 0x1901, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x01,0x00,0x00}}, /* Package strong reference batch */
|
yading@11
|
342 { 0x1902, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x02,0x00,0x00}}, /* Package strong reference batch */
|
yading@11
|
343 // Essence Container Data
|
yading@11
|
344 { 0x2701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x06,0x01,0x00,0x00,0x00}}, /* Linked Package UID */
|
yading@11
|
345 { 0x3F07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x04,0x00,0x00,0x00,0x00}}, /* BodySID */
|
yading@11
|
346 // Package
|
yading@11
|
347 { 0x4401, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x10,0x00,0x00,0x00,0x00}}, /* Package UID */
|
yading@11
|
348 { 0x4405, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x01,0x03,0x00,0x00}}, /* Package Creation Date */
|
yading@11
|
349 { 0x4404, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x05,0x00,0x00}}, /* Package Modified Date */
|
yading@11
|
350 { 0x4403, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x05,0x00,0x00}}, /* Tracks Strong reference array */
|
yading@11
|
351 { 0x4701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x03,0x00,0x00}}, /* Descriptor */
|
yading@11
|
352 // Track
|
yading@11
|
353 { 0x4801, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x07,0x01,0x01,0x00,0x00,0x00,0x00}}, /* Track ID */
|
yading@11
|
354 { 0x4804, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x04,0x01,0x03,0x00,0x00,0x00,0x00}}, /* Track Number */
|
yading@11
|
355 { 0x4B01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x30,0x04,0x05,0x00,0x00,0x00,0x00}}, /* Edit Rate */
|
yading@11
|
356 { 0x4B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x03,0x00,0x00}}, /* Origin */
|
yading@11
|
357 { 0x4803, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x04,0x00,0x00}}, /* Sequence reference */
|
yading@11
|
358 // Sequence
|
yading@11
|
359 { 0x0201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x07,0x01,0x00,0x00,0x00,0x00,0x00}}, /* Data Definition UL */
|
yading@11
|
360 { 0x0202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x02,0x01,0x01,0x03,0x00,0x00}}, /* Duration */
|
yading@11
|
361 { 0x1001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x09,0x00,0x00}}, /* Structural Components reference array */
|
yading@11
|
362 // Source Clip
|
yading@11
|
363 { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x04,0x00,0x00}}, /* Start position */
|
yading@11
|
364 { 0x1101, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x01,0x00,0x00,0x00}}, /* SourcePackageID */
|
yading@11
|
365 { 0x1102, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x02,0x00,0x00,0x00}}, /* SourceTrackID */
|
yading@11
|
366 // Timecode Component
|
yading@11
|
367 { 0x1501, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x05,0x00,0x00}}, /* Start Time Code */
|
yading@11
|
368 { 0x1502, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x04,0x01,0x01,0x02,0x06,0x00,0x00}}, /* Rounded Time Code Base */
|
yading@11
|
369 { 0x1503, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x04,0x01,0x01,0x05,0x00,0x00,0x00}}, /* Drop Frame */
|
yading@11
|
370 // File Descriptor
|
yading@11
|
371 { 0x3F01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x04,0x06,0x0B,0x00,0x00}}, /* Sub Descriptors reference array */
|
yading@11
|
372 { 0x3006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x06,0x01,0x01,0x03,0x05,0x00,0x00,0x00}}, /* Linked Track ID */
|
yading@11
|
373 { 0x3001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x00,0x00,0x00,0x00}}, /* SampleRate */
|
yading@11
|
374 { 0x3004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x02,0x00,0x00}}, /* Essence Container */
|
yading@11
|
375 // Generic Picture Essence Descriptor
|
yading@11
|
376 { 0x320C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Frame Layout */
|
yading@11
|
377 { 0x320D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x02,0x05,0x00,0x00,0x00}}, /* Video Line Map */
|
yading@11
|
378 { 0x3203, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x02,0x00,0x00,0x00}}, /* Stored Width */
|
yading@11
|
379 { 0x3202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00}}, /* Stored Height */
|
yading@11
|
380 { 0x3209, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0C,0x00,0x00,0x00}}, /* Display Width */
|
yading@11
|
381 { 0x3208, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0B,0x00,0x00,0x00}}, /* Display Height */
|
yading@11
|
382 { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, /* Aspect Ratio */
|
yading@11
|
383 { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Picture Essence Coding */
|
yading@11
|
384 { 0x3212, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x01,0x06,0x00,0x00,0x00}}, /* Field Dominance (Opt) */
|
yading@11
|
385 // CDCI Picture Essence Descriptor
|
yading@11
|
386 { 0x3301, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x03,0x0A,0x00,0x00,0x00}}, /* Component Depth */
|
yading@11
|
387 { 0x3302, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x05,0x00,0x00,0x00}}, /* Horizontal Subsampling */
|
yading@11
|
388 // Generic Sound Essence Descriptor
|
yading@11
|
389 { 0x3D02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Locked/Unlocked */
|
yading@11
|
390 { 0x3D03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x01,0x01,0x01,0x00,0x00}}, /* Audio sampling rate */
|
yading@11
|
391 { 0x3D07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x01,0x01,0x04,0x00,0x00,0x00}}, /* ChannelCount */
|
yading@11
|
392 { 0x3D01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x03,0x04,0x00,0x00,0x00}}, /* Quantization bits */
|
yading@11
|
393 { 0x3D06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x02,0x04,0x02,0x00,0x00,0x00,0x00}}, /* Sound Essence Compression */
|
yading@11
|
394 // Index Table Segment
|
yading@11
|
395 { 0x3F0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x05,0x30,0x04,0x06,0x00,0x00,0x00,0x00}}, /* Index Edit Rate */
|
yading@11
|
396 { 0x3F0C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x01,0x03,0x01,0x0A,0x00,0x00}}, /* Index Start Position */
|
yading@11
|
397 { 0x3F0D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x02,0x01,0x01,0x02,0x00,0x00}}, /* Index Duration */
|
yading@11
|
398 { 0x3F05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x06,0x02,0x01,0x00,0x00,0x00,0x00}}, /* Edit Unit Byte Count */
|
yading@11
|
399 { 0x3F06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x05,0x00,0x00,0x00,0x00}}, /* IndexSID */
|
yading@11
|
400 { 0x3F08, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x04,0x04,0x01,0x01,0x00,0x00,0x00}}, /* Slice Count */
|
yading@11
|
401 { 0x3F09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x01,0x06,0x00,0x00,0x00}}, /* Delta Entry Array */
|
yading@11
|
402 { 0x3F0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x02,0x05,0x00,0x00,0x00}}, /* Index Entry Array */
|
yading@11
|
403 // MPEG video Descriptor
|
yading@11
|
404 { 0x8000, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0B,0x00,0x00}}, /* BitRate */
|
yading@11
|
405 { 0x8007, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0A,0x00,0x00}}, /* ProfileAndLevel */
|
yading@11
|
406 // Wave Audio Essence Descriptor
|
yading@11
|
407 { 0x3D09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x03,0x05,0x00,0x00,0x00}}, /* Average Bytes Per Second */
|
yading@11
|
408 { 0x3D0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x02,0x01,0x00,0x00,0x00}}, /* Block Align */
|
yading@11
|
409 };
|
yading@11
|
410
|
yading@11
|
411 static void mxf_write_uuid(AVIOContext *pb, enum MXFMetadataSetType type, int value)
|
yading@11
|
412 {
|
yading@11
|
413 avio_write(pb, uuid_base, 12);
|
yading@11
|
414 avio_wb16(pb, type);
|
yading@11
|
415 avio_wb16(pb, value);
|
yading@11
|
416 }
|
yading@11
|
417
|
yading@11
|
418 static void mxf_write_umid(AVFormatContext *s, int type)
|
yading@11
|
419 {
|
yading@11
|
420 MXFContext *mxf = s->priv_data;
|
yading@11
|
421 avio_write(s->pb, umid_ul, 13);
|
yading@11
|
422 avio_wb24(s->pb, mxf->instance_number);
|
yading@11
|
423 avio_write(s->pb, mxf->umid, 15);
|
yading@11
|
424 avio_w8(s->pb, type);
|
yading@11
|
425 }
|
yading@11
|
426
|
yading@11
|
427 static void mxf_write_refs_count(AVIOContext *pb, int ref_count)
|
yading@11
|
428 {
|
yading@11
|
429 avio_wb32(pb, ref_count);
|
yading@11
|
430 avio_wb32(pb, 16);
|
yading@11
|
431 }
|
yading@11
|
432
|
yading@11
|
433 static int klv_ber_length(uint64_t len)
|
yading@11
|
434 {
|
yading@11
|
435 if (len < 128)
|
yading@11
|
436 return 1;
|
yading@11
|
437 else
|
yading@11
|
438 return (av_log2(len) >> 3) + 2;
|
yading@11
|
439 }
|
yading@11
|
440
|
yading@11
|
441 static int klv_encode_ber_length(AVIOContext *pb, uint64_t len)
|
yading@11
|
442 {
|
yading@11
|
443 // Determine the best BER size
|
yading@11
|
444 int size;
|
yading@11
|
445 if (len < 128) {
|
yading@11
|
446 //short form
|
yading@11
|
447 avio_w8(pb, len);
|
yading@11
|
448 return 1;
|
yading@11
|
449 }
|
yading@11
|
450
|
yading@11
|
451 size = (av_log2(len) >> 3) + 1;
|
yading@11
|
452
|
yading@11
|
453 // long form
|
yading@11
|
454 avio_w8(pb, 0x80 + size);
|
yading@11
|
455 while(size) {
|
yading@11
|
456 size--;
|
yading@11
|
457 avio_w8(pb, len >> 8 * size & 0xff);
|
yading@11
|
458 }
|
yading@11
|
459 return 0;
|
yading@11
|
460 }
|
yading@11
|
461
|
yading@11
|
462 static void klv_encode_ber4_length(AVIOContext *pb, int len)
|
yading@11
|
463 {
|
yading@11
|
464 avio_w8(pb, 0x80 + 3);
|
yading@11
|
465 avio_wb24(pb, len);
|
yading@11
|
466 }
|
yading@11
|
467
|
yading@11
|
468 /*
|
yading@11
|
469 * Get essence container ul index
|
yading@11
|
470 */
|
yading@11
|
471 static int mxf_get_essence_container_ul_index(enum AVCodecID id)
|
yading@11
|
472 {
|
yading@11
|
473 int i;
|
yading@11
|
474 for (i = 0; mxf_essence_mappings[i].id; i++)
|
yading@11
|
475 if (mxf_essence_mappings[i].id == id)
|
yading@11
|
476 return mxf_essence_mappings[i].index;
|
yading@11
|
477 return -1;
|
yading@11
|
478 }
|
yading@11
|
479
|
yading@11
|
480 static void mxf_write_primer_pack(AVFormatContext *s)
|
yading@11
|
481 {
|
yading@11
|
482 AVIOContext *pb = s->pb;
|
yading@11
|
483 int local_tag_number, i = 0;
|
yading@11
|
484
|
yading@11
|
485 local_tag_number = FF_ARRAY_ELEMS(mxf_local_tag_batch);
|
yading@11
|
486
|
yading@11
|
487 avio_write(pb, primer_pack_key, 16);
|
yading@11
|
488 klv_encode_ber_length(pb, local_tag_number * 18 + 8);
|
yading@11
|
489
|
yading@11
|
490 avio_wb32(pb, local_tag_number); // local_tag num
|
yading@11
|
491 avio_wb32(pb, 18); // item size, always 18 according to the specs
|
yading@11
|
492
|
yading@11
|
493 for (i = 0; i < local_tag_number; i++) {
|
yading@11
|
494 avio_wb16(pb, mxf_local_tag_batch[i].local_tag);
|
yading@11
|
495 avio_write(pb, mxf_local_tag_batch[i].uid, 16);
|
yading@11
|
496 }
|
yading@11
|
497 }
|
yading@11
|
498
|
yading@11
|
499 static void mxf_write_local_tag(AVIOContext *pb, int size, int tag)
|
yading@11
|
500 {
|
yading@11
|
501 avio_wb16(pb, tag);
|
yading@11
|
502 avio_wb16(pb, size);
|
yading@11
|
503 }
|
yading@11
|
504
|
yading@11
|
505 static void mxf_write_metadata_key(AVIOContext *pb, unsigned int value)
|
yading@11
|
506 {
|
yading@11
|
507 avio_write(pb, header_metadata_key, 13);
|
yading@11
|
508 avio_wb24(pb, value);
|
yading@11
|
509 }
|
yading@11
|
510
|
yading@11
|
511 static void mxf_free(AVFormatContext *s)
|
yading@11
|
512 {
|
yading@11
|
513 int i;
|
yading@11
|
514
|
yading@11
|
515 for (i = 0; i < s->nb_streams; i++) {
|
yading@11
|
516 AVStream *st = s->streams[i];
|
yading@11
|
517 av_freep(&st->priv_data);
|
yading@11
|
518 }
|
yading@11
|
519 }
|
yading@11
|
520
|
yading@11
|
521 static const MXFCodecUL *mxf_get_data_definition_ul(int type)
|
yading@11
|
522 {
|
yading@11
|
523 const MXFCodecUL *uls = ff_mxf_data_definition_uls;
|
yading@11
|
524 while (uls->uid[0]) {
|
yading@11
|
525 if (type == uls->id)
|
yading@11
|
526 break;
|
yading@11
|
527 uls++;
|
yading@11
|
528 }
|
yading@11
|
529 return uls;
|
yading@11
|
530 }
|
yading@11
|
531
|
yading@11
|
532 //one EC -> one descriptor. N ECs -> MultipleDescriptor + N descriptors
|
yading@11
|
533 #define DESCRIPTOR_COUNT(essence_container_count) \
|
yading@11
|
534 (essence_container_count > 1 ? essence_container_count + 1 : essence_container_count)
|
yading@11
|
535
|
yading@11
|
536 static void mxf_write_essence_container_refs(AVFormatContext *s)
|
yading@11
|
537 {
|
yading@11
|
538 MXFContext *c = s->priv_data;
|
yading@11
|
539 AVIOContext *pb = s->pb;
|
yading@11
|
540 int i;
|
yading@11
|
541
|
yading@11
|
542 mxf_write_refs_count(pb, DESCRIPTOR_COUNT(c->essence_container_count));
|
yading@11
|
543 av_log(s,AV_LOG_DEBUG, "essence container count:%d\n", c->essence_container_count);
|
yading@11
|
544 for (i = 0; i < c->essence_container_count; i++) {
|
yading@11
|
545 MXFStreamContext *sc = s->streams[i]->priv_data;
|
yading@11
|
546 avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
|
yading@11
|
547 }
|
yading@11
|
548
|
yading@11
|
549 if (c->essence_container_count > 1)
|
yading@11
|
550 avio_write(pb, multiple_desc_ul, 16);
|
yading@11
|
551 }
|
yading@11
|
552
|
yading@11
|
553 static void mxf_write_preface(AVFormatContext *s)
|
yading@11
|
554 {
|
yading@11
|
555 MXFContext *mxf = s->priv_data;
|
yading@11
|
556 AVIOContext *pb = s->pb;
|
yading@11
|
557
|
yading@11
|
558 mxf_write_metadata_key(pb, 0x012f00);
|
yading@11
|
559 PRINT_KEY(s, "preface key", pb->buf_ptr - 16);
|
yading@11
|
560 klv_encode_ber_length(pb, 130 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count));
|
yading@11
|
561
|
yading@11
|
562 // write preface set uid
|
yading@11
|
563 mxf_write_local_tag(pb, 16, 0x3C0A);
|
yading@11
|
564 mxf_write_uuid(pb, Preface, 0);
|
yading@11
|
565 PRINT_KEY(s, "preface uid", pb->buf_ptr - 16);
|
yading@11
|
566
|
yading@11
|
567 // last modified date
|
yading@11
|
568 mxf_write_local_tag(pb, 8, 0x3B02);
|
yading@11
|
569 avio_wb64(pb, mxf->timestamp);
|
yading@11
|
570
|
yading@11
|
571 // write version
|
yading@11
|
572 mxf_write_local_tag(pb, 2, 0x3B05);
|
yading@11
|
573 avio_wb16(pb, 258); // v1.2
|
yading@11
|
574
|
yading@11
|
575 // write identification_refs
|
yading@11
|
576 mxf_write_local_tag(pb, 16 + 8, 0x3B06);
|
yading@11
|
577 mxf_write_refs_count(pb, 1);
|
yading@11
|
578 mxf_write_uuid(pb, Identification, 0);
|
yading@11
|
579
|
yading@11
|
580 // write content_storage_refs
|
yading@11
|
581 mxf_write_local_tag(pb, 16, 0x3B03);
|
yading@11
|
582 mxf_write_uuid(pb, ContentStorage, 0);
|
yading@11
|
583
|
yading@11
|
584 // operational pattern
|
yading@11
|
585 mxf_write_local_tag(pb, 16, 0x3B09);
|
yading@11
|
586 avio_write(pb, op1a_ul, 16);
|
yading@11
|
587
|
yading@11
|
588 // write essence_container_refs
|
yading@11
|
589 mxf_write_local_tag(pb, 8 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count), 0x3B0A);
|
yading@11
|
590 mxf_write_essence_container_refs(s);
|
yading@11
|
591
|
yading@11
|
592 // write dm_scheme_refs
|
yading@11
|
593 mxf_write_local_tag(pb, 8, 0x3B0B);
|
yading@11
|
594 avio_wb64(pb, 0);
|
yading@11
|
595 }
|
yading@11
|
596
|
yading@11
|
597 /*
|
yading@11
|
598 * Write a local tag containing an ascii string as utf-16
|
yading@11
|
599 */
|
yading@11
|
600 static void mxf_write_local_tag_utf16(AVIOContext *pb, int tag, const char *value)
|
yading@11
|
601 {
|
yading@11
|
602 int i, size = strlen(value);
|
yading@11
|
603 mxf_write_local_tag(pb, size*2, tag);
|
yading@11
|
604 for (i = 0; i < size; i++)
|
yading@11
|
605 avio_wb16(pb, value[i]);
|
yading@11
|
606 }
|
yading@11
|
607
|
yading@11
|
608 static void mxf_write_identification(AVFormatContext *s)
|
yading@11
|
609 {
|
yading@11
|
610 MXFContext *mxf = s->priv_data;
|
yading@11
|
611 AVIOContext *pb = s->pb;
|
yading@11
|
612 const char *company = "FFmpeg";
|
yading@11
|
613 const char *product = "OP1a Muxer";
|
yading@11
|
614 const char *version;
|
yading@11
|
615 int length;
|
yading@11
|
616
|
yading@11
|
617 mxf_write_metadata_key(pb, 0x013000);
|
yading@11
|
618 PRINT_KEY(s, "identification key", pb->buf_ptr - 16);
|
yading@11
|
619
|
yading@11
|
620 version = s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT ?
|
yading@11
|
621 "0.0.0" : AV_STRINGIFY(LIBAVFORMAT_VERSION);
|
yading@11
|
622 length = 84 + (strlen(company)+strlen(product)+strlen(version))*2; // utf-16
|
yading@11
|
623 klv_encode_ber_length(pb, length);
|
yading@11
|
624
|
yading@11
|
625 // write uid
|
yading@11
|
626 mxf_write_local_tag(pb, 16, 0x3C0A);
|
yading@11
|
627 mxf_write_uuid(pb, Identification, 0);
|
yading@11
|
628 PRINT_KEY(s, "identification uid", pb->buf_ptr - 16);
|
yading@11
|
629
|
yading@11
|
630 // write generation uid
|
yading@11
|
631 mxf_write_local_tag(pb, 16, 0x3C09);
|
yading@11
|
632 mxf_write_uuid(pb, Identification, 1);
|
yading@11
|
633
|
yading@11
|
634 mxf_write_local_tag_utf16(pb, 0x3C01, company); // Company Name
|
yading@11
|
635 mxf_write_local_tag_utf16(pb, 0x3C02, product); // Product Name
|
yading@11
|
636 mxf_write_local_tag_utf16(pb, 0x3C04, version); // Version String
|
yading@11
|
637
|
yading@11
|
638 // write product uid
|
yading@11
|
639 mxf_write_local_tag(pb, 16, 0x3C05);
|
yading@11
|
640 mxf_write_uuid(pb, Identification, 2);
|
yading@11
|
641
|
yading@11
|
642 // modification date
|
yading@11
|
643 mxf_write_local_tag(pb, 8, 0x3C06);
|
yading@11
|
644 avio_wb64(pb, mxf->timestamp);
|
yading@11
|
645 }
|
yading@11
|
646
|
yading@11
|
647 static void mxf_write_content_storage(AVFormatContext *s)
|
yading@11
|
648 {
|
yading@11
|
649 AVIOContext *pb = s->pb;
|
yading@11
|
650
|
yading@11
|
651 mxf_write_metadata_key(pb, 0x011800);
|
yading@11
|
652 PRINT_KEY(s, "content storage key", pb->buf_ptr - 16);
|
yading@11
|
653 klv_encode_ber_length(pb, 92);
|
yading@11
|
654
|
yading@11
|
655 // write uid
|
yading@11
|
656 mxf_write_local_tag(pb, 16, 0x3C0A);
|
yading@11
|
657 mxf_write_uuid(pb, ContentStorage, 0);
|
yading@11
|
658 PRINT_KEY(s, "content storage uid", pb->buf_ptr - 16);
|
yading@11
|
659
|
yading@11
|
660 // write package reference
|
yading@11
|
661 mxf_write_local_tag(pb, 16 * 2 + 8, 0x1901);
|
yading@11
|
662 mxf_write_refs_count(pb, 2);
|
yading@11
|
663 mxf_write_uuid(pb, MaterialPackage, 0);
|
yading@11
|
664 mxf_write_uuid(pb, SourcePackage, 0);
|
yading@11
|
665
|
yading@11
|
666 // write essence container data
|
yading@11
|
667 mxf_write_local_tag(pb, 8 + 16, 0x1902);
|
yading@11
|
668 mxf_write_refs_count(pb, 1);
|
yading@11
|
669 mxf_write_uuid(pb, EssenceContainerData, 0);
|
yading@11
|
670 }
|
yading@11
|
671
|
yading@11
|
672 static void mxf_write_track(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
|
yading@11
|
673 {
|
yading@11
|
674 MXFContext *mxf = s->priv_data;
|
yading@11
|
675 AVIOContext *pb = s->pb;
|
yading@11
|
676 MXFStreamContext *sc = st->priv_data;
|
yading@11
|
677
|
yading@11
|
678 mxf_write_metadata_key(pb, 0x013b00);
|
yading@11
|
679 PRINT_KEY(s, "track key", pb->buf_ptr - 16);
|
yading@11
|
680 klv_encode_ber_length(pb, 80);
|
yading@11
|
681
|
yading@11
|
682 // write track uid
|
yading@11
|
683 mxf_write_local_tag(pb, 16, 0x3C0A);
|
yading@11
|
684 mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, st->index);
|
yading@11
|
685 PRINT_KEY(s, "track uid", pb->buf_ptr - 16);
|
yading@11
|
686
|
yading@11
|
687 // write track id
|
yading@11
|
688 mxf_write_local_tag(pb, 4, 0x4801);
|
yading@11
|
689 avio_wb32(pb, st->index+2);
|
yading@11
|
690
|
yading@11
|
691 // write track number
|
yading@11
|
692 mxf_write_local_tag(pb, 4, 0x4804);
|
yading@11
|
693 if (type == MaterialPackage)
|
yading@11
|
694 avio_wb32(pb, 0); // track number of material package is 0
|
yading@11
|
695 else
|
yading@11
|
696 avio_write(pb, sc->track_essence_element_key + 12, 4);
|
yading@11
|
697
|
yading@11
|
698 mxf_write_local_tag(pb, 8, 0x4B01);
|
yading@11
|
699 avio_wb32(pb, mxf->time_base.den);
|
yading@11
|
700 avio_wb32(pb, mxf->time_base.num);
|
yading@11
|
701
|
yading@11
|
702 // write origin
|
yading@11
|
703 mxf_write_local_tag(pb, 8, 0x4B02);
|
yading@11
|
704 avio_wb64(pb, 0);
|
yading@11
|
705
|
yading@11
|
706 // write sequence refs
|
yading@11
|
707 mxf_write_local_tag(pb, 16, 0x4803);
|
yading@11
|
708 mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index);
|
yading@11
|
709 }
|
yading@11
|
710
|
yading@11
|
711 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 };
|
yading@11
|
712
|
yading@11
|
713 static void mxf_write_common_fields(AVFormatContext *s, AVStream *st)
|
yading@11
|
714 {
|
yading@11
|
715 MXFContext *mxf = s->priv_data;
|
yading@11
|
716 AVIOContext *pb = s->pb;
|
yading@11
|
717
|
yading@11
|
718 // find data define uls
|
yading@11
|
719 mxf_write_local_tag(pb, 16, 0x0201);
|
yading@11
|
720 if (st == mxf->timecode_track)
|
yading@11
|
721 avio_write(pb, smpte_12m_timecode_track_data_ul, 16);
|
yading@11
|
722 else {
|
yading@11
|
723 const MXFCodecUL *data_def_ul = mxf_get_data_definition_ul(st->codec->codec_type);
|
yading@11
|
724 avio_write(pb, data_def_ul->uid, 16);
|
yading@11
|
725 }
|
yading@11
|
726
|
yading@11
|
727 // write duration
|
yading@11
|
728 mxf_write_local_tag(pb, 8, 0x0202);
|
yading@11
|
729 avio_wb64(pb, mxf->duration);
|
yading@11
|
730 }
|
yading@11
|
731
|
yading@11
|
732 static void mxf_write_sequence(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
|
yading@11
|
733 {
|
yading@11
|
734 MXFContext *mxf = s->priv_data;
|
yading@11
|
735 AVIOContext *pb = s->pb;
|
yading@11
|
736 enum MXFMetadataSetType component;
|
yading@11
|
737
|
yading@11
|
738 mxf_write_metadata_key(pb, 0x010f00);
|
yading@11
|
739 PRINT_KEY(s, "sequence key", pb->buf_ptr - 16);
|
yading@11
|
740 klv_encode_ber_length(pb, 80);
|
yading@11
|
741
|
yading@11
|
742 mxf_write_local_tag(pb, 16, 0x3C0A);
|
yading@11
|
743 mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index);
|
yading@11
|
744
|
yading@11
|
745 PRINT_KEY(s, "sequence uid", pb->buf_ptr - 16);
|
yading@11
|
746 mxf_write_common_fields(s, st);
|
yading@11
|
747
|
yading@11
|
748 // write structural component
|
yading@11
|
749 mxf_write_local_tag(pb, 16 + 8, 0x1001);
|
yading@11
|
750 mxf_write_refs_count(pb, 1);
|
yading@11
|
751 if (st == mxf->timecode_track)
|
yading@11
|
752 component = TimecodeComponent;
|
yading@11
|
753 else
|
yading@11
|
754 component = SourceClip;
|
yading@11
|
755 if (type == SourcePackage)
|
yading@11
|
756 component += TypeBottom;
|
yading@11
|
757 mxf_write_uuid(pb, component, st->index);
|
yading@11
|
758 }
|
yading@11
|
759
|
yading@11
|
760 static void mxf_write_timecode_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
|
yading@11
|
761 {
|
yading@11
|
762 MXFContext *mxf = s->priv_data;
|
yading@11
|
763 AVIOContext *pb = s->pb;
|
yading@11
|
764
|
yading@11
|
765 mxf_write_metadata_key(pb, 0x011400);
|
yading@11
|
766 klv_encode_ber_length(pb, 75);
|
yading@11
|
767
|
yading@11
|
768 // UID
|
yading@11
|
769 mxf_write_local_tag(pb, 16, 0x3C0A);
|
yading@11
|
770 mxf_write_uuid(pb, type == MaterialPackage ? TimecodeComponent :
|
yading@11
|
771 TimecodeComponent + TypeBottom, st->index);
|
yading@11
|
772
|
yading@11
|
773 mxf_write_common_fields(s, st);
|
yading@11
|
774
|
yading@11
|
775 // Start Time Code
|
yading@11
|
776 mxf_write_local_tag(pb, 8, 0x1501);
|
yading@11
|
777 avio_wb64(pb, mxf->tc.start);
|
yading@11
|
778
|
yading@11
|
779 // Rounded Time Code Base
|
yading@11
|
780 mxf_write_local_tag(pb, 2, 0x1502);
|
yading@11
|
781 avio_wb16(pb, mxf->timecode_base);
|
yading@11
|
782
|
yading@11
|
783 // Drop Frame
|
yading@11
|
784 mxf_write_local_tag(pb, 1, 0x1503);
|
yading@11
|
785 avio_w8(pb, !!(mxf->tc.flags & AV_TIMECODE_FLAG_DROPFRAME));
|
yading@11
|
786 }
|
yading@11
|
787
|
yading@11
|
788 static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
|
yading@11
|
789 {
|
yading@11
|
790 AVIOContext *pb = s->pb;
|
yading@11
|
791 int i;
|
yading@11
|
792
|
yading@11
|
793 mxf_write_metadata_key(pb, 0x011100);
|
yading@11
|
794 PRINT_KEY(s, "sturctural component key", pb->buf_ptr - 16);
|
yading@11
|
795 klv_encode_ber_length(pb, 108);
|
yading@11
|
796
|
yading@11
|
797 // write uid
|
yading@11
|
798 mxf_write_local_tag(pb, 16, 0x3C0A);
|
yading@11
|
799 mxf_write_uuid(pb, type == MaterialPackage ? SourceClip: SourceClip + TypeBottom, st->index);
|
yading@11
|
800
|
yading@11
|
801 PRINT_KEY(s, "structural component uid", pb->buf_ptr - 16);
|
yading@11
|
802 mxf_write_common_fields(s, st);
|
yading@11
|
803
|
yading@11
|
804 // write start_position
|
yading@11
|
805 mxf_write_local_tag(pb, 8, 0x1201);
|
yading@11
|
806 avio_wb64(pb, 0);
|
yading@11
|
807
|
yading@11
|
808 // write source package uid, end of the reference
|
yading@11
|
809 mxf_write_local_tag(pb, 32, 0x1101);
|
yading@11
|
810 if (type == SourcePackage) {
|
yading@11
|
811 for (i = 0; i < 4; i++)
|
yading@11
|
812 avio_wb64(pb, 0);
|
yading@11
|
813 } else
|
yading@11
|
814 mxf_write_umid(s, 1);
|
yading@11
|
815
|
yading@11
|
816 // write source track id
|
yading@11
|
817 mxf_write_local_tag(pb, 4, 0x1102);
|
yading@11
|
818 if (type == SourcePackage)
|
yading@11
|
819 avio_wb32(pb, 0);
|
yading@11
|
820 else
|
yading@11
|
821 avio_wb32(pb, st->index+2);
|
yading@11
|
822 }
|
yading@11
|
823
|
yading@11
|
824 static void mxf_write_multi_descriptor(AVFormatContext *s)
|
yading@11
|
825 {
|
yading@11
|
826 MXFContext *mxf = s->priv_data;
|
yading@11
|
827 AVIOContext *pb = s->pb;
|
yading@11
|
828 const uint8_t *ul;
|
yading@11
|
829 int i;
|
yading@11
|
830
|
yading@11
|
831 mxf_write_metadata_key(pb, 0x014400);
|
yading@11
|
832 PRINT_KEY(s, "multiple descriptor key", pb->buf_ptr - 16);
|
yading@11
|
833 klv_encode_ber_length(pb, 64 + 16LL * s->nb_streams);
|
yading@11
|
834
|
yading@11
|
835 mxf_write_local_tag(pb, 16, 0x3C0A);
|
yading@11
|
836 mxf_write_uuid(pb, MultipleDescriptor, 0);
|
yading@11
|
837 PRINT_KEY(s, "multi_desc uid", pb->buf_ptr - 16);
|
yading@11
|
838
|
yading@11
|
839 // write sample rate
|
yading@11
|
840 mxf_write_local_tag(pb, 8, 0x3001);
|
yading@11
|
841 avio_wb32(pb, mxf->time_base.den);
|
yading@11
|
842 avio_wb32(pb, mxf->time_base.num);
|
yading@11
|
843
|
yading@11
|
844 // write essence container ul
|
yading@11
|
845 mxf_write_local_tag(pb, 16, 0x3004);
|
yading@11
|
846 if (mxf->essence_container_count > 1)
|
yading@11
|
847 ul = multiple_desc_ul;
|
yading@11
|
848 else {
|
yading@11
|
849 MXFStreamContext *sc = s->streams[0]->priv_data;
|
yading@11
|
850 ul = mxf_essence_container_uls[sc->index].container_ul;
|
yading@11
|
851 }
|
yading@11
|
852 avio_write(pb, ul, 16);
|
yading@11
|
853
|
yading@11
|
854 // write sub descriptor refs
|
yading@11
|
855 mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01);
|
yading@11
|
856 mxf_write_refs_count(pb, s->nb_streams);
|
yading@11
|
857 for (i = 0; i < s->nb_streams; i++)
|
yading@11
|
858 mxf_write_uuid(pb, SubDescriptor, i);
|
yading@11
|
859 }
|
yading@11
|
860
|
yading@11
|
861 static void mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
|
yading@11
|
862 {
|
yading@11
|
863 MXFContext *mxf = s->priv_data;
|
yading@11
|
864 MXFStreamContext *sc = st->priv_data;
|
yading@11
|
865 AVIOContext *pb = s->pb;
|
yading@11
|
866
|
yading@11
|
867 avio_write(pb, key, 16);
|
yading@11
|
868 klv_encode_ber4_length(pb, size+20+8+12+20);
|
yading@11
|
869
|
yading@11
|
870 mxf_write_local_tag(pb, 16, 0x3C0A);
|
yading@11
|
871 mxf_write_uuid(pb, SubDescriptor, st->index);
|
yading@11
|
872
|
yading@11
|
873 mxf_write_local_tag(pb, 4, 0x3006);
|
yading@11
|
874 avio_wb32(pb, st->index+2);
|
yading@11
|
875
|
yading@11
|
876 mxf_write_local_tag(pb, 8, 0x3001);
|
yading@11
|
877 avio_wb32(pb, mxf->time_base.den);
|
yading@11
|
878 avio_wb32(pb, mxf->time_base.num);
|
yading@11
|
879
|
yading@11
|
880 mxf_write_local_tag(pb, 16, 0x3004);
|
yading@11
|
881 avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
|
yading@11
|
882 }
|
yading@11
|
883
|
yading@11
|
884 static const UID mxf_mpegvideo_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 };
|
yading@11
|
885 static const UID mxf_wav_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 };
|
yading@11
|
886 static const UID mxf_aes3_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 };
|
yading@11
|
887 static const UID mxf_cdci_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x28,0x00 };
|
yading@11
|
888 static const UID mxf_generic_sound_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x42,0x00 };
|
yading@11
|
889
|
yading@11
|
890 static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
|
yading@11
|
891 {
|
yading@11
|
892 MXFStreamContext *sc = st->priv_data;
|
yading@11
|
893 AVIOContext *pb = s->pb;
|
yading@11
|
894 int stored_height = (st->codec->height+15)/16*16;
|
yading@11
|
895 int display_height;
|
yading@11
|
896 int f1, f2;
|
yading@11
|
897 unsigned desc_size = size+8+8+8+8+8+8+5+16+sc->interlaced*4+12+20;
|
yading@11
|
898 if (sc->interlaced && sc->field_dominance)
|
yading@11
|
899 desc_size += 5;
|
yading@11
|
900
|
yading@11
|
901 mxf_write_generic_desc(s, st, key, desc_size);
|
yading@11
|
902
|
yading@11
|
903 mxf_write_local_tag(pb, 4, 0x3203);
|
yading@11
|
904 avio_wb32(pb, st->codec->width);
|
yading@11
|
905
|
yading@11
|
906 mxf_write_local_tag(pb, 4, 0x3202);
|
yading@11
|
907 avio_wb32(pb, stored_height>>sc->interlaced);
|
yading@11
|
908
|
yading@11
|
909 mxf_write_local_tag(pb, 4, 0x3209);
|
yading@11
|
910 avio_wb32(pb, st->codec->width);
|
yading@11
|
911
|
yading@11
|
912 if (st->codec->height == 608) // PAL + VBI
|
yading@11
|
913 display_height = 576;
|
yading@11
|
914 else if (st->codec->height == 512) // NTSC + VBI
|
yading@11
|
915 display_height = 486;
|
yading@11
|
916 else
|
yading@11
|
917 display_height = st->codec->height;
|
yading@11
|
918
|
yading@11
|
919 mxf_write_local_tag(pb, 4, 0x3208);
|
yading@11
|
920 avio_wb32(pb, display_height>>sc->interlaced);
|
yading@11
|
921
|
yading@11
|
922 // component depth
|
yading@11
|
923 mxf_write_local_tag(pb, 4, 0x3301);
|
yading@11
|
924 avio_wb32(pb, sc->component_depth);
|
yading@11
|
925
|
yading@11
|
926 // horizontal subsampling
|
yading@11
|
927 mxf_write_local_tag(pb, 4, 0x3302);
|
yading@11
|
928 avio_wb32(pb, 2);
|
yading@11
|
929
|
yading@11
|
930 // frame layout
|
yading@11
|
931 mxf_write_local_tag(pb, 1, 0x320C);
|
yading@11
|
932 avio_w8(pb, sc->interlaced);
|
yading@11
|
933
|
yading@11
|
934 // video line map
|
yading@11
|
935 switch (st->codec->height) {
|
yading@11
|
936 case 576: f1 = 23; f2 = st->codec->codec_id == AV_CODEC_ID_DVVIDEO ? 335 : 336; break;
|
yading@11
|
937 case 608: f1 = 7; f2 = 320; break;
|
yading@11
|
938 case 480: f1 = 20; f2 = st->codec->codec_id == AV_CODEC_ID_DVVIDEO ? 285 : 283; break;
|
yading@11
|
939 case 512: f1 = 7; f2 = 270; break;
|
yading@11
|
940 case 720: f1 = 26; f2 = 0; break; // progressive
|
yading@11
|
941 case 1080: f1 = 21; f2 = 584; break;
|
yading@11
|
942 default: f1 = 0; f2 = 0; break;
|
yading@11
|
943 }
|
yading@11
|
944
|
yading@11
|
945 if (!sc->interlaced) {
|
yading@11
|
946 f2 = 0;
|
yading@11
|
947 f1 *= 2;
|
yading@11
|
948 }
|
yading@11
|
949
|
yading@11
|
950 mxf_write_local_tag(pb, 12+sc->interlaced*4, 0x320D);
|
yading@11
|
951 avio_wb32(pb, sc->interlaced ? 2 : 1);
|
yading@11
|
952 avio_wb32(pb, 4);
|
yading@11
|
953 avio_wb32(pb, f1);
|
yading@11
|
954 if (sc->interlaced)
|
yading@11
|
955 avio_wb32(pb, f2);
|
yading@11
|
956
|
yading@11
|
957 mxf_write_local_tag(pb, 8, 0x320E);
|
yading@11
|
958 avio_wb32(pb, sc->aspect_ratio.num);
|
yading@11
|
959 avio_wb32(pb, sc->aspect_ratio.den);
|
yading@11
|
960
|
yading@11
|
961 mxf_write_local_tag(pb, 16, 0x3201);
|
yading@11
|
962 avio_write(pb, *sc->codec_ul, 16);
|
yading@11
|
963
|
yading@11
|
964 if (sc->interlaced && sc->field_dominance) {
|
yading@11
|
965 mxf_write_local_tag(pb, 1, 0x3212);
|
yading@11
|
966 avio_w8(pb, sc->field_dominance);
|
yading@11
|
967 }
|
yading@11
|
968
|
yading@11
|
969 }
|
yading@11
|
970
|
yading@11
|
971 static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st)
|
yading@11
|
972 {
|
yading@11
|
973 mxf_write_cdci_common(s, st, mxf_cdci_descriptor_key, 0);
|
yading@11
|
974 }
|
yading@11
|
975
|
yading@11
|
976 static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st)
|
yading@11
|
977 {
|
yading@11
|
978 AVIOContext *pb = s->pb;
|
yading@11
|
979 int profile_and_level = (st->codec->profile<<4) | st->codec->level;
|
yading@11
|
980
|
yading@11
|
981 mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key, 8+5);
|
yading@11
|
982
|
yading@11
|
983 // bit rate
|
yading@11
|
984 mxf_write_local_tag(pb, 4, 0x8000);
|
yading@11
|
985 avio_wb32(pb, st->codec->bit_rate);
|
yading@11
|
986
|
yading@11
|
987 // profile and level
|
yading@11
|
988 mxf_write_local_tag(pb, 1, 0x8007);
|
yading@11
|
989 if (!st->codec->profile)
|
yading@11
|
990 profile_and_level |= 0x80; // escape bit
|
yading@11
|
991 avio_w8(pb, profile_and_level);
|
yading@11
|
992 }
|
yading@11
|
993
|
yading@11
|
994 static void mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
|
yading@11
|
995 {
|
yading@11
|
996 AVIOContext *pb = s->pb;
|
yading@11
|
997
|
yading@11
|
998 mxf_write_generic_desc(s, st, key, size+5+12+8+8);
|
yading@11
|
999
|
yading@11
|
1000 // audio locked
|
yading@11
|
1001 mxf_write_local_tag(pb, 1, 0x3D02);
|
yading@11
|
1002 avio_w8(pb, 1);
|
yading@11
|
1003
|
yading@11
|
1004 // write audio sampling rate
|
yading@11
|
1005 mxf_write_local_tag(pb, 8, 0x3D03);
|
yading@11
|
1006 avio_wb32(pb, st->codec->sample_rate);
|
yading@11
|
1007 avio_wb32(pb, 1);
|
yading@11
|
1008
|
yading@11
|
1009 mxf_write_local_tag(pb, 4, 0x3D07);
|
yading@11
|
1010 avio_wb32(pb, st->codec->channels);
|
yading@11
|
1011
|
yading@11
|
1012 mxf_write_local_tag(pb, 4, 0x3D01);
|
yading@11
|
1013 avio_wb32(pb, av_get_bits_per_sample(st->codec->codec_id));
|
yading@11
|
1014 }
|
yading@11
|
1015
|
yading@11
|
1016 static void mxf_write_wav_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
|
yading@11
|
1017 {
|
yading@11
|
1018 AVIOContext *pb = s->pb;
|
yading@11
|
1019
|
yading@11
|
1020 mxf_write_generic_sound_common(s, st, key, size+6+8);
|
yading@11
|
1021
|
yading@11
|
1022 mxf_write_local_tag(pb, 2, 0x3D0A);
|
yading@11
|
1023 avio_wb16(pb, st->codec->block_align);
|
yading@11
|
1024
|
yading@11
|
1025 // avg bytes per sec
|
yading@11
|
1026 mxf_write_local_tag(pb, 4, 0x3D09);
|
yading@11
|
1027 avio_wb32(pb, st->codec->block_align*st->codec->sample_rate);
|
yading@11
|
1028 }
|
yading@11
|
1029
|
yading@11
|
1030 static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st)
|
yading@11
|
1031 {
|
yading@11
|
1032 mxf_write_wav_common(s, st, mxf_wav_descriptor_key, 0);
|
yading@11
|
1033 }
|
yading@11
|
1034
|
yading@11
|
1035 static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st)
|
yading@11
|
1036 {
|
yading@11
|
1037 mxf_write_wav_common(s, st, mxf_aes3_descriptor_key, 0);
|
yading@11
|
1038 }
|
yading@11
|
1039
|
yading@11
|
1040 static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st)
|
yading@11
|
1041 {
|
yading@11
|
1042 mxf_write_generic_sound_common(s, st, mxf_generic_sound_descriptor_key, 0);
|
yading@11
|
1043 }
|
yading@11
|
1044
|
yading@11
|
1045 static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type)
|
yading@11
|
1046 {
|
yading@11
|
1047 MXFContext *mxf = s->priv_data;
|
yading@11
|
1048 AVIOContext *pb = s->pb;
|
yading@11
|
1049 int i, track_count = s->nb_streams+1;
|
yading@11
|
1050
|
yading@11
|
1051 if (type == MaterialPackage) {
|
yading@11
|
1052 mxf_write_metadata_key(pb, 0x013600);
|
yading@11
|
1053 PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16);
|
yading@11
|
1054 klv_encode_ber_length(pb, 92 + 16*track_count);
|
yading@11
|
1055 } else {
|
yading@11
|
1056 mxf_write_metadata_key(pb, 0x013700);
|
yading@11
|
1057 PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16);
|
yading@11
|
1058 klv_encode_ber_length(pb, 112 + 16*track_count); // 20 bytes length for descriptor reference
|
yading@11
|
1059 }
|
yading@11
|
1060
|
yading@11
|
1061 // write uid
|
yading@11
|
1062 mxf_write_local_tag(pb, 16, 0x3C0A);
|
yading@11
|
1063 mxf_write_uuid(pb, type, 0);
|
yading@11
|
1064 av_log(s,AV_LOG_DEBUG, "package type:%d\n", type);
|
yading@11
|
1065 PRINT_KEY(s, "package uid", pb->buf_ptr - 16);
|
yading@11
|
1066
|
yading@11
|
1067 // write package umid
|
yading@11
|
1068 mxf_write_local_tag(pb, 32, 0x4401);
|
yading@11
|
1069 mxf_write_umid(s, type == SourcePackage);
|
yading@11
|
1070 PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16);
|
yading@11
|
1071
|
yading@11
|
1072 // package creation date
|
yading@11
|
1073 mxf_write_local_tag(pb, 8, 0x4405);
|
yading@11
|
1074 avio_wb64(pb, mxf->timestamp);
|
yading@11
|
1075
|
yading@11
|
1076 // package modified date
|
yading@11
|
1077 mxf_write_local_tag(pb, 8, 0x4404);
|
yading@11
|
1078 avio_wb64(pb, mxf->timestamp);
|
yading@11
|
1079
|
yading@11
|
1080 // write track refs
|
yading@11
|
1081 mxf_write_local_tag(pb, track_count*16 + 8, 0x4403);
|
yading@11
|
1082 mxf_write_refs_count(pb, track_count);
|
yading@11
|
1083 mxf_write_uuid(pb, type == MaterialPackage ? Track :
|
yading@11
|
1084 Track + TypeBottom, -1); // timecode track
|
yading@11
|
1085 for (i = 0; i < s->nb_streams; i++)
|
yading@11
|
1086 mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, i);
|
yading@11
|
1087
|
yading@11
|
1088 // write multiple descriptor reference
|
yading@11
|
1089 if (type == SourcePackage) {
|
yading@11
|
1090 mxf_write_local_tag(pb, 16, 0x4701);
|
yading@11
|
1091 if (s->nb_streams > 1) {
|
yading@11
|
1092 mxf_write_uuid(pb, MultipleDescriptor, 0);
|
yading@11
|
1093 mxf_write_multi_descriptor(s);
|
yading@11
|
1094 } else
|
yading@11
|
1095 mxf_write_uuid(pb, SubDescriptor, 0);
|
yading@11
|
1096 }
|
yading@11
|
1097
|
yading@11
|
1098 // write timecode track
|
yading@11
|
1099 mxf_write_track(s, mxf->timecode_track, type);
|
yading@11
|
1100 mxf_write_sequence(s, mxf->timecode_track, type);
|
yading@11
|
1101 mxf_write_timecode_component(s, mxf->timecode_track, type);
|
yading@11
|
1102
|
yading@11
|
1103 for (i = 0; i < s->nb_streams; i++) {
|
yading@11
|
1104 AVStream *st = s->streams[i];
|
yading@11
|
1105 mxf_write_track(s, st, type);
|
yading@11
|
1106 mxf_write_sequence(s, st, type);
|
yading@11
|
1107 mxf_write_structural_component(s, st, type);
|
yading@11
|
1108
|
yading@11
|
1109 if (type == SourcePackage) {
|
yading@11
|
1110 MXFStreamContext *sc = st->priv_data;
|
yading@11
|
1111 mxf_essence_container_uls[sc->index].write_desc(s, st);
|
yading@11
|
1112 }
|
yading@11
|
1113 }
|
yading@11
|
1114 }
|
yading@11
|
1115
|
yading@11
|
1116 static int mxf_write_essence_container_data(AVFormatContext *s)
|
yading@11
|
1117 {
|
yading@11
|
1118 AVIOContext *pb = s->pb;
|
yading@11
|
1119
|
yading@11
|
1120 mxf_write_metadata_key(pb, 0x012300);
|
yading@11
|
1121 klv_encode_ber_length(pb, 72);
|
yading@11
|
1122
|
yading@11
|
1123 mxf_write_local_tag(pb, 16, 0x3C0A); // Instance UID
|
yading@11
|
1124 mxf_write_uuid(pb, EssenceContainerData, 0);
|
yading@11
|
1125
|
yading@11
|
1126 mxf_write_local_tag(pb, 32, 0x2701); // Linked Package UID
|
yading@11
|
1127 mxf_write_umid(s, 1);
|
yading@11
|
1128
|
yading@11
|
1129 mxf_write_local_tag(pb, 4, 0x3F07); // BodySID
|
yading@11
|
1130 avio_wb32(pb, 1);
|
yading@11
|
1131
|
yading@11
|
1132 mxf_write_local_tag(pb, 4, 0x3F06); // IndexSID
|
yading@11
|
1133 avio_wb32(pb, 2);
|
yading@11
|
1134
|
yading@11
|
1135 return 0;
|
yading@11
|
1136 }
|
yading@11
|
1137
|
yading@11
|
1138 static int mxf_write_header_metadata_sets(AVFormatContext *s)
|
yading@11
|
1139 {
|
yading@11
|
1140 mxf_write_preface(s);
|
yading@11
|
1141 mxf_write_identification(s);
|
yading@11
|
1142 mxf_write_content_storage(s);
|
yading@11
|
1143 mxf_write_package(s, MaterialPackage);
|
yading@11
|
1144 mxf_write_package(s, SourcePackage);
|
yading@11
|
1145 mxf_write_essence_container_data(s);
|
yading@11
|
1146 return 0;
|
yading@11
|
1147 }
|
yading@11
|
1148
|
yading@11
|
1149 static unsigned klv_fill_size(uint64_t size)
|
yading@11
|
1150 {
|
yading@11
|
1151 unsigned pad = KAG_SIZE - (size & (KAG_SIZE-1));
|
yading@11
|
1152 if (pad < 20) // smallest fill item possible
|
yading@11
|
1153 return pad + KAG_SIZE;
|
yading@11
|
1154 else
|
yading@11
|
1155 return pad & (KAG_SIZE-1);
|
yading@11
|
1156 }
|
yading@11
|
1157
|
yading@11
|
1158 static void mxf_write_index_table_segment(AVFormatContext *s)
|
yading@11
|
1159 {
|
yading@11
|
1160 MXFContext *mxf = s->priv_data;
|
yading@11
|
1161 AVIOContext *pb = s->pb;
|
yading@11
|
1162 int i, j, temporal_reordering = 0;
|
yading@11
|
1163 int key_index = mxf->last_key_index;
|
yading@11
|
1164
|
yading@11
|
1165 av_log(s, AV_LOG_DEBUG, "edit units count %d\n", mxf->edit_units_count);
|
yading@11
|
1166
|
yading@11
|
1167 if (!mxf->edit_units_count && !mxf->edit_unit_byte_count)
|
yading@11
|
1168 return;
|
yading@11
|
1169
|
yading@11
|
1170 avio_write(pb, index_table_segment_key, 16);
|
yading@11
|
1171
|
yading@11
|
1172 if (mxf->edit_unit_byte_count) {
|
yading@11
|
1173 klv_encode_ber_length(pb, 80);
|
yading@11
|
1174 } else {
|
yading@11
|
1175 klv_encode_ber_length(pb, 85 + 12+(s->nb_streams+1LL)*6 +
|
yading@11
|
1176 12+mxf->edit_units_count*(11+mxf->slice_count*4LL));
|
yading@11
|
1177 }
|
yading@11
|
1178
|
yading@11
|
1179 // instance id
|
yading@11
|
1180 mxf_write_local_tag(pb, 16, 0x3C0A);
|
yading@11
|
1181 mxf_write_uuid(pb, IndexTableSegment, 0);
|
yading@11
|
1182
|
yading@11
|
1183 // index edit rate
|
yading@11
|
1184 mxf_write_local_tag(pb, 8, 0x3F0B);
|
yading@11
|
1185 avio_wb32(pb, mxf->time_base.den);
|
yading@11
|
1186 avio_wb32(pb, mxf->time_base.num);
|
yading@11
|
1187
|
yading@11
|
1188 // index start position
|
yading@11
|
1189 mxf_write_local_tag(pb, 8, 0x3F0C);
|
yading@11
|
1190 avio_wb64(pb, mxf->last_indexed_edit_unit);
|
yading@11
|
1191
|
yading@11
|
1192 // index duration
|
yading@11
|
1193 mxf_write_local_tag(pb, 8, 0x3F0D);
|
yading@11
|
1194 if (mxf->edit_unit_byte_count)
|
yading@11
|
1195 avio_wb64(pb, 0); // index table covers whole container
|
yading@11
|
1196 else
|
yading@11
|
1197 avio_wb64(pb, mxf->edit_units_count);
|
yading@11
|
1198
|
yading@11
|
1199 // edit unit byte count
|
yading@11
|
1200 mxf_write_local_tag(pb, 4, 0x3F05);
|
yading@11
|
1201 avio_wb32(pb, mxf->edit_unit_byte_count);
|
yading@11
|
1202
|
yading@11
|
1203 // index sid
|
yading@11
|
1204 mxf_write_local_tag(pb, 4, 0x3F06);
|
yading@11
|
1205 avio_wb32(pb, 2);
|
yading@11
|
1206
|
yading@11
|
1207 // body sid
|
yading@11
|
1208 mxf_write_local_tag(pb, 4, 0x3F07);
|
yading@11
|
1209 avio_wb32(pb, 1);
|
yading@11
|
1210
|
yading@11
|
1211 if (!mxf->edit_unit_byte_count) {
|
yading@11
|
1212 // real slice count - 1
|
yading@11
|
1213 mxf_write_local_tag(pb, 1, 0x3F08);
|
yading@11
|
1214 avio_w8(pb, mxf->slice_count);
|
yading@11
|
1215
|
yading@11
|
1216 // delta entry array
|
yading@11
|
1217 mxf_write_local_tag(pb, 8 + (s->nb_streams+1)*6, 0x3F09);
|
yading@11
|
1218 avio_wb32(pb, s->nb_streams+1); // num of entries
|
yading@11
|
1219 avio_wb32(pb, 6); // size of one entry
|
yading@11
|
1220 // write system item delta entry
|
yading@11
|
1221 avio_w8(pb, 0);
|
yading@11
|
1222 avio_w8(pb, 0); // slice entry
|
yading@11
|
1223 avio_wb32(pb, 0); // element delta
|
yading@11
|
1224 for (i = 0; i < s->nb_streams; i++) {
|
yading@11
|
1225 AVStream *st = s->streams[i];
|
yading@11
|
1226 MXFStreamContext *sc = st->priv_data;
|
yading@11
|
1227 avio_w8(pb, sc->temporal_reordering);
|
yading@11
|
1228 if (sc->temporal_reordering)
|
yading@11
|
1229 temporal_reordering = 1;
|
yading@11
|
1230 if (i == 0) { // video track
|
yading@11
|
1231 avio_w8(pb, 0); // slice number
|
yading@11
|
1232 avio_wb32(pb, KAG_SIZE); // system item size including klv fill
|
yading@11
|
1233 } else { // audio track
|
yading@11
|
1234 unsigned audio_frame_size = sc->aic.samples[0]*sc->aic.sample_size;
|
yading@11
|
1235 audio_frame_size += klv_fill_size(audio_frame_size);
|
yading@11
|
1236 avio_w8(pb, 1);
|
yading@11
|
1237 avio_wb32(pb, (i-1)*audio_frame_size); // element delta
|
yading@11
|
1238 }
|
yading@11
|
1239 }
|
yading@11
|
1240
|
yading@11
|
1241 mxf_write_local_tag(pb, 8 + mxf->edit_units_count*(11+mxf->slice_count*4), 0x3F0A);
|
yading@11
|
1242 avio_wb32(pb, mxf->edit_units_count); // num of entries
|
yading@11
|
1243 avio_wb32(pb, 11+mxf->slice_count*4); // size of one entry
|
yading@11
|
1244
|
yading@11
|
1245 for (i = 0; i < mxf->edit_units_count; i++) {
|
yading@11
|
1246 int temporal_offset = 0;
|
yading@11
|
1247
|
yading@11
|
1248 if (!(mxf->index_entries[i].flags & 0x33)) { // I frame
|
yading@11
|
1249 mxf->last_key_index = key_index;
|
yading@11
|
1250 key_index = i;
|
yading@11
|
1251 }
|
yading@11
|
1252
|
yading@11
|
1253 if (temporal_reordering) {
|
yading@11
|
1254 int pic_num_in_gop = i - key_index;
|
yading@11
|
1255 if (pic_num_in_gop != mxf->index_entries[i].temporal_ref) {
|
yading@11
|
1256 for (j = key_index; j < mxf->edit_units_count; j++) {
|
yading@11
|
1257 if (pic_num_in_gop == mxf->index_entries[j].temporal_ref)
|
yading@11
|
1258 break;
|
yading@11
|
1259 }
|
yading@11
|
1260 if (j == mxf->edit_units_count)
|
yading@11
|
1261 av_log(s, AV_LOG_WARNING, "missing frames\n");
|
yading@11
|
1262 temporal_offset = j - key_index - pic_num_in_gop;
|
yading@11
|
1263 }
|
yading@11
|
1264 }
|
yading@11
|
1265 avio_w8(pb, temporal_offset);
|
yading@11
|
1266
|
yading@11
|
1267 if ((mxf->index_entries[i].flags & 0x30) == 0x30) { // back and forward prediction
|
yading@11
|
1268 avio_w8(pb, mxf->last_key_index - i);
|
yading@11
|
1269 } else {
|
yading@11
|
1270 avio_w8(pb, key_index - i); // key frame offset
|
yading@11
|
1271 if ((mxf->index_entries[i].flags & 0x20) == 0x20) // only forward
|
yading@11
|
1272 mxf->last_key_index = key_index;
|
yading@11
|
1273 }
|
yading@11
|
1274
|
yading@11
|
1275 if (!(mxf->index_entries[i].flags & 0x33) && // I frame
|
yading@11
|
1276 mxf->index_entries[i].flags & 0x40 && !temporal_offset)
|
yading@11
|
1277 mxf->index_entries[i].flags |= 0x80; // random access
|
yading@11
|
1278 avio_w8(pb, mxf->index_entries[i].flags);
|
yading@11
|
1279 // stream offset
|
yading@11
|
1280 avio_wb64(pb, mxf->index_entries[i].offset);
|
yading@11
|
1281 if (s->nb_streams > 1)
|
yading@11
|
1282 avio_wb32(pb, mxf->index_entries[i].slice_offset);
|
yading@11
|
1283 }
|
yading@11
|
1284
|
yading@11
|
1285 mxf->last_key_index = key_index - mxf->edit_units_count;
|
yading@11
|
1286 mxf->last_indexed_edit_unit += mxf->edit_units_count;
|
yading@11
|
1287 mxf->edit_units_count = 0;
|
yading@11
|
1288 }
|
yading@11
|
1289 }
|
yading@11
|
1290
|
yading@11
|
1291 static void mxf_write_klv_fill(AVFormatContext *s)
|
yading@11
|
1292 {
|
yading@11
|
1293 unsigned pad = klv_fill_size(avio_tell(s->pb));
|
yading@11
|
1294 if (pad) {
|
yading@11
|
1295 avio_write(s->pb, klv_fill_key, 16);
|
yading@11
|
1296 pad -= 16 + 4;
|
yading@11
|
1297 klv_encode_ber4_length(s->pb, pad);
|
yading@11
|
1298 for (; pad; pad--)
|
yading@11
|
1299 avio_w8(s->pb, 0);
|
yading@11
|
1300 av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1)));
|
yading@11
|
1301 }
|
yading@11
|
1302 }
|
yading@11
|
1303
|
yading@11
|
1304 static void mxf_write_partition(AVFormatContext *s, int bodysid,
|
yading@11
|
1305 int indexsid,
|
yading@11
|
1306 const uint8_t *key, int write_metadata)
|
yading@11
|
1307 {
|
yading@11
|
1308 MXFContext *mxf = s->priv_data;
|
yading@11
|
1309 AVIOContext *pb = s->pb;
|
yading@11
|
1310 int64_t header_byte_count_offset;
|
yading@11
|
1311 unsigned index_byte_count = 0;
|
yading@11
|
1312 uint64_t partition_offset = avio_tell(pb);
|
yading@11
|
1313
|
yading@11
|
1314 if (!mxf->edit_unit_byte_count && mxf->edit_units_count)
|
yading@11
|
1315 index_byte_count = 85 + 12+(s->nb_streams+1)*6 +
|
yading@11
|
1316 12+mxf->edit_units_count*(11+mxf->slice_count*4);
|
yading@11
|
1317 else if (mxf->edit_unit_byte_count && indexsid)
|
yading@11
|
1318 index_byte_count = 80;
|
yading@11
|
1319
|
yading@11
|
1320 if (index_byte_count) {
|
yading@11
|
1321 // add encoded ber length
|
yading@11
|
1322 index_byte_count += 16 + klv_ber_length(index_byte_count);
|
yading@11
|
1323 index_byte_count += klv_fill_size(index_byte_count);
|
yading@11
|
1324 }
|
yading@11
|
1325
|
yading@11
|
1326 if (!memcmp(key, body_partition_key, 16)) {
|
yading@11
|
1327 mxf->body_partition_offset =
|
yading@11
|
1328 av_realloc(mxf->body_partition_offset,
|
yading@11
|
1329 (mxf->body_partitions_count+1)*
|
yading@11
|
1330 sizeof(*mxf->body_partition_offset));
|
yading@11
|
1331 mxf->body_partition_offset[mxf->body_partitions_count++] = partition_offset;
|
yading@11
|
1332 }
|
yading@11
|
1333
|
yading@11
|
1334 // write klv
|
yading@11
|
1335 avio_write(pb, key, 16);
|
yading@11
|
1336 klv_encode_ber_length(pb, 88 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count));
|
yading@11
|
1337
|
yading@11
|
1338 // write partition value
|
yading@11
|
1339 avio_wb16(pb, 1); // majorVersion
|
yading@11
|
1340 avio_wb16(pb, 2); // minorVersion
|
yading@11
|
1341 avio_wb32(pb, KAG_SIZE); // KAGSize
|
yading@11
|
1342
|
yading@11
|
1343 avio_wb64(pb, partition_offset); // ThisPartition
|
yading@11
|
1344
|
yading@11
|
1345 if (!memcmp(key, body_partition_key, 16) && mxf->body_partitions_count > 1)
|
yading@11
|
1346 avio_wb64(pb, mxf->body_partition_offset[mxf->body_partitions_count-2]); // PreviousPartition
|
yading@11
|
1347 else if (!memcmp(key, footer_partition_key, 16) && mxf->body_partitions_count)
|
yading@11
|
1348 avio_wb64(pb, mxf->body_partition_offset[mxf->body_partitions_count-1]); // PreviousPartition
|
yading@11
|
1349 else
|
yading@11
|
1350 avio_wb64(pb, 0);
|
yading@11
|
1351
|
yading@11
|
1352 avio_wb64(pb, mxf->footer_partition_offset); // footerPartition
|
yading@11
|
1353
|
yading@11
|
1354 // set offset
|
yading@11
|
1355 header_byte_count_offset = avio_tell(pb);
|
yading@11
|
1356 avio_wb64(pb, 0); // headerByteCount, update later
|
yading@11
|
1357
|
yading@11
|
1358 // indexTable
|
yading@11
|
1359 avio_wb64(pb, index_byte_count); // indexByteCount
|
yading@11
|
1360 avio_wb32(pb, index_byte_count ? indexsid : 0); // indexSID
|
yading@11
|
1361
|
yading@11
|
1362 // BodyOffset
|
yading@11
|
1363 if (bodysid && mxf->edit_units_count && mxf->body_partitions_count) {
|
yading@11
|
1364 avio_wb64(pb, mxf->body_offset);
|
yading@11
|
1365 } else
|
yading@11
|
1366 avio_wb64(pb, 0);
|
yading@11
|
1367
|
yading@11
|
1368 avio_wb32(pb, bodysid); // bodySID
|
yading@11
|
1369
|
yading@11
|
1370 // operational pattern
|
yading@11
|
1371 avio_write(pb, op1a_ul, 16);
|
yading@11
|
1372
|
yading@11
|
1373 // essence container
|
yading@11
|
1374 mxf_write_essence_container_refs(s);
|
yading@11
|
1375
|
yading@11
|
1376 if (write_metadata) {
|
yading@11
|
1377 // mark the start of the headermetadata and calculate metadata size
|
yading@11
|
1378 int64_t pos, start;
|
yading@11
|
1379 unsigned header_byte_count;
|
yading@11
|
1380
|
yading@11
|
1381 mxf_write_klv_fill(s);
|
yading@11
|
1382 start = avio_tell(s->pb);
|
yading@11
|
1383 mxf_write_primer_pack(s);
|
yading@11
|
1384 mxf_write_header_metadata_sets(s);
|
yading@11
|
1385 pos = avio_tell(s->pb);
|
yading@11
|
1386 header_byte_count = pos - start + klv_fill_size(pos);
|
yading@11
|
1387
|
yading@11
|
1388 // update header_byte_count
|
yading@11
|
1389 avio_seek(pb, header_byte_count_offset, SEEK_SET);
|
yading@11
|
1390 avio_wb64(pb, header_byte_count);
|
yading@11
|
1391 avio_seek(pb, pos, SEEK_SET);
|
yading@11
|
1392 }
|
yading@11
|
1393
|
yading@11
|
1394 avio_flush(pb);
|
yading@11
|
1395 }
|
yading@11
|
1396
|
yading@11
|
1397 static int mxf_parse_dnxhd_frame(AVFormatContext *s, AVStream *st,
|
yading@11
|
1398 AVPacket *pkt)
|
yading@11
|
1399 {
|
yading@11
|
1400 MXFContext *mxf = s->priv_data;
|
yading@11
|
1401 MXFStreamContext *sc = st->priv_data;
|
yading@11
|
1402 int i, cid;
|
yading@11
|
1403 uint8_t* header_cid;
|
yading@11
|
1404 int frame_size = 0;
|
yading@11
|
1405
|
yading@11
|
1406 if (mxf->header_written)
|
yading@11
|
1407 return 1;
|
yading@11
|
1408
|
yading@11
|
1409 if (pkt->size < 43)
|
yading@11
|
1410 return -1;
|
yading@11
|
1411
|
yading@11
|
1412 header_cid = pkt->data + 0x28;
|
yading@11
|
1413 cid = header_cid[0] << 24 | header_cid[1] << 16 | header_cid[2] << 8 | header_cid[3];
|
yading@11
|
1414
|
yading@11
|
1415 if ((frame_size = avpriv_dnxhd_get_frame_size(cid)) < 0)
|
yading@11
|
1416 return -1;
|
yading@11
|
1417
|
yading@11
|
1418 switch (cid) {
|
yading@11
|
1419 case 1235:
|
yading@11
|
1420 sc->index = 24;
|
yading@11
|
1421 sc->component_depth = 10;
|
yading@11
|
1422 break;
|
yading@11
|
1423 case 1237:
|
yading@11
|
1424 sc->index = 25;
|
yading@11
|
1425 break;
|
yading@11
|
1426 case 1238:
|
yading@11
|
1427 sc->index = 26;
|
yading@11
|
1428 break;
|
yading@11
|
1429 case 1241:
|
yading@11
|
1430 sc->index = 27;
|
yading@11
|
1431 sc->component_depth = 10;
|
yading@11
|
1432 break;
|
yading@11
|
1433 case 1242:
|
yading@11
|
1434 sc->index = 28;
|
yading@11
|
1435 break;
|
yading@11
|
1436 case 1243:
|
yading@11
|
1437 sc->index = 29;
|
yading@11
|
1438 break;
|
yading@11
|
1439 case 1250:
|
yading@11
|
1440 sc->index = 30;
|
yading@11
|
1441 sc->component_depth = 10;
|
yading@11
|
1442 break;
|
yading@11
|
1443 case 1251:
|
yading@11
|
1444 sc->index = 31;
|
yading@11
|
1445 break;
|
yading@11
|
1446 case 1252:
|
yading@11
|
1447 sc->index = 32;
|
yading@11
|
1448 break;
|
yading@11
|
1449 case 1253:
|
yading@11
|
1450 sc->index = 33;
|
yading@11
|
1451 break;
|
yading@11
|
1452 default:
|
yading@11
|
1453 return -1;
|
yading@11
|
1454 }
|
yading@11
|
1455
|
yading@11
|
1456 sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;
|
yading@11
|
1457 sc->aspect_ratio = (AVRational){ 16, 9 };
|
yading@11
|
1458
|
yading@11
|
1459 mxf->edit_unit_byte_count = KAG_SIZE;
|
yading@11
|
1460 for (i = 0; i < s->nb_streams; i++) {
|
yading@11
|
1461 AVStream *st = s->streams[i];
|
yading@11
|
1462 MXFStreamContext *sc = st->priv_data;
|
yading@11
|
1463 if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
|
yading@11
|
1464 mxf->edit_unit_byte_count += 16 + 4 + sc->aic.samples[0]*sc->aic.sample_size;
|
yading@11
|
1465 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
|
yading@11
|
1466 } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
|
yading@11
|
1467 mxf->edit_unit_byte_count += 16 + 4 + frame_size;
|
yading@11
|
1468 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
|
yading@11
|
1469 }
|
yading@11
|
1470 }
|
yading@11
|
1471
|
yading@11
|
1472 return 1;
|
yading@11
|
1473 }
|
yading@11
|
1474
|
yading@11
|
1475 static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt)
|
yading@11
|
1476 {
|
yading@11
|
1477 MXFContext *mxf = s->priv_data;
|
yading@11
|
1478 MXFStreamContext *sc = st->priv_data;
|
yading@11
|
1479 uint8_t *vs_pack, *vsc_pack;
|
yading@11
|
1480 int i, ul_index, frame_size, stype, pal;
|
yading@11
|
1481
|
yading@11
|
1482 if (mxf->header_written)
|
yading@11
|
1483 return 1;
|
yading@11
|
1484
|
yading@11
|
1485 // Check for minimal frame size
|
yading@11
|
1486 if (pkt->size < 120000)
|
yading@11
|
1487 return -1;
|
yading@11
|
1488
|
yading@11
|
1489 vs_pack = pkt->data + 80*5 + 48;
|
yading@11
|
1490 vsc_pack = pkt->data + 80*5 + 53;
|
yading@11
|
1491 stype = vs_pack[3] & 0x1f;
|
yading@11
|
1492 pal = (vs_pack[3] >> 5) & 0x1;
|
yading@11
|
1493
|
yading@11
|
1494 if ((vs_pack[2] & 0x07) == 0x02)
|
yading@11
|
1495 sc->aspect_ratio = (AVRational){ 16, 9 };
|
yading@11
|
1496 else
|
yading@11
|
1497 sc->aspect_ratio = (AVRational){ 4, 3 };
|
yading@11
|
1498
|
yading@11
|
1499 sc->interlaced = (vsc_pack[3] >> 4) & 0x01;
|
yading@11
|
1500 // TODO: fix dv encoder to set proper FF/FS value in VSC pack
|
yading@11
|
1501 // and set field dominance accordingly
|
yading@11
|
1502 // av_log(s, AV_LOG_DEBUG, "DV vsc pack ff/ss = %x\n", vsc_pack[2] >> 6);
|
yading@11
|
1503
|
yading@11
|
1504 switch (stype) {
|
yading@11
|
1505 case 0x18: // DV100 720p
|
yading@11
|
1506 ul_index = 6 + pal;
|
yading@11
|
1507 frame_size = pal ? 288000 : 240000;
|
yading@11
|
1508 if (sc->interlaced) {
|
yading@11
|
1509 av_log(s, AV_LOG_ERROR, "source marked as interlaced but codec profile is progressive\n");
|
yading@11
|
1510 sc->interlaced = 0;
|
yading@11
|
1511 }
|
yading@11
|
1512 break;
|
yading@11
|
1513 case 0x14: // DV100 1080i
|
yading@11
|
1514 ul_index = 4 + pal;
|
yading@11
|
1515 frame_size = pal ? 576000 : 480000;
|
yading@11
|
1516 break;
|
yading@11
|
1517 case 0x04: // DV50
|
yading@11
|
1518 ul_index = 2 + pal;
|
yading@11
|
1519 frame_size = pal ? 288000 : 240000;
|
yading@11
|
1520 break;
|
yading@11
|
1521 default: // DV25
|
yading@11
|
1522 ul_index = 0 + pal;
|
yading@11
|
1523 frame_size = pal ? 144000 : 120000;
|
yading@11
|
1524 }
|
yading@11
|
1525
|
yading@11
|
1526 sc->index = ul_index + 16;
|
yading@11
|
1527 sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;
|
yading@11
|
1528
|
yading@11
|
1529 mxf->edit_unit_byte_count = KAG_SIZE;
|
yading@11
|
1530 for (i = 0; i < s->nb_streams; i++) {
|
yading@11
|
1531 AVStream *st = s->streams[i];
|
yading@11
|
1532 MXFStreamContext *sc = st->priv_data;
|
yading@11
|
1533 if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
|
yading@11
|
1534 mxf->edit_unit_byte_count += 16 + 4 + sc->aic.samples[0]*sc->aic.sample_size;
|
yading@11
|
1535 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
|
yading@11
|
1536 } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
|
yading@11
|
1537 mxf->edit_unit_byte_count += 16 + 4 + frame_size;
|
yading@11
|
1538 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
|
yading@11
|
1539 }
|
yading@11
|
1540 }
|
yading@11
|
1541
|
yading@11
|
1542 return 1;
|
yading@11
|
1543 }
|
yading@11
|
1544
|
yading@11
|
1545 static const UID mxf_mpeg2_codec_uls[] = {
|
yading@11
|
1546 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x10,0x00 }, // MP-ML I-Frame
|
yading@11
|
1547 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, // MP-ML Long GOP
|
yading@11
|
1548 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x02,0x00 }, // 422P-ML I-Frame
|
yading@11
|
1549 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x03,0x00 }, // 422P-ML Long GOP
|
yading@11
|
1550 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x02,0x00 }, // MP-HL I-Frame
|
yading@11
|
1551 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, // MP-HL Long GOP
|
yading@11
|
1552 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, // 422P-HL I-Frame
|
yading@11
|
1553 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x03,0x00 }, // 422P-HL Long GOP
|
yading@11
|
1554 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x02,0x00 }, // MP@H-14 I-Frame
|
yading@11
|
1555 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x03,0x00 }, // MP@H-14 Long GOP
|
yading@11
|
1556 };
|
yading@11
|
1557
|
yading@11
|
1558 static const UID *mxf_get_mpeg2_codec_ul(AVCodecContext *avctx)
|
yading@11
|
1559 {
|
yading@11
|
1560 int long_gop = avctx->gop_size > 1 || avctx->has_b_frames;
|
yading@11
|
1561
|
yading@11
|
1562 if (avctx->profile == 4) { // Main
|
yading@11
|
1563 if (avctx->level == 8) // Main
|
yading@11
|
1564 return &mxf_mpeg2_codec_uls[0+long_gop];
|
yading@11
|
1565 else if (avctx->level == 4) // High
|
yading@11
|
1566 return &mxf_mpeg2_codec_uls[4+long_gop];
|
yading@11
|
1567 else if (avctx->level == 6) // High 14
|
yading@11
|
1568 return &mxf_mpeg2_codec_uls[8+long_gop];
|
yading@11
|
1569 } else if (avctx->profile == 0) { // 422
|
yading@11
|
1570 if (avctx->level == 5) // Main
|
yading@11
|
1571 return &mxf_mpeg2_codec_uls[2+long_gop];
|
yading@11
|
1572 else if (avctx->level == 2) // High
|
yading@11
|
1573 return &mxf_mpeg2_codec_uls[6+long_gop];
|
yading@11
|
1574 }
|
yading@11
|
1575 return NULL;
|
yading@11
|
1576 }
|
yading@11
|
1577
|
yading@11
|
1578 static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st,
|
yading@11
|
1579 AVPacket *pkt, MXFIndexEntry *e)
|
yading@11
|
1580 {
|
yading@11
|
1581 MXFStreamContext *sc = st->priv_data;
|
yading@11
|
1582 uint32_t c = -1;
|
yading@11
|
1583 int i;
|
yading@11
|
1584
|
yading@11
|
1585 for(i = 0; i < pkt->size - 4; i++) {
|
yading@11
|
1586 c = (c<<8) + pkt->data[i];
|
yading@11
|
1587 if (c == 0x1b5) {
|
yading@11
|
1588 if ((pkt->data[i+1] & 0xf0) == 0x10) { // seq ext
|
yading@11
|
1589 st->codec->profile = pkt->data[i+1] & 0x07;
|
yading@11
|
1590 st->codec->level = pkt->data[i+2] >> 4;
|
yading@11
|
1591 } else if (i + 5 < pkt->size && (pkt->data[i+1] & 0xf0) == 0x80) { // pict coding ext
|
yading@11
|
1592 sc->interlaced = !(pkt->data[i+5] & 0x80); // progressive frame
|
yading@11
|
1593 if (sc->interlaced)
|
yading@11
|
1594 sc->field_dominance = 1 + !(pkt->data[i+4] & 0x80); // top field first
|
yading@11
|
1595 break;
|
yading@11
|
1596 }
|
yading@11
|
1597 } else if (c == 0x1b8) { // gop
|
yading@11
|
1598 if (pkt->data[i+4]>>6 & 0x01) { // closed
|
yading@11
|
1599 sc->closed_gop = 1;
|
yading@11
|
1600 if (e->flags & 0x40) // sequence header present
|
yading@11
|
1601 e->flags |= 0x80; // random access
|
yading@11
|
1602 }
|
yading@11
|
1603 } else if (c == 0x1b3) { // seq
|
yading@11
|
1604 e->flags |= 0x40;
|
yading@11
|
1605 switch ((pkt->data[i+4]>>4) & 0xf) {
|
yading@11
|
1606 case 2: sc->aspect_ratio = (AVRational){ 4, 3}; break;
|
yading@11
|
1607 case 3: sc->aspect_ratio = (AVRational){ 16, 9}; break;
|
yading@11
|
1608 case 4: sc->aspect_ratio = (AVRational){221,100}; break;
|
yading@11
|
1609 default:
|
yading@11
|
1610 av_reduce(&sc->aspect_ratio.num, &sc->aspect_ratio.den,
|
yading@11
|
1611 st->codec->width, st->codec->height, 1024*1024);
|
yading@11
|
1612 }
|
yading@11
|
1613 } else if (c == 0x100) { // pic
|
yading@11
|
1614 int pict_type = (pkt->data[i+2]>>3) & 0x07;
|
yading@11
|
1615 e->temporal_ref = (pkt->data[i+1]<<2) | (pkt->data[i+2]>>6);
|
yading@11
|
1616 if (pict_type == 2) { // P frame
|
yading@11
|
1617 e->flags |= 0x22;
|
yading@11
|
1618 sc->closed_gop = 0; // reset closed gop, don't matter anymore
|
yading@11
|
1619 } else if (pict_type == 3) { // B frame
|
yading@11
|
1620 if (sc->closed_gop)
|
yading@11
|
1621 e->flags |= 0x13; // only backward prediction
|
yading@11
|
1622 else
|
yading@11
|
1623 e->flags |= 0x33;
|
yading@11
|
1624 sc->temporal_reordering = -1;
|
yading@11
|
1625 } else if (!pict_type) {
|
yading@11
|
1626 av_log(s, AV_LOG_ERROR, "error parsing mpeg2 frame\n");
|
yading@11
|
1627 return 0;
|
yading@11
|
1628 }
|
yading@11
|
1629 }
|
yading@11
|
1630 }
|
yading@11
|
1631 if (s->oformat != &ff_mxf_d10_muxer)
|
yading@11
|
1632 sc->codec_ul = mxf_get_mpeg2_codec_ul(st->codec);
|
yading@11
|
1633 return !!sc->codec_ul;
|
yading@11
|
1634 }
|
yading@11
|
1635
|
yading@11
|
1636 static uint64_t mxf_parse_timestamp(time_t timestamp)
|
yading@11
|
1637 {
|
yading@11
|
1638 struct tm *time = gmtime(×tamp);
|
yading@11
|
1639 if (!time)
|
yading@11
|
1640 return 0;
|
yading@11
|
1641 return (uint64_t)(time->tm_year+1900) << 48 |
|
yading@11
|
1642 (uint64_t)(time->tm_mon+1) << 40 |
|
yading@11
|
1643 (uint64_t) time->tm_mday << 32 |
|
yading@11
|
1644 time->tm_hour << 24 |
|
yading@11
|
1645 time->tm_min << 16 |
|
yading@11
|
1646 time->tm_sec << 8;
|
yading@11
|
1647 }
|
yading@11
|
1648
|
yading@11
|
1649 static void mxf_gen_umid(AVFormatContext *s)
|
yading@11
|
1650 {
|
yading@11
|
1651 MXFContext *mxf = s->priv_data;
|
yading@11
|
1652 uint32_t seed = av_get_random_seed();
|
yading@11
|
1653 uint64_t umid = seed + 0x5294713400000000LL;
|
yading@11
|
1654
|
yading@11
|
1655 AV_WB64(mxf->umid , umid);
|
yading@11
|
1656 AV_WB64(mxf->umid+8, umid>>8);
|
yading@11
|
1657
|
yading@11
|
1658 mxf->instance_number = seed;
|
yading@11
|
1659 }
|
yading@11
|
1660
|
yading@11
|
1661 static int mxf_write_header(AVFormatContext *s)
|
yading@11
|
1662 {
|
yading@11
|
1663 MXFContext *mxf = s->priv_data;
|
yading@11
|
1664 int i, ret;
|
yading@11
|
1665 uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0};
|
yading@11
|
1666 const MXFSamplesPerFrame *spf = NULL;
|
yading@11
|
1667 AVDictionaryEntry *t;
|
yading@11
|
1668 int64_t timestamp = 0;
|
yading@11
|
1669 AVDictionaryEntry *tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
|
yading@11
|
1670
|
yading@11
|
1671 if (!s->nb_streams)
|
yading@11
|
1672 return -1;
|
yading@11
|
1673
|
yading@11
|
1674 for (i = 0; i < s->nb_streams; i++) {
|
yading@11
|
1675 AVStream *st = s->streams[i];
|
yading@11
|
1676 MXFStreamContext *sc = av_mallocz(sizeof(*sc));
|
yading@11
|
1677 if (!sc)
|
yading@11
|
1678 return AVERROR(ENOMEM);
|
yading@11
|
1679 st->priv_data = sc;
|
yading@11
|
1680
|
yading@11
|
1681 if ((i == 0) ^ (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)) {
|
yading@11
|
1682 av_log(s, AV_LOG_ERROR, "there must be exactly one video stream and it must be the first one\n");
|
yading@11
|
1683 return -1;
|
yading@11
|
1684 }
|
yading@11
|
1685
|
yading@11
|
1686 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
|
yading@11
|
1687 AVRational rate, tbc = st->codec->time_base;
|
yading@11
|
1688 // Default component depth to 8
|
yading@11
|
1689 sc->component_depth = 8;
|
yading@11
|
1690 mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num;
|
yading@11
|
1691 spf = ff_mxf_get_samples_per_frame(s, tbc);
|
yading@11
|
1692 if (!spf) {
|
yading@11
|
1693 av_log(s, AV_LOG_ERROR, "Unsupported video frame rate %d/%d\n",
|
yading@11
|
1694 tbc.den, tbc.num);
|
yading@11
|
1695 return AVERROR(EINVAL);
|
yading@11
|
1696 }
|
yading@11
|
1697 mxf->time_base = spf->time_base;
|
yading@11
|
1698 rate = av_inv_q(mxf->time_base);
|
yading@11
|
1699 avpriv_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den);
|
yading@11
|
1700 if (!tcr)
|
yading@11
|
1701 tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
|
yading@11
|
1702 if (tcr)
|
yading@11
|
1703 ret = av_timecode_init_from_string(&mxf->tc, rate, tcr->value, s);
|
yading@11
|
1704 else
|
yading@11
|
1705 ret = av_timecode_init(&mxf->tc, rate, 0, 0, s);
|
yading@11
|
1706 if (ret < 0)
|
yading@11
|
1707 return ret;
|
yading@11
|
1708 if (s->oformat == &ff_mxf_d10_muxer) {
|
yading@11
|
1709 if (st->codec->bit_rate == 50000000) {
|
yading@11
|
1710 if (mxf->time_base.den == 25) sc->index = 3;
|
yading@11
|
1711 else sc->index = 5;
|
yading@11
|
1712 } else if (st->codec->bit_rate == 40000000) {
|
yading@11
|
1713 if (mxf->time_base.den == 25) sc->index = 7;
|
yading@11
|
1714 else sc->index = 9;
|
yading@11
|
1715 } else if (st->codec->bit_rate == 30000000) {
|
yading@11
|
1716 if (mxf->time_base.den == 25) sc->index = 11;
|
yading@11
|
1717 else sc->index = 13;
|
yading@11
|
1718 } else {
|
yading@11
|
1719 av_log(s, AV_LOG_ERROR, "error MXF D-10 only support 30/40/50 mbit/s\n");
|
yading@11
|
1720 return -1;
|
yading@11
|
1721 }
|
yading@11
|
1722
|
yading@11
|
1723 mxf->edit_unit_byte_count = KAG_SIZE; // system element
|
yading@11
|
1724 mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)st->codec->bit_rate *
|
yading@11
|
1725 mxf->time_base.num / (8*mxf->time_base.den);
|
yading@11
|
1726 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
|
yading@11
|
1727 mxf->edit_unit_byte_count += 16 + 4 + 4 + spf->samples_per_frame[0]*8*4;
|
yading@11
|
1728 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
|
yading@11
|
1729 }
|
yading@11
|
1730 } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
|
yading@11
|
1731 if (st->codec->sample_rate != 48000) {
|
yading@11
|
1732 av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n");
|
yading@11
|
1733 return -1;
|
yading@11
|
1734 }
|
yading@11
|
1735 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
|
yading@11
|
1736 if (s->oformat == &ff_mxf_d10_muxer) {
|
yading@11
|
1737 if (st->index != 1) {
|
yading@11
|
1738 av_log(s, AV_LOG_ERROR, "MXF D-10 only support one audio track\n");
|
yading@11
|
1739 return -1;
|
yading@11
|
1740 }
|
yading@11
|
1741 if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE &&
|
yading@11
|
1742 st->codec->codec_id != AV_CODEC_ID_PCM_S24LE) {
|
yading@11
|
1743 av_log(s, AV_LOG_ERROR, "MXF D-10 only support 16 or 24 bits le audio\n");
|
yading@11
|
1744 }
|
yading@11
|
1745 sc->index = ((MXFStreamContext*)s->streams[0]->priv_data)->index + 1;
|
yading@11
|
1746 } else
|
yading@11
|
1747 mxf->slice_count = 1;
|
yading@11
|
1748 }
|
yading@11
|
1749
|
yading@11
|
1750 if (!sc->index) {
|
yading@11
|
1751 sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id);
|
yading@11
|
1752 if (sc->index == -1) {
|
yading@11
|
1753 av_log(s, AV_LOG_ERROR, "track %d: could not find essence container ul, "
|
yading@11
|
1754 "codec not currently supported in container\n", i);
|
yading@11
|
1755 return -1;
|
yading@11
|
1756 }
|
yading@11
|
1757 }
|
yading@11
|
1758
|
yading@11
|
1759 sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;
|
yading@11
|
1760
|
yading@11
|
1761 memcpy(sc->track_essence_element_key, mxf_essence_container_uls[sc->index].element_ul, 15);
|
yading@11
|
1762 sc->track_essence_element_key[15] = present[sc->index];
|
yading@11
|
1763 PRINT_KEY(s, "track essence element key", sc->track_essence_element_key);
|
yading@11
|
1764
|
yading@11
|
1765 if (!present[sc->index])
|
yading@11
|
1766 mxf->essence_container_count++;
|
yading@11
|
1767 present[sc->index]++;
|
yading@11
|
1768 }
|
yading@11
|
1769
|
yading@11
|
1770 if (s->oformat == &ff_mxf_d10_muxer) {
|
yading@11
|
1771 mxf->essence_container_count = 1;
|
yading@11
|
1772 }
|
yading@11
|
1773
|
yading@11
|
1774 if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
|
yading@11
|
1775 mxf_gen_umid(s);
|
yading@11
|
1776
|
yading@11
|
1777 for (i = 0; i < s->nb_streams; i++) {
|
yading@11
|
1778 MXFStreamContext *sc = s->streams[i]->priv_data;
|
yading@11
|
1779 // update element count
|
yading@11
|
1780 sc->track_essence_element_key[13] = present[sc->index];
|
yading@11
|
1781 if (!memcmp(sc->track_essence_element_key, mxf_essence_container_uls[15].element_ul, 13)) // DV
|
yading@11
|
1782 sc->order = (0x15 << 24) | AV_RB32(sc->track_essence_element_key+13);
|
yading@11
|
1783 else
|
yading@11
|
1784 sc->order = AV_RB32(sc->track_essence_element_key+12);
|
yading@11
|
1785 }
|
yading@11
|
1786
|
yading@11
|
1787 if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
|
yading@11
|
1788 timestamp = ff_iso8601_to_unix_time(t->value);
|
yading@11
|
1789 if (timestamp)
|
yading@11
|
1790 mxf->timestamp = mxf_parse_timestamp(timestamp);
|
yading@11
|
1791 mxf->duration = -1;
|
yading@11
|
1792
|
yading@11
|
1793 mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track));
|
yading@11
|
1794 if (!mxf->timecode_track)
|
yading@11
|
1795 return AVERROR(ENOMEM);
|
yading@11
|
1796 mxf->timecode_track->priv_data = av_mallocz(sizeof(MXFStreamContext));
|
yading@11
|
1797 if (!mxf->timecode_track->priv_data)
|
yading@11
|
1798 return AVERROR(ENOMEM);
|
yading@11
|
1799 mxf->timecode_track->index = -1;
|
yading@11
|
1800
|
yading@11
|
1801 if (!spf)
|
yading@11
|
1802 spf = ff_mxf_get_samples_per_frame(s, (AVRational){ 1, 25 });
|
yading@11
|
1803
|
yading@11
|
1804 if (ff_audio_interleave_init(s, spf->samples_per_frame, mxf->time_base) < 0)
|
yading@11
|
1805 return -1;
|
yading@11
|
1806
|
yading@11
|
1807 return 0;
|
yading@11
|
1808 }
|
yading@11
|
1809
|
yading@11
|
1810 static const uint8_t system_metadata_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x01,0x00 };
|
yading@11
|
1811 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 };
|
yading@11
|
1812
|
yading@11
|
1813 static void mxf_write_system_item(AVFormatContext *s)
|
yading@11
|
1814 {
|
yading@11
|
1815 MXFContext *mxf = s->priv_data;
|
yading@11
|
1816 AVIOContext *pb = s->pb;
|
yading@11
|
1817 unsigned frame;
|
yading@11
|
1818 uint32_t time_code;
|
yading@11
|
1819
|
yading@11
|
1820 frame = mxf->last_indexed_edit_unit + mxf->edit_units_count;
|
yading@11
|
1821
|
yading@11
|
1822 // write system metadata pack
|
yading@11
|
1823 avio_write(pb, system_metadata_pack_key, 16);
|
yading@11
|
1824 klv_encode_ber4_length(pb, 57);
|
yading@11
|
1825 avio_w8(pb, 0x5c); // UL, user date/time stamp, picture and sound item present
|
yading@11
|
1826 avio_w8(pb, 0x04); // content package rate
|
yading@11
|
1827 avio_w8(pb, 0x00); // content package type
|
yading@11
|
1828 avio_wb16(pb, 0x00); // channel handle
|
yading@11
|
1829 avio_wb16(pb, (mxf->tc.start + frame) & 0xFFFF); // continuity count, supposed to overflow
|
yading@11
|
1830 if (mxf->essence_container_count > 1)
|
yading@11
|
1831 avio_write(pb, multiple_desc_ul, 16);
|
yading@11
|
1832 else {
|
yading@11
|
1833 MXFStreamContext *sc = s->streams[0]->priv_data;
|
yading@11
|
1834 avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
|
yading@11
|
1835 }
|
yading@11
|
1836 avio_w8(pb, 0);
|
yading@11
|
1837 avio_wb64(pb, 0);
|
yading@11
|
1838 avio_wb64(pb, 0); // creation date/time stamp
|
yading@11
|
1839
|
yading@11
|
1840 avio_w8(pb, 0x81); // SMPTE 12M time code
|
yading@11
|
1841 time_code = av_timecode_get_smpte_from_framenum(&mxf->tc, frame);
|
yading@11
|
1842 avio_wb32(pb, time_code);
|
yading@11
|
1843 avio_wb32(pb, 0); // binary group data
|
yading@11
|
1844 avio_wb64(pb, 0);
|
yading@11
|
1845
|
yading@11
|
1846 // write system metadata package set
|
yading@11
|
1847 avio_write(pb, system_metadata_package_set_key, 16);
|
yading@11
|
1848 klv_encode_ber4_length(pb, 35);
|
yading@11
|
1849 avio_w8(pb, 0x83); // UMID
|
yading@11
|
1850 avio_wb16(pb, 0x20);
|
yading@11
|
1851 mxf_write_umid(s, 1);
|
yading@11
|
1852 }
|
yading@11
|
1853
|
yading@11
|
1854 static void mxf_write_d10_video_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
|
yading@11
|
1855 {
|
yading@11
|
1856 MXFContext *mxf = s->priv_data;
|
yading@11
|
1857 AVIOContext *pb = s->pb;
|
yading@11
|
1858 int packet_size = (uint64_t)st->codec->bit_rate*mxf->time_base.num /
|
yading@11
|
1859 (8*mxf->time_base.den); // frame size
|
yading@11
|
1860 int pad;
|
yading@11
|
1861
|
yading@11
|
1862 packet_size += 16 + 4;
|
yading@11
|
1863 packet_size += klv_fill_size(packet_size);
|
yading@11
|
1864
|
yading@11
|
1865 klv_encode_ber4_length(pb, pkt->size);
|
yading@11
|
1866 avio_write(pb, pkt->data, pkt->size);
|
yading@11
|
1867
|
yading@11
|
1868 // ensure CBR muxing by padding to correct video frame size
|
yading@11
|
1869 pad = packet_size - pkt->size - 16 - 4;
|
yading@11
|
1870 if (pad > 20) {
|
yading@11
|
1871 avio_write(s->pb, klv_fill_key, 16);
|
yading@11
|
1872 pad -= 16 + 4;
|
yading@11
|
1873 klv_encode_ber4_length(s->pb, pad);
|
yading@11
|
1874 for (; pad; pad--)
|
yading@11
|
1875 avio_w8(s->pb, 0);
|
yading@11
|
1876 av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1)));
|
yading@11
|
1877 } else {
|
yading@11
|
1878 av_log(s, AV_LOG_WARNING, "cannot fill d-10 video packet\n");
|
yading@11
|
1879 for (; pad > 0; pad--)
|
yading@11
|
1880 avio_w8(s->pb, 0);
|
yading@11
|
1881 }
|
yading@11
|
1882 }
|
yading@11
|
1883
|
yading@11
|
1884 static void mxf_write_d10_audio_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
|
yading@11
|
1885 {
|
yading@11
|
1886 MXFContext *mxf = s->priv_data;
|
yading@11
|
1887 AVIOContext *pb = s->pb;
|
yading@11
|
1888 int frame_size = pkt->size / st->codec->block_align;
|
yading@11
|
1889 uint8_t *samples = pkt->data;
|
yading@11
|
1890 uint8_t *end = pkt->data + pkt->size;
|
yading@11
|
1891 int i;
|
yading@11
|
1892
|
yading@11
|
1893 klv_encode_ber4_length(pb, 4 + frame_size*4*8);
|
yading@11
|
1894
|
yading@11
|
1895 avio_w8(pb, (frame_size == 1920 ? 0 : (mxf->edit_units_count-1) % 5 + 1));
|
yading@11
|
1896 avio_wl16(pb, frame_size);
|
yading@11
|
1897 avio_w8(pb, (1<<st->codec->channels)-1);
|
yading@11
|
1898
|
yading@11
|
1899 while (samples < end) {
|
yading@11
|
1900 for (i = 0; i < st->codec->channels; i++) {
|
yading@11
|
1901 uint32_t sample;
|
yading@11
|
1902 if (st->codec->codec_id == AV_CODEC_ID_PCM_S24LE) {
|
yading@11
|
1903 sample = AV_RL24(samples)<< 4;
|
yading@11
|
1904 samples += 3;
|
yading@11
|
1905 } else {
|
yading@11
|
1906 sample = AV_RL16(samples)<<12;
|
yading@11
|
1907 samples += 2;
|
yading@11
|
1908 }
|
yading@11
|
1909 avio_wl32(pb, sample | i);
|
yading@11
|
1910 }
|
yading@11
|
1911 for (; i < 8; i++)
|
yading@11
|
1912 avio_wl32(pb, i);
|
yading@11
|
1913 }
|
yading@11
|
1914 }
|
yading@11
|
1915
|
yading@11
|
1916 static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt)
|
yading@11
|
1917 {
|
yading@11
|
1918 MXFContext *mxf = s->priv_data;
|
yading@11
|
1919 AVIOContext *pb = s->pb;
|
yading@11
|
1920 AVStream *st = s->streams[pkt->stream_index];
|
yading@11
|
1921 MXFStreamContext *sc = st->priv_data;
|
yading@11
|
1922 MXFIndexEntry ie = {0};
|
yading@11
|
1923
|
yading@11
|
1924 if (!mxf->edit_unit_byte_count && !(mxf->edit_units_count % EDIT_UNITS_PER_BODY)) {
|
yading@11
|
1925 mxf->index_entries = av_realloc(mxf->index_entries,
|
yading@11
|
1926 (mxf->edit_units_count + EDIT_UNITS_PER_BODY)*sizeof(*mxf->index_entries));
|
yading@11
|
1927 if (!mxf->index_entries) {
|
yading@11
|
1928 av_log(s, AV_LOG_ERROR, "could not allocate index entries\n");
|
yading@11
|
1929 return -1;
|
yading@11
|
1930 }
|
yading@11
|
1931 }
|
yading@11
|
1932
|
yading@11
|
1933 if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
|
yading@11
|
1934 if (!mxf_parse_mpeg2_frame(s, st, pkt, &ie)) {
|
yading@11
|
1935 av_log(s, AV_LOG_ERROR, "could not get mpeg2 profile and level\n");
|
yading@11
|
1936 return -1;
|
yading@11
|
1937 }
|
yading@11
|
1938 } else if (st->codec->codec_id == AV_CODEC_ID_DNXHD) {
|
yading@11
|
1939 if (!mxf_parse_dnxhd_frame(s, st, pkt)) {
|
yading@11
|
1940 av_log(s, AV_LOG_ERROR, "could not get dnxhd profile\n");
|
yading@11
|
1941 return -1;
|
yading@11
|
1942 }
|
yading@11
|
1943 } else if (st->codec->codec_id == AV_CODEC_ID_DVVIDEO) {
|
yading@11
|
1944 if (!mxf_parse_dv_frame(s, st, pkt)) {
|
yading@11
|
1945 av_log(s, AV_LOG_ERROR, "could not get dv profile\n");
|
yading@11
|
1946 return -1;
|
yading@11
|
1947 }
|
yading@11
|
1948 }
|
yading@11
|
1949
|
yading@11
|
1950 if (!mxf->header_written) {
|
yading@11
|
1951 if (mxf->edit_unit_byte_count) {
|
yading@11
|
1952 mxf_write_partition(s, 1, 2, header_open_partition_key, 1);
|
yading@11
|
1953 mxf_write_klv_fill(s);
|
yading@11
|
1954 mxf_write_index_table_segment(s);
|
yading@11
|
1955 } else {
|
yading@11
|
1956 mxf_write_partition(s, 0, 0, header_open_partition_key, 1);
|
yading@11
|
1957 }
|
yading@11
|
1958 mxf->header_written = 1;
|
yading@11
|
1959 }
|
yading@11
|
1960
|
yading@11
|
1961 if (st->index == 0) {
|
yading@11
|
1962 if (!mxf->edit_unit_byte_count &&
|
yading@11
|
1963 (!mxf->edit_units_count || mxf->edit_units_count > EDIT_UNITS_PER_BODY) &&
|
yading@11
|
1964 !(ie.flags & 0x33)) { // I frame, Gop start
|
yading@11
|
1965 mxf_write_klv_fill(s);
|
yading@11
|
1966 mxf_write_partition(s, 1, 2, body_partition_key, 0);
|
yading@11
|
1967
|
yading@11
|
1968 mxf_write_klv_fill(s);
|
yading@11
|
1969 mxf_write_index_table_segment(s);
|
yading@11
|
1970 }
|
yading@11
|
1971
|
yading@11
|
1972 mxf_write_klv_fill(s);
|
yading@11
|
1973 mxf_write_system_item(s);
|
yading@11
|
1974
|
yading@11
|
1975 if (!mxf->edit_unit_byte_count) {
|
yading@11
|
1976 mxf->index_entries[mxf->edit_units_count].offset = mxf->body_offset;
|
yading@11
|
1977 mxf->index_entries[mxf->edit_units_count].flags = ie.flags;
|
yading@11
|
1978 mxf->index_entries[mxf->edit_units_count].temporal_ref = ie.temporal_ref;
|
yading@11
|
1979 mxf->body_offset += KAG_SIZE; // size of system element
|
yading@11
|
1980 }
|
yading@11
|
1981 mxf->edit_units_count++;
|
yading@11
|
1982 } else if (!mxf->edit_unit_byte_count && st->index == 1) {
|
yading@11
|
1983 mxf->index_entries[mxf->edit_units_count-1].slice_offset =
|
yading@11
|
1984 mxf->body_offset - mxf->index_entries[mxf->edit_units_count-1].offset;
|
yading@11
|
1985 }
|
yading@11
|
1986
|
yading@11
|
1987 mxf_write_klv_fill(s);
|
yading@11
|
1988 avio_write(pb, sc->track_essence_element_key, 16); // write key
|
yading@11
|
1989 if (s->oformat == &ff_mxf_d10_muxer) {
|
yading@11
|
1990 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
yading@11
|
1991 mxf_write_d10_video_packet(s, st, pkt);
|
yading@11
|
1992 else
|
yading@11
|
1993 mxf_write_d10_audio_packet(s, st, pkt);
|
yading@11
|
1994 } else {
|
yading@11
|
1995 klv_encode_ber4_length(pb, pkt->size); // write length
|
yading@11
|
1996 avio_write(pb, pkt->data, pkt->size);
|
yading@11
|
1997 mxf->body_offset += 16+4+pkt->size + klv_fill_size(16+4+pkt->size);
|
yading@11
|
1998 }
|
yading@11
|
1999
|
yading@11
|
2000 avio_flush(pb);
|
yading@11
|
2001
|
yading@11
|
2002 return 0;
|
yading@11
|
2003 }
|
yading@11
|
2004
|
yading@11
|
2005 static void mxf_write_random_index_pack(AVFormatContext *s)
|
yading@11
|
2006 {
|
yading@11
|
2007 MXFContext *mxf = s->priv_data;
|
yading@11
|
2008 AVIOContext *pb = s->pb;
|
yading@11
|
2009 uint64_t pos = avio_tell(pb);
|
yading@11
|
2010 int i;
|
yading@11
|
2011
|
yading@11
|
2012 avio_write(pb, random_index_pack_key, 16);
|
yading@11
|
2013 klv_encode_ber_length(pb, 28 + 12LL*mxf->body_partitions_count);
|
yading@11
|
2014
|
yading@11
|
2015 if (mxf->edit_unit_byte_count)
|
yading@11
|
2016 avio_wb32(pb, 1); // BodySID of header partition
|
yading@11
|
2017 else
|
yading@11
|
2018 avio_wb32(pb, 0);
|
yading@11
|
2019 avio_wb64(pb, 0); // offset of header partition
|
yading@11
|
2020
|
yading@11
|
2021 for (i = 0; i < mxf->body_partitions_count; i++) {
|
yading@11
|
2022 avio_wb32(pb, 1); // BodySID
|
yading@11
|
2023 avio_wb64(pb, mxf->body_partition_offset[i]);
|
yading@11
|
2024 }
|
yading@11
|
2025
|
yading@11
|
2026 avio_wb32(pb, 0); // BodySID of footer partition
|
yading@11
|
2027 avio_wb64(pb, mxf->footer_partition_offset);
|
yading@11
|
2028
|
yading@11
|
2029 avio_wb32(pb, avio_tell(pb) - pos + 4);
|
yading@11
|
2030 }
|
yading@11
|
2031
|
yading@11
|
2032 static int mxf_write_footer(AVFormatContext *s)
|
yading@11
|
2033 {
|
yading@11
|
2034 MXFContext *mxf = s->priv_data;
|
yading@11
|
2035 AVIOContext *pb = s->pb;
|
yading@11
|
2036
|
yading@11
|
2037 mxf->duration = mxf->last_indexed_edit_unit + mxf->edit_units_count;
|
yading@11
|
2038
|
yading@11
|
2039 mxf_write_klv_fill(s);
|
yading@11
|
2040 mxf->footer_partition_offset = avio_tell(pb);
|
yading@11
|
2041 if (mxf->edit_unit_byte_count) { // no need to repeat index
|
yading@11
|
2042 mxf_write_partition(s, 0, 0, footer_partition_key, 0);
|
yading@11
|
2043 } else {
|
yading@11
|
2044 mxf_write_partition(s, 0, 2, footer_partition_key, 0);
|
yading@11
|
2045
|
yading@11
|
2046 mxf_write_klv_fill(s);
|
yading@11
|
2047 mxf_write_index_table_segment(s);
|
yading@11
|
2048 }
|
yading@11
|
2049
|
yading@11
|
2050 mxf_write_klv_fill(s);
|
yading@11
|
2051 mxf_write_random_index_pack(s);
|
yading@11
|
2052
|
yading@11
|
2053 if (s->pb->seekable) {
|
yading@11
|
2054 avio_seek(pb, 0, SEEK_SET);
|
yading@11
|
2055 if (mxf->edit_unit_byte_count) {
|
yading@11
|
2056 mxf_write_partition(s, 1, 2, header_closed_partition_key, 1);
|
yading@11
|
2057 mxf_write_klv_fill(s);
|
yading@11
|
2058 mxf_write_index_table_segment(s);
|
yading@11
|
2059 } else {
|
yading@11
|
2060 mxf_write_partition(s, 0, 0, header_closed_partition_key, 1);
|
yading@11
|
2061 }
|
yading@11
|
2062 }
|
yading@11
|
2063
|
yading@11
|
2064 ff_audio_interleave_close(s);
|
yading@11
|
2065
|
yading@11
|
2066 av_freep(&mxf->index_entries);
|
yading@11
|
2067 av_freep(&mxf->body_partition_offset);
|
yading@11
|
2068 av_freep(&mxf->timecode_track->priv_data);
|
yading@11
|
2069 av_freep(&mxf->timecode_track);
|
yading@11
|
2070
|
yading@11
|
2071 mxf_free(s);
|
yading@11
|
2072
|
yading@11
|
2073 return 0;
|
yading@11
|
2074 }
|
yading@11
|
2075
|
yading@11
|
2076 static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
|
yading@11
|
2077 {
|
yading@11
|
2078 int i, stream_count = 0;
|
yading@11
|
2079
|
yading@11
|
2080 for (i = 0; i < s->nb_streams; i++)
|
yading@11
|
2081 stream_count += !!s->streams[i]->last_in_packet_buffer;
|
yading@11
|
2082
|
yading@11
|
2083 if (stream_count && (s->nb_streams == stream_count || flush)) {
|
yading@11
|
2084 AVPacketList *pktl = s->packet_buffer;
|
yading@11
|
2085 if (s->nb_streams != stream_count) {
|
yading@11
|
2086 AVPacketList *last = NULL;
|
yading@11
|
2087 // find last packet in edit unit
|
yading@11
|
2088 while (pktl) {
|
yading@11
|
2089 if (!stream_count || pktl->pkt.stream_index == 0)
|
yading@11
|
2090 break;
|
yading@11
|
2091 last = pktl;
|
yading@11
|
2092 pktl = pktl->next;
|
yading@11
|
2093 stream_count--;
|
yading@11
|
2094 }
|
yading@11
|
2095 // purge packet queue
|
yading@11
|
2096 while (pktl) {
|
yading@11
|
2097 AVPacketList *next = pktl->next;
|
yading@11
|
2098
|
yading@11
|
2099 if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl)
|
yading@11
|
2100 s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL;
|
yading@11
|
2101 av_free_packet(&pktl->pkt);
|
yading@11
|
2102 av_freep(&pktl);
|
yading@11
|
2103 pktl = next;
|
yading@11
|
2104 }
|
yading@11
|
2105 if (last)
|
yading@11
|
2106 last->next = NULL;
|
yading@11
|
2107 else {
|
yading@11
|
2108 s->packet_buffer = NULL;
|
yading@11
|
2109 s->packet_buffer_end= NULL;
|
yading@11
|
2110 goto out;
|
yading@11
|
2111 }
|
yading@11
|
2112 pktl = s->packet_buffer;
|
yading@11
|
2113 }
|
yading@11
|
2114
|
yading@11
|
2115 *out = pktl->pkt;
|
yading@11
|
2116 av_dlog(s, "out st:%d dts:%"PRId64"\n", (*out).stream_index, (*out).dts);
|
yading@11
|
2117 s->packet_buffer = pktl->next;
|
yading@11
|
2118 if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl)
|
yading@11
|
2119 s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL;
|
yading@11
|
2120 if(!s->packet_buffer)
|
yading@11
|
2121 s->packet_buffer_end= NULL;
|
yading@11
|
2122 av_freep(&pktl);
|
yading@11
|
2123 return 1;
|
yading@11
|
2124 } else {
|
yading@11
|
2125 out:
|
yading@11
|
2126 av_init_packet(out);
|
yading@11
|
2127 return 0;
|
yading@11
|
2128 }
|
yading@11
|
2129 }
|
yading@11
|
2130
|
yading@11
|
2131 static int mxf_compare_timestamps(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
|
yading@11
|
2132 {
|
yading@11
|
2133 MXFStreamContext *sc = s->streams[pkt ->stream_index]->priv_data;
|
yading@11
|
2134 MXFStreamContext *sc2 = s->streams[next->stream_index]->priv_data;
|
yading@11
|
2135
|
yading@11
|
2136 return next->dts > pkt->dts ||
|
yading@11
|
2137 (next->dts == pkt->dts && sc->order < sc2->order);
|
yading@11
|
2138 }
|
yading@11
|
2139
|
yading@11
|
2140 static int mxf_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
|
yading@11
|
2141 {
|
yading@11
|
2142 return ff_audio_rechunk_interleave(s, out, pkt, flush,
|
yading@11
|
2143 mxf_interleave_get_packet, mxf_compare_timestamps);
|
yading@11
|
2144 }
|
yading@11
|
2145
|
yading@11
|
2146 AVOutputFormat ff_mxf_muxer = {
|
yading@11
|
2147 .name = "mxf",
|
yading@11
|
2148 .long_name = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format)"),
|
yading@11
|
2149 .mime_type = "application/mxf",
|
yading@11
|
2150 .extensions = "mxf",
|
yading@11
|
2151 .priv_data_size = sizeof(MXFContext),
|
yading@11
|
2152 .audio_codec = AV_CODEC_ID_PCM_S16LE,
|
yading@11
|
2153 .video_codec = AV_CODEC_ID_MPEG2VIDEO,
|
yading@11
|
2154 .write_header = mxf_write_header,
|
yading@11
|
2155 .write_packet = mxf_write_packet,
|
yading@11
|
2156 .write_trailer = mxf_write_footer,
|
yading@11
|
2157 .flags = AVFMT_NOTIMESTAMPS,
|
yading@11
|
2158 .interleave_packet = mxf_interleave,
|
yading@11
|
2159 };
|
yading@11
|
2160
|
yading@11
|
2161 AVOutputFormat ff_mxf_d10_muxer = {
|
yading@11
|
2162 .name = "mxf_d10",
|
yading@11
|
2163 .long_name = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format) D-10 Mapping"),
|
yading@11
|
2164 .mime_type = "application/mxf",
|
yading@11
|
2165 .priv_data_size = sizeof(MXFContext),
|
yading@11
|
2166 .audio_codec = AV_CODEC_ID_PCM_S16LE,
|
yading@11
|
2167 .video_codec = AV_CODEC_ID_MPEG2VIDEO,
|
yading@11
|
2168 .write_header = mxf_write_header,
|
yading@11
|
2169 .write_packet = mxf_write_packet,
|
yading@11
|
2170 .write_trailer = mxf_write_footer,
|
yading@11
|
2171 .flags = AVFMT_NOTIMESTAMPS,
|
yading@11
|
2172 .interleave_packet = mxf_interleave,
|
yading@11
|
2173 };
|