我的理解:
//传递两个参数selected:切换为该音轨或者关闭该音轨,stream:第几个音轨
int ffp_set_stream_selected(FFPlayer ffp, int stream, int selected)
{
VideoState is = ffp->is;
AVFormatContext ic = NULL;
AVCodecParameters codecpar = NULL;
if (!is)
return -1;
ic = is->ic;
if (!ic)
return -1;
if (stream < 0 || stream >= ic->nb_streams) {
av_log(ffp, AV_LOG_ERROR, "invalid stream index %d >= stream number (%d)\n", stream, ic->nb_streams);
return -1;
}
codecpar = ic->streams[stream]->codecpar;
if (selected) {
//如果选择该sream,则会先关闭当前的音轨,并打开stream指向的音轨,然后返回打开音轨函数的返回值
switch (codecpar->codec_type) {
case AVMEDIA_TYPE_VIDEO:
if (stream != is->video_stream && is->video_stream >= 0)
stream_component_close(ffp, is->video_stream);
break;
case AVMEDIA_TYPE_AUDIO:
if (stream != is->audio_stream && is->audio_stream >= 0)
stream_component_close(ffp, is->audio_stream);
break;
case AVMEDIA_TYPE_SUBTITLE:
if (stream != is->subtitle_stream && is->subtitle_stream >= 0)
stream_component_close(ffp, is->subtitle_stream);
break;
default:
av_log(ffp, AV_LOG_ERROR, "select invalid stream %d of video type %d\n", stream, codecpar->codec_type);
return -1;
}
return stream_component_open(ffp, stream);
} else {
//如果没有选择,则会执行以下代码关闭该音轨,并返回0
switch (codecpar->codec_type) {
case AVMEDIA_TYPE_VIDEO:
if (stream == is->video_stream)
stream_component_close(ffp, is->video_stream);
break;
case AVMEDIA_TYPE_AUDIO:
if (stream == is->audio_stream)
stream_component_close(ffp, is->audio_stream);
break;
case AVMEDIA_TYPE_SUBTITLE:
if (stream == is->subtitle_stream)
stream_component_close(ffp, is->subtitle_stream);
break;
default:
av_log(ffp, AV_LOG_ERROR, "select invalid stream %d of audio type %d\n", stream, codecpar->codec_type);
return -1;
}
return 0;
}
}
对于这个代码的解释有疑问: //传递两个参数tracksNum:音轨的个数,stream_index:第几个音轨 ffp_set_stream_selected(ffp, tracksNum, stream_index);
我的理解: //传递两个参数selected:切换为该音轨或者关闭该音轨,stream:第几个音轨 int ffp_set_stream_selected(FFPlayer ffp, int stream, int selected) { VideoState is = ffp->is; AVFormatContext ic = NULL; AVCodecParameters codecpar = NULL; if (!is) return -1; ic = is->ic; if (!ic) return -1;
//如果选择该sream,则会先关闭当前的音轨,并打开stream指向的音轨,然后返回打开音轨函数的返回值 switch (codecpar->codec_type) { case AVMEDIA_TYPE_VIDEO: if (stream != is->video_stream && is->video_stream >= 0) stream_component_close(ffp, is->video_stream); break; case AVMEDIA_TYPE_AUDIO: if (stream != is->audio_stream && is->audio_stream >= 0) stream_component_close(ffp, is->audio_stream); break; case AVMEDIA_TYPE_SUBTITLE: if (stream != is->subtitle_stream && is->subtitle_stream >= 0) stream_component_close(ffp, is->subtitle_stream); break; default: av_log(ffp, AV_LOG_ERROR, "select invalid stream %d of video type %d\n", stream, codecpar->codec_type); return -1; } return stream_component_open(ffp, stream); } else { //如果没有选择,则会执行以下代码关闭该音轨,并返回0 switch (codecpar->codec_type) { case AVMEDIA_TYPE_VIDEO: if (stream == is->video_stream) stream_component_close(ffp, is->video_stream); break; case AVMEDIA_TYPE_AUDIO: if (stream == is->audio_stream) stream_component_close(ffp, is->audio_stream); break; case AVMEDIA_TYPE_SUBTITLE: if (stream == is->subtitle_stream) stream_component_close(ffp, is->subtitle_stream); break; default: av_log(ffp, AV_LOG_ERROR, "select invalid stream %d of audio type %d\n", stream, codecpar->codec_type); return -1; } return 0; } }