obs-internal.h 16.8 KB
Newer Older
J
jp9000 已提交
1
/******************************************************************************
J
jp9000 已提交
2
    Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com>
J
jp9000 已提交
3 4 5

    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
6
    the Free Software Foundation, either version 2 of the License, or
J
jp9000 已提交
7 8 9 10 11 12 13 14 15 16 17
    (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/>.
******************************************************************************/

18
#pragma once
J
jp9000 已提交
19

J
jp9000 已提交
20
#include "util/c99defs.h"
J
jp9000 已提交
21
#include "util/darray.h"
22
#include "util/circlebuf.h"
J
jp9000 已提交
23
#include "util/dstr.h"
J
jp9000 已提交
24
#include "util/threading.h"
J
jp9000 已提交
25
#include "util/platform.h"
J
jp9000 已提交
26 27
#include "callback/signal.h"
#include "callback/proc.h"
J
jp9000 已提交
28 29 30

#include "graphics/graphics.h"

J
jp9000 已提交
31
#include "media-io/audio-resampler.h"
J
jp9000 已提交
32 33 34 35
#include "media-io/video-io.h"
#include "media-io/audio-io.h"

#include "obs.h"
36

J
jp9000 已提交
37
#define NUM_TEXTURES 2
38
#define MICROSECOND_DEN 1000000
J
jp9000 已提交
39

40 41 42 43
static inline int64_t packet_dts_usec(struct encoder_packet *packet)
{
	return packet->dts * MICROSECOND_DEN / packet->timebase_den;
}
44

45 46 47 48 49
struct draw_callback {
	void (*draw)(void *param, uint32_t cx, uint32_t cy);
	void *param;
};

J
jp9000 已提交
50
/* ------------------------------------------------------------------------- */
51
/* modules */
J
jp9000 已提交
52 53

struct obs_module {
J
jp9000 已提交
54 55 56
	const char *file;
	char *bin_path;
	char *data_path;
J
jp9000 已提交
57
	void *module;
J
jp9000 已提交
58 59
	bool loaded;

60
	bool        (*load)(void);
J
jp9000 已提交
61 62 63 64
	void        (*unload)(void);
	void        (*set_locale)(const char *locale);
	void        (*free_locale)(void);
	uint32_t    (*ver)(void);
65
	void        (*set_pointer)(obs_module_t *module);
J
jp9000 已提交
66 67 68 69 70
	const char *(*name)(void);
	const char *(*description)(void);
	const char *(*author)(void);

	struct obs_module *next;
J
jp9000 已提交
71 72
};

J
jp9000 已提交
73 74
extern void free_module(struct obs_module *mod);

J
jp9000 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
struct obs_module_path {
	char *bin;
	char *data;
};

static inline void free_module_path(struct obs_module_path *omp)
{
	if (omp) {
		bfree(omp->bin);
		bfree(omp->data);
	}
}

static inline bool check_path(const char *data, const char *path,
		struct dstr *output)
{
	dstr_copy(output, path);
	dstr_cat(output, data);

	return os_file_exists(output->array);
}

J
jp9000 已提交
97

98
/* ------------------------------------------------------------------------- */
J
jp9000 已提交
99
/* views */
100

J
jp9000 已提交
101
struct obs_view {
102
	pthread_mutex_t                 channels_mutex;
103
	obs_source_t                    *channels[MAX_CHANNELS];
104 105
};

J
jp9000 已提交
106 107
extern bool obs_view_init(struct obs_view *view);
extern void obs_view_free(struct obs_view *view);
108 109 110 111 112 113 114 115


/* ------------------------------------------------------------------------- */
/* displays */

struct obs_display {
	bool                            size_changed;
	uint32_t                        cx, cy;
116
	gs_swapchain_t                  *swap;
117 118
	pthread_mutex_t                 draw_callbacks_mutex;
	DARRAY(struct draw_callback)    draw_callbacks;
119 120 121

	struct obs_display              *next;
	struct obs_display              **prev_next;
122 123 124
};

extern bool obs_display_init(struct obs_display *display,
125
		const struct gs_init_data *graphics_data);
126 127 128
extern void obs_display_free(struct obs_display *display);


129
/* ------------------------------------------------------------------------- */
J
jp9000 已提交
130
/* core */
131

132 133 134 135 136
struct obs_vframe_info {
	uint64_t timestamp;
	int count;
};

137
struct obs_core_video {
138 139 140 141 142
	graphics_t                      *graphics;
	gs_stagesurf_t                  *copy_surfaces[NUM_TEXTURES];
	gs_texture_t                    *render_textures[NUM_TEXTURES];
	gs_texture_t                    *output_textures[NUM_TEXTURES];
	gs_texture_t                    *convert_textures[NUM_TEXTURES];
143 144 145
	bool                            textures_rendered[NUM_TEXTURES];
	bool                            textures_output[NUM_TEXTURES];
	bool                            textures_copied[NUM_TEXTURES];
J
jp9000 已提交
146
	bool                            textures_converted[NUM_TEXTURES];
147
	struct circlebuf                vframe_info_buffer;
148
	gs_effect_t                     *default_effect;
P
Palana 已提交
149
	gs_effect_t                     *default_rect_effect;
150 151
	gs_effect_t                     *solid_effect;
	gs_effect_t                     *conversion_effect;
152 153
	gs_effect_t                     *bicubic_effect;
	gs_effect_t                     *lanczos_effect;
154
	gs_stagesurf_t                  *mapped_surface;
155 156
	int                             cur_texture;

157
	video_t                         *video;
158 159 160
	pthread_t                       video_thread;
	bool                            thread_initialized;

J
jp9000 已提交
161 162 163 164 165 166 167 168 169
	bool                            gpu_conversion;
	const char                      *conversion_tech;
	uint32_t                        conversion_height;
	uint32_t                        plane_offsets[3];
	uint32_t                        plane_sizes[3];
	uint32_t                        plane_linewidth[3];

	uint32_t                        output_width;
	uint32_t                        output_height;
170 171
	uint32_t                        base_width;
	uint32_t                        base_height;
172
	float                           color_matrix[16];
173
	enum obs_scale_type             scale_type;
174 175

	struct obs_display              main_display;
176 177
};

178
struct obs_core_audio {
J
jp9000 已提交
179
	/* TODO: sound output subsystem */
180
	audio_t                         *audio;
J
jp9000 已提交
181 182 183

	float                           user_volume;
	float                           present_volume;
184 185
};

186
/* user sources, output channels, and displays */
187
struct obs_core_data {
188 189 190 191 192 193 194 195
	pthread_mutex_t                 user_sources_mutex;
	DARRAY(struct obs_source*)      user_sources;

	struct obs_source               *first_source;
	struct obs_display              *first_display;
	struct obs_output               *first_output;
	struct obs_encoder              *first_encoder;
	struct obs_service              *first_service;
196 197 198 199 200

	pthread_mutex_t                 sources_mutex;
	pthread_mutex_t                 displays_mutex;
	pthread_mutex_t                 outputs_mutex;
	pthread_mutex_t                 encoders_mutex;
201
	pthread_mutex_t                 services_mutex;
202

J
jp9000 已提交
203
	struct obs_view                 main_view;
204

J
jp9000 已提交
205 206
	volatile long                   active_transitions;

J
jp9000 已提交
207 208
	long long                       unnamed_index;

209
	volatile bool                   valid;
210 211
};

212
struct obs_core {
J
jp9000 已提交
213 214 215
	struct obs_module               *first_module;
	DARRAY(struct obs_module_path)  module_paths;

J
jp9000 已提交
216 217 218 219 220 221 222 223 224
	DARRAY(struct obs_source_info)  input_types;
	DARRAY(struct obs_source_info)  filter_types;
	DARRAY(struct obs_source_info)  transition_types;
	DARRAY(struct obs_output_info)  output_types;
	DARRAY(struct obs_encoder_info) encoder_types;
	DARRAY(struct obs_service_info) service_types;
	DARRAY(struct obs_modal_ui)     modal_ui_callbacks;
	DARRAY(struct obs_modeless_ui)  modeless_ui_callbacks;

225 226
	signal_handler_t                *signals;
	proc_handler_t                  *procs;
227

228 229
	char                            *locale;

230 231
	/* segmented into multiple sub-structures to keep things a bit more
	 * clean and organized */
J
jp9000 已提交
232 233 234
	struct obs_core_video           video;
	struct obs_core_audio           audio;
	struct obs_core_data            data;
J
jp9000 已提交
235 236
};

237
extern struct obs_core *obs;
238

J
jp9000 已提交
239
extern void *obs_video_thread(void *param);
J
jp9000 已提交
240 241 242


/* ------------------------------------------------------------------------- */
243
/* obs shared context data */
J
jp9000 已提交
244

245 246
struct obs_context_data {
	char                            *name;
247
	void                            *data;
248 249 250
	obs_data_t                      *settings;
	signal_handler_t                *signals;
	proc_handler_t                  *procs;
J
jp9000 已提交
251

J
jp9000 已提交
252 253 254
	DARRAY(char*)                   rename_cache;
	pthread_mutex_t                 rename_cache_mutex;

255 256 257 258 259 260 261
	pthread_mutex_t                 *mutex;
	struct obs_context_data         *next;
	struct obs_context_data         **prev_next;
};

extern bool obs_context_data_init(
		struct obs_context_data *context,
262
		obs_data_t              *settings,
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
		const char              *name);
extern void obs_context_data_free(struct obs_context_data *context);

extern void obs_context_data_insert(struct obs_context_data *context,
		pthread_mutex_t *mutex, void *first);
extern void obs_context_data_remove(struct obs_context_data *context);

extern void obs_context_data_setname(struct obs_context_data *context,
		const char *name);


/* ------------------------------------------------------------------------- */
/* sources  */

struct obs_source {
	struct obs_context_data         context;
	struct obs_source_info          info;
	volatile long                   refs;

J
jp9000 已提交
282 283
	/* general exposed flags that can be set for the source */
	uint32_t                        flags;
284
	uint32_t                        default_flags;
J
jp9000 已提交
285

286 287 288
	/* indicates ownership of the info.id buffer */
	bool                            owns_info_id;

289
	/* signals to call the source update in the video thread */
290 291
	bool                            defer_update;

292
	/* ensures show/hide are only called once */
J
jp9000 已提交
293
	volatile long                   show_refs;
294

295
	/* ensures activate/deactivate are only called once */
J
jp9000 已提交
296
	volatile long                   activate_refs;
297

J
jp9000 已提交
298 299 300
	/* used to indicate that the source has been removed and all
	 * references to it should be released (not exactly how I would prefer
	 * to handle things but it's the best option) */
301
	bool                            removed;
J
jp9000 已提交
302 303

	/* timing (if video is present, is based upon video) */
304 305 306 307 308
	volatile bool                   timing_set;
	volatile uint64_t               timing_adjust;
	uint64_t                        next_audio_ts_min;
	uint64_t                        last_frame_ts;
	uint64_t                        last_sys_timestamp;
309
	bool                            async_rendered;
J
jp9000 已提交
310 311

	/* audio */
312 313
	bool                            audio_failed;
	struct resample_info            sample_info;
314 315
	audio_resampler_t               *resampler;
	audio_line_t                    *audio_line;
316
	pthread_mutex_t                 audio_mutex;
317
	struct obs_audio_data           audio_data;
318
	size_t                          audio_storage_size;
319
	float                           base_volume;
J
jp9000 已提交
320 321
	float                           user_volume;
	float                           present_volume;
J
jp9000 已提交
322
	int64_t                         sync_offset;
J
jp9000 已提交
323 324

	/* async video data */
325 326
	gs_texture_t                    *async_texture;
	gs_texrender_t                  *async_convert_texrender;
327
	bool                            async_gpu_conversion;
328
	enum video_format               async_format;
329
	enum gs_color_format            async_texture_format;
330
	float                           async_color_matrix[16];
331 332 333
	bool                            async_full_range;
	float                           async_color_range_min[3];
	float                           async_color_range_max[3];
334
	int                             async_plane_offset[2];
335
	bool                            async_flip;
336
	bool                            async_active;
337
	DARRAY(struct obs_source_frame*)video_frames;
338
	pthread_mutex_t                 video_mutex;
339 340
	uint32_t                        async_width;
	uint32_t                        async_height;
341 342
	uint32_t                        async_convert_width;
	uint32_t                        async_convert_height;
J
jp9000 已提交
343 344

	/* filters */
345 346 347 348
	struct obs_source               *filter_parent;
	struct obs_source               *filter_target;
	DARRAY(struct obs_source*)      filters;
	pthread_mutex_t                 filter_mutex;
349
	gs_texrender_t                  *filter_texrender;
350
	bool                            rendering_filter;
J
jp9000 已提交
351 352
};

353 354
extern const struct obs_source_info *find_source(struct darray *list,
		const char *id);
355
extern bool obs_source_init_context(struct obs_source *source,
356
		obs_data_t *settings, const char *name);
J
jp9000 已提交
357 358 359
extern bool obs_source_init(struct obs_source *source,
		const struct obs_source_info *info);

360 361
extern void obs_source_destroy(struct obs_source *source);

362 363 364 365 366
enum view_type {
	MAIN_VIEW,
	AUX_VIEW
};

367 368 369
extern void obs_source_activate(obs_source_t *source, enum view_type type);
extern void obs_source_deactivate(obs_source_t *source, enum view_type type);
extern void obs_source_video_tick(obs_source_t *source, float seconds);
370 371
extern float obs_source_get_target_volume(obs_source_t *source,
		obs_source_t *target);
J
jp9000 已提交
372 373 374 375 376 377


/* ------------------------------------------------------------------------- */
/* outputs  */

struct obs_output {
378
	struct obs_context_data         context;
379
	struct obs_output_info          info;
380

381 382 383 384
	bool                            received_video;
	bool                            received_audio;
	int64_t                         video_offset;
	int64_t                         audio_offset;
J
jp9000 已提交
385 386
	int64_t                         highest_audio_ts;
	int64_t                         highest_video_ts;
J
jp9000 已提交
387
	pthread_mutex_t                 interleaved_mutex;
388
	DARRAY(struct encoder_packet)   interleaved_packets;
J
jp9000 已提交
389

J
jp9000 已提交
390 391 392 393 394
	int                             reconnect_retry_sec;
	int                             reconnect_retry_max;
	int                             reconnect_retries;
	bool                            reconnecting;
	pthread_t                       reconnect_thread;
395
	os_event_t                      *reconnect_stop_event;
J
jp9000 已提交
396 397
	volatile bool                   reconnect_thread_active;

J
jp9000 已提交
398 399 400
	uint32_t                        starting_frame_count;
	uint32_t                        starting_skipped_frame_count;

401 402
	int                             total_frames;

J
jp9000 已提交
403
	bool                            active;
404
	volatile bool                   stopped;
405 406 407 408 409
	video_t                         *video;
	audio_t                         *audio;
	obs_encoder_t                   *video_encoder;
	obs_encoder_t                   *audio_encoder;
	obs_service_t                   *service;
J
jp9000 已提交
410

411 412 413
	uint32_t                        scaled_width;
	uint32_t                        scaled_height;

J
jp9000 已提交
414 415 416 417 418
	bool                            video_conversion_set;
	bool                            audio_conversion_set;
	struct video_scale_info         video_conversion;
	struct audio_convert_info       audio_conversion;

419
	bool                            valid;
J
jp9000 已提交
420 421
};

422 423
extern const struct obs_output_info *find_output(const char *id);

J
jp9000 已提交
424 425 426
extern void obs_output_remove_encoder(struct obs_output *output,
		struct obs_encoder *encoder);

J
jp9000 已提交
427 428 429 430

/* ------------------------------------------------------------------------- */
/* encoders  */

431
struct encoder_callback {
432
	bool sent_first_packet;
J
jp9000 已提交
433 434 435 436 437
	void (*new_packet)(void *param, struct encoder_packet *packet);
	void *param;
};

struct obs_encoder {
438
	struct obs_context_data         context;
439
	struct obs_encoder_info         info;
J
jp9000 已提交
440

441 442 443 444 445 446
	uint32_t                        samplerate;
	size_t                          planes;
	size_t                          blocksize;
	size_t                          framesize;
	size_t                          framesize_bytes;

447 448 449
	uint32_t                        scaled_width;
	uint32_t                        scaled_height;

J
jp9000 已提交
450 451
	bool                            active;

452 453 454 455 456
	uint32_t                        timebase_num;
	uint32_t                        timebase_den;

	int64_t                         cur_pts;

457 458 459 460 461 462 463 464 465 466 467
	struct circlebuf                audio_input_buffer[MAX_AV_PLANES];
	uint8_t                         *audio_output_buffer[MAX_AV_PLANES];

	/* if a video encoder is paired with an audio encoder, make it start
	 * up at the specific timestamp.  if this is the audio encoder,
	 * wait_for_video makes it wait until it's ready to sync up with
	 * video */
	bool                            wait_for_video;
	struct obs_encoder              *paired_encoder;
	uint64_t                        start_ts;

J
jp9000 已提交
468
	pthread_mutex_t                 outputs_mutex;
469
	DARRAY(obs_output_t*)            outputs;
J
jp9000 已提交
470 471 472

	bool                            destroy_on_stop;

473
	/* stores the video/audio media output pointer.  video_t *or audio_t **/
J
jp9000 已提交
474
	void                            *media;
475 476 477

	pthread_mutex_t                 callbacks_mutex;
	DARRAY(struct encoder_callback) callbacks;
J
jp9000 已提交
478
};
J
jp9000 已提交
479

480 481
extern struct obs_encoder_info *find_encoder(const char *id);

482
extern bool obs_encoder_initialize(obs_encoder_t *encoder);
483

484
extern void obs_encoder_start(obs_encoder_t *encoder,
485 486
		void (*new_packet)(void *param, struct encoder_packet *packet),
		void *param);
487
extern void obs_encoder_stop(obs_encoder_t *encoder,
488 489 490
		void (*new_packet)(void *param, struct encoder_packet *packet),
		void *param);

J
jp9000 已提交
491 492 493 494
extern void obs_encoder_add_output(struct obs_encoder *encoder,
		struct obs_output *output);
extern void obs_encoder_remove_output(struct obs_encoder *encoder,
		struct obs_output *output);
495 496 497 498 499 500 501

/* ------------------------------------------------------------------------- */
/* services */

struct obs_service {
	struct obs_context_data         context;
	struct obs_service_info         info;
502 503 504 505

	bool                            active;
	bool                            destroy;
	struct obs_output               *output;
506
};
507

508 509
extern const struct obs_service_info *find_service(const char *id);

510 511 512 513
extern void obs_service_activate(struct obs_service *service);
extern void obs_service_deactivate(struct obs_service *service, bool remove);
extern bool obs_service_initialize(struct obs_service *service,
		struct obs_output *output);