00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <math.h>
00036 #include <time.h>
00037
00038 #include "libavutil/opt.h"
00039 #include "libavutil/random_seed.h"
00040 #include "libavutil/timecode.h"
00041 #include "libavutil/avassert.h"
00042 #include "libavcodec/bytestream.h"
00043 #include "libavcodec/dnxhddata.h"
00044 #include "audiointerleave.h"
00045 #include "avformat.h"
00046 #include "internal.h"
00047 #include "mxf.h"
00048 #include "config.h"
00049
00050 extern AVOutputFormat ff_mxf_d10_muxer;
00051
00052 #define EDIT_UNITS_PER_BODY 250
00053 #define KAG_SIZE 512
00054
00055 typedef struct {
00056 int local_tag;
00057 UID uid;
00058 } MXFLocalTagPair;
00059
00060 typedef struct {
00061 uint8_t flags;
00062 uint64_t offset;
00063 unsigned slice_offset;
00064 uint16_t temporal_ref;
00065 } MXFIndexEntry;
00066
00067 typedef struct {
00068 AudioInterleaveContext aic;
00069 UID track_essence_element_key;
00070 int index;
00071 const UID *codec_ul;
00072 int order;
00073 int interlaced;
00074 int field_dominance;
00075 int component_depth;
00076 int temporal_reordering;
00077 AVRational aspect_ratio;
00078 int closed_gop;
00079 } MXFStreamContext;
00080
00081 typedef struct {
00082 UID container_ul;
00083 UID element_ul;
00084 UID codec_ul;
00085 void (*write_desc)(AVFormatContext *, AVStream *);
00086 } MXFContainerEssenceEntry;
00087
00088 static const struct {
00089 enum AVCodecID id;
00090 int index;
00091 } mxf_essence_mappings[] = {
00092 { AV_CODEC_ID_MPEG2VIDEO, 0 },
00093 { AV_CODEC_ID_PCM_S24LE, 1 },
00094 { AV_CODEC_ID_PCM_S16LE, 1 },
00095 { AV_CODEC_ID_DVVIDEO, 15 },
00096 { AV_CODEC_ID_DNXHD, 24 },
00097 { AV_CODEC_ID_NONE }
00098 };
00099
00100 static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st);
00101 static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st);
00102 static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st);
00103 static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st);
00104 static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st);
00105
00106 static const MXFContainerEssenceEntry mxf_essence_container_uls[] = {
00107 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 },
00108 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
00109 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x00,0x00,0x00 },
00110 mxf_write_mpegvideo_desc },
00111 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x03,0x00 },
00112 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x03,0x00 },
00113 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00114 mxf_write_aes3_desc },
00115 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 },
00116 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x01,0x00 },
00117 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00118 mxf_write_wav_desc },
00119
00120 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 },
00121 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
00122 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 },
00123 mxf_write_cdci_desc },
00124 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 },
00125 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
00126 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00127 mxf_write_generic_sound_desc },
00128
00129 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 },
00130 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
00131 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x02 },
00132 mxf_write_cdci_desc },
00133 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 },
00134 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
00135 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00136 mxf_write_generic_sound_desc },
00137
00138 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 },
00139 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
00140 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x03 },
00141 mxf_write_cdci_desc },
00142 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 },
00143 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
00144 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00145 mxf_write_generic_sound_desc },
00146
00147 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 },
00148 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
00149 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x04 },
00150 mxf_write_cdci_desc },
00151 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 },
00152 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
00153 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00154 mxf_write_generic_sound_desc },
00155
00156 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 },
00157 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
00158 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x05 },
00159 mxf_write_cdci_desc },
00160 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 },
00161 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
00162 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00163 mxf_write_generic_sound_desc },
00164
00165 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 },
00166 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
00167 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x06 },
00168 mxf_write_cdci_desc },
00169 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 },
00170 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
00171 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00172 mxf_write_generic_sound_desc },
00173
00174 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x7F,0x01 },
00175 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
00176 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x00,0x00,0x00 },
00177 mxf_write_cdci_desc },
00178
00179 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x40,0x01 },
00180 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
00181 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x01,0x00 },
00182 mxf_write_cdci_desc },
00183
00184 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,0x01 },
00185 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
00186 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x02,0x00 },
00187 mxf_write_cdci_desc },
00188
00189 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x50,0x01 },
00190 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
00191 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x03,0x00 },
00192 mxf_write_cdci_desc },
00193
00194 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x51,0x01 },
00195 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
00196 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x04,0x00 },
00197 mxf_write_cdci_desc },
00198
00199 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x60,0x01 },
00200 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
00201 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x05,0x00 },
00202 mxf_write_cdci_desc },
00203
00204 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x61,0x01 },
00205 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
00206 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x06,0x00 },
00207 mxf_write_cdci_desc },
00208
00209 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x62,0x01 },
00210 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
00211 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x07,0x00 },
00212 mxf_write_cdci_desc },
00213
00214 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x63,0x01 },
00215 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 },
00216 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x08,0x00 },
00217 mxf_write_cdci_desc },
00218
00219 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
00220 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
00221 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x01,0x00,0x00 },
00222 mxf_write_cdci_desc },
00223
00224 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
00225 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
00226 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x03,0x00,0x00 },
00227 mxf_write_cdci_desc },
00228
00229 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
00230 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
00231 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x04,0x00,0x00 },
00232 mxf_write_cdci_desc },
00233
00234 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
00235 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
00236 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x07,0x00,0x00 },
00237 mxf_write_cdci_desc },
00238
00239 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
00240 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
00241 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x08,0x00,0x00 },
00242 mxf_write_cdci_desc },
00243
00244 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
00245 { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
00246 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x09,0x00,0x00 },
00247 mxf_write_cdci_desc },
00248
00249 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
00250 { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
00251 { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x10,0x00,0x00 },
00252 mxf_write_cdci_desc },
00253
00254 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
00255 { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
00256 { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x11,0x00,0x00 },
00257 mxf_write_cdci_desc },
00258
00259 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
00260 { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
00261 { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x12,0x00,0x00 },
00262 mxf_write_cdci_desc },
00263
00264 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
00265 { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
00266 { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x13,0x00,0x00 },
00267 mxf_write_cdci_desc },
00268 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
00269 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
00270 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
00271 NULL },
00272 };
00273
00274 typedef struct MXFContext {
00275 AVClass *av_class;
00276 int64_t footer_partition_offset;
00277 int essence_container_count;
00278 AVRational time_base;
00279 int header_written;
00280 MXFIndexEntry *index_entries;
00281 unsigned edit_units_count;
00282 uint64_t timestamp;
00283 uint8_t slice_count;
00284 int last_indexed_edit_unit;
00285 uint64_t *body_partition_offset;
00286 unsigned body_partitions_count;
00287 int last_key_index;
00288 uint64_t duration;
00289 AVTimecode tc;
00290 AVStream *timecode_track;
00291 int timecode_base;
00292 int edit_unit_byte_count;
00293 uint64_t body_offset;
00294 uint32_t instance_number;
00295 uint8_t umid[16];
00296 } MXFContext;
00297
00298 static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd };
00299 static const uint8_t umid_ul[] = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13 };
00300
00304 static const uint8_t op1a_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x01,0x09,0x00 };
00305 static const uint8_t footer_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x04,0x04,0x00 };
00306 static const uint8_t primer_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x05,0x01,0x00 };
00307 static const uint8_t index_table_segment_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 };
00308 static const uint8_t random_index_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x11,0x01,0x00 };
00309 static const uint8_t header_open_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x01,0x00 };
00310 static const uint8_t header_closed_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x04,0x00 };
00311 static const uint8_t klv_fill_key[] = { 0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x03,0x01,0x02,0x10,0x01,0x00,0x00,0x00 };
00312 static const uint8_t body_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x03,0x04,0x00 };
00313
00317 static const uint8_t header_metadata_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01 };
00318 static const uint8_t multiple_desc_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x0D,0x01,0x03,0x01,0x02,0x7F,0x01,0x00 };
00319
00323 static const MXFLocalTagPair mxf_local_tag_batch[] = {
00324
00325 { 0x3C0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x02,0x00,0x00,0x00,0x00}},
00326 { 0x3B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x04,0x00,0x00}},
00327 { 0x3B05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x05,0x00,0x00,0x00}},
00328 { 0x3B06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x04,0x00,0x00}},
00329 { 0x3B03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x01,0x00,0x00}},
00330 { 0x3B09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x03,0x00,0x00,0x00,0x00}},
00331 { 0x3B0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x01,0x00,0x00}},
00332 { 0x3B0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x02,0x00,0x00}},
00333
00334 { 0x3C09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x01,0x00,0x00,0x00}},
00335 { 0x3C01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x02,0x01,0x00,0x00}},
00336 { 0x3C02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x03,0x01,0x00,0x00}},
00337 { 0x3C04, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x05,0x01,0x00,0x00}},
00338 { 0x3C05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x07,0x00,0x00,0x00}},
00339 { 0x3C06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x03,0x00,0x00}},
00340
00341 { 0x1901, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x01,0x00,0x00}},
00342 { 0x1902, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x02,0x00,0x00}},
00343
00344 { 0x2701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x06,0x01,0x00,0x00,0x00}},
00345 { 0x3F07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x04,0x00,0x00,0x00,0x00}},
00346
00347 { 0x4401, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x10,0x00,0x00,0x00,0x00}},
00348 { 0x4405, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x01,0x03,0x00,0x00}},
00349 { 0x4404, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x05,0x00,0x00}},
00350 { 0x4403, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x05,0x00,0x00}},
00351 { 0x4701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x03,0x00,0x00}},
00352
00353 { 0x4801, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x07,0x01,0x01,0x00,0x00,0x00,0x00}},
00354 { 0x4804, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x04,0x01,0x03,0x00,0x00,0x00,0x00}},
00355 { 0x4B01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x30,0x04,0x05,0x00,0x00,0x00,0x00}},
00356 { 0x4B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x03,0x00,0x00}},
00357 { 0x4803, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x04,0x00,0x00}},
00358
00359 { 0x0201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x07,0x01,0x00,0x00,0x00,0x00,0x00}},
00360 { 0x0202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x02,0x01,0x01,0x03,0x00,0x00}},
00361 { 0x1001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x09,0x00,0x00}},
00362
00363 { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x04,0x00,0x00}},
00364 { 0x1101, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x01,0x00,0x00,0x00}},
00365 { 0x1102, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x02,0x00,0x00,0x00}},
00366
00367 { 0x1501, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x05,0x00,0x00}},
00368 { 0x1502, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x04,0x01,0x01,0x02,0x06,0x00,0x00}},
00369 { 0x1503, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x04,0x01,0x01,0x05,0x00,0x00,0x00}},
00370
00371 { 0x3F01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x04,0x06,0x0B,0x00,0x00}},
00372 { 0x3006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x06,0x01,0x01,0x03,0x05,0x00,0x00,0x00}},
00373 { 0x3001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x00,0x00,0x00,0x00}},
00374 { 0x3004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x02,0x00,0x00}},
00375
00376 { 0x320C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x03,0x01,0x04,0x00,0x00,0x00}},
00377 { 0x320D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x02,0x05,0x00,0x00,0x00}},
00378 { 0x3203, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x02,0x00,0x00,0x00}},
00379 { 0x3202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00}},
00380 { 0x3209, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0C,0x00,0x00,0x00}},
00381 { 0x3208, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0B,0x00,0x00,0x00}},
00382 { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}},
00383 { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}},
00384 { 0x3212, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x01,0x06,0x00,0x00,0x00}},
00385
00386 { 0x3301, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x03,0x0A,0x00,0x00,0x00}},
00387 { 0x3302, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x05,0x00,0x00,0x00}},
00388
00389 { 0x3D02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x01,0x04,0x00,0x00,0x00}},
00390 { 0x3D03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x01,0x01,0x01,0x00,0x00}},
00391 { 0x3D07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x01,0x01,0x04,0x00,0x00,0x00}},
00392 { 0x3D01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x03,0x04,0x00,0x00,0x00}},
00393 { 0x3D06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x02,0x04,0x02,0x00,0x00,0x00,0x00}},
00394
00395 { 0x3F0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x05,0x30,0x04,0x06,0x00,0x00,0x00,0x00}},
00396 { 0x3F0C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x01,0x03,0x01,0x0A,0x00,0x00}},
00397 { 0x3F0D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x02,0x01,0x01,0x02,0x00,0x00}},
00398 { 0x3F05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x06,0x02,0x01,0x00,0x00,0x00,0x00}},
00399 { 0x3F06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x05,0x00,0x00,0x00,0x00}},
00400 { 0x3F08, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x04,0x04,0x01,0x01,0x00,0x00,0x00}},
00401 { 0x3F09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x01,0x06,0x00,0x00,0x00}},
00402 { 0x3F0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x02,0x05,0x00,0x00,0x00}},
00403
00404 { 0x8000, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0B,0x00,0x00}},
00405 { 0x8007, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0A,0x00,0x00}},
00406
00407 { 0x3D09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x03,0x05,0x00,0x00,0x00}},
00408 { 0x3D0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x02,0x01,0x00,0x00,0x00}},
00409 };
00410
00411 static void mxf_write_uuid(AVIOContext *pb, enum MXFMetadataSetType type, int value)
00412 {
00413 avio_write(pb, uuid_base, 12);
00414 avio_wb16(pb, type);
00415 avio_wb16(pb, value);
00416 }
00417
00418 static void mxf_write_umid(AVFormatContext *s, int type)
00419 {
00420 MXFContext *mxf = s->priv_data;
00421 avio_write(s->pb, umid_ul, 13);
00422 avio_wb24(s->pb, mxf->instance_number);
00423 avio_write(s->pb, mxf->umid, 15);
00424 avio_w8(s->pb, type);
00425 }
00426
00427 static void mxf_write_refs_count(AVIOContext *pb, int ref_count)
00428 {
00429 avio_wb32(pb, ref_count);
00430 avio_wb32(pb, 16);
00431 }
00432
00433 static int klv_ber_length(uint64_t len)
00434 {
00435 if (len < 128)
00436 return 1;
00437 else
00438 return (av_log2(len) >> 3) + 2;
00439 }
00440
00441 static int klv_encode_ber_length(AVIOContext *pb, uint64_t len)
00442 {
00443
00444 int size;
00445 if (len < 128) {
00446
00447 avio_w8(pb, len);
00448 return 1;
00449 }
00450
00451 size = (av_log2(len) >> 3) + 1;
00452
00453
00454 avio_w8(pb, 0x80 + size);
00455 while(size) {
00456 size--;
00457 avio_w8(pb, len >> 8 * size & 0xff);
00458 }
00459 return 0;
00460 }
00461
00462 static void klv_encode_ber4_length(AVIOContext *pb, int len)
00463 {
00464 avio_w8(pb, 0x80 + 3);
00465 avio_wb24(pb, len);
00466 }
00467
00468
00469
00470
00471 static int mxf_get_essence_container_ul_index(enum AVCodecID id)
00472 {
00473 int i;
00474 for (i = 0; mxf_essence_mappings[i].id; i++)
00475 if (mxf_essence_mappings[i].id == id)
00476 return mxf_essence_mappings[i].index;
00477 return -1;
00478 }
00479
00480 static void mxf_write_primer_pack(AVFormatContext *s)
00481 {
00482 AVIOContext *pb = s->pb;
00483 int local_tag_number, i = 0;
00484
00485 local_tag_number = FF_ARRAY_ELEMS(mxf_local_tag_batch);
00486
00487 avio_write(pb, primer_pack_key, 16);
00488 klv_encode_ber_length(pb, local_tag_number * 18 + 8);
00489
00490 avio_wb32(pb, local_tag_number);
00491 avio_wb32(pb, 18);
00492
00493 for (i = 0; i < local_tag_number; i++) {
00494 avio_wb16(pb, mxf_local_tag_batch[i].local_tag);
00495 avio_write(pb, mxf_local_tag_batch[i].uid, 16);
00496 }
00497 }
00498
00499 static void mxf_write_local_tag(AVIOContext *pb, int size, int tag)
00500 {
00501 avio_wb16(pb, tag);
00502 avio_wb16(pb, size);
00503 }
00504
00505 static void mxf_write_metadata_key(AVIOContext *pb, unsigned int value)
00506 {
00507 avio_write(pb, header_metadata_key, 13);
00508 avio_wb24(pb, value);
00509 }
00510
00511 static void mxf_free(AVFormatContext *s)
00512 {
00513 int i;
00514
00515 for (i = 0; i < s->nb_streams; i++) {
00516 AVStream *st = s->streams[i];
00517 av_freep(&st->priv_data);
00518 }
00519 }
00520
00521 static const MXFCodecUL *mxf_get_data_definition_ul(int type)
00522 {
00523 const MXFCodecUL *uls = ff_mxf_data_definition_uls;
00524 while (uls->uid[0]) {
00525 if (type == uls->id)
00526 break;
00527 uls++;
00528 }
00529 return uls;
00530 }
00531
00532 static void mxf_write_essence_container_refs(AVFormatContext *s)
00533 {
00534 MXFContext *c = s->priv_data;
00535 AVIOContext *pb = s->pb;
00536 int i;
00537
00538 mxf_write_refs_count(pb, c->essence_container_count);
00539 av_log(s,AV_LOG_DEBUG, "essence container count:%d\n", c->essence_container_count);
00540 for (i = 0; i < c->essence_container_count; i++) {
00541 MXFStreamContext *sc = s->streams[i]->priv_data;
00542 avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
00543 }
00544 }
00545
00546 static void mxf_write_preface(AVFormatContext *s)
00547 {
00548 MXFContext *mxf = s->priv_data;
00549 AVIOContext *pb = s->pb;
00550
00551 mxf_write_metadata_key(pb, 0x012f00);
00552 PRINT_KEY(s, "preface key", pb->buf_ptr - 16);
00553 klv_encode_ber_length(pb, 130 + 16 * mxf->essence_container_count);
00554
00555
00556 mxf_write_local_tag(pb, 16, 0x3C0A);
00557 mxf_write_uuid(pb, Preface, 0);
00558 PRINT_KEY(s, "preface uid", pb->buf_ptr - 16);
00559
00560
00561 mxf_write_local_tag(pb, 8, 0x3B02);
00562 avio_wb64(pb, mxf->timestamp);
00563
00564
00565 mxf_write_local_tag(pb, 2, 0x3B05);
00566 avio_wb16(pb, 258);
00567
00568
00569 mxf_write_local_tag(pb, 16 + 8, 0x3B06);
00570 mxf_write_refs_count(pb, 1);
00571 mxf_write_uuid(pb, Identification, 0);
00572
00573
00574 mxf_write_local_tag(pb, 16, 0x3B03);
00575 mxf_write_uuid(pb, ContentStorage, 0);
00576
00577
00578 mxf_write_local_tag(pb, 16, 0x3B09);
00579 avio_write(pb, op1a_ul, 16);
00580
00581
00582 mxf_write_local_tag(pb, 8 + 16 * mxf->essence_container_count, 0x3B0A);
00583 mxf_write_essence_container_refs(s);
00584
00585
00586 mxf_write_local_tag(pb, 8, 0x3B0B);
00587 avio_wb64(pb, 0);
00588 }
00589
00590
00591
00592
00593 static void mxf_write_local_tag_utf16(AVIOContext *pb, int tag, const char *value)
00594 {
00595 int i, size = strlen(value);
00596 mxf_write_local_tag(pb, size*2, tag);
00597 for (i = 0; i < size; i++)
00598 avio_wb16(pb, value[i]);
00599 }
00600
00601 static void mxf_write_identification(AVFormatContext *s)
00602 {
00603 MXFContext *mxf = s->priv_data;
00604 AVIOContext *pb = s->pb;
00605 const char *company = "FFmpeg";
00606 const char *product = "OP1a Muxer";
00607 const char *version;
00608 int length;
00609
00610 mxf_write_metadata_key(pb, 0x013000);
00611 PRINT_KEY(s, "identification key", pb->buf_ptr - 16);
00612
00613 version = s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT ?
00614 "0.0.0" : AV_STRINGIFY(LIBAVFORMAT_VERSION);
00615 length = 84 + (strlen(company)+strlen(product)+strlen(version))*2;
00616 klv_encode_ber_length(pb, length);
00617
00618
00619 mxf_write_local_tag(pb, 16, 0x3C0A);
00620 mxf_write_uuid(pb, Identification, 0);
00621 PRINT_KEY(s, "identification uid", pb->buf_ptr - 16);
00622
00623
00624 mxf_write_local_tag(pb, 16, 0x3C09);
00625 mxf_write_uuid(pb, Identification, 1);
00626
00627 mxf_write_local_tag_utf16(pb, 0x3C01, company);
00628 mxf_write_local_tag_utf16(pb, 0x3C02, product);
00629 mxf_write_local_tag_utf16(pb, 0x3C04, version);
00630
00631
00632 mxf_write_local_tag(pb, 16, 0x3C05);
00633 mxf_write_uuid(pb, Identification, 2);
00634
00635
00636 mxf_write_local_tag(pb, 8, 0x3C06);
00637 avio_wb64(pb, mxf->timestamp);
00638 }
00639
00640 static void mxf_write_content_storage(AVFormatContext *s)
00641 {
00642 AVIOContext *pb = s->pb;
00643
00644 mxf_write_metadata_key(pb, 0x011800);
00645 PRINT_KEY(s, "content storage key", pb->buf_ptr - 16);
00646 klv_encode_ber_length(pb, 92);
00647
00648
00649 mxf_write_local_tag(pb, 16, 0x3C0A);
00650 mxf_write_uuid(pb, ContentStorage, 0);
00651 PRINT_KEY(s, "content storage uid", pb->buf_ptr - 16);
00652
00653
00654 mxf_write_local_tag(pb, 16 * 2 + 8, 0x1901);
00655 mxf_write_refs_count(pb, 2);
00656 mxf_write_uuid(pb, MaterialPackage, 0);
00657 mxf_write_uuid(pb, SourcePackage, 0);
00658
00659
00660 mxf_write_local_tag(pb, 8 + 16, 0x1902);
00661 mxf_write_refs_count(pb, 1);
00662 mxf_write_uuid(pb, EssenceContainerData, 0);
00663 }
00664
00665 static void mxf_write_track(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
00666 {
00667 MXFContext *mxf = s->priv_data;
00668 AVIOContext *pb = s->pb;
00669 MXFStreamContext *sc = st->priv_data;
00670
00671 mxf_write_metadata_key(pb, 0x013b00);
00672 PRINT_KEY(s, "track key", pb->buf_ptr - 16);
00673 klv_encode_ber_length(pb, 80);
00674
00675
00676 mxf_write_local_tag(pb, 16, 0x3C0A);
00677 mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, st->index);
00678 PRINT_KEY(s, "track uid", pb->buf_ptr - 16);
00679
00680
00681 mxf_write_local_tag(pb, 4, 0x4801);
00682 avio_wb32(pb, st->index+2);
00683
00684
00685 mxf_write_local_tag(pb, 4, 0x4804);
00686 if (type == MaterialPackage)
00687 avio_wb32(pb, 0);
00688 else
00689 avio_write(pb, sc->track_essence_element_key + 12, 4);
00690
00691 mxf_write_local_tag(pb, 8, 0x4B01);
00692 avio_wb32(pb, mxf->time_base.den);
00693 avio_wb32(pb, mxf->time_base.num);
00694
00695
00696 mxf_write_local_tag(pb, 8, 0x4B02);
00697 avio_wb64(pb, 0);
00698
00699
00700 mxf_write_local_tag(pb, 16, 0x4803);
00701 mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index);
00702 }
00703
00704 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 };
00705
00706 static void mxf_write_common_fields(AVFormatContext *s, AVStream *st)
00707 {
00708 MXFContext *mxf = s->priv_data;
00709 AVIOContext *pb = s->pb;
00710
00711
00712 mxf_write_local_tag(pb, 16, 0x0201);
00713 if (st == mxf->timecode_track)
00714 avio_write(pb, smpte_12m_timecode_track_data_ul, 16);
00715 else {
00716 const MXFCodecUL *data_def_ul = mxf_get_data_definition_ul(st->codec->codec_type);
00717 avio_write(pb, data_def_ul->uid, 16);
00718 }
00719
00720
00721 mxf_write_local_tag(pb, 8, 0x0202);
00722 avio_wb64(pb, mxf->duration);
00723 }
00724
00725 static void mxf_write_sequence(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
00726 {
00727 MXFContext *mxf = s->priv_data;
00728 AVIOContext *pb = s->pb;
00729 enum MXFMetadataSetType component;
00730
00731 mxf_write_metadata_key(pb, 0x010f00);
00732 PRINT_KEY(s, "sequence key", pb->buf_ptr - 16);
00733 klv_encode_ber_length(pb, 80);
00734
00735 mxf_write_local_tag(pb, 16, 0x3C0A);
00736 mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index);
00737
00738 PRINT_KEY(s, "sequence uid", pb->buf_ptr - 16);
00739 mxf_write_common_fields(s, st);
00740
00741
00742 mxf_write_local_tag(pb, 16 + 8, 0x1001);
00743 mxf_write_refs_count(pb, 1);
00744 if (st == mxf->timecode_track)
00745 component = TimecodeComponent;
00746 else
00747 component = SourceClip;
00748 if (type == SourcePackage)
00749 component += TypeBottom;
00750 mxf_write_uuid(pb, component, st->index);
00751 }
00752
00753 static void mxf_write_timecode_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
00754 {
00755 MXFContext *mxf = s->priv_data;
00756 AVIOContext *pb = s->pb;
00757
00758 mxf_write_metadata_key(pb, 0x011400);
00759 klv_encode_ber_length(pb, 75);
00760
00761
00762 mxf_write_local_tag(pb, 16, 0x3C0A);
00763 mxf_write_uuid(pb, type == MaterialPackage ? TimecodeComponent :
00764 TimecodeComponent + TypeBottom, st->index);
00765
00766 mxf_write_common_fields(s, st);
00767
00768
00769 mxf_write_local_tag(pb, 8, 0x1501);
00770 avio_wb64(pb, mxf->tc.start);
00771
00772
00773 mxf_write_local_tag(pb, 2, 0x1502);
00774 avio_wb16(pb, mxf->timecode_base);
00775
00776
00777 mxf_write_local_tag(pb, 1, 0x1503);
00778 avio_w8(pb, !!(mxf->tc.flags & AV_TIMECODE_FLAG_DROPFRAME));
00779 }
00780
00781 static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
00782 {
00783 AVIOContext *pb = s->pb;
00784 int i;
00785
00786 mxf_write_metadata_key(pb, 0x011100);
00787 PRINT_KEY(s, "sturctural component key", pb->buf_ptr - 16);
00788 klv_encode_ber_length(pb, 108);
00789
00790
00791 mxf_write_local_tag(pb, 16, 0x3C0A);
00792 mxf_write_uuid(pb, type == MaterialPackage ? SourceClip: SourceClip + TypeBottom, st->index);
00793
00794 PRINT_KEY(s, "structural component uid", pb->buf_ptr - 16);
00795 mxf_write_common_fields(s, st);
00796
00797
00798 mxf_write_local_tag(pb, 8, 0x1201);
00799 avio_wb64(pb, 0);
00800
00801
00802 mxf_write_local_tag(pb, 32, 0x1101);
00803 if (type == SourcePackage) {
00804 for (i = 0; i < 4; i++)
00805 avio_wb64(pb, 0);
00806 } else
00807 mxf_write_umid(s, 1);
00808
00809
00810 mxf_write_local_tag(pb, 4, 0x1102);
00811 if (type == SourcePackage)
00812 avio_wb32(pb, 0);
00813 else
00814 avio_wb32(pb, st->index+2);
00815 }
00816
00817 static void mxf_write_multi_descriptor(AVFormatContext *s)
00818 {
00819 MXFContext *mxf = s->priv_data;
00820 AVIOContext *pb = s->pb;
00821 const uint8_t *ul;
00822 int i;
00823
00824 mxf_write_metadata_key(pb, 0x014400);
00825 PRINT_KEY(s, "multiple descriptor key", pb->buf_ptr - 16);
00826 klv_encode_ber_length(pb, 64 + 16 * s->nb_streams);
00827
00828 mxf_write_local_tag(pb, 16, 0x3C0A);
00829 mxf_write_uuid(pb, MultipleDescriptor, 0);
00830 PRINT_KEY(s, "multi_desc uid", pb->buf_ptr - 16);
00831
00832
00833 mxf_write_local_tag(pb, 8, 0x3001);
00834 avio_wb32(pb, mxf->time_base.den);
00835 avio_wb32(pb, mxf->time_base.num);
00836
00837
00838 mxf_write_local_tag(pb, 16, 0x3004);
00839 if (mxf->essence_container_count > 1)
00840 ul = multiple_desc_ul;
00841 else {
00842 MXFStreamContext *sc = s->streams[0]->priv_data;
00843 ul = mxf_essence_container_uls[sc->index].container_ul;
00844 }
00845 avio_write(pb, ul, 16);
00846
00847
00848 mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01);
00849 mxf_write_refs_count(pb, s->nb_streams);
00850 for (i = 0; i < s->nb_streams; i++)
00851 mxf_write_uuid(pb, SubDescriptor, i);
00852 }
00853
00854 static void mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
00855 {
00856 MXFContext *mxf = s->priv_data;
00857 MXFStreamContext *sc = st->priv_data;
00858 AVIOContext *pb = s->pb;
00859
00860 avio_write(pb, key, 16);
00861 klv_encode_ber4_length(pb, size+20+8+12+20);
00862
00863 mxf_write_local_tag(pb, 16, 0x3C0A);
00864 mxf_write_uuid(pb, SubDescriptor, st->index);
00865
00866 mxf_write_local_tag(pb, 4, 0x3006);
00867 avio_wb32(pb, st->index+2);
00868
00869 mxf_write_local_tag(pb, 8, 0x3001);
00870 avio_wb32(pb, mxf->time_base.den);
00871 avio_wb32(pb, mxf->time_base.num);
00872
00873 mxf_write_local_tag(pb, 16, 0x3004);
00874 avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
00875 }
00876
00877 static const UID mxf_mpegvideo_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 };
00878 static const UID mxf_wav_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 };
00879 static const UID mxf_aes3_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 };
00880 static const UID mxf_cdci_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x28,0x00 };
00881 static const UID mxf_generic_sound_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x42,0x00 };
00882
00883 static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
00884 {
00885 MXFStreamContext *sc = st->priv_data;
00886 AVIOContext *pb = s->pb;
00887 int stored_height = (st->codec->height+15)/16*16;
00888 int display_height;
00889 int f1, f2;
00890 unsigned desc_size = size+8+8+8+8+8+8+5+16+sc->interlaced*4+12+20;
00891 if (sc->interlaced && sc->field_dominance)
00892 desc_size += 5;
00893
00894 mxf_write_generic_desc(s, st, key, desc_size);
00895
00896 mxf_write_local_tag(pb, 4, 0x3203);
00897 avio_wb32(pb, st->codec->width);
00898
00899 mxf_write_local_tag(pb, 4, 0x3202);
00900 avio_wb32(pb, stored_height>>sc->interlaced);
00901
00902 mxf_write_local_tag(pb, 4, 0x3209);
00903 avio_wb32(pb, st->codec->width);
00904
00905 if (st->codec->height == 608)
00906 display_height = 576;
00907 else if (st->codec->height == 512)
00908 display_height = 486;
00909 else
00910 display_height = st->codec->height;
00911
00912 mxf_write_local_tag(pb, 4, 0x3208);
00913 avio_wb32(pb, display_height>>sc->interlaced);
00914
00915
00916 mxf_write_local_tag(pb, 4, 0x3301);
00917 avio_wb32(pb, sc->component_depth);
00918
00919
00920 mxf_write_local_tag(pb, 4, 0x3302);
00921 avio_wb32(pb, 2);
00922
00923
00924 mxf_write_local_tag(pb, 1, 0x320C);
00925 avio_w8(pb, sc->interlaced);
00926
00927
00928 switch (st->codec->height) {
00929 case 576: f1 = 23; f2 = st->codec->codec_id == AV_CODEC_ID_DVVIDEO ? 335 : 336; break;
00930 case 608: f1 = 7; f2 = 320; break;
00931 case 480: f1 = 20; f2 = st->codec->codec_id == AV_CODEC_ID_DVVIDEO ? 285 : 283; break;
00932 case 512: f1 = 7; f2 = 270; break;
00933 case 720: f1 = 26; f2 = 0; break;
00934 case 1080: f1 = 21; f2 = 584; break;
00935 default: f1 = 0; f2 = 0; break;
00936 }
00937
00938 if (!sc->interlaced) {
00939 f2 = 0;
00940 f1 *= 2;
00941 }
00942
00943 mxf_write_local_tag(pb, 12+sc->interlaced*4, 0x320D);
00944 avio_wb32(pb, sc->interlaced ? 2 : 1);
00945 avio_wb32(pb, 4);
00946 avio_wb32(pb, f1);
00947 if (sc->interlaced)
00948 avio_wb32(pb, f2);
00949
00950 mxf_write_local_tag(pb, 8, 0x320E);
00951 avio_wb32(pb, sc->aspect_ratio.num);
00952 avio_wb32(pb, sc->aspect_ratio.den);
00953
00954 mxf_write_local_tag(pb, 16, 0x3201);
00955 avio_write(pb, *sc->codec_ul, 16);
00956
00957 if (sc->interlaced && sc->field_dominance) {
00958 mxf_write_local_tag(pb, 1, 0x3212);
00959 avio_w8(pb, sc->field_dominance);
00960 }
00961
00962 }
00963
00964 static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st)
00965 {
00966 mxf_write_cdci_common(s, st, mxf_cdci_descriptor_key, 0);
00967 }
00968
00969 static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st)
00970 {
00971 AVIOContext *pb = s->pb;
00972 int profile_and_level = (st->codec->profile<<4) | st->codec->level;
00973
00974 mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key, 8+5);
00975
00976
00977 mxf_write_local_tag(pb, 4, 0x8000);
00978 avio_wb32(pb, st->codec->bit_rate);
00979
00980
00981 mxf_write_local_tag(pb, 1, 0x8007);
00982 if (!st->codec->profile)
00983 profile_and_level |= 0x80;
00984 avio_w8(pb, profile_and_level);
00985 }
00986
00987 static void mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
00988 {
00989 AVIOContext *pb = s->pb;
00990
00991 mxf_write_generic_desc(s, st, key, size+5+12+8+8);
00992
00993
00994 mxf_write_local_tag(pb, 1, 0x3D02);
00995 avio_w8(pb, 1);
00996
00997
00998 mxf_write_local_tag(pb, 8, 0x3D03);
00999 avio_wb32(pb, st->codec->sample_rate);
01000 avio_wb32(pb, 1);
01001
01002 mxf_write_local_tag(pb, 4, 0x3D07);
01003 avio_wb32(pb, st->codec->channels);
01004
01005 mxf_write_local_tag(pb, 4, 0x3D01);
01006 avio_wb32(pb, av_get_bits_per_sample(st->codec->codec_id));
01007 }
01008
01009 static void mxf_write_wav_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
01010 {
01011 AVIOContext *pb = s->pb;
01012
01013 mxf_write_generic_sound_common(s, st, key, size+6+8);
01014
01015 mxf_write_local_tag(pb, 2, 0x3D0A);
01016 avio_wb16(pb, st->codec->block_align);
01017
01018
01019 mxf_write_local_tag(pb, 4, 0x3D09);
01020 avio_wb32(pb, st->codec->block_align*st->codec->sample_rate);
01021 }
01022
01023 static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st)
01024 {
01025 mxf_write_wav_common(s, st, mxf_wav_descriptor_key, 0);
01026 }
01027
01028 static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st)
01029 {
01030 mxf_write_wav_common(s, st, mxf_aes3_descriptor_key, 0);
01031 }
01032
01033 static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st)
01034 {
01035 mxf_write_generic_sound_common(s, st, mxf_generic_sound_descriptor_key, 0);
01036 }
01037
01038 static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type)
01039 {
01040 MXFContext *mxf = s->priv_data;
01041 AVIOContext *pb = s->pb;
01042 int i, track_count = s->nb_streams+1;
01043
01044 if (type == MaterialPackage) {
01045 mxf_write_metadata_key(pb, 0x013600);
01046 PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16);
01047 klv_encode_ber_length(pb, 92 + 16*track_count);
01048 } else {
01049 mxf_write_metadata_key(pb, 0x013700);
01050 PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16);
01051 klv_encode_ber_length(pb, 112 + 16*track_count);
01052 }
01053
01054
01055 mxf_write_local_tag(pb, 16, 0x3C0A);
01056 mxf_write_uuid(pb, type, 0);
01057 av_log(s,AV_LOG_DEBUG, "package type:%d\n", type);
01058 PRINT_KEY(s, "package uid", pb->buf_ptr - 16);
01059
01060
01061 mxf_write_local_tag(pb, 32, 0x4401);
01062 mxf_write_umid(s, type == SourcePackage);
01063 PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16);
01064
01065
01066 mxf_write_local_tag(pb, 8, 0x4405);
01067 avio_wb64(pb, mxf->timestamp);
01068
01069
01070 mxf_write_local_tag(pb, 8, 0x4404);
01071 avio_wb64(pb, mxf->timestamp);
01072
01073
01074 mxf_write_local_tag(pb, track_count*16 + 8, 0x4403);
01075 mxf_write_refs_count(pb, track_count);
01076 mxf_write_uuid(pb, type == MaterialPackage ? Track :
01077 Track + TypeBottom, -1);
01078 for (i = 0; i < s->nb_streams; i++)
01079 mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, i);
01080
01081
01082 if (type == SourcePackage) {
01083 mxf_write_local_tag(pb, 16, 0x4701);
01084 if (s->nb_streams > 1) {
01085 mxf_write_uuid(pb, MultipleDescriptor, 0);
01086 mxf_write_multi_descriptor(s);
01087 } else
01088 mxf_write_uuid(pb, SubDescriptor, 0);
01089 }
01090
01091
01092 mxf_write_track(s, mxf->timecode_track, type);
01093 mxf_write_sequence(s, mxf->timecode_track, type);
01094 mxf_write_timecode_component(s, mxf->timecode_track, type);
01095
01096 for (i = 0; i < s->nb_streams; i++) {
01097 AVStream *st = s->streams[i];
01098 mxf_write_track(s, st, type);
01099 mxf_write_sequence(s, st, type);
01100 mxf_write_structural_component(s, st, type);
01101
01102 if (type == SourcePackage) {
01103 MXFStreamContext *sc = st->priv_data;
01104 mxf_essence_container_uls[sc->index].write_desc(s, st);
01105 }
01106 }
01107 }
01108
01109 static int mxf_write_essence_container_data(AVFormatContext *s)
01110 {
01111 AVIOContext *pb = s->pb;
01112
01113 mxf_write_metadata_key(pb, 0x012300);
01114 klv_encode_ber_length(pb, 72);
01115
01116 mxf_write_local_tag(pb, 16, 0x3C0A);
01117 mxf_write_uuid(pb, EssenceContainerData, 0);
01118
01119 mxf_write_local_tag(pb, 32, 0x2701);
01120 mxf_write_umid(s, 1);
01121
01122 mxf_write_local_tag(pb, 4, 0x3F07);
01123 avio_wb32(pb, 1);
01124
01125 mxf_write_local_tag(pb, 4, 0x3F06);
01126 avio_wb32(pb, 2);
01127
01128 return 0;
01129 }
01130
01131 static int mxf_write_header_metadata_sets(AVFormatContext *s)
01132 {
01133 mxf_write_preface(s);
01134 mxf_write_identification(s);
01135 mxf_write_content_storage(s);
01136 mxf_write_package(s, MaterialPackage);
01137 mxf_write_package(s, SourcePackage);
01138 mxf_write_essence_container_data(s);
01139 return 0;
01140 }
01141
01142 static unsigned klv_fill_size(uint64_t size)
01143 {
01144 unsigned pad = KAG_SIZE - (size & (KAG_SIZE-1));
01145 if (pad < 20)
01146 return pad + KAG_SIZE;
01147 else
01148 return pad & (KAG_SIZE-1);
01149 }
01150
01151 static void mxf_write_index_table_segment(AVFormatContext *s)
01152 {
01153 MXFContext *mxf = s->priv_data;
01154 AVIOContext *pb = s->pb;
01155 int i, j, temporal_reordering = 0;
01156 int key_index = mxf->last_key_index;
01157
01158 av_log(s, AV_LOG_DEBUG, "edit units count %d\n", mxf->edit_units_count);
01159
01160 if (!mxf->edit_units_count && !mxf->edit_unit_byte_count)
01161 return;
01162
01163 avio_write(pb, index_table_segment_key, 16);
01164
01165 if (mxf->edit_unit_byte_count) {
01166 klv_encode_ber_length(pb, 80);
01167 } else {
01168 klv_encode_ber_length(pb, 85 + 12+(s->nb_streams+1)*6 +
01169 12+mxf->edit_units_count*(11+mxf->slice_count*4));
01170 }
01171
01172
01173 mxf_write_local_tag(pb, 16, 0x3C0A);
01174 mxf_write_uuid(pb, IndexTableSegment, 0);
01175
01176
01177 mxf_write_local_tag(pb, 8, 0x3F0B);
01178 avio_wb32(pb, mxf->time_base.den);
01179 avio_wb32(pb, mxf->time_base.num);
01180
01181
01182 mxf_write_local_tag(pb, 8, 0x3F0C);
01183 avio_wb64(pb, mxf->last_indexed_edit_unit);
01184
01185
01186 mxf_write_local_tag(pb, 8, 0x3F0D);
01187 if (mxf->edit_unit_byte_count)
01188 avio_wb64(pb, 0);
01189 else
01190 avio_wb64(pb, mxf->edit_units_count);
01191
01192
01193 mxf_write_local_tag(pb, 4, 0x3F05);
01194 avio_wb32(pb, mxf->edit_unit_byte_count);
01195
01196
01197 mxf_write_local_tag(pb, 4, 0x3F06);
01198 avio_wb32(pb, 2);
01199
01200
01201 mxf_write_local_tag(pb, 4, 0x3F07);
01202 avio_wb32(pb, 1);
01203
01204 if (!mxf->edit_unit_byte_count) {
01205
01206 mxf_write_local_tag(pb, 1, 0x3F08);
01207 avio_w8(pb, mxf->slice_count);
01208
01209
01210 mxf_write_local_tag(pb, 8 + (s->nb_streams+1)*6, 0x3F09);
01211 avio_wb32(pb, s->nb_streams+1);
01212 avio_wb32(pb, 6);
01213
01214 avio_w8(pb, 0);
01215 avio_w8(pb, 0);
01216 avio_wb32(pb, 0);
01217 for (i = 0; i < s->nb_streams; i++) {
01218 AVStream *st = s->streams[i];
01219 MXFStreamContext *sc = st->priv_data;
01220 avio_w8(pb, sc->temporal_reordering);
01221 if (sc->temporal_reordering)
01222 temporal_reordering = 1;
01223 if (i == 0) {
01224 avio_w8(pb, 0);
01225 avio_wb32(pb, KAG_SIZE);
01226 } else {
01227 unsigned audio_frame_size = sc->aic.samples[0]*sc->aic.sample_size;
01228 audio_frame_size += klv_fill_size(audio_frame_size);
01229 avio_w8(pb, 1);
01230 avio_wb32(pb, (i-1)*audio_frame_size);
01231 }
01232 }
01233
01234 mxf_write_local_tag(pb, 8 + mxf->edit_units_count*(11+mxf->slice_count*4), 0x3F0A);
01235 avio_wb32(pb, mxf->edit_units_count);
01236 avio_wb32(pb, 11+mxf->slice_count*4);
01237
01238 for (i = 0; i < mxf->edit_units_count; i++) {
01239 int temporal_offset = 0;
01240
01241 if (!(mxf->index_entries[i].flags & 0x33)) {
01242 mxf->last_key_index = key_index;
01243 key_index = i;
01244 }
01245
01246 if (temporal_reordering) {
01247 int pic_num_in_gop = i - key_index;
01248 if (pic_num_in_gop != mxf->index_entries[i].temporal_ref) {
01249 for (j = key_index; j < mxf->edit_units_count; j++) {
01250 if (pic_num_in_gop == mxf->index_entries[j].temporal_ref)
01251 break;
01252 }
01253 if (j == mxf->edit_units_count)
01254 av_log(s, AV_LOG_WARNING, "missing frames\n");
01255 temporal_offset = j - key_index - pic_num_in_gop;
01256 }
01257 }
01258 avio_w8(pb, temporal_offset);
01259
01260 if ((mxf->index_entries[i].flags & 0x30) == 0x30) {
01261 avio_w8(pb, mxf->last_key_index - i);
01262 } else {
01263 avio_w8(pb, key_index - i);
01264 if ((mxf->index_entries[i].flags & 0x20) == 0x20)
01265 mxf->last_key_index = key_index;
01266 }
01267
01268 if (!(mxf->index_entries[i].flags & 0x33) &&
01269 mxf->index_entries[i].flags & 0x40 && !temporal_offset)
01270 mxf->index_entries[i].flags |= 0x80;
01271 avio_w8(pb, mxf->index_entries[i].flags);
01272
01273 avio_wb64(pb, mxf->index_entries[i].offset);
01274 if (s->nb_streams > 1)
01275 avio_wb32(pb, mxf->index_entries[i].slice_offset);
01276 }
01277
01278 mxf->last_key_index = key_index - mxf->edit_units_count;
01279 mxf->last_indexed_edit_unit += mxf->edit_units_count;
01280 mxf->edit_units_count = 0;
01281 }
01282 }
01283
01284 static void mxf_write_klv_fill(AVFormatContext *s)
01285 {
01286 unsigned pad = klv_fill_size(avio_tell(s->pb));
01287 if (pad) {
01288 avio_write(s->pb, klv_fill_key, 16);
01289 pad -= 16 + 4;
01290 klv_encode_ber4_length(s->pb, pad);
01291 for (; pad; pad--)
01292 avio_w8(s->pb, 0);
01293 av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1)));
01294 }
01295 }
01296
01297 static void mxf_write_partition(AVFormatContext *s, int bodysid,
01298 int indexsid,
01299 const uint8_t *key, int write_metadata)
01300 {
01301 MXFContext *mxf = s->priv_data;
01302 AVIOContext *pb = s->pb;
01303 int64_t header_byte_count_offset;
01304 unsigned index_byte_count = 0;
01305 uint64_t partition_offset = avio_tell(pb);
01306
01307 if (!mxf->edit_unit_byte_count && mxf->edit_units_count)
01308 index_byte_count = 85 + 12+(s->nb_streams+1)*6 +
01309 12+mxf->edit_units_count*(11+mxf->slice_count*4);
01310 else if (mxf->edit_unit_byte_count && indexsid)
01311 index_byte_count = 80;
01312
01313 if (index_byte_count) {
01314
01315 index_byte_count += 16 + klv_ber_length(index_byte_count);
01316 index_byte_count += klv_fill_size(index_byte_count);
01317 }
01318
01319 if (!memcmp(key, body_partition_key, 16)) {
01320 mxf->body_partition_offset =
01321 av_realloc(mxf->body_partition_offset,
01322 (mxf->body_partitions_count+1)*
01323 sizeof(*mxf->body_partition_offset));
01324 mxf->body_partition_offset[mxf->body_partitions_count++] = partition_offset;
01325 }
01326
01327
01328 avio_write(pb, key, 16);
01329 klv_encode_ber_length(pb, 88 + 16 * mxf->essence_container_count);
01330
01331
01332 avio_wb16(pb, 1);
01333 avio_wb16(pb, 2);
01334 avio_wb32(pb, KAG_SIZE);
01335
01336 avio_wb64(pb, partition_offset);
01337
01338 if (!memcmp(key, body_partition_key, 16) && mxf->body_partitions_count > 1)
01339 avio_wb64(pb, mxf->body_partition_offset[mxf->body_partitions_count-2]);
01340 else if (!memcmp(key, footer_partition_key, 16) && mxf->body_partitions_count)
01341 avio_wb64(pb, mxf->body_partition_offset[mxf->body_partitions_count-1]);
01342 else
01343 avio_wb64(pb, 0);
01344
01345 avio_wb64(pb, mxf->footer_partition_offset);
01346
01347
01348 header_byte_count_offset = avio_tell(pb);
01349 avio_wb64(pb, 0);
01350
01351
01352 avio_wb64(pb, index_byte_count);
01353 avio_wb32(pb, index_byte_count ? indexsid : 0);
01354
01355
01356 if (bodysid && mxf->edit_units_count && mxf->body_partitions_count) {
01357 avio_wb64(pb, mxf->body_offset);
01358 } else
01359 avio_wb64(pb, 0);
01360
01361 avio_wb32(pb, bodysid);
01362
01363
01364 avio_write(pb, op1a_ul, 16);
01365
01366
01367 mxf_write_essence_container_refs(s);
01368
01369 if (write_metadata) {
01370
01371 int64_t pos, start;
01372 unsigned header_byte_count;
01373
01374 mxf_write_klv_fill(s);
01375 start = avio_tell(s->pb);
01376 mxf_write_primer_pack(s);
01377 mxf_write_header_metadata_sets(s);
01378 pos = avio_tell(s->pb);
01379 header_byte_count = pos - start + klv_fill_size(pos);
01380
01381
01382 avio_seek(pb, header_byte_count_offset, SEEK_SET);
01383 avio_wb64(pb, header_byte_count);
01384 avio_seek(pb, pos, SEEK_SET);
01385 }
01386
01387 avio_flush(pb);
01388 }
01389
01390 static int mxf_parse_dnxhd_frame(AVFormatContext *s, AVStream *st,
01391 AVPacket *pkt)
01392 {
01393 MXFContext *mxf = s->priv_data;
01394 MXFStreamContext *sc = st->priv_data;
01395 int i, cid;
01396 uint8_t* header_cid;
01397 unsigned int frame_size = 0;
01398
01399 if (mxf->header_written)
01400 return 1;
01401
01402 if (pkt->size < 43)
01403 return -1;
01404
01405 header_cid = pkt->data + 0x28;
01406 cid = header_cid[0] << 24 | header_cid[1] << 16 | header_cid[2] << 8 | header_cid[3];
01407
01408 if ((i = ff_dnxhd_get_cid_table(cid)) < 0)
01409 return -1;
01410
01411 switch (cid) {
01412 case 1235:
01413 sc->index = 24;
01414 sc->component_depth = 10;
01415 break;
01416 case 1237:
01417 sc->index = 25;
01418 break;
01419 case 1238:
01420 sc->index = 26;
01421 break;
01422 case 1241:
01423 sc->index = 27;
01424 sc->component_depth = 10;
01425 break;
01426 case 1242:
01427 sc->index = 28;
01428 break;
01429 case 1243:
01430 sc->index = 29;
01431 break;
01432 case 1250:
01433 sc->index = 30;
01434 sc->component_depth = 10;
01435 break;
01436 case 1251:
01437 sc->index = 31;
01438 break;
01439 case 1252:
01440 sc->index = 32;
01441 break;
01442 case 1253:
01443 sc->index = 33;
01444 break;
01445 default:
01446 return -1;
01447 }
01448
01449 frame_size = ff_dnxhd_cid_table[i].frame_size;
01450 sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;
01451 sc->aspect_ratio = (AVRational){ 16, 9 };
01452
01453 mxf->edit_unit_byte_count = KAG_SIZE;
01454 for (i = 0; i < s->nb_streams; i++) {
01455 AVStream *st = s->streams[i];
01456 MXFStreamContext *sc = st->priv_data;
01457 if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
01458 mxf->edit_unit_byte_count += 16 + 4 + sc->aic.samples[0]*sc->aic.sample_size;
01459 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
01460 } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
01461 mxf->edit_unit_byte_count += 16 + 4 + frame_size;
01462 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
01463 }
01464 }
01465
01466 return 1;
01467 }
01468
01469 static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt)
01470 {
01471 MXFContext *mxf = s->priv_data;
01472 MXFStreamContext *sc = st->priv_data;
01473 uint8_t *vs_pack, *vsc_pack;
01474 int i, ul_index, frame_size, stype, pal;
01475
01476 if (mxf->header_written)
01477 return 1;
01478
01479
01480 if (pkt->size < 120000)
01481 return -1;
01482
01483 vs_pack = pkt->data + 80*5 + 48;
01484 vsc_pack = pkt->data + 80*5 + 53;
01485 stype = vs_pack[3] & 0x1f;
01486 pal = (vs_pack[3] >> 5) & 0x1;
01487
01488 if ((vs_pack[2] & 0x07) == 0x02)
01489 sc->aspect_ratio = (AVRational){ 16, 9 };
01490 else
01491 sc->aspect_ratio = (AVRational){ 4, 3 };
01492
01493 sc->interlaced = (vsc_pack[3] >> 4) & 0x01;
01494
01495
01496
01497
01498 switch (stype) {
01499 case 0x18:
01500 ul_index = 6 + pal;
01501 frame_size = pal ? 288000 : 240000;
01502 if (sc->interlaced) {
01503 av_log(s, AV_LOG_ERROR, "source marked as interlaced but codec profile is progressive\n");
01504 sc->interlaced = 0;
01505 }
01506 break;
01507 case 0x14:
01508 ul_index = 4 + pal;
01509 frame_size = pal ? 576000 : 480000;
01510 break;
01511 case 0x04:
01512 ul_index = 2 + pal;
01513 frame_size = pal ? 288000 : 240000;
01514 break;
01515 default:
01516 ul_index = 0 + pal;
01517 frame_size = pal ? 144000 : 120000;
01518 }
01519
01520 sc->index = ul_index + 16;
01521 sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;
01522
01523 mxf->edit_unit_byte_count = KAG_SIZE;
01524 for (i = 0; i < s->nb_streams; i++) {
01525 AVStream *st = s->streams[i];
01526 MXFStreamContext *sc = st->priv_data;
01527 if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
01528 mxf->edit_unit_byte_count += 16 + 4 + sc->aic.samples[0]*sc->aic.sample_size;
01529 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
01530 } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
01531 mxf->edit_unit_byte_count += 16 + 4 + frame_size;
01532 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
01533 }
01534 }
01535
01536 return 1;
01537 }
01538
01539 static const UID mxf_mpeg2_codec_uls[] = {
01540 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x10,0x00 },
01541 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 },
01542 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x02,0x00 },
01543 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x03,0x00 },
01544 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x02,0x00 },
01545 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 },
01546 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 },
01547 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x03,0x00 },
01548 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x02,0x00 },
01549 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x03,0x00 },
01550 };
01551
01552 static const UID *mxf_get_mpeg2_codec_ul(AVCodecContext *avctx)
01553 {
01554 int long_gop = avctx->gop_size > 1 || avctx->has_b_frames;
01555
01556 if (avctx->profile == 4) {
01557 if (avctx->level == 8)
01558 return &mxf_mpeg2_codec_uls[0+long_gop];
01559 else if (avctx->level == 4)
01560 return &mxf_mpeg2_codec_uls[4+long_gop];
01561 else if (avctx->level == 6)
01562 return &mxf_mpeg2_codec_uls[8+long_gop];
01563 } else if (avctx->profile == 0) {
01564 if (avctx->level == 5)
01565 return &mxf_mpeg2_codec_uls[2+long_gop];
01566 else if (avctx->level == 2)
01567 return &mxf_mpeg2_codec_uls[6+long_gop];
01568 }
01569 return NULL;
01570 }
01571
01572 static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st,
01573 AVPacket *pkt, MXFIndexEntry *e)
01574 {
01575 MXFStreamContext *sc = st->priv_data;
01576 uint32_t c = -1;
01577 int i;
01578
01579 for(i = 0; i < pkt->size - 4; i++) {
01580 c = (c<<8) + pkt->data[i];
01581 if (c == 0x1b5) {
01582 if ((pkt->data[i+1] & 0xf0) == 0x10) {
01583 st->codec->profile = pkt->data[i+1] & 0x07;
01584 st->codec->level = pkt->data[i+2] >> 4;
01585 } else if (i + 5 < pkt->size && (pkt->data[i+1] & 0xf0) == 0x80) {
01586 sc->interlaced = !(pkt->data[i+5] & 0x80);
01587 if (sc->interlaced)
01588 sc->field_dominance = 1 + !(pkt->data[i+4] & 0x80);
01589 break;
01590 }
01591 } else if (c == 0x1b8) {
01592 if (pkt->data[i+4]>>6 & 0x01) {
01593 sc->closed_gop = 1;
01594 if (e->flags & 0x40)
01595 e->flags |= 0x80;
01596 }
01597 } else if (c == 0x1b3) {
01598 e->flags |= 0x40;
01599 switch ((pkt->data[i+4]>>4) & 0xf) {
01600 case 2: sc->aspect_ratio = (AVRational){ 4, 3}; break;
01601 case 3: sc->aspect_ratio = (AVRational){ 16, 9}; break;
01602 case 4: sc->aspect_ratio = (AVRational){221,100}; break;
01603 default:
01604 av_reduce(&sc->aspect_ratio.num, &sc->aspect_ratio.den,
01605 st->codec->width, st->codec->height, 1024*1024);
01606 }
01607 } else if (c == 0x100) {
01608 int pict_type = (pkt->data[i+2]>>3) & 0x07;
01609 e->temporal_ref = (pkt->data[i+1]<<2) | (pkt->data[i+2]>>6);
01610 if (pict_type == 2) {
01611 e->flags |= 0x22;
01612 sc->closed_gop = 0;
01613 } else if (pict_type == 3) {
01614 if (sc->closed_gop)
01615 e->flags |= 0x13;
01616 else
01617 e->flags |= 0x33;
01618 sc->temporal_reordering = -1;
01619 } else if (!pict_type) {
01620 av_log(s, AV_LOG_ERROR, "error parsing mpeg2 frame\n");
01621 return 0;
01622 }
01623 }
01624 }
01625 if (s->oformat != &ff_mxf_d10_muxer)
01626 sc->codec_ul = mxf_get_mpeg2_codec_ul(st->codec);
01627 return !!sc->codec_ul;
01628 }
01629
01630 static uint64_t mxf_parse_timestamp(time_t timestamp)
01631 {
01632 struct tm *time = gmtime(×tamp);
01633 if (!time)
01634 return 0;
01635 return (uint64_t)(time->tm_year+1900) << 48 |
01636 (uint64_t)(time->tm_mon+1) << 40 |
01637 (uint64_t) time->tm_mday << 32 |
01638 time->tm_hour << 24 |
01639 time->tm_min << 16 |
01640 time->tm_sec << 8;
01641 }
01642
01643 static void mxf_gen_umid(AVFormatContext *s)
01644 {
01645 MXFContext *mxf = s->priv_data;
01646 uint32_t seed = av_get_random_seed();
01647 uint64_t umid = seed + 0x5294713400000000LL;
01648
01649 AV_WB64(mxf->umid , umid);
01650 AV_WB64(mxf->umid+8, umid>>8);
01651
01652 mxf->instance_number = seed;
01653 }
01654
01655 static int mxf_write_header(AVFormatContext *s)
01656 {
01657 MXFContext *mxf = s->priv_data;
01658 int i, ret;
01659 uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0};
01660 const MXFSamplesPerFrame *spf = NULL;
01661 AVDictionaryEntry *t;
01662 int64_t timestamp = 0;
01663 AVDictionaryEntry *tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
01664
01665 if (!s->nb_streams)
01666 return -1;
01667
01668 for (i = 0; i < s->nb_streams; i++) {
01669 AVStream *st = s->streams[i];
01670 MXFStreamContext *sc = av_mallocz(sizeof(*sc));
01671 if (!sc)
01672 return AVERROR(ENOMEM);
01673 st->priv_data = sc;
01674
01675 if ((i == 0) ^ (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)) {
01676 av_log(s, AV_LOG_ERROR, "there must be exactly one video stream and it must be the first one\n");
01677 return -1;
01678 }
01679
01680 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
01681 AVRational rate, tbc = st->codec->time_base;
01682
01683 sc->component_depth = 8;
01684 mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num;
01685 spf = ff_mxf_get_samples_per_frame(s, tbc);
01686 if (!spf) {
01687 av_log(s, AV_LOG_ERROR, "Unsupported video frame rate %d/%d\n",
01688 tbc.den, tbc.num);
01689 return AVERROR(EINVAL);
01690 }
01691 mxf->time_base = spf->time_base;
01692 rate = av_inv_q(mxf->time_base);
01693 avpriv_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den);
01694 if (!tcr)
01695 tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
01696 if (tcr)
01697 ret = av_timecode_init_from_string(&mxf->tc, rate, tcr->value, s);
01698 else
01699 ret = av_timecode_init(&mxf->tc, rate, 0, 0, s);
01700 if (ret < 0)
01701 return ret;
01702 if (s->oformat == &ff_mxf_d10_muxer) {
01703 if (st->codec->bit_rate == 50000000)
01704 if (mxf->time_base.den == 25) sc->index = 3;
01705 else sc->index = 5;
01706 else if (st->codec->bit_rate == 40000000)
01707 if (mxf->time_base.den == 25) sc->index = 7;
01708 else sc->index = 9;
01709 else if (st->codec->bit_rate == 30000000)
01710 if (mxf->time_base.den == 25) sc->index = 11;
01711 else sc->index = 13;
01712 else {
01713 av_log(s, AV_LOG_ERROR, "error MXF D-10 only support 30/40/50 mbit/s\n");
01714 return -1;
01715 }
01716
01717 mxf->edit_unit_byte_count = KAG_SIZE;
01718 mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)st->codec->bit_rate *
01719 mxf->time_base.num / (8*mxf->time_base.den);
01720 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
01721 mxf->edit_unit_byte_count += 16 + 4 + 4 + spf->samples_per_frame[0]*8*4;
01722 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
01723 }
01724 } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
01725 if (st->codec->sample_rate != 48000) {
01726 av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n");
01727 return -1;
01728 }
01729 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
01730 if (s->oformat == &ff_mxf_d10_muxer) {
01731 if (st->index != 1) {
01732 av_log(s, AV_LOG_ERROR, "MXF D-10 only support one audio track\n");
01733 return -1;
01734 }
01735 if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE &&
01736 st->codec->codec_id != AV_CODEC_ID_PCM_S24LE) {
01737 av_log(s, AV_LOG_ERROR, "MXF D-10 only support 16 or 24 bits le audio\n");
01738 }
01739 sc->index = ((MXFStreamContext*)s->streams[0]->priv_data)->index + 1;
01740 } else
01741 mxf->slice_count = 1;
01742 }
01743
01744 if (!sc->index) {
01745 sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id);
01746 if (sc->index == -1) {
01747 av_log(s, AV_LOG_ERROR, "track %d: could not find essence container ul, "
01748 "codec not currently supported in container\n", i);
01749 return -1;
01750 }
01751 }
01752
01753 sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;
01754
01755 memcpy(sc->track_essence_element_key, mxf_essence_container_uls[sc->index].element_ul, 15);
01756 sc->track_essence_element_key[15] = present[sc->index];
01757 PRINT_KEY(s, "track essence element key", sc->track_essence_element_key);
01758
01759 if (!present[sc->index])
01760 mxf->essence_container_count++;
01761 present[sc->index]++;
01762 }
01763
01764 if (s->oformat == &ff_mxf_d10_muxer) {
01765 mxf->essence_container_count = 1;
01766 }
01767
01768 if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
01769 mxf_gen_umid(s);
01770
01771 for (i = 0; i < s->nb_streams; i++) {
01772 MXFStreamContext *sc = s->streams[i]->priv_data;
01773
01774 sc->track_essence_element_key[13] = present[sc->index];
01775 if (!memcmp(sc->track_essence_element_key, mxf_essence_container_uls[15].element_ul, 13))
01776 sc->order = (0x15 << 24) | AV_RB32(sc->track_essence_element_key+13);
01777 else
01778 sc->order = AV_RB32(sc->track_essence_element_key+12);
01779 }
01780
01781 if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
01782 timestamp = ff_iso8601_to_unix_time(t->value);
01783 if (timestamp)
01784 mxf->timestamp = mxf_parse_timestamp(timestamp);
01785 mxf->duration = -1;
01786
01787 mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track));
01788 if (!mxf->timecode_track)
01789 return AVERROR(ENOMEM);
01790 mxf->timecode_track->priv_data = av_mallocz(sizeof(MXFStreamContext));
01791 if (!mxf->timecode_track->priv_data)
01792 return AVERROR(ENOMEM);
01793 mxf->timecode_track->index = -1;
01794
01795 if (!spf)
01796 spf = ff_mxf_get_samples_per_frame(s, (AVRational){ 1, 25 });
01797
01798 if (ff_audio_interleave_init(s, spf->samples_per_frame, mxf->time_base) < 0)
01799 return -1;
01800
01801 return 0;
01802 }
01803
01804 static const uint8_t system_metadata_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x01,0x00 };
01805 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 };
01806
01807 static void mxf_write_system_item(AVFormatContext *s)
01808 {
01809 MXFContext *mxf = s->priv_data;
01810 AVIOContext *pb = s->pb;
01811 unsigned frame;
01812 uint32_t time_code;
01813
01814 frame = mxf->last_indexed_edit_unit + mxf->edit_units_count;
01815
01816
01817 avio_write(pb, system_metadata_pack_key, 16);
01818 klv_encode_ber4_length(pb, 57);
01819 avio_w8(pb, 0x5c);
01820 avio_w8(pb, 0x04);
01821 avio_w8(pb, 0x00);
01822 avio_wb16(pb, 0x00);
01823 avio_wb16(pb, mxf->tc.start + frame);
01824 if (mxf->essence_container_count > 1)
01825 avio_write(pb, multiple_desc_ul, 16);
01826 else {
01827 MXFStreamContext *sc = s->streams[0]->priv_data;
01828 avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
01829 }
01830 avio_w8(pb, 0);
01831 avio_wb64(pb, 0);
01832 avio_wb64(pb, 0);
01833
01834 avio_w8(pb, 0x81);
01835 time_code = av_timecode_get_smpte_from_framenum(&mxf->tc, frame);
01836 avio_wb32(pb, time_code);
01837 avio_wb32(pb, 0);
01838 avio_wb64(pb, 0);
01839
01840
01841 avio_write(pb, system_metadata_package_set_key, 16);
01842 klv_encode_ber4_length(pb, 35);
01843 avio_w8(pb, 0x83);
01844 avio_wb16(pb, 0x20);
01845 mxf_write_umid(s, 1);
01846 }
01847
01848 static void mxf_write_d10_video_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
01849 {
01850 MXFContext *mxf = s->priv_data;
01851 AVIOContext *pb = s->pb;
01852 int packet_size = (uint64_t)st->codec->bit_rate*mxf->time_base.num /
01853 (8*mxf->time_base.den);
01854 int pad;
01855
01856 packet_size += 16 + 4;
01857 packet_size += klv_fill_size(packet_size);
01858
01859 klv_encode_ber4_length(pb, pkt->size);
01860 avio_write(pb, pkt->data, pkt->size);
01861
01862
01863 pad = packet_size - pkt->size - 16 - 4;
01864 if (pad > 20) {
01865 avio_write(s->pb, klv_fill_key, 16);
01866 pad -= 16 + 4;
01867 klv_encode_ber4_length(s->pb, pad);
01868 for (; pad; pad--)
01869 avio_w8(s->pb, 0);
01870 av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1)));
01871 } else {
01872 av_log(s, AV_LOG_WARNING, "cannot fill d-10 video packet\n");
01873 for (; pad > 0; pad--)
01874 avio_w8(s->pb, 0);
01875 }
01876 }
01877
01878 static void mxf_write_d10_audio_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
01879 {
01880 MXFContext *mxf = s->priv_data;
01881 AVIOContext *pb = s->pb;
01882 int frame_size = pkt->size / st->codec->block_align;
01883 uint8_t *samples = pkt->data;
01884 uint8_t *end = pkt->data + pkt->size;
01885 int i;
01886
01887 klv_encode_ber4_length(pb, 4 + frame_size*4*8);
01888
01889 avio_w8(pb, (frame_size == 1920 ? 0 : (mxf->edit_units_count-1) % 5 + 1));
01890 avio_wl16(pb, frame_size);
01891 avio_w8(pb, (1<<st->codec->channels)-1);
01892
01893 while (samples < end) {
01894 for (i = 0; i < st->codec->channels; i++) {
01895 uint32_t sample;
01896 if (st->codec->codec_id == AV_CODEC_ID_PCM_S24LE) {
01897 sample = AV_RL24(samples)<< 4;
01898 samples += 3;
01899 } else {
01900 sample = AV_RL16(samples)<<12;
01901 samples += 2;
01902 }
01903 avio_wl32(pb, sample | i);
01904 }
01905 for (; i < 8; i++)
01906 avio_wl32(pb, i);
01907 }
01908 }
01909
01910 static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt)
01911 {
01912 MXFContext *mxf = s->priv_data;
01913 AVIOContext *pb = s->pb;
01914 AVStream *st = s->streams[pkt->stream_index];
01915 MXFStreamContext *sc = st->priv_data;
01916 MXFIndexEntry ie = {0};
01917
01918 if (!mxf->edit_unit_byte_count && !(mxf->edit_units_count % EDIT_UNITS_PER_BODY)) {
01919 mxf->index_entries = av_realloc(mxf->index_entries,
01920 (mxf->edit_units_count + EDIT_UNITS_PER_BODY)*sizeof(*mxf->index_entries));
01921 if (!mxf->index_entries) {
01922 av_log(s, AV_LOG_ERROR, "could not allocate index entries\n");
01923 return -1;
01924 }
01925 }
01926
01927 if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
01928 if (!mxf_parse_mpeg2_frame(s, st, pkt, &ie)) {
01929 av_log(s, AV_LOG_ERROR, "could not get mpeg2 profile and level\n");
01930 return -1;
01931 }
01932 } else if (st->codec->codec_id == AV_CODEC_ID_DNXHD) {
01933 if (!mxf_parse_dnxhd_frame(s, st, pkt)) {
01934 av_log(s, AV_LOG_ERROR, "could not get dnxhd profile\n");
01935 return -1;
01936 }
01937 } else if (st->codec->codec_id == AV_CODEC_ID_DVVIDEO) {
01938 if (!mxf_parse_dv_frame(s, st, pkt)) {
01939 av_log(s, AV_LOG_ERROR, "could not get dv profile\n");
01940 return -1;
01941 }
01942 }
01943
01944 if (!mxf->header_written) {
01945 if (mxf->edit_unit_byte_count) {
01946 mxf_write_partition(s, 1, 2, header_open_partition_key, 1);
01947 mxf_write_klv_fill(s);
01948 mxf_write_index_table_segment(s);
01949 } else {
01950 mxf_write_partition(s, 0, 0, header_open_partition_key, 1);
01951 }
01952 mxf->header_written = 1;
01953 }
01954
01955 if (st->index == 0) {
01956 if (!mxf->edit_unit_byte_count &&
01957 (!mxf->edit_units_count || mxf->edit_units_count > EDIT_UNITS_PER_BODY) &&
01958 !(ie.flags & 0x33)) {
01959 mxf_write_klv_fill(s);
01960 mxf_write_partition(s, 1, 2, body_partition_key, 0);
01961
01962 mxf_write_klv_fill(s);
01963 mxf_write_index_table_segment(s);
01964 }
01965
01966 mxf_write_klv_fill(s);
01967 mxf_write_system_item(s);
01968
01969 if (!mxf->edit_unit_byte_count) {
01970 mxf->index_entries[mxf->edit_units_count].offset = mxf->body_offset;
01971 mxf->index_entries[mxf->edit_units_count].flags = ie.flags;
01972 mxf->index_entries[mxf->edit_units_count].temporal_ref = ie.temporal_ref;
01973 mxf->body_offset += KAG_SIZE;
01974 }
01975 mxf->edit_units_count++;
01976 } else if (!mxf->edit_unit_byte_count && st->index == 1) {
01977 mxf->index_entries[mxf->edit_units_count-1].slice_offset =
01978 mxf->body_offset - mxf->index_entries[mxf->edit_units_count-1].offset;
01979 }
01980
01981 mxf_write_klv_fill(s);
01982 avio_write(pb, sc->track_essence_element_key, 16);
01983 if (s->oformat == &ff_mxf_d10_muxer) {
01984 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
01985 mxf_write_d10_video_packet(s, st, pkt);
01986 else
01987 mxf_write_d10_audio_packet(s, st, pkt);
01988 } else {
01989 klv_encode_ber4_length(pb, pkt->size);
01990 avio_write(pb, pkt->data, pkt->size);
01991 mxf->body_offset += 16+4+pkt->size + klv_fill_size(16+4+pkt->size);
01992 }
01993
01994 avio_flush(pb);
01995
01996 return 0;
01997 }
01998
01999 static void mxf_write_random_index_pack(AVFormatContext *s)
02000 {
02001 MXFContext *mxf = s->priv_data;
02002 AVIOContext *pb = s->pb;
02003 uint64_t pos = avio_tell(pb);
02004 int i;
02005
02006 avio_write(pb, random_index_pack_key, 16);
02007 klv_encode_ber_length(pb, 28 + 12*mxf->body_partitions_count);
02008
02009 if (mxf->edit_unit_byte_count)
02010 avio_wb32(pb, 1);
02011 else
02012 avio_wb32(pb, 0);
02013 avio_wb64(pb, 0);
02014
02015 for (i = 0; i < mxf->body_partitions_count; i++) {
02016 avio_wb32(pb, 1);
02017 avio_wb64(pb, mxf->body_partition_offset[i]);
02018 }
02019
02020 avio_wb32(pb, 0);
02021 avio_wb64(pb, mxf->footer_partition_offset);
02022
02023 avio_wb32(pb, avio_tell(pb) - pos + 4);
02024 }
02025
02026 static int mxf_write_footer(AVFormatContext *s)
02027 {
02028 MXFContext *mxf = s->priv_data;
02029 AVIOContext *pb = s->pb;
02030
02031 mxf->duration = mxf->last_indexed_edit_unit + mxf->edit_units_count;
02032
02033 mxf_write_klv_fill(s);
02034 mxf->footer_partition_offset = avio_tell(pb);
02035 if (mxf->edit_unit_byte_count) {
02036 mxf_write_partition(s, 0, 0, footer_partition_key, 0);
02037 } else {
02038 mxf_write_partition(s, 0, 2, footer_partition_key, 0);
02039
02040 mxf_write_klv_fill(s);
02041 mxf_write_index_table_segment(s);
02042 }
02043
02044 mxf_write_klv_fill(s);
02045 mxf_write_random_index_pack(s);
02046
02047 if (s->pb->seekable) {
02048 avio_seek(pb, 0, SEEK_SET);
02049 if (mxf->edit_unit_byte_count) {
02050 mxf_write_partition(s, 1, 2, header_closed_partition_key, 1);
02051 mxf_write_klv_fill(s);
02052 mxf_write_index_table_segment(s);
02053 } else {
02054 mxf_write_partition(s, 0, 0, header_closed_partition_key, 1);
02055 }
02056 }
02057
02058 ff_audio_interleave_close(s);
02059
02060 av_freep(&mxf->index_entries);
02061 av_freep(&mxf->body_partition_offset);
02062 av_freep(&mxf->timecode_track->priv_data);
02063 av_freep(&mxf->timecode_track);
02064
02065 mxf_free(s);
02066
02067 return 0;
02068 }
02069
02070 static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
02071 {
02072 int i, stream_count = 0;
02073
02074 for (i = 0; i < s->nb_streams; i++)
02075 stream_count += !!s->streams[i]->last_in_packet_buffer;
02076
02077 if (stream_count && (s->nb_streams == stream_count || flush)) {
02078 AVPacketList *pktl = s->packet_buffer;
02079 if (s->nb_streams != stream_count) {
02080 AVPacketList *last = NULL;
02081
02082 while (pktl) {
02083 if (!stream_count || pktl->pkt.stream_index == 0)
02084 break;
02085 last = pktl;
02086 pktl = pktl->next;
02087 stream_count--;
02088 }
02089
02090 while (pktl) {
02091 AVPacketList *next = pktl->next;
02092
02093 if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl)
02094 s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL;
02095 av_free_packet(&pktl->pkt);
02096 av_freep(&pktl);
02097 pktl = next;
02098 }
02099 if (last)
02100 last->next = NULL;
02101 else {
02102 s->packet_buffer = NULL;
02103 s->packet_buffer_end= NULL;
02104 goto out;
02105 }
02106 pktl = s->packet_buffer;
02107 }
02108
02109 *out = pktl->pkt;
02110
02111 s->packet_buffer = pktl->next;
02112 if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl)
02113 s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL;
02114 if(!s->packet_buffer)
02115 s->packet_buffer_end= NULL;
02116 av_freep(&pktl);
02117 return 1;
02118 } else {
02119 out:
02120 av_init_packet(out);
02121 return 0;
02122 }
02123 }
02124
02125 static int mxf_compare_timestamps(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
02126 {
02127 MXFStreamContext *sc = s->streams[pkt ->stream_index]->priv_data;
02128 MXFStreamContext *sc2 = s->streams[next->stream_index]->priv_data;
02129
02130 return next->dts > pkt->dts ||
02131 (next->dts == pkt->dts && sc->order < sc2->order);
02132 }
02133
02134 static int mxf_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
02135 {
02136 return ff_audio_rechunk_interleave(s, out, pkt, flush,
02137 mxf_interleave_get_packet, mxf_compare_timestamps);
02138 }
02139
02140 AVOutputFormat ff_mxf_muxer = {
02141 .name = "mxf",
02142 .long_name = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format)"),
02143 .mime_type = "application/mxf",
02144 .extensions = "mxf",
02145 .priv_data_size = sizeof(MXFContext),
02146 .audio_codec = AV_CODEC_ID_PCM_S16LE,
02147 .video_codec = AV_CODEC_ID_MPEG2VIDEO,
02148 .write_header = mxf_write_header,
02149 .write_packet = mxf_write_packet,
02150 .write_trailer = mxf_write_footer,
02151 .flags = AVFMT_NOTIMESTAMPS,
02152 .interleave_packet = mxf_interleave,
02153 };
02154
02155 AVOutputFormat ff_mxf_d10_muxer = {
02156 .name = "mxf_d10",
02157 .long_name = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format) D-10 Mapping"),
02158 .mime_type = "application/mxf",
02159 .priv_data_size = sizeof(MXFContext),
02160 .audio_codec = AV_CODEC_ID_PCM_S16LE,
02161 .video_codec = AV_CODEC_ID_MPEG2VIDEO,
02162 .write_header = mxf_write_header,
02163 .write_packet = mxf_write_packet,
02164 .write_trailer = mxf_write_footer,
02165 .flags = AVFMT_NOTIMESTAMPS,
02166 .interleave_packet = mxf_interleave,
02167 };