From d526105f084458ed11c9a2f79b61ad9e2bb2c0a8 Mon Sep 17 00:00:00 2001 From: Baptiste Coudurier Date: Sun, 8 Feb 2009 03:29:49 +0000 Subject: [PATCH] only use 2 slices for index, one video(vbr) and one audio(cbr) Originally committed as revision 17035 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavformat/mxfenc.c | 50 ++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 85a77c4b12..65f18bc395 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -62,7 +62,7 @@ typedef struct { typedef struct { uint8_t flags; uint64_t offset; - unsigned slice_offset[17]; // one video, 16 audio + unsigned slice_offset; // offset of audio slice } MXFIndexEntry; typedef struct { @@ -125,6 +125,7 @@ typedef struct MXFContext { MXFIndexEntry *index_entries; unsigned edit_units_count; uint64_t timestamp; ///< timestamp, as year(16),month(8),day(8),hour(8),minutes(8),msec/4(8) + uint8_t slice_count; /// index slice count minus 1 (1 if no audio, 0 otherwise) } MXFContext; static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd }; @@ -849,9 +850,9 @@ static int mxf_write_header_metadata_sets(AVFormatContext *s) return 0; } -static unsigned klv_fill_size(AVFormatContext *s) +static unsigned klv_fill_size(uint64_t size) { - unsigned pad = KAG_SIZE - (url_ftell(s->pb) & (KAG_SIZE-1)); + unsigned pad = KAG_SIZE - (size & (KAG_SIZE-1)); if (pad < 17) // smallest fill item possible return pad + KAG_SIZE; else @@ -862,7 +863,7 @@ static int mxf_write_index_table_segment(AVFormatContext *s) { MXFContext *mxf = s->priv_data; ByteIOContext *pb = s->pb; - int i, j, k, ret; + int i, j, ret; int temporal_reordering = 0; int last_key_index = 0, key_index = 0; @@ -870,7 +871,7 @@ static int mxf_write_index_table_segment(AVFormatContext *s) put_buffer(pb, index_table_segment_key, 16); ret = klv_encode_ber_length(pb, 109 + (s->nb_streams+1)*6 + - mxf->edit_units_count*(11+(s->nb_streams-1)*4)); + mxf->edit_units_count*(11+mxf->slice_count*4)); // instance id mxf_write_local_tag(pb, 16, 0x3C0A); @@ -901,9 +902,9 @@ static int mxf_write_index_table_segment(AVFormatContext *s) mxf_write_local_tag(pb, 4, 0x3F07); put_be32(pb, 1); - // slice count - 1 + // real slice count - 1 mxf_write_local_tag(pb, 1, 0x3F08); - put_byte(pb, s->nb_streams-1); + put_byte(pb, mxf->slice_count); // delta entry array mxf_write_local_tag(pb, 8 + (s->nb_streams+1)*6, 0x3F09); @@ -919,16 +920,21 @@ static int mxf_write_index_table_segment(AVFormatContext *s) put_byte(pb, sc->temporal_reordering); if (sc->temporal_reordering) temporal_reordering = 1; - put_byte(pb, i); - if (i == 0) + // slice number + if (i == 0) { // video track + put_byte(pb, 0); // slice number put_be32(pb, KAG_SIZE); // system item size including klv fill - else - put_be32(pb, 0); // element delta + } else { // audio track + unsigned audio_frame_size = sc->aic.samples[0]*sc->aic.sample_size; + audio_frame_size += klv_fill_size(audio_frame_size); + put_byte(pb, 1); + put_be32(pb, (i-1)*audio_frame_size); // element delta + } } - mxf_write_local_tag(pb, 8 + mxf->edit_units_count*(11+(s->nb_streams-1)*4), 0x3F0A); + mxf_write_local_tag(pb, 8 + mxf->edit_units_count*(11+mxf->slice_count*4), 0x3F0A); put_be32(pb, mxf->edit_units_count); // num of entries - put_be32(pb, 11+(s->nb_streams-1)*4); // size of one entry + put_be32(pb, 11+mxf->slice_count*4); // size of one entry for (i = 0; i < mxf->edit_units_count; i++) { if (temporal_reordering) { int temporal_offset = 0; @@ -963,10 +969,8 @@ static int mxf_write_index_table_segment(AVFormatContext *s) put_byte(pb, mxf->index_entries[i].flags); // stream offset put_be64(pb, mxf->index_entries[i].offset - mxf->index_entries[0].offset); - for (k = 0; k < s->nb_streams; k++) { - if (mxf->index_entries[i].slice_offset[k]) - put_be32(pb, mxf->index_entries[i].slice_offset[k]); - } + if (s->nb_streams > 1) + put_be32(pb, mxf->index_entries[i].slice_offset); } return ret; @@ -1018,7 +1022,7 @@ static void mxf_write_partition(AVFormatContext *s, int bodysid, mxf_write_primer_pack(s); mxf_write_header_metadata_sets(s); pos = url_ftell(s->pb); - header_byte_count = pos - start + klv_fill_size(s); + header_byte_count = pos - start + klv_fill_size(pos); // update header_byte_count url_fseek(pb, header_byte_count_offset, SEEK_SET); @@ -1201,6 +1205,7 @@ static int mxf_write_header(AVFormatContext *s) return -1; } av_set_pts_info(st, 64, 1, st->codec->sample_rate); + mxf->slice_count = 1; } sc->duration = -1; @@ -1243,7 +1248,7 @@ static int mxf_write_header(AVFormatContext *s) static void mxf_write_klv_fill(AVFormatContext *s) { - unsigned pad = klv_fill_size(s); + unsigned pad = klv_fill_size(url_ftell(s->pb)); if (pad) { put_buffer(s->pb, klv_fill_key, 16); pad -= 16; @@ -1354,14 +1359,13 @@ static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt) if (st->index == 0) { mxf->index_entries[mxf->edit_units_count].offset = url_ftell(pb); - mxf->index_entries[mxf->edit_units_count].slice_offset[st->index] = 0; mxf_write_system_item(s); mxf_write_klv_fill(s); mxf->edit_units_count++; - } else { - mxf->index_entries[mxf->edit_units_count-1].slice_offset[st->index] = + } else if (st->index == 1) { + mxf->index_entries[mxf->edit_units_count-1].slice_offset = url_ftell(pb) - mxf->index_entries[mxf->edit_units_count-1].offset; } @@ -1399,7 +1403,7 @@ static int mxf_write_footer(AVFormatContext *s) ByteIOContext *pb = s->pb; unsigned index_byte_count = 109 + (s->nb_streams+1)*6 + - mxf->edit_units_count*(11+(s->nb_streams-1)*4); + mxf->edit_units_count*(11+mxf->slice_count*4); // add encoded ber length index_byte_count += 16 + klv_ber_length(index_byte_count);