通过av_find_best_stream()函数来获取流的索引:
/**
* 在文件中找到“最佳”流。
* 最佳流根据各种启发式确定为最
* 可能是用户所期望的。
* 如果解码器参数非空,av_find_best_stream 将找到
* 流编解码器的默认解码器;没有解码器可以处理的流
* 被发现被忽略。
*
* @param ic 媒体文件句柄
* @param type 流类型:视频、音频、字幕等。
* @param Wanted_stream_nb 用户请求的流号,
* 或 -1 用于自动选择
* @param related_stream 尝试查找相关的流(例如,在相同的
* program) 到这个,或者 -1 如果没有
* @paramdecoder_ret 如果非空,返回解码器
* 选定的流
* @param 标志标志;目前没有定义
* @return 成功时的非负流数,
* AVERROR_STREAM_NOT_FOUND 如果没有请求类型的流
* 可以找到,
* AVERROR_DECODER_NOT_FOUND 如果找到流但没有解码器
* @note 如果 av_find_best_stream 成功返回并且没有decoder_ret
* NULL,则 *decoder_ret 保证设置为有效的 AVCodec。
*/
int av_find_best_stream(AVFormatContext *ic,
enum AVMediaType type,
int wanted_stream_nb,
int related_stream,
AVCodec **decoder_ret,
int flags);
源码:
int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type,
int wanted_stream_nb, int related_stream,
AVCodec **decoder_ret, int flags)
{
int i, nb_streams = ic->nb_streams;
int ret = AVERROR_STREAM_NOT_FOUND;
int best_count = -1, best_multiframe = -1, best_disposition = -1;
int count, multiframe, disposition;
int64_t best_bitrate = -1;
int64_t bitrate;
unsigned *program = NULL;
const AVCodec *decoder = NULL, *best_decoder = NULL;
if (related_stream >= 0 && wanted_stream_nb < 0) {
AVProgram *p = av_find_program_from_stream(ic, NULL, related_stream);
if (p) {
program = p->stream_index;
nb_streams = p->nb_stream_indexes;
}
}
for (i = 0; i < nb_streams; i++) {
int real_stream_index = program ? program[i] : i;
AVStream *st = ic->streams[real_stream_index];
AVCodecParameters *par = st->codecpar;
if (par->codec_type != type)
continue;
if (wanted_stream_nb >= 0 && real_stream_index != wanted_stream_nb)
continue;
if (type == AVMEDIA_TYPE_AUDIO && !(par->channels && par->sample_rate))
continue;
if (decoder_ret) {
decoder = find_decoder(ic, st, par->codec_id);
if (!decoder) {
if (ret < 0)
ret = AVERROR_DECODER_NOT_FOUND;
continue;
}
}
disposition = !(st->disposition & (AV_DISPOSITION_HEARING_IMPAIRED | AV_DISPOSITION_VISUAL_IMPAIRED))
+ !! (st->disposition & AV_DISPOSITION_DEFAULT);
count = st->codec_info_nb_frames;
bitrate = par->bit_rate;
multiframe = FFMIN(5, count);
if ((best_disposition > disposition) ||
(best_disposition == disposition && best_multiframe > multiframe) ||
(best_disposition == disposition && best_multiframe == multiframe && best_bitrate > bitrate) ||
(best_disposition == disposition && best_multiframe == multiframe && best_bitrate == bitrate && best_count >= count))
continue;
best_disposition = disposition;
best_count = count;
best_bitrate = bitrate;
best_multiframe = multiframe;
ret = real_stream_index;
best_decoder = decoder;
if (program && i == nb_streams - 1 && ret < 0) {
program = NULL;
nb_streams = ic->nb_streams;
/* no related stream found, try again with everything */
i = 0;
}
}
if (decoder_ret)
*decoder_ret = (AVCodec*)best_decoder;
return ret;
}