[TOC]
简介
一个简单保存PCM的demo,注意保存那里对双声道的处理,因为pcm对双声道是交替存储的
代码
/*
*一个简单保存PCM的demo,注意保存那里对双声道的处理,因为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 *ifmt_ctx = NULL;
int g_AudioStreamIndex = -1;
#include <stdio.h>
int openinputfile(const char* filename)
{
int ret = 0;
//open the input
if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0)
{
printf("can not open input");
return ret;
}
if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)))
{
printf("can not find input stream info");
return ret;
}
//open the decoder
for (int i = 0; i < ifmt_ctx->nb_streams; i++)
{
if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
{
g_AudioStreamIndex = i;
ret = avcodec_open2(ifmt_ctx->streams[i]->codec,
avcodec_find_decoder(ifmt_ctx->streams[i]->codec->codec_id), NULL);
if (ret < 0)
{
printf("can not open decoder");
return ret;
}
}
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
if (argc < 2)
{
return -1;
}
AVPacket pkt_in, pkt_out;
AVFrame *frame = NULL;
unsigned int stream_index;
av_register_all();
if (openinputfile(argv[1]) < 0)
{
printf("failed to open input file");
goto end;
}
FILE *p = NULL;
char tmpName[100];
sprintf_s(tmpName, "%s_%d_%dchannel.pcm", argv[1],
ifmt_ctx->streams[g_AudioStreamIndex]->codec->sample_rate, ifmt_ctx->streams[g_AudioStreamIndex]->codec->channels);
p = fopen(tmpName, "w+b");
int size = av_get_bytes_per_sample(ifmt_ctx->streams[g_AudioStreamIndex]->codec->sample_fmt);
while(1)
{
if (av_read_frame(ifmt_ctx, &pkt_in) < 0)
{
break;
}
pkt_out.data = NULL;
pkt_out.size = 0;
av_init_packet(&pkt_out);
if (g_AudioStreamIndex == pkt_in.stream_index)
{
stream_index = pkt_in.stream_index;
frame = av_frame_alloc();
int got_frame = -1;
int ret = -1;
ret = avcodec_decode_audio4(ifmt_ctx->streams[stream_index]->codec, frame, &got_frame, &pkt_in);
if (ret < 0)
{
av_frame_free(&frame);
printf("decoding audio stream failed\n");
break;
}
if (got_frame)
{
if (frame->data[0] && frame->data[1])
{
for (int i = 0; i < ifmt_ctx->streams[stream_index]->codec->frame_size; i++)
{
fwrite(frame->data[0] + i * size, 1, size, p);
fwrite(frame->data[1] + i * size, 1, size, p);
}
}
else if(frame->data[0])
{
fwrite(frame->data[0], 1, frame->linesize[0], p);
}
}
}
}
fclose(p);
end:
avformat_close_input(&ifmt_ctx);
printf("enter any key to stop\n");
getchar();
return 0;
}