FFmpegの簡単なSamplesのオーディオコードを学ぶ
インスタンスコード
int audio_Encoder()
{
int channels = 2;
int sampleRate = 48000;
int inSampleFmt = AV_SAMPLE_FMT_S16;
///4 AV_CODEC_ID_AAC
AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
if (!codec)
{
std::cout << "avcodec_find_encoder failed!" << endl;
return NULL;
}
//
AVCodecContext* ac = avcodec_alloc_context3(codec);
if (!ac)
{
std::cout << "avcodec_alloc_context3 failed!" << endl;
return NULL;
}
std::cout << "avcodec_alloc_context3 success!" << endl;
ac->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
ac->codec_tag = 0;
ac->thread_count = XGetCpuNum();
ac->time_base = { 1,1000000 };
ac->bit_rate = 128000;
ac->sample_rate = sampleRate;
ac->sample_fmt = AV_SAMPLE_FMT_FLTP;
ac->channels = 2;
ac->channel_layout = av_get_default_channel_layout(ac->channels);
int size = av_samples_get_buffer_size(NULL, 2, 1024, AV_SAMPLE_FMT_FLTP, 1);
int extradata_size = ac->extradata_size;
//
int ret = avcodec_open2(ac, 0, 0);
if (ret != 0)
{
return XError(ret);
}
std::cout << "avcodec_open2 success!" << endl;
///2
SwrContext* asc = NULL;
asc = swr_alloc_set_opts(asc,
av_get_default_channel_layout(channels), (AVSampleFormat)AV_SAMPLE_FMT_FLTP, sampleRate,//
av_get_default_channel_layout(channels), (AVSampleFormat)inSampleFmt, sampleRate, 0, 0);//
if (!asc)
{
std::cout << "swr_alloc_set_opts failed!";
return false;
}
ret = swr_init(asc);
if (ret != 0)
{
return XError(ret);
}
std::cout << " !" << endl;
///3
AVFrame* pcm = av_frame_alloc();
pcm->format = AV_SAMPLE_FMT_FLTP;
pcm->sample_rate = sampleRate;
pcm->channels = channels;
pcm->channel_layout = av_get_default_channel_layout(channels);
pcm->nb_samples = av_rescale_rnd(1024, sampleRate, sampleRate, AVRounding{ AV_ROUND_UP }); //
ret = av_frame_get_buffer(pcm, 0); // pcm
if (ret != 0)
{
return XError(ret);
}
AVPacket* Encodepacket = av_packet_alloc();
FILE* inputFile = fopen("audio_record_48k_2_s16.pcm", "rb+");
FILE* aac = fopen("audio_record_48k_2_fltp.aac", "wb");
char pcm_buf[10000] = { 0 };
int frameindex = 0;
while (fread(pcm_buf, 1, 4096, inputFile) >= 4096)
{
const uint8_t* indata[AV_NUM_DATA_POINTERS] = { 0 };
indata[0] = (const uint8_t *)pcm_buf;
int len = swr_convert(asc, pcm->data, pcm->nb_samples, // ,
indata, 1024
);
ret = avcodec_send_frame(ac, pcm);
if (ret < 0) {
std::cout << endl;
continue;
}
while (ret >= 0) {
ret = avcodec_receive_packet(ac, Encodepacket);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
}
if (ret < 0) {
break;
}
fwrite(Encodepacket->data, 1, Encodepacket->size, aac);
std::cout << "frameindex : " << frameindex <<" nb_samples :" << len << " encodeSize:" << Encodepacket->size << endl ;
frameindex++;
}
av_packet_unref(Encodepacket);
}
ret = avcodec_send_frame(ac, NULL);
while (ret >= 0) {
ret = avcodec_receive_packet(ac, Encodepacket);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
}
if (ret < 0) {
break;
}
fwrite(Encodepacket->data, 1, Encodepacket->size, aac);
std::cout << "frameindex : " << frameindex << " encodeSize:" << Encodepacket->size << endl;
frameindex++;
}
std::fclose(aac);
av_packet_free(&Encodepacket);
av_frame_free(&pcm);
if (asc)
swr_free(&asc);
if (ac)
avcodec_free_context(&ac);
std::cout << " " << endl;
return 0;
}