The new function is called avformat_match_stream_specifier() and does not include logging the error message.
Unified · Split
| @@ -1088,62 +1088,10 @@ FILE *get_preset_file(char *filename, size_t filename_size, · 1087 unmodified lines | ||
| 1088 | 1088 | |
| 1089 | 1089 | int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec) |
| 1090 | 1090 | { |
| 1091 | − if (*spec <= '9' && *spec >= '0') /* opt:index */ | |
| 1092 | − return strtol(spec, NULL, 0) == st->index; | |
| 1093 | − else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' || | |
| 1094 | − *spec == 't') { /* opt:[vasdt] */ | |
| 1095 | − enum AVMediaType type; | |
| 1096 | − | |
| 1097 | − switch (*spec++) { | |
| 1098 | − case 'v': type = AVMEDIA_TYPE_VIDEO; break; | |
| 1099 | − case 'a': type = AVMEDIA_TYPE_AUDIO; break; | |
| 1100 | − case 's': type = AVMEDIA_TYPE_SUBTITLE; break; | |
| 1101 | − case 'd': type = AVMEDIA_TYPE_DATA; break; | |
| 1102 | − case 't': type = AVMEDIA_TYPE_ATTACHMENT; break; | |
| 1103 | − default: av_assert0(0); | |
| 1104 | − } | |
| 1105 | − if (type != st->codec->codec_type) | |
| 1106 | − return 0; | |
| 1107 | − if (*spec++ == ':') { /* possibly followed by :index */ | |
| 1108 | − int i, index = strtol(spec, NULL, 0); | |
| 1109 | − for (i = 0; i < s->nb_streams; i++) | |
| 1110 | − if (s->streams[i]->codec->codec_type == type && index-- == 0) | |
| 1111 | − return i == st->index; | |
| 1112 | − return 0; | |
| 1113 | − } | |
| 1114 | − return 1; | |
| 1115 | − } else if (*spec == 'p' && *(spec + 1) == ':') { | |
| 1116 | − int prog_id, i, j; | |
| 1117 | − char *endptr; | |
| 1118 | − spec += 2; | |
| 1119 | − prog_id = strtol(spec, &endptr, 0); | |
| 1120 | − for (i = 0; i < s->nb_programs; i++) { | |
| 1121 | − if (s->programs[i]->id != prog_id) | |
| 1122 | − continue; | |
| 1123 | − | |
| 1124 | − if (*endptr++ == ':') { | |
| 1125 | − int stream_idx = strtol(endptr, NULL, 0); | |
| 1126 | − return stream_idx >= 0 && | |
| 1127 | − stream_idx < s->programs[i]->nb_stream_indexes && | |
| 1128 | − st->index == s->programs[i]->stream_index[stream_idx]; | |
| 1129 | − } | |
| 1130 | − | |
| 1131 | − for (j = 0; j < s->programs[i]->nb_stream_indexes; j++) | |
| 1132 | − if (st->index == s->programs[i]->stream_index[j]) | |
| 1133 | − return 1; | |
| 1134 | − } | |
| 1135 | − return 0; | |
| 1136 | − } else if (*spec == '#') { | |
| 1137 | − int sid; | |
| 1138 | − char *endptr; | |
| 1139 | − sid = strtol(spec + 1, &endptr, 0); | |
| 1140 | − if (!*endptr) | |
| 1141 | − return st->id == sid; | |
| 1142 | − } else if (!*spec) /* empty specifier, matches everything */ | |
| 1143 | − return 1; | |
| 1144 | − | |
| 1145 | − av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec); | |
| 1146 | − return AVERROR(EINVAL); | |
| 1091 | + int ret = avformat_match_stream_specifier(s, st, spec); | |
| 1092 | + if (ret < 0) | |
| 1093 | + av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec); | |
| 1094 | + return ret; | |
| 1147 | 1095 | } |
| 1148 | 1096 | |
| 1149 | 1097 | AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, |
| @@ -15,6 +15,9 @@ libavutil: 2011-04-18 · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | API changes, most recent first: |
| 17 | 17 | |
| 18 | +2012-07-20 - xxxxxxx - lavf 54.18.100 | |
| 19 | + Add avformat_match_stream_specifier() function. | |
| 20 | + | |
| 18 | 21 | 2012-07-14 - xxxxxxx - lavc 54.38.100 - avcodec.h |
| 19 | 22 | Add metadata to AVFrame, and the accessor functions |
| 20 | 23 | av_frame_get_metadata() and av_frame_set_metadata(). |
| @@ -1971,6 +1971,22 @@ const struct AVCodecTag *avformat_get_riff_audio_tags(void); · 1970 unmodified lines | ||
| 1971 | 1971 | */ |
| 1972 | 1972 | AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame); |
| 1973 | 1973 | |
| 1974 | +/** | |
| 1975 | + * Check if the stream st contained in s is matched by the stream specifier | |
| 1976 | + * spec. | |
| 1977 | + * | |
| 1978 | + * See the "stream specifiers" chapter in the documentation for the syntax | |
| 1979 | + * of spec. | |
| 1980 | + * | |
| 1981 | + * @return >0 if st is matched by spec; | |
| 1982 | + * 0 if st is not matched by spec; | |
| 1983 | + * AVERROR code if spec is invalid | |
| 1984 | + * | |
| 1985 | + * @note A stream specifier can match several streams in the format. | |
| 1986 | + */ | |
| 1987 | +int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st, | |
| 1988 | + const char *spec); | |
| 1989 | + | |
| 1974 | 1990 | /** |
| 1975 | 1991 | * @} |
| 1976 | 1992 | */ |
| @@ -4509,3 +4509,64 @@ AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *strea · 4508 unmodified lines | ||
| 4509 | 4509 | else |
| 4510 | 4510 | return frame_sample_aspect_ratio; |
| 4511 | 4511 | } |
| 4512 | + | |
| 4513 | +int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st, | |
| 4514 | + const char *spec) | |
| 4515 | +{ | |
| 4516 | + if (*spec <= '9' && *spec >= '0') /* opt:index */ | |
| 4517 | + return strtol(spec, NULL, 0) == st->index; | |
| 4518 | + else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' || | |
| 4519 | + *spec == 't') { /* opt:[vasdt] */ | |
| 4520 | + enum AVMediaType type; | |
| 4521 | + | |
| 4522 | + switch (*spec++) { | |
| 4523 | + case 'v': type = AVMEDIA_TYPE_VIDEO; break; | |
| 4524 | + case 'a': type = AVMEDIA_TYPE_AUDIO; break; | |
| 4525 | + case 's': type = AVMEDIA_TYPE_SUBTITLE; break; | |
| 4526 | + case 'd': type = AVMEDIA_TYPE_DATA; break; | |
| 4527 | + case 't': type = AVMEDIA_TYPE_ATTACHMENT; break; | |
| 4528 | + default: av_assert0(0); | |
| 4529 | + } | |
| 4530 | + if (type != st->codec->codec_type) | |
| 4531 | + return 0; | |
| 4532 | + if (*spec++ == ':') { /* possibly followed by :index */ | |
| 4533 | + int i, index = strtol(spec, NULL, 0); | |
| 4534 | + for (i = 0; i < s->nb_streams; i++) | |
| 4535 | + if (s->streams[i]->codec->codec_type == type && index-- == 0) | |
| 4536 | + return i == st->index; | |
| 4537 | + return 0; | |
| 4538 | + } | |
| 4539 | + return 1; | |
| 4540 | + } else if (*spec == 'p' && *(spec + 1) == ':') { | |
| 4541 | + int prog_id, i, j; | |
| 4542 | + char *endptr; | |
| 4543 | + spec += 2; | |
| 4544 | + prog_id = strtol(spec, &endptr, 0); | |
| 4545 | + for (i = 0; i < s->nb_programs; i++) { | |
| 4546 | + if (s->programs[i]->id != prog_id) | |
| 4547 | + continue; | |
| 4548 | + | |
| 4549 | + if (*endptr++ == ':') { | |
| 4550 | + int stream_idx = strtol(endptr, NULL, 0); | |
| 4551 | + return stream_idx >= 0 && | |
| 4552 | + stream_idx < s->programs[i]->nb_stream_indexes && | |
| 4553 | + st->index == s->programs[i]->stream_index[stream_idx]; | |
| 4554 | + } | |
| 4555 | + | |
| 4556 | + for (j = 0; j < s->programs[i]->nb_stream_indexes; j++) | |
| 4557 | + if (st->index == s->programs[i]->stream_index[j]) | |
| 4558 | + return 1; | |
| 4559 | + } | |
| 4560 | + return 0; | |
| 4561 | + } else if (*spec == '#') { | |
| 4562 | + int sid; | |
| 4563 | + char *endptr; | |
| 4564 | + sid = strtol(spec + 1, &endptr, 0); | |
| 4565 | + if (!*endptr) | |
| 4566 | + return st->id == sid; | |
| 4567 | + } else if (!*spec) /* empty specifier, matches everything */ | |
| 4568 | + return 1; | |
| 4569 | + | |
| 4570 | + av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec); | |
| 4571 | + return AVERROR(EINVAL); | |
| 4572 | +} | |
| @@ -30,8 +30,8 @@ · 29 unmodified lines | ||
| 30 | 30 | #include "libavutil/avutil.h" |
| 31 | 31 | |
| 32 | 32 | #define LIBAVFORMAT_VERSION_MAJOR 54 |
| 33 | −#define LIBAVFORMAT_VERSION_MINOR 17 | |
| 34 | −#define LIBAVFORMAT_VERSION_MICRO 101 | |
| 33 | +#define LIBAVFORMAT_VERSION_MINOR 18 | |
| 34 | +#define LIBAVFORMAT_VERSION_MICRO 100 | |
| 35 | 35 | |
| 36 | 36 | #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ |
| 37 | 37 | LIBAVFORMAT_VERSION_MINOR, \ |