#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#ifdef __cplusplus
};
#endif
uint8_t inbuf[AVCODEC_MAX_AUDIO_FRAME_SIZE * 100];
int main()
{
// 注册编解码器
av_register_all();
AVFormatContext * pFormatCtx = avformat_alloc_context(); // 文件容器上下文
const char * filename = "in.flv";
// 打开输入文件
if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0)
{
printf("can,t open file");
return -1;
}
if (av_find_stream_info(pFormatCtx) < 0) // 检查在文件中的流的信息
{
return -1;
}
av_dump_format(pFormatCtx, 0, filename, false); // 显示pfmtctx->streams里的信息 测试时用到
int i, audioStream;
AVCodecContext * pCodecCtx;
// 找到第一个音频流
audioStream = -1;
for (int i = 0; i < pFormatCtx->nb_streams; ++i) //找到音频、视频对应的stream
{
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
{
audioStream = i;
break;
}
}
if (audioStream == -1) // 有音频
{
printf("no video stream\n");
return -1;
}
// 获得音频流的解码器上下文
pCodecCtx = pFormatCtx->streams[audioStream]->codec;
// 根据解码器上下文找到解码器
AVCodec * pCodec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL)
{
return -1;
}
// Inform the codec that we can handle truncated bitstreams
// bitstreams where frame boundaries can fall in the middle of packets
if (pCodec->capabilities & CODEC_CAP_TRUNCATED)
{
pCodecCtx->flags |= CODEC_CAP_TRUNCATED;
}
// 打开解码器
if (avcodec_open(pCodecCtx, pCodec) < 0)
{
return -1;
}
// Hack to correct wrong frame rates that seem to be generated by some
// codecs
FILE * fp = fopen("out.pcm", "wb");
//AVFrame * pFrame;
//pFrame = avcodec_alloc_frame();
//
AVPacket packet;
uint8_t * pktdata;
int pktsize;
int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 100;
long start = clock(); //开始解码时间
while(av_read_frame(pFormatCtx, &packet) >= 0) //pFormatCtx中调用对应格式的packet获取函数
{
if (packet.stream_index == audioStream)
{
pktdata = packet.data;
pktsize = packet.size;
while (pktsize > 0)
{
out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 100;
int len = avcodec_decode_audio3(pCodecCtx, (short *)inbuf, &out_size, &packet); // 解码
if (len < 0)
{
printf("error\n");
break;
}
if (out_size > 0)
{
fwrite(inbuf, 1, out_size, fp);
}
pktsize -= len;
pktdata += len;
}
av_free_packet(&packet);
}
}
long end = clock();
printf("cost time :%f\n",(double)(end-start)/(double)CLOCKS_PER_SEC);
fclose(fp);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}