ffmpeg解码流程 turorial5详解
2012-05-14 22:52
330 查看
FFMPEG解码流程
1. 注册所有容器格式和CODEC:av_register_all()
2. 打开文件:av_open_input_file()
3. 从文件中提取流信息:av_find_stream_info()
4. 穷举所有的流,查找其中种类为CODEC_TYPE_VIDEO
5. 查找对应的解码器:avcodec_find_decoder()
6. 打开编解码器:avcodec_open()
7. 为解码帧分配内存:avcodec_alloc_frame()
8. 不停地从码流中提取出帧数据:av_read_frame()
9. 判断帧的类型,对于视频帧调用:avcodec_decode_video()
10. 解码完后,释放解码器:avcodec_close()
11. 关闭输入文件:av_close_input_file()
首先第一件事情就是开一个视频文件并从中得到流。我们要做的第一件事情就是使用av_register_all();来初始化libavformat/libavcodec:
这一步注册库中含有的所有可用的文件格式和编码器,这样当打开一个文件时,它们才能够自动选择相应的文件格式和编码器。av_register_all()只需调用一次,所以,要放在初始化代码中。也可以仅仅注册个人的文件格式和编码。
下一步,打开文件:
***FormatContext *pFormatCtx;
const char *filename="myvideo.mpg";
av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL); // 打开视频文件
最后三个参数描述了文件格式,缓冲区大小(size)和格式参数;我们通过简单地指明NULL或0告诉 libavformat 去自动探测文件格式并且使用默认的缓冲区大小。这里的格式参数指的是视频输出参数,比如宽高的坐标。
下一步,我们需要取出包含在文件中的流信息:
av_find_stream_info(pFormatCtx); // 取出流信息
***FormatContext 结构体
dump_format(pFormatCtx, 0, filename, false);//我们可以使用这个函数把获取到得参数全部输出。
for(i=0; i<pFormatCtx->nb_streams; i++) //区分视频流和音频流
if(pFormatCtx->streams->codec.codec_type==CODEC_TYPE_VIDEO) //找到视频流,这里也可以换成音频
{
videoStream=i;
break;
}
接下来就需要寻找解码器
***Codec *pCodec;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
avcodec_open(pCodecCtx, pCodec); // 打开解码器
给视频帧分配空间以便存储解码后的图片:
***Frame *pFrame;
pFrame=avcodec_alloc_frame();
/////////////////////////////////////////开始解码///////////////////////////////////////////
第一步当然是读数据:
我们将要做的是通过读取包来读取整个视频流,然后把它解码成帧,最后转换格式并且保存。
while(av_read_frame(pFormatCtx, &packet)>=0) { //读数据
if(packet.stream_index==videoStream){ //判断是否视频流
avcodec_decode_video(pCodecCtx,pFrame, &frameFinished,
packet.data, packet.size); //解码
if(frameFinished) {
img_convert((***Picture *)pFrameRGB, PIX_FMT_RGB24,(***Picture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height);//转换 }
SaveFrame(pFrameRGB, pCodecCtx->width,pCodecCtx->height, i); //保存数据
av_free_packet(&packet); //释放
av_read_frame()读取一个包并且把它保存到***Packet结构体中。这些数据可以在后面通过av_free_packet()来释 放。函数avcodec_decode_video()把包转换为帧。然而当解码一个包的时候,我们可能没有得到我们需要的关于帧的信息。因此,当我们得到下一帧的时候,avcodec_decode_video()为我们设置了帧结束标志frameFinished。最后,我们使用 img_convert()函数来把帧从原始格式(pCodecCtx->pix_fmt)转换成为RGB格式。要记住,你可以把一个
***Frame结构体的指针转换为***Picture结构体的指针。最后,我们把帧和高度宽度信息传递给我们的SaveFrame函数。
到此解码完毕,显示过程使用SDL完成考虑到我们以后会使用firmware进行显示操作,SDL忽略不讲。
1. 注册所有容器格式和CODEC:av_register_all()
2. 打开文件:av_open_input_file()
3. 从文件中提取流信息:av_find_stream_info()
4. 穷举所有的流,查找其中种类为CODEC_TYPE_VIDEO
5. 查找对应的解码器:avcodec_find_decoder()
6. 打开编解码器:avcodec_open()
7. 为解码帧分配内存:avcodec_alloc_frame()
8. 不停地从码流中提取出帧数据:av_read_frame()
9. 判断帧的类型,对于视频帧调用:avcodec_decode_video()
10. 解码完后,释放解码器:avcodec_close()
11. 关闭输入文件:av_close_input_file()
首先第一件事情就是开一个视频文件并从中得到流。我们要做的第一件事情就是使用av_register_all();来初始化libavformat/libavcodec:
这一步注册库中含有的所有可用的文件格式和编码器,这样当打开一个文件时,它们才能够自动选择相应的文件格式和编码器。av_register_all()只需调用一次,所以,要放在初始化代码中。也可以仅仅注册个人的文件格式和编码。
下一步,打开文件:
***FormatContext *pFormatCtx;
const char *filename="myvideo.mpg";
av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL); // 打开视频文件
最后三个参数描述了文件格式,缓冲区大小(size)和格式参数;我们通过简单地指明NULL或0告诉 libavformat 去自动探测文件格式并且使用默认的缓冲区大小。这里的格式参数指的是视频输出参数,比如宽高的坐标。
下一步,我们需要取出包含在文件中的流信息:
av_find_stream_info(pFormatCtx); // 取出流信息
***FormatContext 结构体
dump_format(pFormatCtx, 0, filename, false);//我们可以使用这个函数把获取到得参数全部输出。
for(i=0; i<pFormatCtx->nb_streams; i++) //区分视频流和音频流
if(pFormatCtx->streams->codec.codec_type==CODEC_TYPE_VIDEO) //找到视频流,这里也可以换成音频
{
videoStream=i;
break;
}
接下来就需要寻找解码器
***Codec *pCodec;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
avcodec_open(pCodecCtx, pCodec); // 打开解码器
给视频帧分配空间以便存储解码后的图片:
***Frame *pFrame;
pFrame=avcodec_alloc_frame();
/////////////////////////////////////////开始解码///////////////////////////////////////////
第一步当然是读数据:
我们将要做的是通过读取包来读取整个视频流,然后把它解码成帧,最后转换格式并且保存。
while(av_read_frame(pFormatCtx, &packet)>=0) { //读数据
if(packet.stream_index==videoStream){ //判断是否视频流
avcodec_decode_video(pCodecCtx,pFrame, &frameFinished,
packet.data, packet.size); //解码
if(frameFinished) {
img_convert((***Picture *)pFrameRGB, PIX_FMT_RGB24,(***Picture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width,pCodecCtx->height);//转换 }
SaveFrame(pFrameRGB, pCodecCtx->width,pCodecCtx->height, i); //保存数据
av_free_packet(&packet); //释放
av_read_frame()读取一个包并且把它保存到***Packet结构体中。这些数据可以在后面通过av_free_packet()来释 放。函数avcodec_decode_video()把包转换为帧。然而当解码一个包的时候,我们可能没有得到我们需要的关于帧的信息。因此,当我们得到下一帧的时候,avcodec_decode_video()为我们设置了帧结束标志frameFinished。最后,我们使用 img_convert()函数来把帧从原始格式(pCodecCtx->pix_fmt)转换成为RGB格式。要记住,你可以把一个
***Frame结构体的指针转换为***Picture结构体的指针。最后,我们把帧和高度宽度信息传递给我们的SaveFrame函数。
到此解码完毕,显示过程使用SDL完成考虑到我们以后会使用firmware进行显示操作,SDL忽略不讲。
相关文章推荐
- ffmpeg解码流程 turorial5详解
- ffmpeg解码流程 turorial5详解
- ffmpeg中MPEG2 TS 流解码的流程分析
- ffmpeg中MPEG2 TS 流解码的流程分析
- FFMPEG解码流程
- FFMPEG解码流程
- FFMpeg的解码流程
- Linux/Windows 下分别编译音视频编解码库ffmpeg的流程和注意事项
- ffmpeg解码流程
- FFmpeg解码流程
- FFmpeg解码H264流程分析
- FFMPEG解码流程理解搜集整理及tutorial5的理解,主要是音视频同步
- ffmpeg解码流程
- ffmpeg解码流程
- MTK图片解码流程及png图片详解
- JPEG解码算法流程详解
- FFMpeg的解码流程
- FFMPEG解码流程
- ffmpeg解码流程
- ffmpeg解码流程