Originally committed as revision 26104 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -13,6 +13,9 @@ libavutil: 2009-03-08 |
| 13 | 13 |
|
| 14 | 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 | 19 |
2010-12-27 - r26103 - lavf 52.90.0 |
| 17 | 20 |
Add AVFMT_NOSTREAMS flag for formats with no streams, |
| 18 | 21 |
like e.g. text metadata. |
| ... | ... |
@@ -22,7 +22,7 @@ |
| 22 | 22 |
#define AVFORMAT_AVFORMAT_H |
| 23 | 23 |
|
| 24 | 24 |
#define LIBAVFORMAT_VERSION_MAJOR 52 |
| 25 |
-#define LIBAVFORMAT_VERSION_MINOR 90 |
|
| 25 |
+#define LIBAVFORMAT_VERSION_MINOR 91 |
|
| 26 | 26 |
#define LIBAVFORMAT_VERSION_MICRO 0 |
| 27 | 27 |
|
| 28 | 28 |
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ |
| ... | ... |
@@ -1141,6 +1141,37 @@ AVFormatContext *avformat_alloc_context(void); |
| 1141 | 1141 |
int av_find_stream_info(AVFormatContext *ic); |
| 1142 | 1142 |
|
| 1143 | 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 |
+ |
|
| 1174 |
+/** |
|
| 1144 | 1175 |
* Read a transport packet from a media file. |
| 1145 | 1176 |
* |
| 1146 | 1177 |
* This function is obsolete and should never be used. |
| ... | ... |
@@ -2458,6 +2458,67 @@ int av_find_stream_info(AVFormatContext *ic) |
| 2458 | 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 | 2524 |
int av_read_play(AVFormatContext *s) |