From 4d3b90a3ee44b87ba2776ad9c7363f271a8832e2 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Fri, 23 Jan 2004 19:15:12 +0000 Subject: [PATCH] Allocate space for the extra data after the RealMedia headers - otherwise the pointers would be invalid. Removed the "set number of samples per packet" function from the AAC packetizer as AAC is still always 1024 samples/packet. --- ChangeLog | 4 ++++ src/common/aac_common.cpp | 7 ++++++ src/input/r_real.cpp | 50 ++++++--------------------------------- src/output/p_aac.cpp | 24 +++++++------------ src/output/p_aac.h | 3 +-- 5 files changed, 27 insertions(+), 61 deletions(-) diff --git a/ChangeLog b/ChangeLog index ca8a7eb84..c11dac849 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2004-01-23 Moritz Bunkus + + * mkvmerge: bug fix: The AAC-in-Real stuff again. + 2004-01-22 Moritz Bunkus * mkvmerge: Changed the complete timecode handling from ms diff --git a/src/common/aac_common.cpp b/src/common/aac_common.cpp index 7aa6d0891..55c31a2ec 100644 --- a/src/common/aac_common.cpp +++ b/src/common/aac_common.cpp @@ -202,9 +202,16 @@ parse_aac_data(unsigned char *data, int &sample_rate, int &output_sample_rate, bool &sbr) { + int i; + if (size < 2) return false; + mxverb(4, "parse_aac_data: size %d, data: 0x", size); + for (i = 0; i < size; i++) + mxverb(4, "%02x ", data[i]); + mxverb(4, "\n"); + profile = (data[0] >> 3) - 1; sample_rate = aac_sampling_freq[((data[0] & 0x07) << 1) | (data[1] >> 7)]; channels = (data[1] & 0x7f) >> 3; diff --git a/src/input/r_real.cpp b/src/input/r_real.cpp index f492a6744..54252063c 100644 --- a/src/input/r_real.cpp +++ b/src/input/r_real.cpp @@ -190,6 +190,7 @@ real_reader_c::~real_reader_c() { delete demuxer->segments; } safefree(demuxer->private_data); + safefree(demuxer->extra_data); safefree(demuxer); } demuxers.clear(); @@ -393,10 +394,12 @@ real_reader_c::parse_headers() { dmx->samples_per_second = get_uint16_be(&ra5p->sample_rate); dmx->bits_per_sample = get_uint16_be(&ra5p->sample_size); if (size > (sizeof(real_audio_v5_props_t) + 4)) { - dmx->extra_data = (unsigned char *)(ra5p + 1); - dmx->extra_data += 4; dmx->extra_data_size = size - 4 - sizeof(real_audio_v5_props_t); + dmx->extra_data = + (unsigned char *)safememdup((unsigned char *)ra5p + 4 + + sizeof(real_audio_v5_props_t), + dmx->extra_data_size); } } mxverb(2, "real_reader: extra_data_size: %d\n", @@ -545,7 +548,6 @@ real_reader_c::create_packetizer(int64_t tid) { dmx->packetizer = new aac_packetizer_c(this, AAC_ID_MPEG4, profile, sample_rate, channels, ti, false, true); - ((aac_packetizer_c *)dmx->packetizer)->set_samples_per_packet(2048); mxverb(1, "+-> Using the AAC output module for stream " "%u (FourCC: %s).\n", dmx->id, dmx->fourcc); if (profile == AAC_PROFILE_SBR) @@ -619,10 +621,6 @@ real_reader_c::finish() { for (i = 0; i < demuxers.size(); i++) { dmx = demuxers[i]; if ((dmx->type == 'a') && (dmx->c_data != NULL)) { - if (dmx->is_aac) { - safefree(dmx->c_data); - continue; - } dur = dmx->c_timecode / dmx->c_numpackets; dmx->packetizer->process(dmx->c_data, dmx->c_len, dmx->c_timecode + dur, dur, dmx->c_keyframe ? -1 : dmx->c_reftimecode); @@ -708,44 +706,10 @@ real_reader_c::read(generic_packetizer_c *) { assemble_packet(dmx, chunk, length, timecode, (flags & 2) == 2); safefree(chunk); - } else if (dmx->is_aac) { - if ((dmx->c_data == NULL) && (dmx->c_numpackets == 0)) { - // Cache the very first packet in order to find the number of - // samples per AAC frame ( = the duration). - dmx->c_data = chunk; - dmx->c_len = length; - dmx->c_timecode = timecode; - dmx->c_numpackets = 1; - return EMOREDATA; - - } else if (dmx->c_data != NULL) { - if ((dmx->c_len < 2) || ((dmx->c_data[1] & 0xf0) == 0)) - mxerror("real_reader: The AAC track %u of '%s' contains an invalid " - "data packet (either it's too short or the number of " - "AAC sub packets is 0). Aborting.\n", dmx->id, ti->fname); - - // We've got the first packet cached. Now calculate the number of - // samples and store that in dmx->c_reftimecode. - dmx->c_reftimecode = (timecode - dmx->c_timecode) * - dmx->samples_per_second / 1000000000; - // Now devide the number of samples in this first packet by the - // number of AAC frames in that packet. Also round it to the nearest - // power of 2. - dmx->c_reftimecode /= chunk[1] >> 4; - dmx->c_reftimecode = round_to_nearest_pow2(dmx->c_reftimecode); - deliver_aac_frames(dmx, dmx->c_data, dmx->c_len); - dmx->c_data = NULL; - mxverb(2, "real_reader: %u/'%s': Samples per AAC frame: %lld\n", - dmx->id, ti->fname, dmx->c_reftimecode); - if (dmx->c_reftimecode != 2048) { - ((aac_packetizer_c *)dmx->packetizer)-> - set_samples_per_packet(dmx->c_reftimecode); - rerender_track_headers(); - } - } + } else if (dmx->is_aac) deliver_aac_frames(dmx, chunk, length); - } else { + else { if (dmx->c_data != NULL) dmx->packetizer->process(dmx->c_data, dmx->c_len, dmx->c_timecode, timecode - dmx->c_timecode, diff --git a/src/output/p_aac.cpp b/src/output/p_aac.cpp index 6d3ab22b5..ee7ead7b2 100644 --- a/src/output/p_aac.cpp +++ b/src/output/p_aac.cpp @@ -51,7 +51,8 @@ aac_packetizer_c::aac_packetizer_c(generic_reader_c *nreader, emphasis_present = nemphasis_present; set_track_type(track_audio); - set_samples_per_packet(1024); + set_track_default_duration((int64_t)(1024 * 1000000000.0 * ti->async.linear / + samples_per_sec)); duplicate_data_on_add(headerless); } @@ -73,7 +74,7 @@ aac_packetizer_c::get_aac_packet(unsigned long *header, if ((pos + aacheader->bytes) > size) return NULL; - pins = samples_per_packet * 1000000000.0 / samples_per_sec; + pins = 1024 * 1000000000.0 / samples_per_sec; if (needs_negative_displacement(pins)) { /* @@ -184,9 +185,9 @@ aac_packetizer_c::process(unsigned char *buf, if (timecode != -1) my_timecode = timecode; else - my_timecode = (int64_t)(1000000000.0 * packetno * samples_per_packet / + my_timecode = (int64_t)(1024 * 1000000000.0 * packetno / samples_per_sec); - duration = (int64_t)(1000000000.0 * samples_per_packet * ti->async.linear / + duration = (int64_t)(1024 * 1000000000.0 * ti->async.linear / samples_per_sec); packetno++; @@ -211,13 +212,13 @@ aac_packetizer_c::process(unsigned char *buf, byte_buffer.add(buf, size); while ((packet = get_aac_packet(&header, &aacheader)) != NULL) { if (timecode == -1) - my_timecode = (int64_t)(1000000000.0 * packetno * samples_per_packet / + my_timecode = (int64_t)(1024 * 1000000000.0 * packetno / samples_per_sec); else my_timecode = timecode + ti->async.displacement; my_timecode = (int64_t)(my_timecode * ti->async.linear); add_packet(packet, aacheader.data_byte_size, my_timecode, - (int64_t)(1000000000.0 * samples_per_packet * + (int64_t)(1024 * 1000000000.0 * ti->async.linear / samples_per_sec)); packetno++; } @@ -228,16 +229,7 @@ aac_packetizer_c::process(unsigned char *buf, } void -aac_packetizer_c::set_samples_per_packet(int nsamples_per_packet) { - samples_per_packet = nsamples_per_packet; - if (use_durations) - set_track_default_duration((int64_t)(samples_per_packet * - 1000000000.0 * - ti->async.linear / - samples_per_sec)); -} - -void aac_packetizer_c::dump_debug_info() { +aac_packetizer_c::dump_debug_info() { mxdebug("aac_packetizer_c: queue: %d; buffer size: %d\n", packet_queue.size(), byte_buffer.get_size()); } diff --git a/src/output/p_aac.h b/src/output/p_aac.h index 43688ffc2..b7f650bac 100644 --- a/src/output/p_aac.h +++ b/src/output/p_aac.h @@ -41,7 +41,7 @@ class aac_packetizer_c: public generic_packetizer_c { private: int64_t bytes_output, packetno; unsigned long samples_per_sec; - int channels, id, profile, samples_per_packet; + int channels, id, profile; bool headerless, emphasis_present; byte_buffer_c byte_buffer; @@ -56,7 +56,6 @@ public: int64_t length = -1, int64_t bref = -1, int64_t fref = -1); virtual void set_headers(); - virtual void set_samples_per_packet(int nsamples_per_packet); private: virtual unsigned char *get_aac_packet(unsigned long *header,