msvideopresets.c 4.95 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2015  Belledonne Communications SARL

This program 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.

This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#ifdef HAVE_CONFIG_H
#include "mediastreamer-config.h"
#endif

#include "mediastreamer2/msvideopresets.h"


27
struct _MSVideoPresetConfiguration {
28 29
	MSList *tags;
	MSVideoConfiguration *config;
30
};
31 32 33 34 35 36

typedef struct _MSVideoPreset {
	char *name;
	MSList *configs; /**< List of MSVideoPresetConfiguration objects */
} MSVideoPreset;

37
struct _MSVideoPresetsManager {
38
	MSFactory *factory;
39
	MSList *presets; /**< List of MSVideoPreset objects */
40 41 42
};


43 44
static void free_preset_config(MSVideoPresetConfiguration *vpc) {
	ms_list_for_each(vpc->tags, ms_free);
45 46
	ms_list_free(vpc->tags);
	ms_free(vpc);
47 48 49 50 51
}

static void free_preset(MSVideoPreset *vp) {
	ms_free(vp->name);
	ms_list_for_each(vp->configs, (MSIterateFunc)free_preset_config);
52 53
	ms_list_free(vp->configs);
	ms_free(vp);
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
}

static MSVideoPreset * add_video_preset(MSVideoPresetsManager *manager, const char *name) {
	MSVideoPreset *vp = ms_new0(MSVideoPreset, 1);
	vp->name = ms_strdup(name);
	manager->presets = ms_list_append(manager->presets, vp);
	return vp;
}

static MSVideoPreset * find_video_preset(MSVideoPresetsManager *manager, const char *name) {
	MSList *elem = manager->presets;
	while (elem != NULL) {
		MSVideoPreset *vp = (MSVideoPreset *)elem->data;
		if (strcmp(name, vp->name) == 0) {
			return vp;
		}
Ghislain MARY's avatar
Ghislain MARY committed
70
		elem = elem->next;
71 72 73 74 75 76
	}
	return NULL;
}

static MSList * parse_tags(const char *tags) {
	MSList *tags_list = NULL;
Ghislain MARY's avatar
Ghislain MARY committed
77 78
	char *t;
	char *p;
Ghislain MARY's avatar
Ghislain MARY committed
79
	if ((tags == NULL) || (tags[0] == '\0')) return NULL;
Ghislain MARY's avatar
Ghislain MARY committed
80
	p = t = ms_strdup(tags);
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
	while (p != NULL) {
		char *next = strstr(p, ",");
		if (next != NULL) {
			*(next++) = '\0';
		}
		tags_list = ms_list_append(tags_list, ms_strdup(p));
		p = next;
	}
	ms_free(t);
	return tags_list;
}

static void add_video_preset_configuration(MSVideoPreset *preset, const char *tags, MSVideoConfiguration *config) {
	MSVideoPresetConfiguration *vpc = ms_new0(MSVideoPresetConfiguration, 1);
	vpc->tags = parse_tags(tags);
	vpc->config = config;
	preset->configs = ms_list_append(preset->configs, vpc);
}

100 101 102 103 104
static int video_preset_configuration_match(MSVideoPresetConfiguration *vpc, MSList *platform_tags, MSList *codec_tags) {
	MSList *elem = vpc->tags;
	int nb = 0;
	while (elem != NULL) {
		char *tag = (char *)elem->data;
105
		if (!ms_tags_list_contains_tag(platform_tags, tag) && !ms_tags_list_contains_tag(codec_tags, tag))
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
			return 0;
		nb++;
		elem = elem->next;
	}
	return nb;
}

void ms_video_presets_manager_destroy(MSVideoPresetsManager *manager) {
	if (manager != NULL) {
		ms_list_for_each(manager->presets, (MSIterateFunc)free_preset);
		ms_list_free(manager->presets);
		ms_free(manager);
	}
}

MSVideoPresetsManager * ms_video_presets_manager_new(MSFactory *factory) {
	MSVideoPresetsManager *manager = (MSVideoPresetsManager *)ms_new0(MSVideoPresetsManager, 1);
	manager->factory = factory;
	if (factory->video_presets_manager != NULL) {
		ms_video_presets_manager_destroy(factory->video_presets_manager);
	}
	factory->video_presets_manager = manager;
	return manager;
129 130 131 132
}

void ms_video_presets_manager_register_preset_configuration(MSVideoPresetsManager *manager,
	const char *name, const char *tags, MSVideoConfiguration *config) {
133 134 135 136 137
	MSVideoPreset *preset = find_video_preset(manager, name);
	if (preset == NULL) {
		preset = add_video_preset(manager, name);
	}
	add_video_preset_configuration(preset, tags, config);
138
}
139 140 141 142 143 144

MSVideoPresetConfiguration * ms_video_presets_manager_find_preset_configuration(MSVideoPresetsManager *manager,
	const char *name, MSList *codec_tags) {
	MSList *elem = NULL;
	MSVideoPreset *preset = find_video_preset(manager, name);
	MSVideoPresetConfiguration *best_vpc = NULL;
145
	int best_nb = -1;
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166

	if (preset == NULL) return NULL;
	elem = preset->configs;
	while (elem != NULL) {
		MSVideoPresetConfiguration *vpc = (MSVideoPresetConfiguration *)elem->data;
		int nb = video_preset_configuration_match(vpc, ms_factory_get_platform_tags(manager->factory), codec_tags);
		if (nb > best_nb) {
			best_vpc = vpc;
		}
		elem = elem->next;
	}
	return best_vpc;
}

MSVideoConfiguration * ms_video_preset_configuration_get_video_configuration(MSVideoPresetConfiguration *vpc) {
	return vpc->config;
}

char * ms_video_preset_configuration_get_tags_as_string(MSVideoPresetConfiguration *vpc) {
	return ms_tags_list_as_string(vpc->tags);
}