Mercurial > libavformat.hg
comparison mxfenc.c @ 4397:6d1626886974 libavformat
only use 2 slices for index, one video(vbr) and one audio(cbr)
author | bcoudurier |
---|---|
date | Sun, 08 Feb 2009 03:29:49 +0000 |
parents | a34ee37a164e |
children | 65adb9e5214f |
comparison
equal
deleted
inserted
replaced
4396:a34ee37a164e | 4397:6d1626886974 |
---|---|
60 } MXFLocalTagPair; | 60 } MXFLocalTagPair; |
61 | 61 |
62 typedef struct { | 62 typedef struct { |
63 uint8_t flags; | 63 uint8_t flags; |
64 uint64_t offset; | 64 uint64_t offset; |
65 unsigned slice_offset[17]; // one video, 16 audio | 65 unsigned slice_offset; // offset of audio slice |
66 } MXFIndexEntry; | 66 } MXFIndexEntry; |
67 | 67 |
68 typedef struct { | 68 typedef struct { |
69 AudioInterleaveContext aic; | 69 AudioInterleaveContext aic; |
70 UID track_essence_element_key; | 70 UID track_essence_element_key; |
123 AVRational time_base; | 123 AVRational time_base; |
124 int header_written; | 124 int header_written; |
125 MXFIndexEntry *index_entries; | 125 MXFIndexEntry *index_entries; |
126 unsigned edit_units_count; | 126 unsigned edit_units_count; |
127 uint64_t timestamp; ///< timestamp, as year(16),month(8),day(8),hour(8),minutes(8),msec/4(8) | 127 uint64_t timestamp; ///< timestamp, as year(16),month(8),day(8),hour(8),minutes(8),msec/4(8) |
128 uint8_t slice_count; /// index slice count minus 1 (1 if no audio, 0 otherwise) | |
128 } MXFContext; | 129 } MXFContext; |
129 | 130 |
130 static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd }; | 131 static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd }; |
131 static const uint8_t umid_base[] = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13,0x00,0x00,0x00 }; | 132 static const uint8_t umid_base[] = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13,0x00,0x00,0x00 }; |
132 | 133 |
847 mxf_write_package(s, SourcePackage); | 848 mxf_write_package(s, SourcePackage); |
848 mxf_write_essence_container_data(s); | 849 mxf_write_essence_container_data(s); |
849 return 0; | 850 return 0; |
850 } | 851 } |
851 | 852 |
852 static unsigned klv_fill_size(AVFormatContext *s) | 853 static unsigned klv_fill_size(uint64_t size) |
853 { | 854 { |
854 unsigned pad = KAG_SIZE - (url_ftell(s->pb) & (KAG_SIZE-1)); | 855 unsigned pad = KAG_SIZE - (size & (KAG_SIZE-1)); |
855 if (pad < 17) // smallest fill item possible | 856 if (pad < 17) // smallest fill item possible |
856 return pad + KAG_SIZE; | 857 return pad + KAG_SIZE; |
857 else | 858 else |
858 return pad & (KAG_SIZE-1); | 859 return pad & (KAG_SIZE-1); |
859 } | 860 } |
860 | 861 |
861 static int mxf_write_index_table_segment(AVFormatContext *s) | 862 static int mxf_write_index_table_segment(AVFormatContext *s) |
862 { | 863 { |
863 MXFContext *mxf = s->priv_data; | 864 MXFContext *mxf = s->priv_data; |
864 ByteIOContext *pb = s->pb; | 865 ByteIOContext *pb = s->pb; |
865 int i, j, k, ret; | 866 int i, j, ret; |
866 int temporal_reordering = 0; | 867 int temporal_reordering = 0; |
867 int last_key_index = 0, key_index = 0; | 868 int last_key_index = 0, key_index = 0; |
868 | 869 |
869 av_log(s, AV_LOG_DEBUG, "edit units count %d\n", mxf->edit_units_count); | 870 av_log(s, AV_LOG_DEBUG, "edit units count %d\n", mxf->edit_units_count); |
870 | 871 |
871 put_buffer(pb, index_table_segment_key, 16); | 872 put_buffer(pb, index_table_segment_key, 16); |
872 ret = klv_encode_ber_length(pb, 109 + (s->nb_streams+1)*6 + | 873 ret = klv_encode_ber_length(pb, 109 + (s->nb_streams+1)*6 + |
873 mxf->edit_units_count*(11+(s->nb_streams-1)*4)); | 874 mxf->edit_units_count*(11+mxf->slice_count*4)); |
874 | 875 |
875 // instance id | 876 // instance id |
876 mxf_write_local_tag(pb, 16, 0x3C0A); | 877 mxf_write_local_tag(pb, 16, 0x3C0A); |
877 mxf_write_uuid(pb, IndexTableSegment, 0); | 878 mxf_write_uuid(pb, IndexTableSegment, 0); |
878 | 879 |
899 | 900 |
900 // body sid | 901 // body sid |
901 mxf_write_local_tag(pb, 4, 0x3F07); | 902 mxf_write_local_tag(pb, 4, 0x3F07); |
902 put_be32(pb, 1); | 903 put_be32(pb, 1); |
903 | 904 |
904 // slice count - 1 | 905 // real slice count - 1 |
905 mxf_write_local_tag(pb, 1, 0x3F08); | 906 mxf_write_local_tag(pb, 1, 0x3F08); |
906 put_byte(pb, s->nb_streams-1); | 907 put_byte(pb, mxf->slice_count); |
907 | 908 |
908 // delta entry array | 909 // delta entry array |
909 mxf_write_local_tag(pb, 8 + (s->nb_streams+1)*6, 0x3F09); | 910 mxf_write_local_tag(pb, 8 + (s->nb_streams+1)*6, 0x3F09); |
910 put_be32(pb, s->nb_streams+1); // num of entries | 911 put_be32(pb, s->nb_streams+1); // num of entries |
911 put_be32(pb, 6); // size of one entry | 912 put_be32(pb, 6); // size of one entry |
917 AVStream *st = s->streams[i]; | 918 AVStream *st = s->streams[i]; |
918 MXFStreamContext *sc = st->priv_data; | 919 MXFStreamContext *sc = st->priv_data; |
919 put_byte(pb, sc->temporal_reordering); | 920 put_byte(pb, sc->temporal_reordering); |
920 if (sc->temporal_reordering) | 921 if (sc->temporal_reordering) |
921 temporal_reordering = 1; | 922 temporal_reordering = 1; |
922 put_byte(pb, i); | 923 // slice number |
923 if (i == 0) | 924 if (i == 0) { // video track |
925 put_byte(pb, 0); // slice number | |
924 put_be32(pb, KAG_SIZE); // system item size including klv fill | 926 put_be32(pb, KAG_SIZE); // system item size including klv fill |
925 else | 927 } else { // audio track |
926 put_be32(pb, 0); // element delta | 928 unsigned audio_frame_size = sc->aic.samples[0]*sc->aic.sample_size; |
927 } | 929 audio_frame_size += klv_fill_size(audio_frame_size); |
928 | 930 put_byte(pb, 1); |
929 mxf_write_local_tag(pb, 8 + mxf->edit_units_count*(11+(s->nb_streams-1)*4), 0x3F0A); | 931 put_be32(pb, (i-1)*audio_frame_size); // element delta |
932 } | |
933 } | |
934 | |
935 mxf_write_local_tag(pb, 8 + mxf->edit_units_count*(11+mxf->slice_count*4), 0x3F0A); | |
930 put_be32(pb, mxf->edit_units_count); // num of entries | 936 put_be32(pb, mxf->edit_units_count); // num of entries |
931 put_be32(pb, 11+(s->nb_streams-1)*4); // size of one entry | 937 put_be32(pb, 11+mxf->slice_count*4); // size of one entry |
932 for (i = 0; i < mxf->edit_units_count; i++) { | 938 for (i = 0; i < mxf->edit_units_count; i++) { |
933 if (temporal_reordering) { | 939 if (temporal_reordering) { |
934 int temporal_offset = 0; | 940 int temporal_offset = 0; |
935 for (j = i+1; j < mxf->edit_units_count; j++) { | 941 for (j = i+1; j < mxf->edit_units_count; j++) { |
936 temporal_offset++; | 942 temporal_offset++; |
961 last_key_index = key_index; | 967 last_key_index = key_index; |
962 } | 968 } |
963 put_byte(pb, mxf->index_entries[i].flags); | 969 put_byte(pb, mxf->index_entries[i].flags); |
964 // stream offset | 970 // stream offset |
965 put_be64(pb, mxf->index_entries[i].offset - mxf->index_entries[0].offset); | 971 put_be64(pb, mxf->index_entries[i].offset - mxf->index_entries[0].offset); |
966 for (k = 0; k < s->nb_streams; k++) { | 972 if (s->nb_streams > 1) |
967 if (mxf->index_entries[i].slice_offset[k]) | 973 put_be32(pb, mxf->index_entries[i].slice_offset); |
968 put_be32(pb, mxf->index_entries[i].slice_offset[k]); | |
969 } | |
970 } | 974 } |
971 | 975 |
972 return ret; | 976 return ret; |
973 } | 977 } |
974 | 978 |
1016 unsigned header_byte_count; | 1020 unsigned header_byte_count; |
1017 | 1021 |
1018 mxf_write_primer_pack(s); | 1022 mxf_write_primer_pack(s); |
1019 mxf_write_header_metadata_sets(s); | 1023 mxf_write_header_metadata_sets(s); |
1020 pos = url_ftell(s->pb); | 1024 pos = url_ftell(s->pb); |
1021 header_byte_count = pos - start + klv_fill_size(s); | 1025 header_byte_count = pos - start + klv_fill_size(pos); |
1022 | 1026 |
1023 // update header_byte_count | 1027 // update header_byte_count |
1024 url_fseek(pb, header_byte_count_offset, SEEK_SET); | 1028 url_fseek(pb, header_byte_count_offset, SEEK_SET); |
1025 put_be64(pb, header_byte_count); | 1029 put_be64(pb, header_byte_count); |
1026 url_fseek(pb, pos, SEEK_SET); | 1030 url_fseek(pb, pos, SEEK_SET); |
1199 if (st->codec->sample_rate != 48000) { | 1203 if (st->codec->sample_rate != 48000) { |
1200 av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n"); | 1204 av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n"); |
1201 return -1; | 1205 return -1; |
1202 } | 1206 } |
1203 av_set_pts_info(st, 64, 1, st->codec->sample_rate); | 1207 av_set_pts_info(st, 64, 1, st->codec->sample_rate); |
1208 mxf->slice_count = 1; | |
1204 } | 1209 } |
1205 sc->duration = -1; | 1210 sc->duration = -1; |
1206 | 1211 |
1207 sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id); | 1212 sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id); |
1208 if (sc->index == -1) { | 1213 if (sc->index == -1) { |
1241 return 0; | 1246 return 0; |
1242 } | 1247 } |
1243 | 1248 |
1244 static void mxf_write_klv_fill(AVFormatContext *s) | 1249 static void mxf_write_klv_fill(AVFormatContext *s) |
1245 { | 1250 { |
1246 unsigned pad = klv_fill_size(s); | 1251 unsigned pad = klv_fill_size(url_ftell(s->pb)); |
1247 if (pad) { | 1252 if (pad) { |
1248 put_buffer(s->pb, klv_fill_key, 16); | 1253 put_buffer(s->pb, klv_fill_key, 16); |
1249 pad -= 16; | 1254 pad -= 16; |
1250 pad -= klv_ber_length(pad); | 1255 pad -= klv_ber_length(pad); |
1251 klv_encode_ber_length(s->pb, pad); | 1256 klv_encode_ber_length(s->pb, pad); |
1352 | 1357 |
1353 mxf_write_klv_fill(s); | 1358 mxf_write_klv_fill(s); |
1354 | 1359 |
1355 if (st->index == 0) { | 1360 if (st->index == 0) { |
1356 mxf->index_entries[mxf->edit_units_count].offset = url_ftell(pb); | 1361 mxf->index_entries[mxf->edit_units_count].offset = url_ftell(pb); |
1357 mxf->index_entries[mxf->edit_units_count].slice_offset[st->index] = 0; | |
1358 | 1362 |
1359 mxf_write_system_item(s); | 1363 mxf_write_system_item(s); |
1360 mxf_write_klv_fill(s); | 1364 mxf_write_klv_fill(s); |
1361 | 1365 |
1362 mxf->edit_units_count++; | 1366 mxf->edit_units_count++; |
1363 } else { | 1367 } else if (st->index == 1) { |
1364 mxf->index_entries[mxf->edit_units_count-1].slice_offset[st->index] = | 1368 mxf->index_entries[mxf->edit_units_count-1].slice_offset = |
1365 url_ftell(pb) - mxf->index_entries[mxf->edit_units_count-1].offset; | 1369 url_ftell(pb) - mxf->index_entries[mxf->edit_units_count-1].offset; |
1366 } | 1370 } |
1367 | 1371 |
1368 put_buffer(pb, sc->track_essence_element_key, 16); // write key | 1372 put_buffer(pb, sc->track_essence_element_key, 16); // write key |
1369 klv_encode_ber_length(pb, pkt->size); // write length | 1373 klv_encode_ber_length(pb, pkt->size); // write length |
1397 { | 1401 { |
1398 MXFContext *mxf = s->priv_data; | 1402 MXFContext *mxf = s->priv_data; |
1399 ByteIOContext *pb = s->pb; | 1403 ByteIOContext *pb = s->pb; |
1400 unsigned index_byte_count = | 1404 unsigned index_byte_count = |
1401 109 + (s->nb_streams+1)*6 + | 1405 109 + (s->nb_streams+1)*6 + |
1402 mxf->edit_units_count*(11+(s->nb_streams-1)*4); | 1406 mxf->edit_units_count*(11+mxf->slice_count*4); |
1403 | 1407 |
1404 // add encoded ber length | 1408 // add encoded ber length |
1405 index_byte_count += 16 + klv_ber_length(index_byte_count); | 1409 index_byte_count += 16 + klv_ber_length(index_byte_count); |
1406 | 1410 |
1407 mxf_write_klv_fill(s); | 1411 mxf_write_klv_fill(s); |