读音视频文件流程:
- 打开文件
char *inUrl = "D:\\TestFiles\\test.mp4";
AVFormatContext *ictx = NULL;
avformat_open_input(&ictx, inUrl, 0, 0);
2. 查看和显示流信息(如果需要)
ret = avformat_find_stream_info(ictx, 0);
av_dump_format(ictx, 0, inUrl, 0);
3. 找音视频流
int vstreamindex = -1, astreamindex = -1;
for(int i=0; i< ictx->nb_streams; i++)
{
AVStream *instream= ictx->streams[i];
if ( instream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
vstreamindex = i;
}
else if (instream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
{
astreamindex = i;
}
}
4. 得到解码器
AVCodec *avcodec_find_decoder(enum AVCodecID id);
AVCodec *avcodec_find_encoder(enum AVCodecID id);
AVCodec *vcodec;
vcodec = avcodec_find_decoder(ictx->streams[vstreamindex]->codecpar->codec_id);
5. 先得到解码器后,再得到AVCodecContext
AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
AVCodecContext *vctx;
vctx = avcodec_alloc_context3(vcodec);
6. 将音频视参数传送给AVCodecContext
int avcodec_parameters_to_context(AVCodecContext *codec, const AVCodecParameters *par);
avcodec_parameters_to_context(vctx, ictx->streams[vstreamindex]->codecpar);
7. 打开解码器
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
avcodec_open2(vctx,vcodec,NULL);
8. 分配packet和frame指针
AVFrame *pFrame;
AVPacket *packet;
packet = av_packet_alloc();
pFrame = av_frame_alloc();
9. 开始while循环读数据流
while (av_read_frame(ictx, packet) >=0)
{
if (packet->stream_index == vstreamindex) {
avcodec_send_packet(vctx, packet);
ret = avcodec_receive_frame(vctx, pFrame);
if (ret == 0 ) {
av_log(vctx,AV_LOG_DEBUG,"vframe count:%d\n",count++);
}
av_packet_unref(packet);
}
10. 完成后释放所有指针。
av_frame_free(&pFrame);
av_packet_free(&packet);
avcodec_close(vctx);
avcodec_free_context(&vctx);
avformat_close_input(&ictx);