Ticket #1834 (closed defect: invalid)
swr_convert() results in integer division by zero exception
| Reported by: | mbradshaw | Owned by: | michael |
|---|---|---|---|
| Priority: | normal | Component: | swresample |
| Version: | git-master | Keywords: | |
| Cc: | Blocked By: | ||
| Blocking: | Reproduced by developer: | no | |
| Analyzed by developer: | no |
Description
Summary of the bug:
When I call swr_convert() I get an integer division by zero exception at 0x707c86ee. The disassembly around 0x707c86ee, should it help, is:
707C86AB je 707C86E4 707C86AD mov edx,dword ptr [ebx+4E8h] 707C86B3 test edx,edx 707C86B5 jne 707C8743 707C86BB mov dword ptr [esp+0Ch],edi 707C86BF mov dword ptr [esp+8],ebp 707C86C3 mov dword ptr [esp+4],esi 707C86C7 mov dword ptr [esp],eax 707C86CA mov dword ptr [esp+2Ch],ecx 707C86CE call 707C2AF4 707C86D3 mov ecx,dword ptr [esp+2Ch] 707C86D7 mov eax,ecx 707C86D9 add esp,3Ch 707C86DC pop ebx 707C86DD pop esi 707C86DE pop edi 707C86DF pop ebp 707C86E0 ret 707C86E1 lea esi,[esi] 707C86E4 test edi,edi 707C86E6 js 707C873C 707C86E8 mov eax,3FFFFFFFh 707C86ED cdq 707C86EE idiv eax,dword ptr [ebx+1B4h] 707C86F4 cdq 707C86F5 idiv eax,dword ptr [ebx+1B0h] 707C86FB cmp edi,eax 707C86FD jg 707C873C 707C86FF cmp edi,dword ptr [ebx+1B8h] 707C8705 jle 707C8724 707C8707 lea eax,[ebx+12Ch] 707C870D mov edx,edi 707C870F mov dword ptr [esp+2Ch],ecx 707C8713 call 707C77C8 707C8718 test eax,eax 707C871A mov ecx,dword ptr [esp+2Ch] 707C871E jns 707C8724 707C8720 mov ecx,eax 707C8722 jmp 707C86D7 707C8724 mov dword ptr [esp+54h],edi 707C8728 mov dword ptr [esp+50h],ebp 707C872C mov edx,esi 707C872E mov eax,ebx 707C8730 add esp,3Ch 707C8733 pop ebx 707C8734 pop esi 707C8735 pop edi 707C8736 pop ebp 707C8737 jmp 707C80B4 707C873C mov ecx,0FFFFFFEAh
This happens with more than just the attached sample file, but I've attached a file just in case. The very first call to swr_convert() results in this division by zero exception.
How to reproduce: (some lame sample code just to show when it's happening)
#include <iostream>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>
};
int main()
{
av_register_all();
AVFrame* frame = avcodec_alloc_frame();
if (!frame)
{
std::cout << "Error allocating the frame" << std::endl;
return 1;
}
AVFormatContext* formatContext = NULL;
if (avformat_open_input(&formatContext, "C:/Users/mbradshaw/Desktop/samples/TimeCode.mov", NULL, NULL) != 0)
{
av_free(frame);
std::cout << "Error opening the file" << std::endl;
return 1;
}
if (avformat_find_stream_info(formatContext, NULL) < 0)
{
av_free(frame);
av_close_input_file(formatContext);
std::cout << "Error finding the stream info" << std::endl;
return 1;
}
AVStream* audioStream = NULL;
for (unsigned int i = 0; i < formatContext->nb_streams; ++i)
{
if (formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
{
audioStream = formatContext->streams[i];
break;
}
}
if (audioStream == NULL)
{
av_free(frame);
av_close_input_file(formatContext);
std::cout << "Could not find any audio stream in the file" << std::endl;
return 1;
}
AVCodecContext* codecContext = audioStream->codec;
codecContext->codec = avcodec_find_decoder(codecContext->codec_id);
if (codecContext->codec == NULL)
{
av_free(frame);
av_close_input_file(formatContext);
std::cout << "Couldn't find a proper decoder" << std::endl;
return 1;
}
else if (avcodec_open2(codecContext, codecContext->codec, NULL) != 0)
{
av_free(frame);
av_close_input_file(formatContext);
std::cout << "Couldn't open the context with the decoder" << std::endl;
return 1;
}
SwrContext* swrContext = NULL;
swrContext = swr_alloc_set_opts(swrContext,
codecContext->channel_layout, // out channel layout
codecContext->sample_fmt, // out sample format
codecContext->sample_rate, // out sample rate
codecContext->channel_layout, // in channel layout
codecContext->sample_fmt, // in sample format
codecContext->sample_rate, // in sample rate
0, // log offset
NULL); // log context
if (!swrContext)
{
av_free(frame);
avcodec_close(codecContext);
av_close_input_file(formatContext);
std::cout << "Couldn't allocate and set the resampling context" << std::endl;
return 1;
}
int bufSize = av_samples_get_buffer_size(NULL, codecContext->channels, codecContext->sample_rate, codecContext->sample_fmt, 0);
uint8_t* buf = new uint8_t[bufSize];
AVPacket packet;
av_init_packet(&packet);
int packetCount = 0;
int decodedFrameCount = 0;
while (av_read_frame(formatContext, &packet) == 0)
{
++packetCount;
if (packet.stream_index == audioStream->index)
{
int frameFinished = 0;
avcodec_decode_audio4(codecContext, frame, &frameFinished, &packet);
if (frameFinished)
{
const uint8_t** in = (const uint8_t**)frame->extended_data;
uint8_t* out[SWR_CH_MAX] = {buf, NULL};
std::cout << "converted: " << swr_convert(swrContext, out, codecContext->sample_rate, in, frame->nb_samples) << std::endl;
}
}
av_free_packet(&packet);
}
delete [] buf;
swr_free(&swrContext);
av_free(frame);
avcodec_close(codecContext);
av_close_input_file(formatContext);
}
Attachments
Change History
comment:1 in reply to: ↑ description ; follow-up: ↓ 2 Changed 7 months ago by cehoyos
Replying to mbradshaw:
Summary of the bug:
When I call swr_convert() I get an integer division by zero exception at 0x707c86ee. The disassembly around 0x707c86ee, should it help, is:
The disassembly looks very odd, did you read http://ffmpeg.org/bugreports.html ?
Is the FPE reproducible with ffmpeg (the application)? If not, do you know why?
comment:2 in reply to: ↑ 1 Changed 7 months ago by mbradshaw
Replying to cehoyos:
Replying to mbradshaw:
Summary of the bug:
When I call swr_convert() I get an integer division by zero exception at 0x707c86ee. The disassembly around 0x707c86ee, should it help, is:
The disassembly looks very odd, did you read http://ffmpeg.org/bugreports.html ?
Heh, sorry, I forgot it was Intel syntax and not AT&T syntax. I've re-run the program (on OS X 10.6) with gdb and got the following:
Program received signal EXC_ARITHMETIC, Arithmetic exception. 0x0000000100632ba8 in realloc_audio (a=0x10185f9d0, count=1024) at libswresample/swresample.c:359 359 if(count < 0 || count > INT_MAX/2/a->bps/a->ch_count)
It looks like a->bps and a->ch_count are both zero.
(gdb) p *a
$5 = {
ch = {0x0 <repeats 32 times>},
data = 0x0,
ch_count = 0,
bps = 0,
count = 0,
planar = 0,
fmt = AV_SAMPLE_FMT_U8
}
Backtrace is (I'm not entirely sure why it says there's only two frames...):
(gdb) bt #0 0x0000000100632ba8 in realloc_audio (a=0x10185f9d0, count=1024) at libswresample/swresample.c:359 #1 0x00000001006334de in swr_convert_internal (s=0x400, out=0x10185fd30, out_count=0, in=0x0, in_count=25557456) at libswresample/swresample.c:535
I can post the disassembly of realloc_audio if needed, but I don't think that's necessary.
Is the FPE reproducible with ffmpeg (the application)? If not, do you know why?
No (or at least I haven't found a way to trigger it). Doing ffmpeg -i TimeCode.mov -strict -2 -af "aconvert=s16:stereo" out.mp4 (or mono) did not result in any errors. I've no clue why my code gets the floating point exception but ffmpeg does not. file reports both my program and ffmpeg as "Mach-O 64-bit executable x86_64". However, I get this same crash on Windows 7 64-bit (using 32-bit ffmpeg in a 32-bit application).
I probably should've added this: the video file info is:
$ ffmpeg -i TimeCode.mov
ffmpeg version N-45342-g6efe1ed Copyright (c) 2000-2012 the FFmpeg developers
built on Oct 13 2012 10:34:47 with gcc 4.2.1 (GCC) (Apple Inc. build 5666) (dot 3)
configuration: --enable-libopenjpeg --enable-libx264 --enable-gpl
libavutil 51. 74.100 / 51. 74.100
libavcodec 54. 65.100 / 54. 65.100
libavformat 54. 32.100 / 54. 32.100
libavdevice 54. 3.100 / 54. 3.100
libavfilter 3. 19.102 / 3. 19.102
libswscale 2. 1.101 / 2. 1.101
libswresample 0. 16.100 / 0. 16.100
libpostproc 52. 1.100 / 52. 1.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'TimeCode.mov':
Metadata:
major_brand : qt
minor_version : 537199360
compatible_brands: qt
creation_time : 2011-06-13 20:22:03
Duration: 00:00:15.04, start: 0.038345, bitrate: 1173 kb/s
Stream #0:0(eng): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, s16, 157 kb/s
Metadata:
creation_time : 2011-06-13 20:22:03
handler_name : Apple Alias Data Handler
Stream #0:1(eng): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 852x480 [SAR 1:1 DAR 71:40], 1003 kb/s, 23.98 fps, 24 tbr, 600 tbn, 47.95 tbc
Metadata:
creation_time : 2011-06-13 20:22:03
handler_name : Apple Alias Data Handler



