Пример #1
0
static int obs_init_graphics(struct obs_video_info *ovi)
{
	struct obs_core_video *video = &obs->video;
	struct gs_init_data graphics_data;
	bool success = true;
	int errorcode;

	make_gs_init_data(&graphics_data, ovi);

	errorcode = gs_create(&video->graphics, ovi->graphics_module,
			&graphics_data);
	if (errorcode != GS_SUCCESS) {
		switch (errorcode) {
		case GS_ERROR_MODULE_NOT_FOUND:
			return OBS_VIDEO_MODULE_NOT_FOUND;
		case GS_ERROR_NOT_SUPPORTED:
			return OBS_VIDEO_NOT_SUPPORTED;
		default:
			return OBS_VIDEO_FAIL;
		}
	}

	gs_enter_context(video->graphics);

	char *filename = find_libobs_data_file("default.effect");
	video->default_effect = gs_effect_create_from_file(filename,
			NULL);
	bfree(filename);

	if (gs_get_device_type() == GS_DEVICE_OPENGL) {
		filename = find_libobs_data_file("default_rect.effect");
		video->default_rect_effect = gs_effect_create_from_file(
				filename, NULL);
		bfree(filename);
	}

	filename = find_libobs_data_file("solid.effect");
	video->solid_effect = gs_effect_create_from_file(filename,
			NULL);
	bfree(filename);

	filename = find_libobs_data_file("format_conversion.effect");
	video->conversion_effect = gs_effect_create_from_file(filename,
			NULL);
	bfree(filename);

	if (!video->default_effect)
		success = false;
	if (gs_get_device_type() == GS_DEVICE_OPENGL) {
		if (!video->default_rect_effect)
			success = false;
	}
	if (!video->solid_effect)
		success = false;
	if (!video->conversion_effect)
		success = false;

	gs_leave_context();
	return success ? OBS_VIDEO_SUCCESS : OBS_VIDEO_FAIL;
}
Пример #2
0
static inline void render_displays(void)
{
	struct obs_display *display;

	if (!obs->data.valid)
		return;

	gs_enter_context(obs->video.graphics);

	/* render extra displays/swaps */
	pthread_mutex_lock(&obs->data.displays_mutex);

	display = obs->data.first_display;
	while (display) {
		render_display(display);
		display = display->next;
	}

	pthread_mutex_unlock(&obs->data.displays_mutex);

	/* render main display */
	render_display(&obs->video.main_display);

	gs_leave_context();
}
Пример #3
0
static inline void output_frame(uint64_t *cur_time, uint64_t interval)
{
	struct obs_core_video *video = &obs->video;
	int cur_texture  = video->cur_texture;
	int prev_texture = cur_texture == 0 ? NUM_TEXTURES-1 : cur_texture-1;
	struct video_data frame;
	bool frame_ready;

	memset(&frame, 0, sizeof(struct video_data));

	gs_enter_context(video->graphics);
	render_video(video, cur_texture, prev_texture);
	frame_ready = download_frame(video, prev_texture, &frame);
	gs_flush();
	gs_leave_context();

	if (frame_ready) {
		struct obs_vframe_info vframe_info;
		circlebuf_pop_front(&video->vframe_info_buffer, &vframe_info,
				sizeof(vframe_info));

		frame.timestamp = vframe_info.timestamp;
		output_video_data(video, &frame, vframe_info.count);
	}

	if (++video->cur_texture == NUM_TEXTURES)
		video->cur_texture = 0;

	video_sleep(video, cur_time, interval);
}
Пример #4
0
void obs_transition_free(obs_source_t *transition)
{
    pthread_mutex_destroy(&transition->transition_mutex);
    pthread_mutex_destroy(&transition->transition_tex_mutex);

    gs_enter_context(obs->video.graphics);
    gs_texrender_destroy(transition->transition_texrender[0]);
    gs_texrender_destroy(transition->transition_texrender[1]);
    gs_leave_context();
}
Пример #5
0
static int obs_init_video(struct obs_video_info *ovi)
{
	struct obs_core_video *video = &obs->video;
	struct video_output_info vi;
	int errorcode;

	make_video_info(&vi, ovi);
	video->base_width     = ovi->base_width;
	video->base_height    = ovi->base_height;
	video->output_width   = ovi->output_width;
	video->output_height  = ovi->output_height;
	video->gpu_conversion = ovi->gpu_conversion;

	errorcode = video_output_open(&video->video, &vi);

	if (errorcode != VIDEO_OUTPUT_SUCCESS) {
		if (errorcode == VIDEO_OUTPUT_INVALIDPARAM) {
			blog(LOG_ERROR, "Invalid video parameters specified");
			return OBS_VIDEO_INVALID_PARAM;
		} else {
			blog(LOG_ERROR, "Could not open video output");
		}
		return OBS_VIDEO_FAIL;
	}

	if (!obs_display_init(&video->main_display, NULL))
		return OBS_VIDEO_FAIL;

	video->main_display.cx = ovi->window_width;
	video->main_display.cy = ovi->window_height;

	gs_enter_context(video->graphics);

	if (ovi->gpu_conversion && !obs_init_gpu_conversion(ovi))
		return OBS_VIDEO_FAIL;
	if (!obs_init_textures(ovi))
		return OBS_VIDEO_FAIL;

	gs_leave_context();

	errorcode = pthread_create(&video->video_thread, NULL,
			obs_video_thread, obs);
	if (errorcode != 0)
		return OBS_VIDEO_FAIL;

	video->thread_initialized = true;
	return OBS_VIDEO_SUCCESS;
}
Пример #6
0
static inline void output_frame(bool raw_active, const bool gpu_active)
{
	struct obs_core_video *video = &obs->video;
	int cur_texture  = video->cur_texture;
	int prev_texture = cur_texture == 0 ? NUM_TEXTURES-1 : cur_texture-1;
	struct video_data frame;
	bool active = raw_active || gpu_active;
	bool frame_ready;

	memset(&frame, 0, sizeof(struct video_data));

	profile_start(output_frame_gs_context_name);
	gs_enter_context(video->graphics);

	profile_start(output_frame_render_video_name);
	render_video(video, raw_active, gpu_active, cur_texture, prev_texture);
	profile_end(output_frame_render_video_name);

	if (raw_active) {
		profile_start(output_frame_download_frame_name);
		frame_ready = download_frame(video, prev_texture, &frame);
		profile_end(output_frame_download_frame_name);
	}

	profile_start(output_frame_gs_flush_name);
	gs_flush();
	profile_end(output_frame_gs_flush_name);

	gs_leave_context();
	profile_end(output_frame_gs_context_name);

	if (raw_active && frame_ready) {
		struct obs_vframe_info vframe_info;
		circlebuf_pop_front(&video->vframe_info_buffer, &vframe_info,
				sizeof(vframe_info));

		frame.timestamp = vframe_info.timestamp;
		profile_start(output_frame_output_video_data_name);
		output_video_data(video, &frame, vframe_info.count);
		profile_end(output_frame_output_video_data_name);
	}

	if (++video->cur_texture == NUM_TEXTURES)
		video->cur_texture = 0;
}
Пример #7
0
static void obs_free_graphics(void)
{
	struct obs_core_video *video = &obs->video;

	if (video->graphics) {
		gs_enter_context(video->graphics);

		gs_effect_destroy(video->default_effect);
		gs_effect_destroy(video->default_rect_effect);
		gs_effect_destroy(video->solid_effect);
		gs_effect_destroy(video->conversion_effect);
		video->default_effect = NULL;

		gs_leave_context();

		gs_destroy(video->graphics);
		video->graphics = NULL;
	}
}
Пример #8
0
static void obs_free_video(void)
{
	struct obs_core_video *video = &obs->video;

	if (video->video) {
		obs_display_free(&video->main_display);

		video_output_close(video->video);
		video->video = NULL;

		if (!video->graphics)
			return;

		gs_enter_context(video->graphics);

		if (video->mapped_surface) {
			gs_stagesurface_unmap(video->mapped_surface);
			video->mapped_surface = NULL;
		}

		for (size_t i = 0; i < NUM_TEXTURES; i++) {
			gs_stagesurface_destroy(video->copy_surfaces[i]);
			gs_texture_destroy(video->render_textures[i]);
			gs_texture_destroy(video->convert_textures[i]);
			gs_texture_destroy(video->output_textures[i]);
			obs_source_frame_free(&video->convert_frames[i]);

			video->copy_surfaces[i]    = NULL;
			video->render_textures[i]  = NULL;
			video->convert_textures[i] = NULL;
			video->output_textures[i]  = NULL;
		}

		gs_leave_context();

		circlebuf_free(&video->timestamp_buffer);

		video->cur_texture = 0;
	}
}
Пример #9
0
obs_display_t *obs_display_create(const struct gs_init_data *graphics_data)
{
	struct obs_display *display = bzalloc(sizeof(struct obs_display));

	gs_enter_context(obs->video.graphics);

	if (!obs_display_init(display, graphics_data)) {
		obs_display_destroy(display);
		display = NULL;
	} else {
		pthread_mutex_lock(&obs->data.displays_mutex);
		display->prev_next      = &obs->data.first_display;
		display->next           = obs->data.first_display;
		obs->data.first_display = display;
		if (display->next)
			display->next->prev_next = &display->next;
		pthread_mutex_unlock(&obs->data.displays_mutex);
	}

	gs_leave_context();

	return display;
}
Пример #10
0
void obs_leave_graphics(void)
{
	if (obs && obs->video.graphics)
		gs_leave_context();
}