Revision 84d4e599 libavformat/matroskaenc.c

View differences:

libavformat/matroskaenc.c
61 61
    int             num_entries;
62 62
} mkv_cues;
63 63

  
64
typedef struct {
65
    int             write_dts;
66
} mkv_track;
67

  
64 68
typedef struct MatroskaMuxContext {
65 69
    ByteIOContext   *dyn_bc;
66 70
    ebml_master     segment;
......
74 78
    mkv_seekhead    *main_seekhead;
75 79
    mkv_seekhead    *cluster_seekhead;
76 80
    mkv_cues        *cues;
81
    mkv_track       *tracks;
77 82

  
78 83
    struct AVMD5    *md5_ctx;
79 84
} MatroskaMuxContext;
......
342 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 352
    mkv_cuepoint *entries = cues->entries;
348 353

  
......
350 355
    if (entries == NULL)
351 356
        return AVERROR(ENOMEM);
352 357

  
353
    entries[cues->num_entries  ].pts = pkt->pts;
354
    entries[cues->num_entries  ].tracknum = pkt->stream_index + 1;
358
    entries[cues->num_entries  ].pts = ts;
359
    entries[cues->num_entries  ].tracknum = stream + 1;
355 360
    entries[cues->num_entries++].cluster_pos = cluster_pos - cues->segment_offset;
356 361

  
357 362
    cues->entries = entries;
......
568 573

  
569 574
                if (qt_id)
570 575
                    put_ebml_string(pb, MATROSKA_ID_CODECID, "V_QUICKTIME");
571
                else if (!native_id)
576
                else if (!native_id) {
572 577
                    // if there is no mkv-specific codec ID, use VFW mode
573 578
                    put_ebml_string(pb, MATROSKA_ID_CODECID, "V_MS/VFW/FOURCC");
579
                    mkv->tracks[i].write_dts = 1;
580
                }
574 581

  
575 582
                subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKVIDEO, 0);
576 583
                // XXX: interlace flag?
......
674 681

  
675 682
    mkv->md5_ctx = av_mallocz(av_md5_size);
676 683
    av_md5_init(mkv->md5_ctx);
684
    mkv->tracks = av_mallocz(s->nb_streams * sizeof(*mkv->tracks));
677 685

  
678 686
    ebml_header = start_ebml_master(pb, EBML_ID_HEADER, 0);
679 687
    put_ebml_uint   (pb, EBML_ID_EBMLVERSION        ,           1);
......
813 821
    AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
814 822
    uint8_t *data = NULL;
815 823
    int size = pkt->size;
824
    int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
816 825

  
817 826
    av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, "
818 827
           "pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n",
......
825 834
    put_ebml_id(pb, blockid);
826 835
    put_ebml_num(pb, size+4, 0);
827 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 838
    put_byte(pb, flags);
830 839
    put_buffer(pb, data, size);
831 840
    if (data != pkt->data)
......
855 864
    int keyframe = !!(pkt->flags & PKT_FLAG_KEY);
856 865
    int duration = pkt->duration;
857 866
    int ret;
867
    int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
858 868

  
859 869
    if (url_is_streamed(s->pb)) {
860 870
        if (!mkv->dyn_bc)
......
868 878

  
869 879
        mkv->cluster_pos = url_ftell(s->pb);
870 880
        mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER, 0);
871
        put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, pkt->pts);
872
        mkv->cluster_pts = pkt->pts;
881
        put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, ts);
882
        mkv->cluster_pts = ts;
873 883
        av_md5_update(mkv->md5_ctx, pkt->data, FFMIN(200, pkt->size));
874 884
    }
875 885

  
......
886 896
    }
887 897

  
888 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 900
        if (ret < 0) return ret;
891 901
    }
892 902

  
893 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)
895
        ||  url_ftell(pb) > mkv->cluster_pos + 5*1024*1024 || pkt->pts > mkv->cluster_pts + 5000) {
904
    if (url_is_streamed(s->pb) && (url_ftell(pb) > 32*1024 || ts > mkv->cluster_pts + 1000)
905
        ||  url_ftell(pb) > mkv->cluster_pos + 5*1024*1024 || ts > mkv->cluster_pts + 5000) {
896 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 908
        end_ebml_master(pb, mkv->cluster);
899 909
        mkv->cluster_pos = 0;
900 910
        if (mkv->dyn_bc)
901 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 915
    return 0;
906 916
}
907 917

  
......
949 959

  
950 960
    end_ebml_master(pb, mkv->segment);
951 961
    av_free(mkv->md5_ctx);
962
    av_free(mkv->tracks);
952 963
    put_flush_packet(pb);
953 964
    return 0;
954 965
}

Also available in: Unified diff