[FFmpeg-cvslog] r26104 - in trunk: doc/APIchanges libavformat/avformat.h libavformat/utils.c
cigaes
subversion
Mon Dec 27 10:08:20 CET 2010
Author: cigaes
Date: Mon Dec 27 10:08:20 2010
New Revision: 26104
Log:
Implement av_find_best_stream.
Modified:
trunk/doc/APIchanges
trunk/libavformat/avformat.h
trunk/libavformat/utils.c
Modified: trunk/doc/APIchanges
==============================================================================
--- trunk/doc/APIchanges Mon Dec 27 08:46:57 2010 (r26103)
+++ trunk/doc/APIchanges Mon Dec 27 10:08:20 2010 (r26104)
@@ -13,6 +13,9 @@ libavutil: 2009-03-08
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
Add AVFMT_NOSTREAMS flag for formats with no streams,
like e.g. text metadata.
Modified: trunk/libavformat/avformat.h
==============================================================================
--- trunk/libavformat/avformat.h Mon Dec 27 08:46:57 2010 (r26103)
+++ trunk/libavformat/avformat.h Mon Dec 27 10:08:20 2010 (r26104)
@@ -22,7 +22,7 @@
#define AVFORMAT_AVFORMAT_H
#define LIBAVFORMAT_VERSION_MAJOR 52
-#define LIBAVFORMAT_VERSION_MINOR 90
+#define LIBAVFORMAT_VERSION_MINOR 91
#define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
@@ -1141,6 +1141,37 @@ AVFormatContext *avformat_alloc_context(
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.
*
* This function is obsolete and should never be used.
Modified: trunk/libavformat/utils.c
==============================================================================
--- trunk/libavformat/utils.c Mon Dec 27 08:46:57 2010 (r26103)
+++ trunk/libavformat/utils.c Mon Dec 27 10:08:20 2010 (r26104)
@@ -2458,6 +2458,67 @@ int av_find_stream_info(AVFormatContext
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)
More information about the ffmpeg-cvslog
mailing list