| 1009 | } |
| 1010 | |
| 1011 | int stream_specifier_parse(StreamSpecifier *ss, const char *spec, |
| 1012 | int allow_remainder, void *logctx) |
| 1013 | { |
| 1014 | char *endptr; |
| 1015 | int ret; |
| 1016 | |
| 1017 | memset(ss, 0, sizeof(*ss)); |
| 1018 | |
| 1019 | ss->idx = -1; |
| 1020 | ss->media_type = AVMEDIA_TYPE_UNKNOWN; |
| 1021 | ss->stream_list = STREAM_LIST_ALL; |
| 1022 | |
| 1023 | av_log(logctx, AV_LOG_TRACE, "Parsing stream specifier: %s\n", spec); |
| 1024 | |
| 1025 | while (*spec) { |
| 1026 | if (*spec <= '9' && *spec >= '0') { /* opt:index */ |
| 1027 | ss->idx = strtol(spec, &endptr, 0); |
| 1028 | |
| 1029 | av_assert0(endptr > spec); |
| 1030 | spec = endptr; |
| 1031 | |
| 1032 | av_log(logctx, AV_LOG_TRACE, |
| 1033 | "Parsed index: %d; remainder: %s\n", ss->idx, spec); |
| 1034 | |
| 1035 | // this terminates the specifier |
| 1036 | break; |
| 1037 | } else if ((*spec == 'v' || *spec == 'a' || *spec == 's' || |
| 1038 | *spec == 'd' || *spec == 't' || *spec == 'V') && |
| 1039 | !cmdutils_isalnum(*(spec + 1))) { /* opt:[vasdtV] */ |
| 1040 | if (ss->media_type != AVMEDIA_TYPE_UNKNOWN) { |
| 1041 | av_log(logctx, AV_LOG_ERROR, "Stream type specified multiple times\n"); |
| 1042 | ret = AVERROR(EINVAL); |
| 1043 | goto fail; |
| 1044 | } |
| 1045 | |
| 1046 | switch (*spec++) { |
| 1047 | case 'v': ss->media_type = AVMEDIA_TYPE_VIDEO; break; |
| 1048 | case 'a': ss->media_type = AVMEDIA_TYPE_AUDIO; break; |
| 1049 | case 's': ss->media_type = AVMEDIA_TYPE_SUBTITLE; break; |
| 1050 | case 'd': ss->media_type = AVMEDIA_TYPE_DATA; break; |
| 1051 | case 't': ss->media_type = AVMEDIA_TYPE_ATTACHMENT; break; |
| 1052 | case 'V': ss->media_type = AVMEDIA_TYPE_VIDEO; |
| 1053 | ss->no_apic = 1; break; |
| 1054 | default: av_assert0(0); |
| 1055 | } |
| 1056 | |
| 1057 | av_log(logctx, AV_LOG_TRACE, "Parsed media type: %s; remainder: %s\n", |
| 1058 | av_get_media_type_string(ss->media_type), spec); |
| 1059 | } else if (*spec == 'g' && *(spec + 1) == ':') { |
| 1060 | if (ss->stream_list != STREAM_LIST_ALL) |
| 1061 | goto multiple_stream_lists; |
| 1062 | |
| 1063 | spec += 2; |
| 1064 | if (*spec == '#' || (*spec == 'i' && *(spec + 1) == ':')) { |
| 1065 | ss->stream_list = STREAM_LIST_GROUP_ID; |
| 1066 | |
| 1067 | spec += 1 + (*spec == 'i'); |
| 1068 | } else |
no test coverage detected