Improved the file type detection code for MPEG transport streams. If such a file is detected then an error message is output.

This commit is contained in:
Moritz Bunkus 2007-04-18 17:20:18 +00:00
parent 1fc84c8b31
commit 6bbfae08fc
6 changed files with 94 additions and 22 deletions

View File

@ -1,3 +1,8 @@
2007-04-18 Moritz Bunkus <moritz@bunkus.org>
* mkvmerge: bug fix: Improved the file type detection code for
MPEG transport streams.
2007-03-23 Moritz Bunkus <moritz@bunkus.org>
* mkvmerge: bug fix: Fixed a problem reading normal AC3 tracks

View File

@ -1329,3 +1329,49 @@ mpeg_ps_reader_c::identify() {
}
}
// ------------------------------------------------------------------------
#define TS_CONSECUTIVE_PACKETS 16
#define TS_PROBE_SIZE (2 * TS_CONSECUTIVE_PACKETS * 204)
int mpeg_ts_reader_c::potential_packet_sizes[] = { 188, 192, 204, 0 };
bool
mpeg_ts_reader_c::probe_file(mm_io_c *io,
int64_t size) {
try {
vector<int> positions;
size = size > TS_PROBE_SIZE ? TS_PROBE_SIZE : size;
memory_cptr buffer(new memory_c(safemalloc(size), size, true));
unsigned char *mem = buffer->get();
int i, k;
io->setFilePointer(0, seek_beginning);
size = io->read(mem, size);
for (i = 0; i < size; ++i)
if (0x47 == mem[i])
positions.push_back(i);
for (i = 0; positions.size() > i; ++i) {
int pos = positions[i];
for (k = 0; 0 != potential_packet_sizes[k]; ++k) {
int packet_size = potential_packet_sizes[k];
int num_startcodes = 1;
while ((TS_CONSECUTIVE_PACKETS > num_startcodes) && (pos < size) && (0x47 == mem[pos])) {
pos += packet_size;
++num_startcodes;
}
if (TS_CONSECUTIVE_PACKETS <= num_startcodes)
return true;
}
}
} catch (...) {
}
return false;
}

View File

@ -164,4 +164,12 @@ private:
void calculate_global_timecode_offset();
};
class mpeg_ts_reader_c {
protected:
static int potential_packet_sizes[];
public:
static bool probe_file(mm_io_c *io, int64_t size);
};
#endif // __R_MPEG_H

View File

@ -363,6 +363,11 @@ identify(const string &filename) {
get_file_type(file);
ti.fname = file.name;
if (FILE_TYPE_MPEG_TS == file.type)
mxerror(_("The file '%s' has been detected as a MPEG transport stream. "
"This file format is not supported by mkvmerge.\n"),
file.name.c_str());
if (file.type == FILE_TYPE_IS_UNKNOWN)
mxerror(_("File %s has unknown type. Please have a look "
"at the supported file types ('mkvmerge --list-types') and "
@ -2176,6 +2181,11 @@ parse_args(vector<string> args) {
get_file_type(file);
ti->fname = this_arg;
if (FILE_TYPE_MPEG_TS == file.type)
mxerror(_("The file '%s' has been detected as a MPEG transport stream. "
"This file format is not supported by mkvmerge.\n"),
file.name.c_str());
if (file.type == FILE_TYPE_IS_UNKNOWN)
mxerror(_("The file '%s' has unknown type. Please have a look "
"at the supported file types ('mkvmerge --list-types') and "

View File

@ -28,31 +28,32 @@ enum display_priority_e {
/* file types */
enum file_type_e {
FILE_TYPE_IS_UNKNOWN = 0,
FILE_TYPE_OGM,
FILE_TYPE_AVI,
FILE_TYPE_WAV,
FILE_TYPE_SRT,
FILE_TYPE_MP3,
FILE_TYPE_AC3,
FILE_TYPE_CHAPTERS,
FILE_TYPE_MICRODVD,
FILE_TYPE_VOBSUB,
FILE_TYPE_MATROSKA,
FILE_TYPE_DTS,
FILE_TYPE_AAC,
FILE_TYPE_SSA,
FILE_TYPE_REAL,
FILE_TYPE_QTMP4,
FILE_TYPE_FLAC,
FILE_TYPE_TTA,
FILE_TYPE_MPEG_ES,
FILE_TYPE_VOBBTN,
FILE_TYPE_WAVPACK4,
FILE_TYPE_MPEG_PS,
FILE_TYPE_AC3,
FILE_TYPE_AVC_ES,
FILE_TYPE_USF,
FILE_TYPE_AVI,
FILE_TYPE_CHAPTERS,
FILE_TYPE_COREPICTURE,
FILE_TYPE_MAX = FILE_TYPE_COREPICTURE
FILE_TYPE_DTS,
FILE_TYPE_FLAC,
FILE_TYPE_MATROSKA,
FILE_TYPE_MICRODVD,
FILE_TYPE_MP3,
FILE_TYPE_MPEG_ES,
FILE_TYPE_MPEG_PS,
FILE_TYPE_MPEG_TS,
FILE_TYPE_OGM,
FILE_TYPE_QTMP4,
FILE_TYPE_REAL,
FILE_TYPE_SRT,
FILE_TYPE_SSA,
FILE_TYPE_TTA,
FILE_TYPE_USF,
FILE_TYPE_VOBBTN,
FILE_TYPE_VOBSUB,
FILE_TYPE_WAV,
FILE_TYPE_WAVPACK4,
FILE_TYPE_MAX = FILE_TYPE_WAVPACK4
};
int64_t create_track_number(generic_reader_c *reader, int64_t tid);

View File

@ -319,6 +319,8 @@ get_file_type(filelist_t &file) {
type = FILE_TYPE_TTA;
else if (wavpack_reader_c::probe_file(io, size))
type = FILE_TYPE_WAVPACK4;
else if (mpeg_ts_reader_c::probe_file(io, size))
type = FILE_TYPE_MPEG_TS;
else if (mpeg_ps_reader_c::probe_file(io, size))
type = FILE_TYPE_MPEG_PS;
else {