Originally committed as revision 26104 to svn://svn.ffmpeg.org/ffmpeg/trunk
Unified · Split
| @@ -13,6 +13,9 @@ libavutil: 2009-03-08 · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | API changes, most recent first: | 14 | API changes, most recent first: |
| 15 | 15 | ||
| 16 | 2010-12-XX - r26104 - lavformat 52.91.0 - av_find_best_stream() | ||
| 17 | Add av_find_best_stream to libavformat/avformat.h. | ||
| 18 | |||
| 16 | 2010-12-27 - r26103 - lavf 52.90.0 | 19 | 2010-12-27 - r26103 - lavf 52.90.0 |
| 17 | Add AVFMT_NOSTREAMS flag for formats with no streams, | 20 | Add AVFMT_NOSTREAMS flag for formats with no streams, |
| 18 | like e.g. text metadata. | 21 | like e.g. text metadata. |
| @@ -22,7 +22,7 @@ · 21 unmodified lines | |||
| 22 | #define AVFORMAT_AVFORMAT_H | 22 | #define AVFORMAT_AVFORMAT_H |
| 23 | 23 | ||
| 24 | #define LIBAVFORMAT_VERSION_MAJOR 52 | 24 | #define LIBAVFORMAT_VERSION_MAJOR 52 |
| 25 | #define LIBAVFORMAT_VERSION_MINOR 90 | 25 | #define LIBAVFORMAT_VERSION_MINOR 91 |
| 26 | #define LIBAVFORMAT_VERSION_MICRO 0 | 26 | #define LIBAVFORMAT_VERSION_MICRO 0 |
| 27 | 27 | ||
| 28 | #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | 28 | #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ |
| @@ -1140,6 +1140,37 @@ AVFormatContext *avformat_alloc_context(void); · 1111 unmodified lines | |||
| 1140 | */ | 1140 | */ |
| 1141 | int av_find_stream_info(AVFormatContext *ic); | 1141 | int av_find_stream_info(AVFormatContext *ic); |
| 1142 | 1142 | ||
| 1143 | /** | ||
| 1144 | * Find the "best" stream in the file. | ||
| 1145 | * The best stream is determined according to various heuristics as the most | ||
| 1146 | * likely to be what the user expects. | ||
| 1147 | * If the decoder parameter is non-NULL, av_find_best_stream will find the | ||
| 1148 | * default decoder for the stream's codec; streams for which no decoder can | ||
| 1149 | * be found are ignored. | ||
| 1150 | * | ||
| 1151 | * @param ic media file handle | ||
| 1152 | * @param type stream type: video, audio, subtitles, etc. | ||
| 1153 | * @param wanted_stream_nb user-requested stream number, | ||
| 1154 | * or -1 for automatic selection | ||
| 1155 | * @param related_stream try to find a stream related (eg. in the same | ||
| 1156 | * program) to this one, or -1 if none | ||
| 1157 | * @param decoder_ret if non-NULL, returns the decoder for the | ||
| 1158 | * selected stream | ||
| 1159 | * @param flags flags; none are currently defined | ||
| 1160 | * @return the non-negative stream number in case of success, | ||
| 1161 | * AVERROR_STREAM_NOT_FOUND if no stream with the requested type | ||
| 1162 | * could be found, | ||
| 1163 | * AVERROR_DECODER_NOT_FOUND if streams were found but no decoder | ||
| 1164 | * @note If av_find_best_stream returns successfully and decoder_ret is not | ||
| 1165 | * NULL, then *decoder_ret is guaranteed to be set to a valid AVCodec. | ||
| 1166 | */ | ||
| 1167 | int av_find_best_stream(AVFormatContext *ic, | ||
| 1168 | enum AVMediaType type, | ||
| 1169 | int wanted_stream_nb, | ||
| 1170 | int related_stream, | ||
| 1171 | AVCodec **decoder_ret, | ||
| 1172 | int flags); | ||
| 1173 | |||
| 1143 | /** | 1174 | /** |
| 1144 | * Read a transport packet from a media file. | 1175 | * Read a transport packet from a media file. |
| 1145 | * | 1176 | * |
| @@ -2458,6 +2458,67 @@ int av_find_stream_info(AVFormatContext *ic) · 2457 unmodified lines | |||
| 2458 | return ret; | 2458 | return ret; |
| 2459 | } | 2459 | } |
| 2460 | 2460 | ||
| 2461 | static AVProgram *find_program_from_stream(AVFormatContext *ic, int s) | ||
| 2462 | { | ||
| 2463 | int i, j; | ||
| 2464 | |||
| 2465 | for (i = 0; i < ic->nb_programs; i++) | ||
| 2466 | for (j = 0; j < ic->programs[i]->nb_stream_indexes; j++) | ||
| 2467 | if (ic->programs[i]->stream_index[j] == s) | ||
| 2468 | return ic->programs[i]; | ||
| 2469 | return NULL; | ||
| 2470 | } | ||
| 2471 | |||
| 2472 | int av_find_best_stream(AVFormatContext *ic, | ||
| 2473 | enum AVMediaType type, | ||
| 2474 | int wanted_stream_nb, | ||
| 2475 | int related_stream, | ||
| 2476 | AVCodec **decoder_ret, | ||
| 2477 | int flags) | ||
| 2478 | { | ||
| 2479 | int i, nb_streams = ic->nb_streams, stream_number = 0; | ||
| 2480 | int ret = AVERROR_STREAM_NOT_FOUND, best_count = -1; | ||
| 2481 | unsigned *program = NULL; | ||
| 2482 | AVCodec *decoder = NULL, *best_decoder = NULL; | ||
| 2483 | |||
| 2484 | if (related_stream >= 0 && wanted_stream_nb < 0) { | ||
| 2485 | AVProgram *p = find_program_from_stream(ic, related_stream); | ||
| 2486 | if (p) { | ||
| 2487 | program = p->stream_index; | ||
| 2488 | nb_streams = p->nb_stream_indexes; | ||
| 2489 | } | ||
| 2490 | } | ||
| 2491 | for (i = 0; i < nb_streams; i++) { | ||
| 2492 | AVStream *st = ic->streams[program ? program[i] : i]; | ||
| 2493 | AVCodecContext *avctx = st->codec; | ||
| 2494 | if (avctx->codec_type != type) | ||
| 2495 | continue; | ||
| 2496 | if (wanted_stream_nb >= 0 && stream_number++ != wanted_stream_nb) | ||
| 2497 | continue; | ||
| 2498 | if (decoder_ret) { | ||
| 2499 | decoder = avcodec_find_decoder(ic->streams[i]->codec->codec_id); | ||
| 2500 | if (!decoder) { | ||
| 2501 | if (ret < 0) | ||
| 2502 | ret = AVERROR_DECODER_NOT_FOUND; | ||
| 2503 | continue; | ||
| 2504 | } | ||
| 2505 | } | ||
| 2506 | if (best_count >= st->codec_info_nb_frames) | ||
| 2507 | continue; | ||
| 2508 | best_count = st->codec_info_nb_frames; | ||
| 2509 | ret = i; | ||
| 2510 | best_decoder = decoder; | ||
| 2511 | if (program && i == nb_streams - 1 && ret < 0) { | ||
| 2512 | program = NULL; | ||
| 2513 | nb_streams = ic->nb_streams; | ||
| 2514 | i = 0; /* no related stream found, try again with everything */ | ||
| 2515 | } | ||
| 2516 | } | ||
| 2517 | if (decoder_ret) | ||
| 2518 | *decoder_ret = best_decoder; | ||
| 2519 | return ret; | ||
| 2520 | } | ||
| 2521 | |||
| 2461 | /*******************************************************/ | 2522 | /*******************************************************/ |
| 2462 | 2523 | ||
| 2463 | int av_read_play(AVFormatContext *s) | 2524 | int av_read_play(AVFormatContext *s) |