obs-encoder.c 4.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/******************************************************************************
    Copyright (C) 2013 by Hugh Bailey <obs.jim@gmail.com>

    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, see <http://www.gnu.org/licenses/>.
******************************************************************************/

#include "obs.h"
J
jp9000 已提交
19
#include "obs-internal.h"
20 21

bool load_encoder_info(void *module, const char *module_name,
22
		const char *id, struct encoder_info *info)
23
{
24 25 26 27 28 29 30 31
	LOAD_MODULE_SUBFUNC(getname, true);
	LOAD_MODULE_SUBFUNC(create, true);
	LOAD_MODULE_SUBFUNC(destroy, true);
	LOAD_MODULE_SUBFUNC(update, true);
	LOAD_MODULE_SUBFUNC(reset, true);
	LOAD_MODULE_SUBFUNC(encode, true);
	LOAD_MODULE_SUBFUNC(getheader, true);

J
jp9000 已提交
32
	LOAD_MODULE_SUBFUNC(properties, false);
33 34 35 36
	LOAD_MODULE_SUBFUNC(setbitrate, false);
	LOAD_MODULE_SUBFUNC(request_keyframe, false);

	info->id = id;
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
	return true;
}

static inline struct encoder_info *get_encoder_info(const char *id)
{
	for (size_t i = 0; i < obs->encoder_types.num; i++) {
		struct encoder_info *info = obs->encoder_types.array+i;

		if (strcmp(info->id, id) == 0)
			return info;
	}

	return NULL;
}

const char *obs_encoder_getdisplayname(const char *id, const char *locale)
{
	struct encoder_info *ei = get_encoder_info(id);
	if (!ei)
		return NULL;

	return ei->getname(locale);
}

obs_encoder_t obs_encoder_create(const char *id, const char *name,
62
		obs_data_t settings)
63 64 65 66 67 68 69
{
	struct obs_encoder *encoder;
	struct encoder_info *ei = get_encoder_info(id);

	if (!ei)
		return NULL;

70
	encoder = bzalloc(sizeof(struct obs_encoder));
71 72 73 74 75 76 77
	encoder->callbacks = *ei;

	if (pthread_mutex_init(&encoder->data_callbacks_mutex, NULL) != 0) {
		bfree(encoder);
		return NULL;
	}

J
jp9000 已提交
78 79 80
	encoder->settings = obs_data_newref(settings);
	encoder->data     = ei->create(encoder->settings, encoder);

81 82
	if (!encoder->data) {
		pthread_mutex_destroy(&encoder->data_callbacks_mutex);
J
jp9000 已提交
83
		obs_data_release(encoder->settings);
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
		bfree(encoder);
		return NULL;
	}

	pthread_mutex_lock(&obs->data.encoders_mutex);
	da_push_back(obs->data.encoders, &encoder);
	pthread_mutex_unlock(&obs->data.encoders_mutex);
	return encoder;
}

void obs_encoder_destroy(obs_encoder_t encoder)
{
	if (encoder) {
		pthread_mutex_lock(&obs->data.encoders_mutex);
		da_erase_item(obs->data.encoders, &encoder);
		pthread_mutex_unlock(&obs->data.encoders_mutex);

		encoder->callbacks.destroy(encoder->data);
102
		obs_data_release(encoder->settings);
103 104 105 106
		bfree(encoder);
	}
}

J
jp9000 已提交
107 108 109 110 111 112 113 114
obs_properties_t obs_encoder_properties(const char *id, const char *locale)
{
	const struct encoder_info *ei = get_encoder_info(id);
	if (ei && ei->properties)
		return ei->properties(locale);
	return NULL;
}

115
void obs_encoder_update(obs_encoder_t encoder, obs_data_t settings)
116
{
117
	obs_data_replace(&encoder->settings, settings);
J
jp9000 已提交
118
	encoder->callbacks.update(encoder->data, encoder->settings);
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
}

bool obs_encoder_reset(obs_encoder_t encoder)
{
	return encoder->callbacks.reset(encoder->data);
}

bool obs_encoder_encode(obs_encoder_t encoder, void *frames, size_t size)
{
	/* TODO */
	//encoder->callbacks.encode(encoder->data, frames, size, packets);
	return false;
}

int obs_encoder_getheader(obs_encoder_t encoder,
		struct encoder_packet **packets)
{
	return encoder->callbacks.getheader(encoder, packets);
}

J
jp9000 已提交
139
bool obs_encoder_setbitrate(obs_encoder_t encoder, uint32_t bitrate,
140 141 142
		uint32_t buffersize)
{
	if (encoder->callbacks.setbitrate)
J
jp9000 已提交
143
		return encoder->callbacks.setbitrate(encoder->data, bitrate,
144
				buffersize);
J
jp9000 已提交
145
	return false;
146 147
}

J
jp9000 已提交
148
bool obs_encoder_request_keyframe(obs_encoder_t encoder)
149 150
{
	if (encoder->callbacks.request_keyframe)
J
jp9000 已提交
151 152
		return encoder->callbacks.request_keyframe(encoder->data);
	return false;
153 154
}

155
obs_data_t obs_encoder_get_settings(obs_encoder_t encoder)
156
{
157 158
	obs_data_addref(encoder->settings);
	return encoder->settings;
159
}