- get the encode_audio.c example from ffmpeg, which converts in-memory raw PCM data to MP2
- compile
gcc -o encode_audio encode_audio.c -I/usr/include/x86_64-linux-gnu/libavcodec -lavformat -lavcodec -lavutil -lm
- check that is works with the MP2 encoder -> OK
- change the encoder to
codec = avcodec_find_encoder(AV_CODEC_ID_ADPCM_G722);
- adapt the output parameters to g722
c->sample_rate = 16000;//select_sample_rate(codec);
c->channel_layout = AV_CH_LAYOUT_MONO;//select_channel_layout(codec);
c->channels = 1; //av_get_channel_layout_nb_channels(c->channel_layout);
- recompile, test... crash!
#0 0x00007ffff5cd5e97 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007ffff5cd7801 in __GI_abort () at abort.c:79
#2 0x00007ffff5d20897 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff5e4db9a "%s\n")
at ../sysdeps/posix/libc_fatal.c:181
#3 0x00007ffff5d2790a in malloc_printerr (str=str@entry=0x7ffff5e4f800 "free(): invalid next size (fast)")
at malloc.c:5350
#4 0x00007ffff5d2a078 in _int_free (have_lock=<optimized out>, p=<optimized out>, av=<optimized out>)
at malloc.c:4213
#5 0x00007ffff5d2a078 in __GI___libc_free (mem=<optimized out>) at malloc.c:3124
#6 0x00007ffff5d2a078 in tcache_thread_shutdown () at malloc.c:2969
#7 0x00007ffff5d2a078 in arena_thread_freeres () at arena.c:950
#8 0x00007ffff5d2c55a in _int_memalign (av=0x7ffff6082c40 <main_arena>, alignment=32, bytes=<optimized out>)
at malloc.c:4750
#9 0x00007ffff5d31e43 in _mid_memalign (address=<optimized out>, bytes=40, alignment=<optimized out>)
at malloc.c:3305
#10 0x00007ffff5d31e43 in __posix_memalign (memptr=0x7fffffffd720, alignment=<optimized out>, size=40)
at malloc.c:5369
#11 0x00007ffff6457663 in av_malloc () at /usr/lib/x86_64-linux-gnu/libavutil.so.55
#12 0x00007ffff645798d in av_mallocz () at /usr/lib/x86_64-linux-gnu/libavutil.so.55
#13 0x00007ffff643b89d in av_buffer_create () at /usr/lib/x86_64-linux-gnu/libavutil.so.55
#14 0x00007ffff643be40 in av_buffer_realloc () at /usr/lib/x86_64-linux-gnu/libavutil.so.55
#15 0x00007ffff6848efa in av_packet_ref () at /usr/lib/x86_64-linux-gnu/libavcodec.so.57
#16 0x00007ffff68f8474 in avcodec_encode_audio2 () at /usr/lib/x86_64-linux-gnu/libavcodec.so.57
#17 0x00007ffff68f8af9 in () at /usr/lib/x86_64-linux-gnu/libavcodec.so.57
#18 0x00007ffff68f8c5a in avcodec_send_frame () at /usr/lib/x86_64-linux-gnu/libavcodec.so.57
#19 0x0000555555555085 in encode ()
#20 0x00005555555555a2 in main ()
Hmm... what am I missing?
Solution:
The code encoding a single ton sound is explicitly written for stereo channel layout. Reducing to one channel avoid the buffer overflow.
samples = (uint16_t*)frame->data[0];
for (j = 0; j < c->frame_size; j++)
{
samples[j] = (int)(sin(t) * 10000);
for (k = 1; k < c->channels; k++)
samples[j + k] = samples[j];
t += tincr;
}