/* internal initialization */ bool obs_source_init(struct obs_source *source, const char *settings, const struct source_info *info) { uint32_t flags = info->get_output_flags(source->data); source->refs = 1; source->volume = 1.0f; pthread_mutex_init_value(&source->filter_mutex); pthread_mutex_init_value(&source->video_mutex); pthread_mutex_init_value(&source->audio_mutex); dstr_copy(&source->settings, settings); memcpy(&source->callbacks, info, sizeof(struct source_info)); if (pthread_mutex_init(&source->filter_mutex, NULL) != 0) return false; if (pthread_mutex_init(&source->audio_mutex, NULL) != 0) return false; if (pthread_mutex_init(&source->video_mutex, NULL) != 0) return false; if (flags & SOURCE_AUDIO) { source->audio_line = audio_output_createline(obs->audio.audio, source->name); if (!source->audio_line) { blog(LOG_ERROR, "Failed to create audio line for " "source '%s'", source->name); return false; } } return true; }
obs_output_t *obs_output_create(const char *id, const char *name, obs_data_t *settings, obs_data_t *hotkey_data) { const struct obs_output_info *info = find_output(id); struct obs_output *output; int ret; output = bzalloc(sizeof(struct obs_output)); pthread_mutex_init_value(&output->interleaved_mutex); pthread_mutex_init_value(&output->delay_mutex); if (pthread_mutex_init(&output->interleaved_mutex, NULL) != 0) goto fail; if (pthread_mutex_init(&output->delay_mutex, NULL) != 0) goto fail; if (!init_output_handlers(output, name, settings, hotkey_data)) goto fail; if (!info) { blog(LOG_ERROR, "Output ID '%s' not found", id); output->info.id = bstrdup(id); output->owns_info_id = true; } else { output->info = *info; } output->video = obs_get_video(); output->audio = obs_get_audio(); if (output->info.get_defaults) output->info.get_defaults(output->context.settings); ret = os_event_init(&output->reconnect_stop_event, OS_EVENT_TYPE_MANUAL); if (ret < 0) goto fail; if (info) output->context.data = info->create(output->context.settings, output); if (!output->context.data) blog(LOG_ERROR, "Failed to create output '%s'!", name); output->reconnect_retry_sec = 2; output->reconnect_retry_max = 20; output->valid = true; output->control = bzalloc(sizeof(obs_weak_output_t)); output->control->output = output; obs_context_data_insert(&output->context, &obs->data.outputs_mutex, &obs->data.first_output); blog(LOG_INFO, "output '%s' (%s) created", name, id); return output; fail: obs_output_destroy(output); return NULL; }
static bool init_encoder(struct obs_encoder *encoder, const char *name, obs_data_t *settings, obs_data_t *hotkey_data) { pthread_mutexattr_t attr; pthread_mutex_init_value(&encoder->init_mutex); pthread_mutex_init_value(&encoder->callbacks_mutex); pthread_mutex_init_value(&encoder->outputs_mutex); if (pthread_mutexattr_init(&attr) != 0) return false; if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0) return false; if (!obs_context_data_init(&encoder->context, OBS_OBJ_TYPE_ENCODER, settings, name, hotkey_data, false)) return false; if (pthread_mutex_init(&encoder->init_mutex, &attr) != 0) return false; if (pthread_mutex_init(&encoder->callbacks_mutex, &attr) != 0) return false; if (pthread_mutex_init(&encoder->outputs_mutex, NULL) != 0) return false; if (encoder->info.get_defaults) encoder->info.get_defaults(encoder->context.settings); return true; }
/* internal initialization */ bool obs_source_init(struct obs_source *source, const struct obs_source_info *info) { source->refs = 1; source->user_volume = 1.0f; source->present_volume = 0.0f; source->sync_offset = 0; pthread_mutex_init_value(&source->filter_mutex); pthread_mutex_init_value(&source->video_mutex); pthread_mutex_init_value(&source->audio_mutex); memcpy(&source->info, info, sizeof(struct obs_source_info)); if (pthread_mutex_init(&source->filter_mutex, NULL) != 0) return false; if (pthread_mutex_init(&source->audio_mutex, NULL) != 0) return false; if (pthread_mutex_init(&source->video_mutex, NULL) != 0) return false; if (info->output_flags & OBS_SOURCE_AUDIO) { source->audio_line = audio_output_createline(obs->audio.audio, source->context.name); if (!source->audio_line) { blog(LOG_ERROR, "Failed to create audio line for " "source '%s'", source->context.name); return false; } } obs_context_data_insert(&source->context, &obs->data.sources_mutex, &obs->data.first_source); return true; }
int audio_output_open(audio_t *audio, media_t media, struct audio_info *info) { struct audio_output *out; if (!valid_audio_params(info)) return AUDIO_OUTPUT_INVALIDPARAM; out = bmalloc(sizeof(struct audio_output)); memset(out, 0, sizeof(struct audio_output)); memcpy(&out->info, info, sizeof(struct audio_info)); pthread_mutex_init_value(&out->line_mutex); out->media = media; out->block_size = get_audio_channels(info->speakers) * get_audio_bytes_per_channel(info->format); if (pthread_mutex_init(&out->line_mutex, NULL) != 0) goto fail; if (event_init(&out->stop_event, true) != 0) goto fail; if (!ao_add_to_media(out)) goto fail; if (pthread_create(&out->thread, NULL, audio_thread, out) != 0) goto fail; out->initialized = true; *audio = out; return AUDIO_OUTPUT_SUCCESS; fail: audio_output_close(out); return AUDIO_OUTPUT_FAIL; }
int gs_create(graphics_t *pgraphics, const char *module, struct gs_init_data *data) { int errcode = GS_ERROR_FAIL; graphics_t graphics = bmalloc(sizeof(struct graphics_subsystem)); memset(graphics, 0, sizeof(struct graphics_subsystem)); pthread_mutex_init_value(&graphics->mutex); graphics->module = os_dlopen(module); if (!graphics->module) { errcode = GS_ERROR_MODULENOTFOUND; goto error; } if (!load_graphics_imports(&graphics->exports, graphics->module, module)) goto error; graphics->device = graphics->exports.device_create(data); if (!graphics->device) goto error; if (!graphics_init(graphics)) goto error; *pgraphics = graphics; return GS_SUCCESS; error: gs_destroy(graphics); return errcode; }
bool obs_display_init(struct obs_display *display, const struct gs_init_data *graphics_data) { pthread_mutex_init_value(&display->draw_callbacks_mutex); if (graphics_data) { display->swap = gs_swapchain_create(graphics_data); if (!display->swap) { blog(LOG_ERROR, "obs_display_init: Failed to " "create swap chain"); return false; } display->cx = graphics_data->cx; display->cy = graphics_data->cy; } if (pthread_mutex_init(&display->draw_callbacks_mutex, NULL) != 0) { blog(LOG_ERROR, "obs_display_init: Failed to create mutex"); return false; } display->background_color = 0x4C4C4C; display->enabled = true; return true; }
static bool obs_init_data(void) { struct obs_core_data *data = &obs->data; pthread_mutexattr_t attr; assert(data != NULL); pthread_mutex_init_value(&obs->data.displays_mutex); if (pthread_mutexattr_init(&attr) != 0) return false; if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0) goto fail; if (pthread_mutex_init(&data->user_sources_mutex, &attr) != 0) goto fail; if (pthread_mutex_init(&data->sources_mutex, &attr) != 0) goto fail; if (pthread_mutex_init(&data->displays_mutex, &attr) != 0) goto fail; if (pthread_mutex_init(&data->outputs_mutex, &attr) != 0) goto fail; if (pthread_mutex_init(&data->encoders_mutex, &attr) != 0) goto fail; if (pthread_mutex_init(&data->services_mutex, &attr) != 0) goto fail; if (!obs_view_init(&data->main_view)) goto fail; data->valid = true; fail: pthread_mutexattr_destroy(&attr); return data->valid; }
obs_fader_t *obs_fader_create(enum obs_fader_type type) { struct obs_fader *fader = bzalloc(sizeof(struct obs_fader)); if (!fader) return NULL; pthread_mutex_init_value(&fader->mutex); if (pthread_mutex_init(&fader->mutex, NULL) != 0) goto fail; fader->signals = signal_handler_create(); if (!fader->signals) goto fail; if (!signal_handler_add_array(fader->signals, fader_signals)) goto fail; switch(type) { case OBS_FADER_CUBIC: fader->def_to_db = cubic_def_to_db; fader->db_to_def = cubic_db_to_def; fader->max_db = 0.0f; fader->min_db = -INFINITY; break; default: goto fail; break; } fader->type = type; return fader; fail: obs_fader_destroy(fader); return NULL; }
static bool init_encoder(struct obs_encoder *encoder, const char *name, obs_data_t settings) { pthread_mutex_init_value(&encoder->callbacks_mutex); pthread_mutex_init_value(&encoder->outputs_mutex); if (!obs_context_data_init(&encoder->context, settings, name)) return false; if (pthread_mutex_init(&encoder->callbacks_mutex, NULL) != 0) return false; if (pthread_mutex_init(&encoder->outputs_mutex, NULL) != 0) return false; if (encoder->info.defaults) encoder->info.defaults(encoder->context.settings); return true; }
bool obs_transition_init(obs_source_t *transition) { pthread_mutex_init_value(&transition->transition_mutex); pthread_mutex_init_value(&transition->transition_tex_mutex); if (pthread_mutex_init(&transition->transition_mutex, NULL) != 0) return false; if (pthread_mutex_init(&transition->transition_tex_mutex, NULL) != 0) return false; transition->transition_alignment = OBS_ALIGN_LEFT | OBS_ALIGN_TOP; transition->transition_texrender[0] = gs_texrender_create(GS_RGBA, GS_ZS_NONE); transition->transition_texrender[1] = gs_texrender_create(GS_RGBA, GS_ZS_NONE); transition->transition_source_active[0] = true; return transition->transition_texrender[0] != NULL && transition->transition_texrender[1] != NULL; }
static bool obs_init_data(void) { struct obs_data *data = &obs->data; pthread_mutex_init_value(&obs->data.displays_mutex); if (pthread_mutex_init(&data->sources_mutex, NULL) != 0) return false; if (pthread_mutex_init(&data->displays_mutex, NULL) != 0) return false; return true; }
bool obs_view_init(struct obs_view *view) { if (!view) return false; pthread_mutex_init_value(&view->channels_mutex); if (pthread_mutex_init(&view->channels_mutex, NULL) != 0) { blog(LOG_ERROR, "obs_view_init: Failed to create mutex"); return false; } return true; }
obs_output_t obs_output_create(const char *id, const char *name, obs_data_t settings) { const struct obs_output_info *info = find_output(id); struct obs_output *output; int ret; if (!info) { blog(LOG_ERROR, "Output '%s' not found", id); return NULL; } output = bzalloc(sizeof(struct obs_output)); pthread_mutex_init_value(&output->interleaved_mutex); if (pthread_mutex_init(&output->interleaved_mutex, NULL) != 0) goto fail; if (!init_output_handlers(output, name, settings)) goto fail; output->info = *info; output->video = obs_video(); output->audio = obs_audio(); if (output->info.defaults) output->info.defaults(output->context.settings); ret = os_event_init(&output->reconnect_stop_event, OS_EVENT_TYPE_MANUAL); if (ret < 0) goto fail; output->context.data = info->create(output->context.settings, output); if (!output->context.data) goto fail; output->reconnect_retry_sec = 2; output->reconnect_retry_max = 20; output->valid = true; obs_context_data_insert(&output->context, &obs->data.outputs_mutex, &obs->data.first_output); return output; fail: obs_output_destroy(output); return NULL; }
static void *rtmp_stream_create(obs_data_t *settings, obs_output_t *output) { struct rtmp_stream *stream = bzalloc(sizeof(struct rtmp_stream)); stream->output = output; pthread_mutex_init_value(&stream->packets_mutex); RTMP_Init(&stream->rtmp); RTMP_LogSetCallback(log_rtmp); RTMP_LogSetLevel(RTMP_LOGWARNING); if (pthread_mutex_init(&stream->packets_mutex, NULL) != 0) goto fail; if (os_event_init(&stream->stop_event, OS_EVENT_TYPE_MANUAL) != 0) goto fail; if (pthread_mutex_init(&stream->write_buf_mutex, NULL) != 0) { warn("Failed to initialize write buffer mutex"); goto fail; } if (os_event_init(&stream->buffer_space_available_event, OS_EVENT_TYPE_AUTO) != 0) { warn("Failed to initialize write buffer event"); goto fail; } if (os_event_init(&stream->buffer_has_data_event, OS_EVENT_TYPE_AUTO) != 0) { warn("Failed to initialize data buffer event"); goto fail; } if (os_event_init(&stream->socket_available_event, OS_EVENT_TYPE_AUTO) != 0) { warn("Failed to initialize socket buffer event"); goto fail; } if (os_event_init(&stream->send_thread_signaled_exit, OS_EVENT_TYPE_MANUAL) != 0) { warn("Failed to initialize socket exit event"); goto fail; } UNUSED_PARAMETER(settings); return stream; fail: rtmp_stream_destroy(stream); return NULL; }
void mp_media_free(mp_media_t *media) { if (!media) return; mp_media_stop(media); mp_kill_thread(media); mp_decode_free(&media->v); mp_decode_free(&media->a); avformat_close_input(&media->fmt); pthread_mutex_destroy(&media->mutex); os_sem_destroy(media->sem); sws_freeContext(media->swscale); av_freep(&media->scale_pic[0]); bfree(media->path); bfree(media->format_name); memset(media, 0, sizeof(*media)); pthread_mutex_init_value(&media->mutex); }
int audio_output_open(audio_t *audio, struct audio_output_info *info) { struct audio_output *out; pthread_mutexattr_t attr; bool planar = is_audio_planar(info->format); if (!valid_audio_params(info)) return AUDIO_OUTPUT_INVALIDPARAM; out = bzalloc(sizeof(struct audio_output)); if (!out) goto fail; memcpy(&out->info, info, sizeof(struct audio_output_info)); pthread_mutex_init_value(&out->line_mutex); out->channels = get_audio_channels(info->speakers); out->planes = planar ? out->channels : 1; out->block_size = (planar ? 1 : out->channels) * get_audio_bytes_per_channel(info->format); if (pthread_mutexattr_init(&attr) != 0) goto fail; if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0) goto fail; if (pthread_mutex_init(&out->line_mutex, &attr) != 0) goto fail; if (pthread_mutex_init(&out->input_mutex, NULL) != 0) goto fail; if (os_event_init(&out->stop_event, OS_EVENT_TYPE_MANUAL) != 0) goto fail; if (pthread_create(&out->thread, NULL, audio_thread, out) != 0) goto fail; out->initialized = true; *audio = out; return AUDIO_OUTPUT_SUCCESS; fail: audio_output_close(out); return AUDIO_OUTPUT_FAIL; }
static void *rtmp_stream_create(obs_data_t *settings, obs_output_t *output) { struct rtmp_stream *stream = bzalloc(sizeof(struct rtmp_stream)); stream->output = output; pthread_mutex_init_value(&stream->packets_mutex); RTMP_Init(&stream->rtmp); RTMP_LogSetCallback(log_rtmp); RTMP_LogSetLevel(RTMP_LOGWARNING); if (pthread_mutex_init(&stream->packets_mutex, NULL) != 0) goto fail; if (os_event_init(&stream->stop_event, OS_EVENT_TYPE_MANUAL) != 0) goto fail; UNUSED_PARAMETER(settings); return stream; fail: rtmp_stream_destroy(stream); return NULL; }
bool mp_media_init(mp_media_t *media, const struct mp_media_info *info) { memset(media, 0, sizeof(*media)); pthread_mutex_init_value(&media->mutex); media->opaque = info->opaque; media->v_cb = info->v_cb; media->a_cb = info->a_cb; media->stop_cb = info->stop_cb; media->v_preload_cb = info->v_preload_cb; media->force_range = info->force_range; media->buffering = info->buffering; media->speed = info->speed; media->is_local_file = info->is_local_file; if (!info->is_local_file || media->speed < 1 || media->speed > 200) media->speed = 100; static bool initialized = false; if (!initialized) { av_register_all(); avdevice_register_all(); avcodec_register_all(); avformat_network_init(); initialized = true; } if (!base_sys_ts) base_sys_ts = (int64_t)os_gettime_ns(); if (!mp_media_init_internal(media, info)) { mp_media_free(media); return false; } return true; }
static inline bool obs_context_data_init_wrap( struct obs_context_data *context, obs_data_t *settings, const char *name) { assert(context); memset(context, 0, sizeof(*context)); pthread_mutex_init_value(&context->rename_cache_mutex); if (pthread_mutex_init(&context->rename_cache_mutex, NULL) < 0) return false; context->signals = signal_handler_create(); if (!context->signals) return false; context->procs = proc_handler_create(); if (!context->procs) return false; context->name = dup_name(name); context->settings = obs_data_newref(settings); return true; }
static bool audio_monitor_init(struct audio_monitor *monitor, obs_source_t *source) { IMMDeviceEnumerator *immde = NULL; WAVEFORMATEX *wfex = NULL; bool success = false; UINT32 frames; HRESULT hr; pthread_mutex_init_value(&monitor->playback_mutex); monitor->source = source; const char *id = obs->audio.monitoring_device_id; if (!id) { return false; } if (source->info.output_flags & OBS_SOURCE_DO_NOT_SELF_MONITOR) { obs_data_t *s = obs_source_get_settings(source); const char *s_dev_id = obs_data_get_string(s, "device_id"); bool match = devices_match(s_dev_id, id); obs_data_release(s); if (match) { monitor->ignore = true; return true; } } /* ------------------------------------------ * * Init device */ hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &IID_IMMDeviceEnumerator, (void**)&immde); if (FAILED(hr)) { return false; } if (strcmp(id, "default") == 0) { hr = immde->lpVtbl->GetDefaultAudioEndpoint(immde, eRender, eConsole, &monitor->device); } else { wchar_t w_id[512]; os_utf8_to_wcs(id, 0, w_id, 512); hr = immde->lpVtbl->GetDevice(immde, w_id, &monitor->device); } if (FAILED(hr)) { goto fail; } /* ------------------------------------------ * * Init client */ hr = monitor->device->lpVtbl->Activate(monitor->device, &IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&monitor->client); if (FAILED(hr)) { goto fail; } hr = monitor->client->lpVtbl->GetMixFormat(monitor->client, &wfex); if (FAILED(hr)) { goto fail; } hr = monitor->client->lpVtbl->Initialize(monitor->client, AUDCLNT_SHAREMODE_SHARED, 0, 10000000, 0, wfex, NULL); if (FAILED(hr)) { goto fail; } /* ------------------------------------------ * * Init resampler */ const struct audio_output_info *info = audio_output_get_info( obs->audio.audio); WAVEFORMATEXTENSIBLE *ext = (WAVEFORMATEXTENSIBLE*)wfex; struct resample_info from; struct resample_info to; from.samples_per_sec = info->samples_per_sec; from.speakers = info->speakers; from.format = AUDIO_FORMAT_FLOAT_PLANAR; to.samples_per_sec = (uint32_t)wfex->nSamplesPerSec; to.speakers = convert_speaker_layout(ext->dwChannelMask, wfex->nChannels); to.format = AUDIO_FORMAT_FLOAT; monitor->sample_rate = (uint32_t)wfex->nSamplesPerSec; monitor->channels = wfex->nChannels; monitor->resampler = audio_resampler_create(&to, &from); if (!monitor->resampler) { goto fail; } /* ------------------------------------------ * * Init client */ hr = monitor->client->lpVtbl->GetBufferSize(monitor->client, &frames); if (FAILED(hr)) { goto fail; } hr = monitor->client->lpVtbl->GetService(monitor->client, &IID_IAudioRenderClient, (void**)&monitor->render); if (FAILED(hr)) { goto fail; } if (pthread_mutex_init(&monitor->playback_mutex, NULL) != 0) { goto fail; } hr = monitor->client->lpVtbl->Start(monitor->client); if (FAILED(hr)) { goto fail; } success = true; fail: safe_release(immde); if (wfex) CoTaskMemFree(wfex); return success; }