diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/av_common.c | 130 | ||||
-rw-r--r-- | core/av_common.h | 30 | ||||
-rw-r--r-- | core/cfg-mplayer.h | 9 | ||||
-rw-r--r-- | core/codec-cfg.c | 607 | ||||
-rw-r--r-- | core/codec-cfg.h | 79 | ||||
-rw-r--r-- | core/codecs.c | 147 | ||||
-rw-r--r-- | core/codecs.h | 43 | ||||
-rw-r--r-- | core/command.c | 62 | ||||
-rw-r--r-- | core/defaultopts.c | 2 | ||||
-rw-r--r-- | core/m_property.c | 2 | ||||
-rw-r--r-- | core/mp_common.h | 7 | ||||
-rw-r--r-- | core/mpc_info.h | 44 | ||||
-rw-r--r-- | core/mplayer.c | 95 | ||||
-rw-r--r-- | core/options.h | 4 |
14 files changed, 395 insertions, 866 deletions
diff --git a/core/av_common.c b/core/av_common.c new file mode 100644 index 0000000000..55fa5e086b --- /dev/null +++ b/core/av_common.c @@ -0,0 +1,130 @@ +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * mpv is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with mpv. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> + +#include "config.h" +#include "core/mp_talloc.h" +#include "av_common.h" +#include "codecs.h" + + +#if !HAVE_AVCODEC_IS_DECODER_API +static int av_codec_is_decoder(AVCodec *codec) +{ + return !!codec->decode; +} +#endif + +void mp_add_lavc_decoders(struct mp_decoder_list *list, enum AVMediaType type) +{ + AVCodec *cur = NULL; + for (;;) { + cur = av_codec_next(cur); + if (!cur) + break; + if (av_codec_is_decoder(cur) && cur->type == type) { + struct mp_decoder_entry entry = { + .family = "lavc", + .codec = mp_codec_from_av_codec_id(cur->id), + .decoder = cur->name, + .desc = cur->long_name, + }; + assert(entry.family); + MP_TARRAY_APPEND(list, list->entries, list->num_entries, entry); + } + } +} + +#if HAVE_AVCODEC_CODEC_DESC_API + +int mp_codec_to_av_codec_id(const char *codec) +{ + + const AVCodecDescriptor *desc = avcodec_descriptor_get_by_name(codec); + return desc ? desc->id : CODEC_ID_NONE; +} + +const char *mp_codec_from_av_codec_id(int codec_id) +{ + const AVCodecDescriptor *desc = avcodec_descriptor_get(codec_id); + return desc ? desc->name : NULL; +} + +#else + +struct mp_av_codec { + const char *name; + int codec_id; +}; + +// Some decoders have a different name from the canonical codec name, for +// example the codec "dts" CODEC_ID_DTS has the decoder named "dca", and +// avcodec_find_decoder_by_name("dts") would return 0. We always want the +// canonical name. +// On newer lavc versions, avcodec_descriptor_get_by_name("dts") will return +// CODEC_ID_DTS, which is what we want, but for older versions we need this +// lookup table. +struct mp_av_codec mp_av_codec_id_list[] = { + {"ra_144", CODEC_ID_RA_144}, + {"ra_288", CODEC_ID_RA_288}, + {"smackaudio", CODEC_ID_SMACKAUDIO}, + {"dts", CODEC_ID_DTS}, + {"musepack7", CODEC_ID_MUSEPACK7}, + {"musepack8", CODEC_ID_MUSEPACK8}, + {"amr_nb", CODEC_ID_AMR_NB}, + {"amr_wb", CODEC_ID_AMR_WB}, + {"adpcm_g722", CODEC_ID_ADPCM_G722}, + {"adpcm_g726", CODEC_ID_ADPCM_G726}, + {"westwood_snd1", CODEC_ID_WESTWOOD_SND1}, + {"mp4als", CODEC_ID_MP4ALS}, + {"vixl", CODEC_ID_VIXL}, + {"flv1", CODEC_ID_FLV1}, + {"msmpeg4v3", CODEC_ID_MSMPEG4V3}, + {"jpeg2000", CODEC_ID_JPEG2000}, + {"ulti", CODEC_ID_ULTI}, + {"smackvideo", CODEC_ID_SMACKVIDEO}, + {"tscc", CODEC_ID_TSCC}, + {"cscd", CODEC_ID_CSCD}, + {"tgv", CODEC_ID_TGV}, + {"roq", CODEC_ID_ROQ}, + {"idcin", CODEC_ID_IDCIN}, + {"ws_vqa", CODEC_ID_WS_VQA}, + {0}, +}; + +int mp_codec_to_av_codec_id(const char *codec) +{ + for (int n = 0; mp_av_codec_id_list[n].name; n++) { + if (strcmp(mp_av_codec_id_list[n].name, codec) == 0) + return mp_av_codec_id_list[n].codec_id; + } + AVCodec *avcodec = avcodec_find_decoder_by_name(codec); + return avcodec ? avcodec->id : CODEC_ID_NONE; +} + +const char *mp_codec_from_av_codec_id(int codec_id) +{ + for (int n = 0; mp_av_codec_id_list[n].name; n++) { + if (mp_av_codec_id_list[n].codec_id == codec_id) + return mp_av_codec_id_list[n].name; + } + AVCodec *avcodec = avcodec_find_decoder(codec_id); + return avcodec ? avcodec->name : NULL; +} + +#endif diff --git a/core/av_common.h b/core/av_common.h new file mode 100644 index 0000000000..4fbe592f11 --- /dev/null +++ b/core/av_common.h @@ -0,0 +1,30 @@ +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * mpv is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with mpv. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MP_AVCOMMON_H +#define MP_AVCOMMON_H + +#include <libavutil/avutil.h> +#include <libavcodec/avcodec.h> + +struct mp_decoder_list; + +void mp_add_lavc_decoders(struct mp_decoder_list *list, enum AVMediaType type); +int mp_codec_to_av_codec_id(const char *codec); +const char *mp_codec_from_av_codec_id(int codec_id); + +#endif diff --git a/core/cfg-mplayer.h b/core/cfg-mplayer.h index 78d85aa9ed..1c0f269e90 100644 --- a/core/cfg-mplayer.h +++ b/core/cfg-mplayer.h @@ -439,11 +439,9 @@ const m_option_t common_opts[] = { {"af-adv", (void *) audio_filter_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, OPT_SETTINGSLIST("vf*", vf_settings, 0, &vf_obj_list), - // select audio/video codec (by name) or codec family (by number): - {"afm", &audio_fm_list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL}, - {"vfm", &video_fm_list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL}, - {"ac", &audio_codec_list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL}, - {"vc", &video_codec_list, CONF_TYPE_STRING_LIST, 0, 0, 0, NULL}, + + OPT_STRING("ad", audio_decoders, 0), + OPT_STRING("vd", video_decoders, 0), OPT_CHOICE("hwdec", hwdec_api, 0, ({"no", 0}, @@ -473,7 +471,6 @@ const m_option_t common_opts[] = { {"lavdopts", (void *) lavc_decode_opts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, {"lavfdopts", (void *) lavfdopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, - OPT_STRING("codecs-file", codecs_file, 0), // ------------------------- subtitles options -------------------- OPT_STRINGLIST("sub", sub_name, 0), diff --git a/core/codec-cfg.c b/core/codec-cfg.c deleted file mode 100644 index ac875a8a82..0000000000 --- a/core/codec-cfg.c +++ /dev/null @@ -1,607 +0,0 @@ -/* - * codecs.conf parser - * - * Copyright (C) 2001 Szabolcs Berecz <szabi@inf.elte.hu> - * - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <ctype.h> -#include <assert.h> -#include <string.h> -#include <stdint.h> - -#include "config.h" -#include "core/mp_msg.h" -#include "video/img_format.h" -#include "codec-cfg.h" -#include "core/bstr.h" -#include "stream/stream.h" -#include "core/path.h" - -static const char embedded_file[] = -#include "codecs.conf.h" - ; -static const struct bstr builtin_codecs_conf = { - .start = (char *)embedded_file, .len = sizeof(embedded_file) - 1 -}; - -#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \ - ( (uint32_t)(uint8_t)(ch0) | ( (uint32_t)(uint8_t)(ch1) << 8 ) | \ - ( (uint32_t)(uint8_t)(ch2) << 16 ) | ( (uint32_t)(uint8_t)(ch3) << 24 ) ) - -#define PRINT_LINENUM mp_msg(MSGT_CODECCFG,MSGL_ERR," at line %d\n", line_num) - -#define MAX_NR_TOKEN 16 - -#define RET_EOF -1 -#define RET_EOL -2 - -#define TYPE_VIDEO 0 -#define TYPE_AUDIO 1 - -static int add_to_fourcc(char *s, char *alias, unsigned int *fourcc, - unsigned int *map) -{ - int i, j, freeslots; - unsigned int tmp; - - /* find first unused slot */ - for (i = 0; i < CODECS_MAX_FOURCC && fourcc[i] != 0xffffffff; i++) - /* NOTHING */; - freeslots = CODECS_MAX_FOURCC - i; - if (!freeslots) - goto err_out_too_many; - - do { - if (strlen(s) < 4) - goto err_out_parse_error; - tmp = mmioFOURCC(s[0], s[1], s[2], s[3]); - for (j = 0; j < i; j++) - if (tmp == fourcc[j]) - goto err_out_duplicated; - fourcc[i] = tmp; - map[i] = alias ? mmioFOURCC(alias[0], alias[1], alias[2], alias[3]) : tmp; - s += 4; - i++; - } while ((*(s++) == ',') && --freeslots); - - if (!freeslots) - goto err_out_too_many; - if (*(--s) != '\0') - goto err_out_parse_error; - return 1; -err_out_duplicated: - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"duplicated FourCC"); - return 0; -err_out_too_many: - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"too many FourCCs/formats..."); - return 0; -err_out_parse_error: - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"parse error"); - return 0; -} - -static int add_to_format(char *s, char *alias,unsigned int *fourcc, unsigned int *fourccmap) -{ - int i, j; - char *endptr; - - /* find first unused slot */ - for (i = 0; i < CODECS_MAX_FOURCC && fourcc[i] != 0xffffffff; i++) - /* NOTHING */; - if (i == CODECS_MAX_FOURCC) { - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"too many FourCCs/formats..."); - return 0; - } - - fourcc[i]=strtoul(s,&endptr,0); - if (*endptr != '\0') { - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"parse error (format ID not a number?)"); - return 0; - } - - if(alias){ - fourccmap[i]=strtoul(alias,&endptr,0); - if (*endptr != '\0') { - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"parse error (format ID alias not a number?)"); - return 0; - } - } else - fourccmap[i]=fourcc[i]; - - for (j = 0; j < i; j++) - if (fourcc[j] == fourcc[i]) { - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"duplicated format ID"); - return 0; - } - - return 1; -} - -static int validate_codec(codecs_t *c, int type) -{ - unsigned int i; - char *tmp_name = c->name; - - for (i = 0; i < strlen(tmp_name) && isalnum(tmp_name[i]); i++) - /* NOTHING */; - - if (i < strlen(tmp_name)) { - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"\ncodec(%s) name is not valid!\n", c->name); - return 0; - } - - if (!c->info) - c->info = strdup(c->name); - - if (!c->drv) { - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"\ncodec(%s) does not have a driver!\n", c->name); - return 0; - } - - return 1; -} - -static int add_comment(char *s, char **d) -{ - int pos; - - if (!*d) - pos = 0; - else { - pos = strlen(*d); - (*d)[pos++] = '\n'; - } - if (!(*d = realloc(*d, pos + strlen(s) + 1))) { - mp_tmsg(MSGT_CODECCFG,MSGL_FATAL,"Can't allocate memory for comment. "); - return 0; - } - strcpy(*d + pos, s); - return 1; -} - -static struct bstr filetext; -static int line_num = 0; -static char *line; -static char *token[MAX_NR_TOKEN]; -static int read_nextline = 1; - -static int get_token(int min, int max) -{ - static int line_pos; - int i; - char c; - - if (max >= MAX_NR_TOKEN) { - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"get_token(): max >= MAX_MR_TOKEN!"); - goto out_eof; - } - - memset(token, 0x00, sizeof(*token) * max); - - if (read_nextline) { - if (!filetext.len) - goto out_eof; - struct bstr nextline = bstr_getline(filetext, &filetext); - line = nextline.start; - line[nextline.len - 1] = 0; - line_pos = 0; - ++line_num; - read_nextline = 0; - } - for (i = 0; i < max; i++) { - while (isspace(line[line_pos])) - ++line_pos; - if (line[line_pos] == '\0' || line[line_pos] == '#' || - line[line_pos] == ';') { - read_nextline = 1; - if (i >= min) - goto out_ok; - goto out_eol; - } - token[i] = line + line_pos; - c = line[line_pos]; - if (c == '"' || c == '\'') { - token[i]++; - while (line[++line_pos] != c && line[line_pos]) - /* NOTHING */; - } else { - for (/* NOTHING */; !isspace(line[line_pos]) && - line[line_pos]; line_pos++) - /* NOTHING */; - } - if (!line[line_pos]) { - read_nextline = 1; - if (i >= min - 1) - goto out_ok; - goto out_eol; - } - line[line_pos] = '\0'; - line_pos++; - } -out_ok: - return i; -out_eof: - read_nextline = 1; - return RET_EOF; -out_eol: - return RET_EOL; -} - -static codecs_t *video_codecs=NULL; -static codecs_t *audio_codecs=NULL; -static int nr_vcodecs = 0; -static int nr_acodecs = 0; - -int parse_codec_cfg(const char *cfgfile) -{ - codecs_t *codec = NULL; // current codec - codecs_t **codecsp = NULL;// points to audio_codecs or to video_codecs - char *endptr; // strtoul()... - int *nr_codecsp; - int codec_type; /* TYPE_VIDEO/TYPE_AUDIO */ - int tmp, i; - int codec_cfg_min; - - for (struct bstr s = builtin_codecs_conf; ; bstr_getline(s, &s)) { - if (!s.len) - abort(); - if (bstr_eatstart0(&s, "release ")) { - codec_cfg_min = atoi(s.start); - break; - } - } - - // in case we call it a second time - codecs_uninit_free(); - - nr_vcodecs = 0; - nr_acodecs = 0; - - if (cfgfile) { - // Avoid printing errors from open_stream when trying optional files - if (!mp_path_exists(cfgfile)) { - mp_tmsg(MSGT_CODECCFG, MSGL_V, - "No optional codecs config file: %s\n", cfgfile); - return 0; - } - mp_msg(MSGT_CODECCFG, MSGL_V, "Reading codec config file: %s\n", - cfgfile); - struct stream *s = open_stream(cfgfile, NULL, NULL); - if (!s) - return 0; - filetext = stream_read_complete(s, NULL, 10000000, 1); - free_stream(s); - if (!filetext.start) - return 0; - } else - // Parsing modifies the data - filetext = bstrdup(NULL, builtin_codecs_conf); - void *tmpmem = filetext.start; - - read_nextline = 1; - - /* - * this only catches release lines at the start of - * codecs.conf, before audiocodecs and videocodecs. - */ - while ((tmp = get_token(1, 1)) == RET_EOL) - /* NOTHING */; - if (tmp == RET_EOF) - goto out; - if (!strcmp(token[0], "release")) { - if (get_token(1, 2) < 0) - goto err_out_parse_error; - tmp = atoi(token[0]); - if (tmp < codec_cfg_min) - goto err_out_release_num; - while ((tmp = get_token(1, 1)) == RET_EOL) - /* NOTHING */; - if (tmp == RET_EOF) - goto out; - } else - goto err_out_release_num; - - /* - * check if the next block starts with 'audiocodec' or - * with 'videocodec' - */ - if (!strcmp(token[0], "audiocodec") || !strcmp(token[0], "videocodec")) - goto loop_enter; - goto err_out_parse_error; - - while ((tmp = get_token(1, 1)) != RET_EOF) { - if (tmp == RET_EOL) - continue; - if (!strcmp(token[0], "audiocodec") || - !strcmp(token[0], "videocodec")) { - if (!validate_codec(codec, codec_type)) - goto err_out_not_valid; - loop_enter: - if (*token[0] == 'v') { - codec_type = TYPE_VIDEO; - nr_codecsp = &nr_vcodecs; - codecsp = &video_codecs; - } else { - assert(*token[0] == 'a'); - codec_type = TYPE_AUDIO; - nr_codecsp = &nr_acodecs; - codecsp = &audio_codecs; - } - if (!(*codecsp = realloc(*codecsp, - sizeof(codecs_t) * (*nr_codecsp + 2)))) { - mp_tmsg(MSGT_CODECCFG,MSGL_FATAL,"Can't realloc '*codecsp': %s\n", strerror(errno)); - goto err_out; - } - codec=*codecsp + *nr_codecsp; - ++*nr_codecsp; - memset(codec,0,sizeof(codecs_t)); - memset(codec->fourcc, 0xff, sizeof(codec->fourcc)); - - if (get_token(1, 1) < 0) - goto err_out_parse_error; - for (i = 0; i < *nr_codecsp - 1; i++) { - if(( (*codecsp)[i].name!=NULL) && - (!strcmp(token[0], (*codecsp)[i].name)) ) { - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"Codec name '%s' isn't unique.", token[0]); - goto err_out_print_linenum; - } - } - if (!(codec->name = strdup(token[0]))) { - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"Can't strdup -> 'name': %s\n", strerror(errno)); - goto err_out; - } - } else if (!strcmp(token[0], "info")) { - if (codec->info || get_token(1, 1) < 0) - goto err_out_parse_error; - if (!(codec->info = strdup(token[0]))) { - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"Can't strdup -> 'info': %s\n", strerror(errno)); - goto err_out; - } - } else if (!strcmp(token[0], "comment")) { - if (get_token(1, 1) < 0) - goto err_out_parse_error; - add_comment(token[0], &codec->comment); - } else if (!strcmp(token[0], "fourcc")) { - if (get_token(1, 2) < 0) - goto err_out_parse_error; - if (!add_to_fourcc(token[0], token[1], - codec->fourcc, - codec->fourccmap)) - goto err_out_print_linenum; - } else if (!strcmp(token[0], "format")) { - if (get_token(1, 2) < 0) - goto err_out_parse_error; - if (!add_to_format(token[0], token[1], - codec->fourcc,codec->fourccmap)) - goto err_out_print_linenum; - } else if (!strcmp(token[0], "driver")) { - if (get_token(1, 1) < 0) - goto err_out_parse_error; - if (!(codec->drv = strdup(token[0]))) { - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"Can't strdup -> 'driver': %s\n", strerror(errno)); - goto err_out; - } - } else if (!strcmp(token[0], "dll")) { - if (get_token(1, 1) < 0) - goto err_out_parse_error; - if (!(codec->dll = strdup(token[0]))) { - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"Can't strdup -> 'dll': %s", strerror(errno)); - goto err_out; - } - } else if (!strcmp(token[0], "guid")) { - if (get_token(11, 11) < 0) - goto err_out_parse_error; - codec->guid.f1=strtoul(token[0],&endptr,0); - if ((*endptr != ',' || *(endptr + 1) != '\0') && - *endptr != '\0') - goto err_out_parse_error; - codec->guid.f2=strtoul(token[1],&endptr,0); - if ((*endptr != ',' || *(endptr + 1) != '\0') && - *endptr != '\0') - goto err_out_parse_error; - codec->guid.f3=strtoul(token[2],&endptr,0); - if ((*endptr != ',' || *(endptr + 1) != '\0') && - *endptr != '\0') - goto err_out_parse_error; - for (i = 0; i < 8; i++) { - codec->guid.f4[i]=strtoul(token[i + 3],&endptr,0); - if ((*endptr != ',' || *(endptr + 1) != '\0') && - *endptr != '\0') - goto err_out_parse_error; - } - } else if (!strcmp(token[0], "flags")) { - if (get_token(1, 1) < 0) - goto err_out_parse_error; - if (!strcmp(token[0], "flip")) - codec->flags |= CODECS_FLAG_FLIP; - else - goto err_out_parse_error; - } else if (!strcmp(token[0], "status")) { - if (get_token(1, 1) < 0) - goto err_out_parse_error; - if (!strcasecmp(token[0], "working")) - codec->status = CODECS_STATUS_WORKING; - else if (!strcasecmp(token[0], "crashing")) - codec->status = CODECS_STATUS_NOT_WORKING; - else if (!strcasecmp(token[0], "untested")) - codec->status = CODECS_STATUS_UNTESTED; - else if (!strcasecmp(token[0], "buggy")) - codec->status = CODECS_STATUS_PROBLEMS; - else - goto err_out_parse_error; - } else if (!strcmp(token[0], "anyinput")) { - codec->anyinput = true; - } else - goto err_out_parse_error; - } - if (!validate_codec(codec, codec_type)) - goto err_out_not_valid; - mp_tmsg(MSGT_CODECCFG, MSGL_V, "%d audio & %d video codecs\n", nr_acodecs, - nr_vcodecs); - if(video_codecs) video_codecs[nr_vcodecs].name = NULL; - if(audio_codecs) audio_codecs[nr_acodecs].name = NULL; -out: - talloc_free(tmpmem); - line=NULL; - return 1; - -err_out_parse_error: - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"parse error"); -err_out_print_linenum: - PRINT_LINENUM; -err_out: - codecs_uninit_free(); - - talloc_free(tmpmem); - line=NULL; - line_num = 0; - return 0; -err_out_not_valid: - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"Codec is not defined correctly."); - goto err_out_print_linenum; -err_out_release_num: - mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"This codecs.conf is too old and incompatible with this MPlayer release!"); - goto err_out_print_linenum; -} - -static void codecs_free(codecs_t* codecs,int count) { - int i; - for ( i = 0; i < count; i++) - if ( codecs[i].name ) { - free(codecs[i].name); - free(codecs[i].info); - free(codecs[i].comment); - free(codecs[i].dll); - free(codecs[i].drv); - } - free(codecs); -} - -void codecs_uninit_free(void) { - if (video_codecs) - codecs_free(video_codecs,nr_vcodecs); - video_codecs=NULL; - if (audio_codecs) - codecs_free(audio_codecs,nr_acodecs); - audio_codecs=NULL; -} - -codecs_t *find_audio_codec(unsigned int fourcc, unsigned int *fourccmap, - codecs_t *start, int force) -{ - return find_codec(fourcc, fourccmap, start, 1, force); -} - -codecs_t *find_video_codec(unsigned int fourcc, unsigned int *fourccmap, - codecs_t *start, int force) -{ - return find_codec(fourcc, fourccmap, start, 0, force); -} - -struct codecs *find_codec(unsigned int fourcc, unsigned int *fourccmap, - codecs_t *start, int audioflag, int force) -{ - struct codecs *c, *end; - - if (audioflag) { - c = audio_codecs; - end = c + nr_acodecs; - } else { - c = video_codecs; - end = c + nr_vcodecs; - } - if (start) - c = start + 1; // actually starts from the next one after the given one - for (; c < end; c++) { - for (int j = 0; j < CODECS_MAX_FOURCC; j++) { - if (c->fourcc[j] == -1) - break; - if (c->fourcc[j] == fourcc) { - if (fourccmap) - *fourccmap = c->fourccmap[j]; - return c; - } - } - if (c->anyinput || force) - return c; - } - return NULL; -} - -void stringset_init(stringset_t *set) { - *set = calloc(1, sizeof(char *)); -} - -void stringset_free(stringset_t *set) { - int count = 0; - while ((*set)[count]) free((*set)[count++]); - free(*set); - *set = NULL; -} - -void stringset_add(stringset_t *set, const char *str) { - int count = 0; - while ((*set)[count]) count++; - count++; - *set = realloc(*set, sizeof(char *) * (count + 1)); - (*set)[count - 1] = strdup(str); - (*set)[count] = NULL; -} - -int stringset_test(stringset_t *set, const char *str) { - stringset_t s; - for (s = *set; *s; s++) - if (strcmp(*s, str) == 0) - return 1; - return 0; -} - -void list_codecs(int audioflag){ - int i; - codecs_t *c; - - if (audioflag) { - i = nr_acodecs; - c = audio_codecs; - mp_msg(MSGT_CODECCFG,MSGL_INFO,"ac: afm: status: info: [lib/dll]\n"); - } else { - i = nr_vcodecs; - c = video_codecs; - mp_msg(MSGT_CODECCFG,MSGL_INFO,"vc: vfm: status: info: [lib/dll]\n"); - } - if(!i) return; - for (/* NOTHING */; i--; c++) { - char* s="unknown "; - switch(c->status){ - case CODECS_STATUS_WORKING: s="working ";break; - case CODECS_STATUS_PROBLEMS: s="problems";break; - case CODECS_STATUS_NOT_WORKING: s="crashing";break; - case CODECS_STATUS_UNTESTED: s="untested";break; - } - if(c->dll) - mp_msg(MSGT_CODECCFG,MSGL_INFO,"%-11s %-9s %s %s [%s]\n",c->name,c->drv,s,c->info,c->dll); - else - mp_msg(MSGT_CODECCFG,MSGL_INFO,"%-11s %-9s %s %s\n",c->name,c->drv,s,c->info); - } -} diff --git a/core/codec-cfg.h b/core/codec-cfg.h deleted file mode 100644 index 01af497c3d..0000000000 --- a/core/codec-cfg.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_CODEC_CFG_H -#define MPLAYER_CODEC_CFG_H - -#include <stdbool.h> - -#define CODECS_MAX_FOURCC 92 - -// Global flags: -#define CODECS_FLAG_FLIP (1<<0) - -#define CODECS_STATUS__MIN 0 -#define CODECS_STATUS_NOT_WORKING -1 -#define CODECS_STATUS_PROBLEMS 0 -#define CODECS_STATUS_WORKING 1 -#define CODECS_STATUS_UNTESTED 2 -#define CODECS_STATUS__MAX 2 - - -#if !defined(GUID_TYPE) && !defined(GUID_DEFINED) -#define GUID_TYPE 1 -#define GUID_DEFINED 1 -typedef struct { - unsigned long f1; - unsigned short f2; - unsigned short f3; - unsigned char f4[8]; -} GUID; -#endif - - -typedef struct codecs { - unsigned int fourcc[CODECS_MAX_FOURCC]; - unsigned int fourccmap[CODECS_MAX_FOURCC]; - char *name; - char *info; - char *comment; - char *dll; - char* drv; - GUID guid; - short flags; - short status; - bool anyinput; -} codecs_t; - -int parse_codec_cfg(const char *cfgfile); -codecs_t* find_video_codec(unsigned int fourcc, unsigned int *fourccmap, - codecs_t *start, int force); -codecs_t* find_audio_codec(unsigned int fourcc, unsigned int *fourccmap, - codecs_t *start, int force); -codecs_t* find_codec(unsigned int fourcc, unsigned int *fourccmap, - codecs_t *start, int audioflag, int force); -void list_codecs(int audioflag); -void codecs_uninit_free(void); - -typedef char ** stringset_t; -void stringset_init(stringset_t *set); -void stringset_free(stringset_t *set); -void stringset_add(stringset_t *set, const char *str); -int stringset_test(stringset_t *set, const char *str); - -#endif /* MPLAYER_CODEC_CFG_H */ diff --git a/core/codecs.c b/core/codecs.c new file mode 100644 index 0000000000..943860a70b --- /dev/null +++ b/core/codecs.c @@ -0,0 +1,147 @@ +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * mpv is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with mpv. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include "core/mp_talloc.h" +#include "core/bstr.h" +#include "core/mp_msg.h" +#include "codecs.h" + +void mp_add_decoder(struct mp_decoder_list *list, const char *family, + const char *codec, const char *decoder, const char *desc) +{ + struct mp_decoder_entry entry = { + .family = talloc_strdup(list, family), + .codec = talloc_strdup(list, codec), + .decoder = talloc_strdup(list, decoder), + .desc = talloc_strdup(list, desc), + }; + MP_TARRAY_APPEND(list, list->entries, list->num_entries, entry); +} + +static void mp_add_decoder_entry(struct mp_decoder_list *list, + struct mp_decoder_entry *entry) +{ + mp_add_decoder(list, entry->family, entry->codec, entry->decoder, + entry->desc); +} + +static struct mp_decoder_entry *find_decoder(struct mp_decoder_list *list, + bstr family, bstr decoder) +{ + for (int n = 0; n < list->num_entries; n++) { + struct mp_decoder_entry *cur = &list->entries[n]; + if (bstr_equals0(decoder, cur->decoder) && + bstr_equals0(family, cur->family)) + return cur; + } + return NULL; +} + +// Add entry, but only if it's not yet on the list, and if the codec matches. +// If codec == NULL, don't compare codecs. +static void add_new(struct mp_decoder_list *to, struct mp_decoder_entry *entry, + const char *codec) +{ + if (!entry || (codec && strcmp(entry->codec, codec) != 0)) + retur |