From 53dc9c103e24c5235f7ebffb4a2861e4557fc8e0 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Tue, 23 Mar 2004 09:04:47 +0000 Subject: [PATCH] Write the duration of the last packet for each track. --- src/input/r_wav.cpp | 4 +++- src/mkvmerge.cpp | 2 ++ src/output/p_flac.cpp | 28 +++++++++++++++++++++++++++- src/output/p_flac.h | 3 +++ src/pr_generic.cpp | 23 +++++++++++++++++++++-- src/pr_generic.h | 2 ++ 6 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/input/r_wav.cpp b/src/input/r_wav.cpp index 19a4f4021..4f7ed5967 100644 --- a/src/input/r_wav.cpp +++ b/src/input/r_wav.cpp @@ -192,7 +192,9 @@ wav_reader_c::read(generic_packetizer_c *) { if (nread != bps) { pcmpacketizer->flush(); return 0; - } else + } else if (mm_io->eof()) + return 0; + else return EMOREDATA; } diff --git a/src/mkvmerge.cpp b/src/mkvmerge.cpp index ec876b976..94d693643 100644 --- a/src/mkvmerge.cpp +++ b/src/mkvmerge.cpp @@ -2592,6 +2592,8 @@ main_loop() { while ((ptzr->pack == NULL) && (ptzr->status == EMOREDATA) && (ptzr->packetizer->packet_available() < 1)) ptzr->status = ptzr->packetizer->read(); + if (ptzr->status != EMOREDATA) + ptzr->packetizer->force_duration_on_last_packet(); if (ptzr->pack == NULL) ptzr->pack = ptzr->packetizer->get_packet(); } diff --git a/src/output/p_flac.cpp b/src/output/p_flac.cpp index 516cd5b19..30b0a2aeb 100644 --- a/src/output/p_flac.cpp +++ b/src/output/p_flac.cpp @@ -62,6 +62,9 @@ flac_packetizer_c::flac_packetizer_c(generic_reader_c *nreader, l_header = nl_header; } + num_packets = 0; + avg_duration = 0; + set_track_type(track_audio); if (use_durations) die("flac_packetizer: use_durations() not supported yet.\n"); @@ -91,16 +94,39 @@ flac_packetizer_c::process(memory_c &mem, int64_t, int64_t, int64_t) { + int64_t duration, this_timecode; + debug_enter("flac_packetizer_c::process"); if (timecode == -1) timecode = last_timecode; + duration = timecode - last_timecode; + if (num_packets > 0) + avg_duration = (avg_duration * (num_packets - 1) + duration) / + num_packets; + num_packets++; + this_timecode = last_timecode; last_timecode = timecode; - add_packet(mem, timecode, 0); + if (last_mem == NULL) { + last_mem = mem.grab(); + return EMOREDATA; + } + add_packet(*last_mem, this_timecode, duration); + delete last_mem; + last_mem = mem.grab(); debug_leave("flac_packetizer_c::process"); return EMOREDATA; } +void +flac_packetizer_c::flush() { + if (last_mem == NULL) + return; + add_packet(*last_mem, last_timecode, avg_duration); + delete last_mem; + last_mem = NULL; +} + void flac_packetizer_c::dump_debug_info() { mxdebug("flac_packetizer_c: queue: %d\n", packet_queue.size()); diff --git a/src/output/p_flac.h b/src/output/p_flac.h index ed304a4ea..90ad3cfcd 100644 --- a/src/output/p_flac.h +++ b/src/output/p_flac.h @@ -35,6 +35,8 @@ private: unsigned char *header; int l_header, sample_rate, channels, bits_per_sample; int64_t last_timecode; + memory_c *last_mem; + int64_t num_packets, avg_duration; public: flac_packetizer_c(generic_reader_c *nreader, @@ -47,6 +49,7 @@ public: int64_t length = -1, int64_t bref = -1, int64_t fref = -1); virtual void set_headers(); + virtual void flush(); virtual void dump_debug_info(); }; diff --git a/src/pr_generic.cpp b/src/pr_generic.cpp index af1759c86..ebea36598 100644 --- a/src/pr_generic.cpp +++ b/src/pr_generic.cpp @@ -970,7 +970,8 @@ generic_packetizer_c::get_next_timecode(int64_t timecode) { return timecode; } -void generic_packetizer_c::displace(float by_ns) { +void +generic_packetizer_c::displace(float by_ns) { ti->async.displacement += (int64_t)by_ns; if (initial_displacement < 0) { if (ti->async.displacement < initial_displacement) @@ -980,9 +981,27 @@ void generic_packetizer_c::displace(float by_ns) { initial_displacement = 0; } +void +generic_packetizer_c::force_duration_on_last_packet() { + packet_t *packet; + + if (packet_queue.empty()) { + mxverb(2, "force_duration_on_last_packet: packet queue is empty for " + "'%s'/%lld\n", ti->fname, ti->id); + return; + } + packet = packet_queue.back(); + packet->duration_mandatory = true; + mxverb(2, "force_duration_on_last_packet: forcing at " FMT_TIMECODE " with " + "%.3fms for '%s'/%lld\n", ARG_TIMECODE_NS(packet->timecode), + packet->duration / 1000.0, ti->fname, ti->id); +} + //-------------------------------------------------------------------- -bool generic_reader_c::demuxing_requested(char type, int64_t id) { +bool +generic_reader_c::demuxing_requested(char type, + int64_t id) { vector *tracks; int i; diff --git a/src/pr_generic.h b/src/pr_generic.h index ff72865ef..6c4f1e79f 100644 --- a/src/pr_generic.h +++ b/src/pr_generic.h @@ -410,6 +410,8 @@ public: } virtual void displace(float by_ns); + virtual void force_duration_on_last_packet(); + protected: virtual void dump_packet(const void *buffer, int size); };