mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2025-01-04 09:15:05 +00:00
Made the AAC detection code stricter.
The code now requires five consecutive identical AAC headers instead of just two arbitrary headers. This fixes mis-detection issues, e.g. those of bugs 373 and 374.
This commit is contained in:
parent
e820f7e390
commit
5f7d53b56e
@ -1,3 +1,9 @@
|
||||
2009-04-25 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mkvmerge: bug fix: Made the AAC detection code stricter in what
|
||||
it accepts. This results in fewer mis-detections. Fix for bugs 373
|
||||
and 374.
|
||||
|
||||
2009-04-16 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mkvmerge: bug fix: Splitting without the option "--engage
|
||||
|
@ -23,8 +23,8 @@ const int aac_sampling_freq[16] = {96000, 88200, 64000, 48000, 44100, 32000,
|
||||
24000, 22050, 16000, 12000, 11025, 8000,
|
||||
0, 0, 0, 0}; // filling
|
||||
|
||||
bool
|
||||
parse_aac_adif_header_internal(unsigned char *buf,
|
||||
static bool
|
||||
parse_aac_adif_header_internal(const unsigned char *buf,
|
||||
int size,
|
||||
aac_header_t *aac_header) {
|
||||
int i, k;
|
||||
@ -93,7 +93,7 @@ parse_aac_adif_header_internal(unsigned char *buf,
|
||||
}
|
||||
|
||||
bool
|
||||
parse_aac_adif_header(unsigned char *buf,
|
||||
parse_aac_adif_header(const unsigned char *buf,
|
||||
int size,
|
||||
aac_header_t *aac_header) {
|
||||
try {
|
||||
@ -104,7 +104,7 @@ parse_aac_adif_header(unsigned char *buf,
|
||||
}
|
||||
|
||||
static bool
|
||||
is_adts_header(unsigned char *buf,
|
||||
is_adts_header(const unsigned char *buf,
|
||||
int size,
|
||||
aac_header_t *aac_header,
|
||||
bool emphasis_present) {
|
||||
@ -128,6 +128,8 @@ is_adts_header(unsigned char *buf,
|
||||
bc.skip_bits(2); // emphasis, MPEG-4 only
|
||||
bc.skip_bits(1 + 1); // copyright_id_bit & copyright_id_start
|
||||
frame_length = bc.get_bits(13);
|
||||
if (0 == frame_length)
|
||||
return false;
|
||||
bc.skip_bits(11); // adts_buffer_fullness
|
||||
bc.skip_bits(2); // no_raw_blocks_in_frame
|
||||
if (!protection_absent)
|
||||
@ -153,7 +155,7 @@ is_adts_header(unsigned char *buf,
|
||||
}
|
||||
|
||||
int
|
||||
find_aac_header(unsigned char *buf,
|
||||
find_aac_header(const unsigned char *buf,
|
||||
int size,
|
||||
aac_header_t *aac_header,
|
||||
bool emphasis_present) {
|
||||
@ -184,7 +186,7 @@ get_aac_sampling_freq_idx(int sampling_freq) {
|
||||
}
|
||||
|
||||
bool
|
||||
parse_aac_data(unsigned char *data,
|
||||
parse_aac_data(const unsigned char *data,
|
||||
int size,
|
||||
int &profile,
|
||||
int &channels,
|
||||
@ -273,3 +275,66 @@ create_aac_data(unsigned char *data,
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
int
|
||||
find_consecutive_aac_headers(const unsigned char *buf,
|
||||
int size,
|
||||
int num) {
|
||||
aac_header_t aac_header, new_header;
|
||||
|
||||
int base = 0;
|
||||
int pos = find_aac_header(&buf[base], size - base, &aac_header, false);
|
||||
|
||||
if (0 > pos)
|
||||
return -1;
|
||||
|
||||
if (1 == num)
|
||||
return pos;
|
||||
base += pos;
|
||||
|
||||
do {
|
||||
mxverb(4, boost::format("find_cons_aac_h: starting with base at %1%\n") % base);
|
||||
|
||||
int offset = aac_header.bytes;
|
||||
int i;
|
||||
for (i = 0; (num - 1) > i; ++i) {
|
||||
if ((size - base - offset) < 2)
|
||||
break;
|
||||
|
||||
pos = find_aac_header(&buf[base + offset], size - base - offset, &new_header, false);
|
||||
if (0 == pos) {
|
||||
if (new_header == aac_header) {
|
||||
mxverb(4, boost::format("find_cons_aac_h: found good header %1%\n") % i);
|
||||
offset += new_header.bytes;
|
||||
continue;
|
||||
} else
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == (num - 1))
|
||||
return base;
|
||||
|
||||
++base;
|
||||
offset = 0;
|
||||
pos = find_aac_header(&buf[base], size - base, &aac_header, false);
|
||||
|
||||
if (-1 == pos)
|
||||
return -1;
|
||||
|
||||
base += pos;
|
||||
} while (base < (size - 5));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool
|
||||
operator ==(const aac_header_t &h1,
|
||||
const aac_header_t &h2) {
|
||||
return (h1.sample_rate == h2.sample_rate)
|
||||
&& (h1.bit_rate == h2.bit_rate)
|
||||
&& (h1.channels == h2.channels)
|
||||
&& (h1.id == h2.id)
|
||||
&& (h1.profile == h2.profile);
|
||||
}
|
||||
|
@ -45,12 +45,15 @@ typedef struct {
|
||||
int header_bit_size, header_byte_size, data_byte_size;
|
||||
} aac_header_t;
|
||||
|
||||
bool MTX_DLL_API parse_aac_adif_header(unsigned char *buf, int size, aac_header_t *aac_header);
|
||||
int MTX_DLL_API find_aac_header(unsigned char *buf, int size, aac_header_t *aac_header, bool emphasis_present);
|
||||
bool MTX_DLL_API operator ==(const aac_header_t &h1, const aac_header_t &h2);
|
||||
|
||||
bool MTX_DLL_API parse_aac_adif_header(const unsigned char *buf, int size, aac_header_t *aac_header);
|
||||
int MTX_DLL_API find_aac_header(const unsigned char *buf, int size, aac_header_t *aac_header, bool emphasis_present);
|
||||
int MTX_DLL_API find_consecutive_aac_headers(const unsigned char *buf, int size, int num);
|
||||
|
||||
int MTX_DLL_API get_aac_sampling_freq_idx(int sampling_freq);
|
||||
|
||||
bool MTX_DLL_API parse_aac_data(unsigned char *data, int size, int &profile, int &channels, int &sample_rate, int &output_sample_rate, bool &sbr);
|
||||
bool MTX_DLL_API parse_aac_data(const unsigned char *data, int size, int &profile, int &channels, int &sample_rate, int &output_sample_rate, bool &sbr);
|
||||
int MTX_DLL_API create_aac_data(unsigned char *data, int profile, int channels, int sample_rate, int output_sample_rate, bool sbr);
|
||||
bool MTX_DLL_API parse_aac_codec_id(const string &codec_id, int &id, int &profile);
|
||||
|
||||
|
@ -22,49 +22,15 @@
|
||||
#include "p_aac.h"
|
||||
#include "output_control.h"
|
||||
|
||||
#define PROBESIZE 8192
|
||||
|
||||
int
|
||||
aac_reader_c::probe_file(mm_io_c *io,
|
||||
int64_t size) {
|
||||
unsigned char buf[PROBESIZE];
|
||||
aac_header_t aacheader;
|
||||
int pos;
|
||||
|
||||
if (size < PROBESIZE)
|
||||
return 0;
|
||||
try {
|
||||
io->setFilePointer(0, seek_beginning);
|
||||
skip_id3v2_tag(*io);
|
||||
if (io->read(buf, PROBESIZE) != PROBESIZE)
|
||||
io->setFilePointer(0, seek_beginning);
|
||||
io->setFilePointer(0, seek_beginning);
|
||||
} catch (...) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (parse_aac_adif_header(buf, PROBESIZE, &aacheader))
|
||||
return 1;
|
||||
|
||||
pos = find_aac_header(buf, PROBESIZE, &aacheader, false);
|
||||
if ((0 > pos) || ((pos + aacheader.bytes) >= PROBESIZE)) {
|
||||
pos = find_aac_header(buf, PROBESIZE, &aacheader, true);
|
||||
if ((0 > pos) || ((pos + aacheader.bytes) >= PROBESIZE))
|
||||
return 0;
|
||||
pos = find_aac_header(&buf[pos + aacheader.bytes], PROBESIZE - pos - aacheader.bytes, &aacheader, true);
|
||||
if (0 != pos)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos = find_aac_header(&buf[pos + aacheader.bytes], PROBESIZE - pos - aacheader.bytes, &aacheader, false);
|
||||
if (0 != pos)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
int64_t size,
|
||||
int64_t probe_range,
|
||||
int num_headers) {
|
||||
return (find_valid_headers(io, probe_range, num_headers) != -1) ? 1 : 0;
|
||||
}
|
||||
|
||||
#define INITCHUNKSIZE 16384
|
||||
#define SINITCHUNKSIZE "16384"
|
||||
#define INITCHUNKSIZE 16384
|
||||
|
||||
aac_reader_c::aac_reader_c(track_info_c &_ti)
|
||||
throw (error_c):
|
||||
@ -219,3 +185,20 @@ aac_reader_c::identify() {
|
||||
id_result_container("AAC");
|
||||
id_result_track(0, ID_RESULT_TRACK_AUDIO, "AAC", verbose_info);
|
||||
}
|
||||
|
||||
int
|
||||
aac_reader_c::find_valid_headers(mm_io_c *io,
|
||||
int64_t probe_range,
|
||||
int num_headers) {
|
||||
try {
|
||||
io->setFilePointer(0, seek_beginning);
|
||||
memory_cptr buf = memory_c::alloc(probe_range);
|
||||
int num_read = io->read(buf->get(), probe_range);
|
||||
int pos = find_consecutive_aac_headers(buf->get(), num_read, num_headers);
|
||||
io->setFilePointer(0, seek_beginning);
|
||||
|
||||
return pos;
|
||||
} catch (...) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -42,10 +42,11 @@ public:
|
||||
virtual int get_progress();
|
||||
virtual void create_packetizer(int64_t id);
|
||||
|
||||
static int probe_file(mm_io_c *io, int64_t size);
|
||||
static int probe_file(mm_io_c *io, int64_t size, int64_t probe_range, int num_headers);
|
||||
|
||||
protected:
|
||||
virtual void guess_adts_version();
|
||||
static int find_valid_headers(mm_io_c *io, int64_t probe_range, int num_headers);
|
||||
};
|
||||
|
||||
#endif // __R_AAC_H
|
||||
|
@ -353,6 +353,8 @@ get_file_type(filelist_t &file) {
|
||||
type = FILE_TYPE_MP3;
|
||||
else if (ac3_reader_c::probe_file(io, size, probe_sizes[i], 5))
|
||||
type = FILE_TYPE_AC3;
|
||||
else if (aac_reader_c::probe_file(io, size, probe_sizes[i], 5))
|
||||
type = FILE_TYPE_AAC;
|
||||
}
|
||||
// More file types with detection issues.
|
||||
if (type != FILE_TYPE_IS_UNKNOWN)
|
||||
@ -363,8 +365,6 @@ get_file_type(filelist_t &file) {
|
||||
type = FILE_TYPE_MP3;
|
||||
else if (dts_reader_c::probe_file(io, size))
|
||||
type = FILE_TYPE_DTS;
|
||||
else if (aac_reader_c::probe_file(io, size))
|
||||
type = FILE_TYPE_AAC;
|
||||
else if (vobbtn_reader_c::probe_file(io, size))
|
||||
type = FILE_TYPE_VOBBTN;
|
||||
else if (avc_es_reader_c::probe_file(io, size))
|
||||
|
Loading…
Reference in New Issue
Block a user