上一篇文章我们对FFmpeg进行交叉编译,得到了编译产物:libffmpeg.so,然后创建了一个Android项目,对libffmpeg.so库实现了集成,还没阅读上一篇文章建议先阅读:Android FFmpeg开发(一),FFmpeg编译与集成
本文将利用FFmpeg对本地MP4视频文件进行视频流解码,然后使用FFmpeg中的libswscale模块将原始视频YUV帧转成RGB帧,最后将RGB帧数据刷到SurfaceView的surface中实现视频画面的渲染。
接下来,介绍下利用FFmpeg完成视频解码、渲染的流程。
一、FFmpeg解码视频流
利用FFmpeg API对视频进行解码,然后将解码数据转换成RGBA格式数据,最后将画面数据刷到surface上,涉及到FFmpeg核心API调用流程如下:
![](https://i-blog.csdnimg.cn/blog_migrate/60cfa7eabcfa7843381d77364df97c59.png)
解码流程代码如下:
// 1. 创建封装格式上下文
mAVFormatContext = avformat_alloc_context();
// 2. 打开文件
if (avformat_open_input(&mAVFormatContext, mUrl, NULL, NULL) != 0) {
LOGD("BaseDecoder::initFFDecoder, avformat_open_input fail\n");
break;
}
// 3. 获取音视频信息流信息
if (avformat_find_stream_info(mAVFormatContext, NULL) < 0) {
LOGD("BaseDecoder::initFFDecoder, avformat_find_stream_info fail\n");
break;
}
// 4. 获取音视频流的索引
for (int i = 0; i < mAVFormatContext->nb_streams; i++) {
if (mAVFormatContext->streams[i]->codecpar->codec_type == mMediaType) {
mStreamIndex = i;
break;
}
}
if (mStreamIndex == -1) {
LOGD("BaseDecoder::initFFDecoder, failed to find stream index\n");
break;
}
// 5. 获取解码器参数
AVCodecParameters *codecParameters = mAVFormatContext->streams[mStreamIndex]->codecpar;
// 6. 获取解码器
mAVCodec = avcodec_find_decoder(codecParameters->codec_id);