MP3 reader: handle big ID3 tags at the start of the file

This commit is contained in:
Moritz Bunkus 2015-03-03 18:15:15 +01:00
parent ca332aedc2
commit 096193c204
4 changed files with 51 additions and 5 deletions

View File

@ -1,5 +1,9 @@
2015-03-03 Moritz Bunkus <moritz@bunkus.org>
* mkvmerge: bug fix: Fixed file type detection for MP3 files with
big ID3 tags at the start of the file (e.g. if they contain cover
images).
* mkvinfo (Qt interface): enhancement: implemented support for
opening files via drag & drop.

View File

@ -16,6 +16,7 @@
#include "common/codec.h"
#include "common/error.h"
#include "common/hacks.h"
#include "common/id3.h"
#include "common/mm_io_x.h"
#include "input/r_mp3.h"
#include "merge/input_x.h"
@ -29,8 +30,15 @@ mp3_reader_c::probe_file(mm_io_c *in,
int64_t probe_range,
int num_headers,
bool require_zero_offset) {
int offset = find_valid_headers(*in, probe_range, num_headers);
return (require_zero_offset && (0 == offset)) || (!require_zero_offset && (0 <= offset));
try {
skip_id3v2_tag(*in);
auto offset = find_valid_headers(*in, probe_range, num_headers);
return (require_zero_offset && (0 == offset)) || (!require_zero_offset && (0 <= offset));
} catch (...) {
return 0;
}
}
mp3_reader_c::mp3_reader_c(const track_info_c &ti,
@ -43,16 +51,26 @@ mp3_reader_c::mp3_reader_c(const track_info_c &ti,
void
mp3_reader_c::read_headers() {
try {
int pos = find_valid_headers(*m_in, 2 * 1024 * 1024, 5);
auto tag_size_start = skip_id3v2_tag(*m_in);
auto tag_size_end = id3_tag_present_at_end(*m_in);
if (0 > tag_size_start)
tag_size_start = 0;
if (0 < tag_size_end)
m_size -= tag_size_end;
auto init_read_len = std::min(m_size - tag_size_start, static_cast<uint64_t>(CHUNK_SIZE));
int pos = find_valid_headers(*m_in, init_read_len, 5);
if (0 > pos)
throw mtx::input::header_parsing_x();
m_in->setFilePointer(pos, seek_beginning);
m_in->setFilePointer(tag_size_start + pos, seek_beginning);
m_in->read(m_chunk->get_buffer(), 4);
decode_mp3_header(m_chunk->get_buffer(), &m_mp3header);
m_in->setFilePointer(pos, seek_beginning);
m_in->setFilePointer(tag_size_start + pos, seek_beginning);
show_demuxer_info();
@ -103,11 +121,28 @@ mp3_reader_c::find_valid_headers(mm_io_c &io,
int num_headers) {
try {
io.setFilePointer(0, seek_beginning);
skip_id3v2_tag(io);
memory_cptr buf = memory_c::alloc(probe_range);
int nread = io.read(buf->get_buffer(), probe_range);
// auto header = mp3_header_t{};
// auto idx = find_mp3_header(buf->get_buffer(), std::min(nread, 32));
// if ((0 == idx) && decode_mp3_header(&buf->get_buffer()[idx], &header) && header.is_tag) {
// probe_range += header.framesize;
// buf->resize(probe_range);
// io.setFilePointer(0, seek_beginning);
// nread = io.read(buf->get_buffer(), probe_range);
// }
io.setFilePointer(0, seek_beginning);
return find_consecutive_mp3_headers(buf->get_buffer(), nread, num_headers);
// auto result = find_consecutive_mp3_headers(buf->get_buffer(), nread, num_headers);
// return -1 == result ? -1 : result + idx;
} catch (...) {
return -1;
}

View File

@ -316,3 +316,4 @@ T_467mpeg_ts_eac3_type_0xa1:6c97721782afd53bc41776abf2d7f445:passed:20150223-221
T_468extract_cues:337fe77a5fb2f3d30deea092820c7ae8-f58aa81140411b045ce403f4d07de361+b71e065b26dd67f03fff849f1cbb929a:passed:20150225-202605:0.373426759
T_469avi_keyframes:cabe8cc129d7e1f72476c606e7e0f0d2:passed:20150225-223922:0.055489645
T_470avi_idx1_video_not_00db:12e8b014a66eaefcce54fb128d9a0d52-7f247aaf4412b0b9fb181d22fd96a1db-bff4ad0da7ec16a0cec0ff41733a7539-bb304b822980242f8bc240e58d3dd1af-298d112e745133b54362b61a3edf2238-6fe2d394bf9d3814795860745c19865b:passed:20150227-215810:0.225420656
T_471mp3_bit_id3_tag_at_start_of_file:3ef78eaf47cfd2aac938ef783979048d-d0fc30e07d0e0d083eff4096f36818e3:passed:20150303-181432:1.035125698

View File

@ -0,0 +1,6 @@
#!/usr/bin/ruby -w
# T_471mp3_bit_id3_tag_at_start_of_file
describe "mkvmerge / MP3 files with big ID3 tags at the start of the file"
test_merge "data/mp3/big-id3-tag-at-start-of-file-1.mp3", :exit_code => :warning
test_merge "data/mp3/big-id3-tag-at-start-of-file-2.mp3"