Implement av_find_best_stream.
Originally committed as revision 26104 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
107a7e3e7b
commit
9128ae08b3
@ -13,6 +13,9 @@ libavutil: 2009-03-08
|
|||||||
|
|
||||||
API changes, most recent first:
|
API changes, most recent first:
|
||||||
|
|
||||||
|
2010-12-XX - r26104 - lavformat 52.91.0 - av_find_best_stream()
|
||||||
|
Add av_find_best_stream to libavformat/avformat.h.
|
||||||
|
|
||||||
2010-12-27 - r26103 - lavf 52.90.0
|
2010-12-27 - r26103 - lavf 52.90.0
|
||||||
Add AVFMT_NOSTREAMS flag for formats with no streams,
|
Add AVFMT_NOSTREAMS flag for formats with no streams,
|
||||||
like e.g. text metadata.
|
like e.g. text metadata.
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#define AVFORMAT_AVFORMAT_H
|
#define AVFORMAT_AVFORMAT_H
|
||||||
|
|
||||||
#define LIBAVFORMAT_VERSION_MAJOR 52
|
#define LIBAVFORMAT_VERSION_MAJOR 52
|
||||||
#define LIBAVFORMAT_VERSION_MINOR 90
|
#define LIBAVFORMAT_VERSION_MINOR 91
|
||||||
#define LIBAVFORMAT_VERSION_MICRO 0
|
#define LIBAVFORMAT_VERSION_MICRO 0
|
||||||
|
|
||||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||||
@ -1140,6 +1140,37 @@ AVFormatContext *avformat_alloc_context(void);
|
|||||||
*/
|
*/
|
||||||
int av_find_stream_info(AVFormatContext *ic);
|
int av_find_stream_info(AVFormatContext *ic);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the "best" stream in the file.
|
||||||
|
* The best stream is determined according to various heuristics as the most
|
||||||
|
* likely to be what the user expects.
|
||||||
|
* If the decoder parameter is non-NULL, av_find_best_stream will find the
|
||||||
|
* default decoder for the stream's codec; streams for which no decoder can
|
||||||
|
* be found are ignored.
|
||||||
|
*
|
||||||
|
* @param ic media file handle
|
||||||
|
* @param type stream type: video, audio, subtitles, etc.
|
||||||
|
* @param wanted_stream_nb user-requested stream number,
|
||||||
|
* or -1 for automatic selection
|
||||||
|
* @param related_stream try to find a stream related (eg. in the same
|
||||||
|
* program) to this one, or -1 if none
|
||||||
|
* @param decoder_ret if non-NULL, returns the decoder for the
|
||||||
|
* selected stream
|
||||||
|
* @param flags flags; none are currently defined
|
||||||
|
* @return the non-negative stream number in case of success,
|
||||||
|
* AVERROR_STREAM_NOT_FOUND if no stream with the requested type
|
||||||
|
* could be found,
|
||||||
|
* AVERROR_DECODER_NOT_FOUND if streams were found but no decoder
|
||||||
|
* @note If av_find_best_stream returns successfully and decoder_ret is not
|
||||||
|
* NULL, then *decoder_ret is guaranteed to be set to a valid AVCodec.
|
||||||
|
*/
|
||||||
|
int av_find_best_stream(AVFormatContext *ic,
|
||||||
|
enum AVMediaType type,
|
||||||
|
int wanted_stream_nb,
|
||||||
|
int related_stream,
|
||||||
|
AVCodec **decoder_ret,
|
||||||
|
int flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a transport packet from a media file.
|
* Read a transport packet from a media file.
|
||||||
*
|
*
|
||||||
|
@ -2458,6 +2458,67 @@ int av_find_stream_info(AVFormatContext *ic)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static AVProgram *find_program_from_stream(AVFormatContext *ic, int s)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < ic->nb_programs; i++)
|
||||||
|
for (j = 0; j < ic->programs[i]->nb_stream_indexes; j++)
|
||||||
|
if (ic->programs[i]->stream_index[j] == s)
|
||||||
|
return ic->programs[i];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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, stream_number = 0;
|
||||||
|
int ret = AVERROR_STREAM_NOT_FOUND, best_count = -1;
|
||||||
|
unsigned *program = NULL;
|
||||||
|
AVCodec *decoder = NULL, *best_decoder = NULL;
|
||||||
|
|
||||||
|
if (related_stream >= 0 && wanted_stream_nb < 0) {
|
||||||
|
AVProgram *p = find_program_from_stream(ic, related_stream);
|
||||||
|
if (p) {
|
||||||
|
program = p->stream_index;
|
||||||
|
nb_streams = p->nb_stream_indexes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < nb_streams; i++) {
|
||||||
|
AVStream *st = ic->streams[program ? program[i] : i];
|
||||||
|
AVCodecContext *avctx = st->codec;
|
||||||
|
if (avctx->codec_type != type)
|
||||||
|
continue;
|
||||||
|
if (wanted_stream_nb >= 0 && stream_number++ != wanted_stream_nb)
|
||||||
|
continue;
|
||||||
|
if (decoder_ret) {
|
||||||
|
decoder = avcodec_find_decoder(ic->streams[i]->codec->codec_id);
|
||||||
|
if (!decoder) {
|
||||||
|
if (ret < 0)
|
||||||
|
ret = AVERROR_DECODER_NOT_FOUND;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (best_count >= st->codec_info_nb_frames)
|
||||||
|
continue;
|
||||||
|
best_count = st->codec_info_nb_frames;
|
||||||
|
ret = i;
|
||||||
|
best_decoder = decoder;
|
||||||
|
if (program && i == nb_streams - 1 && ret < 0) {
|
||||||
|
program = NULL;
|
||||||
|
nb_streams = ic->nb_streams;
|
||||||
|
i = 0; /* no related stream found, try again with everything */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (decoder_ret)
|
||||||
|
*decoder_ret = best_decoder;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************/
|
/*******************************************************/
|
||||||
|
|
||||||
int av_read_play(AVFormatContext *s)
|
int av_read_play(AVFormatContext *s)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user