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
00533 #define DESCRIPTOR_COUNT(essence_container_count) \
00534 (essence_container_count > 1 ? essence_container_count + 1 : essence_container_count)
00535
00536 static void mxf_write_essence_container_refs(AVFormatContext *s)
00537 {
00538 MXFContext *c = s->priv_data;
00539 AVIOContext *pb = s->pb;
00540 int i;
00541
00542 mxf_write_refs_count(pb, DESCRIPTOR_COUNT(c->essence_container_count));
00543 av_log(s,AV_LOG_DEBUG, "essence container count:%d\n", c->essence_container_count);
00544 for (i = 0; i < c->essence_container_count; i++) {
00545 MXFStreamContext *sc = s->streams[i]->priv_data;
00546 avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
00547 }
00548
00549 if (c->essence_container_count > 1)
00550 avio_write(pb, multiple_desc_ul, 16);
00551 }
00552
00553 static void mxf_write_preface(AVFormatContext *s)
00554 {
00555 MXFContext *mxf = s->priv_data;
00556 AVIOContext *pb = s->pb;
00557
00558 mxf_write_metadata_key(pb, 0x012f00);
00559 PRINT_KEY(s, "preface key", pb->buf_ptr - 16);
00560 klv_encode_ber_length(pb, 130 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count));
00561
00562
00563 mxf_write_local_tag(pb, 16, 0x3C0A);
00564 mxf_write_uuid(pb, Preface, 0);
00565 PRINT_KEY(s, "preface uid", pb->buf_ptr - 16);
00566
00567
00568 mxf_write_local_tag(pb, 8, 0x3B02);
00569 avio_wb64(pb, mxf->timestamp);
00570
00571
00572 mxf_write_local_tag(pb, 2, 0x3B05);
00573 avio_wb16(pb, 258);
00574
00575
00576 mxf_write_local_tag(pb, 16 + 8, 0x3B06);
00577 mxf_write_refs_count(pb, 1);
00578 mxf_write_uuid(pb, Identification, 0);
00579
00580
00581 mxf_write_local_tag(pb, 16, 0x3B03);
00582 mxf_write_uuid(pb, ContentStorage, 0);
00583
00584
00585 mxf_write_local_tag(pb, 16, 0x3B09);
00586 avio_write(pb, op1a_ul, 16);
00587
00588
00589 mxf_write_local_tag(pb, 8 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count), 0x3B0A);
00590 mxf_write_essence_container_refs(s);
00591
00592
00593 mxf_write_local_tag(pb, 8, 0x3B0B);
00594 avio_wb64(pb, 0);
00595 }
00596
00597
00598
00599
00600 static void mxf_write_local_tag_utf16(AVIOContext *pb, int tag, const char *value)
00601 {
00602 int i, size = strlen(value);
00603 mxf_write_local_tag(pb, size*2, tag);
00604 for (i = 0; i < size; i++)
00605 avio_wb16(pb, value[i]);
00606 }
00607
00608 static void mxf_write_identification(AVFormatContext *s)
00609 {
00610 MXFContext *mxf = s->priv_data;
00611 AVIOContext *pb = s->pb;
00612 const char *company = "FFmpeg";
00613 const char *product = "OP1a Muxer";
00614 const char *version;
00615 int length;
00616
00617 mxf_write_metadata_key(pb, 0x013000);
00618 PRINT_KEY(s, "identification key", pb->buf_ptr - 16);
00619
00620 version = s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT ?
00621 "0.0.0" : AV_STRINGIFY(LIBAVFORMAT_VERSION);
00622 length = 84 + (strlen(company)+strlen(product)+strlen(version))*2;
00623 klv_encode_ber_length(pb, length);
00624
00625
00626 mxf_write_local_tag(pb, 16, 0x3C0A);
00627 mxf_write_uuid(pb, Identification, 0);
00628 PRINT_KEY(s, "identification uid", pb->buf_ptr - 16);
00629
00630
00631 mxf_write_local_tag(pb, 16, 0x3C09);
00632 mxf_write_uuid(pb, Identification, 1);
00633
00634 mxf_write_local_tag_utf16(pb, 0x3C01, company);
00635 mxf_write_local_tag_utf16(pb, 0x3C02, product);
00636 mxf_write_local_tag_utf16(pb, 0x3C04, version);
00637
00638
00639 mxf_write_local_tag(pb, 16, 0x3C05);
00640 mxf_write_uuid(pb, Identification, 2);
00641
00642
00643 mxf_write_local_tag(pb, 8, 0x3C06);
00644 avio_wb64(pb, mxf->timestamp);
00645 }
00646
00647 static void mxf_write_content_storage(AVFormatContext *s)
00648 {
00649 AVIOContext *pb = s->pb;
00650
00651 mxf_write_metadata_key(pb, 0x011800);
00652 PRINT_KEY(s, "content storage key", pb->buf_ptr - 16);
00653 klv_encode_ber_length(pb, 92);
00654
00655
00656 mxf_write_local_tag(pb, 16, 0x3C0A);
00657 mxf_write_uuid(pb, ContentStorage, 0);
00658 PRINT_KEY(s, "content storage uid", pb->buf_ptr - 16);
00659
00660
00661 mxf_write_local_tag(pb, 16 * 2 + 8, 0x1901);
00662 mxf_write_refs_count(pb, 2);
00663 mxf_write_uuid(pb, MaterialPackage, 0);
00664 mxf_write_uuid(pb, SourcePackage, 0);
00665
00666
00667 mxf_write_local_tag(pb, 8 + 16, 0x1902);
00668 mxf_write_refs_count(pb, 1);
00669 mxf_write_uuid(pb, EssenceContainerData, 0);
00670 }
00671
00672 static void mxf_write_track(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
00673 {
00674 MXFContext *mxf = s->priv_data;
00675 AVIOContext *pb = s->pb;
00676 MXFStreamContext *sc = st->priv_data;
00677
00678 mxf_write_metadata_key(pb, 0x013b00);
00679 PRINT_KEY(s, "track key", pb->buf_ptr - 16);
00680 klv_encode_ber_length(pb, 80);
00681
00682
00683 mxf_write_local_tag(pb, 16, 0x3C0A);
00684 mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, st->index);
00685 PRINT_KEY(s, "track uid", pb->buf_ptr - 16);
00686
00687
00688 mxf_write_local_tag(pb, 4, 0x4801);
00689 avio_wb32(pb, st->index+2);
00690
00691
00692 mxf_write_local_tag(pb, 4, 0x4804);
00693 if (type == MaterialPackage)
00694 avio_wb32(pb, 0);
00695 else
00696 avio_write(pb, sc->track_essence_element_key + 12, 4);
00697
00698 mxf_write_local_tag(pb, 8, 0x4B01);
00699 avio_wb32(pb, mxf->time_base.den);
00700 avio_wb32(pb, mxf->time_base.num);
00701
00702
00703 mxf_write_local_tag(pb, 8, 0x4B02);
00704 avio_wb64(pb, 0);
00705
00706
00707 mxf_write_local_tag(pb, 16, 0x4803);
00708 mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index);
00709 }
00710
00711 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 };
00712
00713 static void mxf_write_common_fields(AVFormatContext *s, AVStream *st)
00714 {
00715 MXFContext *mxf = s->priv_data;
00716 AVIOContext *pb = s->pb;
00717
00718
00719 mxf_write_local_tag(pb, 16, 0x0201);
00720 if (st == mxf->timecode_track)
00721 avio_write(pb, smpte_12m_timecode_track_data_ul, 16);
00722 else {
00723 const MXFCodecUL *data_def_ul = mxf_get_data_definition_ul(st->codec->codec_type);
00724 avio_write(pb, data_def_ul->uid, 16);
00725 }
00726
00727
00728 mxf_write_local_tag(pb, 8, 0x0202);
00729 avio_wb64(pb, mxf->duration);
00730 }
00731
00732 static void mxf_write_sequence(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
00733 {
00734 MXFContext *mxf = s->priv_data;
00735 AVIOContext *pb = s->pb;
00736 enum MXFMetadataSetType component;
00737
00738 mxf_write_metadata_key(pb, 0x010f00);
00739 PRINT_KEY(s, "sequence key", pb->buf_ptr - 16);
00740 klv_encode_ber_length(pb, 80);
00741
00742 mxf_write_local_tag(pb, 16, 0x3C0A);
00743 mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index);
00744
00745 PRINT_KEY(s, "sequence uid", pb->buf_ptr - 16);
00746 mxf_write_common_fields(s, st);
00747
00748
00749 mxf_write_local_tag(pb, 16 + 8, 0x1001);
00750 mxf_write_refs_count(pb, 1);
00751 if (st == mxf->timecode_track)
00752 component = TimecodeComponent;
00753 else
00754 component = SourceClip;
00755 if (type == SourcePackage)
00756 component += TypeBottom;
00757 mxf_write_uuid(pb, component, st->index);
00758 }
00759
00760 static void mxf_write_timecode_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
00761 {
00762 MXFContext *mxf = s->priv_data;
00763 AVIOContext *pb = s->pb;
00764
00765 mxf_write_metadata_key(pb, 0x011400);
00766 klv_encode_ber_length(pb, 75);
00767
00768
00769 mxf_write_local_tag(pb, 16, 0x3C0A);
00770 mxf_write_uuid(pb, type == MaterialPackage ? TimecodeComponent :
00771 TimecodeComponent + TypeBottom, st->index);
00772
00773 mxf_write_common_fields(s, st);
00774
00775
00776 mxf_write_local_tag(pb, 8, 0x1501);
00777 avio_wb64(pb, mxf->tc.start);
00778
00779
00780 mxf_write_local_tag(pb, 2, 0x1502);
00781 avio_wb16(pb, mxf->timecode_base);
00782
00783
00784 mxf_write_local_tag(pb, 1, 0x1503);
00785 avio_w8(pb, !!(mxf->tc.flags & AV_TIMECODE_FLAG_DROPFRAME));
00786 }
00787
00788 static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
00789 {
00790 AVIOContext *pb = s->pb;
00791 int i;
00792
00793 mxf_write_metadata_key(pb, 0x011100);
00794 PRINT_KEY(s, "sturctural component key", pb->buf_ptr - 16);
00795 klv_encode_ber_length(pb, 108);
00796
00797
00798 mxf_write_local_tag(pb, 16, 0x3C0A);
00799 mxf_write_uuid(pb, type == MaterialPackage ? SourceClip: SourceClip + TypeBottom, st->index);
00800
00801 PRINT_KEY(s, "structural component uid", pb->buf_ptr - 16);
00802 mxf_write_common_fields(s, st);
00803
00804
00805 mxf_write_local_tag(pb, 8, 0x1201);
00806 avio_wb64(pb, 0);
00807
00808
00809 mxf_write_local_tag(pb, 32, 0x1101);
00810 if (type == SourcePackage) {
00811 for (i = 0; i < 4; i++)
00812 avio_wb64(pb, 0);
00813 } else
00814 mxf_write_umid(s, 1);
00815
00816
00817 mxf_write_local_tag(pb, 4, 0x1102);
00818 if (type == SourcePackage)
00819 avio_wb32(pb, 0);
00820 else
00821 avio_wb32(pb, st->index+2);
00822 }
00823
00824 static void mxf_write_multi_descriptor(AVFormatContext *s)
00825 {
00826 MXFContext *mxf = s->priv_data;
00827 AVIOContext *pb = s->pb;
00828 const uint8_t *ul;
00829 int i;
00830
00831 mxf_write_metadata_key(pb, 0x014400);
00832 PRINT_KEY(s, "multiple descriptor key", pb->buf_ptr - 16);
00833 klv_encode_ber_length(pb, 64 + 16LL * s->nb_streams);
00834
00835 mxf_write_local_tag(pb, 16, 0x3C0A);
00836 mxf_write_uuid(pb, MultipleDescriptor, 0);
00837 PRINT_KEY(s, "multi_desc uid", pb->buf_ptr - 16);
00838
00839
00840 mxf_write_local_tag(pb, 8, 0x3001);
00841 avio_wb32(pb, mxf->time_base.den);
00842 avio_wb32(pb, mxf->time_base.num);
00843
00844
00845 mxf_write_local_tag(pb, 16, 0x3004);
00846 if (mxf->essence_container_count > 1)
00847 ul = multiple_desc_ul;
00848 else {
00849 MXFStreamContext *sc = s->streams[0]->priv_data;
00850 ul = mxf_essence_container_uls[sc->index].container_ul;
00851 }
00852 avio_write(pb, ul, 16);
00853
00854
00855 mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01);
00856 mxf_write_refs_count(pb, s->nb_streams);
00857 for (i = 0; i < s->nb_streams; i++)
00858 mxf_write_uuid(pb, SubDescriptor, i);
00859 }
00860
00861 static void mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
00862 {
00863 MXFContext *mxf = s->priv_data;
00864 MXFStreamContext *sc = st->priv_data;
00865 AVIOContext *pb = s->pb;
00866
00867 avio_write(pb, key, 16);
00868 klv_encode_ber4_length(pb, size+20+8+12+20);
00869
00870 mxf_write_local_tag(pb, 16, 0x3C0A);
00871 mxf_write_uuid(pb, SubDescriptor, st->index);
00872
00873 mxf_write_local_tag(pb, 4, 0x3006);
00874 avio_wb32(pb, st->index+2);
00875
00876 mxf_write_local_tag(pb, 8, 0x3001);
00877 avio_wb32(pb, mxf->time_base.den);
00878 avio_wb32(pb, mxf->time_base.num);
00879
00880 mxf_write_local_tag(pb, 16, 0x3004);
00881 avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
00882 }
00883
00884 static const UID mxf_mpegvideo_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 };
00885 static const UID mxf_wav_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 };
00886 static const UID mxf_aes3_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 };
00887 static const UID mxf_cdci_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x28,0x00 };
00888 static const UID mxf_generic_sound_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x42,0x00 };
00889
00890 static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
00891 {
00892 MXFStreamContext *sc = st->priv_data;
00893 AVIOContext *pb = s->pb;
00894 int stored_height = (st->codec->height+15)/16*16;
00895 int display_height;
00896 int f1, f2;
00897 unsigned desc_size = size+8+8+8+8+8+8+5+16+sc->interlaced*4+12+20;
00898 if (sc->interlaced && sc->field_dominance)
00899 desc_size += 5;
00900
00901 mxf_write_generic_desc(s, st, key, desc_size);
00902
00903 mxf_write_local_tag(pb, 4, 0x3203);
00904 avio_wb32(pb, st->codec->width);
00905
00906 mxf_write_local_tag(pb, 4, 0x3202);
00907 avio_wb32(pb, stored_height>>sc->interlaced);
00908
00909 mxf_write_local_tag(pb, 4, 0x3209);
00910 avio_wb32(pb, st->codec->width);
00911
00912 if (st->codec->height == 608)
00913 display_height = 576;
00914 else if (st->codec->height == 512)
00915 display_height = 486;
00916 else
00917 display_height = st->codec->height;
00918
00919 mxf_write_local_tag(pb, 4, 0x3208);
00920 avio_wb32(pb, display_height>>sc->interlaced);
00921
00922
00923 mxf_write_local_tag(pb, 4, 0x3301);
00924 avio_wb32(pb, sc->component_depth);
00925
00926
00927 mxf_write_local_tag(pb, 4, 0x3302);
00928 avio_wb32(pb, 2);
00929
00930
00931 mxf_write_local_tag(pb, 1, 0x320C);
00932 avio_w8(pb, sc->interlaced);
00933
00934
00935 switch (st->codec->height) {
00936 case 576: f1 = 23; f2 = st->codec->codec_id == AV_CODEC_ID_DVVIDEO ? 335 : 336; break;
00937 case 608: f1 = 7; f2 = 320; break;
00938 case 480: f1 = 20; f2 = st->codec->codec_id == AV_CODEC_ID_DVVIDEO ? 285 : 283; break;
00939 case 512: f1 = 7; f2 = 270; break;
00940 case 720: f1 = 26; f2 = 0; break;
00941 case 1080: f1 = 21; f2 = 584; break;
00942 default: f1 = 0; f2 = 0; break;
00943 }
00944
00945 if (!sc->interlaced) {
00946 f2 = 0;
00947 f1 *= 2;
00948 }
00949
00950 mxf_write_local_tag(pb, 12+sc->interlaced*4, 0x320D);
00951 avio_wb32(pb, sc->interlaced ? 2 : 1);
00952 avio_wb32(pb, 4);
00953 avio_wb32(pb, f1);
00954 if (sc->interlaced)
00955 avio_wb32(pb, f2);
00956
00957 mxf_write_local_tag(pb, 8, 0x320E);
00958 avio_wb32(pb, sc->aspect_ratio.num);
00959 avio_wb32(pb, sc->aspect_ratio.den);
00960
00961 mxf_write_local_tag(pb, 16, 0x3201);
00962 avio_write(pb, *sc->codec_ul, 16);
00963
00964 if (sc->interlaced && sc->field_dominance) {
00965 mxf_write_local_tag(pb, 1, 0x3212);
00966 avio_w8(pb, sc->field_dominance);
00967 }
00968
00969 }
00970
00971 static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st)
00972 {
00973 mxf_write_cdci_common(s, st, mxf_cdci_descriptor_key, 0);
00974 }
00975
00976 static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st)
00977 {
00978 AVIOContext *pb = s->pb;
00979 int profile_and_level = (st->codec->profile<<4) | st->codec->level;
00980
00981 mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key, 8+5);
00982
00983
00984 mxf_write_local_tag(pb, 4, 0x8000);
00985 avio_wb32(pb, st->codec->bit_rate);
00986
00987
00988 mxf_write_local_tag(pb, 1, 0x8007);
00989 if (!st->codec->profile)
00990 profile_and_level |= 0x80;
00991 avio_w8(pb, profile_and_level);
00992 }
00993
00994 static void mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
00995 {
00996 AVIOContext *pb = s->pb;
00997
00998 mxf_write_generic_desc(s, st, key, size+5+12+8+8);
00999
01000
01001 mxf_write_local_tag(pb, 1, 0x3D02);
01002 avio_w8(pb, 1);
01003
01004
01005 mxf_write_local_tag(pb, 8, 0x3D03);
01006 avio_wb32(pb, st->codec->sample_rate);
01007 avio_wb32(pb, 1);
01008
01009 mxf_write_local_tag(pb, 4, 0x3D07);
01010 avio_wb32(pb, st->codec->channels);
01011
01012 mxf_write_local_tag(pb, 4, 0x3D01);
01013 avio_wb32(pb, av_get_bits_per_sample(st->codec->codec_id));
01014 }
01015
01016 static void mxf_write_wav_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
01017 {
01018 AVIOContext *pb = s->pb;
01019
01020 mxf_write_generic_sound_common(s, st, key, size+6+8);
01021
01022 mxf_write_local_tag(pb, 2, 0x3D0A);
01023 avio_wb16(pb, st->codec->block_align);
01024
01025
01026 mxf_write_local_tag(pb, 4, 0x3D09);
01027 avio_wb32(pb, st->codec->block_align*st->codec->sample_rate);
01028 }
01029
01030 static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st)
01031 {
01032 mxf_write_wav_common(s, st, mxf_wav_descriptor_key, 0);
01033 }
01034
01035 static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st)
01036 {
01037 mxf_write_wav_common(s, st, mxf_aes3_descriptor_key, 0);
01038 }
01039
01040 static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st)
01041 {
01042 mxf_write_generic_sound_common(s, st, mxf_generic_sound_descriptor_key, 0);
01043 }
01044
01045 static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type)
01046 {
01047 MXFContext *mxf = s->priv_data;
01048 AVIOContext *pb = s->pb;
01049 int i, track_count = s->nb_streams+1;
01050
01051 if (type == MaterialPackage) {
01052 mxf_write_metadata_key(pb, 0x013600);
01053 PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16);
01054 klv_encode_ber_length(pb, 92 + 16*track_count);
01055 } else {
01056 mxf_write_metadata_key(pb, 0x013700);
01057 PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16);
01058 klv_encode_ber_length(pb, 112 + 16*track_count);
01059 }
01060
01061
01062 mxf_write_local_tag(pb, 16, 0x3C0A);
01063 mxf_write_uuid(pb, type, 0);
01064 av_log(s,AV_LOG_DEBUG, "package type:%d\n", type);
01065 PRINT_KEY(s, "package uid", pb->buf_ptr - 16);
01066
01067
01068 mxf_write_local_tag(pb, 32, 0x4401);
01069 mxf_write_umid(s, type == SourcePackage);
01070 PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16);
01071
01072
01073 mxf_write_local_tag(pb, 8, 0x4405);
01074 avio_wb64(pb, mxf->timestamp);
01075
01076
01077 mxf_write_local_tag(pb, 8, 0x4404);
01078 avio_wb64(pb, mxf->timestamp);
01079
01080
01081 mxf_write_local_tag(pb, track_count*16 + 8, 0x4403);
01082 mxf_write_refs_count(pb, track_count);
01083 mxf_write_uuid(pb, type == MaterialPackage ? Track :
01084 Track + TypeBottom, -1);
01085 for (i = 0; i < s->nb_streams; i++)
01086 mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, i);
01087
01088
01089 if (type == SourcePackage) {
01090 mxf_write_local_tag(pb, 16, 0x4701);
01091 if (s->nb_streams > 1) {
01092 mxf_write_uuid(pb, MultipleDescriptor, 0);
01093 mxf_write_multi_descriptor(s);
01094 } else
01095 mxf_write_uuid(pb, SubDescriptor, 0);
01096 }
01097
01098
01099 mxf_write_track(s, mxf->timecode_track, type);
01100 mxf_write_sequence(s, mxf->timecode_track, type);
01101 mxf_write_timecode_component(s, mxf->timecode_track, type);
01102
01103 for (i = 0; i < s->nb_streams; i++) {
01104 AVStream *st = s->streams[i];
01105 mxf_write_track(s, st, type);
01106 mxf_write_sequence(s, st, type);
01107 mxf_write_structural_component(s, st, type);
01108
01109 if (type == SourcePackage) {
01110 MXFStreamContext *sc = st->priv_data;
01111 mxf_essence_container_uls[sc->index].write_desc(s, st);
01112 }
01113 }
01114 }
01115
01116 static int mxf_write_essence_container_data(AVFormatContext *s)
01117 {
01118 AVIOContext *pb = s->pb;
01119
01120 mxf_write_metadata_key(pb, 0x012300);
01121 klv_encode_ber_length(pb, 72);
01122
01123 mxf_write_local_tag(pb, 16, 0x3C0A);
01124 mxf_write_uuid(pb, EssenceContainerData, 0);
01125
01126 mxf_write_local_tag(pb, 32, 0x2701);
01127 mxf_write_umid(s, 1);
01128
01129 mxf_write_local_tag(pb, 4, 0x3F07);
01130 avio_wb32(pb, 1);
01131
01132 mxf_write_local_tag(pb, 4, 0x3F06);
01133 avio_wb32(pb, 2);
01134
01135 return 0;
01136 }
01137
01138 static int mxf_write_header_metadata_sets(AVFormatContext *s)
01139 {
01140 mxf_write_preface(s);
01141 mxf_write_identification(s);
01142 mxf_write_content_storage(s);
01143 mxf_write_package(s, MaterialPackage);
01144 mxf_write_package(s, SourcePackage);
01145 mxf_write_essence_container_data(s);
01146 return 0;
01147 }
01148
01149 static unsigned klv_fill_size(uint64_t size)
01150 {
01151 unsigned pad = KAG_SIZE - (size & (KAG_SIZE-1));
01152 if (pad < 20)
01153 return pad + KAG_SIZE;
01154 else
01155 return pad & (KAG_SIZE-1);
01156 }
01157
01158 static void mxf_write_index_table_segment(AVFormatContext *s)
01159 {
01160 MXFContext *mxf = s->priv_data;
01161 AVIOContext *pb = s->pb;
01162 int i, j, temporal_reordering = 0;
01163 int key_index = mxf->last_key_index;
01164
01165 av_log(s, AV_LOG_DEBUG, "edit units count %d\n", mxf->edit_units_count);
01166
01167 if (!mxf->edit_units_count && !mxf->edit_unit_byte_count)
01168 return;
01169
01170 avio_write(pb, index_table_segment_key, 16);
01171
01172 if (mxf->edit_unit_byte_count) {
01173 klv_encode_ber_length(pb, 80);
01174 } else {
01175 klv_encode_ber_length(pb, 85 + 12+(s->nb_streams+1LL)*6 +
01176 12+mxf->edit_units_count*(11+mxf->slice_count*4LL));
01177 }
01178
01179
01180 mxf_write_local_tag(pb, 16, 0x3C0A);
01181 mxf_write_uuid(pb, IndexTableSegment, 0);
01182
01183
01184 mxf_write_local_tag(pb, 8, 0x3F0B);
01185 avio_wb32(pb, mxf->time_base.den);
01186 avio_wb32(pb, mxf->time_base.num);
01187
01188
01189 mxf_write_local_tag(pb, 8, 0x3F0C);
01190 avio_wb64(pb, mxf->last_indexed_edit_unit);
01191
01192
01193 mxf_write_local_tag(pb, 8, 0x3F0D);
01194 if (mxf->edit_unit_byte_count)
01195 avio_wb64(pb, 0);
01196 else
01197 avio_wb64(pb, mxf->edit_units_count);
01198
01199
01200 mxf_write_local_tag(pb, 4, 0x3F05);
01201 avio_wb32(pb, mxf->edit_unit_byte_count);
01202
01203
01204 mxf_write_local_tag(pb, 4, 0x3F06);
01205 avio_wb32(pb, 2);
01206
01207
01208 mxf_write_local_tag(pb, 4, 0x3F07);
01209 avio_wb32(pb, 1);
01210
01211 if (!mxf->edit_unit_byte_count) {
01212
01213 mxf_write_local_tag(pb, 1, 0x3F08);
01214 avio_w8(pb, mxf->slice_count);
01215
01216
01217 mxf_write_local_tag(pb, 8 + (s->nb_streams+1)*6, 0x3F09);
01218 avio_wb32(pb, s->nb_streams+1);
01219 avio_wb32(pb, 6);
01220
01221 avio_w8(pb, 0);
01222 avio_w8(pb, 0);
01223 avio_wb32(pb, 0);
01224 for (i = 0; i < s->nb_streams; i++) {
01225 AVStream *st = s->streams[i];
01226 MXFStreamContext *sc = st->priv_data;
01227 avio_w8(pb, sc->temporal_reordering);
01228 if (sc->temporal_reordering)
01229 temporal_reordering = 1;
01230 if (i == 0) {
01231 avio_w8(pb, 0);
01232 avio_wb32(pb, KAG_SIZE);
01233 } else {
01234 unsigned audio_frame_size = sc->aic.samples[0]*sc->aic.sample_size;
01235 audio_frame_size += klv_fill_size(audio_frame_size);
01236 avio_w8(pb, 1);
01237 avio_wb32(pb, (i-1)*audio_frame_size);
01238 }
01239 }
01240
01241 mxf_write_local_tag(pb, 8 + mxf->edit_units_count*(11+mxf->slice_count*4), 0x3F0A);
01242 avio_wb32(pb, mxf->edit_units_count);
01243 avio_wb32(pb, 11+mxf->slice_count*4);
01244
01245 for (i = 0; i < mxf->edit_units_count; i++) {
01246 int temporal_offset = 0;
01247
01248 if (!(mxf->index_entries[i].flags & 0x33)) {
01249 mxf->last_key_index = key_index;
01250 key_index = i;
01251 }
01252
01253 if (temporal_reordering) {
01254 int pic_num_in_gop = i - key_index;
01255 if (pic_num_in_gop != mxf->index_entries[i].temporal_ref) {
01256 for (j = key_index; j < mxf->edit_units_count; j++) {
01257 if (pic_num_in_gop == mxf->index_entries[j].temporal_ref)
01258 break;
01259 }
01260 if (j == mxf->edit_units_count)
01261 av_log(s, AV_LOG_WARNING, "missing frames\n");
01262 temporal_offset = j - key_index - pic_num_in_gop;
01263 }
01264 }
01265 avio_w8(pb, temporal_offset);
01266
01267 if ((mxf->index_entries[i].flags & 0x30) == 0x30) {
01268 avio_w8(pb, mxf->last_key_index - i);
01269 } else {
01270 avio_w8(pb, key_index - i);
01271 if ((mxf->index_entries[i].flags & 0x20) == 0x20)
01272 mxf->last_key_index = key_index;
01273 }
01274
01275 if (!(mxf->index_entries[i].flags & 0x33) &&
01276 mxf->index_entries[i].flags & 0x40 && !temporal_offset)
01277 mxf->index_entries[i].flags |= 0x80;
01278 avio_w8(pb, mxf->index_entries[i].flags);
01279
01280 avio_wb64(pb, mxf->index_entries[i].offset);
01281 if (s->nb_streams > 1)
01282 avio_wb32(pb, mxf->index_entries[i].slice_offset);
01283 }
01284
01285 mxf->last_key_index = key_index - mxf->edit_units_count;
01286 mxf->last_indexed_edit_unit += mxf->edit_units_count;
01287 mxf->edit_units_count = 0;
01288 }
01289 }
01290
01291 static void mxf_write_klv_fill(AVFormatContext *s)
01292 {
01293 unsigned pad = klv_fill_size(avio_tell(s->pb));
01294 if (pad) {
01295 avio_write(s->pb, klv_fill_key, 16);
01296 pad -= 16 + 4;
01297 klv_encode_ber4_length(s->pb, pad);
01298 for (; pad; pad--)
01299 avio_w8(s->pb, 0);
01300 av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1)));
01301 }
01302 }
01303
01304 static void mxf_write_partition(AVFormatContext *s, int bodysid,
01305 int indexsid,
01306 const uint8_t *key, int write_metadata)
01307 {
01308 MXFContext *mxf = s->priv_data;
01309 AVIOContext *pb = s->pb;
01310 int64_t header_byte_count_offset;
01311 unsigned index_byte_count = 0;
01312 uint64_t partition_offset = avio_tell(pb);
01313
01314 if (!mxf->edit_unit_byte_count && mxf->edit_units_count)
01315 index_byte_count = 85 + 12+(s->nb_streams+1)*6 +
01316 12+mxf->edit_units_count*(11+mxf->slice_count*4);
01317 else if (mxf->edit_unit_byte_count && indexsid)
01318 index_byte_count = 80;
01319
01320 if (index_byte_count) {
01321
01322 index_byte_count += 16 + klv_ber_length(index_byte_count);
01323 index_byte_count += klv_fill_size(index_byte_count);
01324 }
01325
01326 if (!memcmp(key, body_partition_key, 16)) {
01327 mxf->body_partition_offset =
01328 av_realloc(mxf->body_partition_offset,
01329 (mxf->body_partitions_count+1)*
01330 sizeof(*mxf->body_partition_offset));
01331 mxf->body_partition_offset[mxf->body_partitions_count++] = partition_offset;
01332 }
01333
01334
01335 avio_write(pb, key, 16);
01336 klv_encode_ber_length(pb, 88 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count));
01337
01338
01339 avio_wb16(pb, 1);
01340 avio_wb16(pb, 2);
01341 avio_wb32(pb, KAG_SIZE);
01342
01343 avio_wb64(pb, partition_offset);
01344
01345 if (!memcmp(key, body_partition_key, 16) && mxf->body_partitions_count > 1)
01346 avio_wb64(pb, mxf->body_partition_offset[mxf->body_partitions_count-2]);
01347 else if (!memcmp(key, footer_partition_key, 16) && mxf->body_partitions_count)
01348 avio_wb64(pb, mxf->body_partition_offset[mxf->body_partitions_count-1]);
01349 else
01350 avio_wb64(pb, 0);
01351
01352 avio_wb64(pb, mxf->footer_partition_offset);
01353
01354
01355 header_byte_count_offset = avio_tell(pb);
01356 avio_wb64(pb, 0);
01357
01358
01359 avio_wb64(pb, index_byte_count);
01360 avio_wb32(pb, index_byte_count ? indexsid : 0);
01361
01362
01363 if (bodysid && mxf->edit_units_count && mxf->body_partitions_count) {
01364 avio_wb64(pb, mxf->body_offset);
01365 } else
01366 avio_wb64(pb, 0);
01367
01368 avio_wb32(pb, bodysid);
01369
01370
01371 avio_write(pb, op1a_ul, 16);
01372
01373
01374 mxf_write_essence_container_refs(s);
01375
01376 if (write_metadata) {
01377
01378 int64_t pos, start;
01379 unsigned header_byte_count;
01380
01381 mxf_write_klv_fill(s);
01382 start = avio_tell(s->pb);
01383 mxf_write_primer_pack(s);
01384 mxf_write_header_metadata_sets(s);
01385 pos = avio_tell(s->pb);
01386 header_byte_count = pos - start + klv_fill_size(pos);
01387
01388
01389 avio_seek(pb, header_byte_count_offset, SEEK_SET);
01390 avio_wb64(pb, header_byte_count);
01391 avio_seek(pb, pos, SEEK_SET);
01392 }
01393
01394 avio_flush(pb);
01395 }
01396
01397 static int mxf_parse_dnxhd_frame(AVFormatContext *s, AVStream *st,
01398 AVPacket *pkt)
01399 {
01400 MXFContext *mxf = s->priv_data;
01401 MXFStreamContext *sc = st->priv_data;
01402 int i, cid;
01403 uint8_t* header_cid;
01404 unsigned int frame_size = 0;
01405
01406 if (mxf->header_written)
01407 return 1;
01408
01409 if (pkt->size < 43)
01410 return -1;
01411
01412 header_cid = pkt->data + 0x28;
01413 cid = header_cid[0] << 24 | header_cid[1] << 16 | header_cid[2] << 8 | header_cid[3];
01414
01415 if ((i = ff_dnxhd_get_cid_table(cid)) < 0)
01416 return -1;
01417
01418 switch (cid) {
01419 case 1235:
01420 sc->index = 24;
01421 sc->component_depth = 10;
01422 break;
01423 case 1237:
01424 sc->index = 25;
01425 break;
01426 case 1238:
01427 sc->index = 26;
01428 break;
01429 case 1241:
01430 sc->index = 27;
01431 sc->component_depth = 10;
01432 break;
01433 case 1242:
01434 sc->index = 28;
01435 break;
01436 case 1243:
01437 sc->index = 29;
01438 break;
01439 case 1250:
01440 sc->index = 30;
01441 sc->component_depth = 10;
01442 break;
01443 case 1251:
01444 sc->index = 31;
01445 break;
01446 case 1252:
01447 sc->index = 32;
01448 break;
01449 case 1253:
01450 sc->index = 33;
01451 break;
01452 default:
01453 return -1;
01454 }
01455
01456 frame_size = ff_dnxhd_cid_table[i].frame_size;
01457 sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;
01458 sc->aspect_ratio = (AVRational){ 16, 9 };
01459
01460 mxf->edit_unit_byte_count = KAG_SIZE;
01461 for (i = 0; i < s->nb_streams; i++) {
01462 AVStream *st = s->streams[i];
01463 MXFStreamContext *sc = st->priv_data;
01464 if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
01465 mxf->edit_unit_byte_count += 16 + 4 + sc->aic.samples[0]*sc->aic.sample_size;
01466 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
01467 } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
01468 mxf->edit_unit_byte_count += 16 + 4 + frame_size;
01469 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
01470 }
01471 }
01472
01473 return 1;
01474 }
01475
01476 static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt)
01477 {
01478 MXFContext *mxf = s->priv_data;
01479 MXFStreamContext *sc = st->priv_data;
01480 uint8_t *vs_pack, *vsc_pack;
01481 int i, ul_index, frame_size, stype, pal;
01482
01483 if (mxf->header_written)
01484 return 1;
01485
01486
01487 if (pkt->size < 120000)
01488 return -1;
01489
01490 vs_pack = pkt->data + 80*5 + 48;
01491 vsc_pack = pkt->data + 80*5 + 53;
01492 stype = vs_pack[3] & 0x1f;
01493 pal = (vs_pack[3] >> 5) & 0x1;
01494
01495 if ((vs_pack[2] & 0x07) == 0x02)
01496 sc->aspect_ratio = (AVRational){ 16, 9 };
01497 else
01498 sc->aspect_ratio = (AVRational){ 4, 3 };
01499
01500 sc->interlaced = (vsc_pack[3] >> 4) & 0x01;
01501
01502
01503
01504
01505 switch (stype) {
01506 case 0x18:
01507 ul_index = 6 + pal;
01508 frame_size = pal ? 288000 : 240000;
01509 if (sc->interlaced) {
01510 av_log(s, AV_LOG_ERROR, "source marked as interlaced but codec profile is progressive\n");
01511 sc->interlaced = 0;
01512 }
01513 break;
01514 case 0x14:
01515 ul_index = 4 + pal;
01516 frame_size = pal ? 576000 : 480000;
01517 break;
01518 case 0x04:
01519 ul_index = 2 + pal;
01520 frame_size = pal ? 288000 : 240000;
01521 break;
01522 default:
01523 ul_index = 0 + pal;
01524 frame_size = pal ? 144000 : 120000;
01525 }
01526
01527 sc->index = ul_index + 16;
01528 sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;
01529
01530 mxf->edit_unit_byte_count = KAG_SIZE;
01531 for (i = 0; i < s->nb_streams; i++) {
01532 AVStream *st = s->streams[i];
01533 MXFStreamContext *sc = st->priv_data;
01534 if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
01535 mxf->edit_unit_byte_count += 16 + 4 + sc->aic.samples[0]*sc->aic.sample_size;
01536 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
01537 } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
01538 mxf->edit_unit_byte_count += 16 + 4 + frame_size;
01539 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
01540 }
01541 }
01542
01543 return 1;
01544 }
01545
01546 static const UID mxf_mpeg2_codec_uls[] = {
01547 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x10,0x00 },
01548 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 },
01549 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x02,0x00 },
01550 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x03,0x00 },
01551 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x02,0x00 },
01552 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 },
01553 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 },
01554 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x03,0x00 },
01555 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x02,0x00 },
01556 { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x03,0x00 },
01557 };
01558
01559 static const UID *mxf_get_mpeg2_codec_ul(AVCodecContext *avctx)
01560 {
01561 int long_gop = avctx->gop_size > 1 || avctx->has_b_frames;
01562
01563 if (avctx->profile == 4) {
01564 if (avctx->level == 8)
01565 return &mxf_mpeg2_codec_uls[0+long_gop];
01566 else if (avctx->level == 4)
01567 return &mxf_mpeg2_codec_uls[4+long_gop];
01568 else if (avctx->level == 6)
01569 return &mxf_mpeg2_codec_uls[8+long_gop];
01570 } else if (avctx->profile == 0) {
01571 if (avctx->level == 5)
01572 return &mxf_mpeg2_codec_uls[2+long_gop];
01573 else if (avctx->level == 2)
01574 return &mxf_mpeg2_codec_uls[6+long_gop];
01575 }
01576 return NULL;
01577 }
01578
01579 static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st,
01580 AVPacket *pkt, MXFIndexEntry *e)
01581 {
01582 MXFStreamContext *sc = st->priv_data;
01583 uint32_t c = -1;
01584 int i;
01585
01586 for(i = 0; i < pkt->size - 4; i++) {
01587 c = (c<<8) + pkt->data[i];
01588 if (c == 0x1b5) {
01589 if ((pkt->data[i+1] & 0xf0) == 0x10) {
01590 st->codec->profile = pkt->data[i+1] & 0x07;
01591 st->codec->level = pkt->data[i+2] >> 4;
01592 } else if (i + 5 < pkt->size && (pkt->data[i+1] & 0xf0) == 0x80) {
01593 sc->interlaced = !(pkt->data[i+5] & 0x80);
01594 if (sc->interlaced)
01595 sc->field_dominance = 1 + !(pkt->data[i+4] & 0x80);
01596 break;
01597 }
01598 } else if (c == 0x1b8) {
01599 if (pkt->data[i+4]>>6 & 0x01) {
01600 sc->closed_gop = 1;
01601 if (e->flags & 0x40)
01602 e->flags |= 0x80;
01603 }
01604 } else if (c == 0x1b3) {
01605 e->flags |= 0x40;
01606 switch ((pkt->data[i+4]>>4) & 0xf) {
01607 case 2: sc->aspect_ratio = (AVRational){ 4, 3}; break;
01608 case 3: sc->aspect_ratio = (AVRational){ 16, 9}; break;
01609 case 4: sc->aspect_ratio = (AVRational){221,100}; break;
01610 default:
01611 av_reduce(&sc->aspect_ratio.num, &sc->aspect_ratio.den,
01612 st->codec->width, st->codec->height, 1024*1024);
01613 }
01614 } else if (c == 0x100) {
01615 int pict_type = (pkt->data[i+2]>>3) & 0x07;
01616 e->temporal_ref = (pkt->data[i+1]<<2) | (pkt->data[i+2]>>6);
01617 if (pict_type == 2) {
01618 e->flags |= 0x22;
01619 sc->closed_gop = 0;
01620 } else if (pict_type == 3) {
01621 if (sc->closed_gop)
01622 e->flags |= 0x13;
01623 else
01624 e->flags |= 0x33;
01625 sc->temporal_reordering = -1;
01626 } else if (!pict_type) {
01627 av_log(s, AV_LOG_ERROR, "error parsing mpeg2 frame\n");
01628 return 0;
01629 }
01630 }
01631 }
01632 if (s->oformat != &ff_mxf_d10_muxer)
01633 sc->codec_ul = mxf_get_mpeg2_codec_ul(st->codec);
01634 return !!sc->codec_ul;
01635 }
01636
01637 static uint64_t mxf_parse_timestamp(time_t timestamp)
01638 {
01639 struct tm *time = gmtime(×tamp);
01640 if (!time)
01641 return 0;
01642 return (uint64_t)(time->tm_year+1900) << 48 |
01643 (uint64_t)(time->tm_mon+1) << 40 |
01644 (uint64_t) time->tm_mday << 32 |
01645 time->tm_hour << 24 |
01646 time->tm_min << 16 |
01647 time->tm_sec << 8;
01648 }
01649
01650 static void mxf_gen_umid(AVFormatContext *s)
01651 {
01652 MXFContext *mxf = s->priv_data;
01653 uint32_t seed = av_get_random_seed();
01654 uint64_t umid = seed + 0x5294713400000000LL;
01655
01656 AV_WB64(mxf->umid , umid);
01657 AV_WB64(mxf->umid+8, umid>>8);
01658
01659 mxf->instance_number = seed;
01660 }
01661
01662 static int mxf_write_header(AVFormatContext *s)
01663 {
01664 MXFContext *mxf = s->priv_data;
01665 int i, ret;
01666 uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0};
01667 const MXFSamplesPerFrame *spf = NULL;
01668 AVDictionaryEntry *t;
01669 int64_t timestamp = 0;
01670 AVDictionaryEntry *tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
01671
01672 if (!s->nb_streams)
01673 return -1;
01674
01675 for (i = 0; i < s->nb_streams; i++) {
01676 AVStream *st = s->streams[i];
01677 MXFStreamContext *sc = av_mallocz(sizeof(*sc));
01678 if (!sc)
01679 return AVERROR(ENOMEM);
01680 st->priv_data = sc;
01681
01682 if ((i == 0) ^ (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)) {
01683 av_log(s, AV_LOG_ERROR, "there must be exactly one video stream and it must be the first one\n");
01684 return -1;
01685 }
01686
01687 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
01688 AVRational rate, tbc = st->codec->time_base;
01689
01690 sc->component_depth = 8;
01691 mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num;
01692 spf = ff_mxf_get_samples_per_frame(s, tbc);
01693 if (!spf) {
01694 av_log(s, AV_LOG_ERROR, "Unsupported video frame rate %d/%d\n",
01695 tbc.den, tbc.num);
01696 return AVERROR(EINVAL);
01697 }
01698 mxf->time_base = spf->time_base;
01699 rate = av_inv_q(mxf->time_base);
01700 avpriv_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den);
01701 if (!tcr)
01702 tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
01703 if (tcr)
01704 ret = av_timecode_init_from_string(&mxf->tc, rate, tcr->value, s);
01705 else
01706 ret = av_timecode_init(&mxf->tc, rate, 0, 0, s);
01707 if (ret < 0)
01708 return ret;
01709 if (s->oformat == &ff_mxf_d10_muxer) {
01710 if (st->codec->bit_rate == 50000000) {
01711 if (mxf->time_base.den == 25) sc->index = 3;
01712 else sc->index = 5;
01713 } else if (st->codec->bit_rate == 40000000) {
01714 if (mxf->time_base.den == 25) sc->index = 7;
01715 else sc->index = 9;
01716 } else if (st->codec->bit_rate == 30000000) {
01717 if (mxf->time_base.den == 25) sc->index = 11;
01718 else sc->index = 13;
01719 } else {
01720 av_log(s, AV_LOG_ERROR, "error MXF D-10 only support 30/40/50 mbit/s\n");
01721 return -1;
01722 }
01723
01724 mxf->edit_unit_byte_count = KAG_SIZE;
01725 mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)st->codec->bit_rate *
01726 mxf->time_base.num / (8*mxf->time_base.den);
01727 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
01728 mxf->edit_unit_byte_count += 16 + 4 + 4 + spf->samples_per_frame[0]*8*4;
01729 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
01730 }
01731 } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
01732 if (st->codec->sample_rate != 48000) {
01733 av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n");
01734 return -1;
01735 }
01736 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
01737 if (s->oformat == &ff_mxf_d10_muxer) {
01738 if (st->index != 1) {
01739 av_log(s, AV_LOG_ERROR, "MXF D-10 only support one audio track\n");
01740 return -1;
01741 }
01742 if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE &&
01743 st->codec->codec_id != AV_CODEC_ID_PCM_S24LE) {
01744 av_log(s, AV_LOG_ERROR, "MXF D-10 only support 16 or 24 bits le audio\n");
01745 }
01746 sc->index = ((MXFStreamContext*)s->streams[0]->priv_data)->index + 1;
01747 } else
01748 mxf->slice_count = 1;
01749 }
01750
01751 if (!sc->index) {
01752 sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id);
01753 if (sc->index == -1) {
01754 av_log(s, AV_LOG_ERROR, "track %d: could not find essence container ul, "
01755 "codec not currently supported in container\n", i);
01756 return -1;
01757 }
01758 }
01759
01760 sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;
01761
01762 memcpy(sc->track_essence_element_key, mxf_essence_container_uls[sc->index].element_ul, 15);
01763 sc->track_essence_element_key[15] = present[sc->index];
01764 PRINT_KEY(s, "track essence element key", sc->track_essence_element_key);
01765
01766 if (!present[sc->index])
01767 mxf->essence_container_count++;
01768 present[sc->index]++;
01769 }
01770
01771 if (s->oformat == &ff_mxf_d10_muxer) {
01772 mxf->essence_container_count = 1;
01773 }
01774
01775 if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
01776 mxf_gen_umid(s);
01777
01778 for (i = 0; i < s->nb_streams; i++) {
01779 MXFStreamContext *sc = s->streams[i]->priv_data;
01780
01781 sc->track_essence_element_key[13] = present[sc->index];
01782 if (!memcmp(sc->track_essence_element_key, mxf_essence_container_uls[15].element_ul, 13))
01783 sc->order = (0x15 << 24) | AV_RB32(sc->track_essence_element_key+13);
01784 else
01785 sc->order = AV_RB32(sc->track_essence_element_key+12);
01786 }
01787
01788 if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
01789 timestamp = ff_iso8601_to_unix_time(t->value);
01790 if (timestamp)
01791 mxf->timestamp = mxf_parse_timestamp(timestamp);
01792 mxf->duration = -1;
01793
01794 mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track));
01795 if (!mxf->timecode_track)
01796 return AVERROR(ENOMEM);
01797 mxf->timecode_track->priv_data = av_mallocz(sizeof(MXFStreamContext));
01798 if (!mxf->timecode_track->priv_data)
01799 return AVERROR(ENOMEM);
01800 mxf->timecode_track->index = -1;
01801
01802 if (!spf)
01803 spf = ff_mxf_get_samples_per_frame(s, (AVRational){ 1, 25 });
01804
01805 if (ff_audio_interleave_init(s, spf->samples_per_frame, mxf->time_base) < 0)
01806 return -1;
01807
01808 return 0;
01809 }
01810
01811 static const uint8_t system_metadata_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x01,0x00 };
01812 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 };
01813
01814 static void mxf_write_system_item(AVFormatContext *s)
01815 {
01816 MXFContext *mxf = s->priv_data;
01817 AVIOContext *pb = s->pb;
01818 unsigned frame;
01819 uint32_t time_code;
01820
01821 frame = mxf->last_indexed_edit_unit + mxf->edit_units_count;
01822
01823
01824 avio_write(pb, system_metadata_pack_key, 16);
01825 klv_encode_ber4_length(pb, 57);
01826 avio_w8(pb, 0x5c);
01827 avio_w8(pb, 0x04);
01828 avio_w8(pb, 0x00);
01829 avio_wb16(pb, 0x00);
01830 avio_wb16(pb, (mxf->tc.start + frame) & 0xFFFF);
01831 if (mxf->essence_container_count > 1)
01832 avio_write(pb, multiple_desc_ul, 16);
01833 else {
01834 MXFStreamContext *sc = s->streams[0]->priv_data;
01835 avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
01836 }
01837 avio_w8(pb, 0);
01838 avio_wb64(pb, 0);
01839 avio_wb64(pb, 0);
01840
01841 avio_w8(pb, 0x81);
01842 time_code = av_timecode_get_smpte_from_framenum(&mxf->tc, frame);
01843 avio_wb32(pb, time_code);
01844 avio_wb32(pb, 0);
01845 avio_wb64(pb, 0);
01846
01847
01848 avio_write(pb, system_metadata_package_set_key, 16);
01849 klv_encode_ber4_length(pb, 35);
01850 avio_w8(pb, 0x83);
01851 avio_wb16(pb, 0x20);
01852 mxf_write_umid(s, 1);
01853 }
01854
01855 static void mxf_write_d10_video_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
01856 {
01857 MXFContext *mxf = s->priv_data;
01858 AVIOContext *pb = s->pb;
01859 int packet_size = (uint64_t)st->codec->bit_rate*mxf->time_base.num /
01860 (8*mxf->time_base.den);
01861 int pad;
01862
01863 packet_size += 16 + 4;
01864 packet_size += klv_fill_size(packet_size);
01865
01866 klv_encode_ber4_length(pb, pkt->size);
01867 avio_write(pb, pkt->data, pkt->size);
01868
01869
01870 pad = packet_size - pkt->size - 16 - 4;
01871 if (pad > 20) {
01872 avio_write(s->pb, klv_fill_key, 16);
01873 pad -= 16 + 4;
01874 klv_encode_ber4_length(s->pb, pad);
01875 for (; pad; pad--)
01876 avio_w8(s->pb, 0);
01877 av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1)));
01878 } else {
01879 av_log(s, AV_LOG_WARNING, "cannot fill d-10 video packet\n");
01880 for (; pad > 0; pad--)
01881 avio_w8(s->pb, 0);
01882 }
01883 }
01884
01885 static void mxf_write_d10_audio_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
01886 {
01887 MXFContext *mxf = s->priv_data;
01888 AVIOContext *pb = s->pb;
01889 int frame_size = pkt->size / st->codec->block_align;
01890 uint8_t *samples = pkt->data;
01891 uint8_t *end = pkt->data + pkt->size;
01892 int i;
01893
01894 klv_encode_ber4_length(pb, 4 + frame_size*4*8);
01895
01896 avio_w8(pb, (frame_size == 1920 ? 0 : (mxf->edit_units_count-1) % 5 + 1));
01897 avio_wl16(pb, frame_size);
01898 avio_w8(pb, (1<<st->codec->channels)-1);
01899
01900 while (samples < end) {
01901 for (i = 0; i < st->codec->channels; i++) {
01902 uint32_t sample;
01903 if (st->codec->codec_id == AV_CODEC_ID_PCM_S24LE) {
01904 sample = AV_RL24(samples)<< 4;
01905 samples += 3;
01906 } else {
01907 sample = AV_RL16(samples)<<12;
01908 samples += 2;
01909 }
01910 avio_wl32(pb, sample | i);
01911 }
01912 for (; i < 8; i++)
01913 avio_wl32(pb, i);
01914 }
01915 }
01916
01917 static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt)
01918 {
01919 MXFContext *mxf = s->priv_data;
01920 AVIOContext *pb = s->pb;
01921 AVStream *st = s->streams[pkt->stream_index];
01922 MXFStreamContext *sc = st->priv_data;
01923 MXFIndexEntry ie = {0};
01924
01925 if (!mxf->edit_unit_byte_count && !(mxf->edit_units_count % EDIT_UNITS_PER_BODY)) {
01926 mxf->index_entries = av_realloc(mxf->index_entries,
01927 (mxf->edit_units_count + EDIT_UNITS_PER_BODY)*sizeof(*mxf->index_entries));
01928 if (!mxf->index_entries) {
01929 av_log(s, AV_LOG_ERROR, "could not allocate index entries\n");
01930 return -1;
01931 }
01932 }
01933
01934 if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
01935 if (!mxf_parse_mpeg2_frame(s, st, pkt, &ie)) {
01936 av_log(s, AV_LOG_ERROR, "could not get mpeg2 profile and level\n");
01937 return -1;
01938 }
01939 } else if (st->codec->codec_id == AV_CODEC_ID_DNXHD) {
01940 if (!mxf_parse_dnxhd_frame(s, st, pkt)) {
01941 av_log(s, AV_LOG_ERROR, "could not get dnxhd profile\n");
01942 return -1;
01943 }
01944 } else if (st->codec->codec_id == AV_CODEC_ID_DVVIDEO) {
01945 if (!mxf_parse_dv_frame(s, st, pkt)) {
01946 av_log(s, AV_LOG_ERROR, "could not get dv profile\n");
01947 return -1;
01948 }
01949 }
01950
01951 if (!mxf->header_written) {
01952 if (mxf->edit_unit_byte_count) {
01953 mxf_write_partition(s, 1, 2, header_open_partition_key, 1);
01954 mxf_write_klv_fill(s);
01955 mxf_write_index_table_segment(s);
01956 } else {
01957 mxf_write_partition(s, 0, 0, header_open_partition_key, 1);
01958 }
01959 mxf->header_written = 1;
01960 }
01961
01962 if (st->index == 0) {
01963 if (!mxf->edit_unit_byte_count &&
01964 (!mxf->edit_units_count || mxf->edit_units_count > EDIT_UNITS_PER_BODY) &&
01965 !(ie.flags & 0x33)) {
01966 mxf_write_klv_fill(s);
01967 mxf_write_partition(s, 1, 2, body_partition_key, 0);
01968
01969 mxf_write_klv_fill(s);
01970 mxf_write_index_table_segment(s);
01971 }
01972
01973 mxf_write_klv_fill(s);
01974 mxf_write_system_item(s);
01975
01976 if (!mxf->edit_unit_byte_count) {
01977 mxf->index_entries[mxf->edit_units_count].offset = mxf->body_offset;
01978 mxf->index_entries[mxf->edit_units_count].flags = ie.flags;
01979 mxf->index_entries[mxf->edit_units_count].temporal_ref = ie.temporal_ref;
01980 mxf->body_offset += KAG_SIZE;
01981 }
01982 mxf->edit_units_count++;
01983 } else if (!mxf->edit_unit_byte_count && st->index == 1) {
01984 mxf->index_entries[mxf->edit_units_count-1].slice_offset =
01985 mxf->body_offset - mxf->index_entries[mxf->edit_units_count-1].offset;
01986 }
01987
01988 mxf_write_klv_fill(s);
01989 avio_write(pb, sc->track_essence_element_key, 16);
01990 if (s->oformat == &ff_mxf_d10_muxer) {
01991 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
01992 mxf_write_d10_video_packet(s, st, pkt);
01993 else
01994 mxf_write_d10_audio_packet(s, st, pkt);
01995 } else {
01996 klv_encode_ber4_length(pb, pkt->size);
01997 avio_write(pb, pkt->data, pkt->size);
01998 mxf->body_offset += 16+4+pkt->size + klv_fill_size(16+4+pkt->size);
01999 }
02000
02001 avio_flush(pb);
02002
02003 return 0;
02004 }
02005
02006 static void mxf_write_random_index_pack(AVFormatContext *s)
02007 {
02008 MXFContext *mxf = s->priv_data;
02009 AVIOContext *pb = s->pb;
02010 uint64_t pos = avio_tell(pb);
02011 int i;
02012
02013 avio_write(pb, random_index_pack_key, 16);
02014 klv_encode_ber_length(pb, 28 + 12LL*mxf->body_partitions_count);
02015
02016 if (mxf->edit_unit_byte_count)
02017 avio_wb32(pb, 1);
02018 else
02019 avio_wb32(pb, 0);
02020 avio_wb64(pb, 0);
02021
02022 for (i = 0; i < mxf->body_partitions_count; i++) {
02023 avio_wb32(pb, 1);
02024 avio_wb64(pb, mxf->body_partition_offset[i]);
02025 }
02026
02027 avio_wb32(pb, 0);
02028 avio_wb64(pb, mxf->footer_partition_offset);
02029
02030 avio_wb32(pb, avio_tell(pb) - pos + 4);
02031 }
02032
02033 static int mxf_write_footer(AVFormatContext *s)
02034 {
02035 MXFContext *mxf = s->priv_data;
02036 AVIOContext *pb = s->pb;
02037
02038 mxf->duration = mxf->last_indexed_edit_unit + mxf->edit_units_count;
02039
02040 mxf_write_klv_fill(s);
02041 mxf->footer_partition_offset = avio_tell(pb);
02042 if (mxf->edit_unit_byte_count) {
02043 mxf_write_partition(s, 0, 0, footer_partition_key, 0);
02044 } else {
02045 mxf_write_partition(s, 0, 2, footer_partition_key, 0);
02046
02047 mxf_write_klv_fill(s);
02048 mxf_write_index_table_segment(s);
02049 }
02050
02051 mxf_write_klv_fill(s);
02052 mxf_write_random_index_pack(s);
02053
02054 if (s->pb->seekable) {
02055 avio_seek(pb, 0, SEEK_SET);
02056 if (mxf->edit_unit_byte_count) {
02057 mxf_write_partition(s, 1, 2, header_closed_partition_key, 1);
02058 mxf_write_klv_fill(s);
02059 mxf_write_index_table_segment(s);
02060 } else {
02061 mxf_write_partition(s, 0, 0, header_closed_partition_key, 1);
02062 }
02063 }
02064
02065 ff_audio_interleave_close(s);
02066
02067 av_freep(&mxf->index_entries);
02068 av_freep(&mxf->body_partition_offset);
02069 av_freep(&mxf->timecode_track->priv_data);
02070 av_freep(&mxf->timecode_track);
02071
02072 mxf_free(s);
02073
02074 return 0;
02075 }
02076
02077 static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
02078 {
02079 int i, stream_count = 0;
02080
02081 for (i = 0; i < s->nb_streams; i++)
02082 stream_count += !!s->streams[i]->last_in_packet_buffer;
02083
02084 if (stream_count && (s->nb_streams == stream_count || flush)) {
02085 AVPacketList *pktl = s->packet_buffer;
02086 if (s->nb_streams != stream_count) {
02087 AVPacketList *last = NULL;
02088
02089 while (pktl) {
02090 if (!stream_count || pktl->pkt.stream_index == 0)
02091 break;
02092 last = pktl;
02093 pktl = pktl->next;
02094 stream_count--;
02095 }
02096
02097 while (pktl) {
02098 AVPacketList *next = pktl->next;
02099
02100 if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl)
02101 s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL;
02102 av_free_packet(&pktl->pkt);
02103 av_freep(&pktl);
02104 pktl = next;
02105 }
02106 if (last)
02107 last->next = NULL;
02108 else {
02109 s->packet_buffer = NULL;
02110 s->packet_buffer_end= NULL;
02111 goto out;
02112 }
02113 pktl = s->packet_buffer;
02114 }
02115
02116 *out = pktl->pkt;
02117 av_dlog(s, "out st:%d dts:%"PRId64"\n", (*out).stream_index, (*out).dts);
02118 s->packet_buffer = pktl->next;
02119 if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl)
02120 s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL;
02121 if(!s->packet_buffer)
02122 s->packet_buffer_end= NULL;
02123 av_freep(&pktl);
02124 return 1;
02125 } else {
02126 out:
02127 av_init_packet(out);
02128 return 0;
02129 }
02130 }
02131
02132 static int mxf_compare_timestamps(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
02133 {
02134 MXFStreamContext *sc = s->streams[pkt ->stream_index]->priv_data;
02135 MXFStreamContext *sc2 = s->streams[next->stream_index]->priv_data;
02136
02137 return next->dts > pkt->dts ||
02138 (next->dts == pkt->dts && sc->order < sc2->order);
02139 }
02140
02141 static int mxf_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
02142 {
02143 return ff_audio_rechunk_interleave(s, out, pkt, flush,
02144 mxf_interleave_get_packet, mxf_compare_timestamps);
02145 }
02146
02147 AVOutputFormat ff_mxf_muxer = {
02148 .name = "mxf",
02149 .long_name = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format)"),
02150 .mime_type = "application/mxf",
02151 .extensions = "mxf",
02152 .priv_data_size = sizeof(MXFContext),
02153 .audio_codec = AV_CODEC_ID_PCM_S16LE,
02154 .video_codec = AV_CODEC_ID_MPEG2VIDEO,
02155 .write_header = mxf_write_header,
02156 .write_packet = mxf_write_packet,
02157 .write_trailer = mxf_write_footer,
02158 .flags = AVFMT_NOTIMESTAMPS,
02159 .interleave_packet = mxf_interleave,
02160 };
02161
02162 AVOutputFormat ff_mxf_d10_muxer = {
02163 .name = "mxf_d10",
02164 .long_name = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format) D-10 Mapping"),
02165 .mime_type = "application/mxf",
02166 .priv_data_size = sizeof(MXFContext),
02167 .audio_codec = AV_CODEC_ID_PCM_S16LE,
02168 .video_codec = AV_CODEC_ID_MPEG2VIDEO,
02169 .write_header = mxf_write_header,
02170 .write_packet = mxf_write_packet,
02171 .write_trailer = mxf_write_footer,
02172 .flags = AVFMT_NOTIMESTAMPS,
02173 .interleave_packet = mxf_interleave,
02174 };