[FFmpeg-trac] #369(avcodec:new): Multichannel encoding with the native aac encoder crashes
FFmpeg
trac at avcodec.org
Fri Jul 29 13:50:24 CEST 2011
#369: Multichannel encoding with the native aac encoder crashes
---------------------------+----------------------
Reporter: cehoyos | Owner:
Type: defect | Status: new
Priority: important | Component: avcodec
Version: git-master | Resolution:
Keywords: aac regression | Blocked By:
Blocking: | Reproduced: 0
Analyzed: 0 |
---------------------------+----------------------
Comment (by danijel):
I recreated your crash, but for me it ended up in a different place.
Nevertheless I think I know what might be a problem. This is the gdb dump
in my case:
{{{
(gdb) r -i Canyon-5.1-48khz-448kbit.ac3 -strict experimental out.aac
Starting program: /home/guest/ffmpeg/test/bin/ffmpeg -i Canyon-5.1-48khz-
448kbit
.ac3 -strict experimental out.aac
[Thread debugging using libthread_db enabled]
ffmpeg version N-31617-g4095fa9, Copyright (c) 2000-2011 the FFmpeg
developers
built on Jul 29 2011 12:42:33 with gcc 4.6.1
configuration: --prefix=/home/guest/ffmpeg/test --pkg-config=pkg-config
--enab
le-shared --disable-static --enable-runtime-cpudetect --enable-debug=3
--disable
-optimizations --disable-stripping
libavutil 51. 11. 0 / 51. 11. 0
libavcodec 53. 8. 0 / 53. 8. 0
libavformat 53. 6. 0 / 53. 6. 0
libavdevice 53. 2. 0 / 53. 2. 0
libavfilter 2. 27. 2 / 2. 27. 2
libswscale 2. 0. 0 / 2. 0. 0
[ac3 @ 0x806a380] max_analyze_duration 5000000 reached at 5024000
[ac3 @ 0x806a380] Estimating duration from bitrate, this may be inaccurate
Input #0, ac3, from 'Canyon-5.1-48khz-448kbit.ac3':
Duration: 00:00:37.98, start: 0.000000, bitrate: 448 kb/s
Stream #0.0: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
File 'out.aac' already exists. Overwrite ? [y/N] y
Output #0, adts, to 'out.aac':
Metadata:
encoder : Lavf53.6.0
Stream #0.0: Audio: aac, 48000 Hz, 5.1, s16, 64 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Press [q] to stop, [?] for help
Program received signal SIGSEGV, Segmentation fault.
0xb731384f in psy_3gpp_analyze_channel (ctx=0x80668ec, channel=6,
coefs=0xb65e62c0, wi=0xbfffe554) at libavcodec/aacpsy.c:599
599 bands[g].thr = FFMAX(bands[g].thr, bands[g-1].thr *
coeffs[
g].spread_hi[0]);
}}}
The code in question being:
{{{
(gdb) list 576,603
576 for (w = 0; w < wi->num_windows*16; w += 16) {
577 for (g = 0; g < num_bands; g++) {
578 AacPsyBand *band = &pch->band[w+g];
579
580 float form_factor = 0.0f;
581 band->energy = 0.0f;
582 for (i = 0; i < band_sizes[g]; i++) {
583 band->energy += coefs[start+i] * coefs[start+i];
584 form_factor += sqrtf(fabs(coefs[start+i]));
585 }
586 band->thr = band->energy * 0.001258925f;
587 band->nz_lines = form_factor / powf(band->energy /
band_sizes[g], 0.25f);
588
589 start += band_sizes[g];
590 }
591 }
592 //modify thresholds and energies - spread, threshold in quiet,
pre-e---Type <return> to continue, or q <return> to quit---
cho control
593 for (w = 0; w < wi->num_windows*16; w += 16) {
594 AacPsyBand *bands = &pch->band[w];
595
596 //5.4.2.3 "Spreading" & 5.4.3 "Spreaded Energy Calculation"
597 spread_en[0] = bands[0].energy;
598 for (g = 1; g < num_bands; g++) {
599 bands[g].thr = FFMAX(bands[g].thr, bands[g-1].thr *
coeffs[g].spread_hi[0]);
600 spread_en[w+g] = FFMAX(bands[g].energy, spread_en[w+g-1] *
coeffs[g].spread_hi[1]);
601 }
602 for (g = num_bands - 2; g >= 0; g--) {
603 bands[g].thr = FFMAX(bands[g].thr, bands[g+1].thr *
coeffs[g].spread_low[0]);
}}}
My error is in line 599 and yours in 583. I will now show how I analyzed
my bug and you can do the same yourself to confirm the error.
If I print the bands variable it turns out to be NULL:
{{{
(gdb) p bands
$8 = (AacPsyBand *) 0x0
}}}
Which is strange since it's being set properly to {{{AacPsyBand *bands =
&pch->band[w];}}} a few lines earlier and not changed anywhere else in
that loop. If we print the second half of that expression we get a valid
pointer:
{{{
(gdb) p &pch->band[w]
$10 = (AacPsyBand *) 0x80f1f28
}}}
Clearly the error is some sort of a memory leak causing overwriting local
variables. If we look at what's really happening we can see that
{{{bands}}} is set to a certain offset of {{{pch->band}}} array
({{{&pch->band[w]}}} is the same as {{{pch->band+w}}}) where the array is
set to a static size of 128 as shown under this link:
http://ffmpeg.org/doxygen/trunk/structAacPsyChannel.html
This array is then iterated from the starting offset of 96 (as shown by
command {{{p w}}}) and increased for {{{num_bands}}} times which is 49.
Since 96+49 is more than 128, we get a memory leak. In fact, the SEGFAULT
happens way too late, since on my machine {{{g}}} is at value 44 when the
OS realizes the error:
{{{
(gdb) p w
$12 = 96
(gdb) p num_bands
$13 = 49
(gdb) p g
$14 = 44
}}}
I guess you could try and increase the static size of the {{{bands}}}
array to at least 596 (a bit more to make sure) in AacPsyChannel structure
located in libavcodec/aacpsy.c:117, but I'm not sure if that's how the
code is supposed to work. My conclusion is meerly by looking at the code.
I don't really know what it does. I think there is just a bad bug in here
somewhere cause the code seems to assume that num_bands is <16 and
wi->num_windows is <8.
--
Ticket URL: <https://ffmpeg.org/trac/ffmpeg/ticket/369#comment:1>
FFmpeg <http://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list