int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)

{

    if (*spec <= '9' && *spec >= '0') 

        return strtol(spec, NULL, 0) == st->index;

    else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||

             *spec == 't') { 

        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;


        }

        if (type != st->codec->codec_type)

            return 0;

        if (*spec++ == ':') { 

            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) 

        return 1;



    av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);

    return AVERROR(EINVAL);

}