#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; }