FFmpeg+SDL学习笔记4,音频编码(pcm to acc)

#include <iostream>
using namespace std;

extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/avutil.h>
#include <libswresample/swresample.h>
}

#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"swscale.lib")
#pragma comment(lib,"swresample.lib")
int p = 0;

int main()
{
	const char* inFile = "./file/testOut.wmv";
	const char* oFile = "./file/out.aac";

	//注册所有的封装器解封装器
	av_register_all();
	//注册所有的编码器和解码器
	avcodec_register_all();
	
	//1,打开音频编码器
	AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
	if (!codec)
	{
		cout << "avcodec_find_encoder" << endl;
		return -1;
	}
	//创建编码器上下文
	AVCodecContext* c = avcodec_alloc_context3(codec);
	if (!c)
	{
		cout << "avcodec_alloc_context3" << endl;
		return -1;
	}
	//设置比特率
	c->bit_rate = 64000;
	//采样率
	c->sample_rate = 44100;
	c->sample_fmt = AV_SAMPLE_FMT_FLTP;
	//通道类型
	c->channel_layout = AV_CH_LAYOUT_STEREO;
	//通道数
	c->channels = 2;
	//
	c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

	int ret = avcodec_open2(c, codec, NULL);
	if (ret < 0)
	{
		cout << "avcodec_open2" << endl;
		return -1;
	}
	cout << "打开文件成功" << endl;


	//2,打开输出封装的上下文
	AVFormatContext *oc = NULL;
	avformat_alloc_output_context2(&oc, NULL, NULL,  oFile);
	if (!oc)
	{
		cout << "avformat_alloc_output_context2" << endl;
		return -1;
	}


	AVStream* st = avformat_new_stream(oc, NULL);
	st->codecpar->codec_tag = 0;
	avcodec_parameters_from_context(st->codecpar, c);
	//打印信息
	av_dump_format(oc, 0, oFile, 1);  //索引是0,

	//3,open io  , write head
	ret = avio_open(&oc->pb, oFile, AVIO_FLAG_WRITE);
	if (ret < 0)
	{
		cout << "avio_open" << endl;
		return -1;
	}
	ret = avformat_write_header(oc, NULL);
	if (ret < 0)
	{
		cout << "avformat_write_header" << endl;
		return -1;
	}

	
	//4,创建音频重采样上下文
	SwrContext* actx = NULL;
	actx = swr_alloc_set_opts(actx, 
		c->channel_layout, c->sample_fmt, c->sample_rate,	//输出格式
		AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, 44100,		//输入格式
		0, 0);
	if (!actx)
	{
		cout << "swr_alloc_set_opts" << endl;
		return -1;
	}

	ret = swr_init(actx);
	if (ret<0)
	{
		cout << "swr_init" << endl;
		return -1;
	}

	//5,打开输入音频文件,进行重采样
	AVFrame* frame = av_frame_alloc();
	frame->format = AV_SAMPLE_FMT_FLTP;
	frame->channels = 2;
	frame->channel_layout = AV_CH_LAYOUT_STEREO;
	frame->nb_samples = 1024;	//一帧音频存放的样本数量
	ret = av_frame_get_buffer(frame, 0);
	if (ret < 0)
	{
		cout << "av_frame_get_buffer" << endl;
		return -1;
	}

	int readSize = frame->nb_samples * 2 * 2; //一次读取的大小,样本数*样本大小
	char* pcm = new char[readSize];
	FILE* fp = fopen(inFile, "rb");

	for (;;)
	{
		int len = fread(pcm, 1, readSize, fp);
		if (len <= 0)
			break;
		const uint8_t* data[1];
		data[0] = (uint8_t*)pcm;
		len = swr_convert(actx, frame->data, frame->nb_samples,
			data, frame->nb_samples);
		if (len <= 0)
			break;
		cout << "《" << len << "》";

		//6,音频编码
		AVPacket pkt;
		av_init_packet(&pkt);
		ret = avcodec_send_frame(c, frame);
		if (ret != 0)
			continue;
		ret = avcodec_receive_packet(c, &pkt);
		if (ret != 0)
			continue;

		//7,音频封装acc文件
		pkt.stream_index = 0;
		pkt.pts = 0;
		pkt.dts = 0;
		ret = av_interleaved_write_frame(oc, &pkt);
	}

	delete pcm;
	pcm = NULL;


	//写入视频索引
	av_write_trailer(oc);
	//关闭视频输出io
	avio_close(oc->pb);
	//清理封装输出上下文
	avformat_free_context(oc);
	//关闭编码器
	avcodec_close(c);
	//清理编码器上下文
	avcodec_free_context(&c);


	getchar();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值