您的位置:首页 > 其它

ffmpeg音频编码

2016-11-09 00:57 211 查看

简介

一个简单编码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, "flv", outFileName); //RTMP

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("旅行.mp3_44100_2channel.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+=2)
{
memcpy(frame->data[0] + i * sampleSize, PcmData + 2 * i * sampleSize, sampleSize);
memcpy(frame->data[0] + 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;
}


下载地址

http://download.csdn.net/detail/dancing_night/9677013
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ffmpeg