Revamped the track selection meaning and handling: -a/-s/-d now use the track IDs reported by the readers or by --identify. Fixed a but in the Matroska reader which tried to set headers for tracks which were not requested for demuxing.

This commit is contained in:
Moritz Bunkus 2003-06-15 08:40:43 +00:00
parent fe02129e8a
commit d9329f351a
17 changed files with 276 additions and 373 deletions

View File

@ -1,3 +1,7 @@
2003-06-15 Moritz Bunkus <moritz@bunkus.org>
* The Matroska reader now handles track selection correctly.
2003-06-13 Moritz Bunkus <moritz@bunkus.org>
* Added an option for identifying input files and their track types.

View File

@ -47,6 +47,7 @@
#define VERSIONINFO "mkvmerge v" VERSION
using namespace std;
using namespace LIBEBML_NAMESPACE;
#define DISPLAYPRIORITY_HIGH 10
#define DISPLAYPRIORITY_MEDIUM 5

View File

@ -88,16 +88,19 @@ section \fBFILE LINKING\fR below for details.
Options that can be used for each input file:
.TP
\fB\-a\fR, \fB\-\-atracks\fR <\fIn\fR,\fIm\fR,...>
Copy the audio tracks \fIn\fR, \fIm\fR etc.
Default: copy all audio tracks.
Copy the audio tracks \fIn\fR, \fIm\fR etc. The numbers are track IDs which
can be obtained with the \fB\-\-identify\fR switch. They're \fBnot\fR simply
the track numbers. Default: copy all audio tracks.
.TP
\fB\-d\fR, \fB\-\-vtracks\fR <\fIn\fR,\fIm\fR,...>
Copy the video tracks \fIn\fR, \fIm\fR etc.
Default: copy all video tracks.
Copy the video tracks \fIn\fR, \fIm\fR etc. The numbers are track IDs which
can be obtained with the \fB\-\-identify\fR switch. They're \fBnot\fR simply
the track numbers. Default: copy all video tracks.
.TP
\fB\-s\fR, \fB\-\-stracks\fR <\fIn\fR,\fIm\fR,...>
Copy the subtitle tracks \fIn\fR, \fIm\fR etc.
Default: copy all subtitle tracks.
Copy the subtitle tracks \fIn\fR, \fIm\fR etc. The numbers are track IDs which
can be obtained with the \fB\-\-identify\fR switch. They're \fBnot\fR simply
the track numbers. Default: copy all subtitle tracks.
.TP
\fB\-A\fR, \fB\-\-noaudio\fR
Don't copy any audio track from this file.

View File

@ -34,7 +34,7 @@
#include <string>
#include <vector>
#ifdef LIBEBML_GCC2
#if __GNUC__ == 2
#include <typeinfo>
#endif
@ -247,7 +247,6 @@ bool no_lacing = false, no_linking = false;
int64_t split_after = -1;
bool split_by_time = false;
int split_max_num_files = 65535;
bool identify_only = false;
float video_fps = -1.0;
int default_tracks[3];
@ -461,58 +460,35 @@ void add_packetizer(generic_packetizer_c *packetizer) {
packetizers.push_back(pack);
}
static unsigned char *parse_tracks(char *s) {
char *c = s;
char *nstart;
int n, ntracks;
unsigned char *tracks;
static void parse_tracks(char *s, vector<int64_t> *tracks) {
char *comma;
int64_t tid;
nstart = NULL;
tracks = NULL;
ntracks = 0;
while (*c) {
if ((*c >= '0') && (*c <= '9')) {
if (nstart == NULL)
nstart = c;
} else if (*c == ',') {
*c = 0;
if (nstart != NULL) {
n = atoi(nstart);
if ((n <= 0) || (n > 255)) {
fprintf(stderr, "Error: stream number out of range (1..255): %d\n",
n);
exit(1);
}
tracks = (unsigned char *)saferealloc(tracks, ntracks + 2);
tracks[ntracks] = (unsigned char)n;
tracks[ntracks + 1] = 0;
nstart = NULL;
ntracks++;
} else
fprintf(stderr, "Warning: useless use of ','\n");
} else if (!isspace(*c)) {
fprintf(stderr, "Error: unrecognized character in stream list: '%c'\n",
*c);
tracks->clear();
comma = strchr(s, ',');
while ((comma != NULL) && (*s != 0)) {
*comma = 0;
tid = strtol(s, NULL, 10);
if (errno == ERANGE) {
fprintf(stderr, "Error: Invalid track ID '%s'.\n", s);
exit(1);
}
c++;
tracks->push_back(tid);
s = &comma[1];
comma = strchr(s, ',');
}
if (nstart != NULL) {
n = atoi(nstart);
if ((n <= 0) || (n > 255)) {
fprintf(stderr, "Error: stream number out of range (1..255): %d\n",
n);
if (*s != 0) {
tid = strtol(s, NULL, 10);
if (errno == ERANGE) {
fprintf(stderr, "Error: Invalid track ID '%s'.\n", s);
exit(1);
}
tracks = (unsigned char *)saferealloc(tracks, ntracks + 2);
tracks[ntracks] = (unsigned char)n;
tracks[ntracks + 1] = 0;
nstart = NULL;
ntracks++;
tracks->push_back(tid);
}
return tracks;
}
static void parse_sync(char *s, audio_sync_t *async) {
@ -758,77 +734,62 @@ static void create_readers() {
break;
#endif // HAVE_OGGVORBIS
case TYPEAVI:
if (file->ti->stracks != NULL)
fprintf(stderr, "Warning: -t/-T are ignored for AVI files.\n");
if ((file->ti->stracks->size() != 0) || file->ti->no_subs)
fprintf(stderr, "Warning: -s/-S are ignored for AVI files.\n");
file->reader = new avi_reader_c(file->ti);
break;
case TYPEWAV:
if ((file->ti->atracks != NULL) || (file->ti->vtracks != NULL) ||
(file->ti->stracks != NULL))
fprintf(stderr, "Warning: -a/-A/-d/-D/-t/-T are ignored for " \
if ((file->ti->stracks->size() != 0) || file->ti->no_subs ||
(file->ti->atracks->size() != 0) || file->ti->no_audio ||
(file->ti->vtracks->size() != 0) || file->ti->no_video)
fprintf(stderr, "Warning: -a/-A/-d/-D/-s/-S are ignored for "
"WAVE files.\n");
file->reader = new wav_reader_c(file->ti);
break;
case TYPESRT:
if ((file->ti->atracks != NULL) || (file->ti->vtracks != NULL) ||
(file->ti->stracks != NULL))
fprintf(stderr, "Warning: -a/-A/-d/-D/-t/-T are ignored for " \
if ((file->ti->stracks->size() != 0) || file->ti->no_subs ||
(file->ti->atracks->size() != 0) || file->ti->no_audio ||
(file->ti->vtracks->size() != 0) || file->ti->no_video)
fprintf(stderr, "Warning: -a/-A/-d/-D/-s/-S are ignored for "
"SRT files.\n");
file->reader = new srt_reader_c(file->ti);
break;
case TYPEMP3:
if ((file->ti->atracks != NULL) || (file->ti->vtracks != NULL) ||
(file->ti->stracks != NULL))
fprintf(stderr, "Warning: -a/-A/-d/-D/-t/-T are ignored for " \
if ((file->ti->stracks->size() != 0) || file->ti->no_subs ||
(file->ti->atracks->size() != 0) || file->ti->no_audio ||
(file->ti->vtracks->size() != 0) || file->ti->no_video)
fprintf(stderr, "Warning: -a/-A/-d/-D/-s/-S are ignored for "
"MP3 files.\n");
file->reader = new mp3_reader_c(file->ti);
break;
case TYPEAC3:
if ((file->ti->atracks != NULL) || (file->ti->vtracks != NULL) ||
(file->ti->stracks != NULL))
fprintf(stderr, "Warning: -a/-A/-d/-D/-t/-T are ignored for " \
if ((file->ti->stracks->size() != 0) || file->ti->no_subs ||
(file->ti->atracks->size() != 0) || file->ti->no_audio ||
(file->ti->vtracks->size() != 0) || file->ti->no_video)
fprintf(stderr, "Warning: -a/-A/-d/-D/-s/-S are ignored for "
"AC3 files.\n");
file->reader = new ac3_reader_c(file->ti);
break;
case TYPEDTS:
if ((file->ti->atracks != NULL) || (file->ti->vtracks != NULL) ||
(file->ti->stracks != NULL))
fprintf(stderr, "Warning: -a/-A/-d/-D/-t/-T are ignored for " \
if ((file->ti->stracks->size() != 0) || file->ti->no_subs ||
(file->ti->atracks->size() != 0) || file->ti->no_audio ||
(file->ti->vtracks->size() != 0) || file->ti->no_video)
fprintf(stderr, "Warning: -a/-A/-d/-D/-s/-S are ignored for "
"DTS files.\n");
file->reader = new dts_reader_c(file->ti);
break;
case TYPEAAC:
if ((file->ti->atracks != NULL) || (file->ti->vtracks != NULL) ||
(file->ti->stracks != NULL))
fprintf(stderr, "Warning: -a/-A/-d/-D/-t/-T are ignored for " \
if ((file->ti->stracks->size() != 0) || file->ti->no_subs ||
(file->ti->atracks->size() != 0) || file->ti->no_audio ||
(file->ti->vtracks->size() != 0) || file->ti->no_video)
fprintf(stderr, "Warning: -a/-A/-d/-D/-s/-S are ignored for "
"AAC files.\n");
file->reader = new aac_reader_c(file->ti);
break;
// case TYPECHAPTERS:
// if (chapters != NULL) {
// fprintf(stderr, "Error: only one chapter file allowed.\n");
// exit(1);
// }
// chapters = chapter_information_read(file->name);
// break;
// case TYPEMICRODVD:
// if ((atracks != NULL) || (vtracks != NULL) ||
// (stracks != NULL))
// fprintf(stderr, "Warning: -a/-A/-d/-D/-t/-T are ignored for " \
// "MicroDVD files.\n");
// file->reader = new microdvd_reader_c(file->name, &async);
// break;
// case TYPEVOBSUB:
// if ((atracks != NULL) || (vtracks != NULL) ||
// (stracks != NULL))
// fprintf(stderr, "Warning: -a/-A/-d/-D/-t/-T are ignored for " \
// "VobSub files.\n");
// file->reader = new vobsub_reader_c(file->name, &async);
// break;
default:
fprintf(stderr, "Error: EVIL internal bug! (unknown file type)\n");
exit(1);
break;
default:
fprintf(stderr, "Error: EVIL internal bug! (unknown file type)\n");
exit(1);
break;
}
} catch (error_c error) {
fprintf(stderr, "Error: Demultiplexer failed to initialize:\n%s\n",
@ -846,6 +807,9 @@ static void identify(const char *filename) {
ti.async.linear = 1.0;
ti.cues = CUES_UNSPECIFIED;
ti.aspect_ratio = 1.0;
ti.atracks = new vector<int64_t>;
ti.vtracks = new vector<int64_t>;
ti.stracks = new vector<int64_t>;
file = (filelist_t *)safemalloc(sizeof(filelist_t));
@ -876,18 +840,17 @@ static void identify(const char *filename) {
static void parse_args(int argc, char **argv) {
track_info_t ti;
int i, j, noaudio, novideo, nosubs;
int i, j;
filelist_t *file;
char *s;
noaudio = 0;
novideo = 0;
nosubs = 0;
memset(&ti, 0, sizeof(track_info_t));
ti.async.linear = 1.0;
ti.cues = CUES_UNSPECIFIED;
ti.aspect_ratio = 1.0;
ti.atracks = new vector<int64_t>;
ti.vtracks = new vector<int64_t>;
ti.stracks = new vector<int64_t>;
// Check if only information about the file is wanted. In this mode only
// two parameters are allowed: the --identify switch and the file.
@ -918,7 +881,7 @@ static void parse_args(int argc, char **argv) {
outfile = safestrdup(argv[i + 1]);
i++;
} else if (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--list-types")) {
fprintf(stdout, "Known file types:\n ext description\n" \
fprintf(stdout, "Known file types:\n ext description\n"
" --- --------------------------\n");
for (j = 1; file_types[j].ext; j++)
fprintf(stdout, " %s %s\n", file_types[j].ext, file_types[j].desc);
@ -1062,22 +1025,20 @@ static void parse_args(int argc, char **argv) {
// Options that apply to the next input file only.
else if (!strcmp(argv[i], "-A") || !strcmp(argv[i], "--noaudio"))
noaudio = 1;
ti.no_audio = true;
else if (!strcmp(argv[i], "-D") || !strcmp(argv[i], "--novideo"))
novideo = 1;
ti.no_video = true;
else if (!strcmp(argv[i], "-S") || !strcmp(argv[i], "--nosubs"))
nosubs = 1;
ti.no_subs = true;
else if (!strcmp(argv[i], "-a") || !strcmp(argv[i], "--atracks")) {
if ((i + 1) >= argc) {
fprintf(stderr, "Error: -a lacks the stream number(s).\n");
exit(1);
}
if (ti.atracks != NULL)
safefree(ti.atracks);
ti.atracks = parse_tracks(argv[i + 1]);
parse_tracks(argv[i + 1], ti.atracks);
i++;
} else if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--vtracks")) {
@ -1085,9 +1046,7 @@ static void parse_args(int argc, char **argv) {
fprintf(stderr, "Error: -d lacks the stream number(s).\n");
exit(1);
}
if (ti.vtracks != NULL)
safefree(ti.vtracks);
ti.vtracks = parse_tracks(argv[i + 1]);
parse_tracks(argv[i + 1], ti.vtracks);
i++;
} else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--stracks")) {
@ -1095,9 +1054,7 @@ static void parse_args(int argc, char **argv) {
fprintf(stderr, "Error: -s lacks the stream number(s).\n");
exit(1);
}
if (ti.stracks != NULL)
safefree(ti.stracks);
ti.stracks = parse_tracks(argv[i + 1]);
parse_tracks(argv[i + 1], ti.stracks);
i++;
} else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--fourcc")) {
@ -1177,24 +1134,18 @@ static void parse_args(int argc, char **argv) {
// The argument is an input file.
else {
if ((ti.atracks != NULL) && noaudio) {
if ((ti.atracks->size() != 0) && ti.no_audio) {
fprintf(stderr, "Error: -A and -a used on the same source file.\n");
exit(1);
}
if ((ti.vtracks != NULL) && novideo) {
if ((ti.vtracks->size() != 0) && ti.no_video) {
fprintf(stderr, "Error: -D and -d used on the same source file.\n");
exit(1);
}
if ((ti.stracks != NULL) && nosubs) {
if ((ti.stracks->size() != 0) && ti.no_subs) {
fprintf(stderr, "Error: -S and -s used on the same source file.\n");
exit(1);
}
if (noaudio)
ti.atracks = (unsigned char *)safestrdup("");
if (novideo)
ti.vtracks = (unsigned char *)safestrdup("");
if (nosubs)
ti.stracks = (unsigned char *)safestrdup("");
file = (filelist_t *)safemalloc(sizeof(filelist_t));
file->name = argv[i];
@ -1219,20 +1170,16 @@ static void parse_args(int argc, char **argv) {
} else
safefree(file);
noaudio = 0;
novideo = 0;
nosubs = 0;
if (ti.atracks != NULL)
safefree(ti.atracks);
if (ti.vtracks != NULL)
safefree(ti.vtracks);
if (ti.stracks != NULL)
safefree(ti.stracks);
delete ti.atracks;
delete ti.vtracks;
delete ti.stracks;
memset(&ti, 0, sizeof(track_info_t));
ti.async.linear = 1.0;
ti.cues = CUES_UNSPECIFIED;
ti.aspect_ratio = 1.0;
ti.atracks = new vector<int64_t>;
ti.vtracks = new vector<int64_t>;
ti.stracks = new vector<int64_t>;
}
}

View File

@ -172,7 +172,7 @@ int mp3_packetizer_c::process(unsigned char *buf, int size,
packetno++;
if ((4 - ((header >> 17) & 3)) != 3) {
fprintf(stdout, "Warning: p_mp3: packet is not a valid MP3 packet (" \
fprintf(stdout, "Warning: p_mp3: packet is not a valid MP3 packet ("
"packet number %lld)\n", packetno);
safefree(packet);
packetno++;

View File

@ -412,6 +412,36 @@ generic_reader_c::~generic_reader_c() {
free_track_info(ti);
}
bool generic_reader_c::demuxing_requested(char type, int64_t id) {
vector<int64_t> *tracks;
int i;
if (type == 'v') {
if (ti->no_video)
return false;
tracks = ti->vtracks;
} else if (type == 'a') {
if (ti->no_audio)
return false;
tracks = ti->atracks;
} else if (type == 's') {
if (ti->no_subs)
return false;
tracks = ti->stracks;
} else
die("pr_generic.cpp/generic_reader_c::demuxing_requested(): Invalid track "
"type %c.", type);
if (tracks->size() == 0)
return true;
for (i = 0; i < tracks->size(); i++)
if ((*tracks)[i] == id)
return true;
return false;
}
//--------------------------------------------------------------------
track_info_t *duplicate_track_info(track_info_t *src) {
@ -422,9 +452,9 @@ track_info_t *duplicate_track_info(track_info_t *src) {
dst = (track_info_t *)safememdup(src, sizeof(track_info_t));
dst->fname = safestrdup(src->fname);
dst->atracks = safestrdup(src->atracks);
dst->vtracks = safestrdup(src->vtracks);
dst->stracks = safestrdup(src->stracks);
dst->atracks = new vector<int64_t>(*src->atracks);
dst->vtracks = new vector<int64_t>(*src->vtracks);
dst->stracks = new vector<int64_t>(*src->stracks);
dst->private_data = (unsigned char *)safememdup(src->private_data,
src->private_size);
dst->language = safestrdup(src->language);
@ -438,9 +468,9 @@ void free_track_info(track_info_t *ti) {
return;
safefree(ti->fname);
safefree(ti->atracks);
safefree(ti->vtracks);
safefree(ti->stracks);
delete ti->atracks;
delete ti->vtracks;
delete ti->stracks;
safefree(ti->private_data);
safefree(ti->language);
safefree(ti->sub_charset);

View File

@ -22,6 +22,7 @@
#define __PR_GENERIC_H
#include <deque>
#include <vector>
#include "KaxBlock.h"
#include "KaxCluster.h"
@ -55,7 +56,8 @@ typedef struct {
typedef struct {
// Options used by the readers.
char *fname;
unsigned char *atracks, *vtracks, *stracks;
bool no_audio, no_video, no_subs;
vector<int64_t> *atracks, *vtracks, *stracks;
int cues;
// Options used by the packetizers.
@ -169,6 +171,9 @@ public:
virtual void display_progress() = 0;
virtual void set_headers() = 0;
virtual void identify() = 0;
protected:
virtual bool demuxing_requested(char type, int64_t id);
};
track_info_t *duplicate_track_info(track_info_t *src);

View File

@ -69,7 +69,7 @@ aac_reader_c::aac_reader_c(track_info_t *nti) throw (error_c):
throw error_c("aac_reader: ADIF header files are not supported.");
adif = 1;
} else if (find_aac_header(chunk, 4096, &aacheader) < 0)
throw error_c("aac_reader: No valid AAC packet found in the first " \
throw error_c("aac_reader: No valid AAC packet found in the first "
"4096 bytes.\n");
else
adif = 0;
@ -81,7 +81,7 @@ aac_reader_c::aac_reader_c(track_info_t *nti) throw (error_c):
throw error_c("aac_reader: Could not open the file.");
}
if (verbose)
fprintf(stdout, "Using AAC demultiplexer for %s.\n+-> Using " \
fprintf(stdout, "Using AAC demultiplexer for %s.\n+-> Using "
"AAC output module for audio stream.\n", ti->fname);
}

View File

@ -75,13 +75,13 @@ ac3_reader_c::ac3_reader_c(track_info_t *nti) throw (error_c):
}
pos = find_ac3_header(chunk, 4096, &ac3header);
if (pos < 0)
throw error_c("ac3_reader: No valid AC3 packet found in the first " \
throw error_c("ac3_reader: No valid AC3 packet found in the first "
"4096 bytes.\n");
bytes_processed = 0;
ac3packetizer = new ac3_packetizer_c(this, ac3header.sample_rate,
ac3header.channels, ti);
if (verbose)
fprintf(stdout, "Using AC3 demultiplexer for %s.\n+-> Using " \
fprintf(stdout, "Using AC3 demultiplexer for %s.\n+-> Using "
"AC3 output module for audio stream.\n", ti->fname);
}

149
r_avi.cpp
View File

@ -61,8 +61,8 @@ int avi_reader_c::probe_file(mm_io_c *mm_io, int64_t size) {
*/
avi_reader_c::avi_reader_c(track_info_t *nti) throw (error_c):
generic_reader_c(nti) {
int fsize, i, extract_video = 1;
int64_t size;
int fsize, i;
int64_t size, bps;
mm_io_c *mm_io;
avi_demuxer_t *demuxer;
char *codec;
@ -103,17 +103,7 @@ avi_reader_c::avi_reader_c(track_info_t *nti) throw (error_c):
fsize = AVI_frame_size(avi, i);
max_frame_size = fsize;
if (ti->vtracks != NULL) {
extract_video = 0;
for (i = 0; i < strlen((char *)ti->vtracks); i++) {
if (ti->vtracks[i] > 0)
fprintf(stderr, "Warning: avi_reader: only one video stream per AVI " \
"is supported. Will ignore -d %d.\n", ti->vtracks[i]);
else if (ti->vtracks[i] == 1)
extract_video = 1;
}
}
if (extract_video) {
if (demuxing_requested('v', 0)) {
codec = AVI_video_compressor(avi);
if (!strcasecmp(codec, "DIV3") ||
!strcasecmp(codec, "AP41") || // Angel Potion
@ -143,47 +133,20 @@ avi_reader_c::avi_reader_c(track_info_t *nti) throw (error_c):
24, // fixme!
1, ti);
if (verbose)
fprintf(stdout, "+-> Using video output module for video stream.\n");
fprintf(stdout, "+-> Using video output module for video track ID 0.\n");
} else
vpacketizer = NULL;
ademuxers = NULL;
if (ti->atracks != NULL) { // use only specific audio tracks or none at all
for (i = 0; i < strlen((char *)ti->atracks); i++) {
if (ti->atracks[i] >= AVI_audio_tracks(avi))
fprintf(stderr, "Warning: avi_reader: the AVI does not contain an " \
"audio stream with the id %d. Number of audio tracks: %d\n",
ti->atracks[i], AVI_audio_tracks(avi));
else {
int already_extracting = 0;
avi_demuxer_t *demuxer = ademuxers;
while (demuxer) {
if (demuxer->aid == ti->atracks[i]) {
already_extracting = 1;
break;
}
demuxer = demuxer->next;
}
if (already_extracting)
fprintf(stderr, "Warning: avi_reader: already extracting audio " \
"stream number %d. Will only do this once.\n",
ti->atracks[i]);
else
add_audio_demuxer(avi, ti->atracks[i]);
}
}
} else // use all audio tracks (no parameter specified)
for (i = 0; i < AVI_audio_tracks(avi); i++)
for (i = 0; i < AVI_audio_tracks(avi); i++)
if (demuxing_requested('a', i + 1))
add_audio_demuxer(avi, i);
demuxer = ademuxers;
while (demuxer != NULL) {
long bps = demuxer->samples_per_second * demuxer->channels *
demuxer->bits_per_sample / 8;
for (i = 0; i < ademuxers.size(); i++) {
demuxer = ademuxers[i];
bps = demuxer->samples_per_second * demuxer->channels *
demuxer->bits_per_sample / 8;
if (bps > fsize)
fsize = bps;
demuxer = demuxer->next;
}
max_frame_size = fsize;
chunk = (unsigned char *)safemalloc(fsize < 16384 ? 16384 : fsize);
@ -194,7 +157,8 @@ avi_reader_c::avi_reader_c(track_info_t *nti) throw (error_c):
}
avi_reader_c::~avi_reader_c() {
struct avi_demuxer_t *demuxer, *tmp;
avi_demuxer_t *demuxer;
int i;
if (avi != NULL)
AVI_close(avi);
@ -203,14 +167,13 @@ avi_reader_c::~avi_reader_c() {
if (vpacketizer != NULL)
delete vpacketizer;
demuxer = ademuxers;
while (demuxer) {
for (i = 0; i < ademuxers.size(); i++) {
demuxer = ademuxers[i];
if (demuxer->packetizer != NULL)
delete demuxer->packetizer;
tmp = demuxer->next;
safefree(demuxer);
demuxer = tmp;
}
ademuxers.clear();
if (old_chunk != NULL)
safefree(old_chunk);
@ -218,13 +181,15 @@ avi_reader_c::~avi_reader_c() {
ti->private_data = NULL;
}
int avi_reader_c::add_audio_demuxer(avi_t *avi, int aid) {
avi_demuxer_t *demuxer, *append_to;
void avi_reader_c::add_audio_demuxer(avi_t *avi, int aid) {
avi_demuxer_t *demuxer;
WAVEFORMATEX *wfe;
int i;
for (i = 0; i < ademuxers.size(); i++)
if (ademuxers[i]->aid == aid) // Demuxer already added?
return;
append_to = ademuxers;
while ((append_to != NULL) && (append_to->next != NULL))
append_to = append_to->next;
AVI_set_audio_track(avi, aid);
demuxer = (avi_demuxer_t *)safemalloc(sizeof(avi_demuxer_t));
memset(demuxer, 0, sizeof(avi_demuxer_t));
@ -238,8 +203,8 @@ int avi_reader_c::add_audio_demuxer(avi_t *avi, int aid) {
switch (AVI_audio_format(avi)) {
case 0x0001: // raw PCM audio
if (verbose)
fprintf(stdout, "+-> Using PCM output module for audio stream %d.\n",
aid);
fprintf(stdout, "+-> Using PCM output module for audio track ID %d.\n",
aid + 1);
demuxer->samples_per_second = AVI_audio_rate(avi);
demuxer->channels = AVI_audio_channels(avi);
demuxer->bits_per_sample = AVI_audio_bits(avi);
@ -250,8 +215,8 @@ int avi_reader_c::add_audio_demuxer(avi_t *avi, int aid) {
break;
case 0x0055: // MP3
if (verbose)
fprintf(stdout, "+-> Using MP3 output module for audio stream %d.\n",
aid);
fprintf(stdout, "+-> Using MP3 output module for audio track ID %d.\n",
aid + 1);
demuxer->samples_per_second = AVI_audio_rate(avi);
demuxer->channels = AVI_audio_channels(avi);
demuxer->bits_per_sample = AVI_audio_mp3rate(avi);
@ -261,8 +226,8 @@ int avi_reader_c::add_audio_demuxer(avi_t *avi, int aid) {
break;
case 0x2000: // AC3
if (verbose)
fprintf(stdout, "+-> Using AC3 output module for audio stream %d.\n",
aid);
fprintf(stdout, "+-> Using AC3 output module for audio track ID %d.\n",
aid + 1);
demuxer->samples_per_second = AVI_audio_rate(avi);
demuxer->channels = AVI_audio_channels(avi);
demuxer->bits_per_sample = AVI_audio_mp3rate(avi);
@ -271,17 +236,12 @@ int avi_reader_c::add_audio_demuxer(avi_t *avi, int aid) {
demuxer->channels, ti);
break;
default:
fprintf(stderr, "Error: Unknown audio format 0x%04x for audio stream " \
"%d.\n", AVI_audio_format(avi), aid);
return -1;
fprintf(stderr, "Error: Unknown audio format 0x%04x for audio track ID "
"%d.\n", AVI_audio_format(avi), aid + 1);
return;
}
if (append_to == NULL)
ademuxers = demuxer;
else
append_to->next = demuxer;
return 0;
ademuxers.push_back(demuxer);
}
int avi_reader_c::is_keyframe(unsigned char *data, long size, int suggestion) {
@ -312,17 +272,17 @@ int avi_reader_c::is_keyframe(unsigned char *data, long size, int suggestion) {
}
int avi_reader_c::read() {
int nread, key, last_frame;
int nread, key, last_frame, i;
avi_demuxer_t *demuxer;
int need_more_data;
int done, frames_read, size;
bool need_more_data, done;
int frames_read, size;
debug_enter("avi_reader_c::read (video)");
need_more_data = 0;
need_more_data = false;
if ((vpacketizer != NULL) && !video_done) {
last_frame = 0;
done = 0;
done = false;
// Make sure we have a frame to work with.
if (old_chunk == NULL) {
@ -331,7 +291,7 @@ int avi_reader_c::read() {
debug_leave("AVI_read_frame");
if (nread < 0) {
frames = maxframes + 1;
done = 1;
done = true;
} else {
key = is_keyframe(chunk, nread, key);
old_chunk = (unsigned char *)safememdup(chunk, nread);
@ -342,7 +302,6 @@ int avi_reader_c::read() {
}
if (!done) {
frames_read = 1;
done = 0;
// Check whether we have identical frames
while (!done && (frames <= (maxframes - 1))) {
debug_enter("AVI_read_frame");
@ -357,12 +316,12 @@ int avi_reader_c::read() {
key = is_keyframe(chunk, nread, key);
if (frames == (maxframes - 1)) {
last_frame = 1;
done = 1;
done = true;
}
if (nread == 0)
frames_read++;
else if (nread > 0)
done = 1;
done = true;
frames++;
}
if (nread > 0) {
@ -386,18 +345,16 @@ int avi_reader_c::read() {
frames = maxframes + 1;
video_done = 1;
} else if (frames != (maxframes + 1))
need_more_data = 1;
need_more_data = true;
}
debug_leave("avi_reader_c::read (video)");
debug_enter("avi_reader_c::read (audio)");
demuxer = ademuxers;
while (demuxer != NULL) {
if (demuxer->packetizer->packet_available() >= 2) {
demuxer = demuxer->next;
for (i = 0; i < ademuxers.size(); i++) {
demuxer = ademuxers[i];
if (demuxer->packetizer->packet_available() >= 2)
continue;
}
AVI_set_audio_track(avi, demuxer->aid);
if (AVI_audio_format(avi) == 0x0001)
@ -417,8 +374,7 @@ int avi_reader_c::read() {
demuxer->packetizer->process(chunk, nread);
}
if (!demuxer->eos)
need_more_data = 1;
demuxer = demuxer->next;
need_more_data = true;
}
debug_leave("avi_reader_c::read (audio)");
@ -432,14 +388,15 @@ int avi_reader_c::read() {
packet_t *avi_reader_c::get_packet() {
generic_packetizer_c *winner;
avi_demuxer_t *demuxer;
int i;
winner = NULL;
if ((vpacketizer != NULL) && (vpacketizer->packet_available()))
winner = vpacketizer;
demuxer = ademuxers;
while (demuxer != NULL) {
for (i = 0; i < ademuxers.size(); i++) {
demuxer = ademuxers[i];
if (winner == NULL) {
if (demuxer->packetizer->packet_available())
winner = demuxer->packetizer;
@ -447,7 +404,6 @@ packet_t *avi_reader_c::get_packet() {
(winner->get_smallest_timecode() >
demuxer->packetizer->get_smallest_timecode()))
winner = demuxer->packetizer;
demuxer = demuxer->next;
}
if (winner != NULL)
@ -483,16 +439,13 @@ void avi_reader_c::display_progress() {
}
void avi_reader_c::set_headers() {
avi_demuxer_t *demuxer;
int i;
if (vpacketizer != NULL)
vpacketizer->set_headers();
demuxer = ademuxers;
while (demuxer != NULL) {
demuxer->packetizer->set_headers();
demuxer = demuxer->next;
}
for (i = 0; i < ademuxers.size(); i++)
ademuxers[i]->packetizer->set_headers();
}
void avi_reader_c::identify() {

View File

@ -23,6 +23,8 @@
#include <stdio.h>
#include <vector>
extern "C" {
#include <avilib.h>
}
@ -43,7 +45,6 @@ typedef struct avi_demuxer_t {
int aid;
int eos;
int64_t bytes_processed;
avi_demuxer_t *next;
} avi_demuxer_t;
class avi_reader_c: public generic_reader_c {
@ -51,7 +52,7 @@ private:
unsigned char *chunk, *old_chunk;
avi_t *avi;
video_packetizer_c *vpacketizer;
avi_demuxer_t *ademuxers;
vector<avi_demuxer_t *> ademuxers;
double fps;
int frames, max_frame_size, act_wchar, old_key, old_nread;
int video_done, maxframes, is_divx, rederive_keyframes;
@ -70,7 +71,7 @@ public:
static int probe_file(mm_io_c *mm_io, int64_t size);
private:
virtual int add_audio_demuxer(avi_t *avi, int aid);
virtual void add_audio_demuxer(avi_t *avi, int aid);
virtual int is_keyframe(unsigned char *data, long size, int suggestion);
};

View File

@ -421,7 +421,7 @@ void mkv_reader_c::verify_tracks() {
continue;
}
if (t->ok && verbose)
if (t->ok && (verbose > 1))
printf("matroska_reader: Track %u seems to be ok.\n", t->tnum);
}
}
@ -448,22 +448,22 @@ int mkv_reader_c::read_headers() {
// Don't verify its data for now.
l0->SkipData(*es, l0->Generic().Context);
delete l0;
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: Found the head...\n");
// Next element must be a segment
l0 = es->FindNextID(KaxSegment::ClassInfos, 0xFFFFFFFFL);
if (l0 == NULL) {
if (verbose)
fprintf(stdout, "matroska_reader: but no segment :(\n");
fprintf(stdout, "matroska_reader: No segment found.\n");
return 0;
}
if (!(EbmlId(*l0) == KaxSegment::ClassInfos.GlobalId)) {
if (verbose)
fprintf(stdout, "matroska_reader: but no segment :(\n");
fprintf(stdout, "matroska_reader: No segment found.\n");
return 0;
}
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: + a segment...\n");
segment = l0;
@ -480,7 +480,7 @@ int mkv_reader_c::read_headers() {
if (EbmlId(*l1) == KaxInfo::ClassInfos.GlobalId) {
// General info about this Matroska file
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: |+ segment information...\n");
l2 = es->FindNextElement(l1->Generic().Context, upper_lvl_el,
@ -493,7 +493,7 @@ int mkv_reader_c::read_headers() {
KaxTimecodeScale &ktc_scale = *static_cast<KaxTimecodeScale *>(l2);
ktc_scale.ReadData(es->I_O());
tc_scale = uint64(ktc_scale);
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + timecode scale: %llu\n",
tc_scale);
@ -502,17 +502,11 @@ int mkv_reader_c::read_headers() {
duration.ReadData(es->I_O());
segment_duration = float(duration) * tc_scale / 1000000000.0;
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + duration: %.3fs\n",
segment_duration);
} else if (!is_ebmlvoid(l2) &&
!(EbmlId(*l2) == KaxWritingApp::ClassInfos.GlobalId) &&
!(EbmlId(*l2) == KaxMuxingApp::ClassInfos.GlobalId) &&
!(EbmlId(*l2) == KaxDateUTC::ClassInfos.GlobalId))
if (verbose)
fprintf(stdout, "matroska_reader: | + unknown element@2: %s\n",
typeid(*l2).name());
}
if (upper_lvl_el > 0) { // we're coming from l3
upper_lvl_el--;
@ -531,7 +525,7 @@ int mkv_reader_c::read_headers() {
} else if (EbmlId(*l1) == KaxTracks::ClassInfos.GlobalId) {
// Yep, we've found our KaxTracks element. Now find all tracks
// contained in this segment.
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: |+ segment tracks...\n");
l2 = es->FindNextElement(l1->Generic().Context, upper_lvl_el,
@ -542,7 +536,7 @@ int mkv_reader_c::read_headers() {
if (EbmlId(*l2) == KaxTrackEntry::ClassInfos.GlobalId) {
// We actually found a track entry :) We're happy now.
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + a track...\n");
track = new_mkv_track();
@ -559,12 +553,12 @@ int mkv_reader_c::read_headers() {
if (EbmlId(*l3) == KaxTrackNumber::ClassInfos.GlobalId) {
KaxTrackNumber &tnum = *static_cast<KaxTrackNumber *>(l3);
tnum.ReadData(es->I_O());
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Track number: %d\n",
uint8(tnum));
track->tnum = uint8(tnum);
if (find_track_by_num(track->tnum, track) != NULL)
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + WARNING: There's "
"more than one track with the number %u.\n",
track->tnum);
@ -572,12 +566,12 @@ int mkv_reader_c::read_headers() {
} else if (EbmlId(*l3) == KaxTrackUID::ClassInfos.GlobalId) {
KaxTrackUID &tuid = *static_cast<KaxTrackUID *>(l3);
tuid.ReadData(es->I_O());
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Track UID: %u\n",
uint32(tuid));
track->tuid = uint32(tuid);
if (find_track_by_uid(track->tuid, track) != NULL)
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + WARNING: There's "
"more than one track with the UID %u.\n",
track->tnum);
@ -588,7 +582,7 @@ int mkv_reader_c::read_headers() {
*static_cast<KaxTrackDefaultDuration *>(l3);
def_duration.ReadData(es->I_O());
track->v_frate = 1000000000.0 / (float)uint64(def_duration);
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Default duration: "
"%.3fms ( = %.3f fps)\n",
(float)uint64(def_duration) / 1000000.0,
@ -597,34 +591,34 @@ int mkv_reader_c::read_headers() {
} else if (EbmlId(*l3) == KaxTrackType::ClassInfos.GlobalId) {
KaxTrackType &ttype = *static_cast<KaxTrackType *>(l3);
ttype.ReadData(es->I_O());
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Track type: ");
switch (uint8(ttype)) {
case track_audio:
if (verbose)
if (verbose > 1)
printf("Audio\n");
track->type = 'a';
break;
case track_video:
if (verbose)
if (verbose > 1)
printf("Video\n");
track->type = 'v';
break;
case track_subtitle:
if (verbose)
if (verbose > 1)
printf("Subtitle\n");
track->type = 's';
break;
default:
if (verbose)
if (verbose > 1)
printf("unknown\n");
track->type = '?';
break;
}
} else if (EbmlId(*l3) == KaxTrackAudio::ClassInfos.GlobalId) {
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Audio track\n");
l4 = es->FindNextElement(l3->Generic().Context, upper_lvl_el,
0xFFFFFFFFL, true, 1);
@ -638,7 +632,7 @@ int mkv_reader_c::read_headers() {
*static_cast<KaxAudioSamplingFreq*>(l4);
freq.ReadData(es->I_O());
track->a_sfreq = float(freq);
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Sampling "
"frequency: %f\n", track->a_sfreq);
@ -648,7 +642,7 @@ int mkv_reader_c::read_headers() {
*static_cast<KaxAudioChannels*>(l4);
channels.ReadData(es->I_O());
track->a_channels = uint8(channels);
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Channels: %u\n",
track->a_channels);
@ -658,12 +652,12 @@ int mkv_reader_c::read_headers() {
*static_cast<KaxAudioBitDepth*>(l4);
bps.ReadData(es->I_O());
track->a_bps = uint8(bps);
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Bit depth: %u\n",
track->a_bps);
} else if (!is_ebmlvoid(l4))
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + unknown "
"element@4: %s\n", typeid(*l4).name());
@ -679,7 +673,7 @@ int mkv_reader_c::read_headers() {
} // while (l4 != NULL)
} else if (EbmlId(*l3) == KaxTrackVideo::ClassInfos.GlobalId) {
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Video track\n");
l4 = es->FindNextElement(l3->Generic().Context, upper_lvl_el,
0xFFFFFFFFL, true, 1);
@ -692,7 +686,7 @@ int mkv_reader_c::read_headers() {
*static_cast<KaxVideoPixelWidth *>(l4);
width.ReadData(es->I_O());
track->v_width = uint16(width);
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Pixel width: "
"%u\n", track->v_width);
@ -702,7 +696,7 @@ int mkv_reader_c::read_headers() {
*static_cast<KaxVideoPixelHeight *>(l4);
height.ReadData(es->I_O());
track->v_height = uint16(height);
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Pixel height: "
"%u\n", track->v_height);
@ -712,7 +706,7 @@ int mkv_reader_c::read_headers() {
*static_cast<KaxVideoDisplayWidth *>(l4);
width.ReadData(es->I_O());
track->v_dwidth = uint16(width);
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Display width: "
"%u\n", track->v_dwidth);
@ -722,7 +716,7 @@ int mkv_reader_c::read_headers() {
*static_cast<KaxVideoDisplayHeight *>(l4);
height.ReadData(es->I_O());
track->v_dheight = uint16(height);
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Display height: "
"%u\n", track->v_dheight);
@ -733,12 +727,12 @@ int mkv_reader_c::read_headers() {
*static_cast<KaxVideoFrameRate *>(l4);
framerate.ReadData(es->I_O());
track->v_frate = float(framerate);
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Frame rate: "
"%f\n", float(framerate));
} else if (!is_ebmlvoid(l4))
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + unknown "
"element@4: %s\n", typeid(*l4).name());
@ -756,7 +750,7 @@ int mkv_reader_c::read_headers() {
} else if (EbmlId(*l3) == KaxCodecID::ClassInfos.GlobalId) {
KaxCodecID &codec_id = *static_cast<KaxCodecID*>(l3);
codec_id.ReadData(es->I_O());
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Codec ID: %s\n",
string(codec_id).c_str());
track->codec_id = safestrdup(string(codec_id).c_str());
@ -764,7 +758,7 @@ int mkv_reader_c::read_headers() {
} else if (EbmlId(*l3) == KaxCodecPrivate::ClassInfos.GlobalId) {
KaxCodecPrivate &c_priv = *static_cast<KaxCodecPrivate*>(l3);
c_priv.ReadData(es->I_O());
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + CodecPrivate, length "
"%llu\n", c_priv.GetSize());
track->private_size = c_priv.GetSize();
@ -777,7 +771,7 @@ int mkv_reader_c::read_headers() {
KaxTrackMinCache &min_cache =
*static_cast<KaxTrackMinCache*>(l3);
min_cache.ReadData(es->I_O());
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + MinCache: %u\n",
uint32(min_cache));
@ -786,7 +780,7 @@ int mkv_reader_c::read_headers() {
KaxTrackMaxCache &max_cache =
*static_cast<KaxTrackMaxCache*>(l3);
max_cache.ReadData(es->I_O());
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + MaxCache: %u\n",
uint32(max_cache));
@ -795,7 +789,7 @@ int mkv_reader_c::read_headers() {
KaxTrackFlagDefault &f_default =
*static_cast<KaxTrackFlagDefault *>(l3);
f_default.ReadData(es->I_O());
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Default flag: %d\n",
uint32(f_default));
track->default_track = uint32(f_default);
@ -805,15 +799,12 @@ int mkv_reader_c::read_headers() {
KaxTrackLanguage &lang =
*static_cast<KaxTrackLanguage *>(l3);
lang.ReadData(es->I_O());
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: | + Language: %s\n",
string(lang).c_str());
track->language = safestrdup(string(lang).c_str());
} else if (!is_ebmlvoid(l3))
if (verbose)
fprintf(stdout, "matroska_reader: | + unknown element@3: "
"%s\n", typeid(*l3).name());
}
if (upper_lvl_el > 0) { // we're coming from l4
upper_lvl_el--;
@ -829,10 +820,8 @@ int mkv_reader_c::read_headers() {
}
} // while (l3 != NULL)
} else if (!is_ebmlvoid(l2))
if (verbose)
fprintf(stdout, "matroska_reader: | + unknown element@2: %s\n",
typeid(*l2).name());
}
if (upper_lvl_el > 0) { // we're coming from l3
upper_lvl_el--;
delete l2;
@ -848,17 +837,13 @@ int mkv_reader_c::read_headers() {
} // while (l2 != NULL)
} else if (EbmlId(*l1) == KaxCluster::ClassInfos.GlobalId) {
if (verbose)
if (verbose > 1)
fprintf(stdout, "matroska_reader: |+ found cluster, headers are "
"parsed completely :)\n");
saved_l1 = l1;
exit_loop = 1;
} else if (!(EbmlId(*l1) == KaxSeekHead::ClassInfos.GlobalId) &&
!is_ebmlvoid(l1))
if (verbose)
fprintf(stdout, "matroska_reader: |+ unknown element@1: %s\n",
typeid(*l1).name());
}
if (exit_loop) // we've found the first cluster, so get out
break;
@ -908,12 +893,15 @@ void mkv_reader_c::create_packetizers() {
if (nti.language == 0)
nti.language = t->language;
if (t->ok && demuxing_requested(t)) {
if (t->ok && demuxing_requested(t->type, t->tnum)) {
switch (t->type) {
case 'v':
if (nti.fourcc[0] == 0)
memcpy(nti.fourcc, t->v_fourcc, 5);
if (verbose)
fprintf(stdout, "Matroska demultiplexer (%s): using video output "
"module for track ID %u.\n", ti->fname, t->tnum);
t->packetizer = new video_packetizer_c(this, t->v_frate, t->v_width,
t->v_height, 24, 1, &nti);
if (nti.aspect_ratio == 1.0) { // The user didn't set it.
@ -928,20 +916,29 @@ void mkv_reader_c::create_packetizers() {
break;
case 'a':
if (t->a_formattag == 0x0001)
if (t->a_formattag == 0x0001) {
t->packetizer = new pcm_packetizer_c(this,
(unsigned long)t->a_sfreq,
t->a_channels, t->a_bps,
&nti);
else if (t->a_formattag == 0x0055)
if (verbose)
fprintf(stdout, "Matroska demultiplexer (%s): using the PCM "
"output module for track ID %u.\n", ti->fname, t->tnum);
} else if (t->a_formattag == 0x0055) {
t->packetizer = new mp3_packetizer_c(this,
(unsigned long)t->a_sfreq,
t->a_channels, &nti);
else if (t->a_formattag == 0x2000)
if (verbose)
fprintf(stdout, "Matroska demultiplexer (%s): using the MP3 "
"output module for track ID %u.\n", ti->fname, t->tnum);
} else if (t->a_formattag == 0x2000) {
t->packetizer = new ac3_packetizer_c(this,
(unsigned long)t->a_sfreq,
t->a_channels, &nti);
else if (t->a_formattag == 0x2001) {
if (verbose)
fprintf(stdout, "Matroska demultiplexer (%s): using the AC3 "
"output module for track ID %u.\n", ti->fname, t->tnum);
} else if (t->a_formattag == 0x2001) {
fprintf(stderr, "Reading DTS from Matroska not implemented yet,"
"cannot we get a complete DTS_Header here for construction"
"of the packetizer?");
@ -951,7 +948,7 @@ void mkv_reader_c::create_packetizers() {
(unsigned long)t->a_sfreq,
&nti);
*/
} else if (t->a_formattag == 0xFFFE)
} else if (t->a_formattag == 0xFFFE) {
t->packetizer = new vorbis_packetizer_c(this,
t->headers[0],
t->header_sizes[0],
@ -959,7 +956,10 @@ void mkv_reader_c::create_packetizers() {
t->header_sizes[1],
t->headers[2],
t->header_sizes[2], &nti);
else if (t->a_formattag == FOURCC('M', 'P', '4', 'A')) {
if (verbose)
fprintf(stdout, "Matroska demultiplexer (%s): using the Vorbis "
" output module for track ID %u.\n", ti->fname, t->tnum);
} else if (t->a_formattag == FOURCC('M', 'P', '4', 'A')) {
// A_AAC/MPEG2/MAIN
// 0123456789012345
int id, profile;
@ -990,6 +990,9 @@ void mkv_reader_c::create_packetizers() {
t->packetizer = new aac_packetizer_c(this, id, profile,
(unsigned long)t->a_sfreq,
t->a_channels, &nti, true);
if (verbose)
fprintf(stdout, "Matroska demultiplexer (%s): using the AAC "
"output module for track ID %u.\n", ti->fname, t->tnum);
} else {
fprintf(stderr, "Error: matroska_reader: Unsupported track type "
"for track %d.\n", t->tnum);
@ -1092,7 +1095,8 @@ int mkv_reader_c::read() {
block->SetParent(*cluster);
block_track = find_track_by_num(block->TrackNum());
if ((block_track != NULL) && demuxing_requested(block_track))
if ((block_track != NULL) &&
demuxing_requested(block_track->type, block_track->tnum))
delete_element = 0;
else
block = NULL;
@ -1176,10 +1180,7 @@ int mkv_reader_c::read() {
}
} // while (l2 != NULL)
} else if (!(EbmlId(*l1) == KaxCues::ClassInfos.GlobalId) &&
!is_ebmlvoid(l1))
printf("matroska_reader: Unknown element@1: %s\n",
typeid(*l1).name());
}
if (exit_loop)
break;
@ -1210,33 +1211,6 @@ int mkv_reader_c::read() {
return 0;
}
/*
* Checks whether the user wants a certain stream extracted or not.
*/
int mkv_reader_c::demuxing_requested(mkv_track_t *t) {
unsigned char *tracks;
int i;
if (t->type == 'v')
tracks = ti->vtracks;
else if ((t->type == 'a') || (t->type == 'V'))
tracks = ti->atracks;
else if (t->type == 's')
tracks = ti->stracks;
else
die("r_matroska.cpp/mkv_reader_c::demuxing_requested(): internal bug - "
"unknown stream type %d", t->type);
if (tracks == NULL)
return 1;
for (i = 0; i < strlen((char *)tracks); i++)
if (tracks[i] == t->tnum)
return 1;
return 0;
}
packet_t *mkv_reader_c::get_packet() {
generic_packetizer_c *winner;
mkv_track_t *t;
@ -1305,7 +1279,8 @@ void mkv_reader_c::set_headers() {
int i;
for (i = 0; i < num_tracks; i++)
tracks[i]->packetizer->set_headers();
if (demuxing_requested(tracks[i]->type, tracks[i]->tnum))
tracks[i]->packetizer->set_headers();
}
void mkv_reader_c::identify() {

View File

@ -109,7 +109,6 @@ public:
static int probe_file(mm_io_c *mm_io, int64_t size);
private:
virtual int demuxing_requested(mkv_track_t *t);
virtual int read_headers();
virtual void create_packetizers();
virtual mkv_track_t *new_mkv_track();

View File

@ -82,7 +82,7 @@ mp3_reader_c::mp3_reader_c(track_info_t *nti) throw (error_c):
}
pos = find_mp3_header(chunk, 4096, &header);
if (pos < 0)
throw error_c("mp3_reader: No valid MP3 packet found in the first " \
throw error_c("mp3_reader: No valid MP3 packet found in the first "
"4096 bytes.\n");
decode_mp3_header(header, &mp3header);
@ -91,7 +91,7 @@ mp3_reader_c::mp3_reader_c(track_info_t *nti) throw (error_c):
mp3_freqs[mp3header.sampling_frequency],
mp3header.stereo ? 2 : 1, ti);
if (verbose)
fprintf(stdout, "Using MP3 demultiplexer for %s.\n+-> Using " \
fprintf(stdout, "Using MP3 demultiplexer for %s.\n+-> Using "
"MP3 output module for audio stream.\n", ti->fname);
}

View File

@ -119,22 +119,6 @@ ogm_reader_c::~ogm_reader_c() {
ti->private_data = NULL;
}
/*
* Checks whether the user wants a certain stream extracted or not.
*/
int ogm_reader_c::demuxing_requested(unsigned char *streams, int serialno) {
int i;
if (streams == NULL)
return 1;
for (i = 0; i < strlen((char *)streams); i++)
if (streams[i] == serialno)
return 1;
return 0;
}
ogm_demuxer_t *ogm_reader_c::find_demuxer(int serialno) {
int i;
@ -430,7 +414,7 @@ void ogm_reader_c::handle_new_stream(ogg_page *og) {
if ((op.bytes >= 7) && !strncmp((char *)&op.packet[1], "vorbis", 6)) {
nastreams++;
numstreams++;
if (!demuxing_requested(ti->atracks, ogg_page_serialno(og))) {
if (!demuxing_requested('a', ogg_page_serialno(og))) {
ogg_stream_clear(&new_oss);
safefree(dmx->packet_data[0]);
safefree(dmx);
@ -453,7 +437,7 @@ void ogm_reader_c::handle_new_stream(ogg_page *og) {
if (!strncmp(sth->streamtype, "video", 5)) {
nvstreams++;
numstreams++;
if (!demuxing_requested(ti->vtracks, ogg_page_serialno(og))) {
if (!demuxing_requested('v', ogg_page_serialno(og))) {
ogg_stream_clear(&new_oss);
safefree(dmx->packet_data[0]);
safefree(dmx);
@ -474,7 +458,7 @@ void ogm_reader_c::handle_new_stream(ogg_page *og) {
if (!strncmp(sth->streamtype, "audio", 5)) {
nastreams++;
numstreams++;
if (!demuxing_requested(ti->atracks, ogg_page_serialno(og))) {
if (!demuxing_requested('a', ogg_page_serialno(og))) {
ogg_stream_clear(&new_oss);
return;
}
@ -510,7 +494,7 @@ void ogm_reader_c::handle_new_stream(ogg_page *og) {
ntstreams++;
numstreams++;
if (!demuxing_requested(ti->stracks, ogg_page_serialno(og))) {
if (!demuxing_requested('s', ogg_page_serialno(og))) {
ogg_stream_clear(&new_oss);
return;
}

View File

@ -25,6 +25,8 @@
#include <ogg/ogg.h>
#include <vector>
#include "mm_io.h"
#include "common.h"
#include "pr_generic.h"
@ -70,7 +72,6 @@ public:
private:
virtual ogm_demuxer_t *find_demuxer(int serialno);
virtual int demuxing_requested(unsigned char *, int);
virtual int read_page(ogg_page *);
virtual void add_new_demuxer(ogm_demuxer_t *);
virtual void handle_new_stream(ogg_page *);

View File

@ -77,7 +77,7 @@ srt_reader_c::srt_reader_c(track_info_t *nti) throw (error_c):
throw error_c("srt_reader: Could not open the source file.");
}
if (verbose)
fprintf(stdout, "Using SRT subtitle reader for %s.\n+-> Using " \
fprintf(stdout, "Using SRT subtitle reader for %s.\n+-> Using "
"text subtitle output module for subtitles.\n", ti->fname);
}
@ -138,8 +138,8 @@ int srt_reader_c::read() {
}
if ((subs.check() != 0) && verbose)
fprintf(stdout, "srt_reader: Warning: The subtitle file seems to be " \
"badly broken. The output file might not be playable " \
fprintf(stdout, "srt_reader: Warning: The subtitle file seems to be "
"badly broken. The output file might not be playable "
"correctly.\n");
subs.process(textsubs_packetizer);