Moved the packetizer creation out of the c'tors in preparation for a global track re-ordering.

This commit is contained in:
Moritz Bunkus 2004-06-14 07:26:37 +00:00
parent 3bb368ee8a
commit f25917add1
30 changed files with 326 additions and 368 deletions

View File

@ -75,8 +75,6 @@ aac_reader_c::aac_reader_c(track_info_c *nti)
throw (error_c): throw (error_c):
generic_reader_c(nti) { generic_reader_c(nti) {
int adif, i; int adif, i;
aac_header_t aacheader;
generic_packetizer_c *aacpacketizer;
try { try {
mm_io = new mm_io_c(ti->fname, MODE_READ); mm_io = new mm_io_c(ti->fname, MODE_READ);
@ -106,26 +104,11 @@ aac_reader_c::aac_reader_c(track_info_c *nti)
aacheader.profile = AAC_PROFILE_SBR; aacheader.profile = AAC_PROFILE_SBR;
break; break;
} }
if ((aacheader.profile != AAC_PROFILE_SBR) && !identifying)
mxwarn("AAC files may contain HE-AAC / AAC+ / SBR AAC audio. "
"This can NOT be detected automatically. Therefore you have to "
"specifiy '--aac-is-sbr 0' manually for this input file if the "
"file actually contains SBR AAC. The file will be muxed in the "
"WRONG way otherwise. Also read mkvmerge's documentation.\n");
aacpacketizer = new aac_packetizer_c(this, aacheader.id, aacheader.profile,
aacheader.sample_rate,
aacheader.channels, ti,
emphasis_present);
add_packetizer(aacpacketizer);
if (aacheader.profile == AAC_PROFILE_SBR)
aacpacketizer->set_audio_output_sampling_freq(aacheader.sample_rate * 2);
} catch (exception &ex) { } catch (exception &ex) {
throw error_c("aac_reader: Could not open the file."); throw error_c("aac_reader: Could not open the file.");
} }
if (verbose) if (verbose)
mxinfo("Using AAC demultiplexer for %s.\n+-> Using " mxinfo(FMT_FN "Using the AAC demultiplexer.\n", ti->fname);
"AAC output module for audio stream.\n", ti->fname);
} }
aac_reader_c::~aac_reader_c() { aac_reader_c::~aac_reader_c() {
@ -133,6 +116,29 @@ aac_reader_c::~aac_reader_c() {
safefree(chunk); safefree(chunk);
} }
void
aac_reader_c::create_packetizer(int64_t) {
generic_packetizer_c *aacpacketizer;
if (NPTZR() != 0)
return;
if (aacheader.profile != AAC_PROFILE_SBR)
mxwarn("AAC files may contain HE-AAC / AAC+ / SBR AAC audio. "
"This can NOT be detected automatically. Therefore you have to "
"specifiy '--aac-is-sbr 0' manually for this input file if the "
"file actually contains SBR AAC. The file will be muxed in the "
"WRONG way otherwise. Also read mkvmerge's documentation.\n");
aacpacketizer = new aac_packetizer_c(this, aacheader.id, aacheader.profile,
aacheader.sample_rate,
aacheader.channels, ti,
emphasis_present);
add_packetizer(aacpacketizer);
if (aacheader.profile == AAC_PROFILE_SBR)
aacpacketizer->set_audio_output_sampling_freq(aacheader.sample_rate * 2);
mxinfo(FMT_TID "Using the AAC output module.\n", ti->fname, (int64_t)0);
}
// Try to guess if the MPEG4 header contains the emphasis field (2 bits) // Try to guess if the MPEG4 header contains the emphasis field (2 bits)
void void
aac_reader_c::guess_adts_version() { aac_reader_c::guess_adts_version() {

View File

@ -25,10 +25,11 @@
#include <stdio.h> #include <stdio.h>
#include "mm_io.h" #include "aac_common.h"
#include "pr_generic.h"
#include "common.h" #include "common.h"
#include "error.h" #include "error.h"
#include "mm_io.h"
#include "pr_generic.h"
class aac_reader_c: public generic_reader_c { class aac_reader_c: public generic_reader_c {
private: private:
@ -36,6 +37,7 @@ private:
mm_io_c *mm_io; mm_io_c *mm_io;
int64_t bytes_processed, size; int64_t bytes_processed, size;
bool emphasis_present; bool emphasis_present;
aac_header_t aacheader;
public: public:
aac_reader_c(track_info_c *nti) throw (error_c); aac_reader_c(track_info_c *nti) throw (error_c);
@ -45,6 +47,7 @@ public:
virtual int display_priority(); virtual int display_priority();
virtual void display_progress(bool final = false); virtual void display_progress(bool final = false);
virtual void identify(); virtual void identify();
virtual void create_packetizer(int64_t id);
static int probe_file(mm_io_c *mm_io, int64_t size); static int probe_file(mm_io_c *mm_io, int64_t size);

View File

@ -68,7 +68,6 @@ ac3_reader_c::ac3_reader_c(track_info_c *nti)
throw (error_c): throw (error_c):
generic_reader_c(nti) { generic_reader_c(nti) {
int pos; int pos;
ac3_header_t ac3header;
try { try {
mm_io = new mm_io_c(ti->fname, MODE_READ); mm_io = new mm_io_c(ti->fname, MODE_READ);
@ -88,11 +87,8 @@ ac3_reader_c::ac3_reader_c(track_info_c *nti)
"4096 bytes.\n"); "4096 bytes.\n");
bytes_processed = 0; bytes_processed = 0;
ti->id = 0; // ID for this track. ti->id = 0; // ID for this track.
add_packetizer(new ac3_packetizer_c(this, ac3header.sample_rate,
ac3header.channels, ac3header.bsid, ti));
if (verbose) if (verbose)
mxinfo("Using AC3 demultiplexer for %s.\n+-> Using " mxinfo(FMT_FN "Using the AC3 demultiplexer.\n", ti->fname);
"AC3 output module for audio stream.\n", ti->fname);
} }
ac3_reader_c::~ac3_reader_c() { ac3_reader_c::~ac3_reader_c() {
@ -100,6 +96,15 @@ ac3_reader_c::~ac3_reader_c() {
safefree(chunk); safefree(chunk);
} }
void
ac3_reader_c::create_packetizer(int64_t) {
if (NPTZR() != 0)
return;
add_packetizer(new ac3_packetizer_c(this, ac3header.sample_rate,
ac3header.channels, ac3header.bsid, ti));
mxinfo(FMT_TID "Using the AC3 output module.\n", ti->fname, (int64_t)0);
}
int int
ac3_reader_c::read(generic_packetizer_c *) { ac3_reader_c::read(generic_packetizer_c *) {
int nread; int nread;

View File

@ -25,16 +25,18 @@
#include <stdio.h> #include <stdio.h>
#include "mm_io.h" #include "ac3_common.h"
#include "pr_generic.h"
#include "common.h" #include "common.h"
#include "error.h" #include "error.h"
#include "mm_io.h"
#include "pr_generic.h"
class ac3_reader_c: public generic_reader_c { class ac3_reader_c: public generic_reader_c {
private: private:
unsigned char *chunk; unsigned char *chunk;
mm_io_c *mm_io; mm_io_c *mm_io;
int64_t bytes_processed, size; int64_t bytes_processed, size;
ac3_header_t ac3header;
public: public:
ac3_reader_c(track_info_c *nti) throw (error_c); ac3_reader_c(track_info_c *nti) throw (error_c);
@ -44,6 +46,7 @@ public:
virtual int display_priority(); virtual int display_priority();
virtual void display_progress(bool final = false); virtual void display_progress(bool final = false);
virtual void identify(); virtual void identify();
virtual void create_packetizer(int64_t id);
static int probe_file(mm_io_c *mm_io, int64_t size); static int probe_file(mm_io_c *mm_io, int64_t size);
}; };

View File

@ -82,7 +82,7 @@ avi_reader_c::avi_reader_c(track_info_c *nti)
throw (error_c): throw (error_c):
generic_reader_c(nti) { generic_reader_c(nti) {
long fsize, i; long fsize, i;
int64_t size, bps; int64_t size;
vector<avi_demuxer_t>::iterator demuxer; vector<avi_demuxer_t>::iterator demuxer;
try { try {
@ -95,7 +95,7 @@ avi_reader_c::avi_reader_c(track_info_c *nti)
} }
if (verbose) if (verbose)
mxinfo("Using AVI demultiplexer for %s. Opening file. This " mxinfo(FMT_FN "Using the AVI demultiplexer. Opening file. This "
"may take some time depending on the file's size.\n", ti->fname); "may take some time depending on the file's size.\n", ti->fname);
fsize = 0; fsize = 0;
@ -121,15 +121,6 @@ avi_reader_c::avi_reader_c(track_info_c *nti)
fsize = AVI_frame_size(avi, i); fsize = AVI_frame_size(avi, i);
max_frame_size = fsize; max_frame_size = fsize;
create_packetizers();
foreach(demuxer, ademuxers) {
bps = demuxer->samples_per_second * demuxer->channels *
demuxer->bits_per_sample / 8;
if (bps > fsize)
fsize = bps;
}
if (video_fps < 0) if (video_fps < 0)
video_fps = fps; video_fps = fps;
chunk_size = max_frame_size < MIN_CHUNK_SIZE ? MIN_CHUNK_SIZE : chunk_size = max_frame_size < MIN_CHUNK_SIZE ? MIN_CHUNK_SIZE :
@ -189,7 +180,8 @@ avi_reader_c::create_packetizer(int64_t tid) {
AVI_video_height(avi), AVI_video_height(avi),
false, ti)); false, ti));
if (verbose) if (verbose)
mxinfo("+-> Using video output module for video track ID 0.\n"); mxinfo(FMT_TID "Using the video output module for the video track.\n",
ti->fname, (int64_t)0);
} }
if (tid == 0) if (tid == 0)
return; return;
@ -200,7 +192,8 @@ avi_reader_c::create_packetizer(int64_t tid) {
void void
avi_reader_c::create_packetizers() { avi_reader_c::create_packetizers() {
uint32_t i; uint32_t i, bps;
vector<avi_demuxer_t>::iterator demuxer;
for (i = 0; i < ti->track_order->size(); i++) for (i = 0; i < ti->track_order->size(); i++)
create_packetizer((*ti->track_order)[i]); create_packetizer((*ti->track_order)[i]);
@ -209,6 +202,15 @@ avi_reader_c::create_packetizers() {
for (i = 0; i < AVI_audio_tracks(avi); i++) for (i = 0; i < AVI_audio_tracks(avi); i++)
create_packetizer(i + 1); create_packetizer(i + 1);
foreach(demuxer, ademuxers) {
bps = demuxer->samples_per_second * demuxer->channels *
demuxer->bits_per_sample / 8;
if (bps > chunk_size) {
chunk_size = bps;
chunk = (unsigned char *)saferealloc(chunk, chunk_size);
}
}
} }
// {{{ FUNCTION avi_reader_c::add_audio_demuxer // {{{ FUNCTION avi_reader_c::add_audio_demuxer
@ -257,23 +259,23 @@ avi_reader_c::add_audio_demuxer(int aid) {
switch(audio_format) { switch(audio_format) {
case 0x0001: // raw PCM audio case 0x0001: // raw PCM audio
if (verbose) if (verbose)
mxinfo("+-> Using the PCM output module for audio track ID %d.\n", mxinfo(FMT_TID "Using the PCM output module.\n", ti->fname,
aid + 1); (int64_t)aid + 1);
packetizer = new pcm_packetizer_c(this, demuxer.samples_per_second, packetizer = new pcm_packetizer_c(this, demuxer.samples_per_second,
demuxer.channels, demuxer.channels,
demuxer.bits_per_sample, ti); demuxer.bits_per_sample, ti);
break; break;
case 0x0055: // MP3 case 0x0055: // MP3
if (verbose) if (verbose)
mxinfo("+-> Using the MPEG audio output module for audio track ID " mxinfo(FMT_TID "Using the MPEG audio output module.\n", ti->fname,
"%d.\n", aid + 1); (int64_t)aid + 1);
packetizer = new mp3_packetizer_c(this, demuxer.samples_per_second, packetizer = new mp3_packetizer_c(this, demuxer.samples_per_second,
demuxer.channels, ti); demuxer.channels, ti);
break; break;
case 0x2000: // AC3 case 0x2000: // AC3
if (verbose) if (verbose)
mxinfo("+-> Using the AC3 output module for audio track ID %d.\n", mxinfo(FMT_TID "Using the AC3 output module.\n", ti->fname,
aid + 1); (int64_t)aid + 1);
packetizer = new ac3_packetizer_c(this, demuxer.samples_per_second, packetizer = new ac3_packetizer_c(this, demuxer.samples_per_second,
demuxer.channels, 0, ti); demuxer.channels, 0, ti);
break; break;
@ -282,21 +284,22 @@ avi_reader_c::add_audio_demuxer(int aid) {
bool is_sbr; bool is_sbr;
if ((ti->private_size != 2) && (ti->private_size != 5)) if ((ti->private_size != 2) && (ti->private_size != 5))
mxerror("The AAC track %d does not contain valid headers. The extra " mxerror(FMT_TID "This AAC track does not contain valid headers. The "
"header size is %d bytes, expected were 2 or 5 bytes.\n", "extra header size is %d bytes, expected were 2 or 5 bytes.\n",
aid + 1, ti->private_size); ti->fname, (int64_t)aid + 1, ti->private_size);
if (!parse_aac_data(ti->private_data, ti->private_size, profile, if (!parse_aac_data(ti->private_data, ti->private_size, profile,
channels, sample_rate, output_sample_rate, channels, sample_rate, output_sample_rate,
is_sbr)) is_sbr))
mxerror("The AAC track %d does not contain valid headers. Could not " mxerror(FMT_TID "This AAC track does not contain valid headers. Could "
"parse the AAC information.\n", aid + 1); "not parse the AAC information.\n", ti->fname, (int64_t)aid +
1);
if (is_sbr) if (is_sbr)
profile = AAC_PROFILE_SBR; profile = AAC_PROFILE_SBR;
demuxer.samples_per_second = sample_rate; demuxer.samples_per_second = sample_rate;
demuxer.channels = channels; demuxer.channels = channels;
if (verbose) if (verbose)
mxinfo("+-> Using the AAC output module for audio track ID %d.\n", mxinfo(FMT_TID "Using the AAC audio output module.\n", ti->fname,
aid + 1); (int64_t)aid + 1);
packetizer = new aac_packetizer_c(this, AAC_ID_MPEG4, profile, packetizer = new aac_packetizer_c(this, AAC_ID_MPEG4, profile,
demuxer.samples_per_second, demuxer.samples_per_second,
demuxer.channels, ti, false, true); demuxer.channels, ti, false, true);
@ -305,8 +308,8 @@ avi_reader_c::add_audio_demuxer(int aid) {
break; break;
} }
default: default:
mxerror("Unknown/unsupported audio format 0x%04x for audio track ID " mxerror(FMT_TID "Unknown/unsupported audio format 0x%04x for this audio "
"%d.\n", audio_format, aid + 1); "track.\n", ti->fname, (int64_t)aid + 1, audio_format);
} }
demuxer.ptzr = add_packetizer(packetizer); demuxer.ptzr = add_packetizer(packetizer);

View File

@ -68,14 +68,14 @@ public:
virtual void display_progress(bool final = false); virtual void display_progress(bool final = false);
virtual void set_headers(); virtual void set_headers();
virtual void identify(); virtual void identify();
virtual void create_packetizers();
virtual void create_packetizer(int64_t tid);
static int probe_file(mm_io_c *mm_io, int64_t size); static int probe_file(mm_io_c *mm_io, int64_t size);
protected: protected:
virtual void add_audio_demuxer(int aid); virtual void add_audio_demuxer(int aid);
virtual int is_keyframe(unsigned char *data, long size, int suggestion); virtual int is_keyframe(unsigned char *data, long size, int suggestion);
virtual void create_packetizers();
virtual void create_packetizer(int64_t tid);
}; };
#endif // __R_AVI_H #endif // __R_AVI_H

View File

@ -59,7 +59,6 @@ dts_reader_c::dts_reader_c(track_info_c *nti)
throw (error_c): throw (error_c):
generic_reader_c(nti) { generic_reader_c(nti) {
int pos; int pos;
dts_header_t dtsheader;
try { try {
mm_io = new mm_io_c(ti->fname, MODE_READ); mm_io = new mm_io_c(ti->fname, MODE_READ);
@ -81,14 +80,9 @@ dts_reader_c::dts_reader_c(track_info_c *nti)
"max_dts_packet_size bytes.\n"); "max_dts_packet_size bytes.\n");
bytes_processed = 0; bytes_processed = 0;
ti->id = 0; // ID for this track. ti->id = 0; // ID for this track.
add_packetizer(new dts_packetizer_c(this, dtsheader, ti));
if (verbose) { if (verbose)
mxinfo("Using DTS demultiplexer for %s.\n+-> Using " mxinfo(FMT_FN "Using the DTS demultiplexer.\n", ti->fname);
"DTS output module for audio stream.\n", ti->fname);
print_dts_header(&dtsheader);
}
} }
dts_reader_c::~dts_reader_c() { dts_reader_c::~dts_reader_c() {
@ -96,6 +90,15 @@ dts_reader_c::~dts_reader_c() {
safefree(chunk); safefree(chunk);
} }
void
dts_reader_c::create_packetizer(int64_t) {
if (NPTZR() != 0)
return;
add_packetizer(new dts_packetizer_c(this, dtsheader, ti));
mxinfo(FMT_TID "Using the DTS output module.\n", ti->fname, (int64_t)0);
print_dts_header(&dtsheader);
}
int int
dts_reader_c::read(generic_packetizer_c *) { dts_reader_c::read(generic_packetizer_c *) {
int nread; int nread;

View File

@ -25,16 +25,18 @@
#include <stdio.h> #include <stdio.h>
#include "common.h"
#include "dts_common.h"
#include "error.h"
#include "mm_io.h" #include "mm_io.h"
#include "pr_generic.h" #include "pr_generic.h"
#include "common.h"
#include "error.h"
class dts_reader_c: public generic_reader_c { class dts_reader_c: public generic_reader_c {
private: private:
unsigned char *chunk; unsigned char *chunk;
mm_io_c *mm_io; mm_io_c *mm_io;
int64_t bytes_processed, size; int64_t bytes_processed, size;
dts_header_t dtsheader;
public: public:
dts_reader_c(track_info_c *nti) throw (error_c); dts_reader_c(track_info_c *nti) throw (error_c);
@ -44,6 +46,7 @@ public:
virtual int display_priority(); virtual int display_priority();
virtual void display_progress(bool final = false); virtual void display_progress(bool final = false);
virtual void identify(); virtual void identify();
virtual void create_packetizer(int64_t id);
static int probe_file(mm_io_c *mm_io, int64_t size); static int probe_file(mm_io_c *mm_io, int64_t size);
}; };

View File

@ -108,12 +108,13 @@ flac_reader_c::flac_reader_c(track_info_c *nti)
return; return;
} }
if (verbose) if (verbose)
mxinfo("Using the FLAC demultiplexer for %s.\n", ti->fname); mxinfo(FMT_FN "Using the FLAC demultiplexer.\n", ti->fname);
read_buffer = (unsigned char *)safemalloc(BUFFER_SIZE); read_buffer = (unsigned char *)safemalloc(BUFFER_SIZE);
if (!parse_file()) if (!parse_file())
throw error_c(FPFX "Could not read all header packets."); throw error_c(FPFX "Could not read all header packets.");
header = NULL;
try { try {
block_size = 0; block_size = 0;
for (current_block = blocks.begin(); for (current_block = blocks.begin();
@ -131,49 +132,34 @@ flac_reader_c::flac_reader_c(track_info_c *nti)
mxerror(FPFX "Could not read a header packet.\n"); mxerror(FPFX "Could not read a header packet.\n");
block_size += current_block->len; block_size += current_block->len;
} }
add_packetizer(new flac_packetizer_c(this, sample_rate, channels, header = buf;
bits_per_sample, buf, block_size, header_size = block_size;
ti));
safefree(buf);
} catch (error_c &error) { } catch (error_c &error) {
mxerror(FPFX "could not initialize the FLAC packetizer.\n"); mxerror(FPFX "could not initialize the FLAC packetizer.\n");
} }
if (verbose)
mxinfo("+-> Using the FLAC output module.\n");
} }
flac_reader_c::~flac_reader_c() { flac_reader_c::~flac_reader_c() {
delete file; delete file;
safefree(read_buffer); safefree(read_buffer);
safefree(header);
}
void
flac_reader_c::create_packetizer(int64_t) {
if (NPTZR() != 0)
return;
add_packetizer(new flac_packetizer_c(this, sample_rate, channels,
bits_per_sample, header, header_size,
ti));
mxinfo(FMT_TID "Using the FLAC output module.\n", ti->fname, (int64_t)0);
} }
bool bool
flac_reader_c::parse_file() { flac_reader_c::parse_file() {
FLAC__StreamDecoder *decoder; FLAC__StreamDecoder *decoder;
int result; int result;
// , offset, pd_size;
// uint32_t i;
// unsigned char *pass_data;
// flac_block_t block;
// if ((pass == 2) &&
// ((pass_data = retrieve_pass_data(ti, pd_size)) != NULL)) {
// offset = 20;
// metadata_parsed = get_uint32(&pass_data[0]);
// channels = get_uint32(&pass_data[4]);
// sample_rate = get_uint32(&pass_data[8]);
// bits_per_sample = get_uint32(&pass_data[12]);
// pd_size = get_uint32(&pass_data[16]);
// for (i = 0; i < pd_size; i++) {
// memcpy(&block, &pass_data[offset + i * sizeof(flac_block_t)],
// sizeof(flac_block_t));
// blocks.push_back(block);
// }
// safefree(pass_data);
// return metadata_parsed;
// }
done = false; done = false;
file->setFilePointer(0); file->setFilePointer(0);
@ -217,23 +203,6 @@ flac_reader_c::parse_file() {
blocks[0].len -= 4; blocks[0].len -= 4;
blocks[0].filepos = 4; blocks[0].filepos = 4;
// if (pass == 1) {
// offset = 20;
// pass_data = (unsigned char *)safemalloc(offset + blocks.size() *
// sizeof(flac_block_t));
// put_uint32(&pass_data[0], (uint32_t)metadata_parsed);
// put_uint32(&pass_data[4], channels);
// put_uint32(&pass_data[8], sample_rate);
// put_uint32(&pass_data[12], bits_per_sample);
// put_uint32(&pass_data[16], blocks.size());
// for (i = 0; i < blocks.size(); i++)
// memcpy(&pass_data[offset + i * sizeof(flac_block_t)], &blocks[i],
// sizeof(flac_block_t));
// set_pass_data(ti, pass_data, offset + blocks.size() *
// sizeof(flac_block_t));
// safefree(pass_data);
// }
return metadata_parsed; return metadata_parsed;
} }

View File

@ -47,6 +47,8 @@ private:
int pos, size, channels, sample_rate, bits_per_sample; int pos, size, channels, sample_rate, bits_per_sample;
bool metadata_parsed, done; bool metadata_parsed, done;
int64_t samples, packet_start, file_size, old_progress; int64_t samples, packet_start, file_size, old_progress;
unsigned char *header;
int header_size;
vector<flac_block_t> blocks; vector<flac_block_t> blocks;
vector<flac_block_t>::iterator current_block; vector<flac_block_t>::iterator current_block;
@ -56,6 +58,7 @@ public:
virtual int read(generic_packetizer_c *ptzr); virtual int read(generic_packetizer_c *ptzr);
virtual void identify(); virtual void identify();
virtual void create_packetizer(int64_t id);
virtual int display_priority(); virtual int display_priority();
virtual void display_progress(bool final = false); virtual void display_progress(bool final = false);

View File

@ -140,8 +140,8 @@ kax_reader_c::kax_reader_c(track_info_c *nti)
if (!read_headers()) if (!read_headers())
throw error_c(PFX "Failed to read the headers."); throw error_c(PFX "Failed to read the headers.");
if (verbose)
create_packetizers(); mxinfo(FMT_FN "Using the Matroska demultiplexer.\n", ti->fname);
} }
// }}} // }}}
@ -1375,8 +1375,9 @@ kax_reader_c::init_passthrough_packetizer(kax_track_t *t) {
passthrough_packetizer_c *ptzr; passthrough_packetizer_c *ptzr;
track_info_c *nti; track_info_c *nti;
mxverb(1, "+-> Using the passthrough output module for the %s " mxinfo(FMT_TID "Using the passthrough output module for this %s "
"track with the ID %u.\n", MAP_TRACK_TYPE_STRING(t->type), t->tnum); "track.\n", ti->fname, (int64_t)t->tnum,
MAP_TRACK_TYPE_STRING(t->type));
nti = new track_info_c(*ti); nti = new track_info_c(*ti);
nti->id = t->tnum; nti->id = t->tnum;
@ -1479,8 +1480,8 @@ kax_reader_c::create_packetizer(int64_t tid) {
!strcmp(t->codec_id, MKV_V_MSCOMP) || !strcmp(t->codec_id, MKV_V_MSCOMP) ||
!strncmp(t->codec_id, "V_REAL", 6) || !strncmp(t->codec_id, "V_REAL", 6) ||
!strcmp(t->codec_id, MKV_V_QUICKTIME)) { !strcmp(t->codec_id, MKV_V_QUICKTIME)) {
mxverb(1, "+-> Using video output module for track ID %u.\n", mxinfo(FMT_TID "Using the video output module.\n", ti->fname,
t->tnum); (int64_t)t->tnum);
t->ptzr = add_packetizer(new video_packetizer_c(this, t->codec_id, t->ptzr = add_packetizer(new video_packetizer_c(this, t->codec_id,
t->v_frate, t->v_frate,
t->v_width, t->v_width,
@ -1502,16 +1503,14 @@ kax_reader_c::create_packetizer(int64_t tid) {
t->ptzr = t->ptzr =
add_packetizer(new pcm_packetizer_c(this, (int32_t)t->a_sfreq, add_packetizer(new pcm_packetizer_c(this, (int32_t)t->a_sfreq,
t->a_channels, t->a_bps, nti)); t->a_channels, t->a_bps, nti));
if (verbose) mxinfo(FMT_TID "Using the PCM output module.\n", ti->fname,
mxinfo("+-> Using the PCM output module for track ID %u.\n", (int64_t)t->tnum);
t->tnum);
} else if (t->a_formattag == 0x0055) { } else if (t->a_formattag == 0x0055) {
t->ptzr = t->ptzr =
add_packetizer(new mp3_packetizer_c(this, (int32_t)t->a_sfreq, add_packetizer(new mp3_packetizer_c(this, (int32_t)t->a_sfreq,
t->a_channels, nti)); t->a_channels, nti));
if (verbose) mxinfo(FMT_TID "Using the MPEG audio output module.\n",
mxinfo("+-> Using the MPEG audio output module for track ID %u." ti->fname, (int64_t)t->tnum);
"\n", t->tnum);
} else if (t->a_formattag == 0x2000) { } else if (t->a_formattag == 0x2000) {
int bsid; int bsid;
@ -1524,9 +1523,8 @@ kax_reader_c::create_packetizer(int64_t tid) {
t->ptzr = t->ptzr =
add_packetizer(new ac3_packetizer_c(this, (int32_t)t->a_sfreq, add_packetizer(new ac3_packetizer_c(this, (int32_t)t->a_sfreq,
t->a_channels, bsid, nti)); t->a_channels, bsid, nti));
if (verbose) mxinfo(FMT_TID "Using the AC3 output module.\n", ti->fname,
mxinfo("+-> Using the AC3 output module for track ID %u.\n", (int64_t)t->tnum);
t->tnum);
} else if (t->a_formattag == 0x2001) { } else if (t->a_formattag == 0x2001) {
mxerror("Reading DTS from Matroska not implemented yet," mxerror("Reading DTS from Matroska not implemented yet,"
"cannot we get a complete DTS_Header here for construction" "cannot we get a complete DTS_Header here for construction"
@ -1545,9 +1543,8 @@ kax_reader_c::create_packetizer(int64_t tid) {
t->header_sizes[1], t->header_sizes[1],
t->headers[2], t->headers[2],
t->header_sizes[2], nti)); t->header_sizes[2], nti));
if (verbose) mxinfo(FMT_TID "Using the Vorbis output module.\n", ti->fname,
mxinfo("+-> Using the Vorbis output module for track ID %u.\n", (int64_t)t->tnum);
t->tnum);
} else if (t->a_formattag == FOURCC('M', 'P', '4', 'A')) { } else if (t->a_formattag == FOURCC('M', 'P', '4', 'A')) {
// A_AAC/MPEG2/MAIN // A_AAC/MPEG2/MAIN
// 0123456789012345 // 0123456789012345
@ -1560,8 +1557,8 @@ kax_reader_c::create_packetizer(int64_t tid) {
else if (t->codec_id[10] == '4') else if (t->codec_id[10] == '4')
id = AAC_ID_MPEG4; id = AAC_ID_MPEG4;
else else
mxerror(PFX "Malformed codec id '%s' for track %d.\n", mxerror(FMT_TID "Malformed codec id '%s'.\n", ti->fname,
t->codec_id, t->tnum); (int64_t)t->tnum, t->codec_id);
if (!strcmp(&t->codec_id[12], "MAIN")) if (!strcmp(&t->codec_id[12], "MAIN"))
profile = AAC_PROFILE_MAIN; profile = AAC_PROFILE_MAIN;
@ -1574,8 +1571,8 @@ kax_reader_c::create_packetizer(int64_t tid) {
else if (!strcmp(&t->codec_id[12], "LC/SBR")) else if (!strcmp(&t->codec_id[12], "LC/SBR"))
profile = AAC_PROFILE_SBR; profile = AAC_PROFILE_SBR;
else else
mxerror(PFX "Malformed codec id %s for track %d.\n", mxerror(FMT_TID "Malformed codec id '%s'.\n", ti->fname,
t->codec_id, t->tnum); (int64_t)t->tnum, t->codec_id);
for (sbridx = 0; sbridx < ti->aac_is_sbr->size(); sbridx++) for (sbridx = 0; sbridx < ti->aac_is_sbr->size(); sbridx++)
if (((*ti->aac_is_sbr)[sbridx] == t->tnum) || if (((*ti->aac_is_sbr)[sbridx] == t->tnum) ||
@ -1589,9 +1586,8 @@ kax_reader_c::create_packetizer(int64_t tid) {
(int32_t)t->a_sfreq, (int32_t)t->a_sfreq,
t->a_channels, nti, t->a_channels, nti,
false, true)); false, true));
if (verbose) mxinfo(FMT_TID "Using the AAC output module.\n", ti->fname,
mxinfo("+-> Using the AAC output module for track ID %u.\n", (int64_t)t->tnum);
t->tnum);
#if defined(HAVE_FLAC_FORMAT_H) #if defined(HAVE_FLAC_FORMAT_H)
} else if ((t->a_formattag == FOURCC('f', 'L', 'a', 'C')) || } else if ((t->a_formattag == FOURCC('f', 'L', 'a', 'C')) ||
@ -1616,9 +1612,8 @@ kax_reader_c::create_packetizer(int64_t tid) {
nti); nti);
t->ptzr = add_packetizer(p); t->ptzr = add_packetizer(p);
} }
if (verbose) mxinfo(FMT_TID "Using the FLAC output module.\n", ti->fname,
mxinfo("+-> Using the FLAC output module for track ID %u.\n", (int64_t)t->tnum);
t->tnum);
#endif #endif
} else } else
@ -1634,9 +1629,8 @@ kax_reader_c::create_packetizer(int64_t tid) {
t->ptzr = t->ptzr =
add_packetizer(new vobsub_packetizer_c(this, t->private_data, add_packetizer(new vobsub_packetizer_c(this, t->private_data,
t->private_size, nti)); t->private_size, nti));
if (verbose) mxinfo(FMT_TID "Using the VobSub output module.\n", ti->fname,
mxinfo("+-> Using the VobSub output module for track ID %u.\n", (int64_t)t->tnum);
t->tnum);
t->sub_type = 'v'; t->sub_type = 'v';
@ -1650,9 +1644,8 @@ kax_reader_c::create_packetizer(int64_t tid) {
t->private_data, t->private_data,
t->private_size, false, t->private_size, false,
true, nti)); true, nti));
if (verbose) mxinfo(FMT_TID "Using the text subtitle output module.\n",
mxinfo("+-> Using the text subtitle output module for track ID " ti->fname, (int64_t)t->tnum);
"%u.\n", t->tnum);
t->sub_type = 't'; t->sub_type = 't';
} else } else
@ -1661,7 +1654,8 @@ kax_reader_c::create_packetizer(int64_t tid) {
break; break;
default: default:
mxerror(PFX "Unsupported track type for track %d.\n", t->tnum); mxerror(FMT_TID "Unsupported track type for this track.\n",
ti->fname, (int64_t)t->tnum);
break; break;
} }
set_packetizer_headers(t); set_packetizer_headers(t);

View File

@ -143,6 +143,8 @@ public:
virtual void display_progress(bool final = false); virtual void display_progress(bool final = false);
virtual void set_headers(); virtual void set_headers();
virtual void identify(); virtual void identify();
virtual void create_packetizers();
virtual void create_packetizer(int64_t tid);
virtual void add_attachments(KaxAttachments *a); virtual void add_attachments(KaxAttachments *a);
static int probe_file(mm_io_c *mm_io, int64_t size); static int probe_file(mm_io_c *mm_io, int64_t size);
@ -151,8 +153,6 @@ protected:
virtual int read_headers(); virtual int read_headers();
virtual void init_passthrough_packetizer(kax_track_t *t); virtual void init_passthrough_packetizer(kax_track_t *t);
virtual void set_packetizer_headers(kax_track_t *t); virtual void set_packetizer_headers(kax_track_t *t);
virtual void create_packetizers();
virtual void create_packetizer(int64_t tid);
virtual kax_track_t *new_kax_track(); virtual kax_track_t *new_kax_track();
virtual kax_track_t *find_track_by_num(uint32_t num, kax_track_t *c = NULL); virtual kax_track_t *find_track_by_num(uint32_t num, kax_track_t *c = NULL);
virtual kax_track_t *find_track_by_uid(uint32_t uid, kax_track_t *c = NULL); virtual kax_track_t *find_track_by_uid(uint32_t uid, kax_track_t *c = NULL);

View File

@ -60,11 +60,8 @@ mp3_reader_c::mp3_reader_c(track_info_c *nti)
bytes_processed = 0; bytes_processed = 0;
ti->id = 0; // ID for this track. ti->id = 0; // ID for this track.
add_packetizer(new mp3_packetizer_c(this, mp3header.sampling_frequency,
mp3header.channels, ti));
if (verbose) if (verbose)
mxinfo("Using MP2/MP3 demultiplexer for %s.\n+-> Using " mxinfo(FMT_FN "Using the MP2/MP3 demultiplexer.\n", ti->fname);
"MPEG audio output module for audio stream.\n", ti->fname);
} catch (exception &ex) { } catch (exception &ex) {
throw error_c("mp3_reader: Could not open the source file."); throw error_c("mp3_reader: Could not open the source file.");
} }
@ -74,6 +71,16 @@ mp3_reader_c::~mp3_reader_c() {
delete mm_io; delete mm_io;
} }
void
mp3_reader_c::create_packetizer(int64_t) {
if (NPTZR() != 0)
return;
add_packetizer(new mp3_packetizer_c(this, mp3header.sampling_frequency,
mp3header.channels, ti));
mxinfo(FMT_TID "Using the MPEG audio output module.\n", ti->fname,
(int64_t)0);
}
int int
mp3_reader_c::read(generic_packetizer_c *) { mp3_reader_c::read(generic_packetizer_c *) {
int nread; int nread;

View File

@ -44,6 +44,7 @@ public:
virtual int read(generic_packetizer_c *ptzr); virtual int read(generic_packetizer_c *ptzr);
virtual void identify(); virtual void identify();
virtual void create_packetizer(int64_t tid);
virtual int display_priority(); virtual int display_priority();
virtual void display_progress(bool final = false); virtual void display_progress(bool final = false);

View File

@ -324,12 +324,11 @@ ogm_reader_c::ogm_reader_c(track_info_c *nti)
num_sdemuxers = 0; num_sdemuxers = 0;
if (verbose) if (verbose)
mxinfo("Using OGG/OGM demultiplexer for %s.\n", ti->fname); mxinfo(FMT_FN "Using the OGG/OGM demultiplexer.\n", ti->fname);
if (read_headers() <= 0) if (read_headers() <= 0)
throw error_c("ogm_reader: Could not read all header packets."); throw error_c("ogm_reader: Could not read all header packets.");
handle_stream_comments(); handle_stream_comments();
create_packetizers();
} }
ogm_reader_c::~ogm_reader_c() { ogm_reader_c::~ogm_reader_c() {
@ -460,73 +459,39 @@ ogm_reader_c::create_packetizer(int64_t tid) {
ti->private_data = (unsigned char *)&bih; ti->private_data = (unsigned char *)&bih;
ti->private_size = sizeof(alBITMAPINFOHEADER); ti->private_size = sizeof(alBITMAPINFOHEADER);
try { ptzr = new video_packetizer_c(this, NULL, (double)10000000.0 /
ptzr = new video_packetizer_c(this, NULL, (double)10000000.0 / get_uint64(&sth->time_unit),
get_uint64(&sth->time_unit), get_uint32(&sth->sh.video.width),
get_uint32(&sth->sh.video.width), get_uint32(&sth->sh.video.height),
get_uint32(&sth->sh.video.height), false, ti);
false, ti);
} catch (error_c &error) {
mxwarn("ogm_reader: could not initialize video "
"packetizer for stream id %d. Will try to continue and "
"ignore this stream.\n", dmx->serial);
break;
}
if (verbose) mxinfo(FMT_TID "Using the video output module.\n", ti->fname,
mxinfo("OGG/OGM demultiplexer (%s): using video output " (int64_t)dmx->serial);
"module for stream %d.\n", ti->fname, dmx->serial);
break; break;
case OGM_STREAM_TYPE_PCM: case OGM_STREAM_TYPE_PCM:
try { ptzr = new pcm_packetizer_c(this, get_uint64(&sth->samples_per_unit),
ptzr = new pcm_packetizer_c(this, get_uint64(&sth->samples_per_unit), get_uint16(&sth->sh.audio.channels),
get_uint16(&sth->sh.audio.channels), get_uint16(&sth->bits_per_sample), ti);
get_uint16(&sth->bits_per_sample), ti);
} catch (error_c &error) {
mxwarn("ogm_reader: could not initialize PCM "
"packetizer for stream id %d. Will try to continue and "
"ignore this stream.\n", dmx->serial);
break;
}
if (verbose) mxinfo(FMT_TID "Using the PCM output module.\n", ti->fname,
mxinfo("OGG/OGM demultiplexer (%s): using PCM output " (int64_t)dmx->serial);
"module for stream %d.\n", ti->fname, dmx->serial);
break; break;
case OGM_STREAM_TYPE_MP3: case OGM_STREAM_TYPE_MP3:
try { ptzr = new mp3_packetizer_c(this, get_uint64(&sth->samples_per_unit),
ptzr = new mp3_packetizer_c(this, get_uint64(&sth->samples_per_unit), get_uint16(&sth->sh.audio.channels), ti);
get_uint16(&sth->sh.audio.channels), ti); mxinfo(FMT_TID "Using the MP3 output module.\n", ti->fname,
} catch (error_c &error) { (int64_t)dmx->serial);
mxwarn("Error: ogm_reader: could not initialize MP3 "
"packetizer for stream id %d. Will try to continue and "
"ignore this stream.\n", dmx->serial);
break;
}
if (verbose)
mxinfo("OGG/OGM demultiplexer (%s): using MP3 output "
"module for stream %d.\n", ti->fname, dmx->serial);
break; break;
case OGM_STREAM_TYPE_AC3: case OGM_STREAM_TYPE_AC3:
try { ptzr = new ac3_packetizer_c(this, get_uint64(&sth->samples_per_unit),
ptzr = new ac3_packetizer_c(this, get_uint64(&sth->samples_per_unit), get_uint16(&sth->sh.audio.channels), 0,
get_uint16(&sth->sh.audio.channels), 0, ti);
ti); mxinfo(FMT_TID "Using the AC3 output module.\n", ti->fname,
} catch (error_c &error) { (int64_t)dmx->serial);
mxwarn("ogm_reader: could not initialize AC3 "
"packetizer for stream id %d. Will try to continue and "
"ignore this stream.\n", dmx->serial);
break;
}
if (verbose)
mxinfo("OGG/OGM demultiplexer (%s): using AC3 output "
"module for stream %d.\n", ti->fname, dmx->serial);
break; break;
@ -552,21 +517,13 @@ ogm_reader_c::create_packetizer(int64_t tid) {
"%d, sbr %d, output_sample_rate %d, ex %d\n", ti->id, ti->fname, "%d, sbr %d, output_sample_rate %d, ex %d\n", ti->id, ti->fname,
profile, channels, sample_rate, (int)sbr, output_sample_rate, profile, channels, sample_rate, (int)sbr, output_sample_rate,
(int)aac_info_extracted); (int)aac_info_extracted);
try { ptzr = new aac_packetizer_c(this, AAC_ID_MPEG4, profile, sample_rate,
ptzr = new aac_packetizer_c(this, AAC_ID_MPEG4, profile, sample_rate, channels, ti, false, true);
channels, ti, false, true); if (sbr)
if (sbr) ptzr->set_audio_output_sampling_freq(output_sample_rate);
ptzr->set_audio_output_sampling_freq(output_sample_rate);
} catch (error_c &error) {
mxwarn("ogm_reader: could not initialize AAC "
"packetizer for stream id %d. Will try to continue and "
"ignore this stream.\n", dmx->serial);
break;
}
if (verbose) mxinfo(FMT_TID "Using the AAC output module.\n", ti->fname,
mxinfo("OGG/OGM demultiplexer (%s): using AAC output " (int64_t)dmx->serial);
"module for stream %d.\n", ti->fname, dmx->serial);
break; break;
@ -581,72 +538,46 @@ ogm_reader_c::create_packetizer(int64_t tid) {
dmx->vorbis_rate = vi.rate; dmx->vorbis_rate = vi.rate;
vorbis_info_clear(&vi); vorbis_info_clear(&vi);
vorbis_comment_clear(&vc); vorbis_comment_clear(&vc);
try { ptzr =
ptzr = new vorbis_packetizer_c(this,
new vorbis_packetizer_c(this, dmx->packet_data[0], dmx->packet_sizes[0],
dmx->packet_data[0], dmx->packet_sizes[0], dmx->packet_data[1], dmx->packet_sizes[1],
dmx->packet_data[1], dmx->packet_sizes[1], dmx->packet_data[2], dmx->packet_sizes[2],
dmx->packet_data[2], dmx->packet_sizes[2], ti);
ti);
} catch (error_c &error) {
mxwarn("Error: ogm_reader: could not initialize Vorbis "
"packetizer for stream id %d. Will try to continue and "
"ignore this stream.\n", dmx->serial);
break;
}
if (verbose) mxinfo(FMT_TID "Using the Vorbis output module.\n", ti->fname,
mxinfo("OGG/OGM demultiplexer (%s): using Vorbis output " (int64_t)dmx->serial);
"module for stream %d.\n", ti->fname, dmx->serial);
break; break;
case OGM_STREAM_TYPE_TEXT: case OGM_STREAM_TYPE_TEXT:
try { ptzr = new textsubs_packetizer_c(this, MKV_S_TEXTUTF8, NULL, 0, true,
ptzr = new textsubs_packetizer_c(this, MKV_S_TEXTUTF8, NULL, 0, true, false, ti);
false, ti); mxinfo(FMT_TID "Using the text subtitle output module.\n", ti->fname,
} catch (error_c &error) { (int64_t)dmx->serial);
mxwarn("ogm_reader: could not initialize the "
"text subtitles packetizer for stream id %d. Will try to "
"continue and ignore this stream.\n", dmx->serial);
break;
}
if (verbose)
mxinfo("OGG/OGM demultiplexer (%s): using text subtitle "
"output module for stream %d.\n", ti->fname, dmx->serial);
break; break;
#if defined(HAVE_FLAC_FORMAT_H) #if defined(HAVE_FLAC_FORMAT_H)
case OGM_STREAM_TYPE_FLAC: case OGM_STREAM_TYPE_FLAC:
try { unsigned char *buf;
unsigned char *buf; int size;
int size;
size = 0; size = 0;
for (i = 1; i < (int)dmx->packet_sizes.size(); i++) for (i = 1; i < (int)dmx->packet_sizes.size(); i++)
size += dmx->packet_sizes[i]; size += dmx->packet_sizes[i];
buf = (unsigned char *)safemalloc(size); buf = (unsigned char *)safemalloc(size);
size = 0; size = 0;
for (i = 1; i < (int)dmx->packet_sizes.size(); i++) { for (i = 1; i < (int)dmx->packet_sizes.size(); i++) {
memcpy(&buf[size], dmx->packet_data[i], dmx->packet_sizes[i]); memcpy(&buf[size], dmx->packet_data[i], dmx->packet_sizes[i]);
size += dmx->packet_sizes[i]; size += dmx->packet_sizes[i];
}
ptzr = new flac_packetizer_c(this, dmx->vorbis_rate, dmx->channels,
dmx->bits_per_sample, buf, size, ti);
safefree(buf);
} catch (error_c &error) {
mxwarn("ogm_reader: could not initialize the "
"FLAC packetizer for stream id %d. Will try to "
"continue and ignore this stream.\n", dmx->serial);
break;
} }
ptzr = new flac_packetizer_c(this, dmx->vorbis_rate, dmx->channels,
dmx->bits_per_sample, buf, size, ti);
safefree(buf);
if (verbose) mxinfo(FMT_TID "Using the FLAC output module.\n", ti->fname,
mxinfo("OGG/OGM demultiplexer (%s): using the FLAC " (int64_t)dmx->serial);
"output module for stream %d.\n", ti->fname, dmx->serial);
break; break;
#endif #endif

View File

@ -114,6 +114,8 @@ public:
virtual int read(generic_packetizer_c *ptzr); virtual int read(generic_packetizer_c *ptzr);
virtual void set_headers(); virtual void set_headers();
virtual void identify(); virtual void identify();
virtual void create_packetizers();
virtual void create_packetizer(int64_t tid);
virtual int display_priority(); virtual int display_priority();
virtual void display_progress(bool final = false); virtual void display_progress(bool final = false);
@ -131,8 +133,6 @@ private:
virtual int read_headers(); virtual int read_headers();
virtual void process_header_page(ogg_page *pg); virtual void process_header_page(ogg_page *pg);
virtual void process_header_packets(ogm_demuxer_t *dmx); virtual void process_header_packets(ogm_demuxer_t *dmx);
virtual void create_packetizers();
virtual void create_packetizer(int64_t tid);
virtual void free_demuxer(int); virtual void free_demuxer(int);
virtual void flush_packetizers(); virtual void flush_packetizers();
virtual void handle_stream_comments(); virtual void handle_stream_comments();

View File

@ -100,11 +100,9 @@ qtmp4_reader_c::qtmp4_reader_c(track_info_c *nti)
throw error_c(PFX "Source is not a valid Quicktime/MP4 file."); throw error_c(PFX "Source is not a valid Quicktime/MP4 file.");
if (verbose) if (verbose)
mxinfo("Using Quicktime/MP4 demultiplexer for %s.\n", ti->fname); mxinfo(FMT_FN "Using the Quicktime/MP4 demultiplexer.\n", ti->fname);
parse_headers(); parse_headers();
if (!identifying)
create_packetizers();
} catch (exception &ex) { } catch (exception &ex) {
throw error_c(PFX "Could not read the source file."); throw error_c(PFX "Could not read the source file.");
@ -1133,8 +1131,8 @@ qtmp4_reader_c::create_packetizer(int64_t tid) {
false, ti)); false, ti));
ti->private_data = NULL; ti->private_data = NULL;
} }
mxinfo("+-> Using the video packetizer for track %u (FourCC: %.4s).\n", mxinfo(FMT_TID "Using the video output module (FourCC: %.4s).\n",
dmx->id, dmx->fourcc); ti->fname, (int64_t)dmx->id, dmx->fourcc);
} else { } else {
if (!strncasecmp(dmx->fourcc, "QDMC", 4) || if (!strncasecmp(dmx->fourcc, "QDMC", 4) ||
@ -1149,9 +1147,8 @@ qtmp4_reader_c::create_packetizer(int64_t tid) {
ptzr->set_audio_channels(dmx->a_channels); ptzr->set_audio_channels(dmx->a_channels);
ptzr->set_audio_bit_depth(dmx->a_bitdepth); ptzr->set_audio_bit_depth(dmx->a_bitdepth);
if (verbose) mxinfo(FMT_TID "Using the generic audio output module (FourCC: %.4s)."
mxinfo("+-> Using generic audio output module for stream " "\n", ti->fname, (int64_t)dmx->id, dmx->fourcc);
"%u (FourCC: %.4s).\n", dmx->id, dmx->fourcc);
} else if (!strncasecmp(dmx->fourcc, "MP4A", 4)) { } else if (!strncasecmp(dmx->fourcc, "MP4A", 4)) {
int profile, sample_rate, channels, output_sample_rate; int profile, sample_rate, channels, output_sample_rate;
@ -1174,11 +1171,12 @@ qtmp4_reader_c::create_packetizer(int64_t tid) {
if (sbraac) if (sbraac)
PTZR(dmx->ptzr)-> PTZR(dmx->ptzr)->
set_audio_output_sampling_freq(output_sample_rate); set_audio_output_sampling_freq(output_sample_rate);
if (verbose) mxinfo(FMT_TID "Using the AAC output module.\n", ti->fname,
mxinfo("+-> Using AAC output module for stream %u.\n", dmx->id); (int64_t)dmx->id);
} else } else
mxerror(PFX "AAC found, but decoder config data has length %u.\n", mxerror(FMT_TID "AAC found, but decoder config data has length %u."
"\n", ti->fname, (int64_t)dmx->id,
dmx->esds.decoder_config_len); dmx->esds.decoder_config_len);
} else if (!strncasecmp(dmx->fourcc, "twos", 4) || } else if (!strncasecmp(dmx->fourcc, "twos", 4) ||
@ -1188,8 +1186,8 @@ qtmp4_reader_c::create_packetizer(int64_t tid) {
dmx->a_channels, dmx->a_bitdepth, dmx->a_channels, dmx->a_bitdepth,
ti, (dmx->a_bitdepth > 8) && ti, (dmx->a_bitdepth > 8) &&
(dmx->fourcc[0] == 't'))); (dmx->fourcc[0] == 't')));
if (verbose) mxinfo(FMT_TID "Using the PCM output module.\n", ti->fname,
mxinfo("+-> Using PCM output module for stream %u.\n", dmx->id); (int64_t)dmx->id);
} else } else
die(PFX "Should not have happened #1."); die(PFX "Should not have happened #1.");

View File

@ -131,13 +131,13 @@ public:
virtual void display_progress(bool final = false); virtual void display_progress(bool final = false);
virtual void set_headers(); virtual void set_headers();
virtual void identify(); virtual void identify();
virtual void create_packetizers();
virtual void create_packetizer(int64_t tid);
static int probe_file(mm_io_c *in, int64_t size); static int probe_file(mm_io_c *in, int64_t size);
protected: protected:
virtual void parse_headers(); virtual void parse_headers();
virtual void create_packetizers();
virtual void create_packetizer(int64_t tid);
virtual void handle_header_atoms(uint32_t parent, int64_t parent_size, virtual void handle_header_atoms(uint32_t parent, int64_t parent_size,
uint64_t parent_pos, int level); uint64_t parent_pos, int level);
virtual void read_atom(uint32_t &atom, uint64_t &size, uint64_t &pos, virtual void read_atom(uint32_t &atom, uint64_t &size, uint64_t &pos,

View File

@ -89,12 +89,10 @@ real_reader_c::real_reader_c(track_info_c *nti)
done = false; done = false;
if (verbose) if (verbose)
mxinfo("Using RealMedia demultiplexer for %s.\n", ti->fname); mxinfo(FMT_FN "Using the RealMedia demultiplexer.\n", ti->fname);
parse_headers(); parse_headers();
get_information_from_data(); get_information_from_data();
if (!identifying)
create_packetizers();
} }
// }}} // }}}
@ -273,9 +271,8 @@ real_reader_c::create_packetizer(int64_t tid) {
(dmx->fourcc[2] != '4') || (dmx->fourcc[3] != '0')) (dmx->fourcc[2] != '4') || (dmx->fourcc[3] != '0'))
dmx->rv_dimensions = true; dmx->rv_dimensions = true;
if (verbose) mxinfo(FMT_TID "Using the video output module (FourCC: %s).\n",
mxinfo("+-> Using video output module for stream %u (FourCC: " ti->fname, (int64_t)track->id, dmx->fourcc);
"%s).\n", track->id, dmx->fourcc);
} else { } else {
ra_packetizer_c *ptzr; ra_packetizer_c *ptzr;
@ -285,8 +282,8 @@ real_reader_c::create_packetizer(int64_t tid) {
add_packetizer(new ac3_bs_packetizer_c(this, dmx->samples_per_second, add_packetizer(new ac3_bs_packetizer_c(this, dmx->samples_per_second,
dmx->channels, dmx->bsid, dmx->channels, dmx->bsid,
ti)); ti));
mxverb(1, "+-> Using the AC3 output module for stream " mxinfo(FMT_TID "Using the AC3 output module (FourCC: %s).\n",
"%u (FourCC: %s).\n", track->id, dmx->fourcc); ti->fname, (int64_t)track->id, dmx->fourcc);
} else if (!strcasecmp(dmx->fourcc, "raac") || } else if (!strcasecmp(dmx->fourcc, "raac") ||
!strcasecmp(dmx->fourcc, "racp")) { !strcasecmp(dmx->fourcc, "racp")) {
@ -343,8 +340,8 @@ real_reader_c::create_packetizer(int64_t tid) {
add_packetizer(new aac_packetizer_c(this, AAC_ID_MPEG4, profile, add_packetizer(new aac_packetizer_c(this, AAC_ID_MPEG4, profile,
sample_rate, channels, ti, false, sample_rate, channels, ti, false,
true)); true));
mxverb(1, "+-> Using the AAC output module for stream " mxinfo(FMT_TID "Using the AAC output module (FourCC: %s).\n",
"%u (FourCC: %s).\n", track->id, dmx->fourcc); ti->fname, (int64_t)track->id, dmx->fourcc);
if (profile == AAC_PROFILE_SBR) if (profile == AAC_PROFILE_SBR)
PTZR(dmx->ptzr)->set_audio_output_sampling_freq(output_sample_rate); PTZR(dmx->ptzr)->set_audio_output_sampling_freq(output_sample_rate);
else if (!extra_data_parsed) else if (!extra_data_parsed)
@ -366,9 +363,8 @@ real_reader_c::create_packetizer(int64_t tid) {
dmx->ptzr = add_packetizer(ptzr); dmx->ptzr = add_packetizer(ptzr);
dmx->segments = new vector<rv_segment_t>; dmx->segments = new vector<rv_segment_t>;
if (verbose) mxinfo(FMT_TID "Using the RealAudio output module (FourCC: %s).\n",
mxinfo("+-> Using the RealAudio output module for stream " ti->fname, (int64_t)track->id, dmx->fourcc);
"%u (FourCC: %s).\n", track->id, dmx->fourcc);
} }
} }
} }

View File

@ -79,13 +79,13 @@ public:
virtual void display_progress(bool final = false); virtual void display_progress(bool final = false);
virtual void set_headers(); virtual void set_headers();
virtual void identify(); virtual void identify();
virtual void create_packetizers();
virtual void create_packetizer(int64_t tid);
static int probe_file(mm_io_c *mm_io, int64_t size); static int probe_file(mm_io_c *mm_io, int64_t size);
protected: protected:
virtual void parse_headers(); virtual void parse_headers();
virtual void create_packetizers();
virtual void create_packetizer(int64_t tid);
virtual real_demuxer_t *find_demuxer(int id); virtual real_demuxer_t *find_demuxer(int id);
virtual void assemble_video_packet(real_demuxer_t *dmx, rmff_frame_t *frame); virtual void assemble_video_packet(real_demuxer_t *dmx, rmff_frame_t *frame);
virtual int finish(); virtual int finish();

View File

@ -70,28 +70,37 @@ srt_reader_c::probe_file(mm_text_io_c *mm_io,
srt_reader_c::srt_reader_c(track_info_c *nti) srt_reader_c::srt_reader_c(track_info_c *nti)
throw (error_c): throw (error_c):
generic_reader_c(nti) { generic_reader_c(nti) {
bool is_utf8;
try { try {
mm_io = new mm_text_io_c(ti->fname); mm_io = new mm_text_io_c(ti->fname);
if (!srt_reader_c::probe_file(mm_io, 0)) if (!srt_reader_c::probe_file(mm_io, 0))
throw error_c("srt_reader: Source is not a valid SRT file."); throw error_c("srt_reader: Source is not a valid SRT file.");
ti->id = 0; // ID for this track. ti->id = 0; // ID for this track.
is_utf8 = mm_io->get_byte_order() != BO_NONE;
add_packetizer(new textsubs_packetizer_c(this, MKV_S_TEXTUTF8, NULL, 0,
true, is_utf8, ti));
} catch (exception &ex) { } catch (exception &ex) {
throw error_c("srt_reader: Could not open the source file."); throw error_c("srt_reader: Could not open the source file.");
} }
if (verbose) if (verbose)
mxinfo("Using SRT subtitle reader for %s.\n+-> Using " mxinfo(FMT_FN "Using the SRT subtitle reader.\n", ti->fname);
"text subtitle output module for subtitles.\n", ti->fname);
} }
srt_reader_c::~srt_reader_c() { srt_reader_c::~srt_reader_c() {
delete mm_io; delete mm_io;
} }
void
srt_reader_c::create_packetizer(int64_t) {
bool is_utf8;
if (NPTZR() != 0)
return;
is_utf8 = mm_io->get_byte_order() != BO_NONE;
add_packetizer(new textsubs_packetizer_c(this, MKV_S_TEXTUTF8, NULL, 0,
true, is_utf8, ti));
mxinfo(FMT_TID "Using the text subtitle output module.\n", ti->fname,
(int64_t)0);
}
#define STATE_INITIAL 0 #define STATE_INITIAL 0
#define STATE_SUBS 1 #define STATE_SUBS 1
#define STATE_SUBS_OR_NUMBER 2 #define STATE_SUBS_OR_NUMBER 2

View File

@ -39,6 +39,7 @@ public:
virtual int read(generic_packetizer_c *ptzr); virtual int read(generic_packetizer_c *ptzr);
virtual void identify(); virtual void identify();
virtual void create_packetizer(int64_t tid);
static int probe_file(mm_text_io_c *mm_io, int64_t size); static int probe_file(mm_text_io_c *mm_io, int64_t size);
}; };

View File

@ -68,10 +68,10 @@ ssa_reader_c::probe_file(mm_text_io_c *mm_io,
ssa_reader_c::ssa_reader_c(track_info_c *nti) ssa_reader_c::ssa_reader_c(track_info_c *nti)
throw (error_c): throw (error_c):
generic_reader_c(nti) { generic_reader_c(nti) {
string line, global; string line;
int64_t old_pos; int64_t old_pos;
char section; char section;
bool is_ass, sub_charset_found; bool sub_charset_found;
int i; int i;
is_ass = false; is_ass = false;
@ -136,22 +136,30 @@ ssa_reader_c::ssa_reader_c(track_info_c *nti)
throw error_c("ssa_reader: Invalid format. Could not find the " throw error_c("ssa_reader: Invalid format. Could not find the "
"\"Format\" line in the \"[Events]\" section."); "\"Format\" line in the \"[Events]\" section.");
add_packetizer(new textsubs_packetizer_c(this, is_ass ? MKV_S_TEXTASS :
MKV_S_TEXTSSA, global.c_str(),
global.length(), false, false,
ti));
} catch (exception &ex) { } catch (exception &ex) {
throw error_c("ssa_reader: Could not open the source file."); throw error_c("ssa_reader: Could not open the source file.");
} }
if (verbose) if (verbose)
mxinfo("Using SSA/ASS subtitle reader for %s.\n+-> Using " mxinfo(FMT_FN "Using the SSA/ASS subtitle reader.\n", ti->fname);
"text subtitle output module for subtitles.\n", ti->fname);
} }
ssa_reader_c::~ssa_reader_c() { ssa_reader_c::~ssa_reader_c() {
delete mm_io; delete mm_io;
} }
void
ssa_reader_c::create_packetizer(int64_t) {
if (NPTZR() != 0)
return;
add_packetizer(new textsubs_packetizer_c(this, is_ass ? MKV_S_TEXTASS :
MKV_S_TEXTSSA, global.c_str(),
global.length(), false, false,
ti));
mxinfo(FMT_TID "Using the text subtitle output module.\n", ti->fname,
(int64_t)0);
}
string string
ssa_reader_c::get_element(const char *index, ssa_reader_c::get_element(const char *index,
vector<string> &fields) { vector<string> &fields) {

View File

@ -39,6 +39,8 @@ private:
mm_text_io_c *mm_io; mm_text_io_c *mm_io;
vector<string> format; vector<string> format;
int cc_utf8; int cc_utf8;
bool is_ass;
string global;
public: public:
ssa_reader_c(track_info_c *nti) throw (error_c); ssa_reader_c(track_info_c *nti) throw (error_c);
@ -46,6 +48,7 @@ public:
virtual int read(generic_packetizer_c *ptzr); virtual int read(generic_packetizer_c *ptzr);
virtual void identify(); virtual void identify();
virtual void create_packetizer(int64_t tid);
static int probe_file(mm_text_io_c *mm_io, int64_t size); static int probe_file(mm_text_io_c *mm_io, int64_t size);

View File

@ -122,7 +122,7 @@ vobsub_reader_c::vobsub_reader_c(track_info_c *nti)
if (!idx_file->getline2(line) || if (!idx_file->getline2(line) ||
strncasecmp(line.c_str(), "# VobSub index file, v", len) || strncasecmp(line.c_str(), "# VobSub index file, v", len) ||
(line.length() < (len + 1))) (line.length() < (len + 1)))
mxerror(PFX "No version number found.\n"); mxerror(PFX "%s: No version number found.\n", ti->fname);
version = line[len] - '0'; version = line[len] - '0';
len++; len++;
@ -131,15 +131,15 @@ vobsub_reader_c::vobsub_reader_c(track_info_c *nti)
len++; len++;
} }
if (version < 7) if (version < 7)
mxerror(PFX "Only v7 and newer VobSub files are supported. If you have an " mxerror(PFX "%s: Only v7 and newer VobSub files are supported. If you "
"older version then use the VSConv utility from " "have an older version then use the VSConv utility from "
"http://sourceforge.net/projects/guliverkli/ to convert these " "http://sourceforge.net/projects/guliverkli/ to convert these "
"files to v7 files.\n"); "files to v7 files.\n", ti->fname);
parse_headers(); parse_headers();
mxinfo("Using VobSub subtitle reader for '%s' & '%s'.\n", ti->fname, if (verbose)
sub_name.c_str()); mxinfo(FMT_FN "Using the VobSub subtitle reader (SUB file '%s').\n",
create_packetizers(); ti->fname, sub_name.c_str());
} }
vobsub_reader_c::~vobsub_reader_c() { vobsub_reader_c::~vobsub_reader_c() {
@ -191,9 +191,8 @@ vobsub_reader_c::create_packetizer(int64_t tid) {
avg_duration /= (tracks[i]->timecodes.size() - 1); avg_duration /= (tracks[i]->timecodes.size() - 1);
tracks[i]->durations.push_back(avg_duration); tracks[i]->durations.push_back(avg_duration);
if (verbose) mxinfo(FMT_TID "Using the VobSub subtitle output module (language: %s).\n",
mxinfo("+-> Using VobSub subtitle output module for subtitle track " ti->fname, (int64_t)i, tracks[i]->language);
"%u (language: %s).\n", i, tracks[i]->language);
ti->language = NULL; ti->language = NULL;
} }
} }

View File

@ -72,13 +72,13 @@ public:
virtual int read(generic_packetizer_c *ptzr); virtual int read(generic_packetizer_c *ptzr);
virtual void set_headers(); virtual void set_headers();
virtual void identify(); virtual void identify();
virtual void create_packetizers();
virtual void create_packetizer(int64_t tid);
static int probe_file(mm_io_c *mm_io, int64_t size); static int probe_file(mm_io_c *mm_io, int64_t size);
protected: protected:
virtual void parse_headers(); virtual void parse_headers();
virtual void create_packetizers();
virtual void create_packetizer(int64_t tid);
virtual void flush_packetizers(); virtual void flush_packetizers();
virtual int deliver_packet(unsigned char *buf, int size, virtual int deliver_packet(unsigned char *buf, int size,
int64_t timecode, int64_t default_duration, int64_t timecode, int64_t default_duration,

View File

@ -95,6 +95,9 @@ wav_reader_c::wav_reader_c(track_info_c *nti)
ti->id = 0; // ID for this track. ti->id = 0; // ID for this track.
is_dts = false; is_dts = false;
if (verbose)
mxinfo(FMT_FN "Using the WAV demultiplexer.\n", ti->fname);
{ {
// check wether .wav file contains DTS data... // check wether .wav file contains DTS data...
unsigned short obuf[max_dts_packet_size/2]; unsigned short obuf[max_dts_packet_size/2];
@ -120,33 +123,26 @@ wav_reader_c::wav_reader_c(track_info_c *nti)
cur_buf ^= 1; cur_buf ^= 1;
} }
dts_header_t dtsheader; if (find_dts_header((const unsigned char *)buf[cur_buf], erlen,
int pos = find_dts_header((const unsigned char *)buf[cur_buf], erlen, &dtsheader) >= 0)
&dtsheader); is_dts = true;
if (pos >= 0) {
if (verbose) {
mxinfo("Using WAV demultiplexer for %s.\n"
"+-> Using DTS output module for audio stream. %s %s\n",
ti->fname, (dts_swap_bytes)? "(bytes swapped)" : "",
(dts_14_16)? "(DTS14 encoded)" : "(DTS16 encoded)");
print_dts_header(&dtsheader);
is_dts = true;
}
add_packetizer(new dts_packetizer_c(this, dtsheader, ti));
// .wav's with DTS are always filled up with other stuff to match
// the bitrate...
((dts_packetizer_c *)PTZR0)->skipping_is_normal = true;
break;
}
} }
if (is_dts) if (is_dts)
break; break;
} }
} }
}
wav_reader_c::~wav_reader_c() {
delete mm_io;
safefree(chunk);
}
void
wav_reader_c::create_packetizer(int64_t) {
if (NPTZR() != 0)
return;
if (!is_dts) { if (!is_dts) {
generic_packetizer_c *ptzr; generic_packetizer_c *ptzr;
@ -155,19 +151,21 @@ wav_reader_c::wav_reader_c(track_info_c *nti)
get_uint16(&wheader.common.wChannels), get_uint16(&wheader.common.wChannels),
get_uint16(&wheader.common.wBitsPerSample), ti); get_uint16(&wheader.common.wBitsPerSample), ti);
add_packetizer(ptzr); add_packetizer(ptzr);
mxinfo(FMT_TID "Using the PCM output module.\n", ti->fname, (int64_t)0);
if (verbose) } else {
mxinfo("Using WAV demultiplexer for %s.\n+-> Using " add_packetizer(new dts_packetizer_c(this, dtsheader, ti));
"PCM output module for audio stream.\n", ti->fname); // .wav's with DTS are always filled up with other stuff to match
is_dts = false; // the bitrate...
((dts_packetizer_c *)PTZR0)->skipping_is_normal = true;
mxinfo(FMT_TID "Using the DTS output module. %s %s\n",
ti->fname, (int64_t)0, (dts_swap_bytes)? "(bytes swapped)" : "",
(dts_14_16)? "(DTS14 encoded)" : "(DTS16 encoded)");
if (verbose > 1)
print_dts_header(&dtsheader);
} }
} }
wav_reader_c::~wav_reader_c() {
delete mm_io;
safefree(chunk);
}
int int
wav_reader_c::read(generic_packetizer_c *) { wav_reader_c::read(generic_packetizer_c *) {
if (!is_dts) { if (!is_dts) {

View File

@ -26,9 +26,10 @@
#include <stdio.h> #include <stdio.h>
#include "mm_io.h"
#include "common.h" #include "common.h"
#include "dts_common.h"
#include "error.h" #include "error.h"
#include "mm_io.h"
extern "C" { extern "C" {
#include "avilib.h" #include "avilib.h"
@ -43,6 +44,7 @@ private:
struct wave_header wheader; struct wave_header wheader;
int64_t bytes_processed; int64_t bytes_processed;
bool is_dts; bool is_dts;
dts_header_t dtsheader;
public: public:
wav_reader_c(track_info_c *nti) throw (error_c); wav_reader_c(track_info_c *nti) throw (error_c);
@ -50,6 +52,7 @@ public:
virtual int read(generic_packetizer_c *ptzr); virtual int read(generic_packetizer_c *ptzr);
virtual void identify(); virtual void identify();
virtual void create_packetizer(int64_t tid);
virtual int display_priority(); virtual int display_priority();
virtual void display_progress(bool final = false); virtual void display_progress(bool final = false);

View File

@ -1400,6 +1400,10 @@ create_readers() {
} catch (error_c error) { } catch (error_c error) {
mxerror("Demultiplexer failed to initialize:\n%s\n", error.get_error()); mxerror("Demultiplexer failed to initialize:\n%s\n", error.get_error());
} }
}
for (i = 0; i < files.size(); i++) {
files[i]->reader->create_packetizers();
if (!file->first) if (!file->first)
file->reader->connect(files[i - 1]->reader); file->reader->connect(files[i - 1]->reader);
} }

View File

@ -105,6 +105,9 @@ typedef struct {
#define DEFAULT_TRACK_PRIORITY_FROM_SOURCE 50 #define DEFAULT_TRACK_PRIORITY_FROM_SOURCE 50
#define DEFAULT_TRACK_PRIORITY_CMDLINE 255 #define DEFAULT_TRACK_PRIORITY_CMDLINE 255
#define FMT_FN "'%s': "
#define FMT_TID "'%s' track %lld: "
typedef struct { typedef struct {
KaxBlockGroup *group; KaxBlockGroup *group;
KaxBlock *block; KaxBlock *block;
@ -243,6 +246,7 @@ typedef struct packetizer_container_t {
#define OPTZR(i) reader_packetizers[i].orig #define OPTZR(i) reader_packetizers[i].orig
#define PTZR(i) reader_packetizers[i].current #define PTZR(i) reader_packetizers[i].current
#define PTZR0 PTZR(0) #define PTZR0 PTZR(0)
#define NPTZR() reader_packetizers.size()
class generic_reader_c { class generic_reader_c {
protected: protected:
@ -261,6 +265,10 @@ public:
virtual void display_progress(bool final = false); virtual void display_progress(bool final = false);
virtual void set_headers(); virtual void set_headers();
virtual void identify() = 0; virtual void identify() = 0;
virtual void create_packetizer(int64_t tid) = 0;
virtual void create_packetizers() {
create_packetizer(0);
}
virtual void add_attachments(KaxAttachments *a) { virtual void add_attachments(KaxAttachments *a) {
} }