mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
lavf/mxfenc: support creating s436m data tracks
This commit is contained in:
parent
bb89109a0a
commit
9b7ab57953
@ -28,6 +28,7 @@
|
|||||||
const MXFCodecUL ff_mxf_data_definition_uls[] = {
|
const MXFCodecUL ff_mxf_data_definition_uls[] = {
|
||||||
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x01,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_VIDEO },
|
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x01,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_VIDEO },
|
||||||
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x02,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_AUDIO },
|
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x02,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_AUDIO },
|
||||||
|
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x03,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_DATA },
|
||||||
{ { 0x80,0x7D,0x00,0x60,0x08,0x14,0x3E,0x6F,0x6F,0x3C,0x8C,0xE1,0x6C,0xEF,0x11,0xD2 }, 16, AVMEDIA_TYPE_VIDEO }, /* LegacyPicture Avid Media Composer MXF */
|
{ { 0x80,0x7D,0x00,0x60,0x08,0x14,0x3E,0x6F,0x6F,0x3C,0x8C,0xE1,0x6C,0xEF,0x11,0xD2 }, 16, AVMEDIA_TYPE_VIDEO }, /* LegacyPicture Avid Media Composer MXF */
|
||||||
{ { 0x80,0x7D,0x00,0x60,0x08,0x14,0x3E,0x6F,0x78,0xE1,0xEB,0xE1,0x6C,0xEF,0x11,0xD2 }, 16, AVMEDIA_TYPE_AUDIO }, /* LegacySound Avid Media Composer MXF */
|
{ { 0x80,0x7D,0x00,0x60,0x08,0x14,0x3E,0x6F,0x78,0xE1,0xEB,0xE1,0x6C,0xEF,0x11,0xD2 }, 16, AVMEDIA_TYPE_AUDIO }, /* LegacySound Avid Media Composer MXF */
|
||||||
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AVMEDIA_TYPE_DATA },
|
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AVMEDIA_TYPE_DATA },
|
||||||
|
@ -3311,6 +3311,8 @@ static int mxf_set_pts(MXFContext *mxf, AVStream *st, AVPacket *pkt)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
} else if (track) {
|
} else if (track) {
|
||||||
|
pkt->dts = pkt->pts = track->sample_count;
|
||||||
|
pkt->duration = 1;
|
||||||
track->sample_count++;
|
track->sample_count++;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -180,6 +180,7 @@ static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st);
|
|||||||
static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st);
|
static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st);
|
||||||
static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st);
|
static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st);
|
||||||
static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st);
|
static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st);
|
||||||
|
static void mxf_write_s436m_anc_desc(AVFormatContext *s, AVStream *st);
|
||||||
|
|
||||||
static const MXFContainerEssenceEntry mxf_essence_container_uls[] = {
|
static const MXFContainerEssenceEntry mxf_essence_container_uls[] = {
|
||||||
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 },
|
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 },
|
||||||
@ -391,6 +392,11 @@ static const MXFContainerEssenceEntry mxf_essence_container_uls[] = {
|
|||||||
{ 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
|
{ 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
|
||||||
{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x00,0x00,0x00 },
|
{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x00,0x00,0x00 },
|
||||||
mxf_write_mpegvideo_desc },
|
mxf_write_mpegvideo_desc },
|
||||||
|
// S436M ANC
|
||||||
|
{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x0D,0x01,0x03,0x01,0x02,0x0e,0x00,0x00 },
|
||||||
|
{ 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x17,0x01,0x02,0x00 },
|
||||||
|
{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x01,0x5C,0x00 },
|
||||||
|
mxf_write_s436m_anc_desc },
|
||||||
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
||||||
@ -725,9 +731,14 @@ static void mxf_write_essence_container_refs(AVFormatContext *s)
|
|||||||
|
|
||||||
mxf_write_refs_count(pb, DESCRIPTOR_COUNT(c->essence_container_count));
|
mxf_write_refs_count(pb, DESCRIPTOR_COUNT(c->essence_container_count));
|
||||||
av_log(s,AV_LOG_DEBUG, "essence container count:%d\n", c->essence_container_count);
|
av_log(s,AV_LOG_DEBUG, "essence container count:%d\n", c->essence_container_count);
|
||||||
for (i = 0; i < c->essence_container_count; i++) {
|
for (i = 0; i < s->nb_streams; i++) {
|
||||||
MXFStreamContext *sc = s->streams[i]->priv_data;
|
MXFStreamContext *sc = s->streams[i]->priv_data;
|
||||||
|
// check first track of essence container type and only write it once
|
||||||
|
if (sc->track_essence_element_key[15] != 0)
|
||||||
|
continue;
|
||||||
avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
|
avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
|
||||||
|
if (c->essence_container_count == 1)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->essence_container_count > 1)
|
if (c->essence_container_count > 1)
|
||||||
@ -1184,6 +1195,7 @@ static int64_t mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UI
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const UID mxf_s436m_anc_descriptor_key = { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5c,0x00 };
|
||||||
static const UID mxf_mpegvideo_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 };
|
static const UID mxf_mpegvideo_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 };
|
||||||
static const UID mxf_wav_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 };
|
static const UID mxf_wav_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 };
|
||||||
static const UID mxf_aes3_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 };
|
static const UID mxf_aes3_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 };
|
||||||
@ -1399,6 +1411,12 @@ static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st)
|
|||||||
mxf_update_klv_size(s->pb, pos);
|
mxf_update_klv_size(s->pb, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mxf_write_s436m_anc_desc(AVFormatContext *s, AVStream *st)
|
||||||
|
{
|
||||||
|
int64_t pos = mxf_write_generic_desc(s, st, mxf_s436m_anc_descriptor_key);
|
||||||
|
mxf_update_klv_size(s->pb, pos);
|
||||||
|
}
|
||||||
|
|
||||||
static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st)
|
static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st)
|
||||||
{
|
{
|
||||||
AVIOContext *pb = s->pb;
|
AVIOContext *pb = s->pb;
|
||||||
@ -1753,6 +1771,7 @@ static void mxf_write_index_table_segment(AVFormatContext *s)
|
|||||||
int i, j, temporal_reordering = 0;
|
int i, j, temporal_reordering = 0;
|
||||||
int key_index = mxf->last_key_index;
|
int key_index = mxf->last_key_index;
|
||||||
int prev_non_b_picture = 0;
|
int prev_non_b_picture = 0;
|
||||||
|
int audio_frame_size = 0;
|
||||||
int64_t pos;
|
int64_t pos;
|
||||||
|
|
||||||
av_log(s, AV_LOG_DEBUG, "edit units count %d\n", mxf->edit_units_count);
|
av_log(s, AV_LOG_DEBUG, "edit units count %d\n", mxf->edit_units_count);
|
||||||
@ -1822,9 +1841,11 @@ static void mxf_write_index_table_segment(AVFormatContext *s)
|
|||||||
} else if (i == 0) { // video track
|
} else if (i == 0) { // video track
|
||||||
avio_w8(pb, 0); // slice number
|
avio_w8(pb, 0); // slice number
|
||||||
avio_wb32(pb, KAG_SIZE); // system item size including klv fill
|
avio_wb32(pb, KAG_SIZE); // system item size including klv fill
|
||||||
} else { // audio track
|
} else { // audio or data track
|
||||||
unsigned audio_frame_size = sc->aic.samples[0]*sc->aic.sample_size;
|
if (!audio_frame_size) {
|
||||||
audio_frame_size += klv_fill_size(audio_frame_size);
|
audio_frame_size = sc->aic.samples[0]*sc->aic.sample_size;
|
||||||
|
audio_frame_size += klv_fill_size(audio_frame_size);
|
||||||
|
}
|
||||||
avio_w8(pb, 1);
|
avio_w8(pb, 1);
|
||||||
avio_wb32(pb, (i-1)*audio_frame_size); // element delta
|
avio_wb32(pb, (i-1)*audio_frame_size); // element delta
|
||||||
}
|
}
|
||||||
@ -2556,6 +2577,18 @@ static int mxf_write_header(AVFormatContext *s)
|
|||||||
sc->frame_size = (st->codecpar->channels * spf[0].samples_per_frame[0] *
|
sc->frame_size = (st->codecpar->channels * spf[0].samples_per_frame[0] *
|
||||||
av_get_bits_per_sample(st->codecpar->codec_id)) / 8;
|
av_get_bits_per_sample(st->codecpar->codec_id)) / 8;
|
||||||
}
|
}
|
||||||
|
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
|
||||||
|
AVDictionaryEntry *e = av_dict_get(st->metadata, "data_type", NULL, 0);
|
||||||
|
if (e && !strcmp(e->value, "vbi_vanc_smpte_436M")) {
|
||||||
|
sc->index = 38;
|
||||||
|
} else {
|
||||||
|
av_log(s, AV_LOG_ERROR, "track %d: unsupported data type\n", i);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (st->index != s->nb_streams - 1) {
|
||||||
|
av_log(s, AV_LOG_ERROR, "data track must be placed last\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sc->index) {
|
if (!sc->index) {
|
||||||
@ -2625,13 +2658,21 @@ static void mxf_write_system_item(AVFormatContext *s)
|
|||||||
AVIOContext *pb = s->pb;
|
AVIOContext *pb = s->pb;
|
||||||
unsigned frame;
|
unsigned frame;
|
||||||
uint32_t time_code;
|
uint32_t time_code;
|
||||||
|
int i, system_item_bitmap = 0x58; // UL, user date/time stamp, picture present
|
||||||
|
|
||||||
frame = mxf->last_indexed_edit_unit + mxf->edit_units_count;
|
frame = mxf->last_indexed_edit_unit + mxf->edit_units_count;
|
||||||
|
|
||||||
// write system metadata pack
|
// write system metadata pack
|
||||||
avio_write(pb, system_metadata_pack_key, 16);
|
avio_write(pb, system_metadata_pack_key, 16);
|
||||||
klv_encode_ber4_length(pb, 57);
|
klv_encode_ber4_length(pb, 57);
|
||||||
avio_w8(pb, 0x5c); // UL, user date/time stamp, picture and sound item present
|
|
||||||
|
for (i = 0; i < s->nb_streams; i++) {
|
||||||
|
if (s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
|
||||||
|
system_item_bitmap |= 0x4;
|
||||||
|
else if (s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_DATA)
|
||||||
|
system_item_bitmap |= 0x2;
|
||||||
|
}
|
||||||
|
avio_w8(pb, system_item_bitmap);
|
||||||
avio_w8(pb, mxf->content_package_rate); // content package rate
|
avio_w8(pb, mxf->content_package_rate); // content package rate
|
||||||
avio_w8(pb, 0x00); // content package type
|
avio_w8(pb, 0x00); // content package type
|
||||||
avio_wb16(pb, 0x00); // channel handle
|
avio_wb16(pb, 0x00); // channel handle
|
||||||
|
Loading…
Reference in New Issue
Block a user