From d9329f351a15ae79ee58c5a82585bfb1ae02e8bc Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Sun, 15 Jun 2003 08:40:43 +0000 Subject: [PATCH] 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. --- ChangeLog | 4 + common.h | 1 + mkvmerge.1 | 15 ++-- mkvmerge.cpp | 203 ++++++++++++++++++------------------------------- p_mp3.cpp | 2 +- pr_generic.cpp | 42 ++++++++-- pr_generic.h | 7 +- r_aac.cpp | 4 +- r_ac3.cpp | 4 +- r_avi.cpp | 149 +++++++++++++----------------------- r_avi.h | 7 +- r_matroska.cpp | 173 ++++++++++++++++++----------------------- r_matroska.h | 1 - r_mp3.cpp | 4 +- r_ogm.cpp | 24 +----- r_ogm.h | 3 +- r_srt.cpp | 6 +- 17 files changed, 276 insertions(+), 373 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05a41fd2c..4e8d7109e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2003-06-15 Moritz Bunkus + + * The Matroska reader now handles track selection correctly. + 2003-06-13 Moritz Bunkus * Added an option for identifying input files and their track types. diff --git a/common.h b/common.h index 0b9addd87..f3aab26eb 100644 --- a/common.h +++ b/common.h @@ -47,6 +47,7 @@ #define VERSIONINFO "mkvmerge v" VERSION using namespace std; +using namespace LIBEBML_NAMESPACE; #define DISPLAYPRIORITY_HIGH 10 #define DISPLAYPRIORITY_MEDIUM 5 diff --git a/mkvmerge.1 b/mkvmerge.1 index 4a24e9af9..9b9e1a0a5 100644 --- a/mkvmerge.1 +++ b/mkvmerge.1 @@ -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. diff --git a/mkvmerge.cpp b/mkvmerge.cpp index 4c40fcee5..0837121b6 100644 --- a/mkvmerge.cpp +++ b/mkvmerge.cpp @@ -34,7 +34,7 @@ #include #include -#ifdef LIBEBML_GCC2 +#if __GNUC__ == 2 #include #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 *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; + ti.vtracks = new vector; + ti.stracks = new vector; 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; + ti.vtracks = new vector; + ti.stracks = new vector; // 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; + ti.vtracks = new vector; + ti.stracks = new vector; } } diff --git a/p_mp3.cpp b/p_mp3.cpp index cc4e32f70..47427c247 100644 --- a/p_mp3.cpp +++ b/p_mp3.cpp @@ -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++; diff --git a/pr_generic.cpp b/pr_generic.cpp index c701b0442..2c06c7aec 100644 --- a/pr_generic.cpp +++ b/pr_generic.cpp @@ -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 *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(*src->atracks); + dst->vtracks = new vector(*src->vtracks); + dst->stracks = new vector(*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); diff --git a/pr_generic.h b/pr_generic.h index 6e283c138..13e0f4889 100644 --- a/pr_generic.h +++ b/pr_generic.h @@ -22,6 +22,7 @@ #define __PR_GENERIC_H #include +#include #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 *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); diff --git a/r_aac.cpp b/r_aac.cpp index 6d6715381..c5182d3a4 100644 --- a/r_aac.cpp +++ b/r_aac.cpp @@ -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); } diff --git a/r_ac3.cpp b/r_ac3.cpp index dfba44436..08a09db1c 100644 --- a/r_ac3.cpp +++ b/r_ac3.cpp @@ -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); } diff --git a/r_avi.cpp b/r_avi.cpp index 55565f182..230a50b21 100644 --- a/r_avi.cpp +++ b/r_avi.cpp @@ -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() { diff --git a/r_avi.h b/r_avi.h index 8d0b5a65a..519c8d4c6 100644 --- a/r_avi.h +++ b/r_avi.h @@ -23,6 +23,8 @@ #include +#include + extern "C" { #include } @@ -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 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); }; diff --git a/r_matroska.cpp b/r_matroska.cpp index 054656082..99634333e 100644 --- a/r_matroska.cpp +++ b/r_matroska.cpp @@ -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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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() { diff --git a/r_matroska.h b/r_matroska.h index 12a418e7a..98ac0af5e 100644 --- a/r_matroska.h +++ b/r_matroska.h @@ -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(); diff --git a/r_mp3.cpp b/r_mp3.cpp index 11e4fcee9..94e0d147d 100644 --- a/r_mp3.cpp +++ b/r_mp3.cpp @@ -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); } diff --git a/r_ogm.cpp b/r_ogm.cpp index ea7591a22..5489ffbf2 100644 --- a/r_ogm.cpp +++ b/r_ogm.cpp @@ -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; } diff --git a/r_ogm.h b/r_ogm.h index ed67812ea..6189bbd12 100644 --- a/r_ogm.h +++ b/r_ogm.h @@ -25,6 +25,8 @@ #include +#include + #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 *); diff --git a/r_srt.cpp b/r_srt.cpp index 0f5cb6072..84cef75bc 100644 --- a/r_srt.cpp +++ b/r_srt.cpp @@ -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);