From 6bbfae08fc99bf08c63510cb9cdeafded9c11dfc Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Wed, 18 Apr 2007 17:20:18 +0000 Subject: [PATCH] Improved the file type detection code for MPEG transport streams. If such a file is detected then an error message is output. --- ChangeLog | 5 ++++ src/input/r_mpeg.cpp | 46 ++++++++++++++++++++++++++++++++++++ src/input/r_mpeg.h | 8 +++++++ src/merge/mkvmerge.cpp | 10 ++++++++ src/merge/mkvmerge.h | 45 ++++++++++++++++++----------------- src/merge/output_control.cpp | 2 ++ 6 files changed, 94 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 42e976a9b..3a53a1b27 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2007-04-18 Moritz Bunkus + + * mkvmerge: bug fix: Improved the file type detection code for + MPEG transport streams. + 2007-03-23 Moritz Bunkus * mkvmerge: bug fix: Fixed a problem reading normal AC3 tracks diff --git a/src/input/r_mpeg.cpp b/src/input/r_mpeg.cpp index d1a23eddf..ddcfbce13 100644 --- a/src/input/r_mpeg.cpp +++ b/src/input/r_mpeg.cpp @@ -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 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; +} diff --git a/src/input/r_mpeg.h b/src/input/r_mpeg.h index c518c8ced..bc953c9e4 100644 --- a/src/input/r_mpeg.h +++ b/src/input/r_mpeg.h @@ -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 diff --git a/src/merge/mkvmerge.cpp b/src/merge/mkvmerge.cpp index c1183c2ac..c7614aa8d 100644 --- a/src/merge/mkvmerge.cpp +++ b/src/merge/mkvmerge.cpp @@ -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 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 " diff --git a/src/merge/mkvmerge.h b/src/merge/mkvmerge.h index 3dacedaca..ebbdb1f7b 100644 --- a/src/merge/mkvmerge.h +++ b/src/merge/mkvmerge.h @@ -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); diff --git a/src/merge/output_control.cpp b/src/merge/output_control.cpp index 8caf24531..3a5616128 100644 --- a/src/merge/output_control.cpp +++ b/src/merge/output_control.cpp @@ -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 {