...
|
...
|
@@ -44,6 +44,8 @@
|
44
|
44
|
static const int NTSC_samples_per_frame[] = { 1602, 1601, 1602, 1601, 1602, 0 };
|
45
|
45
|
static const int PAL_samples_per_frame[] = { 1920, 0 };
|
46
|
46
|
|
|
47
|
+AVOutputFormat mxf_d10_muxer;
|
|
48
|
+
|
47
|
49
|
#define EDIT_UNITS_PER_BODY 250
|
48
|
50
|
#define KAG_SIZE 512
|
49
|
51
|
|
...
|
...
|
@@ -88,6 +90,8 @@ static const struct {
|
88
|
88
|
static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st);
|
89
|
89
|
static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st);
|
90
|
90
|
static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st);
|
|
91
|
+static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st);
|
|
92
|
+static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st);
|
91
|
93
|
|
92
|
94
|
static const MXFContainerEssenceEntry mxf_essence_container_uls[] = {
|
93
|
95
|
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 },
|
...
|
...
|
@@ -102,6 +106,60 @@ static const MXFContainerEssenceEntry mxf_essence_container_uls[] = {
|
102
|
102
|
{ 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x01,0x00 },
|
103
|
103
|
{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
104
|
104
|
mxf_write_wav_desc },
|
|
105
|
+ // D-10 625/50 PAL 50mb/s
|
|
106
|
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 },
|
|
107
|
+ { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
|
|
108
|
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 },
|
|
109
|
+ mxf_write_cdci_desc },
|
|
110
|
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 },
|
|
111
|
+ { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
|
|
112
|
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
|
113
|
+ mxf_write_generic_sound_desc },
|
|
114
|
+ // D-10 525/60 NTSC 50mb/s
|
|
115
|
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 },
|
|
116
|
+ { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
|
|
117
|
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x02 },
|
|
118
|
+ mxf_write_cdci_desc },
|
|
119
|
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 },
|
|
120
|
+ { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
|
|
121
|
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
|
122
|
+ mxf_write_generic_sound_desc },
|
|
123
|
+ // D-10 625/50 PAL 40mb/s
|
|
124
|
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 },
|
|
125
|
+ { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
|
|
126
|
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x03 },
|
|
127
|
+ mxf_write_cdci_desc },
|
|
128
|
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 },
|
|
129
|
+ { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
|
|
130
|
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
|
131
|
+ mxf_write_generic_sound_desc },
|
|
132
|
+ // D-10 525/60 NTSC 40mb/s
|
|
133
|
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 },
|
|
134
|
+ { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
|
|
135
|
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x04 },
|
|
136
|
+ mxf_write_cdci_desc },
|
|
137
|
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 },
|
|
138
|
+ { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
|
|
139
|
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
|
140
|
+ mxf_write_generic_sound_desc },
|
|
141
|
+ // D-10 625/50 PAL 30mb/s
|
|
142
|
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 },
|
|
143
|
+ { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
|
|
144
|
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x05 },
|
|
145
|
+ mxf_write_cdci_desc },
|
|
146
|
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 },
|
|
147
|
+ { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
|
|
148
|
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
|
149
|
+ mxf_write_generic_sound_desc },
|
|
150
|
+ // D-10 525/60 NTSC 30mb/s
|
|
151
|
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 },
|
|
152
|
+ { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
|
|
153
|
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x06 },
|
|
154
|
+ mxf_write_cdci_desc },
|
|
155
|
+ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 },
|
|
156
|
+ { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
|
|
157
|
+ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
|
|
158
|
+ mxf_write_generic_sound_desc },
|
105
|
159
|
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
106
|
160
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
107
|
161
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
...
|
...
|
@@ -128,6 +186,7 @@ typedef struct MXFContext {
|
128
|
128
|
int timecode_base; ///< rounded time code base (25 or 30)
|
129
|
129
|
int timecode_start; ///< frame number computed from mpeg-2 gop header timecode
|
130
|
130
|
int timecode_drop_frame; ///< time code use drop frame method frop mpeg-2 essence gop header
|
|
131
|
+ int edit_unit_byte_count; ///< fixed edit unit byte count
|
131
|
132
|
} MXFContext;
|
132
|
133
|
|
133
|
134
|
static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd };
|
...
|
...
|
@@ -652,6 +711,7 @@ static void mxf_write_multi_descriptor(AVFormatContext *s)
|
652
|
652
|
{
|
653
|
653
|
MXFContext *mxf = s->priv_data;
|
654
|
654
|
ByteIOContext *pb = s->pb;
|
|
655
|
+ const uint8_t *ul;
|
655
|
656
|
int i;
|
656
|
657
|
|
657
|
658
|
mxf_write_metadata_key(pb, 0x014400);
|
...
|
...
|
@@ -669,7 +729,11 @@ static void mxf_write_multi_descriptor(AVFormatContext *s)
|
669
|
669
|
|
670
|
670
|
// write essence container ul
|
671
|
671
|
mxf_write_local_tag(pb, 16, 0x3004);
|
672
|
|
- put_buffer(pb, multiple_desc_ul, 16);
|
|
672
|
+ if (mxf->essence_container_count > 1)
|
|
673
|
+ ul = multiple_desc_ul;
|
|
674
|
+ else
|
|
675
|
+ ul = mxf_essence_container_uls[mxf->essence_containers_indices[0]].container_ul;
|
|
676
|
+ put_buffer(pb, ul, 16);
|
673
|
677
|
|
674
|
678
|
// write sub descriptor refs
|
675
|
679
|
mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01);
|
...
|
...
|
@@ -704,6 +768,8 @@ static void mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UID k
|
704
|
704
|
static const UID mxf_mpegvideo_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 };
|
705
|
705
|
static const UID mxf_wav_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 };
|
706
|
706
|
static const UID mxf_aes3_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 };
|
|
707
|
+static const UID mxf_cdci_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x28,0x00 };
|
|
708
|
+static const UID mxf_generic_sound_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x42,0x00 };
|
707
|
709
|
|
708
|
710
|
static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
|
709
|
711
|
{
|
...
|
...
|
@@ -783,6 +849,12 @@ static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID ke
|
783
|
783
|
put_buffer(pb, *sc->codec_ul, 16);
|
784
|
784
|
}
|
785
|
785
|
|
|
786
|
+static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st)
|
|
787
|
+{
|
|
788
|
+ MXFStreamContext *sc = st->priv_data;
|
|
789
|
+ mxf_write_cdci_common(s, st, mxf_cdci_descriptor_key, 161+sc->interlaced*4);
|
|
790
|
+}
|
|
791
|
+
|
786
|
792
|
static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st)
|
787
|
793
|
{
|
788
|
794
|
MXFStreamContext *sc = st->priv_data;
|
...
|
...
|
@@ -841,6 +913,11 @@ static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st)
|
841
|
841
|
mxf_write_wav_common(s, st, mxf_aes3_descriptor_key, 107);
|
842
|
842
|
}
|
843
|
843
|
|
|
844
|
+static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st)
|
|
845
|
+{
|
|
846
|
+ mxf_write_generic_sound_common(s, st, mxf_generic_sound_descriptor_key, 93);
|
|
847
|
+}
|
|
848
|
+
|
844
|
849
|
static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type)
|
845
|
850
|
{
|
846
|
851
|
MXFContext *mxf = s->priv_data;
|
...
|
...
|
@@ -966,12 +1043,17 @@ static void mxf_write_index_table_segment(AVFormatContext *s)
|
966
|
966
|
|
967
|
967
|
av_log(s, AV_LOG_DEBUG, "edit units count %d\n", mxf->edit_units_count);
|
968
|
968
|
|
969
|
|
- if (!mxf->edit_units_count)
|
|
969
|
+ if (!mxf->edit_units_count && !mxf->edit_unit_byte_count)
|
970
|
970
|
return;
|
971
|
971
|
|
972
|
972
|
put_buffer(pb, index_table_segment_key, 16);
|
973
|
|
- klv_encode_ber_length(pb, 109 + (s->nb_streams+1)*6 +
|
974
|
|
- mxf->edit_units_count*(11+mxf->slice_count*4));
|
|
973
|
+
|
|
974
|
+ if (mxf->edit_unit_byte_count) {
|
|
975
|
+ klv_encode_ber_length(pb, 85);
|
|
976
|
+ } else {
|
|
977
|
+ klv_encode_ber_length(pb, 85 + 12+(s->nb_streams+1)*6 +
|
|
978
|
+ 12+mxf->edit_units_count*(11+mxf->slice_count*4));
|
|
979
|
+ }
|
975
|
980
|
|
976
|
981
|
// instance id
|
977
|
982
|
mxf_write_local_tag(pb, 16, 0x3C0A);
|
...
|
...
|
@@ -992,7 +1074,7 @@ static void mxf_write_index_table_segment(AVFormatContext *s)
|
992
|
992
|
|
993
|
993
|
// edit unit byte count
|
994
|
994
|
mxf_write_local_tag(pb, 4, 0x3F05);
|
995
|
|
- put_be32(pb, 0);
|
|
995
|
+ put_be32(pb, mxf->edit_unit_byte_count);
|
996
|
996
|
|
997
|
997
|
// index sid
|
998
|
998
|
mxf_write_local_tag(pb, 4, 0x3F06);
|
...
|
...
|
@@ -1006,6 +1088,7 @@ static void mxf_write_index_table_segment(AVFormatContext *s)
|
1006
|
1006
|
mxf_write_local_tag(pb, 1, 0x3F08);
|
1007
|
1007
|
put_byte(pb, mxf->slice_count);
|
1008
|
1008
|
|
|
1009
|
+ if (!mxf->edit_unit_byte_count) {
|
1009
|
1010
|
// delta entry array
|
1010
|
1011
|
mxf_write_local_tag(pb, 8 + (s->nb_streams+1)*6, 0x3F09);
|
1011
|
1012
|
put_be32(pb, s->nb_streams+1); // num of entries
|
...
|
...
|
@@ -1076,6 +1159,7 @@ static void mxf_write_index_table_segment(AVFormatContext *s)
|
1076
|
1076
|
mxf->last_key_index = key_index - mxf->edit_units_count;
|
1077
|
1077
|
mxf->last_indexed_edit_unit += mxf->edit_units_count;
|
1078
|
1078
|
mxf->edit_units_count = 0;
|
|
1079
|
+ }
|
1079
|
1080
|
}
|
1080
|
1081
|
|
1081
|
1082
|
static void mxf_write_klv_fill(AVFormatContext *s)
|
...
|
...
|
@@ -1101,9 +1185,13 @@ static void mxf_write_partition(AVFormatContext *s, int bodysid,
|
1101
|
1101
|
unsigned index_byte_count = 0;
|
1102
|
1102
|
uint64_t partition_offset = url_ftell(pb);
|
1103
|
1103
|
|
1104
|
|
- if (mxf->edit_units_count) {
|
1105
|
|
- index_byte_count = 109 + (s->nb_streams+1)*6 +
|
1106
|
|
- mxf->edit_units_count*(11+mxf->slice_count*4);
|
|
1104
|
+ if (!mxf->edit_unit_byte_count && mxf->edit_units_count)
|
|
1105
|
+ index_byte_count = 85 + 12+(s->nb_streams+1)*6 +
|
|
1106
|
+ 12+mxf->edit_units_count*(11+mxf->slice_count*4);
|
|
1107
|
+ else if (mxf->edit_unit_byte_count && indexsid)
|
|
1108
|
+ index_byte_count = 85;
|
|
1109
|
+
|
|
1110
|
+ if (index_byte_count) {
|
1107
|
1111
|
// add encoded ber length
|
1108
|
1112
|
index_byte_count += 16 + klv_ber_length(index_byte_count);
|
1109
|
1113
|
index_byte_count += klv_fill_size(index_byte_count);
|
...
|
...
|
@@ -1147,7 +1235,7 @@ static void mxf_write_partition(AVFormatContext *s, int bodysid,
|
1147
|
1147
|
put_be32(pb, index_byte_count ? indexsid : 0); // indexSID
|
1148
|
1148
|
|
1149
|
1149
|
// BodyOffset
|
1150
|
|
- if (bodysid && mxf->edit_units_count) {
|
|
1150
|
+ if (bodysid && mxf->edit_units_count && mxf->body_partitions_count) {
|
1151
|
1151
|
uint64_t partition_end = url_ftell(pb) + 8 + 4 + 16 + 8 +
|
1152
|
1152
|
16*mxf->essence_container_count;
|
1153
|
1153
|
put_be64(pb, partition_end + klv_fill_size(partition_end) +
|
...
|
...
|
@@ -1279,7 +1367,8 @@ static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt
|
1279
|
1279
|
}
|
1280
|
1280
|
}
|
1281
|
1281
|
}
|
1282
|
|
- sc->codec_ul = mxf_get_mpeg2_codec_ul(st->codec);
|
|
1282
|
+ if (s->oformat != &mxf_d10_muxer)
|
|
1283
|
+ sc->codec_ul = mxf_get_mpeg2_codec_ul(st->codec);
|
1283
|
1284
|
return !!sc->codec_ul;
|
1284
|
1285
|
}
|
1285
|
1286
|
|
...
|
...
|
@@ -1326,21 +1415,56 @@ static int mxf_write_header(AVFormatContext *s)
|
1326
|
1326
|
return -1;
|
1327
|
1327
|
}
|
1328
|
1328
|
av_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den);
|
|
1329
|
+ if (s->oformat == &mxf_d10_muxer) {
|
|
1330
|
+ if (st->codec->bit_rate == 50000000)
|
|
1331
|
+ if (mxf->time_base.den == 25) sc->index = 3;
|
|
1332
|
+ else sc->index = 5;
|
|
1333
|
+ else if (st->codec->bit_rate == 40000000)
|
|
1334
|
+ if (mxf->time_base.den == 25) sc->index = 7;
|
|
1335
|
+ else sc->index = 9;
|
|
1336
|
+ else if (st->codec->bit_rate == 30000000)
|
|
1337
|
+ if (mxf->time_base.den == 25) sc->index = 11;
|
|
1338
|
+ else sc->index = 13;
|
|
1339
|
+ else {
|
|
1340
|
+ av_log(s, AV_LOG_ERROR, "error MXF D-10 only support 30/40/50 mbit/s\n");
|
|
1341
|
+ return -1;
|
|
1342
|
+ }
|
|
1343
|
+
|
|
1344
|
+ mxf->edit_unit_byte_count = KAG_SIZE; // system element
|
|
1345
|
+ mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)st->codec->bit_rate *
|
|
1346
|
+ mxf->time_base.num / (8*mxf->time_base.den);
|
|
1347
|
+ mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
|
|
1348
|
+ mxf->edit_unit_byte_count += 16 + 4 + 4 + samples_per_frame[0]*8*4;
|
|
1349
|
+ mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
|
|
1350
|
+ }
|
1329
|
1351
|
} else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
|
1330
|
1352
|
if (st->codec->sample_rate != 48000) {
|
1331
|
1353
|
av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n");
|
1332
|
1354
|
return -1;
|
1333
|
1355
|
}
|
1334
|
1356
|
av_set_pts_info(st, 64, 1, st->codec->sample_rate);
|
|
1357
|
+ if (s->oformat == &mxf_d10_muxer) {
|
|
1358
|
+ if (st->index != 1) {
|
|
1359
|
+ av_log(s, AV_LOG_ERROR, "MXF D-10 only support one audio track\n");
|
|
1360
|
+ return -1;
|
|
1361
|
+ }
|
|
1362
|
+ if (st->codec->codec_id != CODEC_ID_PCM_S16LE &&
|
|
1363
|
+ st->codec->codec_id != CODEC_ID_PCM_S24LE) {
|
|
1364
|
+ av_log(s, AV_LOG_ERROR, "MXF D-10 only support 16 or 24 bits le audio\n");
|
|
1365
|
+ }
|
|
1366
|
+ sc->index = ((MXFStreamContext*)s->streams[0]->priv_data)->index + 1;
|
|
1367
|
+ } else
|
1335
|
1368
|
mxf->slice_count = 1;
|
1336
|
1369
|
}
|
1337
|
1370
|
|
|
1371
|
+ if (!sc->index) {
|
1338
|
1372
|
sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id);
|
1339
|
1373
|
if (sc->index == -1) {
|
1340
|
1374
|
av_log(s, AV_LOG_ERROR, "track %d: could not find essence container ul, "
|
1341
|
1375
|
"codec not currently supported in container\n", i);
|
1342
|
1376
|
return -1;
|
1343
|
1377
|
}
|
|
1378
|
+ }
|
1344
|
1379
|
|
1345
|
1380
|
sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;
|
1346
|
1381
|
|
...
|
...
|
@@ -1354,6 +1478,10 @@ static int mxf_write_header(AVFormatContext *s)
|
1354
|
1354
|
PRINT_KEY(s, "track essence element key", sc->track_essence_element_key);
|
1355
|
1355
|
}
|
1356
|
1356
|
|
|
1357
|
+ if (s->oformat == &mxf_d10_muxer) {
|
|
1358
|
+ mxf->essence_container_count = 1;
|
|
1359
|
+ }
|
|
1360
|
+
|
1357
|
1361
|
for (i = 0; i < s->nb_streams; i++) {
|
1358
|
1362
|
MXFStreamContext *sc = s->streams[i]->priv_data;
|
1359
|
1363
|
// update element count
|
...
|
...
|
@@ -1441,6 +1569,110 @@ static void mxf_write_system_item(AVFormatContext *s)
|
1441
|
1441
|
mxf_write_umid(pb, SourcePackage, 0);
|
1442
|
1442
|
}
|
1443
|
1443
|
|
|
1444
|
+static void mxf_write_d10_video_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
|
|
1445
|
+{
|
|
1446
|
+ MXFContext *mxf = s->priv_data;
|
|
1447
|
+ ByteIOContext *pb = s->pb;
|
|
1448
|
+ int packet_size = (uint64_t)st->codec->bit_rate*mxf->time_base.num /
|
|
1449
|
+ (8*mxf->time_base.den); // frame size
|
|
1450
|
+ int pad;
|
|
1451
|
+
|
|
1452
|
+ packet_size += 16 + 4;
|
|
1453
|
+ packet_size += klv_fill_size(packet_size);
|
|
1454
|
+
|
|
1455
|
+ klv_encode_ber4_length(pb, pkt->size);
|
|
1456
|
+ put_buffer(pb, pkt->data, pkt->size);
|
|
1457
|
+
|
|
1458
|
+ // ensure CBR muxing by padding to correct video frame size
|
|
1459
|
+ pad = packet_size - pkt->size - 16 - 4;
|
|
1460
|
+ if (pad > 20) {
|
|
1461
|
+ put_buffer(s->pb, klv_fill_key, 16);
|
|
1462
|
+ pad -= 16 + 4;
|
|
1463
|
+ klv_encode_ber4_length(s->pb, pad);
|
|
1464
|
+ for (; pad; pad--)
|
|
1465
|
+ put_byte(s->pb, 0);
|
|
1466
|
+ assert(!(url_ftell(s->pb) & (KAG_SIZE-1)));
|
|
1467
|
+ } else {
|
|
1468
|
+ av_log(s, AV_LOG_WARNING, "cannot fill d-10 video packet\n");
|
|
1469
|
+ for (; pad > 0; pad--)
|
|
1470
|
+ put_byte(s->pb, 0);
|
|
1471
|
+ }
|
|
1472
|
+}
|
|
1473
|
+
|
|
1474
|
+static void mxf_write_d10_audio_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
|
|
1475
|
+{
|
|
1476
|
+ MXFContext *mxf = s->priv_data;
|
|
1477
|
+ ByteIOContext *pb = s->pb;
|
|
1478
|
+ int frame_size = (pkt->size<<3) /
|
|
1479
|
+ (st->codec->channels*av_get_bits_per_sample(st->codec->codec_id));
|
|
1480
|
+ uint8_t *samples = pkt->data;
|
|
1481
|
+ uint8_t *end = pkt->data + pkt->size;
|
|
1482
|
+ int i;
|
|
1483
|
+
|
|
1484
|
+ klv_encode_ber4_length(pb, 4 + frame_size*4*8);
|
|
1485
|
+
|
|
1486
|
+ put_byte(pb, (frame_size == 1920 ? 0 : (mxf->edit_units_count-1) % 5 + 1));
|
|
1487
|
+ put_le16(pb, frame_size);
|
|
1488
|
+ put_byte(pb, (1<<st->codec->channels)-1);
|
|
1489
|
+
|
|
1490
|
+ while (samples < end) {
|
|
1491
|
+ for (i = 0; i < st->codec->channels; i++) {
|
|
1492
|
+ uint32_t sample;
|
|
1493
|
+ if (st->codec->codec_id == CODEC_ID_PCM_S24LE) {
|
|
1494
|
+ sample = (AV_RL24(samples)<< 4)|((samples==pkt->data)<<3) | i;
|
|
1495
|
+ samples += 3;
|
|
1496
|
+ } else {
|
|
1497
|
+ sample = (AV_RL16(samples)<<12)|((samples==pkt->data)<<3) | i;
|
|
1498
|
+ samples += 2;
|
|
1499
|
+ }
|
|
1500
|
+ put_le32(pb, sample);
|
|
1501
|
+ }
|
|
1502
|
+ for (; i < 8; i++)
|
|
1503
|
+ put_le32(pb, 0);
|
|
1504
|
+ }
|
|
1505
|
+}
|
|
1506
|
+
|
|
1507
|
+static int mxf_write_d10_packet(AVFormatContext *s, AVPacket *pkt)
|
|
1508
|
+{
|
|
1509
|
+ MXFContext *mxf = s->priv_data;
|
|
1510
|
+ ByteIOContext *pb = s->pb;
|
|
1511
|
+ AVStream *st = s->streams[pkt->stream_index];
|
|
1512
|
+ MXFStreamContext *sc = st->priv_data;
|
|
1513
|
+ int flags = 0;
|
|
1514
|
+
|
|
1515
|
+ if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO) {
|
|
1516
|
+ if (!mxf_parse_mpeg2_frame(s, st, pkt, &flags)) {
|
|
1517
|
+ av_log(s, AV_LOG_ERROR, "could not get mpeg2 profile and level\n");
|
|
1518
|
+ return -1;
|
|
1519
|
+ }
|
|
1520
|
+ }
|
|
1521
|
+
|
|
1522
|
+ if (!mxf->header_written) {
|
|
1523
|
+ mxf_write_partition(s, 1, 2, header_open_partition_key, 1);
|
|
1524
|
+ mxf->header_written = 1;
|
|
1525
|
+ mxf_write_klv_fill(s);
|
|
1526
|
+ mxf_write_index_table_segment(s);
|
|
1527
|
+ }
|
|
1528
|
+
|
|
1529
|
+ if (st->index == 0) {
|
|
1530
|
+ mxf_write_klv_fill(s);
|
|
1531
|
+ mxf_write_system_item(s);
|
|
1532
|
+
|
|
1533
|
+ mxf->edit_units_count++;
|
|
1534
|
+ }
|
|
1535
|
+
|
|
1536
|
+ mxf_write_klv_fill(s);
|
|
1537
|
+ put_buffer(pb, sc->track_essence_element_key, 16); // write key
|
|
1538
|
+ if (st->codec->codec_type == CODEC_TYPE_VIDEO)
|
|
1539
|
+ mxf_write_d10_video_packet(s, st, pkt);
|
|
1540
|
+ else
|
|
1541
|
+ mxf_write_d10_audio_packet(s, st, pkt);
|
|
1542
|
+
|
|
1543
|
+ put_flush_packet(pb);
|
|
1544
|
+
|
|
1545
|
+ return 0;
|
|
1546
|
+}
|
|
1547
|
+
|
1444
|
1548
|
static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt)
|
1445
|
1549
|
{
|
1446
|
1550
|
MXFContext *mxf = s->priv_data;
|
...
|
...
|
@@ -1535,17 +1767,35 @@ static int mxf_write_footer(AVFormatContext *s)
|
1535
|
1535
|
|
1536
|
1536
|
mxf_write_klv_fill(s);
|
1537
|
1537
|
mxf->footer_partition_offset = url_ftell(pb);
|
|
1538
|
+ if (mxf->edit_unit_byte_count) { // no need to repeat index
|
|
1539
|
+ mxf_write_partition(s, 0, 0, footer_partition_key, 0);
|
|
1540
|
+ } else {
|
1538
|
1541
|
mxf_write_partition(s, 0, 2, footer_partition_key, 0);
|
1539
|
1542
|
|
1540
|
1543
|
mxf_write_klv_fill(s);
|
1541
|
1544
|
mxf_write_index_table_segment(s);
|
|
1545
|
+ }
|
1542
|
1546
|
|
1543
|
1547
|
mxf_write_klv_fill(s);
|
1544
|
1548
|
mxf_write_random_index_pack(s);
|
1545
|
1549
|
|
1546
|
1550
|
if (!url_is_streamed(s->pb)) {
|
|
1551
|
+ int index;
|
1547
|
1552
|
url_fseek(pb, 0, SEEK_SET);
|
1548
|
|
- mxf_write_partition(s, 0, 0, header_closed_partition_key, 1);
|
|
1553
|
+ if (s->oformat == &mxf_d10_muxer) {
|
|
1554
|
+ mxf_write_partition(s, 1, 2, header_closed_partition_key, 1);
|
|
1555
|
+ index = 1;
|
|
1556
|
+ } else if (mxf->edit_unit_byte_count) {
|
|
1557
|
+ mxf_write_partition(s, 0, 2, header_closed_partition_key, 1);
|
|
1558
|
+ index = 1;
|
|
1559
|
+ } else {
|
|
1560
|
+ mxf_write_partition(s, 0, 0, header_closed_partition_key, 1);
|
|
1561
|
+ index = 0;
|
|
1562
|
+ }
|
|
1563
|
+ if (index) {
|
|
1564
|
+ mxf_write_klv_fill(s);
|
|
1565
|
+ mxf_write_index_table_segment(s);
|
|
1566
|
+ }
|
1549
|
1567
|
}
|
1550
|
1568
|
|
1551
|
1569
|
ff_audio_interleave_close(s);
|
...
|
...
|
@@ -1646,3 +1896,19 @@ AVOutputFormat mxf_muxer = {
|
1646
|
1646
|
NULL,
|
1647
|
1647
|
mxf_interleave,
|
1648
|
1648
|
};
|
|
1649
|
+
|
|
1650
|
+AVOutputFormat mxf_d10_muxer = {
|
|
1651
|
+ "mxf_d10",
|
|
1652
|
+ NULL_IF_CONFIG_SMALL("Material eXchange Format, D-10 Mapping"),
|
|
1653
|
+ "application/mxf",
|
|
1654
|
+ NULL,
|
|
1655
|
+ sizeof(MXFContext),
|
|
1656
|
+ CODEC_ID_PCM_S16LE,
|
|
1657
|
+ CODEC_ID_MPEG2VIDEO,
|
|
1658
|
+ mxf_write_header,
|
|
1659
|
+ mxf_write_d10_packet,
|
|
1660
|
+ mxf_write_footer,
|
|
1661
|
+ AVFMT_NOTIMESTAMPS,
|
|
1662
|
+ NULL,
|
|
1663
|
+ mxf_interleave,
|
|
1664
|
+};
|