1 /******************************************************************************
2     Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com>
3 
4     This program is free software: you can redistribute it and/or modify
5     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
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 ******************************************************************************/
17 
18 #include "obs.h"
19 #include "obs-internal.h"
20 #include "util/util_uint64.h"
21 
22 #define encoder_active(encoder) os_atomic_load_bool(&encoder->active)
23 #define set_encoder_active(encoder, val) \
24 	os_atomic_set_bool(&encoder->active, val)
25 
find_encoder(const char * id)26 struct obs_encoder_info *find_encoder(const char *id)
27 {
28 	for (size_t i = 0; i < obs->encoder_types.num; i++) {
29 		struct obs_encoder_info *info = obs->encoder_types.array + i;
30 
31 		if (strcmp(info->id, id) == 0)
32 			return info;
33 	}
34 
35 	return NULL;
36 }
37 
obs_encoder_get_display_name(const char * id)38 const char *obs_encoder_get_display_name(const char *id)
39 {
40 	struct obs_encoder_info *ei = find_encoder(id);
41 	return ei ? ei->get_name(ei->type_data) : NULL;
42 }
43 
init_encoder(struct obs_encoder * encoder,const char * name,obs_data_t * settings,obs_data_t * hotkey_data)44 static bool init_encoder(struct obs_encoder *encoder, const char *name,
45 			 obs_data_t *settings, obs_data_t *hotkey_data)
46 {
47 	pthread_mutex_init_value(&encoder->init_mutex);
48 	pthread_mutex_init_value(&encoder->callbacks_mutex);
49 	pthread_mutex_init_value(&encoder->outputs_mutex);
50 	pthread_mutex_init_value(&encoder->pause.mutex);
51 
52 	if (!obs_context_data_init(&encoder->context, OBS_OBJ_TYPE_ENCODER,
53 				   settings, name, hotkey_data, false))
54 		return false;
55 	if (pthread_mutex_init_recursive(&encoder->init_mutex) != 0)
56 		return false;
57 	if (pthread_mutex_init_recursive(&encoder->callbacks_mutex) != 0)
58 		return false;
59 	if (pthread_mutex_init(&encoder->outputs_mutex, NULL) != 0)
60 		return false;
61 	if (pthread_mutex_init(&encoder->pause.mutex, NULL) != 0)
62 		return false;
63 
64 	if (encoder->orig_info.get_defaults) {
65 		encoder->orig_info.get_defaults(encoder->context.settings);
66 	}
67 	if (encoder->orig_info.get_defaults2) {
68 		encoder->orig_info.get_defaults2(encoder->context.settings,
69 						 encoder->orig_info.type_data);
70 	}
71 
72 	return true;
73 }
74 
75 static struct obs_encoder *
create_encoder(const char * id,enum obs_encoder_type type,const char * name,obs_data_t * settings,size_t mixer_idx,obs_data_t * hotkey_data)76 create_encoder(const char *id, enum obs_encoder_type type, const char *name,
77 	       obs_data_t *settings, size_t mixer_idx, obs_data_t *hotkey_data)
78 {
79 	struct obs_encoder *encoder;
80 	struct obs_encoder_info *ei = find_encoder(id);
81 	bool success;
82 
83 	if (ei && ei->type != type)
84 		return NULL;
85 
86 	encoder = bzalloc(sizeof(struct obs_encoder));
87 	encoder->mixer_idx = mixer_idx;
88 
89 	if (!ei) {
90 		blog(LOG_ERROR, "Encoder ID '%s' not found", id);
91 
92 		encoder->info.id = bstrdup(id);
93 		encoder->info.type = type;
94 		encoder->owns_info_id = true;
95 		encoder->orig_info = encoder->info;
96 	} else {
97 		encoder->info = *ei;
98 		encoder->orig_info = *ei;
99 	}
100 
101 	success = init_encoder(encoder, name, settings, hotkey_data);
102 	if (!success) {
103 		blog(LOG_ERROR, "creating encoder '%s' (%s) failed", name, id);
104 		obs_encoder_destroy(encoder);
105 		return NULL;
106 	}
107 
108 	encoder->control = bzalloc(sizeof(obs_weak_encoder_t));
109 	encoder->control->encoder = encoder;
110 
111 	obs_context_data_insert(&encoder->context, &obs->data.encoders_mutex,
112 				&obs->data.first_encoder);
113 
114 	blog(LOG_DEBUG, "encoder '%s' (%s) created", name, id);
115 	return encoder;
116 }
117 
obs_video_encoder_create(const char * id,const char * name,obs_data_t * settings,obs_data_t * hotkey_data)118 obs_encoder_t *obs_video_encoder_create(const char *id, const char *name,
119 					obs_data_t *settings,
120 					obs_data_t *hotkey_data)
121 {
122 	if (!name || !id)
123 		return NULL;
124 	return create_encoder(id, OBS_ENCODER_VIDEO, name, settings, 0,
125 			      hotkey_data);
126 }
127 
obs_audio_encoder_create(const char * id,const char * name,obs_data_t * settings,size_t mixer_idx,obs_data_t * hotkey_data)128 obs_encoder_t *obs_audio_encoder_create(const char *id, const char *name,
129 					obs_data_t *settings, size_t mixer_idx,
130 					obs_data_t *hotkey_data)
131 {
132 	if (!name || !id)
133 		return NULL;
134 	return create_encoder(id, OBS_ENCODER_AUDIO, name, settings, mixer_idx,
135 			      hotkey_data);
136 }
137 
138 static void receive_video(void *param, struct video_data *frame);
139 static void receive_audio(void *param, size_t mix_idx, struct audio_data *data);
140 
get_audio_info(const struct obs_encoder * encoder,struct audio_convert_info * info)141 static inline void get_audio_info(const struct obs_encoder *encoder,
142 				  struct audio_convert_info *info)
143 {
144 	const struct audio_output_info *aoi;
145 	aoi = audio_output_get_info(encoder->media);
146 
147 	if (info->format == AUDIO_FORMAT_UNKNOWN)
148 		info->format = aoi->format;
149 	if (!info->samples_per_sec)
150 		info->samples_per_sec = aoi->samples_per_sec;
151 	if (info->speakers == SPEAKERS_UNKNOWN)
152 		info->speakers = aoi->speakers;
153 
154 	if (encoder->info.get_audio_info)
155 		encoder->info.get_audio_info(encoder->context.data, info);
156 }
157 
get_video_info(struct obs_encoder * encoder,struct video_scale_info * info)158 static inline void get_video_info(struct obs_encoder *encoder,
159 				  struct video_scale_info *info)
160 {
161 	const struct video_output_info *voi;
162 	voi = video_output_get_info(encoder->media);
163 
164 	info->format = voi->format;
165 	info->colorspace = voi->colorspace;
166 	info->range = voi->range;
167 	info->width = obs_encoder_get_width(encoder);
168 	info->height = obs_encoder_get_height(encoder);
169 
170 	if (encoder->info.get_video_info)
171 		encoder->info.get_video_info(encoder->context.data, info);
172 
173 	if (info->width != voi->width || info->height != voi->height)
174 		obs_encoder_set_scaled_size(encoder, info->width, info->height);
175 }
176 
has_scaling(const struct obs_encoder * encoder)177 static inline bool has_scaling(const struct obs_encoder *encoder)
178 {
179 	uint32_t video_width = video_output_get_width(encoder->media);
180 	uint32_t video_height = video_output_get_height(encoder->media);
181 
182 	return encoder->scaled_width && encoder->scaled_height &&
183 	       (video_width != encoder->scaled_width ||
184 		video_height != encoder->scaled_height);
185 }
186 
gpu_encode_available(const struct obs_encoder * encoder)187 static inline bool gpu_encode_available(const struct obs_encoder *encoder)
188 {
189 	return (encoder->info.caps & OBS_ENCODER_CAP_PASS_TEXTURE) != 0 &&
190 	       obs->video.using_nv12_tex;
191 }
192 
add_connection(struct obs_encoder * encoder)193 static void add_connection(struct obs_encoder *encoder)
194 {
195 	if (encoder->info.type == OBS_ENCODER_AUDIO) {
196 		struct audio_convert_info audio_info = {0};
197 		get_audio_info(encoder, &audio_info);
198 
199 		audio_output_connect(encoder->media, encoder->mixer_idx,
200 				     &audio_info, receive_audio, encoder);
201 	} else {
202 		struct video_scale_info info = {0};
203 		get_video_info(encoder, &info);
204 
205 		if (gpu_encode_available(encoder)) {
206 			start_gpu_encode(encoder);
207 		} else {
208 			start_raw_video(encoder->media, &info, receive_video,
209 					encoder);
210 		}
211 	}
212 
213 	set_encoder_active(encoder, true);
214 }
215 
remove_connection(struct obs_encoder * encoder,bool shutdown)216 static void remove_connection(struct obs_encoder *encoder, bool shutdown)
217 {
218 	if (encoder->info.type == OBS_ENCODER_AUDIO) {
219 		audio_output_disconnect(encoder->media, encoder->mixer_idx,
220 					receive_audio, encoder);
221 	} else {
222 		if (gpu_encode_available(encoder)) {
223 			stop_gpu_encode(encoder);
224 		} else {
225 			stop_raw_video(encoder->media, receive_video, encoder);
226 		}
227 	}
228 
229 	/* obs_encoder_shutdown locks init_mutex, so don't call it on encode
230 	 * errors, otherwise you can get a deadlock with outputs when they end
231 	 * data capture, which will lock init_mutex and the video callback
232 	 * mutex in the reverse order.  instead, call shutdown before starting
233 	 * up again */
234 	if (shutdown)
235 		obs_encoder_shutdown(encoder);
236 	set_encoder_active(encoder, false);
237 }
238 
free_audio_buffers(struct obs_encoder * encoder)239 static inline void free_audio_buffers(struct obs_encoder *encoder)
240 {
241 	for (size_t i = 0; i < MAX_AV_PLANES; i++) {
242 		circlebuf_free(&encoder->audio_input_buffer[i]);
243 		bfree(encoder->audio_output_buffer[i]);
244 		encoder->audio_output_buffer[i] = NULL;
245 	}
246 }
247 
obs_encoder_actually_destroy(obs_encoder_t * encoder)248 static void obs_encoder_actually_destroy(obs_encoder_t *encoder)
249 {
250 	if (encoder) {
251 		pthread_mutex_lock(&encoder->outputs_mutex);
252 		for (size_t i = 0; i < encoder->outputs.num; i++) {
253 			struct obs_output *output = encoder->outputs.array[i];
254 			obs_output_remove_encoder(output, encoder);
255 		}
256 		da_free(encoder->outputs);
257 		pthread_mutex_unlock(&encoder->outputs_mutex);
258 
259 		blog(LOG_DEBUG, "encoder '%s' destroyed",
260 		     encoder->context.name);
261 
262 		free_audio_buffers(encoder);
263 
264 		if (encoder->context.data)
265 			encoder->info.destroy(encoder->context.data);
266 		da_free(encoder->callbacks);
267 		pthread_mutex_destroy(&encoder->init_mutex);
268 		pthread_mutex_destroy(&encoder->callbacks_mutex);
269 		pthread_mutex_destroy(&encoder->outputs_mutex);
270 		pthread_mutex_destroy(&encoder->pause.mutex);
271 		obs_context_data_free(&encoder->context);
272 		if (encoder->owns_info_id)
273 			bfree((void *)encoder->info.id);
274 		if (encoder->last_error_message)
275 			bfree(encoder->last_error_message);
276 		bfree(encoder);
277 	}
278 }
279 
280 /* does not actually destroy the encoder until all connections to it have been
281  * removed. (full reference counting really would have been superfluous) */
obs_encoder_destroy(obs_encoder_t * encoder)282 void obs_encoder_destroy(obs_encoder_t *encoder)
283 {
284 	if (encoder) {
285 		bool destroy;
286 
287 		obs_context_data_remove(&encoder->context);
288 
289 		pthread_mutex_lock(&encoder->init_mutex);
290 		pthread_mutex_lock(&encoder->callbacks_mutex);
291 		destroy = encoder->callbacks.num == 0;
292 		if (!destroy)
293 			encoder->destroy_on_stop = true;
294 		pthread_mutex_unlock(&encoder->callbacks_mutex);
295 		pthread_mutex_unlock(&encoder->init_mutex);
296 
297 		if (destroy)
298 			obs_encoder_actually_destroy(encoder);
299 	}
300 }
301 
obs_encoder_get_name(const obs_encoder_t * encoder)302 const char *obs_encoder_get_name(const obs_encoder_t *encoder)
303 {
304 	return obs_encoder_valid(encoder, "obs_encoder_get_name")
305 		       ? encoder->context.name
306 		       : NULL;
307 }
308 
obs_encoder_set_name(obs_encoder_t * encoder,const char * name)309 void obs_encoder_set_name(obs_encoder_t *encoder, const char *name)
310 {
311 	if (!obs_encoder_valid(encoder, "obs_encoder_set_name"))
312 		return;
313 
314 	if (name && *name && strcmp(name, encoder->context.name) != 0)
315 		obs_context_data_setname(&encoder->context, name);
316 }
317 
get_defaults(const struct obs_encoder_info * info)318 static inline obs_data_t *get_defaults(const struct obs_encoder_info *info)
319 {
320 	obs_data_t *settings = obs_data_create();
321 	if (info->get_defaults) {
322 		info->get_defaults(settings);
323 	}
324 	if (info->get_defaults2) {
325 		info->get_defaults2(settings, info->type_data);
326 	}
327 	return settings;
328 }
329 
obs_encoder_defaults(const char * id)330 obs_data_t *obs_encoder_defaults(const char *id)
331 {
332 	const struct obs_encoder_info *info = find_encoder(id);
333 	return (info) ? get_defaults(info) : NULL;
334 }
335 
obs_encoder_get_defaults(const obs_encoder_t * encoder)336 obs_data_t *obs_encoder_get_defaults(const obs_encoder_t *encoder)
337 {
338 	if (!obs_encoder_valid(encoder, "obs_encoder_defaults"))
339 		return NULL;
340 
341 	return get_defaults(&encoder->info);
342 }
343 
obs_get_encoder_properties(const char * id)344 obs_properties_t *obs_get_encoder_properties(const char *id)
345 {
346 	const struct obs_encoder_info *ei = find_encoder(id);
347 	if (ei && (ei->get_properties || ei->get_properties2)) {
348 		obs_data_t *defaults = get_defaults(ei);
349 		obs_properties_t *properties = NULL;
350 
351 		if (ei->get_properties2) {
352 			properties = ei->get_properties2(NULL, ei->type_data);
353 		} else if (ei->get_properties) {
354 			properties = ei->get_properties(NULL);
355 		}
356 
357 		obs_properties_apply_settings(properties, defaults);
358 		obs_data_release(defaults);
359 		return properties;
360 	}
361 	return NULL;
362 }
363 
obs_encoder_properties(const obs_encoder_t * encoder)364 obs_properties_t *obs_encoder_properties(const obs_encoder_t *encoder)
365 {
366 	if (!obs_encoder_valid(encoder, "obs_encoder_properties"))
367 		return NULL;
368 
369 	if (encoder->orig_info.get_properties2) {
370 		obs_properties_t *props;
371 		props = encoder->orig_info.get_properties2(
372 			encoder->context.data, encoder->orig_info.type_data);
373 		obs_properties_apply_settings(props, encoder->context.settings);
374 		return props;
375 
376 	} else if (encoder->orig_info.get_properties) {
377 		obs_properties_t *props;
378 		props = encoder->orig_info.get_properties(
379 			encoder->context.data);
380 		obs_properties_apply_settings(props, encoder->context.settings);
381 		return props;
382 	}
383 
384 	return NULL;
385 }
386 
obs_encoder_update(obs_encoder_t * encoder,obs_data_t * settings)387 void obs_encoder_update(obs_encoder_t *encoder, obs_data_t *settings)
388 {
389 	if (!obs_encoder_valid(encoder, "obs_encoder_update"))
390 		return;
391 
392 	obs_data_apply(encoder->context.settings, settings);
393 
394 	// Note, we don't actually apply the changes to the encoder here
395 	// as it may be active in another thread. Setting this to true
396 	// makes the changes apply at the next possible moment in the
397 	// encoder / GPU encoder thread.
398 	if (encoder->info.update)
399 		encoder->reconfigure_requested = true;
400 }
401 
obs_encoder_get_extra_data(const obs_encoder_t * encoder,uint8_t ** extra_data,size_t * size)402 bool obs_encoder_get_extra_data(const obs_encoder_t *encoder,
403 				uint8_t **extra_data, size_t *size)
404 {
405 	if (!obs_encoder_valid(encoder, "obs_encoder_get_extra_data"))
406 		return false;
407 
408 	if (encoder->info.get_extra_data && encoder->context.data)
409 		return encoder->info.get_extra_data(encoder->context.data,
410 						    extra_data, size);
411 
412 	return false;
413 }
414 
obs_encoder_get_settings(const obs_encoder_t * encoder)415 obs_data_t *obs_encoder_get_settings(const obs_encoder_t *encoder)
416 {
417 	if (!obs_encoder_valid(encoder, "obs_encoder_get_settings"))
418 		return NULL;
419 
420 	obs_data_addref(encoder->context.settings);
421 	return encoder->context.settings;
422 }
423 
reset_audio_buffers(struct obs_encoder * encoder)424 static inline void reset_audio_buffers(struct obs_encoder *encoder)
425 {
426 	free_audio_buffers(encoder);
427 
428 	for (size_t i = 0; i < encoder->planes; i++)
429 		encoder->audio_output_buffer[i] =
430 			bmalloc(encoder->framesize_bytes);
431 }
432 
intitialize_audio_encoder(struct obs_encoder * encoder)433 static void intitialize_audio_encoder(struct obs_encoder *encoder)
434 {
435 	struct audio_convert_info info = {0};
436 	get_audio_info(encoder, &info);
437 
438 	encoder->samplerate = info.samples_per_sec;
439 	encoder->planes = get_audio_planes(info.format, info.speakers);
440 	encoder->blocksize = get_audio_size(info.format, info.speakers, 1);
441 	encoder->framesize =
442 		encoder->info.get_frame_size(encoder->context.data);
443 
444 	encoder->framesize_bytes = encoder->blocksize * encoder->framesize;
445 	reset_audio_buffers(encoder);
446 }
447 
448 static THREAD_LOCAL bool can_reroute = false;
449 
obs_encoder_initialize_internal(obs_encoder_t * encoder)450 static inline bool obs_encoder_initialize_internal(obs_encoder_t *encoder)
451 {
452 	if (encoder_active(encoder))
453 		return true;
454 	if (encoder->initialized)
455 		return true;
456 
457 	obs_encoder_shutdown(encoder);
458 
459 	if (encoder->orig_info.create) {
460 		can_reroute = true;
461 		encoder->info = encoder->orig_info;
462 		encoder->context.data = encoder->orig_info.create(
463 			encoder->context.settings, encoder);
464 		can_reroute = false;
465 	}
466 	if (!encoder->context.data)
467 		return false;
468 
469 	if (encoder->orig_info.type == OBS_ENCODER_AUDIO)
470 		intitialize_audio_encoder(encoder);
471 
472 	encoder->initialized = true;
473 	return true;
474 }
475 
obs_encoder_create_rerouted(obs_encoder_t * encoder,const char * reroute_id)476 void *obs_encoder_create_rerouted(obs_encoder_t *encoder,
477 				  const char *reroute_id)
478 {
479 	if (!obs_ptr_valid(encoder, "obs_encoder_reroute"))
480 		return NULL;
481 	if (!obs_ptr_valid(reroute_id, "obs_encoder_reroute"))
482 		return NULL;
483 	if (!can_reroute)
484 		return NULL;
485 
486 	const struct obs_encoder_info *ei = find_encoder(reroute_id);
487 	if (ei) {
488 		if (ei->type != encoder->orig_info.type ||
489 		    astrcmpi(ei->codec, encoder->orig_info.codec) != 0) {
490 			return NULL;
491 		}
492 		encoder->info = *ei;
493 		return encoder->info.create(encoder->context.settings, encoder);
494 	}
495 
496 	return NULL;
497 }
498 
obs_encoder_initialize(obs_encoder_t * encoder)499 bool obs_encoder_initialize(obs_encoder_t *encoder)
500 {
501 	bool success;
502 
503 	if (!encoder)
504 		return false;
505 
506 	pthread_mutex_lock(&encoder->init_mutex);
507 	success = obs_encoder_initialize_internal(encoder);
508 	pthread_mutex_unlock(&encoder->init_mutex);
509 
510 	return success;
511 }
512 
obs_encoder_shutdown(obs_encoder_t * encoder)513 void obs_encoder_shutdown(obs_encoder_t *encoder)
514 {
515 	pthread_mutex_lock(&encoder->init_mutex);
516 	if (encoder->context.data) {
517 		encoder->info.destroy(encoder->context.data);
518 		encoder->context.data = NULL;
519 		encoder->paired_encoder = NULL;
520 		encoder->first_received = false;
521 		encoder->offset_usec = 0;
522 		encoder->start_ts = 0;
523 	}
524 	obs_encoder_set_last_error(encoder, NULL);
525 	pthread_mutex_unlock(&encoder->init_mutex);
526 }
527 
528 static inline size_t
get_callback_idx(const struct obs_encoder * encoder,void (* new_packet)(void * param,struct encoder_packet * packet),void * param)529 get_callback_idx(const struct obs_encoder *encoder,
530 		 void (*new_packet)(void *param, struct encoder_packet *packet),
531 		 void *param)
532 {
533 	for (size_t i = 0; i < encoder->callbacks.num; i++) {
534 		struct encoder_callback *cb = encoder->callbacks.array + i;
535 
536 		if (cb->new_packet == new_packet && cb->param == param)
537 			return i;
538 	}
539 
540 	return DARRAY_INVALID;
541 }
542 
pause_reset(struct pause_data * pause)543 void pause_reset(struct pause_data *pause)
544 {
545 	pthread_mutex_lock(&pause->mutex);
546 	pause->last_video_ts = 0;
547 	pause->ts_start = 0;
548 	pause->ts_end = 0;
549 	pause->ts_offset = 0;
550 	pthread_mutex_unlock(&pause->mutex);
551 }
552 
obs_encoder_start_internal(obs_encoder_t * encoder,void (* new_packet)(void * param,struct encoder_packet * packet),void * param)553 static inline void obs_encoder_start_internal(
554 	obs_encoder_t *encoder,
555 	void (*new_packet)(void *param, struct encoder_packet *packet),
556 	void *param)
557 {
558 	struct encoder_callback cb = {false, new_packet, param};
559 	bool first = false;
560 
561 	if (!encoder->context.data)
562 		return;
563 
564 	pthread_mutex_lock(&encoder->callbacks_mutex);
565 
566 	first = (encoder->callbacks.num == 0);
567 
568 	size_t idx = get_callback_idx(encoder, new_packet, param);
569 	if (idx == DARRAY_INVALID)
570 		da_push_back(encoder->callbacks, &cb);
571 
572 	pthread_mutex_unlock(&encoder->callbacks_mutex);
573 
574 	if (first) {
575 		os_atomic_set_bool(&encoder->paused, false);
576 		pause_reset(&encoder->pause);
577 
578 		encoder->cur_pts = 0;
579 		add_connection(encoder);
580 	}
581 }
582 
obs_encoder_start(obs_encoder_t * encoder,void (* new_packet)(void * param,struct encoder_packet * packet),void * param)583 void obs_encoder_start(obs_encoder_t *encoder,
584 		       void (*new_packet)(void *param,
585 					  struct encoder_packet *packet),
586 		       void *param)
587 {
588 	if (!obs_encoder_valid(encoder, "obs_encoder_start"))
589 		return;
590 	if (!obs_ptr_valid(new_packet, "obs_encoder_start"))
591 		return;
592 
593 	pthread_mutex_lock(&encoder->init_mutex);
594 	obs_encoder_start_internal(encoder, new_packet, param);
595 	pthread_mutex_unlock(&encoder->init_mutex);
596 }
597 
obs_encoder_stop_internal(obs_encoder_t * encoder,void (* new_packet)(void * param,struct encoder_packet * packet),void * param)598 static inline bool obs_encoder_stop_internal(
599 	obs_encoder_t *encoder,
600 	void (*new_packet)(void *param, struct encoder_packet *packet),
601 	void *param)
602 {
603 	bool last = false;
604 	size_t idx;
605 
606 	pthread_mutex_lock(&encoder->callbacks_mutex);
607 
608 	idx = get_callback_idx(encoder, new_packet, param);
609 	if (idx != DARRAY_INVALID) {
610 		da_erase(encoder->callbacks, idx);
611 		last = (encoder->callbacks.num == 0);
612 	}
613 
614 	pthread_mutex_unlock(&encoder->callbacks_mutex);
615 
616 	if (last) {
617 		remove_connection(encoder, true);
618 		encoder->initialized = false;
619 
620 		if (encoder->destroy_on_stop) {
621 			pthread_mutex_unlock(&encoder->init_mutex);
622 			obs_encoder_actually_destroy(encoder);
623 			return true;
624 		}
625 	}
626 
627 	return false;
628 }
629 
obs_encoder_stop(obs_encoder_t * encoder,void (* new_packet)(void * param,struct encoder_packet * packet),void * param)630 void obs_encoder_stop(obs_encoder_t *encoder,
631 		      void (*new_packet)(void *param,
632 					 struct encoder_packet *packet),
633 		      void *param)
634 {
635 	bool destroyed;
636 
637 	if (!obs_encoder_valid(encoder, "obs_encoder_stop"))
638 		return;
639 	if (!obs_ptr_valid(new_packet, "obs_encoder_stop"))
640 		return;
641 
642 	pthread_mutex_lock(&encoder->init_mutex);
643 	destroyed = obs_encoder_stop_internal(encoder, new_packet, param);
644 	if (!destroyed)
645 		pthread_mutex_unlock(&encoder->init_mutex);
646 }
647 
obs_encoder_get_codec(const obs_encoder_t * encoder)648 const char *obs_encoder_get_codec(const obs_encoder_t *encoder)
649 {
650 	return obs_encoder_valid(encoder, "obs_encoder_get_codec")
651 		       ? encoder->info.codec
652 		       : NULL;
653 }
654 
obs_get_encoder_codec(const char * id)655 const char *obs_get_encoder_codec(const char *id)
656 {
657 	struct obs_encoder_info *info = find_encoder(id);
658 	return info ? info->codec : NULL;
659 }
660 
obs_encoder_get_type(const obs_encoder_t * encoder)661 enum obs_encoder_type obs_encoder_get_type(const obs_encoder_t *encoder)
662 {
663 	return obs_encoder_valid(encoder, "obs_encoder_get_type")
664 		       ? encoder->info.type
665 		       : OBS_ENCODER_AUDIO;
666 }
667 
obs_get_encoder_type(const char * id)668 enum obs_encoder_type obs_get_encoder_type(const char *id)
669 {
670 	struct obs_encoder_info *info = find_encoder(id);
671 	return info ? info->type : OBS_ENCODER_AUDIO;
672 }
673 
obs_encoder_set_scaled_size(obs_encoder_t * encoder,uint32_t width,uint32_t height)674 void obs_encoder_set_scaled_size(obs_encoder_t *encoder, uint32_t width,
675 				 uint32_t height)
676 {
677 	if (!obs_encoder_valid(encoder, "obs_encoder_set_scaled_size"))
678 		return;
679 	if (encoder->info.type != OBS_ENCODER_VIDEO) {
680 		blog(LOG_WARNING,
681 		     "obs_encoder_set_scaled_size: "
682 		     "encoder '%s' is not a video encoder",
683 		     obs_encoder_get_name(encoder));
684 		return;
685 	}
686 	if (encoder_active(encoder)) {
687 		blog(LOG_WARNING,
688 		     "encoder '%s': Cannot set the scaled "
689 		     "resolution while the encoder is active",
690 		     obs_encoder_get_name(encoder));
691 		return;
692 	}
693 
694 	encoder->scaled_width = width;
695 	encoder->scaled_height = height;
696 }
697 
obs_encoder_scaling_enabled(const obs_encoder_t * encoder)698 bool obs_encoder_scaling_enabled(const obs_encoder_t *encoder)
699 {
700 	if (!obs_encoder_valid(encoder, "obs_encoder_scaling_enabled"))
701 		return false;
702 
703 	return encoder->scaled_width || encoder->scaled_height;
704 }
705 
obs_encoder_get_width(const obs_encoder_t * encoder)706 uint32_t obs_encoder_get_width(const obs_encoder_t *encoder)
707 {
708 	if (!obs_encoder_valid(encoder, "obs_encoder_get_width"))
709 		return 0;
710 	if (encoder->info.type != OBS_ENCODER_VIDEO) {
711 		blog(LOG_WARNING,
712 		     "obs_encoder_get_width: "
713 		     "encoder '%s' is not a video encoder",
714 		     obs_encoder_get_name(encoder));
715 		return 0;
716 	}
717 	if (!encoder->media)
718 		return 0;
719 
720 	return encoder->scaled_width != 0
721 		       ? encoder->scaled_width
722 		       : video_output_get_width(encoder->media);
723 }
724 
obs_encoder_get_height(const obs_encoder_t * encoder)725 uint32_t obs_encoder_get_height(const obs_encoder_t *encoder)
726 {
727 	if (!obs_encoder_valid(encoder, "obs_encoder_get_height"))
728 		return 0;
729 	if (encoder->info.type != OBS_ENCODER_VIDEO) {
730 		blog(LOG_WARNING,
731 		     "obs_encoder_get_height: "
732 		     "encoder '%s' is not a video encoder",
733 		     obs_encoder_get_name(encoder));
734 		return 0;
735 	}
736 	if (!encoder->media)
737 		return 0;
738 
739 	return encoder->scaled_height != 0
740 		       ? encoder->scaled_height
741 		       : video_output_get_height(encoder->media);
742 }
743 
obs_encoder_get_sample_rate(const obs_encoder_t * encoder)744 uint32_t obs_encoder_get_sample_rate(const obs_encoder_t *encoder)
745 {
746 	if (!obs_encoder_valid(encoder, "obs_encoder_get_sample_rate"))
747 		return 0;
748 	if (encoder->info.type != OBS_ENCODER_AUDIO) {
749 		blog(LOG_WARNING,
750 		     "obs_encoder_get_sample_rate: "
751 		     "encoder '%s' is not an audio encoder",
752 		     obs_encoder_get_name(encoder));
753 		return 0;
754 	}
755 	if (!encoder->media)
756 		return 0;
757 
758 	return encoder->samplerate != 0
759 		       ? encoder->samplerate
760 		       : audio_output_get_sample_rate(encoder->media);
761 }
762 
obs_encoder_set_video(obs_encoder_t * encoder,video_t * video)763 void obs_encoder_set_video(obs_encoder_t *encoder, video_t *video)
764 {
765 	const struct video_output_info *voi;
766 
767 	if (!obs_encoder_valid(encoder, "obs_encoder_set_video"))
768 		return;
769 	if (encoder->info.type != OBS_ENCODER_VIDEO) {
770 		blog(LOG_WARNING,
771 		     "obs_encoder_set_video: "
772 		     "encoder '%s' is not a video encoder",
773 		     obs_encoder_get_name(encoder));
774 		return;
775 	}
776 	if (!video)
777 		return;
778 
779 	voi = video_output_get_info(video);
780 
781 	encoder->media = video;
782 	encoder->timebase_num = voi->fps_den;
783 	encoder->timebase_den = voi->fps_num;
784 }
785 
obs_encoder_set_audio(obs_encoder_t * encoder,audio_t * audio)786 void obs_encoder_set_audio(obs_encoder_t *encoder, audio_t *audio)
787 {
788 	if (!obs_encoder_valid(encoder, "obs_encoder_set_audio"))
789 		return;
790 	if (encoder->info.type != OBS_ENCODER_AUDIO) {
791 		blog(LOG_WARNING,
792 		     "obs_encoder_set_audio: "
793 		     "encoder '%s' is not an audio encoder",
794 		     obs_encoder_get_name(encoder));
795 		return;
796 	}
797 	if (!audio)
798 		return;
799 
800 	encoder->media = audio;
801 	encoder->timebase_num = 1;
802 	encoder->timebase_den = audio_output_get_sample_rate(audio);
803 }
804 
obs_encoder_video(const obs_encoder_t * encoder)805 video_t *obs_encoder_video(const obs_encoder_t *encoder)
806 {
807 	if (!obs_encoder_valid(encoder, "obs_encoder_video"))
808 		return NULL;
809 	if (encoder->info.type != OBS_ENCODER_VIDEO) {
810 		blog(LOG_WARNING,
811 		     "obs_encoder_set_video: "
812 		     "encoder '%s' is not a video encoder",
813 		     obs_encoder_get_name(encoder));
814 		return NULL;
815 	}
816 
817 	return encoder->media;
818 }
819 
obs_encoder_audio(const obs_encoder_t * encoder)820 audio_t *obs_encoder_audio(const obs_encoder_t *encoder)
821 {
822 	if (!obs_encoder_valid(encoder, "obs_encoder_audio"))
823 		return NULL;
824 	if (encoder->info.type != OBS_ENCODER_AUDIO) {
825 		blog(LOG_WARNING,
826 		     "obs_encoder_set_audio: "
827 		     "encoder '%s' is not an audio encoder",
828 		     obs_encoder_get_name(encoder));
829 		return NULL;
830 	}
831 
832 	return encoder->media;
833 }
834 
obs_encoder_active(const obs_encoder_t * encoder)835 bool obs_encoder_active(const obs_encoder_t *encoder)
836 {
837 	return obs_encoder_valid(encoder, "obs_encoder_active")
838 		       ? encoder_active(encoder)
839 		       : false;
840 }
841 
get_sei(const struct obs_encoder * encoder,uint8_t ** sei,size_t * size)842 static inline bool get_sei(const struct obs_encoder *encoder, uint8_t **sei,
843 			   size_t *size)
844 {
845 	if (encoder->info.get_sei_data)
846 		return encoder->info.get_sei_data(encoder->context.data, sei,
847 						  size);
848 	return false;
849 }
850 
send_first_video_packet(struct obs_encoder * encoder,struct encoder_callback * cb,struct encoder_packet * packet)851 static void send_first_video_packet(struct obs_encoder *encoder,
852 				    struct encoder_callback *cb,
853 				    struct encoder_packet *packet)
854 {
855 	struct encoder_packet first_packet;
856 	DARRAY(uint8_t) data;
857 	uint8_t *sei;
858 	size_t size;
859 
860 	/* always wait for first keyframe */
861 	if (!packet->keyframe)
862 		return;
863 
864 	da_init(data);
865 
866 	if (!get_sei(encoder, &sei, &size) || !sei || !size) {
867 		cb->new_packet(cb->param, packet);
868 		cb->sent_first_packet = true;
869 		return;
870 	}
871 
872 	da_push_back_array(data, sei, size);
873 	da_push_back_array(data, packet->data, packet->size);
874 
875 	first_packet = *packet;
876 	first_packet.data = data.array;
877 	first_packet.size = data.num;
878 
879 	cb->new_packet(cb->param, &first_packet);
880 	cb->sent_first_packet = true;
881 
882 	da_free(data);
883 }
884 
885 static const char *send_packet_name = "send_packet";
send_packet(struct obs_encoder * encoder,struct encoder_callback * cb,struct encoder_packet * packet)886 static inline void send_packet(struct obs_encoder *encoder,
887 			       struct encoder_callback *cb,
888 			       struct encoder_packet *packet)
889 {
890 	profile_start(send_packet_name);
891 	/* include SEI in first video packet */
892 	if (encoder->info.type == OBS_ENCODER_VIDEO && !cb->sent_first_packet)
893 		send_first_video_packet(encoder, cb, packet);
894 	else
895 		cb->new_packet(cb->param, packet);
896 	profile_end(send_packet_name);
897 }
898 
full_stop(struct obs_encoder * encoder)899 void full_stop(struct obs_encoder *encoder)
900 {
901 	if (encoder) {
902 		pthread_mutex_lock(&encoder->outputs_mutex);
903 		for (size_t i = 0; i < encoder->outputs.num; i++) {
904 			struct obs_output *output = encoder->outputs.array[i];
905 			obs_output_force_stop(output);
906 
907 			pthread_mutex_lock(&output->interleaved_mutex);
908 			output->info.encoded_packet(output->context.data, NULL);
909 			pthread_mutex_unlock(&output->interleaved_mutex);
910 		}
911 		pthread_mutex_unlock(&encoder->outputs_mutex);
912 
913 		pthread_mutex_lock(&encoder->callbacks_mutex);
914 		da_free(encoder->callbacks);
915 		pthread_mutex_unlock(&encoder->callbacks_mutex);
916 
917 		remove_connection(encoder, false);
918 		encoder->initialized = false;
919 	}
920 }
921 
send_off_encoder_packet(obs_encoder_t * encoder,bool success,bool received,struct encoder_packet * pkt)922 void send_off_encoder_packet(obs_encoder_t *encoder, bool success,
923 			     bool received, struct encoder_packet *pkt)
924 {
925 	if (!success) {
926 		blog(LOG_ERROR, "Error encoding with encoder '%s'",
927 		     encoder->context.name);
928 		full_stop(encoder);
929 		return;
930 	}
931 
932 	if (received) {
933 		if (!encoder->first_received) {
934 			encoder->offset_usec = packet_dts_usec(pkt);
935 			encoder->first_received = true;
936 		}
937 
938 		/* we use system time here to ensure sync with other encoders,
939 		 * you do not want to use relative timestamps here */
940 		pkt->dts_usec = encoder->start_ts / 1000 +
941 				packet_dts_usec(pkt) - encoder->offset_usec;
942 		pkt->sys_dts_usec = pkt->dts_usec;
943 
944 		pthread_mutex_lock(&encoder->pause.mutex);
945 		pkt->sys_dts_usec += encoder->pause.ts_offset / 1000;
946 		pthread_mutex_unlock(&encoder->pause.mutex);
947 
948 		pthread_mutex_lock(&encoder->callbacks_mutex);
949 
950 		for (size_t i = encoder->callbacks.num; i > 0; i--) {
951 			struct encoder_callback *cb;
952 			cb = encoder->callbacks.array + (i - 1);
953 			send_packet(encoder, cb, pkt);
954 		}
955 
956 		pthread_mutex_unlock(&encoder->callbacks_mutex);
957 	}
958 }
959 
960 static const char *do_encode_name = "do_encode";
do_encode(struct obs_encoder * encoder,struct encoder_frame * frame)961 bool do_encode(struct obs_encoder *encoder, struct encoder_frame *frame)
962 {
963 	profile_start(do_encode_name);
964 	if (!encoder->profile_encoder_encode_name)
965 		encoder->profile_encoder_encode_name =
966 			profile_store_name(obs_get_profiler_name_store(),
967 					   "encode(%s)", encoder->context.name);
968 
969 	struct encoder_packet pkt = {0};
970 	bool received = false;
971 	bool success;
972 
973 	if (encoder->reconfigure_requested) {
974 		encoder->reconfigure_requested = false;
975 		encoder->info.update(encoder->context.data,
976 				     encoder->context.settings);
977 	}
978 
979 	pkt.timebase_num = encoder->timebase_num;
980 	pkt.timebase_den = encoder->timebase_den;
981 	pkt.encoder = encoder;
982 
983 	profile_start(encoder->profile_encoder_encode_name);
984 	success = encoder->info.encode(encoder->context.data, frame, &pkt,
985 				       &received);
986 	profile_end(encoder->profile_encoder_encode_name);
987 	send_off_encoder_packet(encoder, success, received, &pkt);
988 
989 	profile_end(do_encode_name);
990 
991 	return success;
992 }
993 
video_pause_check_internal(struct pause_data * pause,uint64_t ts)994 static inline bool video_pause_check_internal(struct pause_data *pause,
995 					      uint64_t ts)
996 {
997 	pause->last_video_ts = ts;
998 	if (!pause->ts_start) {
999 		return false;
1000 	}
1001 
1002 	if (ts == pause->ts_end) {
1003 		pause->ts_start = 0;
1004 		pause->ts_end = 0;
1005 
1006 	} else if (ts >= pause->ts_start) {
1007 		return true;
1008 	}
1009 
1010 	return false;
1011 }
1012 
video_pause_check(struct pause_data * pause,uint64_t timestamp)1013 bool video_pause_check(struct pause_data *pause, uint64_t timestamp)
1014 {
1015 	bool ignore_frame;
1016 
1017 	pthread_mutex_lock(&pause->mutex);
1018 	ignore_frame = video_pause_check_internal(pause, timestamp);
1019 	pthread_mutex_unlock(&pause->mutex);
1020 
1021 	return ignore_frame;
1022 }
1023 
1024 static const char *receive_video_name = "receive_video";
receive_video(void * param,struct video_data * frame)1025 static void receive_video(void *param, struct video_data *frame)
1026 {
1027 	profile_start(receive_video_name);
1028 
1029 	struct obs_encoder *encoder = param;
1030 	struct obs_encoder *pair = encoder->paired_encoder;
1031 	struct encoder_frame enc_frame;
1032 
1033 	if (!encoder->first_received && pair) {
1034 		if (!pair->first_received ||
1035 		    pair->first_raw_ts > frame->timestamp) {
1036 			goto wait_for_audio;
1037 		}
1038 	}
1039 
1040 	if (video_pause_check(&encoder->pause, frame->timestamp))
1041 		goto wait_for_audio;
1042 
1043 	memset(&enc_frame, 0, sizeof(struct encoder_frame));
1044 
1045 	for (size_t i = 0; i < MAX_AV_PLANES; i++) {
1046 		enc_frame.data[i] = frame->data[i];
1047 		enc_frame.linesize[i] = frame->linesize[i];
1048 	}
1049 
1050 	if (!encoder->start_ts)
1051 		encoder->start_ts = frame->timestamp;
1052 
1053 	enc_frame.frames = 1;
1054 	enc_frame.pts = encoder->cur_pts;
1055 
1056 	if (do_encode(encoder, &enc_frame))
1057 		encoder->cur_pts += encoder->timebase_num;
1058 
1059 wait_for_audio:
1060 	profile_end(receive_video_name);
1061 }
1062 
clear_audio(struct obs_encoder * encoder)1063 static void clear_audio(struct obs_encoder *encoder)
1064 {
1065 	for (size_t i = 0; i < encoder->planes; i++)
1066 		circlebuf_free(&encoder->audio_input_buffer[i]);
1067 }
1068 
push_back_audio(struct obs_encoder * encoder,struct audio_data * data,size_t size,size_t offset_size)1069 static inline void push_back_audio(struct obs_encoder *encoder,
1070 				   struct audio_data *data, size_t size,
1071 				   size_t offset_size)
1072 {
1073 	size -= offset_size;
1074 
1075 	/* push in to the circular buffer */
1076 	if (size)
1077 		for (size_t i = 0; i < encoder->planes; i++)
1078 			circlebuf_push_back(&encoder->audio_input_buffer[i],
1079 					    data->data[i] + offset_size, size);
1080 }
1081 
calc_offset_size(struct obs_encoder * encoder,uint64_t v_start_ts,uint64_t a_start_ts)1082 static inline size_t calc_offset_size(struct obs_encoder *encoder,
1083 				      uint64_t v_start_ts, uint64_t a_start_ts)
1084 {
1085 	uint64_t offset = v_start_ts - a_start_ts;
1086 	offset = util_mul_div64(offset, encoder->samplerate, 1000000000ULL);
1087 	return (size_t)offset * encoder->blocksize;
1088 }
1089 
start_from_buffer(struct obs_encoder * encoder,uint64_t v_start_ts)1090 static void start_from_buffer(struct obs_encoder *encoder, uint64_t v_start_ts)
1091 {
1092 	size_t size = encoder->audio_input_buffer[0].size;
1093 	struct audio_data audio = {0};
1094 	size_t offset_size = 0;
1095 
1096 	for (size_t i = 0; i < MAX_AV_PLANES; i++) {
1097 		audio.data[i] = encoder->audio_input_buffer[i].data;
1098 		memset(&encoder->audio_input_buffer[i], 0,
1099 		       sizeof(struct circlebuf));
1100 	}
1101 
1102 	if (encoder->first_raw_ts < v_start_ts)
1103 		offset_size = calc_offset_size(encoder, v_start_ts,
1104 					       encoder->first_raw_ts);
1105 
1106 	push_back_audio(encoder, &audio, size, offset_size);
1107 
1108 	for (size_t i = 0; i < MAX_AV_PLANES; i++)
1109 		bfree(audio.data[i]);
1110 }
1111 
1112 static const char *buffer_audio_name = "buffer_audio";
buffer_audio(struct obs_encoder * encoder,struct audio_data * data)1113 static bool buffer_audio(struct obs_encoder *encoder, struct audio_data *data)
1114 {
1115 	profile_start(buffer_audio_name);
1116 
1117 	size_t size = data->frames * encoder->blocksize;
1118 	size_t offset_size = 0;
1119 	bool success = true;
1120 
1121 	if (!encoder->start_ts && encoder->paired_encoder) {
1122 		uint64_t end_ts = data->timestamp;
1123 		uint64_t v_start_ts = encoder->paired_encoder->start_ts;
1124 
1125 		/* no video yet, so don't start audio */
1126 		if (!v_start_ts) {
1127 			success = false;
1128 			goto fail;
1129 		}
1130 
1131 		/* audio starting point still not synced with video starting
1132 		 * point, so don't start audio */
1133 		end_ts += util_mul_div64(data->frames, 1000000000ULL,
1134 					 encoder->samplerate);
1135 		if (end_ts <= v_start_ts) {
1136 			success = false;
1137 			goto fail;
1138 		}
1139 
1140 		/* ready to start audio, truncate if necessary */
1141 		if (data->timestamp < v_start_ts)
1142 			offset_size = calc_offset_size(encoder, v_start_ts,
1143 						       data->timestamp);
1144 		if (data->timestamp <= v_start_ts)
1145 			clear_audio(encoder);
1146 
1147 		encoder->start_ts = v_start_ts;
1148 
1149 		/* use currently buffered audio instead */
1150 		if (v_start_ts < data->timestamp) {
1151 			start_from_buffer(encoder, v_start_ts);
1152 		}
1153 
1154 	} else if (!encoder->start_ts && !encoder->paired_encoder) {
1155 		encoder->start_ts = data->timestamp;
1156 	}
1157 
1158 fail:
1159 	push_back_audio(encoder, data, size, offset_size);
1160 
1161 	profile_end(buffer_audio_name);
1162 	return success;
1163 }
1164 
send_audio_data(struct obs_encoder * encoder)1165 static bool send_audio_data(struct obs_encoder *encoder)
1166 {
1167 	struct encoder_frame enc_frame;
1168 
1169 	memset(&enc_frame, 0, sizeof(struct encoder_frame));
1170 
1171 	for (size_t i = 0; i < encoder->planes; i++) {
1172 		circlebuf_pop_front(&encoder->audio_input_buffer[i],
1173 				    encoder->audio_output_buffer[i],
1174 				    encoder->framesize_bytes);
1175 
1176 		enc_frame.data[i] = encoder->audio_output_buffer[i];
1177 		enc_frame.linesize[i] = (uint32_t)encoder->framesize_bytes;
1178 	}
1179 
1180 	enc_frame.frames = (uint32_t)encoder->framesize;
1181 	enc_frame.pts = encoder->cur_pts;
1182 
1183 	if (!do_encode(encoder, &enc_frame))
1184 		return false;
1185 
1186 	encoder->cur_pts += encoder->framesize;
1187 	return true;
1188 }
1189 
pause_audio(struct pause_data * pause,struct audio_data * data,size_t sample_rate)1190 static void pause_audio(struct pause_data *pause, struct audio_data *data,
1191 			size_t sample_rate)
1192 {
1193 	uint64_t cutoff_frames = pause->ts_start - data->timestamp;
1194 	cutoff_frames = ns_to_audio_frames(sample_rate, cutoff_frames);
1195 
1196 	data->frames = (uint32_t)cutoff_frames;
1197 }
1198 
unpause_audio(struct pause_data * pause,struct audio_data * data,size_t sample_rate)1199 static void unpause_audio(struct pause_data *pause, struct audio_data *data,
1200 			  size_t sample_rate)
1201 {
1202 	uint64_t cutoff_frames = pause->ts_end - data->timestamp;
1203 	cutoff_frames = ns_to_audio_frames(sample_rate, cutoff_frames);
1204 
1205 	for (size_t i = 0; i < MAX_AV_PLANES; i++) {
1206 		if (!data->data[i])
1207 			break;
1208 		data->data[i] += cutoff_frames * sizeof(float);
1209 	}
1210 
1211 	data->timestamp = pause->ts_start;
1212 	data->frames = data->frames - (uint32_t)cutoff_frames;
1213 	pause->ts_start = 0;
1214 	pause->ts_end = 0;
1215 }
1216 
audio_pause_check_internal(struct pause_data * pause,struct audio_data * data,size_t sample_rate)1217 static inline bool audio_pause_check_internal(struct pause_data *pause,
1218 					      struct audio_data *data,
1219 					      size_t sample_rate)
1220 {
1221 	uint64_t end_ts;
1222 
1223 	if (!pause->ts_start) {
1224 		return false;
1225 	}
1226 
1227 	end_ts =
1228 		data->timestamp + audio_frames_to_ns(sample_rate, data->frames);
1229 
1230 	if (pause->ts_start >= data->timestamp) {
1231 		if (pause->ts_start <= end_ts) {
1232 			pause_audio(pause, data, sample_rate);
1233 			return !data->frames;
1234 		}
1235 
1236 	} else {
1237 		if (pause->ts_end >= data->timestamp &&
1238 		    pause->ts_end <= end_ts) {
1239 			unpause_audio(pause, data, sample_rate);
1240 			return !data->frames;
1241 		}
1242 
1243 		return true;
1244 	}
1245 
1246 	return false;
1247 }
1248 
audio_pause_check(struct pause_data * pause,struct audio_data * data,size_t sample_rate)1249 bool audio_pause_check(struct pause_data *pause, struct audio_data *data,
1250 		       size_t sample_rate)
1251 {
1252 	bool ignore_audio;
1253 
1254 	pthread_mutex_lock(&pause->mutex);
1255 	ignore_audio = audio_pause_check_internal(pause, data, sample_rate);
1256 	data->timestamp -= pause->ts_offset;
1257 	pthread_mutex_unlock(&pause->mutex);
1258 
1259 	return ignore_audio;
1260 }
1261 
1262 static const char *receive_audio_name = "receive_audio";
receive_audio(void * param,size_t mix_idx,struct audio_data * in)1263 static void receive_audio(void *param, size_t mix_idx, struct audio_data *in)
1264 {
1265 	profile_start(receive_audio_name);
1266 
1267 	struct obs_encoder *encoder = param;
1268 	struct audio_data audio = *in;
1269 
1270 	if (!encoder->first_received) {
1271 		encoder->first_raw_ts = audio.timestamp;
1272 		encoder->first_received = true;
1273 		clear_audio(encoder);
1274 	}
1275 
1276 	if (audio_pause_check(&encoder->pause, &audio, encoder->samplerate))
1277 		goto end;
1278 
1279 	if (!buffer_audio(encoder, &audio))
1280 		goto end;
1281 
1282 	while (encoder->audio_input_buffer[0].size >=
1283 	       encoder->framesize_bytes) {
1284 		if (!send_audio_data(encoder)) {
1285 			break;
1286 		}
1287 	}
1288 
1289 	UNUSED_PARAMETER(mix_idx);
1290 
1291 end:
1292 	profile_end(receive_audio_name);
1293 }
1294 
obs_encoder_add_output(struct obs_encoder * encoder,struct obs_output * output)1295 void obs_encoder_add_output(struct obs_encoder *encoder,
1296 			    struct obs_output *output)
1297 {
1298 	if (!encoder)
1299 		return;
1300 
1301 	pthread_mutex_lock(&encoder->outputs_mutex);
1302 	da_push_back(encoder->outputs, &output);
1303 	pthread_mutex_unlock(&encoder->outputs_mutex);
1304 }
1305 
obs_encoder_remove_output(struct obs_encoder * encoder,struct obs_output * output)1306 void obs_encoder_remove_output(struct obs_encoder *encoder,
1307 			       struct obs_output *output)
1308 {
1309 	if (!encoder)
1310 		return;
1311 
1312 	pthread_mutex_lock(&encoder->outputs_mutex);
1313 	da_erase_item(encoder->outputs, &output);
1314 	pthread_mutex_unlock(&encoder->outputs_mutex);
1315 }
1316 
obs_encoder_packet_create_instance(struct encoder_packet * dst,const struct encoder_packet * src)1317 void obs_encoder_packet_create_instance(struct encoder_packet *dst,
1318 					const struct encoder_packet *src)
1319 {
1320 	long *p_refs;
1321 
1322 	*dst = *src;
1323 	p_refs = bmalloc(src->size + sizeof(long));
1324 	dst->data = (void *)(p_refs + 1);
1325 	*p_refs = 1;
1326 	memcpy(dst->data, src->data, src->size);
1327 }
1328 
1329 /* OBS_DEPRECATED */
obs_duplicate_encoder_packet(struct encoder_packet * dst,const struct encoder_packet * src)1330 void obs_duplicate_encoder_packet(struct encoder_packet *dst,
1331 				  const struct encoder_packet *src)
1332 {
1333 	obs_encoder_packet_create_instance(dst, src);
1334 }
1335 
1336 /* OBS_DEPRECATED */
obs_free_encoder_packet(struct encoder_packet * packet)1337 void obs_free_encoder_packet(struct encoder_packet *packet)
1338 {
1339 	obs_encoder_packet_release(packet);
1340 }
1341 
obs_encoder_packet_ref(struct encoder_packet * dst,struct encoder_packet * src)1342 void obs_encoder_packet_ref(struct encoder_packet *dst,
1343 			    struct encoder_packet *src)
1344 {
1345 	if (!src)
1346 		return;
1347 
1348 	if (src->data) {
1349 		long *p_refs = ((long *)src->data) - 1;
1350 		os_atomic_inc_long(p_refs);
1351 	}
1352 
1353 	*dst = *src;
1354 }
1355 
obs_encoder_packet_release(struct encoder_packet * pkt)1356 void obs_encoder_packet_release(struct encoder_packet *pkt)
1357 {
1358 	if (!pkt)
1359 		return;
1360 
1361 	if (pkt->data) {
1362 		long *p_refs = ((long *)pkt->data) - 1;
1363 		if (os_atomic_dec_long(p_refs) == 0)
1364 			bfree(p_refs);
1365 	}
1366 
1367 	memset(pkt, 0, sizeof(struct encoder_packet));
1368 }
1369 
obs_encoder_set_preferred_video_format(obs_encoder_t * encoder,enum video_format format)1370 void obs_encoder_set_preferred_video_format(obs_encoder_t *encoder,
1371 					    enum video_format format)
1372 {
1373 	if (!encoder || encoder->info.type != OBS_ENCODER_VIDEO)
1374 		return;
1375 
1376 	encoder->preferred_format = format;
1377 }
1378 
1379 enum video_format
obs_encoder_get_preferred_video_format(const obs_encoder_t * encoder)1380 obs_encoder_get_preferred_video_format(const obs_encoder_t *encoder)
1381 {
1382 	if (!encoder || encoder->info.type != OBS_ENCODER_VIDEO)
1383 		return VIDEO_FORMAT_NONE;
1384 
1385 	return encoder->preferred_format;
1386 }
1387 
obs_encoder_addref(obs_encoder_t * encoder)1388 void obs_encoder_addref(obs_encoder_t *encoder)
1389 {
1390 	if (!encoder)
1391 		return;
1392 
1393 	obs_ref_addref(&encoder->control->ref);
1394 }
1395 
obs_encoder_release(obs_encoder_t * encoder)1396 void obs_encoder_release(obs_encoder_t *encoder)
1397 {
1398 	if (!encoder)
1399 		return;
1400 
1401 	obs_weak_encoder_t *control = encoder->control;
1402 	if (obs_ref_release(&control->ref)) {
1403 		// The order of operations is important here since
1404 		// get_context_by_name in obs.c relies on weak refs
1405 		// being alive while the context is listed
1406 		obs_encoder_destroy(encoder);
1407 		obs_weak_encoder_release(control);
1408 	}
1409 }
1410 
obs_weak_encoder_addref(obs_weak_encoder_t * weak)1411 void obs_weak_encoder_addref(obs_weak_encoder_t *weak)
1412 {
1413 	if (!weak)
1414 		return;
1415 
1416 	obs_weak_ref_addref(&weak->ref);
1417 }
1418 
obs_weak_encoder_release(obs_weak_encoder_t * weak)1419 void obs_weak_encoder_release(obs_weak_encoder_t *weak)
1420 {
1421 	if (!weak)
1422 		return;
1423 
1424 	if (obs_weak_ref_release(&weak->ref))
1425 		bfree(weak);
1426 }
1427 
obs_encoder_get_ref(obs_encoder_t * encoder)1428 obs_encoder_t *obs_encoder_get_ref(obs_encoder_t *encoder)
1429 {
1430 	if (!encoder)
1431 		return NULL;
1432 
1433 	return obs_weak_encoder_get_encoder(encoder->control);
1434 }
1435 
obs_encoder_get_weak_encoder(obs_encoder_t * encoder)1436 obs_weak_encoder_t *obs_encoder_get_weak_encoder(obs_encoder_t *encoder)
1437 {
1438 	if (!encoder)
1439 		return NULL;
1440 
1441 	obs_weak_encoder_t *weak = encoder->control;
1442 	obs_weak_encoder_addref(weak);
1443 	return weak;
1444 }
1445 
obs_weak_encoder_get_encoder(obs_weak_encoder_t * weak)1446 obs_encoder_t *obs_weak_encoder_get_encoder(obs_weak_encoder_t *weak)
1447 {
1448 	if (!weak)
1449 		return NULL;
1450 
1451 	if (obs_weak_ref_get_ref(&weak->ref))
1452 		return weak->encoder;
1453 
1454 	return NULL;
1455 }
1456 
obs_weak_encoder_references_encoder(obs_weak_encoder_t * weak,obs_encoder_t * encoder)1457 bool obs_weak_encoder_references_encoder(obs_weak_encoder_t *weak,
1458 					 obs_encoder_t *encoder)
1459 {
1460 	return weak && encoder && weak->encoder == encoder;
1461 }
1462 
obs_encoder_get_type_data(obs_encoder_t * encoder)1463 void *obs_encoder_get_type_data(obs_encoder_t *encoder)
1464 {
1465 	return obs_encoder_valid(encoder, "obs_encoder_get_type_data")
1466 		       ? encoder->orig_info.type_data
1467 		       : NULL;
1468 }
1469 
obs_encoder_get_id(const obs_encoder_t * encoder)1470 const char *obs_encoder_get_id(const obs_encoder_t *encoder)
1471 {
1472 	return obs_encoder_valid(encoder, "obs_encoder_get_id")
1473 		       ? encoder->orig_info.id
1474 		       : NULL;
1475 }
1476 
obs_get_encoder_caps(const char * encoder_id)1477 uint32_t obs_get_encoder_caps(const char *encoder_id)
1478 {
1479 	struct obs_encoder_info *info = find_encoder(encoder_id);
1480 	return info ? info->caps : 0;
1481 }
1482 
obs_encoder_get_caps(const obs_encoder_t * encoder)1483 uint32_t obs_encoder_get_caps(const obs_encoder_t *encoder)
1484 {
1485 	return obs_encoder_valid(encoder, "obs_encoder_get_caps")
1486 		       ? encoder->orig_info.caps
1487 		       : 0;
1488 }
1489 
obs_encoder_paused(const obs_encoder_t * encoder)1490 bool obs_encoder_paused(const obs_encoder_t *encoder)
1491 {
1492 	return obs_encoder_valid(encoder, "obs_encoder_paused")
1493 		       ? os_atomic_load_bool(&encoder->paused)
1494 		       : false;
1495 }
1496 
obs_encoder_get_last_error(obs_encoder_t * encoder)1497 const char *obs_encoder_get_last_error(obs_encoder_t *encoder)
1498 {
1499 	if (!obs_encoder_valid(encoder, "obs_encoder_get_last_error"))
1500 		return NULL;
1501 
1502 	return encoder->last_error_message;
1503 }
1504 
obs_encoder_set_last_error(obs_encoder_t * encoder,const char * message)1505 void obs_encoder_set_last_error(obs_encoder_t *encoder, const char *message)
1506 {
1507 	if (!obs_encoder_valid(encoder, "obs_encoder_set_last_error"))
1508 		return;
1509 
1510 	if (encoder->last_error_message)
1511 		bfree(encoder->last_error_message);
1512 
1513 	if (message)
1514 		encoder->last_error_message = bstrdup(message);
1515 	else
1516 		encoder->last_error_message = NULL;
1517 }
1518