Timecode file handling for B frames. Patch by Steve Lhomme (see AUTHORS). Does not work yet as far as I can tell.

This commit is contained in:
Moritz Bunkus 2005-07-25 15:58:07 +00:00
parent b08f7dd45f
commit 871d1b744b
5 changed files with 67 additions and 24 deletions

View File

@ -43,8 +43,9 @@ struct packet_t {
unsigned char *data;
int length, ref_priority, time_factor;
int64_t timecode, bref, fref, duration, packet_num, assigned_timecode;
int64_t timecode_before_factory;
int64_t unmodified_assigned_timecode, unmodified_duration;
bool duration_mandatory, superseeded, gap_following;
bool duration_mandatory, superseeded, gap_following, factory_applied;
generic_packetizer_c *source;
vector<unsigned char *> data_adds;
vector<int> data_adds_lengths;
@ -57,10 +58,10 @@ struct packet_t {
ref_priority(0), time_factor(1),
timecode(0), bref(0), fref(0), duration(0),
packet_num(packet_number_counter++),
assigned_timecode(0), unmodified_assigned_timecode(0),
unmodified_duration(0),
assigned_timecode(0), timecode_before_factory(0),
unmodified_assigned_timecode(0), unmodified_duration(0),
duration_mandatory(false), superseeded(false), gap_following(false),
source(NULL) { }
factory_applied(false), source(NULL) { }
packet_t(memory_cptr n_memory,
int64_t n_timecode = -1,
@ -72,10 +73,10 @@ struct packet_t {
timecode(n_timecode), bref(n_bref), fref(n_fref),
duration(n_duration),
packet_num(packet_number_counter++),
assigned_timecode(0), unmodified_assigned_timecode(0),
unmodified_duration(0),
assigned_timecode(0), timecode_before_factory(0),
unmodified_assigned_timecode(0), unmodified_duration(0),
duration_mandatory(false), superseeded(false), gap_following(false),
source(NULL), memory(n_memory) { }
factory_applied(false), source(NULL), memory(n_memory) { }
packet_t(memory_c *n_memory,
int64_t n_timecode = -1,
@ -87,10 +88,10 @@ struct packet_t {
timecode(n_timecode), bref(n_bref), fref(n_fref),
duration(n_duration),
packet_num(packet_number_counter++),
assigned_timecode(0), unmodified_assigned_timecode(0),
unmodified_duration(0),
assigned_timecode(0), timecode_before_factory(0),
unmodified_assigned_timecode(0), unmodified_duration(0),
duration_mandatory(false), superseeded(false), gap_following(false),
source(NULL), memory(memory_cptr(n_memory)) { }
factory_applied(false), source(NULL), memory(memory_cptr(n_memory)) { }
~packet_t();
};

View File

@ -924,18 +924,7 @@ generic_packetizer_c::add_packet2(packet_cptr pack) {
}
safety_last_timecode = pack->timecode;
safety_last_duration = pack->duration;
pack->assigned_timecode = pack->timecode;
pack->gap_following = timecode_factory->get_next(pack);
pack->assigned_timecode += ti.packet_delay;
mxverb(2, "mux: track %lld assigned_timecode %lld\n", ti.id,
pack->assigned_timecode);
if (max_timecode_seen < (pack->assigned_timecode + pack->duration))
max_timecode_seen = pack->assigned_timecode + pack->duration;
if (reader->max_timecode_seen < max_timecode_seen)
reader->max_timecode_seen = max_timecode_seen;
pack->timecode_before_factory = pack->timecode;
packet_queue.push_back(pack);
}
@ -949,14 +938,60 @@ generic_packetizer_c::process_deferred_packets() {
deferred_packets.clear();
}
bool
generic_packetizer_c::has_enough_packets() const {
if (packet_queue.size() < 2)
return false;
const packet_cptr &pack = packet_queue.front();
deque<packet_cptr>::const_iterator packet = packet_queue.begin();
++packet;
while ((packet_queue.end() != packet) &&
((*packet)->timecode_before_factory <= pack->timecode_before_factory))
++packet;
return (packet_queue.end() != packet);
}
packet_cptr
generic_packetizer_c::get_packet() {
deque<packet_cptr>::iterator p_timecoded, p_tmp;
int64_t factory_timecode, min_timecode;
packet_cptr pack;
if (packet_queue.size() == 0)
return packet_cptr(NULL);
pack = packet_queue.front();
// use the timecode factory on all previous packets up to the one extracted
do {
// find the next packet to feed the timecode factory
min_timecode = pack->timecode_before_factory;
p_timecoded = packet_queue.begin();
for (p_tmp = packet_queue.begin(); packet_queue.end() != p_tmp; ++p_tmp) {
if (!(*p_tmp)->factory_applied &&
(min_timecode > (*p_tmp)->timecode_before_factory)) {
min_timecode = (*p_tmp)->timecode_before_factory;
p_timecoded = p_tmp;
}
}
if (!(*p_timecoded)->factory_applied) {
factory_timecode = (*p_timecoded)->timecode;
(*p_timecoded)->gap_following = timecode_factory->get_next(*p_timecoded);
(*p_timecoded)->assigned_timecode = factory_timecode + ti.packet_delay;
(*p_timecoded)->factory_applied = true;
if (max_timecode_seen <
((*p_timecoded)->assigned_timecode + (*p_timecoded)->duration))
max_timecode_seen = (*p_timecoded)->assigned_timecode +
(*p_timecoded)->duration;
if (reader->max_timecode_seen < max_timecode_seen)
reader->max_timecode_seen = max_timecode_seen;
}
} while (packet_queue.begin() != p_timecoded);
packet_queue.pop_front();
enqueued_bytes -= pack->length;

View File

@ -567,6 +567,9 @@ public:
}
virtual void set_displacement_maybe(int64_t displacement);
protected:
inline bool has_enough_packets() const;
};
extern vector<generic_packetizer_c *> ptzrs_in_header_order;

View File

@ -365,14 +365,17 @@ timecode_factory_v3_c::get_next(packet_cptr &packet,
bool result = false;
if (durations[current_duration].is_gap) {
// find the next non-gap
size_t duration_index = current_duration;
while (durations[duration_index].is_gap) {
while (durations[duration_index].is_gap ||
(0 == durations[duration_index].duration)) {
current_offset += durations[duration_index].duration;
duration_index++;
}
if (!peek_only) {
current_duration = duration_index;
}
// yes, there is a gap before this frame
result = true;
}
@ -382,6 +385,7 @@ timecode_factory_v3_c::get_next(packet_cptr &packet,
packet->duration =
(int64_t)(1000000000.0 / durations[current_duration].fps);
}
packet->duration /= packet->time_factor;
if (!peek_only) {
current_timecode += packet->duration;
if (current_timecode >= durations[current_duration].duration) {

View File

@ -54,6 +54,6 @@ T_204wavpack_without_correctiondata:0d01f5162a71fedc934d7e8a675a0004:passed:2005
T_205X_cuesheets:3b00b00c7d185137e30d7e95e3123d33-b3bb67d316e20da12926d5c1d628f6e5:passed:20050210-211853
T_206X_vobsub:93c40bd212b1165b14b03d00148fecab-f0b88ab55ffda1f9cc447a784829bcba-2c2cb8dd42f5c15e64bc0f62ba2234b4-39e6f66ff3e0287735c4a577487de878-b5f2200404d4501859c92dcf78cf3a89:passed:20050211-231728
T_207segmentinfo:f3b9681e4a2d154fb501afeafb527eab:passed:20050211-234856
T_208cat_and_splitting:9009f933b8ef8cbe51f5a8abcc1bc814-1f477939efd77d991b9fc4cd9ea8430a:passed:20050306-152640
T_208cat_and_splitting:9009f933b8ef8cbe51f5a8abcc1bc814-e1e8aeebcae89a40bbc9c003c4c0c3f1:passed:20050306-152640
T_209ac3misdeetected_as_mpeges:4ba8d5b8e4e847c5f74ca58f69ad3c69:passed:20050315-092851
T_210splitting_and_chapters:1b7f8527b18911d49a1be6d1a06facd1-94ff3b0066760b32fd6a270daa9f5fca-509fabbe60c9520b6551b4fe27cd7bd5-c7a9564d80552c041177a0ed2661df28:passed:20050406-165104