mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 20:01:53 +00:00
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.
This commit is contained in:
parent
5d2e36dc92
commit
4d3b90a3ee
@ -1,3 +1,7 @@
|
|||||||
|
2004-01-23 Moritz Bunkus <moritz@bunkus.org>
|
||||||
|
|
||||||
|
* mkvmerge: bug fix: The AAC-in-Real stuff again.
|
||||||
|
|
||||||
2004-01-22 Moritz Bunkus <moritz@bunkus.org>
|
2004-01-22 Moritz Bunkus <moritz@bunkus.org>
|
||||||
|
|
||||||
* mkvmerge: Changed the complete timecode handling from ms
|
* mkvmerge: Changed the complete timecode handling from ms
|
||||||
|
@ -202,9 +202,16 @@ parse_aac_data(unsigned char *data,
|
|||||||
int &sample_rate,
|
int &sample_rate,
|
||||||
int &output_sample_rate,
|
int &output_sample_rate,
|
||||||
bool &sbr) {
|
bool &sbr) {
|
||||||
|
int i;
|
||||||
|
|
||||||
if (size < 2)
|
if (size < 2)
|
||||||
return false;
|
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;
|
profile = (data[0] >> 3) - 1;
|
||||||
sample_rate = aac_sampling_freq[((data[0] & 0x07) << 1) | (data[1] >> 7)];
|
sample_rate = aac_sampling_freq[((data[0] & 0x07) << 1) | (data[1] >> 7)];
|
||||||
channels = (data[1] & 0x7f) >> 3;
|
channels = (data[1] & 0x7f) >> 3;
|
||||||
|
@ -190,6 +190,7 @@ real_reader_c::~real_reader_c() {
|
|||||||
delete demuxer->segments;
|
delete demuxer->segments;
|
||||||
}
|
}
|
||||||
safefree(demuxer->private_data);
|
safefree(demuxer->private_data);
|
||||||
|
safefree(demuxer->extra_data);
|
||||||
safefree(demuxer);
|
safefree(demuxer);
|
||||||
}
|
}
|
||||||
demuxers.clear();
|
demuxers.clear();
|
||||||
@ -393,10 +394,12 @@ real_reader_c::parse_headers() {
|
|||||||
dmx->samples_per_second = get_uint16_be(&ra5p->sample_rate);
|
dmx->samples_per_second = get_uint16_be(&ra5p->sample_rate);
|
||||||
dmx->bits_per_sample = get_uint16_be(&ra5p->sample_size);
|
dmx->bits_per_sample = get_uint16_be(&ra5p->sample_size);
|
||||||
if (size > (sizeof(real_audio_v5_props_t) + 4)) {
|
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 -
|
dmx->extra_data_size = size - 4 -
|
||||||
sizeof(real_audio_v5_props_t);
|
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",
|
mxverb(2, "real_reader: extra_data_size: %d\n",
|
||||||
@ -545,7 +548,6 @@ real_reader_c::create_packetizer(int64_t tid) {
|
|||||||
dmx->packetizer =
|
dmx->packetizer =
|
||||||
new aac_packetizer_c(this, AAC_ID_MPEG4, profile,
|
new aac_packetizer_c(this, AAC_ID_MPEG4, profile,
|
||||||
sample_rate, channels, ti, false, true);
|
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 "
|
mxverb(1, "+-> Using the AAC output module for stream "
|
||||||
"%u (FourCC: %s).\n", dmx->id, dmx->fourcc);
|
"%u (FourCC: %s).\n", dmx->id, dmx->fourcc);
|
||||||
if (profile == AAC_PROFILE_SBR)
|
if (profile == AAC_PROFILE_SBR)
|
||||||
@ -619,10 +621,6 @@ real_reader_c::finish() {
|
|||||||
for (i = 0; i < demuxers.size(); i++) {
|
for (i = 0; i < demuxers.size(); i++) {
|
||||||
dmx = demuxers[i];
|
dmx = demuxers[i];
|
||||||
if ((dmx->type == 'a') && (dmx->c_data != NULL)) {
|
if ((dmx->type == 'a') && (dmx->c_data != NULL)) {
|
||||||
if (dmx->is_aac) {
|
|
||||||
safefree(dmx->c_data);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
dur = dmx->c_timecode / dmx->c_numpackets;
|
dur = dmx->c_timecode / dmx->c_numpackets;
|
||||||
dmx->packetizer->process(dmx->c_data, dmx->c_len, dmx->c_timecode + dur,
|
dmx->packetizer->process(dmx->c_data, dmx->c_len, dmx->c_timecode + dur,
|
||||||
dur, dmx->c_keyframe ? -1 : dmx->c_reftimecode);
|
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);
|
assemble_packet(dmx, chunk, length, timecode, (flags & 2) == 2);
|
||||||
safefree(chunk);
|
safefree(chunk);
|
||||||
|
|
||||||
} else if (dmx->is_aac) {
|
} 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deliver_aac_frames(dmx, chunk, length);
|
deliver_aac_frames(dmx, chunk, length);
|
||||||
|
|
||||||
} else {
|
else {
|
||||||
if (dmx->c_data != NULL)
|
if (dmx->c_data != NULL)
|
||||||
dmx->packetizer->process(dmx->c_data, dmx->c_len, dmx->c_timecode,
|
dmx->packetizer->process(dmx->c_data, dmx->c_len, dmx->c_timecode,
|
||||||
timecode - dmx->c_timecode,
|
timecode - dmx->c_timecode,
|
||||||
|
@ -51,7 +51,8 @@ aac_packetizer_c::aac_packetizer_c(generic_reader_c *nreader,
|
|||||||
emphasis_present = nemphasis_present;
|
emphasis_present = nemphasis_present;
|
||||||
|
|
||||||
set_track_type(track_audio);
|
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);
|
duplicate_data_on_add(headerless);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ aac_packetizer_c::get_aac_packet(unsigned long *header,
|
|||||||
if ((pos + aacheader->bytes) > size)
|
if ((pos + aacheader->bytes) > size)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pins = samples_per_packet * 1000000000.0 / samples_per_sec;
|
pins = 1024 * 1000000000.0 / samples_per_sec;
|
||||||
|
|
||||||
if (needs_negative_displacement(pins)) {
|
if (needs_negative_displacement(pins)) {
|
||||||
/*
|
/*
|
||||||
@ -184,9 +185,9 @@ aac_packetizer_c::process(unsigned char *buf,
|
|||||||
if (timecode != -1)
|
if (timecode != -1)
|
||||||
my_timecode = timecode;
|
my_timecode = timecode;
|
||||||
else
|
else
|
||||||
my_timecode = (int64_t)(1000000000.0 * packetno * samples_per_packet /
|
my_timecode = (int64_t)(1024 * 1000000000.0 * packetno /
|
||||||
samples_per_sec);
|
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);
|
samples_per_sec);
|
||||||
packetno++;
|
packetno++;
|
||||||
|
|
||||||
@ -211,13 +212,13 @@ aac_packetizer_c::process(unsigned char *buf,
|
|||||||
byte_buffer.add(buf, size);
|
byte_buffer.add(buf, size);
|
||||||
while ((packet = get_aac_packet(&header, &aacheader)) != NULL) {
|
while ((packet = get_aac_packet(&header, &aacheader)) != NULL) {
|
||||||
if (timecode == -1)
|
if (timecode == -1)
|
||||||
my_timecode = (int64_t)(1000000000.0 * packetno * samples_per_packet /
|
my_timecode = (int64_t)(1024 * 1000000000.0 * packetno /
|
||||||
samples_per_sec);
|
samples_per_sec);
|
||||||
else
|
else
|
||||||
my_timecode = timecode + ti->async.displacement;
|
my_timecode = timecode + ti->async.displacement;
|
||||||
my_timecode = (int64_t)(my_timecode * ti->async.linear);
|
my_timecode = (int64_t)(my_timecode * ti->async.linear);
|
||||||
add_packet(packet, aacheader.data_byte_size, my_timecode,
|
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));
|
ti->async.linear / samples_per_sec));
|
||||||
packetno++;
|
packetno++;
|
||||||
}
|
}
|
||||||
@ -228,16 +229,7 @@ aac_packetizer_c::process(unsigned char *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
aac_packetizer_c::set_samples_per_packet(int nsamples_per_packet) {
|
aac_packetizer_c::dump_debug_info() {
|
||||||
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() {
|
|
||||||
mxdebug("aac_packetizer_c: queue: %d; buffer size: %d\n",
|
mxdebug("aac_packetizer_c: queue: %d; buffer size: %d\n",
|
||||||
packet_queue.size(), byte_buffer.get_size());
|
packet_queue.size(), byte_buffer.get_size());
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ class aac_packetizer_c: public generic_packetizer_c {
|
|||||||
private:
|
private:
|
||||||
int64_t bytes_output, packetno;
|
int64_t bytes_output, packetno;
|
||||||
unsigned long samples_per_sec;
|
unsigned long samples_per_sec;
|
||||||
int channels, id, profile, samples_per_packet;
|
int channels, id, profile;
|
||||||
bool headerless, emphasis_present;
|
bool headerless, emphasis_present;
|
||||||
byte_buffer_c byte_buffer;
|
byte_buffer_c byte_buffer;
|
||||||
|
|
||||||
@ -56,7 +56,6 @@ public:
|
|||||||
int64_t length = -1, int64_t bref = -1,
|
int64_t length = -1, int64_t bref = -1,
|
||||||
int64_t fref = -1);
|
int64_t fref = -1);
|
||||||
virtual void set_headers();
|
virtual void set_headers();
|
||||||
virtual void set_samples_per_packet(int nsamples_per_packet);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual unsigned char *get_aac_packet(unsigned long *header,
|
virtual unsigned char *get_aac_packet(unsigned long *header,
|
||||||
|
Loading…
Reference in New Issue
Block a user