Implementing references. First step. Not working.

This commit is contained in:
Moritz Bunkus 2003-02-27 09:35:55 +00:00
parent 43e9b3d1d7
commit 244b5bfd2d
8 changed files with 203 additions and 88 deletions

View File

@ -13,7 +13,7 @@
/*!
\file
\version \$Id: mkvmerge.cpp,v 1.16 2003/02/26 08:59:54 mosu Exp $
\version \$Id: mkvmerge.cpp,v 1.17 2003/02/27 09:35:55 mosu Exp $
\brief command line parameter parsing, looping, output handling
\author Moritz Bunkus <moritz @ bunkus.org>
*/
@ -85,17 +85,18 @@ typedef struct filelist_tag {
char *outfile = NULL;
filelist_t *input= NULL;
int max_blocks_per_cluster = 65535;
int max_ms_per_cluster = 5000;
int max_ms_per_cluster = 1000;
float video_fps = -1.0;
packet_t **packet_queue = NULL;
int num_packets_in_packetq = 0;
KaxSegment kax_segment;
KaxTracks *kax_tracks;
KaxTrackEntry *kax_last_entry;
int track_number = 1;
cluster_helper_c *cluster_helper = NULL;
KaxSegment kax_segment;
KaxTracks *kax_tracks;
KaxTrackEntry *kax_last_entry;
int track_number = 1;
StdIOCallback *out;
@ -409,7 +410,6 @@ static void parse_args(int argc, char **argv) {
audio_sync_t async;
range_t range;
char *fourcc, *s;
// vorbis_comment *chapters;
noaudio = 0;
novideo = 0;
@ -421,7 +421,6 @@ static void parse_args(int argc, char **argv) {
async.displacement = 0;
async.linear = 1.0;
fourcc = NULL;
// chapters = NULL;
for (i = 1; i < argc; i++)
if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version")) {
@ -736,70 +735,52 @@ static void parse_args(int argc, char **argv) {
}*/
}
static void add_packet_to_packetq(packet_t *pack) {
packet_queue = (packet_t **)realloc(packet_queue, sizeof(packet_t *) *
(num_packets_in_packetq + 1));
if (packet_queue == NULL)
die("realloc");
packet_queue[num_packets_in_packetq] = pack;
num_packets_in_packetq++;
}
static void clear_packetq() {
int i;
packet_t *p;
for (i = 0; i < num_packets_in_packetq; i++) {
p = packet_queue[i];
if (p != NULL) {
free(p->data);
delete p->data_buffer;
free(p);
}
}
num_packets_in_packetq = 0;
free(packet_queue);
packet_queue = NULL;
}
static void write_packetq() {
KaxCues dummy_cues;
KaxCluster cluster;
KaxBlockGroup *last_group = NULL;
int i;
KaxCluster *cluster;
int i, num_packets;
u_int64_t cluster_timecode;
KaxClusterTimecode &timecode = GetChild<KaxClusterTimecode>(cluster);
*(static_cast<EbmlUInteger *>(&timecode)) = packet_queue[0]->timestamp;
cluster = cluster_helper->get_cluster();
cluster_timecode = cluster_helper->get_timecode();
num_packets = cluster_helper->get_packet_count();
for (i = 0; i < num_packets_in_packetq; i++) {
for (i = 0; i < num_packets; i++) {
packet_t *pack;
pack = packet_queue[i];
pack = cluster_helper->get_packet(i);
if (last_group == NULL)
pack->group = &GetChild<KaxBlockGroup>(cluster);
pack->group = &GetChild<KaxBlockGroup>(*cluster);
else
pack->group = &GetNextChild<KaxBlockGroup>(cluster, *last_group);
pack->group = &GetNextChild<KaxBlockGroup>(*cluster, *last_group);
last_group = pack->group;
pack->block = &GetChild<KaxBlock>(*pack->group);
pack->data_buffer = new DataBuffer((binary *)pack->data, pack->length);
KaxTrackEntry &track_entry =
static_cast<KaxTrackEntry &>(*pack->source->track_entry);
pack->block->AddFrame(track_entry,
pack->timestamp - packet_queue[0]->timestamp,
pack->block->AddFrame(track_entry, pack->timestamp - cluster_timecode,
*pack->data_buffer);
pack->source->added_packet_to_cluster(pack, cluster_helper);
}
cluster.Render(static_cast<StdIOCallback &>(*out), dummy_cues);
clear_packetq();
cluster->Render(static_cast<StdIOCallback &>(*out), dummy_cues);
cluster_helper->release();
}
static int write_packet(packet_t *pack) {
add_packet_to_packetq(pack);
u_int64_t timecode;
if (((pack->timestamp - packet_queue[0]->timestamp) > max_ms_per_cluster) ||
if (cluster_helper == NULL)
cluster_helper = new cluster_helper_c();
cluster_helper->add_packet(pack);
timecode = cluster_helper->get_timecode();
if (((pack->timestamp - timecode) > max_ms_per_cluster) ||
(num_packets_in_packetq > max_blocks_per_cluster))
write_packetq();

View File

@ -13,7 +13,7 @@
/*!
\file
\version \$Id: p_ac3.cpp,v 1.2 2003/02/23 23:23:10 mosu Exp $
\version \$Id: p_ac3.cpp,v 1.3 2003/02/27 09:35:55 mosu Exp $
\brief AC3 output module
\author Moritz Bunkus <moritz @ bunkus.org>
*/
@ -183,7 +183,8 @@ void ac3_packetizer_c::set_header() {
static_cast<KaxTrackEntry &>(*kax_last_entry));
kax_last_entry = track_entry;
serialno = track_number++;
if (serialno == -1)
serialno = track_number++;
KaxTrackNumber &tnumber =
GetChild<KaxTrackNumber>(static_cast<KaxTrackEntry &>(*track_entry));
*(static_cast<EbmlUInteger *>(&tnumber)) = serialno;

View File

@ -13,7 +13,7 @@
/*!
\file
\version \$Id: p_mp3.cpp,v 1.3 2003/02/19 09:31:24 mosu Exp $
\version \$Id: p_mp3.cpp,v 1.4 2003/02/27 09:35:55 mosu Exp $
\brief MP3 output module
\author Moritz Bunkus <moritz @ bunkus.org>
*/
@ -172,7 +172,8 @@ void mp3_packetizer_c::set_header() {
static_cast<KaxTrackEntry &>(*kax_last_entry));
kax_last_entry = track_entry;
serialno = track_number++;
if (serialno == -1)
serialno = track_number++;
KaxTrackNumber &tnumber =
GetChild<KaxTrackNumber>(static_cast<KaxTrackEntry &>(*track_entry));
*(static_cast<EbmlUInteger *>(&tnumber)) = serialno;

View File

@ -13,7 +13,7 @@
/*!
\file
\version \$Id: p_video.cpp,v 1.3 2003/02/25 14:24:43 mosu Exp $
\version \$Id: p_video.cpp,v 1.4 2003/02/27 09:35:55 mosu Exp $
\brief video output module
\author Moritz Bunkus <moritz @ bunkus.org>
*/
@ -58,9 +58,10 @@ video_packetizer_c::video_packetizer_c(void *pr_data, int pd_size,
avi_compat_mode = navi_compat_mode;
frames_output = 0;
avi_compat_mode = 1;
last_id = 1;
last_keyframe = NULL;
set_private_data(pr_data, pd_size);
set_header();
// add_index(serialno);
}
void video_packetizer_c::set_header() {
@ -77,7 +78,8 @@ void video_packetizer_c::set_header() {
static_cast<KaxTrackEntry &>(*kax_last_entry));
kax_last_entry = track_entry;
serialno = track_number++;
if (serialno == -1)
serialno = track_number++;
KaxTrackNumber &tnumber =
GetChild<KaxTrackNumber>(static_cast<KaxTrackEntry &>(*track_entry));
*(static_cast<EbmlUInteger *>(&tnumber)) = serialno;
@ -123,7 +125,12 @@ int video_packetizer_c::process(char *buf, int size, int num_frames,
if ((packetno >= range.start) &&
((range.end == 0) || (packetno < range.end))) {
add_packet(buf, size, (u_int64_t)(1000.0 * frames_output / fps), key);
if (key)
last_id = add_packet(buf, size,
(u_int64_t)(1000.0 * frames_output / fps));
else
add_packet(buf, size, (u_int64_t)(1000.0 * frames_output / fps),
last_id);
frames_output += num_frames;
}
packetno++;
@ -135,3 +142,14 @@ video_packetizer_c::~video_packetizer_c() {
if (tempbuf != NULL)
free(tempbuf);
}
void video_packetizer_c::added_packet_to_cluster(packet_t *packet,
cluster_helper_c *helper) {
if (packet->ref == 0) { // this is a keyframe
if (last_helper)
last_helper->release();
last_helper = helper;
last_keyframe = packet;
last_helper->add_ref();
}
}

View File

@ -13,7 +13,7 @@
/*!
\file
\version \$Id: p_video.h,v 1.3 2003/02/26 19:20:26 mosu Exp $
\version \$Id: p_video.h,v 1.4 2003/02/27 09:35:55 mosu Exp $
\brief class definition for the video output module
\author Moritz Bunkus <moritz @ bunkus.org>
*/
@ -25,17 +25,18 @@
#include "queue.h"
class video_packetizer_c: public q_c {
private:
char codec[5];
double fps;
int width, height;
int bpp;
int max_frame_size;
int packetno, frames_output;
char *tempbuf;
int avi_compat_mode;
range_t range;
public:
private:
char codec[5];
double fps;
int width, height, bpp, max_frame_size, packetno;
int frames_output;
char *tempbuf;
int avi_compat_mode;
range_t range;
u_int64_t last_id;
packet_t *last_keyframe;
cluster_helper_c *last_helper;
public:
video_packetizer_c(void *, int, char *, double, int, int, int, int,
audio_sync_t *, range_t *nrange, int) throw (error_c);
virtual ~video_packetizer_c();
@ -43,6 +44,8 @@ class video_packetizer_c: public q_c {
virtual int process(char *buf, int size, int num_frames, int key,
int last_frame);
virtual void set_header();
virtual void added_packet_to_cluster(packet_t *packet,
cluster_helper_c *helper);
};
#endif

View File

@ -13,13 +13,16 @@
/*!
\file
\version \$Id: pr_generic.cpp,v 1.2 2003/02/24 12:31:17 mosu Exp $
\version \$Id: pr_generic.cpp,v 1.3 2003/02/27 09:35:55 mosu Exp $
\brief functions common for all readers/packetizers
\author Moritz Bunkus <moritz @ bunkus.org>
*/
#include <malloc.h>
#include "KaxCluster.h"
#include "KaxClusterData.h"
#include "pr_generic.h"
generic_packetizer_c::generic_packetizer_c() {
@ -44,6 +47,10 @@ void generic_packetizer_c::set_private_data(void *data, int size) {
private_data_size = size;
}
void generic_packetizer_c::added_packet_to_cluster(packet_t *,
cluster_helper_c *) {
}
//--------------------------------------------------------------------
generic_reader_c::generic_reader_c() {
@ -51,3 +58,83 @@ generic_reader_c::generic_reader_c() {
generic_reader_c::~generic_reader_c() {
}
//--------------------------------------------------------------------
cluster_helper_c::cluster_helper_c(KaxCluster *ncluster) {
num_packets = 0;
packet_q = NULL;
refcount = 1;
if (ncluster == NULL)
cluster = new KaxCluster();
else
cluster = ncluster;
}
cluster_helper_c::~cluster_helper_c() {
int i;
if (packet_q) {
for (i = 0; i < num_packets; i++) {
free(packet_q[i]->data);
delete packet_q[i]->data_buffer;
free(packet_q[i]);
}
free(packet_q);
}
if (cluster)
delete cluster;
}
KaxCluster *cluster_helper_c::get_cluster() {
return cluster;
}
KaxCluster &cluster_helper_c::operator *() {
return *cluster;
}
int cluster_helper_c::add_ref() {
refcount++;
return refcount;
}
int cluster_helper_c::release() {
int ref;
refcount--;
ref = refcount;
if (refcount == 0)
delete this;
return ref;
}
void cluster_helper_c::add_packet(packet_t *packet) {
packet_q = (packet_t **)realloc(packet_q, sizeof(packet_t *) *
(num_packets + 1));
if (packet_q == NULL)
die("realloc");
packet_q[num_packets] = packet;
if (num_packets == 0) {
KaxClusterTimecode &timecode = GetChild<KaxClusterTimecode>(*cluster);
*(static_cast<EbmlUInteger *>(&timecode)) = packet->timestamp;
}
num_packets++;
}
u_int64_t cluster_helper_c::get_timecode() {
if (packet_q == NULL)
return 0;
return packet_q[0]->timestamp;
}
packet_t *cluster_helper_c::get_packet(int num) {
if (packet_q == NULL)
return NULL;
if ((num < 0) || (num > num_packets))
return NULL;
return packet_q[num];
}
int cluster_helper_c::get_packet_count() {
return num_packets;
}

View File

@ -13,7 +13,7 @@
/*!
\file
\version \$Id: pr_generic.h,v 1.4 2003/02/26 19:20:26 mosu Exp $
\version \$Id: pr_generic.h,v 1.5 2003/02/27 09:35:55 mosu Exp $
\brief class definition for the generic reader and packetizer
\author Moritz Bunkus <moritz @ bunkus.org>
*/
@ -25,21 +25,44 @@
#include "common.h"
#include "KaxBlock.h"
#include "KaxCluster.h"
#include "KaxTracks.h"
extern LIBMATROSKA_NAMESPACE::KaxTracks *kax_tracks;
extern LIBMATROSKA_NAMESPACE::KaxTrackEntry *kax_last_entry;
using namespace LIBMATROSKA_NAMESPACE;
extern KaxTracks *kax_tracks;
extern KaxTrackEntry *kax_last_entry;
extern int track_number;
struct packet_t;
typedef class cluster_helper_c {
private:
int refcount;
KaxCluster *cluster;
packet_t **packet_q;
int num_packets;
public:
cluster_helper_c(KaxCluster *ncluster = NULL);
virtual ~cluster_helper_c();
KaxCluster *get_cluster();
int add_ref();
void add_packet(packet_t *packet);
u_int64_t get_timecode();
packet_t *get_packet(int num);
int get_packet_count();
int release();
KaxCluster &operator *();
} cluster_helper_c;
typedef class generic_packetizer_c {
protected:
protected:
int serialno;
void *private_data;
int private_data_size;
public:
LIBMATROSKA_NAMESPACE::KaxTrackEntry *track_entry;
public:
KaxTrackEntry *track_entry;
generic_packetizer_c();
virtual ~generic_packetizer_c();
@ -48,10 +71,12 @@ typedef class generic_packetizer_c {
virtual void set_header() = 0;
virtual stamp_t get_smallest_timestamp() = 0;
virtual void set_private_data(void *data, int size);
virtual void added_packet_to_cluster(packet_t *packet,
cluster_helper_c *helper);
} generic_packetizer_c;
typedef class generic_reader_c {
public:
public:
generic_reader_c();
virtual ~generic_reader_c();
virtual int read() = 0;
@ -61,15 +86,14 @@ typedef class generic_reader_c {
} generic_reader_c;
typedef struct packet_t {
LIBMATROSKA_NAMESPACE::DataBuffer *data_buffer;
LIBMATROSKA_NAMESPACE::KaxBlockGroup *group;
LIBMATROSKA_NAMESPACE::KaxBlock *block;
LIBMATROSKA_NAMESPACE::KaxCluster *cluster;
char *data;
int length;
u_int64_t timestamp;
u_int64_t id, ref;
generic_packetizer_c *source;
DataBuffer *data_buffer;
KaxBlockGroup *group;
KaxBlock *block;
KaxCluster *cluster;
char *data;
int length;
u_int64_t timestamp, id, ref;
generic_packetizer_c *source;
} packet_t;
#endif // __PR_GENERIC_H

View File

@ -13,7 +13,7 @@
/*!
\file
\version \$Id: queue.cpp,v 1.4 2003/02/26 19:20:26 mosu Exp $
\version \$Id: queue.cpp,v 1.5 2003/02/27 09:35:55 mosu Exp $
\brief packet queueing class used by every packetizer
\author Moritz Bunkus <moritz @ bunkus.org>
*/
@ -58,7 +58,7 @@ u_int64_t q_c::add_packet(char *data, int length, u_int64_t timestamp,
q_page_t *qpage;
if (data == NULL)
return -1;
return 0;
qpage = (q_page_t *)malloc(sizeof(q_page_t));
if (qpage == NULL)
die("malloc");