Imlpemented appending chapters.

This commit is contained in:
Moritz Bunkus 2004-11-13 17:49:50 +00:00
parent 03184bb462
commit 92eb6cad48
7 changed files with 115 additions and 53 deletions

View File

@ -589,7 +589,7 @@ move_chapters_by_edition(KaxChapters &dst,
for (i = 0; i < src.ListSize(); i++) {
KaxEditionEntry *ee_dst;
KaxEditionUID *euid_src, *euid_dst;
KaxEditionUID *euid_src;
EbmlMaster *m;
m = static_cast<EbmlMaster *>(src[i]);
@ -597,16 +597,9 @@ move_chapters_by_edition(KaxChapters &dst,
// Find an edition to which these atoms will be added.
ee_dst = NULL;
euid_src = FINDFIRST(m, KaxEditionUID);
if (euid_src != NULL) {
for (k = 0; k < dst.ListSize(); k++) {
euid_dst = FINDFIRST(static_cast<EbmlMaster *>(dst[k]),
KaxEditionUID);
if ((euid_dst != NULL) && (uint32(*euid_src) == uint32(*euid_dst))) {
ee_dst = static_cast<KaxEditionEntry *>(dst[k]);
break;
}
}
}
if (euid_src != NULL)
ee_dst = find_edition_with_uid(dst, uint32(*euid_src));
// No edition with the same UID found as the one we want to handle?
// Then simply move the complete edition over.
if (ee_dst == NULL)
@ -614,10 +607,68 @@ move_chapters_by_edition(KaxChapters &dst,
else {
// Move all atoms from the old edition to the new one.
for (k = 0; k < m->ListSize(); k++)
ee_dst->PushElement(*(*m)[k]);
if (is_id((*m)[k], KaxChapterAtom))
ee_dst->PushElement(*(*m)[k]);
else
delete (*m)[k];
m->RemoveAll();
delete m;
}
}
src.RemoveAll();
}
/** \brief Adjust all start and end timecodes by an offset
*
* All start and end timecodes are adjusted by an offset. This is done
* recursively.
*
* \param master A master containint the elements to adjust. This can be
* a KaxChapters, KaxEditionEntry or KaxChapterAtom object.
* \param offset The offset to add to each timecode. Can be negative. If
* the resulting timecode would be smaller than zero then it will be set
* to zero.
*/
void
adjust_chapter_timecodes(EbmlMaster &master,
int64_t offset) {
int i;
for (i = 0; i < master.ListSize(); i++) {
KaxChapterAtom *atom;
KaxChapterTimeStart *start;
KaxChapterTimeEnd *end;
int64_t new_value;
if (!is_id(master[i], KaxChapterAtom))
continue;
atom = static_cast<KaxChapterAtom *>(master[i]);
start = FINDFIRST(atom, KaxChapterTimeStart);
if (start != NULL) {
new_value = uint64(*start);
new_value += offset;
if (new_value < 0)
new_value = 0;
*static_cast<EbmlUInteger *>(start) = new_value;
}
end = FINDFIRST(atom, KaxChapterTimeEnd);
if (end != NULL) {
new_value = uint64(*end);
new_value += offset;
if (new_value < 0)
new_value = 0;
*static_cast<EbmlUInteger *>(end) = new_value;
}
}
for (i = 0; i < master.ListSize(); i++) {
EbmlMaster *m;
m = dynamic_cast<EbmlMaster *>(master[i]);
if (m != NULL)
adjust_chapter_timecodes(*m, offset);
}
}

View File

@ -23,6 +23,10 @@
#include "common.h"
#include "mm_io.h"
namespace libebml {
class EbmlMaster;
};
namespace libmatroska {
class KaxChapters;
class KaxTags;
@ -95,6 +99,6 @@ KaxChapterAtom *MTX_DLL_API find_chapter_with_uid(KaxChapters &chapters,
uint64_t uid);
void MTX_DLL_API move_chapters_by_edition(KaxChapters &dst, KaxChapters &src);
void MTX_DLL_API adjust_chapter_timecodes(EbmlMaster &master, int64_t offset);
#endif // __CHAPTERS_H

View File

@ -1864,8 +1864,11 @@ kax_reader_c::read(generic_packetizer_c *,
cluster_tc = uint64(*ctc);
cluster->InitTimecode(cluster_tc, tc_scale);
if (first_timecode == -1)
if (first_timecode == -1) {
first_timecode = cluster_tc * tc_scale;
if ((chapters != NULL) && (first_timecode > 0))
adjust_chapter_timecodes(*chapters, -first_timecode);
}
for (bgidx = 0; bgidx < cluster->ListSize(); bgidx++) {
if (!(EbmlId(*(*cluster)[bgidx]) ==

View File

@ -49,7 +49,7 @@ cluster_helper_c::cluster_helper_c() {
num_clusters = 0;
clusters = NULL;
cluster_content_size = 0;
max_timecode = 0;
max_timecode_and_duration = 0;
last_cluster_tc = 0;
num_cue_elements = 0;
header_overhead = -1;
@ -102,7 +102,7 @@ void
cluster_helper_c::add_packet(packet_t *packet) {
ch_contents_t *c;
packet_t *p;
int64_t timecode, old_max_timecode, additional_size;
int64_t timecode, additional_size;
int i;
bool split;
@ -181,12 +181,6 @@ cluster_helper_c::add_packet(packet_t *packet) {
if (split) {
render();
old_max_timecode = max_timecode;
if ((packet->unmodified_assigned_timecode +
packet->unmodified_duration) >
max_timecode)
max_timecode = packet->unmodified_assigned_timecode +
packet->unmodified_duration;
num_cue_elements = 0;
mxinfo("\n");
@ -198,16 +192,20 @@ cluster_helper_c::add_packet(packet_t *packet) {
bytes_in_file = 0;
first_timecode_in_file = -1;
max_timecode = old_max_timecode;
if (no_linking) {
timecode_offset = -1;
timecode_offset = packet->assigned_timecode;
first_timecode = 0;
} else
first_timecode = -1;
}
}
if ((packet->unmodified_assigned_timecode + packet->unmodified_duration) >
max_timecode_and_duration)
max_timecode_and_duration = packet->unmodified_assigned_timecode +
packet->unmodified_duration;
packet->packet_num = packet_num;
packet_num++;
@ -219,11 +217,6 @@ cluster_helper_c::add_packet(packet_t *packet) {
c->num_packets++;
cluster_content_size += packet->length;
if ((packet->unmodified_assigned_timecode + packet->unmodified_duration) >
max_timecode)
max_timecode = packet->unmodified_assigned_timecode +
packet->unmodified_duration;
walk_clusters();
// Render the cluster if it is full (according to my many criteria).
@ -433,8 +426,6 @@ cluster_helper_c::render_cluster(ch_contents_t *clstr) {
if (first_timecode == -1)
first_timecode = pack->assigned_timecode;
if (timecode_offset == -1)
timecode_offset = pack->assigned_timecode;
if (i == 0)
static_cast<kax_cluster_c *>
(cluster)->set_min_timecode(pack->assigned_timecode - timecode_offset);
@ -760,8 +751,8 @@ cluster_helper_c::free_ref(int64_t ref_timecode,
}
int64_t
cluster_helper_c::get_max_timecode() {
return max_timecode - timecode_offset;
cluster_helper_c::get_duration() {
return max_timecode_and_duration - timecode_offset;
}
int64_t

View File

@ -49,7 +49,8 @@ class cluster_helper_c {
private:
ch_contents_t **clusters;
int num_clusters, cluster_content_size;
int64_t max_timecode, last_cluster_tc, num_cue_elements, header_overhead;
int64_t max_timecode_and_duration;
int64_t last_cluster_tc, num_cue_elements, header_overhead;
int64_t packet_num, timecode_offset, *last_packets, first_timecode;
int64_t bytes_in_file, first_timecode_in_file;
mm_io_c *out;
@ -69,7 +70,7 @@ public:
int free_ref(int64_t ref_timecode, generic_packetizer_c *source);
int free_clusters();
int get_cluster_content_size();
int64_t get_max_timecode();
int64_t get_duration();
int64_t get_first_timecode();
int64_t get_timecode_offset();

View File

@ -206,8 +206,7 @@ sighandler(int signum) {
// as the file's duration.
out->save_pos(kax_duration->GetElementPosition());
*(static_cast<EbmlFloat *>(kax_duration)) =
irnd((double)(cluster_helper->get_max_timecode() -
cluster_helper->get_first_timecode()) /
irnd((double)cluster_helper->get_duration() /
(double)((int64_t)timecode_scale));
kax_duration->Render(*out);
out->restore_pos();
@ -1339,14 +1338,12 @@ finish_file(bool last_file) {
// Now re-render the kax_duration and fill in the biggest timecode
// as the file's duration.
out->save_pos(kax_duration->GetElementPosition());
mxverb(3, "mkvmerge: kax_duration: gmt %lld tcs %f du %lld\n",
cluster_helper->get_max_timecode(), timecode_scale,
irnd((double)(cluster_helper->get_max_timecode() -
cluster_helper->get_first_timecode()) /
mxverb(3, "mkvmerge: kax_duration: gdur %lld tcs %f du %lld\n",
cluster_helper->get_duration(), timecode_scale,
irnd((double)cluster_helper->get_duration() /
(double)((int64_t)timecode_scale)));
*(static_cast<EbmlFloat *>(kax_duration)) =
irnd((double)(cluster_helper->get_max_timecode() -
cluster_helper->get_first_timecode()) /
irnd((double)cluster_helper->get_duration() /
(double)((int64_t)timecode_scale));
kax_duration->Render(*out);
@ -1390,7 +1387,7 @@ finish_file(bool last_file) {
else
offset = 0;
start = cluster_helper->get_first_timecode() + offset;
end = cluster_helper->get_max_timecode() + offset;
end = start + cluster_helper->get_duration();
chapters_here = copy_chapters(kax_chapters);
if (splitting)
@ -1498,15 +1495,30 @@ void
append_track(packetizer_t &ptzr,
const append_spec_t &amap) {
vector<generic_packetizer_c *>::const_iterator gptzr;
filelist_t &src_file = files[amap.src_file_id];
filelist_t &dst_file = files[amap.dst_file_id];
foreach(gptzr, files[amap.src_file_id].reader->reader_packetizers)
foreach(gptzr, src_file.reader->reader_packetizers)
if (amap.src_track_id == (*gptzr)->ti->id)
break;
if (gptzr == files[amap.src_file_id].reader->reader_packetizers.end())
if (gptzr == src_file.reader->reader_packetizers.end())
die("Could not find gptzr when appending. %s\n", BUGMSG);
if ((*gptzr)->get_track_type() == track_subtitle)
files[ptzr.file].reader->read_all();
if (((*gptzr)->get_track_type() == track_subtitle) ||
(src_file.reader->chapters != NULL))
dst_file.reader->read_all();
// Append some more chapters and adjust their timecodes by the highest
// timecode seen in the previous file.
if (src_file.reader->chapters != NULL) {
if (kax_chapters == NULL)
kax_chapters = new KaxChapters;
adjust_chapter_timecodes(*src_file.reader->chapters,
dst_file.reader->max_timecode_seen);
move_chapters_by_edition(*kax_chapters, *src_file.reader->chapters);
delete src_file.reader->chapters;
src_file.reader->chapters = NULL;
}
mxinfo("Appending track %lld from file no. %lld ('%s') to track %lld from "
"file no. %lld ('%s').\n",
@ -1514,9 +1526,9 @@ append_track(packetizer_t &ptzr,
ptzr.packetizer->ti->id, amap.dst_file_id,
ptzr.packetizer->ti->fname);
if (display_reader == files[amap.dst_file_id].reader) {
if (display_reader == dst_file.reader) {
display_files_done++;
display_reader = files[amap.src_file_id].reader;
display_reader = src_file.reader;
}
(*gptzr)->connect(ptzr.packetizer);

View File

@ -11,12 +11,12 @@ T_010realvideo_4:0d25e4137c50066f43fd12da6a4871af:passed:20040825-175700
T_011srt:d7ac4923916c695a9b47425a90e39a0b:passed:20040825-175700
T_012ssa:9ecbc6bdfa5dec6495f99c7a97342844:passed:20040825-175700
T_013vobsubs:8983288ea21b811fbb85d2ea272ccfe5:passed:20040825-175700
T_014splitting_by_size:feeb1aba481b5a51d7142599359f2eac-5c639e8a08cf526d051fdf64f856c0d2:passed:20040825-175700
T_015splitting_by_time:d0e769a906ec4eacc9c9af929add6474-c32e2d8c31e21e71f68875f2d9735565:passed:20040825-175700
T_014splitting_by_size:feeb1aba481b5a51d7142599359f2eac-5c639e8a08cf526d051fdf64f856c0d2:failed:20040825-175700
T_015splitting_by_time:d0e769a906ec4eacc9c9af929add6474-c32e2d8c31e21e71f68875f2d9735565:failed:20040825-175700
T_016cuesheet:61b3a09c06ba2a8c7018d045d80f9c30:passed:20040825-175700
T_017chapters:562b2281edfa5acca556c3f77f60a291-4b54a7add7783cb99d83dd476a50e135:passed:20040825-175700
T_018attachments:bac27359516bab4984df3021aa295213-7e8e1f17615f157db0e98fba9ad88bad:passed:20040825-175700
T_019attachments2:8d9ba46c4edbf3daf50175f9de2f87b4-94349d68c9b7d493ec0d5a49f7291e40-8d9ba46c4edbf3daf50175f9de2f87b4-5c639e8a08cf526d051fdf64f856c0d2:passed:20040825-175700
T_019attachments2:8d9ba46c4edbf3daf50175f9de2f87b4-94349d68c9b7d493ec0d5a49f7291e40-8d9ba46c4edbf3daf50175f9de2f87b4-5c639e8a08cf526d051fdf64f856c0d2:failed:20040825-175700
T_020languages:a2ade9796f89718812d0ef9926922c38:passed:20040825-234208
T_021aspect_ratio:f6e8aa4cfd776d99ff824f21d4e3c640-990a5f94678b5c8886dc8c3a5c6a22dd:passed:20040825-234244
T_022display_dimensions:108880396ffe5244465a3d25e8a57f93:passed:20040825-234339