(ffmpeg3.3.x更新纪要)雷霄骅《最简单的基于FFMPEG+SDL的视频播放器》

最近由于工作需要,需要使用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,大概就是这些

你可能感兴趣的:(ffmpeg)