Simplest FFMPEG based audio encoder (PCM encoded to AAC)

Hello everyone, see you again, I'm Full Stack Jun.

This article introduces one of the simplest FFMPEG-based audio encoders. The encoder implements the encoding of PCM audio sample data into AAC compression encoded data. The encoder code is very simple, but every line of code is very important. By looking at the source code of this encoder. Be able to understand the process of FFMPEG audio encoding.

This program uses the latest version of the class library (compile time is 2014.5.6). The development platform is VC2010. All the configuration has been done, just need to execute it.

Process (updated on 2014.9.29)

The following is a flowchart of encoding audio using FFmpeg.

Use this process. Not only can encode AAC audio, but also can encode MP3, MP2 and other audio supported by FFmpeg. The function with the blue background in the figure is the function of the actual output data.

The functions in light green are the functions of the audio encoding.

Briefly describe the meaning of each function in the process:

av_register_all(): Register all FFmpeg codecs. avformat_alloc_output_context2(): Initializes the AVFormatContext of the output stream. avio_open(): Open the output file. av_new_stream(): Create an AVStream of the output stream. avcodec_find_encoder(): Find the encoder. avcodec_open2(): Open the encoder. avformat_write_header(): Write the file header (for some encapsulation formats without file headers, this function is not required. For example, MPEG2TS). avcodec_encode_audio2(): Encode audio. That is, AVFrame (stores PCM sample data) is encoded into AVPacket (stores code stream data in AAC, MP3 and other formats). av_write_frame(): Write the encoded video stream to a file. av_write_trailer(): Write the end of the file (for some encapsulation formats without file headers. This function is not required. For example, MPEG2TS).

code

/**
 *Simplest FFmpeg based audio encoder
 *Simplest FFmpeg Audio Encoder
 *
 *Lei Xiaohua Lei Xiaohua
 *leixiaohua1020@126.com
 *Communication University of China/Digital TV Technology
 *Communication University of China / Digital TV Technology
 *http://blog.csdn.net/leixiaohua1020
 *
 *This program realizes the encoding of audio PCM sample data into compressed stream (MP3. WMA, AAC, etc.).  * is the easiest tutorial on FFmpeg audio encoding.  *By learning this sample, you can understand the encoding process of FFmpeg.  *This software encode PCM data to AAC bitstream. *It's the simplest audio encoding software based on FFmpeg. *Suitable for beginner of FFmpeg  */#include <stdio.h>#define __STDC_CONSTANT_MACROS#ifdef _WIN32//Windowsextern "C"{#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"};#else//Linux...#ifdef __cplusplusextern "C"{#endif#include <libavcodec/avcodec.h>#include <libavformat/avformat.h>#ifdef __cplusplus};#endif#endifint flush_encoder(AVFormatContext *fmt_ctx,unsigned int stream_index){	int ret;	int got_frame;	AVPacket enc_pkt;	if (!(fmt_ctx->streams[stream_index]->codec->codec->capabilities &		CODEC_CAP_DELAY))		return 0;	while (1) {		enc_pkt.data = NULL;		enc_pkt.size = 0;		av_init_packet(&enc_pkt);		ret = avcodec_encode_audio2 (fmt_ctx->streams[stream_index]->codec, &enc_pkt,			NULL, &got_frame);		av_frame_free(NULL);		if (ret < 0)			break;		if (!got_frame){			ret=0;			break;		}		printf("Flush Encoder: Succeed to encode 1 frame!\tsize:%5d\n",enc_pkt.size);		/* mux encoded frame */		ret = av_write_frame(fmt_ctx, &enc_pkt);		if (ret < 0)			break;	}	return ret;}int main(int argc, char* argv[]){	AVFormatContext* pFormatCtx;	AVOutputFormat* fmt;	AVStream* audio_st;	AVCodecContext* pCodecCtx;	AVCodec* pCodec;	uint8_t* frame_buf;	AVFrame* pFrame;	AVPacket pkt;	int got_frame=0;	int ret=0;	int size=0;	FILE *in_file=NULL;	                        //Raw PCM data	int framenum=1000;                          //Audio frame number	const char* out_file = "tdjm.aac";          //Output URL	int i;	in_file= fopen("tdjm.pcm", "rb");	av_register_all();	//Method 1.	pFormatCtx = avformat_alloc_context();	fmt = av_guess_format(NULL, out_file, NULL);	pFormatCtx->oformat = fmt;	//Method 2.	//avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);	//fmt = pFormatCtx->oformat;	//Open output URL	if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0){		printf("Failed to open output file!\n");		return -1;	}	audio_st = avformat_new_stream(pFormatCtx, 0);	if (audio_st==NULL){		return -1;	}	pCodecCtx = audio_st->codec;	pCodecCtx->codec_id = fmt->audio_codec;	pCodecCtx->codec_type = AVMEDIA_TYPE_AUDIO;	pCodecCtx->sample_fmt = AV_SAMPLE_FMT_S16;	pCodecCtx->sample_rate= 44100;	pCodecCtx->channel_layout=AV_CH_LAYOUT_STEREO;	pCodecCtx->channels = av_get_channel_layout_nb_channels(pCodecCtx->channel_layout);	pCodecCtx->bit_rate = 64000;  	//Show some information	av_dump_format(pFormatCtx, 0, out_file, 1);	pCodec = avcodec_find_encoder(pCodecCtx->codec_id);	if (!pCodec){		printf("Can not find encoder!\n");		return -1;	}	if (avcodec_open2(pCodecCtx, pCodec,NULL) < 0){		printf("Failed to open encoder!\n");		return -1;	}	pFrame = av_frame_alloc();	pFrame->nb_samples= pCodecCtx->frame_size;	pFrame->format= pCodecCtx->sample_fmt;		size = av_samples_get_buffer_size(NULL, pCodecCtx->channels,pCodecCtx->frame_size,pCodecCtx->sample_fmt, 1);	frame_buf = (uint8_t *)av_malloc(size);	avcodec_fill_audio_frame(pFrame, pCodecCtx->channels, pCodecCtx->sample_fmt,(const uint8_t*)frame_buf, size, 1);		//Write Header	avformat_write_header(pFormatCtx,NULL);	av_new_packet(&pkt,size);	for (i=0; i<framenum; i++){		//Read PCM		if (fread(frame_buf, 1, size, in_file) <= 0){			printf("Failed to read raw data! \n");			return -1;		}else if(feof(in_file)){			break;		}		pFrame->data[0] = frame_buf;  //PCM Data		pFrame->pts=i*100;		got_frame=0;		//Encode		ret = avcodec_encode_audio2(pCodecCtx, &pkt,pFrame, &got_frame);		if(ret < 0){			printf("Failed to encode!\n");			return -1;		}		if (got_frame==1){			printf("Succeed to encode 1 frame! \tsize:%5d\n",pkt.size);			pkt.stream_index = audio_st->index;			ret = av_write_frame(pFormatCtx, &pkt);			av_free_packet(&pkt);		}	}		//Flush Encoder	ret = flush_encoder(pFormatCtx,0);	if (ret < 0) {		printf("Flushing encoder failed\n");		return -1;	}	//Write Trailer	av_write_trailer(pFormatCtx);	//Clean	if (audio_st){		avcodec_close(audio_st->codec);		av_free(pFrame);		av_free(frame_buf);	}	avio_close(pFormatCtx->pb);	avformat_free_context(pFormatCtx);	fclose(in_file);	return 0;}
copy

result

After the program is executed. A PCM sample data file (*.pcm) will be encoded into an AAC stream file (*.aac).

download

simplest ffmpeg audio encoder

Project homepage

SourceForge: https://sourceforge.net/projects/simplestffmpegaudioencoder/

Github: https://github.com/leixiaohua1020/simplest_ffmpeg_audio_encoder

Open Source China: http://git.oschina.net/leixiaohua1020/simplest_ffmpeg_audio_encoder

CSDNproject download address:

http://download.csdn.net/detail/leixiaohua1020/7324091

PUDNproject download address:

http://www.pudn.com/downloads644/sourcecode/multimedia/detail2605236.html

Update-1.1 (2015.2.13)==========================================

This time, the source code was adjusted in consideration of cross-platform requirements. After this adjustment, the source code can be compiled and passed on the following platforms:

VC++: You can compile by opening the sln file without configuration.

cl.exe: Open compile_cl.bat and use cl.exe to compile under the command line. Note that the parameters in the script may need to be adjusted according to the installation path of VC. The compilation command is as follows.

::VS2010 Environment
call "D:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
::include
@set INCLUDE=include;%INCLUDE%
::lib
@set LIB=lib;%LIB%
::compile and link
cl simplest_ffmpeg_audio_encoder.cpp /link avcodec.lib avformat.lib avutil.lib ^
avdevice.lib avfilter.lib postproc.lib swresample.lib swscale.lib /OPT:NOREF
copy

MinGW: Execute compile_mingw.sh on the MinGW command line to compile with MinGW's g++. The compilation command is as follows.

g++ simplest_ffmpeg_audio_encoder.cpp -g -o simplest_ffmpeg_audio_encoder.exe \
-I /usr/local/include -L /usr/local/lib -lavformat -lavcodec -lavutil
copy

GCC: Execute compile_gcc.sh on the Linux or MacOS command line to compile with GCC. The compilation command is as follows.

gcc simplest_ffmpeg_audio_encoder.cpp -g -o simplest_ffmpeg_audio_encoder.out \
-I /usr/local/include -L /usr/local/lib -lavformat -lavcodec -lavutil
copy

PS: The relevant compilation commands have been saved to the project directory

CSDN download address: http://download.csdn.net/detail/leixiaohua1020/8445209

SourceForge has been updated.

Publisher: full stack programmer, please indicate the source: https://javaforall.cn/116024.html Original link: https://javaforall.cn

Posted by wbar on Fri, 08 Jul 2022 14:33:19 +0530