概述
最近由于工作需要,需要使用ffmpeg,以前没有接触过,初学自然少不了先翻翻雷霄骅的原创文章,向雷霄骅致敬 & 怀念~
雷霄骅的两篇文章中的代码,在ffmpeg3.3.x上有几个API已经被标记为deprecated了,所以直接下载例子代码,换成ffmpeg3.3.x的库会编译不过,当然,大多数根据header文件中的说明换一下即可。不过有几个变化稍微大一点的地方,还是需要先看看介绍再动手。这里对需要更换的API做一点简单的记录,便于日后查阅。
参考:
- 100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)
- 最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)
- New AVCodec API
需要替换的API
获取流信息:
av_find_stream_info() -> avformat_find_stream_info()
获取codec_type:
原来的判断:pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO
现在的判断:pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
AVCodecContext* codec已经在AVStream中被标记为deprecated了
获取AVCodecContext的方式:
原来直接这样就拿到了: pFormatCtx->streams[videoindex]->codec 。但由于 AVCodecContext* codec 已经在AVStream中被标记为deprecated了,所以需要换一种途径,主要是利用这两个API:
- AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
- int avcodec_parameters_to_context(AVCodecContext *codec, const AVCodecParameters *par);
其中AVCodecParameters来自于AVStream的codecpar成员变量。
codec打开API:
avcodec_open() -> avcodec_open2()
AVFrame初始化API:
avcodec_alloc_frame() -> av_frame_alloc()
初始化buffer:
avpicture_get_size() -> av_image_get_buffer_size()
avpicture_fill() -> av_image_fill_arrays()
读取视频帧并绘制:
原来在调用了av_read_frame()后直接利用 avcodec_decode_video2() 就可以获得AVFrame交给SDL绘制了,由于新的ffmpeg中废除了 avcodec_decode_video2() 这个方法,改为 avcodec_send_packet() 与 avcodec_receive_frame() 组合,因此代码上需要进行一些改造,伪代码如下:
while(av_read_frame(pFormatCtx, packet) >= 0) {
if(packet->stream_index == videoindex) {
ret = avcodec_send_packet(pCodecCtx, packet);
if(ret < 0) { do something }
while(ret >= 0) {
ret = avcodec_receive_frame(pCodecCtx, pFrame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){
break;
}else if (ret < 0) {
goto end;
//end处进行资源释放等善后处理
}
if (ret >= 0) {
//调用雷霄骅示例程序中的SDL绘制处理代码即可
}
}
}
}
以上伪代码只是大概表明了新API的使用方法,一些细节如API返回值异常处理需要在实际运用中再进行补充。
OK,大概就是这些
最后
以上就是酷炫翅膀为你收集整理的(ffmpeg3.3.x更新纪要)雷霄骅《最简单的基于FFMPEG+SDL的视频播放器》的全部内容,希望文章能够帮你解决(ffmpeg3.3.x更新纪要)雷霄骅《最简单的基于FFMPEG+SDL的视频播放器》所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复