The new function is called avformat_match_stream_specifier() and does not include logging the error message.tags/n1.0
| @@ -1088,62 +1088,10 @@ FILE *get_preset_file(char *filename, size_t filename_size, | |||||
| int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec) | int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec) | ||||
| { | { | ||||
| if (*spec <= '9' && *spec >= '0') /* opt:index */ | |||||
| return strtol(spec, NULL, 0) == st->index; | |||||
| else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' || | |||||
| *spec == 't') { /* opt:[vasdt] */ | |||||
| enum AVMediaType type; | |||||
| switch (*spec++) { | |||||
| case 'v': type = AVMEDIA_TYPE_VIDEO; break; | |||||
| case 'a': type = AVMEDIA_TYPE_AUDIO; break; | |||||
| case 's': type = AVMEDIA_TYPE_SUBTITLE; break; | |||||
| case 'd': type = AVMEDIA_TYPE_DATA; break; | |||||
| case 't': type = AVMEDIA_TYPE_ATTACHMENT; break; | |||||
| default: av_assert0(0); | |||||
| } | |||||
| if (type != st->codec->codec_type) | |||||
| return 0; | |||||
| if (*spec++ == ':') { /* possibly followed by :index */ | |||||
| int i, index = strtol(spec, NULL, 0); | |||||
| for (i = 0; i < s->nb_streams; i++) | |||||
| if (s->streams[i]->codec->codec_type == type && index-- == 0) | |||||
| return i == st->index; | |||||
| return 0; | |||||
| } | |||||
| return 1; | |||||
| } else if (*spec == 'p' && *(spec + 1) == ':') { | |||||
| int prog_id, i, j; | |||||
| char *endptr; | |||||
| spec += 2; | |||||
| prog_id = strtol(spec, &endptr, 0); | |||||
| for (i = 0; i < s->nb_programs; i++) { | |||||
| if (s->programs[i]->id != prog_id) | |||||
| continue; | |||||
| if (*endptr++ == ':') { | |||||
| int stream_idx = strtol(endptr, NULL, 0); | |||||
| return stream_idx >= 0 && | |||||
| stream_idx < s->programs[i]->nb_stream_indexes && | |||||
| st->index == s->programs[i]->stream_index[stream_idx]; | |||||
| } | |||||
| for (j = 0; j < s->programs[i]->nb_stream_indexes; j++) | |||||
| if (st->index == s->programs[i]->stream_index[j]) | |||||
| return 1; | |||||
| } | |||||
| return 0; | |||||
| } else if (*spec == '#') { | |||||
| int sid; | |||||
| char *endptr; | |||||
| sid = strtol(spec + 1, &endptr, 0); | |||||
| if (!*endptr) | |||||
| return st->id == sid; | |||||
| } else if (!*spec) /* empty specifier, matches everything */ | |||||
| return 1; | |||||
| av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec); | |||||
| return AVERROR(EINVAL); | |||||
| int ret = avformat_match_stream_specifier(s, st, spec); | |||||
| if (ret < 0) | |||||
| av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec); | |||||
| return ret; | |||||
| } | } | ||||
| AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, | AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, | ||||
| @@ -15,6 +15,9 @@ libavutil: 2011-04-18 | |||||
| API changes, most recent first: | API changes, most recent first: | ||||
| 2012-07-20 - xxxxxxx - lavf 54.18.100 | |||||
| Add avformat_match_stream_specifier() function. | |||||
| 2012-07-14 - xxxxxxx - lavc 54.38.100 - avcodec.h | 2012-07-14 - xxxxxxx - lavc 54.38.100 - avcodec.h | ||||
| Add metadata to AVFrame, and the accessor functions | Add metadata to AVFrame, and the accessor functions | ||||
| av_frame_get_metadata() and av_frame_set_metadata(). | av_frame_get_metadata() and av_frame_set_metadata(). | ||||
| @@ -1971,6 +1971,22 @@ const struct AVCodecTag *avformat_get_riff_audio_tags(void); | |||||
| */ | */ | ||||
| AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame); | AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame); | ||||
| /** | |||||
| * Check if the stream st contained in s is matched by the stream specifier | |||||
| * spec. | |||||
| * | |||||
| * See the "stream specifiers" chapter in the documentation for the syntax | |||||
| * of spec. | |||||
| * | |||||
| * @return >0 if st is matched by spec; | |||||
| * 0 if st is not matched by spec; | |||||
| * AVERROR code if spec is invalid | |||||
| * | |||||
| * @note A stream specifier can match several streams in the format. | |||||
| */ | |||||
| int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st, | |||||
| const char *spec); | |||||
| /** | /** | ||||
| * @} | * @} | ||||
| */ | */ | ||||
| @@ -4509,3 +4509,64 @@ AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *strea | |||||
| else | else | ||||
| return frame_sample_aspect_ratio; | return frame_sample_aspect_ratio; | ||||
| } | } | ||||
| int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st, | |||||
| const char *spec) | |||||
| { | |||||
| if (*spec <= '9' && *spec >= '0') /* opt:index */ | |||||
| return strtol(spec, NULL, 0) == st->index; | |||||
| else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' || | |||||
| *spec == 't') { /* opt:[vasdt] */ | |||||
| enum AVMediaType type; | |||||
| switch (*spec++) { | |||||
| case 'v': type = AVMEDIA_TYPE_VIDEO; break; | |||||
| case 'a': type = AVMEDIA_TYPE_AUDIO; break; | |||||
| case 's': type = AVMEDIA_TYPE_SUBTITLE; break; | |||||
| case 'd': type = AVMEDIA_TYPE_DATA; break; | |||||
| case 't': type = AVMEDIA_TYPE_ATTACHMENT; break; | |||||
| default: av_assert0(0); | |||||
| } | |||||
| if (type != st->codec->codec_type) | |||||
| return 0; | |||||
| if (*spec++ == ':') { /* possibly followed by :index */ | |||||
| int i, index = strtol(spec, NULL, 0); | |||||
| for (i = 0; i < s->nb_streams; i++) | |||||
| if (s->streams[i]->codec->codec_type == type && index-- == 0) | |||||
| return i == st->index; | |||||
| return 0; | |||||
| } | |||||
| return 1; | |||||
| } else if (*spec == 'p' && *(spec + 1) == ':') { | |||||
| int prog_id, i, j; | |||||
| char *endptr; | |||||
| spec += 2; | |||||
| prog_id = strtol(spec, &endptr, 0); | |||||
| for (i = 0; i < s->nb_programs; i++) { | |||||
| if (s->programs[i]->id != prog_id) | |||||
| continue; | |||||
| if (*endptr++ == ':') { | |||||
| int stream_idx = strtol(endptr, NULL, 0); | |||||
| return stream_idx >= 0 && | |||||
| stream_idx < s->programs[i]->nb_stream_indexes && | |||||
| st->index == s->programs[i]->stream_index[stream_idx]; | |||||
| } | |||||
| for (j = 0; j < s->programs[i]->nb_stream_indexes; j++) | |||||
| if (st->index == s->programs[i]->stream_index[j]) | |||||
| return 1; | |||||
| } | |||||
| return 0; | |||||
| } else if (*spec == '#') { | |||||
| int sid; | |||||
| char *endptr; | |||||
| sid = strtol(spec + 1, &endptr, 0); | |||||
| if (!*endptr) | |||||
| return st->id == sid; | |||||
| } else if (!*spec) /* empty specifier, matches everything */ | |||||
| return 1; | |||||
| av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec); | |||||
| return AVERROR(EINVAL); | |||||
| } | |||||
| @@ -30,8 +30,8 @@ | |||||
| #include "libavutil/avutil.h" | #include "libavutil/avutil.h" | ||||
| #define LIBAVFORMAT_VERSION_MAJOR 54 | #define LIBAVFORMAT_VERSION_MAJOR 54 | ||||
| #define LIBAVFORMAT_VERSION_MINOR 17 | |||||
| #define LIBAVFORMAT_VERSION_MICRO 101 | |||||
| #define LIBAVFORMAT_VERSION_MINOR 18 | |||||
| #define LIBAVFORMAT_VERSION_MICRO 100 | |||||
| #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | ||||
| LIBAVFORMAT_VERSION_MINOR, \ | LIBAVFORMAT_VERSION_MINOR, \ | ||||