FFmpeg的使用过程(解码)

 

1.引用头文件

extern "C"的解释,C++支持函数的重载,面向过程的C语言不支持函数重载的。同一个函数在C++中编译后与在C中编译后,在符号表中的签名时不同的,假设针对同一个函数,void decode(float position,float duration);在C语言中编译的签名是_decode,而在C++语言中,一般编译器的生成则类似于_decode_float_float.虽然编译没有问题,在链接的过程会链接_decode_float_float,FFmpeg核心是C语言写的。

2.注册协议,格式与编解码器

avformat_network_init();av_register_all();avcodec_register_all();av_register_all方法已经调用了avcodec_register_all()

3.打开媒体文件源,并设置超时回调

*注册了格式以及编解码之后,接下来就应该打开对应的媒体文件,当然文件可能是本地磁盘的文件,也可以是网络媒体资源的一个链接,如果是网络链接,则会涉及到不同的协议,比如RTMP,HTTP等协议的视频源。打开媒体资源以及设置超时回调的代码:AVFormatContext *formatCtx = avformat_alloc_context();AVIOInterruptCB int_cb = {interrupt_callback,(__bridge void *)(self)};formatCtx->interrput_callback = int_cb;avformat_open_input(formatCtx,path,NULL,NULL);avformat_find_stream_info(formatCtx,NULL);

4.寻找各个流,并且打开对应的解码器

for(int i = 0;i < formatCtx->nb_streams;i++){AVStream *stream = formatCtx->streams[i];if(AVMEDIA_TYPE_VIDEO == stream->codec->codec_type){//视频流videoStreamIndex = i;}else if(AVMEDIA_TYPE_AUDIO == stream->codec->codec_type){//音频流audioStreamIndex = i;}}

打开音频流解码器

AVCodecContext *audioCodecCtx = audioStream->codec;AVCodec *codec = avcodec_find_decoder(audioCodecCtx->codec_id);if(!codec){//找不到对应的音频解码器}int openCodecErrCode = 0;if((openCodecErrCode = avcodec_open2(codecCtx,codec,NULL)) < 0){//打开音频解码器失败}

打开视频流解码器

AVCodecContext *videoCodecCtx = videoStream->codec;AVCodec *codec = avcodec_find_decoder(videoCodecCtx->codec_id);if(!codec){//找不到对应的视频解码器}int openCodecErrCode = 0;if((openCodecErrCode = avcodec_open2(codecCtx,codec,NULL)) < 0){//打开视频解码器失败}

5.初始化解码后数据的结构体

*知道了音视频解码器的信息之后,下面需要分配出解码之后的数据所存放的内存空间,以及进行格式转换需要用到的对象。

构建音频格式转换对象以及音频解码后数据存放的对象:

*SwrContext *swrContext = NULL;if(audioCodecCtx->sample_fmt != AV_SAMPLE_FMT_S16){///如果不是我们需要的数据格式swrContext = swr_alloc_set_opts(NULL,outputChannel,AV_SAMPLE_FMT_S16,outSampleRate,in_ch_layout,0,NULL);if(!swrContext || swr_init(swrContext)){if(swrContext){swr_free(&swrContext);}}audioFrame = avcodec_alloc_frame();}

构建视频格式转换对象以及视频解码后的数据存放的对象

AVPicture picture;bool pictureValid = avpicture_alloc(&picture,PIX_FMT_YUV420P,videoCodecCtx->width,videoCodecCtx->height)==0;if(!pictureValid){return false;}swsContext = sws_getCachedContext(swsContext,videoCodecCtx->width,videoCodecCtx->height,videoCodecCtx->pix_fmt,videoCodecCtx->width,videoCodecCtx->height,PIX_FMT_YUV420P,SWS_FAST_BILINEAR,NULL,NULL,NULL);videoFrame = avcodec_alloc_frame();

6.读取流内容并且解码

*打开解码器之后,就可以读取一部分流中的数据,然后将压缩的数据作为解码器的输入,解码器将其解码成原始数据,之后将原始数据写入文件

7.处理解码后的裸数据

*音频的裸数据PCM,视频的裸数据YUV

8.关闭所有的资源

*解码完毕后,或者在解码过程中不想继续解码了,就可以退出程序了,包括用到FFMPEG框架中的资源,对外的链接资源,关闭音频资源,视频资源。

 

原文链接: https://www.cnblogs.com/tryFighting/p/13021854.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    FFmpeg的使用过程(解码)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/352041

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午7:18
下一篇 2023年3月2日 上午7:18

相关推荐