ffmpeg音频编码

##简介
一个简单编码PCM的demo
##代码

/*
*一个简单编码PCM的demo,参数都是根据PCM数据格式填写的,如果你的PCM不是s16p 44100 双声道,那么你需要自己修改编码上下文参数
*注意读取对双声道的处理,因为pcm对双声道是交替存储的
*缪国凯
*MK(821486004@qq.com)
*/


#ifdef	__cplusplus
extern "C"
{
#endif

#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
#include "libavfilter/avfilter.h"
#include "libavfilter/avfiltergraph.h"
#include "libavfilter/buffersink.h"
#include "libavfilter/buffersrc.h"
#include "libavutil/audio_fifo.h"
#include "libavutil/avutil.h"
#include "libavutil/fifo.h"

#ifdef	__cplusplus
}
#endif

#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "avdevice.lib")
#pragma comment(lib, "avfilter.lib")

//#pragma comment(lib, "avfilter.lib")
//#pragma comment(lib, "postproc.lib")
//#pragma comment(lib, "swresample.lib")
#pragma comment(lib, "swscale.lib")

#include <windows.h>
#include <conio.h>
#include <time.h>
#include <tchar.h>

AVFormatContext *pFormatCtx_Out = NULL;  
int g_AudioStreamIndex = -1;

#include <stdio.h>  


int OpenOutPut()
{
	AVStream *pVideoStream = NULL, *pAudioStream = NULL;
	const char *outFileName = "test.MP3";

	avformat_alloc_output_context2(&pFormatCtx_Out, NULL, NULL, outFileName);

	
	AVCodecContext *pOutputCodecCtx;
	g_AudioStreamIndex = 0;
	pAudioStream = avformat_new_stream(pFormatCtx_Out, NULL);

	pAudioStream->codec->codec = avcodec_find_encoder(pFormatCtx_Out->oformat->audio_codec);

	pOutputCodecCtx = pAudioStream->codec;

	pOutputCodecCtx->sample_rate = 44100;
	pOutputCodecCtx->channel_layout = 3;
	pOutputCodecCtx->channels = 2;

	pOutputCodecCtx->sample_fmt = AV_SAMPLE_FMT_S16P;
	AVRational time_base={1, pAudioStream->codec->sample_rate};
	pAudioStream->codec->time_base = time_base;
	//audioCodecCtx->time_base = time_base;

	pOutputCodecCtx->codec_tag = 0;  
	if (pFormatCtx_Out->oformat->flags & AVFMT_GLOBALHEADER)  
		pOutputCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;

	if (avcodec_open2(pOutputCodecCtx, pOutputCodecCtx->codec, 0) < 0)
	{
		//编码器打开失败,退出程序
		return -1;
	}

	if (!(pFormatCtx_Out->oformat->flags & AVFMT_NOFILE))
	{
		if(avio_open(&pFormatCtx_Out->pb, outFileName, AVIO_FLAG_WRITE) < 0)
		{
			printf("can not open output file handle!\n");
			return -1;
		}
	}

	if(avformat_write_header(pFormatCtx_Out, NULL) < 0)
	{
		printf("can not write the header of the output file!\n");
		return -1;
	}

	return 0;
}

int _tmain(int argc, _TCHAR* argv[])  
{ 
	av_register_all();  

	if (OpenOutPut() < 0)  
	{  
		printf("failed to open input file");  
		goto end;  
	}  

	FILE *p = NULL;
	p = fopen("abc.pcm", "rb");


	int linesize = av_get_bytes_per_sample(pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->sample_fmt) * pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->frame_size;
	uint8_t *PcmData = new uint8_t[2*linesize];
	int sampleSize = av_get_bytes_per_sample(pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->sample_fmt);
	int AudioFrameIndex = 0;
	while(1)  
	{ 
		if (p)
		{
			if(2*linesize != fread(PcmData, 1, 2*linesize, p))
				break;

			AVFrame *frame;
			frame = av_frame_alloc();
			frame->nb_samples = pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->frame_size>0 ? pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->frame_size: 1152;
			frame->channel_layout = pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->channel_layout;
			frame->format = pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->sample_fmt;
			frame->sample_rate = pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->sample_rate;
			av_frame_get_buffer(frame, 0);

			for (int i = 0; i < pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->frame_size; i++)
			{
				memcpy(frame->data[0] + i * sampleSize, PcmData + 2 * i * sampleSize, sampleSize);
				memcpy(frame->data[1] + i * sampleSize, PcmData + 2 * i * sampleSize + sampleSize, sampleSize);
			}

			AVPacket pkt_out;
			av_init_packet(&pkt_out);
			int got_picture = -1;
			pkt_out.data = NULL;
			pkt_out.size = 0;

			frame->pts = AudioFrameIndex * pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->frame_size;
			if (avcodec_encode_audio2(pFormatCtx_Out->streams[g_AudioStreamIndex]->codec, &pkt_out, frame, &got_picture) < 0)
			{
				printf("can not decoder a frame");
			}
			av_frame_free(&frame);
			if (got_picture) 
			{
				pkt_out.stream_index = g_AudioStreamIndex;
				pkt_out.pts = AudioFrameIndex * pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->frame_size;
				pkt_out.dts = AudioFrameIndex * pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->frame_size;
				pkt_out.duration = pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->frame_size;

				pkt_out.pts = av_rescale_q_rnd(pkt_out.pts, 
					pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->time_base,
					pFormatCtx_Out->streams[g_AudioStreamIndex]->time_base,
					(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
				pkt_out.dts = pkt_out.pts;
				pkt_out.duration = av_rescale_q_rnd(pkt_out.duration,
					pFormatCtx_Out->streams[g_AudioStreamIndex]->codec->time_base,
					pFormatCtx_Out->streams[g_AudioStreamIndex]->time_base,
					(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));

				int ret = av_interleaved_write_frame(pFormatCtx_Out, &pkt_out);
				av_free_packet(&pkt_out);
			}
			AudioFrameIndex++;
		}
	}  
	fclose(p);  
end:  
	av_write_trailer(pFormatCtx_Out);

	avio_close(pFormatCtx_Out->pb);
	avformat_free_context(pFormatCtx_Out);

	printf("enter any key to stop\n");
	getchar();  
	return 0;  
}  

##下载地址
https://download.csdn.net/download/dancing_night/10818878

注:2018-11-30发现bug,已修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dancing_night

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值