New upstream version 21.0.2+dfsg1

This commit is contained in:
Sebastian Ramacher 2018-02-19 20:54:37 +01:00
parent 1f1bbb3518
commit baafb6325b
706 changed files with 49633 additions and 5044 deletions

View file

@ -1,4 +1,4 @@
PulseInput="오디오 입력 캡쳐(PulseAudio)"
PulseInput="오디오 입력 캡쳐 (PulseAudio)"
PulseOutput="오디오 출력 캡쳐(PulseAudio)"
Device="장치"

View file

@ -0,0 +1,4 @@
PulseInput="Thu âm đầu vào (PulseAudio)"
PulseOutput="Thu âm đầu ra (PulseAudio)"
Device="Thiết bị"

View file

@ -33,6 +33,7 @@ struct pulse_data {
/* user settings */
char *device;
bool input;
/* server info */
enum speaker_layout speakers;
@ -80,18 +81,73 @@ static enum speaker_layout pulse_channels_to_obs_speakers(
uint_fast32_t channels)
{
switch(channels) {
case 1: return SPEAKERS_MONO;
case 2: return SPEAKERS_STEREO;
case 3: return SPEAKERS_2POINT1;
case 4: return SPEAKERS_SURROUND;
case 5: return SPEAKERS_4POINT1;
case 6: return SPEAKERS_5POINT1;
case 8: return SPEAKERS_7POINT1;
case 1: return SPEAKERS_MONO;
case 2: return SPEAKERS_STEREO;
case 3: return SPEAKERS_2POINT1;
case 4: return SPEAKERS_4POINT0;
case 5: return SPEAKERS_4POINT1;
case 6: return SPEAKERS_5POINT1;
case 8: return SPEAKERS_7POINT1;
}
return SPEAKERS_UNKNOWN;
}
static pa_channel_map pulse_channel_map(enum speaker_layout layout)
{
pa_channel_map ret;
ret.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
ret.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
ret.map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
ret.map[3] = PA_CHANNEL_POSITION_LFE;
ret.map[4] = PA_CHANNEL_POSITION_REAR_LEFT;
ret.map[5] = PA_CHANNEL_POSITION_REAR_RIGHT;
ret.map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
ret.map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
switch (layout) {
case SPEAKERS_MONO:
ret.channels = 1;
ret.map[0] = PA_CHANNEL_POSITION_MONO;
break;
case SPEAKERS_STEREO:
ret.channels = 2;
break;
case SPEAKERS_2POINT1:
ret.channels = 3;
ret.map[2] = PA_CHANNEL_POSITION_LFE;
break;
case SPEAKERS_4POINT0:
ret.channels = 4;
ret.map[3] = PA_CHANNEL_POSITION_REAR_CENTER;
break;
case SPEAKERS_4POINT1:
ret.channels = 5;
ret.map[4] = PA_CHANNEL_POSITION_REAR_CENTER;
break;
case SPEAKERS_5POINT1:
ret.channels = 6;
break;
case SPEAKERS_7POINT1:
ret.channels = 8;
break;
case SPEAKERS_UNKNOWN:
default:
ret.channels = 0;
break;
}
return ret;
}
static inline uint64_t samples_to_ns(size_t frames, uint_fast32_t rate)
{
return frames * NSEC_PER_SEC / rate;
@ -164,11 +220,30 @@ static void pulse_server_info(pa_context *c, const pa_server_info *i,
void *userdata)
{
UNUSED_PARAMETER(c);
UNUSED_PARAMETER(userdata);
PULSE_DATA(userdata);
blog(LOG_INFO, "Server name: '%s %s'",
i->server_name, i->server_version);
if (data->device && strcmp("default", data->device) == 0) {
if (data->input) {
bfree(data->device);
data->device = bstrdup(i->default_source_name);
blog(LOG_DEBUG, "Default input device: '%s'", data->device);
} else {
char *monitor = bzalloc(strlen(i->default_sink_name) + 9);
strcat(monitor, i->default_sink_name);
strcat(monitor, ".monitor");
bfree(data->device);
data->device = bstrdup(monitor);
blog(LOG_DEBUG, "Default output device: '%s'", data->device);
bfree(monitor);
}
}
pulse_signal(0);
}
@ -200,7 +275,7 @@ static void pulse_source_info(pa_context *c, const pa_source_info *i, int eol,
pa_sample_format_t format = i->sample_spec.format;
if (pulse_to_obs_audio_format(format) == AUDIO_FORMAT_UNKNOWN) {
format = PA_SAMPLE_S16LE;
format = PA_SAMPLE_FLOAT32LE;
blog(LOG_INFO, "Sample format %s not supported by OBS,"
"using %s instead for recording",
@ -266,8 +341,10 @@ static int_fast32_t pulse_start_recording(struct pulse_data *data)
data->speakers = pulse_channels_to_obs_speakers(spec.channels);
data->bytes_per_frame = pa_frame_size(&spec);
pa_channel_map channel_map = pulse_channel_map(data->speakers);
data->stream = pulse_stream_new(obs_source_get_name(data->source),
&spec, NULL);
&spec, &channel_map);
if (!data->stream) {
blog(LOG_ERROR, "Unable to create stream");
return -1;
@ -343,15 +420,15 @@ skip:
/**
* output info callback
*/
static void pulse_output_info(pa_context *c, const pa_source_info *i, int eol,
static void pulse_output_info(pa_context *c, const pa_sink_info *i, int eol,
void *userdata)
{
UNUSED_PARAMETER(c);
if (eol != 0 || i->monitor_of_sink == PA_INVALID_INDEX)
if (eol != 0 || i->monitor_source == PA_INVALID_INDEX)
goto skip;
obs_property_list_add_string((obs_property_t*) userdata,
i->description, i->name);
i->description, i->monitor_source_name);
skip:
pulse_signal(0);
@ -368,10 +445,18 @@ static obs_properties_t *pulse_properties(bool input)
OBS_COMBO_FORMAT_STRING);
pulse_init();
pa_source_info_cb_t cb = (input) ? pulse_input_info : pulse_output_info;
pulse_get_source_info_list(cb, (void *) devices);
if (input)
pulse_get_source_info_list(pulse_input_info, (void *) devices);
else
pulse_get_sink_info_list(pulse_output_info, (void *) devices);
pulse_unref();
size_t count = obs_property_list_item_count(devices);
if (count > 0)
obs_property_list_insert_string(devices, 0,
obs_module_text("Default"), "default");
return props;
}
@ -389,61 +474,12 @@ static obs_properties_t *pulse_output_properties(void *unused)
return pulse_properties(false);
}
/**
* Server info callback
*/
static void pulse_input_device(pa_context *c, const pa_server_info *i,
void *userdata)
{
UNUSED_PARAMETER(c);
obs_data_t *settings = (obs_data_t*) userdata;
obs_data_set_default_string(settings, "device_id",
i->default_source_name);
blog(LOG_DEBUG, "Default input device: '%s'", i->default_source_name);
pulse_signal(0);
}
static void pulse_output_device(pa_context *c, const pa_server_info *i,
void *userdata)
{
UNUSED_PARAMETER(c);
obs_data_t *settings = (obs_data_t*) userdata;
char *monitor = bzalloc(strlen(i->default_sink_name) + 9);
strcat(monitor, i->default_sink_name);
strcat(monitor, ".monitor");
obs_data_set_default_string(settings, "device_id", monitor);
blog(LOG_DEBUG, "Default output device: '%s'", monitor);
bfree(monitor);
pulse_signal(0);
}
/**
* Get plugin defaults
*/
static void pulse_defaults(obs_data_t *settings, bool input)
static void pulse_defaults(obs_data_t *settings)
{
pulse_init();
pa_server_info_cb_t cb = (input)
? pulse_input_device : pulse_output_device;
pulse_get_server_info(cb, (void *) settings);
pulse_unref();
}
static void pulse_input_defaults(obs_data_t *settings)
{
return pulse_defaults(settings, true);
}
static void pulse_output_defaults(obs_data_t *settings)
{
return pulse_defaults(settings, false);
obs_data_set_default_string(settings, "device_id", "default");
}
/**
@ -508,10 +544,11 @@ static void pulse_update(void *vptr, obs_data_t *settings)
/**
* Create the plugin object
*/
static void *pulse_create(obs_data_t *settings, obs_source_t *source)
static void *pulse_create(obs_data_t *settings, obs_source_t *source, bool input)
{
struct pulse_data *data = bzalloc(sizeof(struct pulse_data));
data->input = input;
data->source = source;
pulse_init();
@ -520,16 +557,26 @@ static void *pulse_create(obs_data_t *settings, obs_source_t *source)
return data;
}
static void *pulse_input_create(obs_data_t *settings, obs_source_t *source)
{
return pulse_create(settings, source, true);
}
static void *pulse_output_create(obs_data_t *settings, obs_source_t *source)
{
return pulse_create(settings, source, false);
}
struct obs_source_info pulse_input_capture = {
.id = "pulse_input_capture",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_AUDIO |
OBS_SOURCE_DO_NOT_DUPLICATE,
.get_name = pulse_input_getname,
.create = pulse_create,
.create = pulse_input_create,
.destroy = pulse_destroy,
.update = pulse_update,
.get_defaults = pulse_input_defaults,
.get_defaults = pulse_defaults,
.get_properties = pulse_input_properties
};
@ -540,9 +587,9 @@ struct obs_source_info pulse_output_capture = {
OBS_SOURCE_DO_NOT_DUPLICATE |
OBS_SOURCE_DO_NOT_SELF_MONITOR,
.get_name = pulse_output_getname,
.create = pulse_create,
.create = pulse_output_create,
.destroy = pulse_destroy,
.update = pulse_update,
.get_defaults = pulse_output_defaults,
.get_defaults = pulse_defaults,
.get_properties = pulse_output_properties
};

View file

@ -185,6 +185,28 @@ int_fast32_t pulse_get_source_info_list(pa_source_info_cb_t cb, void* userdata)
return 0;
}
int_fast32_t pulse_get_sink_info_list(pa_sink_info_cb_t cb, void *userdata)
{
if (pulse_context_ready() < 0)
return -1;
pulse_lock();
pa_operation *op = pa_context_get_sink_info_list(
pulse_context, cb, userdata);
if (!op) {
pulse_unlock();
return -1;
}
while (pa_operation_get_state(op) == PA_OPERATION_RUNNING)
pulse_wait();
pa_operation_unref(op);
pulse_unlock();
return 0;
}
int_fast32_t pulse_get_source_info(pa_source_info_cb_t cb, const char *name,
void *userdata)
{

View file

@ -93,6 +93,20 @@ void pulse_accept();
*/
int_fast32_t pulse_get_source_info_list(pa_source_info_cb_t cb, void *userdata);
/**
* Request sink information
*
* The function will block until the operation was executed and the mainloop
* called the provided callback function.
*
* @return negative on error
*
* @note The function will block until the server context is ready.
*
* @warning call without active locks
*/
int_fast32_t pulse_get_sink_info_list(pa_sink_info_cb_t cb, void *userdata);
/**
* Request source information from a specific source
*