Mercurial > libavformat.hg
comparison mxfenc.c @ 4448:587ce9359a9b libavformat
write timecode track
author | bcoudurier |
---|---|
date | Wed, 11 Feb 2009 07:18:00 +0000 |
parents | efe78f986bec |
children | aaae79b414f3 |
comparison
equal
deleted
inserted
replaced
4447:1fb8c4a56366 | 4448:587ce9359a9b |
---|---|
61 typedef struct { | 61 typedef struct { |
62 AudioInterleaveContext aic; | 62 AudioInterleaveContext aic; |
63 UID track_essence_element_key; | 63 UID track_essence_element_key; |
64 int index; ///< index in mxf_essence_container_uls table | 64 int index; ///< index in mxf_essence_container_uls table |
65 const UID *codec_ul; | 65 const UID *codec_ul; |
66 int64_t duration; | |
67 int order; ///< interleaving order if dts are equal | 66 int order; ///< interleaving order if dts are equal |
68 int interlaced; ///< wether picture is interlaced | 67 int interlaced; ///< wether picture is interlaced |
69 int temporal_reordering; | 68 int temporal_reordering; |
70 } MXFStreamContext; | 69 } MXFStreamContext; |
71 | 70 |
122 int last_indexed_edit_unit; | 121 int last_indexed_edit_unit; |
123 uint64_t first_edit_unit_offset; | 122 uint64_t first_edit_unit_offset; |
124 uint64_t *body_partition_offset; | 123 uint64_t *body_partition_offset; |
125 unsigned body_partitions_count; | 124 unsigned body_partitions_count; |
126 int last_key_index; ///< index of last key frame | 125 int last_key_index; ///< index of last key frame |
126 uint64_t duration; | |
127 AVStream *timecode_track; | |
128 int timecode_base; ///< rounded time code base (25 or 30) | |
129 int timecode_start; ///< value from mpeg-2 essence gop header | |
130 int timecode_drop_frame; ///< time code use drop frame method frop mpeg-2 essence gop header | |
127 } MXFContext; | 131 } MXFContext; |
128 | 132 |
129 static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd }; | 133 static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd }; |
130 static const uint8_t umid_base[] = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13,0x00,0x00,0x00 }; | 134 static const uint8_t umid_base[] = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13,0x00,0x00,0x00 }; |
131 | 135 |
192 { 0x1001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x09,0x00,0x00}}, /* Structural Components reference array */ | 196 { 0x1001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x09,0x00,0x00}}, /* Structural Components reference array */ |
193 // Source Clip | 197 // Source Clip |
194 { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x04,0x00,0x00}}, /* Start position */ | 198 { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x04,0x00,0x00}}, /* Start position */ |
195 { 0x1101, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x01,0x00,0x00,0x00}}, /* SourcePackageID */ | 199 { 0x1101, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x01,0x00,0x00,0x00}}, /* SourcePackageID */ |
196 { 0x1102, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x02,0x00,0x00,0x00}}, /* SourceTrackID */ | 200 { 0x1102, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x02,0x00,0x00,0x00}}, /* SourceTrackID */ |
201 // Timecode Component | |
202 { 0x1501, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x05,0x00,0x00}}, /* Start Time Code */ | |
203 { 0x1502, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x04,0x01,0x01,0x02,0x06,0x00,0x00}}, /* Rounded Time Code Base */ | |
204 { 0x1503, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x04,0x01,0x01,0x05,0x00,0x00,0x00}}, /* Drop Frame */ | |
197 // File Descriptor | 205 // File Descriptor |
198 { 0x3F01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x04,0x06,0x0B,0x00,0x00}}, /* Sub Descriptors reference array */ | 206 { 0x3F01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x04,0x06,0x0B,0x00,0x00}}, /* Sub Descriptors reference array */ |
199 { 0x3006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x06,0x01,0x01,0x03,0x05,0x00,0x00,0x00}}, /* Linked Track ID */ | 207 { 0x3006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x06,0x01,0x01,0x03,0x05,0x00,0x00,0x00}}, /* Linked Track ID */ |
200 { 0x3001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x00,0x00,0x00,0x00}}, /* SampleRate */ | 208 { 0x3001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x00,0x00,0x00,0x00}}, /* SampleRate */ |
201 { 0x3004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x02,0x00,0x00}}, /* Essence Container */ | 209 { 0x3004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x02,0x00,0x00}}, /* Essence Container */ |
520 // write sequence refs | 528 // write sequence refs |
521 mxf_write_local_tag(pb, 16, 0x4803); | 529 mxf_write_local_tag(pb, 16, 0x4803); |
522 mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index); | 530 mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index); |
523 } | 531 } |
524 | 532 |
525 static void mxf_write_common_fields(ByteIOContext *pb, AVStream *st) | 533 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 }; |
526 { | 534 |
527 const MXFCodecUL *data_def_ul = mxf_get_data_definition_ul(st->codec->codec_type); | 535 static void mxf_write_common_fields(AVFormatContext *s, AVStream *st) |
528 MXFStreamContext *sc = st->priv_data; | 536 { |
537 MXFContext *mxf = s->priv_data; | |
538 ByteIOContext *pb = s->pb; | |
529 | 539 |
530 // find data define uls | 540 // find data define uls |
531 mxf_write_local_tag(pb, 16, 0x0201); | 541 mxf_write_local_tag(pb, 16, 0x0201); |
532 put_buffer(pb, data_def_ul->uid, 16); | 542 if (st == mxf->timecode_track) |
543 put_buffer(pb, smpte_12m_timecode_track_data_ul, 16); | |
544 else { | |
545 const MXFCodecUL *data_def_ul = mxf_get_data_definition_ul(st->codec->codec_type); | |
546 put_buffer(pb, data_def_ul->uid, 16); | |
547 } | |
533 | 548 |
534 // write duration | 549 // write duration |
535 mxf_write_local_tag(pb, 8, 0x0202); | 550 mxf_write_local_tag(pb, 8, 0x0202); |
536 put_be64(pb, sc->duration); | 551 put_be64(pb, mxf->duration); |
537 } | 552 } |
538 | 553 |
539 static void mxf_write_sequence(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type) | 554 static void mxf_write_sequence(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type) |
540 { | 555 { |
541 ByteIOContext *pb = s->pb; | 556 MXFContext *mxf = s->priv_data; |
557 ByteIOContext *pb = s->pb; | |
558 enum MXFMetadataSetType component; | |
542 | 559 |
543 mxf_write_metadata_key(pb, 0x010f00); | 560 mxf_write_metadata_key(pb, 0x010f00); |
544 PRINT_KEY(s, "sequence key", pb->buf_ptr - 16); | 561 PRINT_KEY(s, "sequence key", pb->buf_ptr - 16); |
545 klv_encode_ber_length(pb, 80); | 562 klv_encode_ber_length(pb, 80); |
546 | 563 |
547 mxf_write_local_tag(pb, 16, 0x3C0A); | 564 mxf_write_local_tag(pb, 16, 0x3C0A); |
548 mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index); | 565 mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index); |
549 | 566 |
550 PRINT_KEY(s, "sequence uid", pb->buf_ptr - 16); | 567 PRINT_KEY(s, "sequence uid", pb->buf_ptr - 16); |
551 mxf_write_common_fields(pb, st); | 568 mxf_write_common_fields(s, st); |
552 | 569 |
553 // write structural component | 570 // write structural component |
554 mxf_write_local_tag(pb, 16 + 8, 0x1001); | 571 mxf_write_local_tag(pb, 16 + 8, 0x1001); |
555 mxf_write_refs_count(pb, 1); | 572 mxf_write_refs_count(pb, 1); |
556 mxf_write_uuid(pb, type == MaterialPackage ? SourceClip: SourceClip + TypeBottom, st->index); | 573 if (st == mxf->timecode_track) |
574 component = TimecodeComponent; | |
575 else if (type == MaterialPackage) | |
576 component = SourceClip; | |
577 else | |
578 component = SourceClip+TypeBottom; | |
579 mxf_write_uuid(pb, component, st->index); | |
580 } | |
581 | |
582 static void mxf_write_timecode_component(AVFormatContext *s, AVStream *st) | |
583 { | |
584 MXFContext *mxf = s->priv_data; | |
585 ByteIOContext *pb = s->pb; | |
586 | |
587 mxf_write_metadata_key(pb, 0x011400); | |
588 klv_encode_ber_length(pb, 75); | |
589 | |
590 // UID | |
591 mxf_write_local_tag(pb, 16, 0x3C0A); | |
592 mxf_write_uuid(pb, TimecodeComponent, st->index); | |
593 | |
594 mxf_write_common_fields(s, st); | |
595 | |
596 // Start Time Code | |
597 mxf_write_local_tag(pb, 8, 0x1501); | |
598 put_be64(pb, mxf->timecode_start); | |
599 | |
600 // Rounded Time Code Base | |
601 mxf_write_local_tag(pb, 2, 0x1502); | |
602 put_be16(pb, mxf->timecode_base); | |
603 | |
604 // Drop Frame | |
605 mxf_write_local_tag(pb, 1, 0x1503); | |
606 put_byte(pb, mxf->timecode_drop_frame); | |
557 } | 607 } |
558 | 608 |
559 static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type) | 609 static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type) |
560 { | 610 { |
561 ByteIOContext *pb = s->pb; | 611 ByteIOContext *pb = s->pb; |
568 // write uid | 618 // write uid |
569 mxf_write_local_tag(pb, 16, 0x3C0A); | 619 mxf_write_local_tag(pb, 16, 0x3C0A); |
570 mxf_write_uuid(pb, type == MaterialPackage ? SourceClip: SourceClip + TypeBottom, st->index); | 620 mxf_write_uuid(pb, type == MaterialPackage ? SourceClip: SourceClip + TypeBottom, st->index); |
571 | 621 |
572 PRINT_KEY(s, "structural component uid", pb->buf_ptr - 16); | 622 PRINT_KEY(s, "structural component uid", pb->buf_ptr - 16); |
573 mxf_write_common_fields(pb, st); | 623 mxf_write_common_fields(s, st); |
574 | 624 |
575 // write start_position | 625 // write start_position |
576 mxf_write_local_tag(pb, 8, 0x1201); | 626 mxf_write_local_tag(pb, 8, 0x1201); |
577 put_be64(pb, 0); | 627 put_be64(pb, 0); |
578 | 628 |
771 | 821 |
772 static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type) | 822 static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type) |
773 { | 823 { |
774 MXFContext *mxf = s->priv_data; | 824 MXFContext *mxf = s->priv_data; |
775 ByteIOContext *pb = s->pb; | 825 ByteIOContext *pb = s->pb; |
776 int i; | 826 int i, track_count; |
777 | 827 |
778 if (type == MaterialPackage) { | 828 if (type == MaterialPackage) { |
829 track_count = s->nb_streams + 1; // add timecode track | |
779 mxf_write_metadata_key(pb, 0x013600); | 830 mxf_write_metadata_key(pb, 0x013600); |
780 PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16); | 831 PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16); |
781 klv_encode_ber_length(pb, 92 + 16 * s->nb_streams); | 832 klv_encode_ber_length(pb, 92 + 16*track_count); |
782 } else { | 833 } else { |
834 track_count = s->nb_streams; | |
783 mxf_write_metadata_key(pb, 0x013700); | 835 mxf_write_metadata_key(pb, 0x013700); |
784 PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16); | 836 PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16); |
785 klv_encode_ber_length(pb, 112 + 16 * s->nb_streams); // 20 bytes length for descriptor reference | 837 klv_encode_ber_length(pb, 112 + 16*track_count); // 20 bytes length for descriptor reference |
786 } | 838 } |
787 | 839 |
788 // write uid | 840 // write uid |
789 mxf_write_local_tag(pb, 16, 0x3C0A); | 841 mxf_write_local_tag(pb, 16, 0x3C0A); |
790 mxf_write_uuid(pb, type, 0); | 842 mxf_write_uuid(pb, type, 0); |
803 // package modified date | 855 // package modified date |
804 mxf_write_local_tag(pb, 8, 0x4404); | 856 mxf_write_local_tag(pb, 8, 0x4404); |
805 put_be64(pb, mxf->timestamp); | 857 put_be64(pb, mxf->timestamp); |
806 | 858 |
807 // write track refs | 859 // write track refs |
808 mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x4403); | 860 mxf_write_local_tag(pb, track_count*16 + 8, 0x4403); |
809 mxf_write_refs_count(pb, s->nb_streams); | 861 mxf_write_refs_count(pb, track_count); |
810 for (i = 0; i < s->nb_streams; i++) | 862 for (i = 0; i < s->nb_streams; i++) |
811 mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, i); | 863 mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, i); |
864 if (type == MaterialPackage) | |
865 mxf_write_uuid(pb, Track, s->nb_streams); // timecode track | |
812 | 866 |
813 // write multiple descriptor reference | 867 // write multiple descriptor reference |
814 if (type == SourcePackage) { | 868 if (type == SourcePackage) { |
815 mxf_write_local_tag(pb, 16, 0x4701); | 869 mxf_write_local_tag(pb, 16, 0x4701); |
816 if (s->nb_streams > 1) { | 870 if (s->nb_streams > 1) { |
817 mxf_write_uuid(pb, MultipleDescriptor, 0); | 871 mxf_write_uuid(pb, MultipleDescriptor, 0); |
818 mxf_write_multi_descriptor(s); | 872 mxf_write_multi_descriptor(s); |
819 } else | 873 } else |
820 mxf_write_uuid(pb, SubDescriptor, 0); | 874 mxf_write_uuid(pb, SubDescriptor, 0); |
875 } else { | |
876 // write timecode track | |
877 mxf_write_track(s, mxf->timecode_track, type); | |
878 mxf_write_sequence(s, mxf->timecode_track, type); | |
879 mxf_write_timecode_component(s, mxf->timecode_track); | |
821 } | 880 } |
822 | 881 |
823 for (i = 0; i < s->nb_streams; i++) { | 882 for (i = 0; i < s->nb_streams; i++) { |
824 AVStream *st = s->streams[i]; | 883 AVStream *st = s->streams[i]; |
825 mxf_write_track(s, st, type); | 884 mxf_write_track(s, st, type); |
1218 return -1; | 1277 return -1; |
1219 } | 1278 } |
1220 if (fabs(av_q2d(st->codec->time_base) - 1/25.0) < 0.0001) { | 1279 if (fabs(av_q2d(st->codec->time_base) - 1/25.0) < 0.0001) { |
1221 samples_per_frame = PAL_samples_per_frame; | 1280 samples_per_frame = PAL_samples_per_frame; |
1222 mxf->time_base = (AVRational){ 1, 25 }; | 1281 mxf->time_base = (AVRational){ 1, 25 }; |
1282 mxf->timecode_base = 25; | |
1223 } else if (fabs(av_q2d(st->codec->time_base) - 1001/30000.0) < 0.0001) { | 1283 } else if (fabs(av_q2d(st->codec->time_base) - 1001/30000.0) < 0.0001) { |
1224 samples_per_frame = NTSC_samples_per_frame; | 1284 samples_per_frame = NTSC_samples_per_frame; |
1225 mxf->time_base = (AVRational){ 1001, 30000 }; | 1285 mxf->time_base = (AVRational){ 1001, 30000 }; |
1286 mxf->timecode_base = 30; | |
1226 } else { | 1287 } else { |
1227 av_log(s, AV_LOG_ERROR, "unsupported video frame rate\n"); | 1288 av_log(s, AV_LOG_ERROR, "unsupported video frame rate\n"); |
1228 return -1; | 1289 return -1; |
1229 } | 1290 } |
1230 av_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den); | 1291 av_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den); |
1234 return -1; | 1295 return -1; |
1235 } | 1296 } |
1236 av_set_pts_info(st, 64, 1, st->codec->sample_rate); | 1297 av_set_pts_info(st, 64, 1, st->codec->sample_rate); |
1237 mxf->slice_count = 1; | 1298 mxf->slice_count = 1; |
1238 } | 1299 } |
1239 sc->duration = -1; | |
1240 | 1300 |
1241 sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id); | 1301 sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id); |
1242 if (sc->index == -1) { | 1302 if (sc->index == -1) { |
1243 av_log(s, AV_LOG_ERROR, "track %d: could not find essence container ul, " | 1303 av_log(s, AV_LOG_ERROR, "track %d: could not find essence container ul, " |
1244 "codec not currently supported in container\n", i); | 1304 "codec not currently supported in container\n", i); |
1263 sc->track_essence_element_key[13] = present[sc->index]; | 1323 sc->track_essence_element_key[13] = present[sc->index]; |
1264 sc->order = AV_RB32(sc->track_essence_element_key+12); | 1324 sc->order = AV_RB32(sc->track_essence_element_key+12); |
1265 } | 1325 } |
1266 | 1326 |
1267 mxf->timestamp = mxf_parse_timestamp(s->timestamp); | 1327 mxf->timestamp = mxf_parse_timestamp(s->timestamp); |
1328 mxf->duration = -1; | |
1329 | |
1330 mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track)); | |
1331 if (!mxf->timecode_track) | |
1332 return AVERROR(ENOMEM); | |
1333 mxf->timecode_track->priv_data = av_mallocz(sizeof(MXFStreamContext)); | |
1334 if (!mxf->timecode_track->priv_data) | |
1335 return AVERROR(ENOMEM); | |
1336 mxf->timecode_track->index = s->nb_streams; | |
1268 | 1337 |
1269 if (!samples_per_frame) | 1338 if (!samples_per_frame) |
1270 samples_per_frame = PAL_samples_per_frame; | 1339 samples_per_frame = PAL_samples_per_frame; |
1271 | 1340 |
1272 if (ff_audio_interleave_init(s, samples_per_frame, mxf->time_base) < 0) | 1341 if (ff_audio_interleave_init(s, samples_per_frame, mxf->time_base) < 0) |
1298 | 1367 |
1299 static void mxf_write_system_item(AVFormatContext *s) | 1368 static void mxf_write_system_item(AVFormatContext *s) |
1300 { | 1369 { |
1301 MXFContext *mxf = s->priv_data; | 1370 MXFContext *mxf = s->priv_data; |
1302 ByteIOContext *pb = s->pb; | 1371 ByteIOContext *pb = s->pb; |
1303 unsigned fps, frame; | 1372 unsigned frame; |
1304 uint32_t time_code; | 1373 uint32_t time_code; |
1305 | 1374 |
1306 frame = mxf->last_indexed_edit_unit + mxf->edit_units_count; | 1375 frame = mxf->last_indexed_edit_unit + mxf->edit_units_count; |
1307 | 1376 |
1308 // write system metadata pack | 1377 // write system metadata pack |
1319 put_buffer(pb, mxf_essence_container_uls[mxf->essence_containers_indices[0]].container_ul, 16); | 1388 put_buffer(pb, mxf_essence_container_uls[mxf->essence_containers_indices[0]].container_ul, 16); |
1320 put_byte(pb, 0); | 1389 put_byte(pb, 0); |
1321 put_be64(pb, 0); | 1390 put_be64(pb, 0); |
1322 put_be64(pb, 0); // creation date/time stamp | 1391 put_be64(pb, 0); // creation date/time stamp |
1323 | 1392 |
1324 // XXX drop frame | |
1325 if (mxf->time_base.den == 30000) fps = 30; | |
1326 else fps = 25; | |
1327 | |
1328 put_byte(pb, 0x81); // SMPTE 12M time code | 1393 put_byte(pb, 0x81); // SMPTE 12M time code |
1329 time_code = ff_framenum_to_12m_time_code(frame, 0, fps); | 1394 time_code = ff_framenum_to_12m_time_code(frame, mxf->timecode_drop_frame, mxf->timecode_base); |
1330 put_be32(pb, time_code); | 1395 put_be32(pb, time_code); |
1331 put_be32(pb, 0); // binary group data | 1396 put_be32(pb, 0); // binary group data |
1332 put_be64(pb, 0); | 1397 put_be64(pb, 0); |
1333 | 1398 |
1334 // write system metadata package set | 1399 // write system metadata package set |
1394 mxf_write_klv_fill(s); | 1459 mxf_write_klv_fill(s); |
1395 put_buffer(pb, sc->track_essence_element_key, 16); // write key | 1460 put_buffer(pb, sc->track_essence_element_key, 16); // write key |
1396 klv_encode_ber_length(pb, pkt->size); // write length | 1461 klv_encode_ber_length(pb, pkt->size); // write length |
1397 put_buffer(pb, pkt->data, pkt->size); // write value | 1462 put_buffer(pb, pkt->data, pkt->size); // write value |
1398 | 1463 |
1399 sc->duration = FFMAX(pkt->pts + pkt->duration, sc->duration); | |
1400 | |
1401 put_flush_packet(pb); | 1464 put_flush_packet(pb); |
1402 return 0; | 1465 return 0; |
1403 } | 1466 } |
1404 | 1467 |
1405 static void mxf_write_random_index_pack(AVFormatContext *s) | 1468 static void mxf_write_random_index_pack(AVFormatContext *s) |
1429 static int mxf_write_footer(AVFormatContext *s) | 1492 static int mxf_write_footer(AVFormatContext *s) |
1430 { | 1493 { |
1431 MXFContext *mxf = s->priv_data; | 1494 MXFContext *mxf = s->priv_data; |
1432 ByteIOContext *pb = s->pb; | 1495 ByteIOContext *pb = s->pb; |
1433 | 1496 |
1497 mxf->duration = mxf->last_indexed_edit_unit + mxf->edit_units_count; | |
1498 | |
1434 mxf_write_klv_fill(s); | 1499 mxf_write_klv_fill(s); |
1435 mxf->footer_partition_offset = url_ftell(pb); | 1500 mxf->footer_partition_offset = url_ftell(pb); |
1436 mxf_write_partition(s, 0, 2, footer_partition_key, 0); | 1501 mxf_write_partition(s, 0, 2, footer_partition_key, 0); |
1437 | 1502 |
1438 mxf_write_klv_fill(s); | 1503 mxf_write_klv_fill(s); |
1448 | 1513 |
1449 ff_audio_interleave_close(s); | 1514 ff_audio_interleave_close(s); |
1450 | 1515 |
1451 av_freep(&mxf->index_entries); | 1516 av_freep(&mxf->index_entries); |
1452 av_freep(&mxf->body_partition_offset); | 1517 av_freep(&mxf->body_partition_offset); |
1518 av_freep(&mxf->timecode_track->priv_data); | |
1519 av_freep(&mxf->timecode_track); | |
1453 | 1520 |
1454 mxf_free(s); | 1521 mxf_free(s); |
1455 return 0; | 1522 return 0; |
1456 } | 1523 } |
1457 | 1524 |