/*******************************************************************************
Copyright (c) wubihe Tech. Co., Ltd. All rights reserved.
--------------------------------------------------------------------------------
Date Created: 2014-10-25
Author: wubihe QQ:1269122125 Email:1269122125@qq.com
Description: 代码实现PCM编码AAC,MP3格式
--------------------------------------------------------------------------------
Modification History
DATE AUTHOR DESCRIPTION
--------------------------------------------------------------------------------
********************************************************************************/
#include <stdio.h>
#define __STDC_CONSTANT_MACROS
#ifdef _WIN32
//Windows
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
};
#else
//Linux...
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#ifdef __cplusplus
};
#endif
#endif
#define INPUT_FILE_NAME ("huangdun_r48000_FMT_S16_c2.pcm")
//输出文件前缀
#define OUTPUT_FILE_NAME_PREFIX ("huangdun")
//输出文件后缀
//#define OUTPUT_FILE_NAME_SUFFIX ("aac")
//输出文件后缀
#define OUTPUT_FILE_NAME_SUFFIX ("mp3")
//输出文件比特率 该值越大 音频质量越好 音质损失越小
#define OUTPUT_FILE_BIT_RATE (64000)
int 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);
//输入视频帧为NULL
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()
{
static char*pFormatName[]=
{
"FMT_U8","FMT_S16","FMT_S32","FMT_FLT","FMT_DBL",
"FMT_U8P","FMT_S16P","FMT_S32P","FMT_FLTP","FMT_DBLP"
};
//各种不同格式对应字节数
static int mapSampleBytes[AV_SAMPLE_FMT_NB]
={1,2,4,4,8,1,2,4,4,8};
//PCM原始数据格式
uint64_t iInputLayout = AV_CH_LAYOUT_STEREO;
int iInputChans = av_get_channel_layout_nb_channels(iInputLayout);
AVSampleFormat eInputSampleFormat = AV_SAMPLE_FMT_S16;
int iInputSampleRate = 48000;
//不同样本格式长度
int iInputSampleBytes = mapSampleBytes[eInputSampleFormat];
//PCM需要重采样的格式 部分编码器不支持原始PCM的数据格式如MP3
uint64_t iOutputLayout = AV_CH_LAYOUT_STEREO;
int iOutputChans = av_get_channel_layout_nb_channels(iOutputLayout);
AVSampleFormat eOutputSampleFormat ;
int iOutputSampleRate = 48000;
if(strcmp(OUTPUT_FILE_NAME_SUFFIX,"aac") == 0)
{
eOutputSampleFormat = AV_SAMPLE_FMT_S16;
}
else if(strcmp(OUTPUT_FILE_NAME_SUFFIX,"mp3") == 0)
{
//MP3不支持AV_SAMPLE_FMT_S16这种格式
eOutputSampleFormat = AV_SAMPLE_FMT_S16P;
}
else
{
}
//编码样本长度
int iOutputSampleBytes = mapSampleBytes[eOutputSampleFormat];
//是否需要重采样
bool bNeedResample = false;
if(eInputSampleFormat != eOutputSampleFormat)
{
bNeedResample = true;
}
//是否平面存储结构
bool bPlanner = false;
if((eOutputSampleFormat>=AV_SAMPLE_FMT_U8P) &&(eOutputSampleFormat<=AV_SAMPLE_FMT_DBLP))
{
bPlanner = true;
}
//打开输入文件
FILE *pInputFile = fopen("huangdun_r48000_FMT_S16_c2.pcm", "rb");
if(pInputFile == NULL)
{
}
//打开输出文件
char szOutFileName[256]={0};
sprintf(szOutFileName,"%s_br%d_sr%d.%s",OUTPUT_FILE_NAME_PREFIX,OUTPUT_FILE_BIT_RATE,iOutputSampleRate,OUTPUT_FILE_NAME_SUFFIX);
FILE *pOutputFile = fopen(szOutFileName, "wb");
//打开中间测试文件
char szTempFileName[256]={0};
sprintf(szTempFileName,"%s_sr%d_c1.pcm",OUTPUT_FILE_NAME_PREFIX,iOutputSampleRate);
FILE *pTempFile = fopen(szTempFileName, "wb");
int iReturn;
///////////编码器操作////////////////////////////////
//注册所有编解码器
av_register_all();
//封装格式上下文 AVFormatContext中有AVInputFormat和AVOutputFormat
//解复用时avformat_open_input()初始化AVInputFormat,复用时用户自己初始化AVOutputFormat
AVFormatContext* pFormatCtx;
AVOutputFormat * fmt;
//Method 1.分配一个封装格式
pFormatCtx = avformat_alloc_context();
//根据后缀名 填充 输出格式上下文
fmt = av_guess_format(NULL, szOutFileName, NULL);
pFormatCtx->oformat = fmt;
//Method 2.
//avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);
//fmt = pFormatCtx->oformat;
//添加一个流
AVStream *audio_st = avformat_new_stream(pFormatCtx, 0);
if (audio_st==NULL)
{
return -1;
}
//添加一个输出路径
if (avio_open(&pFormatCtx->pb,szOutFileName, AVIO_FLAG_READ_WRITE) < 0)
{
printf("Failed to open output file!\n");
return -1;
}
//Show some information 日志信息
av_dump_format(pFormatCtx, 0, szOutFileName, 1);
//初始化编码器相关结构体 获取输出流中的编码上下文
AVCodecContext* pCodecCtx = audio_st->codec;
pCodecCtx->codec_id = fmt->audio_codec ;
pCodecCtx->codec_type = AVMEDIA_TYPE_AUDIO ;
//立体声
pCodecCtx->channel_layout = iOutputLayout ;
pCodecCtx->channels = iOutputChans ;
//编码比特率 AAC支持多种比特率 一般比特率越高 视频质量越好 需要传输带宽越大
pCodecCtx->bit_rate = OUTPUT_FILE_BIT_RATE;
pCodecCtx->sample_rate = iOutputSampleRate;
//PCM样本深度为AV_SAMPLE_FMT_S16 但不是所有格式的编码都支持这种格式
pCodecCtx->sample_fmt = eOutputSampleFormat;
//编码器
AVCodec* pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
if (!pCodec)
{
printf("Can not find encoder!\n");
return -1;
}
//打开解码器 有可能失败 -22 错误,原因不同的编码格式支持的样本格式不一样
//如封装AAC格式样本格式是AV_SAMPLE_FMT_FLT,打开就出错
if ((iReturn = avcodec_open2(pCodecCtx, pCodec,NULL)) < 0)
{
printf("Failed to open encoder :[%d]!\n",iReturn);
return -1;
}
//重采用上下文
SwrContext *pSwrCtx = NULL;
//原始数据帧
AVFrame* pRawframe = NULL;
//原始帧一Planer的大小 非平面分布的情况就是缓存总大小
int iRawLineSize = 0;
//原始帧缓存大小
int iRawBuffSize = 0;
//原始帧缓存
uint8_t *pRawBuff= NULL;
//重采样后数据帧
AVFrame* pConvertframe = NULL;
//重采样后一Planer的大小
int iConvertLineSize = 0;
//重采样后缓存大小
int iConvertBuffSize = 0;
//重采样后帧缓存
uint8_t *pConvertBuff = NULL;
//1帧数据样本数
int iFrameSamples = pCodecCtx->frame_size;
// 存储原始数据
iRawLineSize = 0;
iRawBuffSize = av_samples_get_buffer_size(&iRawLineSize, iInputChans, iFrameSamples, eInputSampleFormat, 0);
pRawBuff = (uint8_t *)av_malloc(iRawBuffSize);
//原始数据保存在AVFrame结构体中
pRawframe = av_frame_alloc();
pRawframe->nb_samples = iFrameSamples;
pRawframe->format = eInputSampleFormat;
pRawframe->channels = iInputChans;
iReturn = avcodec_fill_audio_frame(pRawframe, iInputChans, eInputSampleFormat, (const uint8_t*)pRawBuff, iRawBuffSize, 0);
if(iReturn<0)
{
return -1;
}
if(bNeedResample)
{
pSwrCtx = swr_alloc_set_opts(NULL,iOutputLayout, eOutputSampleFormat, iOutputSampleRate,
iInputLayout,eInputSampleFormat , iInputSampleRate,0, NULL);
swr_init(pSwrCtx);
// 存储转换后数据
iConvertLineSize = 0;
iConvertBuffSize = av_samples_get_buffer_size(&iConvertLineSize, iOutputChans, iFrameSamples, eOutputSampleFormat, 0);
pConvertBuff = (uint8_t *)av_malloc(iConvertBuffSize);
//转换后数据保存在AVFrame结构体中
pConvertframe = av_frame_alloc();
pConvertframe->nb_samples = iFrameSamples;
pConvertframe->format = eOutputSampleFormat;
pConvertframe->channels = iOutputCh
没有合适的资源?快使用搜索试试~ 我知道了~
FFMPEG实现PCM编码AAC和MP3(采用封装格式实现)
共127个文件
h:93个
dll:8个
lib:8个
5星 · 超过95%的资源 需积分: 47 144 下载量 62 浏览量
2018-07-28
17:02:06
上传
评论 3
收藏 22.99MB RAR 举报
温馨提示
基于FFMPEG实现把PCM编码成AAC或者MP3格式的视频文件,编码的比特率都是64kbps,代码中AAC格式编码不需要音频重采样,而MP3格式编码只支持样本平行存储的方式。
资源推荐
资源详情
资源评论
收起资源包目录
FFMPEG实现PCM编码AAC和MP3(采用封装格式实现) (127个子文件)
main.cpp 10KB
mt.dep 65B
avcodec-56.dll 18.4MB
avformat-56.dll 5.46MB
avfilter-5.dll 2.1MB
avdevice-56.dll 1.28MB
swscale-3.dll 427KB
avutil-54.dll 415KB
swresample-1.dll 263KB
postproc-53.dll 119KB
PcmEncode.exe 34KB
avcodec.h 173KB
avformat.h 100KB
avfilter.h 56KB
opt.h 35KB
pixfmt.h 32KB
frame.h 23KB
swresample.h 19KB
avio.h 18KB
intreadwrite.h 18KB
avdevice.h 16KB
mem.h 14KB
old_pix_fmts.h 14KB
common.h 14KB
pixdesc.h 13KB
avstring.h 12KB
swscale.h 12KB
old_codec_ids.h 10KB
log.h 10KB
samplefmt.h 10KB
buffer.h 10KB
channel_layout.h 9KB
avutil.h 8KB
imgutils.h 8KB
_mingw.h 8KB
bprint.h 8KB
buffersink.h 7KB
parseutils.h 7KB
dict.h 7KB
vdpau.h 6KB
xvmc.h 6KB
version.h 6KB
stdint.h 6KB
inttypes.h 6KB
vda.h 5KB
timecode.h 5KB
eval.h 5KB
mathematics.h 5KB
error.h 5KB
fifo.h 5KB
buffersrc.h 5KB
cpu.h 5KB
audio_fifo.h 4KB
version.h 4KB
attributes.h 4KB
rational.h 4KB
vaapi.h 4KB
avcodec.h 4KB
stereo3d.h 4KB
dv_profile.h 4KB
hash.h 4KB
asrc_abuffer.h 3KB
version.h 3KB
downmix_info.h 3KB
display.h 3KB
threadmessage.h 3KB
avfft.h 3KB
version.h 3KB
postprocess.h 3KB
hmac.h 3KB
bswap.h 3KB
crc.h 3KB
timestamp.h 3KB
file.h 2KB
dxva2.h 2KB
blowfish.h 2KB
version.h 2KB
avassert.h 2KB
base64.h 2KB
pixelutils.h 2KB
lzo.h 2KB
sha512.h 2KB
ripemd.h 2KB
lfg.h 2KB
md5.h 2KB
sha.h 2KB
xtea.h 2KB
version.h 2KB
aes.h 2KB
time.h 2KB
intfloat.h 2KB
version.h 2KB
version.h 2KB
replaygain.h 2KB
adler32.h 2KB
motion_vector.h 2KB
intfloat_readwrite.h 2KB
random_seed.h 1KB
murmur3.h 1KB
macros.h 1KB
共 127 条
- 1
- 2
资源评论
- 暗黑程序员2019-10-09不错的例子
- QQ5153114452019-05-07功能正常,非常好用
- _HF_XiaoC_316_2020-04-15功能正常,非常好用
QQ_1695710968
- 粉丝: 583
- 资源: 28
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功