ffplay源码__stream_component_open函数分析

前言

在read_thread线程中有三个地方调用了stream_component_open函数,分别对应音频流、视频流和字幕流,由于字幕流的索引值st_index[AVMEDIA_TYPE_SUBTITLE]小于0,实际执行时,只有前两个地方生效。在stream_component_open函数内部,又产生了两个线程audio_thread和video_thread,分别用于解码音频和视频,并把解码后的数据保存到对应的FrameQueue中。

一、打开解码器

1、寻找解码器

对于音频和视频,前面的操作都是一致的,分配解码器上下文AVCodecContext,并把媒体流的参数信息填充到新分配的解码器上下文avctx中,接下来根据解码器ID,从已经注册的解码器中,寻找对应的解码器。

以mp4为例,对于音频格式,一般是AAC,对于视频格式,一般是h264。

2、强制指定解码器

接下来有个forced_codec_name变量,这个变量是在switch语句中赋值的

audio_codec_name和video_codec_name,是main函数设置参数时用到的,如果运行ffplay时,参数中没有强制指定解码器,那么audio_codec_name和video_codec_name的值为NULL,对应forced_codec_name的值也为NULL。

if (forced_codec_name)
    codec = avcodec_find_decoder_by_name(forced_codec_name);

如果指定了解码器名称,则需要调用avcodec_find_decoder_by_name函数查找解码器。

3、解析参数

初步阶段只是添加了mp4文件作为参数,解析参数相关的功能,先忽略。

opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
   

4、打开解码器

然后用avcodec_open2()函数打开对应的解码器。

if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
        goto fail;
    }

接下来有个switch语句,对音频和视频单独处理,处理音频的功能相对复杂一些。

二、开启音频解码线程

这一部分涉及到SDL的功能,有几个重要的函数SDL_OpenAudioDevice和SDL_PauseAudioDevice,以及音频回调函数sdl_audio_callback,还有一个结构体SDL_AudioSpec都比较重要。

1、audio_open函数

首先定义了两个数组next_nb_channels和数组next_sample_rates,这两个数组是打开音频设备失败时用到的,实际运行时一般都可以找到音频设备,暂不分析。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值