[Libav-user] I can't get audio decoding to work.

Bill Messenger apothemmusic at gmail.com
Tue Jun 28 00:28:37 CEST 2016


Okay, we're finally getting somewhere! I found out that frame->data[0] only
contains the data for the left channel. When I play the left channel, it
sounds correct. I used frame->linesize[] (0-7) and found that only data[0]
contains data. Where is the data for the right channel? I tried calling
"avcodec_decode_audio4(codecCtx, frame, &gotFrame, &packet);" twice in the
same packet, but that just gave me garbled audio.

On Sat, Jun 25, 2016 at 8:39 PM, Bill Messenger <apothemmusic at gmail.com>
wrote:

> But I tried "std::memcpy(sampleBuffer + totalBufferSize, frame->data[0],
> dataSize-4);", and it still gave me the same result. I even tried
> subtracting 8, 16, 32, 64, and so on, and it still gave the same result.
> When I go up to dataSize/2, however, it doesn't give me that UNADDRESSABLE
> ACCESS error. Does frame->data[0] only contain half of the data for planar
> audio?
>
> On Fri, Jun 24, 2016 at 6:58 PM, Bill Messenger <apothemmusic at gmail.com>
> wrote:
>
>> I used "_heapchk" in every place I could think of in my function, and it
>> always returns "_HEAPOK" before the line that crashes. I can't see the
>> value of _heapchk() after the crash though, Visual Studio won't let me
>> continue after the crash. I also made a new project that just uses the
>> FFmpeg libraries to make sure the problem wasn't with PortAudio or
>> wxWidgets, but it's still crashing in that same place. When I ran it
>> through Dr. Memory with an mp3 or ogg file, it output an UNADDRESSABLE
>> ACCESS error. When I ran it with a wav or flac file, it didn't output that
>> error.
>>
>> This is what Dr. Memory output with the mp3 file one: (Line 154 of
>> audiodecoder.cpp is the "std::memcpy(sampleBuffer + totalBufferSize,
>> frame->data[0], dataSize);" that was crashing before. I guess I should also
>> mention that the crash happens in both 32 bit and 64 bit builds in both
>> debug and release mode.)
>>
>> Dr. Memory version 1.10.1 build 3 built on Apr 10 2016 18:05:55
>> Dr. Memory results for pid 2804: "FFmpegTest.exe"
>> Application cmdline:
>> "C:\Users\BillM\Documents\My_Files\Code\FFmpegTest\x64\Release\FFmpegTest.exe"
>> Recorded 115 suppression(s) from default C:\Program Files (x86)\Dr.
>> Memory\bin64\suppress-default.txt
>>
>> Error #1: UNADDRESSABLE ACCESS beyond heap bounds: reading
>> 0x000002a77c94fbb8-0x000002a77c94fbbc 4 byte(s)
>> # 0 replace_memmove
>> [d:\drmemory_package\drmemory\replace.c:763]
>> # 1 AudioDecoder::decodeFile
>>  [c:\users\billm\documents\my_files\code\ffmpegtest\ffmpegtest\audiodecoder.cpp:154]
>> # 2 VCRUNTIME140.dll!set_se_translator       +0x47a
>>  (0x00007ff846f44acb <VCRUNTIME140.dll+0x4acb>)
>> # 3 VCRUNTIME140.dll!set_se_translator       +0x21b
>>  (0x00007ff846f4486c <VCRUNTIME140.dll+0x486c>)
>> # 4 MSVCP140.dll!std::basic_ostream<>::flush
>>  [f:\dd\vctools\crt\crtw32\stdhpp\ostream:581]
>> # 5 KERNEL32.dll!BaseThreadInitThunk         +0x21
>> (0x00007ff850678102 <KERNEL32.dll+0x18102>)
>> Note: @0:00:01.844 in thread 11544
>> Note: refers to 1 byte(s) beyond last valid byte in prior malloc
>> Note: prev lower malloc:  0x000002a77c94f290-0x000002a77c94fbb7
>> Note: allocated here:
>> Note: # 0 replace_malloc
>> [d:\drmemory_package\common\alloc_replace.c:2576]
>> Note: # 1 avcodec-57.dll!?            +0x0      (0x00007ff81b56e61c
>> <avcodec-57.dll+0x4fe61c>)
>> Note: # 2 avutil-55.dll!?             +0x0      (0x00007ff821617b6c
>> <avutil-55.dll+0x27b6c>)
>> Note: # 3 avutil-55.dll!?             +0x0      (0x00007ff8215f627a
>> <avutil-55.dll+0x627a>)
>> Note: # 4 avutil-55.dll!?             +0x0      (0x00007ff821617e92
>> <avutil-55.dll+0x27e92>)
>> Note: # 5 avutil-55.dll!?             +0x0      (0x00007ff8215f6c06
>> <avutil-55.dll+0x6c06>)
>> Note: # 6 avutil-55.dll!?             +0x0      (0x00007ff8215f69a8
>> <avutil-55.dll+0x69a8>)
>> Note: # 7 avcodec-57.dll!?            +0x0      (0x00007ff81b7af025
>> <avcodec-57.dll+0x73f025>)
>> Note: # 8 avcodec-57.dll!?            +0x0      (0x00007ff81c00dc4d
>> <avcodec-57.dll+0xf9dc4d>)
>> Note: # 9 avcodec-57.dll!?            +0x0      (0x00007ff81b7af385
>> <avcodec-57.dll+0x73f385>)
>> Note: #10 avcodec-57.dll!?            +0x0      (0x00007ff81b7af66b
>> <avcodec-57.dll+0x73f66b>)
>> Note: #11 avcodec-57.dll!?            +0x0      (0x00007ff81b574b9a
>> <avcodec-57.dll+0x504b9a>)
>> Note: instruction: mov    (%rcx) -> %ecx
>>
>> Error #2: LEAK 1175 direct bytes 0x000002a77c946100-0x000002a77c946597 +
>> 0 indirect bytes
>> # 0 replace_malloc
>>  [d:\drmemory_package\common\alloc_replace.c:2576]
>> # 1 avutil-55.dll!?                            +0x0
>>  (0x00007ff82161c761 <avutil-55.dll+0x2c761>)
>> # 2 avutil-55.dll!?                            +0x0
>>  (0x00007ff821617b6c <avutil-55.dll+0x27b6c>)
>> # 3 avcodec-57.dll!?                           +0x0
>>  (0x00007ff81b646873 <avcodec-57.dll+0x5d6873>)
>> # 4 AudioDecoder::decodeFile
>>  [c:\users\billm\documents\my_files\code\ffmpegtest\ffmpegtest\audiodecoder.cpp:63]
>> # 5 VCRUNTIME140.dll!set_se_translator         +0x47a
>>  (0x00007ff846f44acb <VCRUNTIME140.dll+0x4acb>)
>> # 6 VCRUNTIME140.dll!set_se_translator         +0x21b
>>  (0x00007ff846f4486c <VCRUNTIME140.dll+0x486c>)
>> # 7 MSVCP140.dll!std::basic_filebuf<>::_Unlock
>>  [f:\dd\vctools\crt\crtw32\stdhpp\fstream:365]
>> # 8 MSVCP140.dll!std::basic_ostream<>::flush
>>  [f:\dd\vctools\crt\crtw32\stdhpp\ostream:581]
>> # 9 KERNEL32.dll!BaseThreadInitThunk           +0x21
>> (0x00007ff850678102 <KERNEL32.dll+0x18102>)
>>
>>
>> ===========================================================================
>> FINAL SUMMARY:
>>
>> DUPLICATE ERROR COUNTS:
>> Error #   1:   1706
>>
>> SUPPRESSIONS USED:
>>
>> ERRORS FOUND:
>>       1 unique,  1706 total unaddressable access(es)
>>       0 unique,     0 total invalid heap argument(s)
>>       0 unique,     0 total GDI usage error(s)
>>       0 unique,     0 total handle leak(s)
>>       0 unique,     0 total warning(s)
>>       1 unique,     1 total,   1175 byte(s) of leak(s)
>>       0 unique,     0 total,      0 byte(s) of possible leak(s)
>> ERRORS IGNORED:
>>       1 potential leak(s) (suspected false positives)
>>          (details: C:\Users\BillM\AppData\Roaming\Dr.
>> Memory\DrMemory-FFmpegTest.exe.2804.000\potential_errors.txt)
>>      14 unique,    14 total,   7286 byte(s) of still-reachable
>> allocation(s)
>>          (re-run with "-show_reachable" for details)
>> Details: C:\Users\BillM\AppData\Roaming\Dr.
>> Memory\DrMemory-FFmpegTest.exe.2804.000\results.txt
>>
>>
>> On Wed, Jun 22, 2016 at 3:58 PM, Bill Messenger <apothemmusic at gmail.com>
>> wrote:
>>
>>> I added some code to check if it was crashing because dataSize is
>>> negative. It's not. Also, I found out that dtSize in this instance is 4608,
>>> and no matter what I do, sizeof(frame->data[0]) is always 8. Also, I tried
>>> sizeof(frame->data) which returned 64.
>>>
>>> int dtSize = av_samples_get_buffer_size(nullptr, codecCtx->channels,
>>> frame->nb_samples, codecCtx->sample_fmt, 1);
>>> wxGetApp().popUpErrorDialog("dtSize: " + std::to_string(dtSize));
>>> dataSize = dtSize;
>>>
>>> while(totalBufferSize + dataSize > estimatedBuffSize)
>>> {
>>> estimatedBuffSize *= 1.1;
>>> sampleBuffer = (uint8_t*)std::realloc(sampleBuffer, estimatedBuffSize);
>>> }
>>> wxGetApp().popUpErrorDialog("sizeof(frame->data[0]): " +
>>> std::to_string(sizeof(frame->data[0])));
>>>
>>> std::memcpy(sampleBuffer + totalBufferSize, frame->data[0], dataSize);
>>>
>>> totalBufferSize += dataSize;
>>> totalSamples += frame->nb_samples;
>>>
>>> On Mon, Jun 20, 2016 at 5:47 PM, Bill Messenger <apothemmusic at gmail.com>
>>> wrote:
>>>
>>>> This is the function I'm using to decode the audio file. My guess is
>>>> that it's crashing because "dataSize" is larger than "frame->data[0]", but
>>>> I'm pretty sure my calculation of dataSize is correct. Am I copying the
>>>> frame data to "sampleBuffer" the wrong way?
>>>>
>>>> bool AudioDecoder::decodeFile(std::string* filename)
>>>> {
>>>> reset(); // if a file has already been decoded, free it from memory and
>>>> reset
>>>>
>>>> AVFormatContext* formatCtx = avformat_alloc_context();
>>>> if(avformat_open_input(&formatCtx, filename->c_str(), nullptr, nullptr)
>>>> < 0)
>>>> {
>>>> wxGetApp().popUpErrorDialog("Couldn't open \"" + *filename + "\".");
>>>> avformat_close_input(&formatCtx);
>>>> return false;
>>>> }
>>>>
>>>> if(avformat_find_stream_info(formatCtx, nullptr) < 0)
>>>> {
>>>> wxGetApp().popUpErrorDialog("Couldn't find file info for \"" +
>>>> *filename + "\".");
>>>> avformat_close_input(&formatCtx);
>>>> return false;
>>>> }
>>>>
>>>> av_dump_format(formatCtx, 0, filename->c_str(), false);
>>>>
>>>> int streamID = -1;
>>>> for(int i = 0; i < formatCtx->nb_streams; i++)
>>>> {
>>>> if(formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
>>>> {
>>>> streamID = i;
>>>> break;
>>>> }
>>>> }
>>>> if(streamID == -1)
>>>> {
>>>> wxGetApp().popUpErrorDialog("\"" + *filename + "\" does not contain
>>>> audio.");
>>>> avformat_close_input(&formatCtx);
>>>> return false;
>>>> }
>>>>
>>>> AVCodecContext* codecCtx = formatCtx->streams[streamID]->codec;
>>>> AVCodec* codec = avcodec_find_decoder(codecCtx->codec_id);
>>>> if(!codec)
>>>> {
>>>> wxGetApp().popUpErrorDialog("Couldn't find the codec for \"" +
>>>> *filename + "\".");
>>>> avformat_close_input(&formatCtx);
>>>> return false;
>>>> }
>>>> if(avcodec_open2(codecCtx, codec, nullptr) < 0)
>>>> {
>>>> wxGetApp().popUpErrorDialog("Couldn't open the codec for\"" + *filename
>>>> + "\".");
>>>> avformat_close_input(&formatCtx);
>>>> return false;
>>>> }
>>>>
>>>> sampleFormat = codecCtx->sample_fmt;
>>>> if(!(sampleFormat == AV_SAMPLE_FMT_U8 || sampleFormat ==
>>>> AV_SAMPLE_FMT_U8P ||
>>>> sampleFormat == AV_SAMPLE_FMT_S16 || sampleFormat == AV_SAMPLE_FMT_S16P
>>>> ||
>>>> sampleFormat == AV_SAMPLE_FMT_S32 || sampleFormat == AV_SAMPLE_FMT_S32P
>>>> ||
>>>> sampleFormat == AV_SAMPLE_FMT_FLT || sampleFormat == AV_SAMPLE_FMT_FLTP
>>>> ||
>>>> sampleFormat == AV_SAMPLE_FMT_DBL || sampleFormat ==
>>>> AV_SAMPLE_FMT_DBLP))
>>>> {
>>>> wxGetApp().popUpErrorDialog("\"" + *filename + "\" uses an unsupported
>>>> format.");
>>>> avcodec_close(codecCtx);
>>>> avformat_close_input(&formatCtx);
>>>> return false;
>>>> }
>>>>
>>>> planar = false;
>>>> if(sampleFormat == AV_SAMPLE_FMT_U8P || sampleFormat ==
>>>> AV_SAMPLE_FMT_S16P ||
>>>>   sampleFormat == AV_SAMPLE_FMT_S32P || sampleFormat ==
>>>> AV_SAMPLE_FMT_FLTP || sampleFormat == AV_SAMPLE_FMT_DBLP)
>>>> {
>>>> planar = true;
>>>> }
>>>>
>>>> AVFrame* frame = av_frame_alloc();
>>>> if(!frame)
>>>> {
>>>> wxGetApp().popUpErrorDialog("Failed to allocate an audio frame.");
>>>> avcodec_close(codecCtx);
>>>> avformat_close_input(&formatCtx);
>>>> return false;
>>>> }
>>>>
>>>> AVPacket packet;
>>>> av_init_packet(&packet);
>>>>
>>>> duration = formatCtx->duration / (double)AV_TIME_BASE; // duration is
>>>> defined in AudioDecoder.h as "double duration = 0;"
>>>>
>>>> uint64_t estimatedBuffSize = std::ceil(duration * codecCtx->sample_rate
>>>> * av_get_bytes_per_sample(codecCtx->sample_fmt) * codecCtx->channels);
>>>>
>>>> sampleBuffer = (uint8_t*)std::malloc(estimatedBuffSize); //
>>>> sampleBuffer is defined in AudioDecoder.h as "uint8_t* sampleBuffer =
>>>> nullptr;"
>>>> sampleBufferSet = true;
>>>>
>>>> int len;
>>>> int gotFrame = 0;
>>>> uint64_t dataSize;
>>>> uint64_t totalBufferSize = 0;
>>>> uint64_t totalSamples = 0;
>>>> while(av_read_frame(formatCtx, &packet) == 0)
>>>> {
>>>> len = avcodec_decode_audio4(codecCtx, frame, &gotFrame, &packet);
>>>> if(len < 0)
>>>> {
>>>> wxGetApp().popUpErrorDialog("Error while decoding.");
>>>> std::free(sampleBuffer);
>>>> sampleBufferSet = false;
>>>> av_packet_unref(&packet);
>>>> av_frame_free(&frame);
>>>> avcodec_close(codecCtx);
>>>> avformat_close_input(&formatCtx);
>>>> return false;
>>>> }
>>>>
>>>> if(gotFrame)
>>>> {
>>>> dataSize = av_samples_get_buffer_size(nullptr, codecCtx->channels,
>>>> frame->nb_samples, codecCtx->sample_fmt, 1);
>>>>
>>>> while(totalBufferSize + dataSize > estimatedBuffSize)
>>>> {
>>>> estimatedBuffSize *= 1.1;
>>>> sampleBuffer = (uint8_t*)std::realloc(sampleBuffer, estimatedBuffSize);
>>>> }
>>>>
>>>> std::memcpy(sampleBuffer + totalBufferSize, frame->data[0], dataSize);
>>>>
>>>> totalBufferSize += dataSize;
>>>> totalSamples += frame->nb_samples;
>>>> }
>>>>
>>>> av_packet_unref(&packet);
>>>> }
>>>>
>>>> sampleBuffer = (uint8_t*)std::realloc(sampleBuffer, totalBufferSize);
>>>>
>>>> numChannels = codecCtx->channels;
>>>> sampleRate = codecCtx->sample_rate;
>>>> numSamples = totalSamples;
>>>> bufferSize = totalBufferSize;
>>>>
>>>> av_packet_unref(&packet);
>>>> av_frame_free(&frame);
>>>> avcodec_close(codecCtx);
>>>> avformat_close_input(&formatCtx);
>>>>
>>>> didInit = true;
>>>>
>>>> return true;
>>>> }
>>>>
>>>> On Fri, Jun 17, 2016 at 4:20 PM, Bill Messenger <apothemmusic at gmail.com
>>>> > wrote:
>>>>
>>>>> Update: I found out that it only crashes in debug mode. When I build
>>>>> it in release mode, it doesn't crash. It must be a bug in MSVC 2015 or
>>>>> something.
>>>>>
>>>>> On Fri, Jun 17, 2016 at 4:06 PM, Bill Messenger <
>>>>> apothemmusic at gmail.com> wrote:
>>>>>
>>>>>> I'm trying to create a class that uses FFmpeg to decode any audio
>>>>>> file and store it into memory. Then it has a function that returns a float
>>>>>> value of any sample in that buffer. The code I wrote works perfectly for
>>>>>> wav and flac files, produces weird audio for mp3 and ogg files, and crashes
>>>>>> on certain mp3 files. I spent days trying to figure out why it isn't
>>>>>> working, but I can't come up with anything.
>>>>>>
>>>>>> I think the reason why the audio is weird for mp3 and ogg files is
>>>>>> that it uses planar audio instead of interleaved audio, but I don't see
>>>>>> what's wrong with the code I wrote. I may be missing something though. For
>>>>>> example, to get a sample for 16 bit interleaved audio I use:
>>>>>>
>>>>>> int16_t tmp = ((int16_t*)sampleBuffer)[numChannels*sample + channel];
>>>>>> rv = (float)tmp / 32767.0f;
>>>>>>
>>>>>> and to get a sample for 16 bit planar audio I use:
>>>>>>
>>>>>> int16_t tmp = ((int16_t*)sampleBuffer)[sample + numSamples*channel];
>>>>>> rv = (float)tmp / 32767.0f;
>>>>>>
>>>>>> And I have no clue why it crashes on certain mp3 files. I paid close
>>>>>> attention to make sure there is enough memory allocated in the buffer.
>>>>>> What's even weirder is that the file I created "Chiptune 15 2.mp3" didn't
>>>>>> crash, but when I renamed it to "test.mp3", it crashed! These crashes
>>>>>> happen on line 139 of "AudioDecoder.cpp":
>>>>>>
>>>>>> std::memcpy(sampleBuffer + totalBufferSize, frame->extended_data[0],
>>>>>> dataSize);
>>>>>>
>>>>>> with an "Access violation reading location" error in
>>>>>> vcruntime140d.dll. It says it isn't with location 0x0000000000000000 or
>>>>>> 0xFFFFFFFFFFFFFFFF though, it's a different random location.
>>>>>>
>>>>>> I attached a zip file with the c++ code and two mp3's. Oh yeah, I
>>>>>> should also mention that I'm using MSVC 2015 Community in Windows 10.
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20160627/31ff2ccc/attachment.html>


More information about the Libav-user mailing list