From 4905caf9633efa5cca944a3e5cc51337c1b41225 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Sun, 9 Mar 2008 16:02:08 +0000 Subject: [PATCH] Added support for AAC files with ID3 tags. --- ChangeLog | 3 ++ src/input/r_aac.cpp | 69 ++++++++++++++++++++---------- tests/results.txt | 1 + tests/test-239aac_with_id3_tags.rb | 13 ++++++ 4 files changed, 63 insertions(+), 23 deletions(-) create mode 100644 tests/test-239aac_with_id3_tags.rb diff --git a/ChangeLog b/ChangeLog index 01cbd589d..bdff0a090 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2008-03-09 Moritz Bunkus + * mkvmerge: new feature: Added support for skipping ID3 tags in + AAC files. + * mkvmerge: new feature: Added support for DTS-HD (both "master audio" and "high resolution"). diff --git a/src/input/r_aac.cpp b/src/input/r_aac.cpp index dbfe29ddc..b3ae2ba7f 100644 --- a/src/input/r_aac.cpp +++ b/src/input/r_aac.cpp @@ -20,6 +20,7 @@ #include "common.h" #include "error.h" +#include "id3_common.h" #include "r_aac.h" #include "p_aac.h" #include "output_control.h" @@ -37,26 +38,28 @@ aac_reader_c::probe_file(mm_io_c *io, 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 ((pos < 0) || ((pos + aacheader.bytes) >= PROBESIZE)) { pos = find_aac_header(buf, PROBESIZE, &aacheader, true); if ((pos < 0) || ((pos + aacheader.bytes) >= PROBESIZE)) return 0; - pos = find_aac_header(&buf[pos + aacheader.bytes], PROBESIZE - pos - - aacheader.bytes, &aacheader, true); + pos = find_aac_header(&buf[pos + aacheader.bytes], PROBESIZE - pos - aacheader.bytes, &aacheader, true); if (pos != 0) return 0; } - pos = find_aac_header(&buf[pos + aacheader.bytes], PROBESIZE - pos - - aacheader.bytes, &aacheader, false); + + pos = find_aac_header(&buf[pos + aacheader.bytes], PROBESIZE - pos - aacheader.bytes, &aacheader, false); if (pos != 0) return 0; @@ -73,26 +76,38 @@ aac_reader_c::aac_reader_c(track_info_c &_ti) int adif, detected_profile; try { - io = new mm_file_io_c(ti.fname); - size = io->get_size(); - chunk = (unsigned char *)safemalloc(INITCHUNKSIZE); - if (io->read(chunk, INITCHUNKSIZE) != INITCHUNKSIZE) - throw error_c("aac_reader: Could not read " SINITCHUNKSIZE " bytes."); - io->setFilePointer(0, seek_beginning); - if (parse_aac_adif_header(chunk, INITCHUNKSIZE, &aacheader)) { + io = new mm_file_io_c(ti.fname); + size = io->get_size(); + + int tag_size_start = skip_id3v2_tag(*io); + int tag_size_end = id3_tag_present_at_end(*io); + + if (0 > tag_size_start) + tag_size_start = 0; + if (0 < tag_size_end) + size -= tag_size_end; + + int init_read_len = MXMIN(size - tag_size_start, INITCHUNKSIZE); + chunk = (unsigned char *)safemalloc(INITCHUNKSIZE); + + if (io->read(chunk, init_read_len) != init_read_len) + throw error_c(mxsprintf("aac_reader: Could not read %d bytes.", init_read_len)); + + io->setFilePointer(tag_size_start, seek_beginning); + + if (parse_aac_adif_header(chunk, init_read_len, &aacheader)) { throw error_c("aac_reader: ADIF header files are not supported."); adif = 1; + } else { - if (find_aac_header(chunk, INITCHUNKSIZE, &aacheader, emphasis_present) - != 0) - throw error_c("aac_reader: No valid AAC packet found in the first " - SINITCHUNKSIZE " bytes.\n"); + if (find_aac_header(chunk, init_read_len, &aacheader, emphasis_present) != 0) + throw error_c(mxsprintf("aac_reader: No valid AAC packet found in the first %d bytes.\n", init_read_len)); guess_adts_version(); adif = 0; } - bytes_processed = 0; - ti.id = 0; // ID for this track. + ti.id = 0; // ID for this track. + bytes_processed = 0; detected_profile = aacheader.profile; if (24000 >= aacheader.sample_rate) @@ -113,6 +128,7 @@ aac_reader_c::aac_reader_c(track_info_c &_ti) } catch (...) { throw error_c("aac_reader: Could not open the file."); } + if (verbose) mxinfo(FMT_FN "Using the AAC demultiplexer.\n", ti.fname.c_str()); } @@ -176,17 +192,24 @@ aac_reader_c::guess_adts_version() { file_status_e aac_reader_c::read(generic_packetizer_c *, bool) { - int nread; + int remaining_bytes = size - io->getFilePointer(); + int read_len = MXMIN(INITCHUNKSIZE, remaining_bytes); + int num_read = io->read(chunk, read_len); - nread = io->read(chunk, 4096); - if (nread <= 0) { + if (num_read < 0) { PTZR0->flush(); return FILE_STATUS_DONE; } - PTZR0->process(new packet_t(new memory_c(chunk, nread, false))); - bytes_processed += nread; - return FILE_STATUS_MOREDATA; + PTZR0->process(new packet_t(new memory_c(chunk, num_read, false))); + bytes_processed += num_read; + + if ((remaining_bytes - num_read) > 0) + return FILE_STATUS_MOREDATA; + + PTZR0->flush(); + + return FILE_STATUS_DONE; } int diff --git a/tests/results.txt b/tests/results.txt index 03d2cf491..b9dda5c8a 100644 --- a/tests/results.txt +++ b/tests/results.txt @@ -86,3 +86,4 @@ T_235wav_fmt_chunk_length:2eff110d0ccae554d7cb5da4c337dc48:passed:20080226-13454 T_236ac3_in_mov:31555c8af38f9c00435fa17b40258554:passed:20080229-103912 T_237ac3_in_wav_iec61937_mode:e9643247b6e39a5860797c8f69ba0767:passed:20080229-152103 T_238ac3_in_wav_acm_mode:90e1ee4c9eab7d9c8a7f208065a13c86:passed:20080229-152339 +T_239aac_with_id3_tags:acd6eaf5b25d73bdbc9a7ed9a150f0ec:passed:20080309-170151 diff --git a/tests/test-239aac_with_id3_tags.rb b/tests/test-239aac_with_id3_tags.rb new file mode 100644 index 000000000..61740135c --- /dev/null +++ b/tests/test-239aac_with_id3_tags.rb @@ -0,0 +1,13 @@ +#!/usr/bin/ruby -w + +class T_239aac_with_id3_tags < Test + def description + return "mkvmerge / AAC with ID3v1 and v2 tags / in(AAC)" + end + + def run + merge(1, "data/simple/aac-with-id3-tags.aac") + return hash_tmp + end +end +