Implemented support for SegmentUID, PrevUID and NextUID.

This commit is contained in:
Moritz Bunkus 2003-06-08 19:00:33 +00:00
parent efefc4289e
commit c9e0a7bffb
6 changed files with 175 additions and 29 deletions

View File

@ -1,3 +1,11 @@
2003-06-08 Moritz Bunkus <moritz@bunkus.org>
* Added support for splitting output files by size or by time and
limiting the number of output files.
* Added support for the segment UID/next segment UID/previous
segment UID.
2003-06-06 Moritz Bunkus <moritz@bunkus.org>
* A lot of changes to comply with libmatroska/libebml 0.4.4.

View File

@ -13,7 +13,7 @@
/*!
\file
\version \$Id: cluster_helper.cpp,v 1.24 2003/06/08 16:14:05 mosu Exp $
\version \$Id: cluster_helper.cpp,v 1.25 2003/06/08 18:59:43 mosu Exp $
\brief cluster helper
\author Moritz Bunkus <moritz@bunkus.org>
*/
@ -28,7 +28,7 @@
#include "StdIOCallback.h"
vector<splitpoint_t *> splitpoints;
vector<splitpoint_t *> cluster_helper_c::splitpoints;
//#define walk_clusters() check_clusters(__LINE__)
#define walk_clusters()
@ -230,6 +230,10 @@ void cluster_helper_c::find_next_splitpoint() {
next_splitpoint = i;
}
int cluster_helper_c::get_next_splitpoint() {
return next_splitpoint;
}
void cluster_helper_c::set_output(mm_io_c *nout) {
out = nout;
}
@ -252,12 +256,8 @@ int cluster_helper_c::render() {
cluster = clstr->cluster;
// Splitpoint stuff
if (header_overhead == -1) {
if (pass != 0)
header_overhead = out->getFilePointer();
if (pass == 2)
find_next_splitpoint();
}
if ((header_overhead == -1) && (pass != 0))
header_overhead = out->getFilePointer();
elements_in_cluster = 0;
num_cue_elements_here = 0;
@ -362,13 +362,14 @@ int cluster_helper_c::render() {
if (kax_seekhead != NULL)
kax_seekhead->IndexThis(*cluster, *kax_segment);
}
find_next_splitpoint();
old_max_timecode = max_timecode;
max_timecode = pack->timecode;
fprintf(stdout, "\n");
finish_file();
create_next_output_file();
create_next_output_file(next_splitpoint >= splitpoints.size());
max_timecode = old_max_timecode;
@ -381,8 +382,6 @@ int cluster_helper_c::render() {
elements_in_cluster = 0;
timecode_offset = pack->timecode;
find_next_splitpoint();
}
}

View File

@ -13,7 +13,7 @@
/*!
\file
\version \$Id: cluster_helper.h,v 1.7 2003/06/08 15:38:03 mosu Exp $
\version \$Id: cluster_helper.h,v 1.8 2003/06/08 18:59:43 mosu Exp $
\brief class definition for the cluster helper
\author Moritz Bunkus <moritz@bunkus.org>
*/
@ -45,6 +45,9 @@ private:
int64_t max_timecode, last_cluster_tc, num_cue_elements, header_overhead;
int64_t packet_num, timecode_offset;
mm_io_c *out;
public:
static vector<splitpoint_t *> splitpoints;
public:
cluster_helper_c();
virtual ~cluster_helper_c();
@ -61,6 +64,8 @@ public:
int free_clusters();
int get_cluster_content_size();
int64_t get_max_timecode();
void find_next_splitpoint();
int get_next_splitpoint();
private:
int find_cluster(KaxCluster *cluster);
@ -68,7 +73,6 @@ private:
packet_t *find_packet(int64_t ref_timecode);
void free_contents(ch_contents_t *clstr);
void check_clusters(int num);
void find_next_splitpoint();
};
extern cluster_helper_c *cluster_helper;

View File

@ -12,7 +12,7 @@
/*!
\file
\version \$Id: mkvinfo.cpp,v 1.57 2003/06/07 14:30:10 mosu Exp $
\version \$Id: mkvinfo.cpp,v 1.58 2003/06/08 18:59:43 mosu Exp $
\brief retrieves and displays information about a Matroska file
\author Moritz Bunkus <moritz@bunkus.org>
*/
@ -344,6 +344,36 @@ bool process_file(const char *file_name) {
} else
show_element(l2, 2, "Date (invalid, value: %d)", temptime);
} else if (EbmlId(*l2) == KaxSegmentUID::ClassInfos.GlobalId) {
KaxSegmentUID &uid = *static_cast<KaxSegmentUID *>(l2);
uid.ReadData(es->I_O());
char buffer[uid.GetSize() * 5 + 1];
const unsigned char *b = (const unsigned char *)&binary(uid);
buffer[0] = 0;
for (i = 0; i < uid.GetSize(); i++)
sprintf(&buffer[strlen(buffer)], " 0x%02x", b[i]);
show_element(l2, 2, "Segment UID:%s", buffer);
} else if (EbmlId(*l2) == KaxPrevUID::ClassInfos.GlobalId) {
KaxPrevUID &uid = *static_cast<KaxPrevUID *>(l2);
uid.ReadData(es->I_O());
char buffer[uid.GetSize() * 5 + 1];
const unsigned char *b = (const unsigned char *)&binary(uid);
buffer[0] = 0;
for (i = 0; i < uid.GetSize(); i++)
sprintf(&buffer[strlen(buffer)], " 0x%02x", b[i]);
show_element(l2, 2, "Previous segment UID:%s", buffer);
} else if (EbmlId(*l2) == KaxNextUID::ClassInfos.GlobalId) {
KaxNextUID &uid = *static_cast<KaxNextUID *>(l2);
uid.ReadData(es->I_O());
char buffer[uid.GetSize() * 5 + 1];
const unsigned char *b = (const unsigned char *)&binary(uid);
buffer[0] = 0;
for (i = 0; i < uid.GetSize(); i++)
sprintf(&buffer[strlen(buffer)], " 0x%02x", b[i]);
show_element(l2, 2, "Next segment UID:%s", buffer);
} else if (!is_ebmlvoid(l2, 2))
show_unknown_element(l2, 2);

View File

@ -13,7 +13,7 @@
/*!
\file
\version \$Id: mkvmerge.cpp,v 1.91 2003/06/08 16:14:05 mosu Exp $
\version \$Id: mkvmerge.cpp,v 1.92 2003/06/08 18:59:43 mosu Exp $
\brief command line parameter parsing, looping, output handling
\author Moritz Bunkus <moritz@bunkus.org>
*/
@ -80,6 +80,80 @@
using namespace LIBMATROSKA_NAMESPACE;
using namespace std;
class bitvalue_c {
private:
unsigned char *value;
int bitsize;
public:
bitvalue_c(int nsize);
bitvalue_c(const bitvalue_c &src);
virtual ~bitvalue_c();
bitvalue_c &operator =(const bitvalue_c &src);
bool operator ==(const bitvalue_c &cmp) const;
unsigned char operator [](int index) const;
int size() const;
void generate_random();
unsigned char *data() const;
};
bitvalue_c::bitvalue_c(int nbitsize) {
assert(nbitsize > 0);
assert((nbitsize % 8) == 0);
bitsize = nbitsize;
value = (unsigned char *)safemalloc(bitsize / 8);
memset(value, 0, bitsize / 8);
}
bitvalue_c::bitvalue_c(const bitvalue_c &src) {
value = NULL;
*this = src;
}
bitvalue_c &bitvalue_c::operator =(const bitvalue_c &src) {
safefree(value);
bitsize = src.bitsize;
value = (unsigned char *)safememdup(src.value, bitsize / 8);
return *this;
}
bitvalue_c::~bitvalue_c() {
safefree(value);
}
bool bitvalue_c::operator ==(const bitvalue_c &cmp) const {
int i;
if (cmp.bitsize != bitsize)
return false;
for (i = 0; i < bitsize / 8; i++)
if (value[i] != cmp.value[i])
return false;
return true;
}
unsigned char bitvalue_c::operator [](int index) const {
assert((index >= 0) && (index < (bitsize / 8)));
return value[index];
}
int bitvalue_c::size() const {
return bitsize;
}
unsigned char *bitvalue_c::data() const {
return value;
}
void bitvalue_c::generate_random() {
int i;
for (i = 0; i < bitsize / 8; i++)
value[i] = (unsigned char)(255.0 * rand() / RAND_MAX);
}
typedef struct {
char *ext;
int type;
@ -146,6 +220,8 @@ int track_number = 1;
mm_io_c *out;
bitvalue_c seguid_prev(128), seguid_current(128), seguid_next(128);
file_type_t file_types[] =
{{"---", TYPEUNKNOWN, "<unknown>"},
{"demultiplexers:", -1, ""},
@ -509,7 +585,7 @@ static void parse_split(const char *arg) {
split_by_time = false;
}
static void render_headers(mm_io_c *out) {
static void render_headers(mm_io_c *out, bool last_file, bool first_file) {
EbmlHead head;
int i;
@ -539,6 +615,31 @@ static void render_headers(mm_io_c *out) {
cstr_to_UTFstring(VERSIONINFO);
GetChild<KaxDateUTC>(*kax_infos).SetEpochDate(time(NULL));
// Generate the segment UIDs.
if (first_file) {
seguid_current.generate_random();
if (!last_file)
seguid_next.generate_random();
} else {
seguid_prev = seguid_current;
seguid_current = seguid_next;
if (!last_file)
seguid_next.generate_random();
}
// Set the segment UIDs.
KaxSegmentUID &kax_seguid = GetChild<KaxSegmentUID>(*kax_infos);
kax_seguid.CopyBuffer(seguid_current.data(), 128 / 8);
if (!first_file) {
KaxPrevUID &kax_prevuid = GetChild<KaxPrevUID>(*kax_infos);
kax_prevuid.CopyBuffer(seguid_prev.data(), 128 / 8);
}
if (!last_file) {
KaxNextUID &kax_nextuid = GetChild<KaxNextUID>(*kax_infos);
kax_nextuid.CopyBuffer(seguid_next.data(), 128 / 8);
}
kax_segment->WriteHead(*out, 5);
// Reserve some space for the meta seek stuff.
@ -618,7 +719,8 @@ static void parse_args(int argc, char **argv) {
}
if (outfile == NULL) {
fprintf(stderr, "Error: no output files given.\n");
fprintf(stderr, "Error: no output file given.\n\n");
usage();
exit(1);
}
@ -1196,13 +1298,16 @@ string create_output_name() {
return s;
}
void create_next_output_file() {
void create_next_output_file(bool last_file, bool first_file) {
string this_outfile;
kax_segment = new KaxSegment();
kax_cues = new KaxCues();
kax_cues->SetGlobalTimecodeScale(TIMECODE_SCALE);
fprintf(stdout, "createnext: last: %s, first: %s\n", last_file ? "true" :
"false", first_file ? "true" : "false");
if (pass == 1) {
// Open the a dummy file.
try {
@ -1213,7 +1318,7 @@ void create_next_output_file() {
}
cluster_helper->set_output(out);
render_headers(out);
render_headers(out, last_file, first_file);
return;
}
@ -1235,7 +1340,7 @@ void create_next_output_file() {
fprintf(stdout, "Opened '%s\' for writing.\n", this_outfile.c_str());
cluster_helper->set_output(out);
render_headers(out);
render_headers(out, last_file, first_file);
file_num++;
}
@ -1362,8 +1467,6 @@ void main_loop() {
}
}
extern vector<splitpoint_t *>splitpoints;
int main(int argc, char **argv) {
int i;
@ -1380,15 +1483,15 @@ int main(int argc, char **argv) {
create_readers();
pass = 1;
create_next_output_file();
create_next_output_file(true, true);
main_loop();
finish_file();
fprintf(stdout, "\nPass 2: merging the files. This will take even longer."
"\n\n");
for (i = 0; i < splitpoints.size(); i++) {
splitpoint_t *sp = splitpoints[i];
for (i = 0; i < cluster_helper_c::splitpoints.size(); i++) {
splitpoint_t *sp = cluster_helper_c::splitpoints[i];
fprintf(stdout, "%d: tc %lld, fpos %lld + cues %lld = %lld, pn: %lld\n",
i, sp->timecode, sp->filepos, sp->cues_size,
sp->filepos + sp->cues_size, sp->packet_num);
@ -1399,10 +1502,12 @@ int main(int argc, char **argv) {
init_globals();
cluster_helper = new cluster_helper_c();
cluster_helper->find_next_splitpoint();
create_readers();
pass = 2;
create_next_output_file();
create_next_output_file(cluster_helper->get_next_splitpoint() >=
cluster_helper_c::splitpoints.size(), true);
main_loop();
finish_file();
@ -1411,7 +1516,7 @@ int main(int argc, char **argv) {
create_readers();
pass = 0;
create_next_output_file();
create_next_output_file(true, true);
main_loop();
finish_file();
}

View File

@ -13,7 +13,7 @@
/*!
\file
\version \$Id: mkvmerge.h,v 1.15 2003/06/08 16:14:05 mosu Exp $
\version \$Id: mkvmerge.h,v 1.16 2003/06/08 18:59:43 mosu Exp $
\brief definition of global variables found in mkvmerge.cpp
\author Moritz Bunkus <moritz@bunkus.org>
*/
@ -47,7 +47,7 @@ extern bool no_lacing;
void add_packetizer(generic_packetizer_c *packetizer);
void create_next_output_file();
void create_next_output_file(bool last_file = false, bool first_file = false);
void finish_file();
string create_output_name();