Я пытаюсь кодировать входящие необработанные аудиоданные PCM в аудиофайл в кодировке AA C. Следующее аварийное завершение работы SIGABRT при вызове avcodec_encode_audio2
:
aac_encoding. c
#include <stdio.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>
typedef struct AACEncoder {
AVFormatContext* pFormatCtx;
AVStream* audio_st;
AVCodecContext* pCodecCtx;
AVFrame* pFrame;
AVPacket* pkt;
uint8_t* frame_buf;
} AACEncoder;
AACEncoder *openEncoder(char* out_file) {
AACEncoder* encoder = (AACEncoder*)malloc(sizeof(AACEncoder*));
av_register_all();
AVFormatContext* pFormatCtx = avformat_alloc_context();
encoder->pFormatCtx = pFormatCtx;
AVOutputFormat* outFormat = av_guess_format(NULL, out_file, NULL);
pFormatCtx->oformat = outFormat;
if (avio_open(&pFormatCtx->pb, out_file, AVIO_FLAG_READ_WRITE) < 0) {
printf("Failed to open output file!\n");
return NULL;
}
AVStream* audio_st = avformat_new_stream(pFormatCtx, 0);
if (audio_st==NULL){
return NULL;
}
encoder->audio_st;
AVCodecContext* pCodecCtx = audio_st->codec;
encoder->pCodecCtx = pCodecCtx;
pCodecCtx->codec_id = outFormat->audio_codec;
pCodecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
pCodecCtx->sample_fmt = AV_SAMPLE_FMT_FLTP;
pCodecCtx->sample_rate= 48000;
pCodecCtx->channel_layout = AV_CH_LAYOUT_MONO;
pCodecCtx->channels = av_get_channel_layout_nb_channels(pCodecCtx->channel_layout);
pCodecCtx->bit_rate = 64000;
av_dump_format(pFormatCtx, 0, out_file, 1);
AVCodec* pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
if (!pCodec){
printf("Can not find encoder!\n");
return NULL;
}
if (avcodec_open2(pCodecCtx, pCodec,NULL) < 0){
printf("Failed to open encoder!\n");
return NULL;
}
AVFrame* pFrame = av_frame_alloc();
encoder->pFrame = pFrame;
pFrame->nb_samples= pCodecCtx->frame_size;
pFrame->format= pCodecCtx->sample_fmt;
int size = av_samples_get_buffer_size(NULL, pCodecCtx->channels,pCodecCtx->frame_size,pCodecCtx->sample_fmt, 1);
uint8_t* frame_buf = (uint8_t *)av_malloc(size);
encoder->frame_buf = frame_buf;
avcodec_fill_audio_frame(pFrame, pCodecCtx->channels, pCodecCtx->sample_fmt,(const uint8_t*)frame_buf, size, 1);
//Write Header
avformat_write_header(pFormatCtx,NULL);
AVPacket pkt;
encoder->pkt = &pkt;
av_new_packet(&pkt,size);
return encoder;
}
int writePCM(AACEncoder* encoder, int16_t* pcmData, size_t pcmSize) {
SwrContext* swr = swr_alloc();
av_opt_set_int(swr, "in_channel_layout", encoder->pCodecCtx->channel_layout, 0);
av_opt_set_int(swr, "out_channel_layout", encoder->pCodecCtx->channel_layout, 0);
av_opt_set_int(swr, "in_sample_rate", encoder->pCodecCtx->sample_rate, 0);
av_opt_set_int(swr, "out_sample_rate", encoder->pCodecCtx->sample_rate, 0);
av_opt_set_sample_fmt(swr, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
swr_init(swr);
printf("Initialized SwrContext\n");
fflush(stdout);
int ret = swr_convert(swr, encoder->pFrame->extended_data, pcmSize, &pcmData, pcmSize);
int got_frame=0;
if(ret < 0){
printf("Failed to resample!\n");
return -1;
}
//Encode
ret = avcodec_encode_audio2(encoder->pCodecCtx, encoder->pkt, encoder->pFrame, &got_frame);
printf("Encoded audio using AAC\n");
fflush(stdout);
swr_free(&swr);
if(ret < 0){
printf("Failed to encode!\n");
return -1;
}
if (got_frame==1){
printf("Succeed to encode 1 frame! \tsize:%5d\n", encoder->pkt->size);
encoder->pkt->stream_index = encoder->audio_st->index;
ret = av_write_frame(encoder->pFormatCtx, encoder->pkt);
av_free_packet(encoder->pkt);
}
}