[FFmpeg-devel] [PATCH] aacenc: Segmentation fault when frame contains samples with NaN values.
Anders Rein
are at vizrt.com
Mon Mar 10 16:47:51 CET 2014
On 03/07/2014 08:26 PM, Reimar Döffinger wrote:
> On Fri, Mar 07, 2014 at 04:41:19PM +0100, Anders Rein wrote:
>> On 03/07/2014 04:16 PM, Michael Niedermayer wrote:
>>> On Fri, Mar 07, 2014 at 04:08:25PM +0100, Anders Rein wrote:
>>>> The ffmpeg executable gave a segmentation fault when transcoding a
>>>> wmv file to mp4 (h264, aac). The segfault happend in the aac encoder
>>>> code and was caused by the wma2 decoder returning NaN samples. I
>>>> tried to find the bug in the wma2 decoder, but eventually gave up. I
>>>> did however add float clamping and checking for NaN in the aac
>>>> encoder to make it more robust and avoid segmentation faults.
>>> How can the NaN sample production be reproduced ?
>>> I dont think decoders should return NaN samples
>> Here is a link to the input file (I stripped away most of the file plus the
>> video stream for copyright reasons):
>> https://www.dropbox.com/s/4zzp03yes94mnrl/nan_example.wma
>>
>> Command line to reproduce the segmentation fault:
>> ffmpeg -i nan_example.wma -acodec aac -strict -2 out.mp4
>>
>> While I agree that decoders shouldn't return NaN samples, I also don't see
>> any reason to make the aac encoder more robust. An encoder shouldn't
>> segfault no matter what data is put into it right?
> IMHO robustness means understanding the issue and not have exploitable
> bugs as soon as somehow an NaN manages to sneak in.
> Though I suspect that the encoder cannot work properly if it
> gets values outside the 0-1 range and thus needs to be "protected"
> anyway.
> I found two issues:
> 1) aaccoder.c:79
> out[i] = (int)FFMIN(qc + 0.4054, (double)maxval);
> To me, this code is a giant WTF, I have no idea why it is done this way,
> but it's basically done in exactly the only possible way that
> will cause a crash with NaNs.
> Swapping the order of the FFMIN arguments for example would
> make it work correctly, however this way around the NaN will
> go through, and casting to int then gives INT_MIN.
> I also don't know what speaks against first converting
> to int and then doing FFMIN, except possible overflow issues?
>
>
> 2) cost calculation in quantize_and_encode_band_cost_template.
> If the cost returned is NaN there will be crashes later on.
> I have not analyzed in more detail, so those might be issues
> that can be triggered even without a NaN.
>
> A quick hack avoiding the crash would look like this:
> --- a/libavcodec/aaccoder.c
> +++ b/libavcodec/aaccoder.c
> @@ -76,7 +76,7 @@ static void quantize_bands(int *out, const float *in, const float *scaled,
> double qc;
> for (i = 0; i < size; i++) {
> qc = scaled[i] * Q34;
> - out[i] = (int)FFMIN(qc + 0.4054, (double)maxval);
> + out[i] = (int)FFMIN((double)maxval, qc + 0.4054);
> if (is_signed && in[i] < 0.0f) {
> out[i] = -out[i];
> }
> @@ -128,6 +128,7 @@ static av_always_inline float quantize_and_encode_band_cost_template(
> cost += in[i]*in[i];
> if (bits)
> *bits = 0;
> + if (cost != cost) cost = 0;
> return cost * lambda;
> }
> if (!scaled) {
> @@ -204,6 +205,7 @@ static av_always_inline float quantize_and_encode_band_cost_template(
>
> if (bits)
> *bits = resbits;
> + if (cost != cost) cost = 0;
> return cost;
> }
>
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
I think this looks much better than my patch. Is there any reason to not
include this patch?
More information about the ffmpeg-devel
mailing list