コード例 #1
0
ファイル: configfiles.c プロジェクト: LiminWang/mpv
void mp_parse_cfgfiles(struct MPContext *mpctx)
{
    struct MPOpts *opts = mpctx->opts;
    if (!opts->load_config)
        return;

    mp_mk_config_dir(mpctx->global, "");

    m_config_t *conf = mpctx->mconfig;
    char *section = NULL;
    bool encoding = opts->encode_opts &&
        opts->encode_opts->file && opts->encode_opts->file[0];
    // In encoding mode, we don't want to apply normal config options.
    // So we "divert" normal options into a separate section, and the diverted
    // section is never used - unless maybe it's explicitly referenced from an
    // encoding profile.
    if (encoding)
        section = "playback-default";

    // The #if is a stupid hack to avoid errors if libavfilter is not available.
#if HAVE_LIBAVFILTER && HAVE_ENCODING
    char *cf = mp_find_config_file(NULL, mpctx->global, "encoding-profiles.conf");
    if (cf)
        m_config_parse_config_file(mpctx->mconfig, cf, SECT_ENCODE, 0);
    talloc_free(cf);
#endif

    load_all_cfgfiles(mpctx, section, "config");
    load_all_cfgfiles(mpctx, section, "mpv.conf");

    if (encoding)
        m_config_set_profile(conf, m_config_add_profile(conf, SECT_ENCODE), 0);
}
コード例 #2
0
ファイル: ass_mp.c プロジェクト: Bluelich/mpv
void mp_ass_configure_fonts(ASS_Renderer *priv, struct osd_style_opts *opts,
                            struct mpv_global *global, struct mp_log *log)
{
    void *tmp = talloc_new(NULL);
    char *default_font = mp_find_config_file(tmp, global, "subfont.ttf");
    char *config       = mp_find_config_file(tmp, global, "fonts.conf");

    if (default_font && !mp_path_exists(default_font))
        default_font = NULL;

    mp_verbose(log, "Setting up fonts...\n");
    ass_set_fonts(priv, default_font, opts->font, 1, config, 1);
    mp_verbose(log, "Done.\n");

    talloc_free(tmp);
}
コード例 #3
0
ファイル: configfiles.c プロジェクト: LiminWang/mpv
static void mp_load_per_file_config(struct MPContext *mpctx)
{
    struct MPOpts *opts = mpctx->opts;
    char *confpath;
    char cfg[512];
    const char *file = mpctx->filename;

    if (snprintf(cfg, sizeof(cfg), "%s.conf", file) >= sizeof(cfg)) {
        MP_VERBOSE(mpctx, "Filename is too long, "
                   "can not load file or directory specific config files\n");
        return;
    }

    char *name = mp_basename(cfg);

    if (opts->use_filedir_conf) {
        bstr dir = mp_dirname(cfg);
        char *dircfg = mp_path_join(NULL, dir, bstr0("mpv.conf"));
        try_load_config(mpctx, dircfg, FILE_LOCAL_FLAGS);
        talloc_free(dircfg);

        if (try_load_config(mpctx, cfg, FILE_LOCAL_FLAGS))
            return;
    }

    if ((confpath = mp_find_config_file(NULL, mpctx->global, name))) {
        try_load_config(mpctx, confpath, FILE_LOCAL_FLAGS);

        talloc_free(confpath);
    }
}
コード例 #4
0
ファイル: configfiles.c プロジェクト: kleopatra999/mpv
bool mp_parse_cfgfiles(struct MPContext *mpctx)
{
    struct MPOpts *opts = mpctx->opts;
    if (!opts->load_config)
        return true;

    m_config_t *conf = mpctx->mconfig;
    void *tmp = talloc_new(NULL);
    bool r = true;
    char *conffile;

    // The #if is a stupid hack to avoid errors if libavfilter is not available.
#if HAVE_VF_LAVFI && HAVE_ENCODING
    conffile = mp_find_config_file(tmp, mpctx->global, "encoding-profiles.conf");
    if (conffile && mp_path_exists(conffile))
        m_config_parse_config_file(mpctx->mconfig, conffile, 0);
#endif

    conffile = mp_find_global_config_file(tmp, mpctx->global, "mpv.conf");
    if (conffile && m_config_parse_config_file(conf, conffile, 0) < 0) {
        r = false;
        goto done;
    }
    mp_mk_config_dir(mpctx->global, NULL);
    if (!(conffile = mp_find_user_config_file(tmp, mpctx->global, "config")))
        MP_ERR(mpctx, "mp_find_user_config_file(\"config\") problem\n");
    else if (m_config_parse_config_file(conf, conffile, 0) < 0) {
        r = false;
        goto done;
    }

done:
    talloc_free(tmp);
    return r;
}
コード例 #5
0
ファイル: configfiles.c プロジェクト: FyhSky/bomi
static char *mp_get_playback_resume_config_filename(struct mpv_global *global,
                                                    const char *fname)
{
    struct MPOpts *opts = global->opts;
    char *res = NULL;
    void *tmp = talloc_new(NULL);
    const char *realpath = fname;
    bstr bfname = bstr0(fname);
    if (!mp_is_url(bfname)) {
        if (opts->ignore_path_in_watch_later_config) {
            realpath = mp_basename(fname);
        } else {
            char *cwd = mp_getcwd(tmp);
            if (!cwd)
                goto exit;
            realpath = mp_path_join(tmp, bstr0(cwd), bstr0(fname));
        }
    }
    if (bstr_startswith0(bfname, "dvd://"))
        realpath = talloc_asprintf(tmp, "%s - %s", realpath, opts->dvd_device);
    if (bstr_startswith0(bfname, "br://") || bstr_startswith0(bfname, "bd://") ||
        bstr_startswith0(bfname, "bluray://"))
        realpath = talloc_asprintf(tmp, "%s - %s", realpath, opts->bluray_device);
    uint8_t md5[16];
    av_md5_sum(md5, realpath, strlen(realpath));
    char *conf = talloc_strdup(tmp, "");
    for (int i = 0; i < 16; i++)
        conf = talloc_asprintf_append(conf, "%02X", md5[i]);

    res = talloc_asprintf(tmp, MP_WATCH_LATER_CONF "/%s", conf);
    res = mp_find_config_file(NULL, global, res);

    if (!res) {
        res = mp_find_config_file(tmp, global, MP_WATCH_LATER_CONF);
        if (res)
            res = talloc_asprintf(NULL, "%s/%s", res, conf);
    }

exit:
    talloc_free(tmp);
    return res;
}
コード例 #6
0
ファイル: ass_mp.c プロジェクト: kax4/mpv
void mp_ass_configure_fonts(ASS_Renderer *priv, struct osd_style_opts *opts)
{
    char *default_font = mp_find_user_config_file("subfont.ttf");
    char *config       = mp_find_config_file("fonts.conf");

    if (!mp_path_exists(default_font)) {
        talloc_free(default_font);
        default_font = NULL;
    }

    ass_set_fonts(priv, default_font, opts->font, 1, config, 1);

    talloc_free(default_font);
    talloc_free(config);
}
コード例 #7
0
ファイル: configfiles.c プロジェクト: asdlei00/mpv
bool mp_parse_cfgfiles(struct MPContext *mpctx)
{
    struct MPOpts *opts = mpctx->opts;
    if (!opts->load_config)
        return true;

    m_config_t *conf = mpctx->mconfig;
    void *tmp = talloc_new(NULL);
    bool r = true;
    char *conffile;
    char *section = NULL;
    bool encoding = opts->encode_output.file && *opts->encode_output.file;
    // In encoding mode, we don't want to apply normal config options.
    // So we "divert" normal options into a separate section, and the diverted
    // section is never used - unless maybe it's explicitly referenced from an
    // encoding profile.
    if (encoding)
        section = "playback-default";

    // The #if is a stupid hack to avoid errors if libavfilter is not available.
#if HAVE_LIBAVFILTER && HAVE_ENCODING
    conffile = mp_find_config_file(tmp, mpctx->global, "encoding-profiles.conf");
    if (conffile && mp_path_exists(conffile))
        m_config_parse_config_file(mpctx->mconfig, conffile, SECT_ENCODE, 0);
#endif

    conffile = mp_find_global_config_file(tmp, mpctx->global, "mpv.conf");
    if (conffile && m_config_parse_config_file(conf, conffile, section, 0) < 0) {
        r = false;
        goto done;
    }
    mp_mk_config_dir(mpctx->global, NULL);
    if (!(conffile = mp_find_user_config_file(tmp, mpctx->global, "config")))
        MP_ERR(mpctx, "mp_find_user_config_file(\"config\") problem\n");
    else if (m_config_parse_config_file(conf, conffile, section, 0) < 0) {
        r = false;
        goto done;
    }

    if (encoding)
        m_config_set_profile(conf, m_config_add_profile(conf, SECT_ENCODE), 0);

done:
    talloc_free(tmp);
    return r;
}
コード例 #8
0
void mp_ass_configure_fonts(ASS_Renderer *priv, struct osd_style_opts *opts)
{
    char *default_font = mp_find_user_config_file("subfont.ttf");
    char *config       = mp_find_config_file("fonts.conf");

    if (default_font && !mp_path_exists(default_font)) {
        talloc_free(default_font);
        default_font = NULL;
    }

    mp_msg(MSGT_ASS, MSGL_V, "[ass] Setting up fonts...\n");
    ass_set_fonts(priv, default_font, opts->font, 1, config, 1);
    mp_msg(MSGT_ASS, MSGL_V, "[ass] Done.\n");

    talloc_free(default_font);
    talloc_free(config);
}
コード例 #9
0
ファイル: find_subfiles.c プロジェクト: AoD314/mpv
static struct bstr strip_ext(struct bstr str)
{
    int dotpos = bstrrchr(str, '.');
    if (dotpos < 0)
        return str;
    return (struct bstr){str.start, dotpos};
}

static struct bstr get_ext(struct bstr s)
{
    int dotpos = bstrrchr(s, '.');
    if (dotpos < 0)
        return (struct bstr){NULL, 0};
    return bstr_splice(s, dotpos + 1, s.len);
}

bool mp_might_be_subtitle_file(const char *filename)
{
    return test_ext(get_ext(bstr0(filename))) == STREAM_SUB;
}

static int compare_sub_filename(const void *a, const void *b)
{
    const struct subfn *s1 = a;
    const struct subfn *s2 = b;
    return strcoll(s1->fname, s2->fname);
}

static int compare_sub_priority(const void *a, const void *b)
{
    const struct subfn *s1 = a;
    const struct subfn *s2 = b;
    if (s1->priority > s2->priority)
        return -1;
    if (s1->priority < s2->priority)
        return 1;
    return strcoll(s1->fname, s2->fname);
}

static struct bstr guess_lang_from_filename(struct bstr name)
{
    if (name.len < 2)
        return (struct bstr){NULL, 0};

    int n = 0;
    int i = name.len - 1;

    if (name.start[i] == ')' || name.start[i] == ']')
        i--;
    while (i >= 0 && mp_isalpha(name.start[i])) {
        n++;
        if (n > 3)
            return (struct bstr){NULL, 0};
        i--;
    }
    if (n < 2)
        return (struct bstr){NULL, 0};
    return (struct bstr){name.start + i + 1, n};
}

static void append_dir_subtitles(struct mpv_global *global,
                                 struct subfn **slist, int *nsub,
                                 struct bstr path, const char *fname,
                                 int limit_fuzziness)
{
    void *tmpmem = talloc_new(NULL);
    struct MPOpts *opts = global->opts;
    struct mp_log *log = mp_log_new(tmpmem, global->log, "find_files");

    if (mp_is_url(bstr0(fname)))
        goto out;

    struct bstr f_fname = bstr0(mp_basename(fname));
    struct bstr f_fname_noext = bstrdup(tmpmem, strip_ext(f_fname));
    bstr_lower(f_fname_noext);
    struct bstr f_fname_trim = bstr_strip(f_fname_noext);

    // 0 = nothing
    // 1 = any subtitle file
    // 2 = any sub file containing movie name
    // 3 = sub file containing movie name and the lang extension
    char *path0 = bstrdup0(tmpmem, path);
    DIR *d = opendir(path0);
    if (!d)
        goto out;
    mp_verbose(log, "Loading external files in %.*s\n", BSTR_P(path));
    struct dirent *de;
    while ((de = readdir(d))) {
        struct bstr dename = bstr0(de->d_name);
        void *tmpmem2 = talloc_new(tmpmem);

        // retrieve various parts of the filename
        struct bstr tmp_fname_noext = bstrdup(tmpmem2, strip_ext(dename));
        bstr_lower(tmp_fname_noext);
        struct bstr tmp_fname_ext = get_ext(dename);
        struct bstr tmp_fname_trim = bstr_strip(tmp_fname_noext);

        // check what it is (most likely)
        int type = test_ext(tmp_fname_ext);
        char **langs = NULL;
        int fuzz = -1;
        switch (type) {
        case STREAM_SUB:
            langs = opts->sub_lang;
            fuzz = opts->sub_auto;
            break;
        case STREAM_AUDIO:
            langs = opts->audio_lang;
            fuzz = opts->audiofile_auto;
            break;
        }

        if (fuzz < 0)
            goto next_sub;

        // we have a (likely) subtitle file
        int prio = 0;
        char *found_lang = NULL;
        if (langs) {
            if (bstr_startswith(tmp_fname_trim, f_fname_trim)) {
                struct bstr lang = guess_lang_from_filename(tmp_fname_trim);
                if (lang.len) {
                    for (int n = 0; langs[n]; n++) {
                        if (bstr_startswith0(lang, langs[n])) {
                            prio = 4; // matches the movie name + lang extension
                            found_lang = langs[n];
                            break;
                        }
                    }
                }
            }
        }
        if (!prio && bstrcmp(tmp_fname_trim, f_fname_trim) == 0)
            prio = 3; // matches the movie name
        if (!prio && bstr_find(tmp_fname_trim, f_fname_trim) >= 0 && fuzz >= 1)
            prio = 2; // contains the movie name
        if (!prio) {
            // doesn't contain the movie name
            // don't try in the mplayer subtitle directory
            if (!limit_fuzziness && fuzz >= 2) {
                prio = 1;
            }
        }

        mp_dbg(log, "Potential external file: \"%s\"  Priority: %d\n",
               de->d_name, prio);

        if (prio) {
            prio += prio;
            char *subpath = mp_path_join(*slist, path, dename);
            if (mp_path_exists(subpath)) {
                MP_GROW_ARRAY(*slist, *nsub);
                struct subfn *sub = *slist + (*nsub)++;

                // annoying and redundant
                if (strncmp(subpath, "./", 2) == 0)
                    subpath += 2;

                sub->type     = type;
                sub->priority = prio;
                sub->fname    = subpath;
                sub->lang     = found_lang;
            } else
                talloc_free(subpath);
        }

    next_sub:
        talloc_free(tmpmem2);
    }
    closedir(d);

 out:
    talloc_free(tmpmem);
}

static bool case_endswith(const char *s, const char *end)
{
    size_t len = strlen(s);
    size_t elen = strlen(end);
    return len >= elen && strcasecmp(s + len - elen, end) == 0;
}

// Drop .sub file if .idx file exists.
// Assumes slist is sorted by compare_sub_filename.
static void filter_subidx(struct subfn **slist, int *nsub)
{
    const char *prev = NULL;
    for (int n = 0; n < *nsub; n++) {
        const char *fname = (*slist)[n].fname;
        if (case_endswith(fname, ".idx")) {
            prev = fname;
        } else if (case_endswith(fname, ".sub")) {
            if (prev && strncmp(prev, fname, strlen(fname) - 4) == 0)
                (*slist)[n].priority = -1;
        }
    }
    for (int n = *nsub - 1; n >= 0; n--) {
        if ((*slist)[n].priority < 0)
            MP_TARRAY_REMOVE_AT(*slist, *nsub, n);
    }
}

// Return a list of subtitles and audio files found, sorted by priority.
// Last element is terminated with a fname==NULL entry.
struct subfn *find_external_files(struct mpv_global *global, const char *fname)
{
    struct MPOpts *opts = global->opts;
    struct subfn *slist = talloc_array_ptrtype(NULL, slist, 1);
    int n = 0;

    // Load subtitles from current media directory
    append_dir_subtitles(global, &slist, &n, mp_dirname(fname), fname, 0);

    if (opts->sub_auto >= 0) {
        // Load subtitles in dirs specified by sub-paths option
        if (opts->sub_paths) {
            for (int i = 0; opts->sub_paths[i]; i++) {
                char *path = mp_path_join(slist, mp_dirname(fname),
                                        bstr0(opts->sub_paths[i]));
                append_dir_subtitles(global, &slist, &n, bstr0(path), fname, 0);
            }
        }

        // Load subtitles in ~/.mpv/sub limiting sub fuzziness
        char *mp_subdir = mp_find_config_file(NULL, global, "sub/");
        if (mp_subdir)
            append_dir_subtitles(global, &slist, &n, bstr0(mp_subdir), fname, 1);
        talloc_free(mp_subdir);
    }

    // Sort by name for filter_subidx()
    qsort(slist, n, sizeof(*slist), compare_sub_filename);

    filter_subidx(&slist, &n);

    // Sort subs by priority and append them
    qsort(slist, n, sizeof(*slist), compare_sub_priority);

    struct subfn z = {0};
    MP_TARRAY_APPEND(NULL, slist, n, z);

    return slist;
}
コード例 #10
0
ファイル: stream_dvb.c プロジェクト: Deadsign/mpv
dvb_config_t *dvb_get_config(stream_t *stream)
{
        struct mp_log *log = stream->log;
        struct mpv_global *global = stream->global;
        int i, fd, type, size;
        char filename[30], *conf_file, *name;
        dvb_channels_list *list;
        dvb_card_config_t *cards = NULL, *tmp;
        dvb_config_t *conf = NULL;


        conf = malloc(sizeof(dvb_config_t));
        if(conf == NULL)
                return NULL;

        conf->priv = NULL;
        conf->count = 0;
        conf->cards = NULL;
        for(i=0; i<MAX_CARDS; i++)
        {
                snprintf(filename, sizeof(filename), "/dev/dvb/adapter%d/frontend0", i);
                fd = open(filename, O_RDONLY|O_NONBLOCK|O_CLOEXEC);
                if(fd < 0)
                {
                        mp_verbose(log, "DVB_CONFIG, can't open device %s, skipping\n", filename);
                        continue;
                }

                type = dvb_get_tuner_type(fd, log);
                close(fd);
                if(type != TUNER_SAT && type != TUNER_TER && type != TUNER_CBL && type != TUNER_ATSC)
                {
                        mp_verbose(log, "DVB_CONFIG, can't detect tuner type of card %d, skipping\n", i);
                        continue;
                }

        void *talloc_ctx = talloc_new(NULL);
        conf_file = mp_find_config_file(talloc_ctx, global, "channels.conf");
        switch(type) {
            case TUNER_TER:
                conf_file = mp_find_config_file(talloc_ctx, global, "channels.conf.ter");
                break;
            case TUNER_CBL:
                conf_file = mp_find_config_file(talloc_ctx, global, "channels.conf.cbl");
                break;
            case TUNER_SAT:
                conf_file = mp_find_config_file(talloc_ctx, global, "channels.conf.sat");
                break;
            case TUNER_ATSC:
                conf_file = mp_find_config_file(talloc_ctx, global, "channels.conf.atsc");
                break;
        }

        if(conf_file && (access(conf_file, F_OK | R_OK) != 0))
            conf_file = mp_find_config_file(talloc_ctx, global, "channels.conf");

        list = dvb_get_channels(log, conf_file, type);
        talloc_free(talloc_ctx);

                if(list == NULL)
                        continue;

                size = sizeof(dvb_card_config_t) * (conf->count + 1);
                tmp = realloc(conf->cards, size);

                if(tmp == NULL)
                {
                        fprintf(stderr, "DVB_CONFIG, can't realloc %d bytes, skipping\n", size);
                        continue;
                }
                cards = tmp;

                name = malloc(20);
                if(name==NULL)
                {
                        fprintf(stderr, "DVB_CONFIG, can't realloc 20 bytes, skipping\n");
                        continue;
                }

                conf->cards = cards;
                conf->cards[conf->count].devno = i;
                conf->cards[conf->count].list = list;
                conf->cards[conf->count].type = type;
                snprintf(name, 20, "DVB-%c card n. %d", type==TUNER_TER ? 'T' : (type==TUNER_CBL ? 'C' : 'S'), conf->count+1);
                conf->cards[conf->count].name = name;
                conf->count++;
        }

        if(conf->count == 0)
        {
                free(conf);
                conf = NULL;
        }

        return conf;
}
コード例 #11
0
ファイル: stream_dvb.c プロジェクト: AddictXQ/mpv
dvb_state_t *dvb_get_state(stream_t *stream)
{
    if (global_dvb_state != NULL) {
      return global_dvb_state;
    }
    struct mp_log *log = stream->log;
    struct mpv_global *global = stream->global;
    dvb_priv_t *priv = stream->priv;
    int type, size;
    char filename[30], *name;
    dvb_channels_list *list;
    dvb_card_config_t *cards = NULL, *tmp;
    dvb_state_t *state = NULL;

    state = malloc(sizeof(dvb_state_t));
    if (state == NULL)
        return NULL;

    state->count = 0;
    state->switching_channel = false;
    state->stream_used = true;
    state->cards = NULL;
    state->fe_fd = state->dvr_fd = -1;
    for (int i = 0; i < MAX_CARDS; i++) {
        snprintf(filename, sizeof(filename), "/dev/dvb/adapter%d/frontend0", i);
        int fd = open(filename, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
        if (fd < 0) {
            mp_verbose(log, "DVB_CONFIG, can't open device %s, skipping\n",
                       filename);
            continue;
        }

        mp_verbose(log, "Opened device %s, FD: %d\n", filename, fd);
        int* tuner_types = NULL;
        int num_tuner_types = dvb_get_tuner_types(fd, log, &tuner_types);
        close(fd);
        mp_verbose(log, "Frontend device %s offers %d supported delivery systems.\n",
                   filename, num_tuner_types);
        for (int num_tuner_type=0; num_tuner_type<num_tuner_types; num_tuner_type++) {
          type = tuner_types[num_tuner_type];
          if (type != TUNER_SAT && type != TUNER_TER && type != TUNER_CBL &&
              type != TUNER_ATSC) {
            mp_verbose(log, "DVB_CONFIG, can't detect tuner type of "
                       "card %d, skipping\n", i);
            continue;
          }

          void *talloc_ctx = talloc_new(NULL);
          char *conf_file = NULL;
          if (priv->cfg_file && priv->cfg_file[0])
            conf_file = priv->cfg_file;
          else {
            switch (type) {
            case TUNER_TER:
              conf_file = mp_find_config_file(talloc_ctx, global,
                                              "channels.conf.ter");
              break;
            case TUNER_CBL:
              conf_file = mp_find_config_file(talloc_ctx, global,
                                              "channels.conf.cbl");
              break;
            case TUNER_SAT:
              conf_file = mp_find_config_file(talloc_ctx, global,
                                              "channels.conf.sat");
              break;
            case TUNER_ATSC:
              conf_file = mp_find_config_file(talloc_ctx, global,
                                              "channels.conf.atsc");
              break;
            }
            if (conf_file) {
              mp_verbose(log, "Ignoring other channels.conf files.\n");
            } else {
              conf_file = mp_find_config_file(talloc_ctx, global,
                                              "channels.conf");
            }
          }

          list = dvb_get_channels(log, priv->cfg_full_transponder, conf_file,
                                  type);
          talloc_free(talloc_ctx);

          if (list == NULL)
            continue;

          size = sizeof(dvb_card_config_t) * (state->count + 1);
          tmp = realloc(state->cards, size);

          if (tmp == NULL) {
            mp_err(log, "DVB_CONFIG, can't realloc %d bytes, skipping\n",
                   size);
            free(list);
            continue;
          }
          cards = tmp;

          name = malloc(20);
          if (name == NULL) {
            mp_err(log, "DVB_CONFIG, can't realloc 20 bytes, skipping\n");
            free(list);
            free(tmp);
            continue;
          }

          state->cards = cards;
          state->cards[state->count].devno = i;
          state->cards[state->count].list = list;
          state->cards[state->count].type = type;
          snprintf(name, 20, "DVB-%c card n. %d",
                   type == TUNER_TER ? 'T' : (type == TUNER_CBL ? 'C' : 'S'),
                   state->count + 1);
          state->cards[state->count].name = name;
          state->count++;
        }
        talloc_free(tuner_types);
    }

    if (state->count == 0) {
        free(state);
        state = NULL;
    }

    global_dvb_state = state;
    return state;
}