Skip to content
Snippets Groups Projects
cmdutils.c 40.4 KiB
Newer Older
  • Learn to ignore specific revisions
  •     *size = ftell(f);
        fseek(f, 0, SEEK_SET);
        *bufptr = av_malloc(*size + 1);
        if (!*bufptr) {
    
            av_log(NULL, AV_LOG_ERROR, "Could not allocate file buffer\n");
    
        ret = fread(*bufptr, 1, *size, f);
        if (ret < *size) {
            av_free(*bufptr);
            if (ferror(f)) {
                av_log(NULL, AV_LOG_ERROR, "Error while reading file '%s': %s\n",
                       filename, strerror(errno));
                ret = AVERROR(errno);
            } else
                ret = AVERROR_EOF;
        } else {
            ret = 0;
            (*bufptr)[*size++] = '\0';
        }
    
        return ret;
    
    FILE *get_preset_file(char *filename, size_t filename_size,
    
                          const char *preset_name, int is_path,
                          const char *codec_name)
    
        const char *base[3] = { getenv("FFMPEG_DATADIR"),
    
                                getenv("HOME"),
    
    
        if (is_path) {
            av_strlcpy(filename, preset_name, filename_size);
            f = fopen(filename, "r");
        } else {
    
    Gianluigi Tiesi's avatar
    Gianluigi Tiesi committed
    #ifdef _WIN32
            char datadir[MAX_PATH], *ls;
            base[2] = NULL;
    
            if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1))
            {
                for (ls = datadir; ls < datadir + strlen(datadir); ls++)
                    if (*ls == '\\') *ls = '/';
    
                if (ls = strrchr(datadir, '/'))
                {
                    *ls = 0;
                    strncat(datadir, "/ffpresets",  sizeof(datadir) - 1 - strlen(datadir));
                    base[2] = datadir;
                }
            }
    #endif
    
            for (i = 0; i < 3 && !f; i++) {
                if (!base[i])
                    continue;
    
                snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i],
    
                         i != 1 ? "" : "/.ffmpeg", preset_name);
    
                f = fopen(filename, "r");
                if (!f && codec_name) {
                    snprintf(filename, filename_size,
    
                             "%s%s/%s-%s.ffpreset",
    
                             base[i],  i != 1 ? "" : "/.ffmpeg", codec_name,
    
                             preset_name);
    
    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: abort(); // never reached, silence warning
    
            }
            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) /* empty specifier, matches everything */
            return 1;
    
        av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
        return AVERROR(EINVAL);
    }
    
    
    AVDictionary *filter_codec_opts(AVDictionary *opts, AVCodec *codec,
    
                                    AVFormatContext *s, AVStream *st)
    
    {
        AVDictionary    *ret = NULL;
        AVDictionaryEntry *t = NULL;
    
        int            flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM
                                          : AV_OPT_FLAG_DECODING_PARAM;
    
        const AVClass    *cc = avcodec_get_class();
    
        case AVMEDIA_TYPE_VIDEO:
            prefix  = 'v';
            flags  |= AV_OPT_FLAG_VIDEO_PARAM;
            break;
        case AVMEDIA_TYPE_AUDIO:
            prefix  = 'a';
            flags  |= AV_OPT_FLAG_AUDIO_PARAM;
            break;
        case AVMEDIA_TYPE_SUBTITLE:
            prefix  = 's';
            flags  |= AV_OPT_FLAG_SUBTITLE_PARAM;
            break;
    
        }
    
        while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
    
            char *p = strchr(t->key, ':');
    
            /* check stream specification in opt name */
            if (p)
                switch (check_stream_specifier(s, st, p + 1)) {
                case  1: *p = 0; break;
                case  0:         continue;
                default:         return NULL;
                }
    
    
            if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
    
                (codec && codec->priv_class &&
                 av_opt_find(&codec->priv_class, t->key, NULL, flags,
                             AV_OPT_SEARCH_FAKE_OBJ)))
    
                av_dict_set(&ret, t->key, t->value, 0);
    
            else if (t->key[0] == prefix &&
                     av_opt_find(&cc, t->key + 1, NULL, flags,
                                 AV_OPT_SEARCH_FAKE_OBJ))
                av_dict_set(&ret, t->key + 1, t->value, 0);
    
    AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
                                               AVDictionary *codec_opts)
    
    {
        int i;
        AVDictionary **opts;
    
        if (!s->nb_streams)
            return NULL;
        opts = av_mallocz(s->nb_streams * sizeof(*opts));
        if (!opts) {
    
            av_log(NULL, AV_LOG_ERROR,
                   "Could not alloc memory for stream options.\n");
    
            return NULL;
        }
        for (i = 0; i < s->nb_streams; i++)
    
            opts[i] = filter_codec_opts(codec_opts, avcodec_find_decoder(s->streams[i]->codec->codec_id),
    
                                        s, s->streams[i]);
    
    void *grow_array(void *array, int elem_size, int *size, int new_size)
    {
        if (new_size >= INT_MAX / elem_size) {
            av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
            exit_program(1);
        }
        if (*size < new_size) {
            uint8_t *tmp = av_realloc(array, new_size*elem_size);
            if (!tmp) {
                av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
                exit_program(1);
            }
            memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
            *size = new_size;
            return tmp;
        }
        return array;
    }