Mercurial > libavformat.hg
comparison matroskaenc.c @ 5793:640f14283092 libavformat
mkvenc: write dts for VFW mode
author | conrad |
---|---|
date | Tue, 09 Mar 2010 04:23:28 +0000 |
parents | 551765b1772b |
children | 31e8a43123c5 |
comparison
equal
deleted
inserted
replaced
5792:2fb291f12e5f | 5793:640f14283092 |
---|---|
59 int64_t segment_offset; | 59 int64_t segment_offset; |
60 mkv_cuepoint *entries; | 60 mkv_cuepoint *entries; |
61 int num_entries; | 61 int num_entries; |
62 } mkv_cues; | 62 } mkv_cues; |
63 | 63 |
64 typedef struct { | |
65 int write_dts; | |
66 } mkv_track; | |
67 | |
64 typedef struct MatroskaMuxContext { | 68 typedef struct MatroskaMuxContext { |
65 ByteIOContext *dyn_bc; | 69 ByteIOContext *dyn_bc; |
66 ebml_master segment; | 70 ebml_master segment; |
67 int64_t segment_offset; | 71 int64_t segment_offset; |
68 int64_t segment_uid; | 72 int64_t segment_uid; |
72 int64_t duration_offset; | 76 int64_t duration_offset; |
73 uint64_t duration; | 77 uint64_t duration; |
74 mkv_seekhead *main_seekhead; | 78 mkv_seekhead *main_seekhead; |
75 mkv_seekhead *cluster_seekhead; | 79 mkv_seekhead *cluster_seekhead; |
76 mkv_cues *cues; | 80 mkv_cues *cues; |
81 mkv_track *tracks; | |
77 | 82 |
78 struct AVMD5 *md5_ctx; | 83 struct AVMD5 *md5_ctx; |
79 } MatroskaMuxContext; | 84 } MatroskaMuxContext; |
80 | 85 |
81 | 86 |
340 | 345 |
341 cues->segment_offset = segment_offset; | 346 cues->segment_offset = segment_offset; |
342 return cues; | 347 return cues; |
343 } | 348 } |
344 | 349 |
345 static int mkv_add_cuepoint(mkv_cues *cues, AVPacket *pkt, int64_t cluster_pos) | 350 static int mkv_add_cuepoint(mkv_cues *cues, int stream, int64_t ts, int64_t cluster_pos) |
346 { | 351 { |
347 mkv_cuepoint *entries = cues->entries; | 352 mkv_cuepoint *entries = cues->entries; |
348 | 353 |
349 entries = av_realloc(entries, (cues->num_entries + 1) * sizeof(mkv_cuepoint)); | 354 entries = av_realloc(entries, (cues->num_entries + 1) * sizeof(mkv_cuepoint)); |
350 if (entries == NULL) | 355 if (entries == NULL) |
351 return AVERROR(ENOMEM); | 356 return AVERROR(ENOMEM); |
352 | 357 |
353 entries[cues->num_entries ].pts = pkt->pts; | 358 entries[cues->num_entries ].pts = ts; |
354 entries[cues->num_entries ].tracknum = pkt->stream_index + 1; | 359 entries[cues->num_entries ].tracknum = stream + 1; |
355 entries[cues->num_entries++].cluster_pos = cluster_pos - cues->segment_offset; | 360 entries[cues->num_entries++].cluster_pos = cluster_pos - cues->segment_offset; |
356 | 361 |
357 cues->entries = entries; | 362 cues->entries = entries; |
358 return 0; | 363 return 0; |
359 } | 364 } |
566 || codec->codec_id == CODEC_ID_CINEPAK)) | 571 || codec->codec_id == CODEC_ID_CINEPAK)) |
567 qt_id = 1; | 572 qt_id = 1; |
568 | 573 |
569 if (qt_id) | 574 if (qt_id) |
570 put_ebml_string(pb, MATROSKA_ID_CODECID, "V_QUICKTIME"); | 575 put_ebml_string(pb, MATROSKA_ID_CODECID, "V_QUICKTIME"); |
571 else if (!native_id) | 576 else if (!native_id) { |
572 // if there is no mkv-specific codec ID, use VFW mode | 577 // if there is no mkv-specific codec ID, use VFW mode |
573 put_ebml_string(pb, MATROSKA_ID_CODECID, "V_MS/VFW/FOURCC"); | 578 put_ebml_string(pb, MATROSKA_ID_CODECID, "V_MS/VFW/FOURCC"); |
579 mkv->tracks[i].write_dts = 1; | |
580 } | |
574 | 581 |
575 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKVIDEO, 0); | 582 subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKVIDEO, 0); |
576 // XXX: interlace flag? | 583 // XXX: interlace flag? |
577 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , codec->width); | 584 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , codec->width); |
578 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, codec->height); | 585 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, codec->height); |
672 AVMetadataTag *tag; | 679 AVMetadataTag *tag; |
673 int ret; | 680 int ret; |
674 | 681 |
675 mkv->md5_ctx = av_mallocz(av_md5_size); | 682 mkv->md5_ctx = av_mallocz(av_md5_size); |
676 av_md5_init(mkv->md5_ctx); | 683 av_md5_init(mkv->md5_ctx); |
684 mkv->tracks = av_mallocz(s->nb_streams * sizeof(*mkv->tracks)); | |
677 | 685 |
678 ebml_header = start_ebml_master(pb, EBML_ID_HEADER, 0); | 686 ebml_header = start_ebml_master(pb, EBML_ID_HEADER, 0); |
679 put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1); | 687 put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1); |
680 put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1); | 688 put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1); |
681 put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4); | 689 put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4); |
811 { | 819 { |
812 MatroskaMuxContext *mkv = s->priv_data; | 820 MatroskaMuxContext *mkv = s->priv_data; |
813 AVCodecContext *codec = s->streams[pkt->stream_index]->codec; | 821 AVCodecContext *codec = s->streams[pkt->stream_index]->codec; |
814 uint8_t *data = NULL; | 822 uint8_t *data = NULL; |
815 int size = pkt->size; | 823 int size = pkt->size; |
824 int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; | |
816 | 825 |
817 av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, " | 826 av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, " |
818 "pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n", | 827 "pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n", |
819 url_ftell(pb), pkt->size, pkt->pts, pkt->dts, pkt->duration, flags); | 828 url_ftell(pb), pkt->size, pkt->pts, pkt->dts, pkt->duration, flags); |
820 if (codec->codec_id == CODEC_ID_H264 && codec->extradata_size > 0 && | 829 if (codec->codec_id == CODEC_ID_H264 && codec->extradata_size > 0 && |
823 else | 832 else |
824 data = pkt->data; | 833 data = pkt->data; |
825 put_ebml_id(pb, blockid); | 834 put_ebml_id(pb, blockid); |
826 put_ebml_num(pb, size+4, 0); | 835 put_ebml_num(pb, size+4, 0); |
827 put_byte(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126 | 836 put_byte(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126 |
828 put_be16(pb, pkt->pts - mkv->cluster_pts); | 837 put_be16(pb, ts - mkv->cluster_pts); |
829 put_byte(pb, flags); | 838 put_byte(pb, flags); |
830 put_buffer(pb, data, size); | 839 put_buffer(pb, data, size); |
831 if (data != pkt->data) | 840 if (data != pkt->data) |
832 av_free(data); | 841 av_free(data); |
833 } | 842 } |
853 ByteIOContext *pb = s->pb; | 862 ByteIOContext *pb = s->pb; |
854 AVCodecContext *codec = s->streams[pkt->stream_index]->codec; | 863 AVCodecContext *codec = s->streams[pkt->stream_index]->codec; |
855 int keyframe = !!(pkt->flags & PKT_FLAG_KEY); | 864 int keyframe = !!(pkt->flags & PKT_FLAG_KEY); |
856 int duration = pkt->duration; | 865 int duration = pkt->duration; |
857 int ret; | 866 int ret; |
867 int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; | |
858 | 868 |
859 if (url_is_streamed(s->pb)) { | 869 if (url_is_streamed(s->pb)) { |
860 if (!mkv->dyn_bc) | 870 if (!mkv->dyn_bc) |
861 url_open_dyn_buf(&mkv->dyn_bc); | 871 url_open_dyn_buf(&mkv->dyn_bc); |
862 pb = mkv->dyn_bc; | 872 pb = mkv->dyn_bc; |
866 ret = mkv_add_seekhead_entry(mkv->cluster_seekhead, MATROSKA_ID_CLUSTER, url_ftell(pb)); | 876 ret = mkv_add_seekhead_entry(mkv->cluster_seekhead, MATROSKA_ID_CLUSTER, url_ftell(pb)); |
867 if (ret < 0) return ret; | 877 if (ret < 0) return ret; |
868 | 878 |
869 mkv->cluster_pos = url_ftell(s->pb); | 879 mkv->cluster_pos = url_ftell(s->pb); |
870 mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER, 0); | 880 mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER, 0); |
871 put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, pkt->pts); | 881 put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, ts); |
872 mkv->cluster_pts = pkt->pts; | 882 mkv->cluster_pts = ts; |
873 av_md5_update(mkv->md5_ctx, pkt->data, FFMIN(200, pkt->size)); | 883 av_md5_update(mkv->md5_ctx, pkt->data, FFMIN(200, pkt->size)); |
874 } | 884 } |
875 | 885 |
876 if (codec->codec_type != CODEC_TYPE_SUBTITLE) { | 886 if (codec->codec_type != CODEC_TYPE_SUBTITLE) { |
877 mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7); | 887 mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7); |
884 put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration); | 894 put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration); |
885 end_ebml_master(pb, blockgroup); | 895 end_ebml_master(pb, blockgroup); |
886 } | 896 } |
887 | 897 |
888 if (codec->codec_type == CODEC_TYPE_VIDEO && keyframe) { | 898 if (codec->codec_type == CODEC_TYPE_VIDEO && keyframe) { |
889 ret = mkv_add_cuepoint(mkv->cues, pkt, mkv->cluster_pos); | 899 ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, ts, mkv->cluster_pos); |
890 if (ret < 0) return ret; | 900 if (ret < 0) return ret; |
891 } | 901 } |
892 | 902 |
893 // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming | 903 // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming |
894 if (url_is_streamed(s->pb) && (url_ftell(pb) > 32*1024 || pkt->pts > mkv->cluster_pts + 1000) | 904 if (url_is_streamed(s->pb) && (url_ftell(pb) > 32*1024 || ts > mkv->cluster_pts + 1000) |
895 || url_ftell(pb) > mkv->cluster_pos + 5*1024*1024 || pkt->pts > mkv->cluster_pts + 5000) { | 905 || url_ftell(pb) > mkv->cluster_pos + 5*1024*1024 || ts > mkv->cluster_pts + 5000) { |
896 av_log(s, AV_LOG_DEBUG, "Starting new cluster at offset %" PRIu64 | 906 av_log(s, AV_LOG_DEBUG, "Starting new cluster at offset %" PRIu64 |
897 " bytes, pts %" PRIu64 "\n", url_ftell(pb), pkt->pts); | 907 " bytes, pts %" PRIu64 "\n", url_ftell(pb), ts); |
898 end_ebml_master(pb, mkv->cluster); | 908 end_ebml_master(pb, mkv->cluster); |
899 mkv->cluster_pos = 0; | 909 mkv->cluster_pos = 0; |
900 if (mkv->dyn_bc) | 910 if (mkv->dyn_bc) |
901 mkv_flush_dynbuf(s); | 911 mkv_flush_dynbuf(s); |
902 } | 912 } |
903 | 913 |
904 mkv->duration = FFMAX(mkv->duration, pkt->pts + duration); | 914 mkv->duration = FFMAX(mkv->duration, ts + duration); |
905 return 0; | 915 return 0; |
906 } | 916 } |
907 | 917 |
908 static int mkv_write_trailer(AVFormatContext *s) | 918 static int mkv_write_trailer(AVFormatContext *s) |
909 { | 919 { |
947 url_fseek(pb, currentpos, SEEK_SET); | 957 url_fseek(pb, currentpos, SEEK_SET); |
948 } | 958 } |
949 | 959 |
950 end_ebml_master(pb, mkv->segment); | 960 end_ebml_master(pb, mkv->segment); |
951 av_free(mkv->md5_ctx); | 961 av_free(mkv->md5_ctx); |
962 av_free(mkv->tracks); | |
952 put_flush_packet(pb); | 963 put_flush_packet(pb); |
953 return 0; | 964 return 0; |
954 } | 965 } |
955 | 966 |
956 AVOutputFormat matroska_muxer = { | 967 AVOutputFormat matroska_muxer = { |