annotate ffmpeg/libavformat/mxfenc.c @ 13:844d341cf643 tip

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