#1834 closed defect (invalid)
swr_convert() results in integer division by zero exception
Reported by: | mbradshaw | Owned by: | Michael Niedermayer |
---|---|---|---|
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 (1)
Change History (8)
by , 12 years ago
Attachment: | TimeCode.mov added |
---|
follow-up: 2 comment:1 by , 12 years ago
comment:2 by , 12 years ago
Replying to cehoyos:
Replying to mbradshaw:
Summary of the bug:
When I callswr_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
comment:3 by , 12 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
*Sigh*
I wasn't calling swr_init()
.
comment:4 by , 11 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
Hey.
I do have the same problem as the OP, but mine did not go away after calling swr_init() as I did so from the beginning.
Here us how I initialize the context:
SwrContext* swrContext = swr_alloc_set_opts(NULL, audioCodecContext->channel_layout, AV_SAMPLE_FMT_S16P, audioCodecContext->sample_rate, audioCodecContext->channel_layout, audioCodecContext->sample_fmt, audioCodecContext->sample_rate, 0, NULL); int result = swr_init(swrContext); // Create destination sample buffer uint8_t* destBuffer = NULL; int destBufferLinesize; av_samples_alloc( &destBuffer, &destBufferLinesize, videoInfo.audioNumChannels, 2048, AV_SAMPLE_FMT_S16P, 0);
And here is the call to convert:
int outputSamples = swr_convert(p_swrContext, &p_destBuffer, 2048, (const uint8_t**)p_frame->extended_data, p_frame->nb_samples);
I also tried using AV_SAMPLE_FMT_S16 (non-planaer, as that is what OpenAL wants AFAIK), but it yields the same crash (division by 0 because of what OP said).
also, I do not get any FFmpeg errors in the log and av_samples_alloc, swr_alloc_set_opts and swr_init do not return any errors, either.
comment:5 by , 11 years ago
Resolution: | → invalid |
---|---|
Status: | reopened → closed |
Please do not reopen ancient tickets and please understand that this is a bug tracker, not a support forum.
comment:6 by , 11 years ago
Should I open a new one instead? This really does seem like a bug to me (or at least a missing error log).
comment:7 by , 11 years ago
If there is a bug, then a report would be (very) welcome.
Can you reproduce the crash with ffmpeg (the application)? If not, please consider to find out why before opening a new ticket. I also believe that you should give other readers of libav-user a little more time to answer.
Replying to mbradshaw:
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?