您的位置:首页 > 移动开发 > Android开发

Android音视频二-FFmpeg的解码流程

2018-02-07 14:42 471 查看

前言

在学习FFmpeg的时候很有幸读到了雷霄骅博士的博客,非常感谢他留下的宝贵财富,知识是不朽的。

1 FFmpeg库简介



2 总体流程图如下



以上的所有函数都比较重要,需要记住。另外由于FFmpeg版本的改变,其中的不少函数也进行了修改。修改的地方大家可以查看
ffmpeg-3.4.1\doc\APIchanges
文件,里面有不同版本函数更改的说明。

2.1 FFmpeg解码函数简介

av_register_all() :注册所有组件
avformat_open_input() :打开输入视频文件
avformat_find_stream_info() :获取视频文件信息
avcodec_find_decoder() :查找解码器
avcodec_open2() : 打开解码器
av_read_frame() : 从输入文件读取一帧压缩数据;
avcodec_decode_video2() 解码一帧压缩数据
avcodec_close() 关闭解码器
avformat_close_input() 关闭输入视频文件


2.2 FFmpeg解码的数据结构



有的视频含有字幕,还会有AVStrean[3]



读取例如MP4格式的数据,就会得到stream数组,含有音视频和字幕那么数组的长度就是3,这里不确定哪个是音视频,这里就需要

遍历数组判断。

//视频解码,需要找到视频对应的AVStream所在format_ctx->streams的索引位置
//获取音频和视频流的索引位置
int i;
for(i = 0; i < format_ctx->nb_streams;i++){
if(format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){
player->video_stream_index = i;
}
else if(format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO){
player->audio_stream_index = i;
}
}


然后根据索引的位置获取相应的解码器

得到解码器上下文
AVFormatContext *format_ctx = player->input_format_ctx;
//获取解码器
AVCodecContext *codec_ctx = format_ctx->streams[stream_idx]->codec;


2.3 FFmpeg数据结构简介

AVFormatContext

封装格式上下文结构体,也是统领全局的结构体,保存了视频文件的封装格式相关信息

初始化
AVFormatContext *pFormatCtx = avformat_alloc_context();




AVInputFormat

每种封装格式(例如FLV,MKV,MP4,AVI)对应一个该结构体

初始化
AVInputFormat *av_input_format = pFormatCtx->iformat;




AVStream

视频文件中每个视频(音频)流对应的一个该结构体

pFormatCtx->streams[i]




AVCodecContext

编码器上下文结构体,保存了视频(音频)编解码相关信息

AVCodecContext *pCodecCtx = pFormatCtx->streams[v_stream_idx]->codec;




AVCodec

每种视频(音频)编解码器(例如H.264解码器)对应一个该结构体

AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id)




AVPacket

AVPacket用于存储一帧一帧的压缩数据(H264)

缓冲区,开辟空间

AVPacket *packet = (AVPacket*)av_malloc(sizeof(AVPacket));




AVFrame

存储一帧解码后像素(采样)数据

AVFrame *pFrame = av_frame_alloc();






3 总结

基础很重要,前期由于纠结一些细节导致学习效率很低,经过这一段时间的学习、总结发现还是要将基础打牢才能事半功倍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android ndk FFmpeg