mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 11:54:01 +00:00
Implemented support for SegmentUID, PrevUID and NextUID.
This commit is contained in:
parent
efefc4289e
commit
c9e0a7bffb
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
32
mkvinfo.cpp
32
mkvinfo.cpp
@ -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);
|
||||
|
||||
|
131
mkvmerge.cpp
131
mkvmerge.cpp
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user