1 /******************************************************************************
2 Copyright (C) 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
obs_view_init(struct obs_view * view)21 bool obs_view_init(struct obs_view *view)
22 {
23 if (!view)
24 return false;
25
26 pthread_mutex_init_value(&view->channels_mutex);
27
28 if (pthread_mutex_init(&view->channels_mutex, NULL) != 0) {
29 blog(LOG_ERROR, "obs_view_init: Failed to create mutex");
30 return false;
31 }
32
33 return true;
34 }
35
obs_view_create(void)36 obs_view_t *obs_view_create(void)
37 {
38 struct obs_view *view = bzalloc(sizeof(struct obs_view));
39
40 if (!obs_view_init(view)) {
41 bfree(view);
42 view = NULL;
43 }
44
45 return view;
46 }
47
obs_view_free(struct obs_view * view)48 void obs_view_free(struct obs_view *view)
49 {
50 if (!view)
51 return;
52
53 for (size_t i = 0; i < MAX_CHANNELS; i++) {
54 struct obs_source *source = view->channels[i];
55 if (source) {
56 obs_source_deactivate(source, AUX_VIEW);
57 obs_source_release(source);
58 }
59 }
60
61 memset(view->channels, 0, sizeof(view->channels));
62 pthread_mutex_destroy(&view->channels_mutex);
63 }
64
obs_view_destroy(obs_view_t * view)65 void obs_view_destroy(obs_view_t *view)
66 {
67 if (view) {
68 obs_view_free(view);
69 bfree(view);
70 }
71 }
72
obs_view_get_source(obs_view_t * view,uint32_t channel)73 obs_source_t *obs_view_get_source(obs_view_t *view, uint32_t channel)
74 {
75 obs_source_t *source;
76 assert(channel < MAX_CHANNELS);
77
78 if (!view)
79 return NULL;
80 if (channel >= MAX_CHANNELS)
81 return NULL;
82
83 pthread_mutex_lock(&view->channels_mutex);
84
85 source = view->channels[channel];
86 if (source)
87 obs_source_addref(source);
88
89 pthread_mutex_unlock(&view->channels_mutex);
90
91 return source;
92 }
93
obs_view_set_source(obs_view_t * view,uint32_t channel,obs_source_t * source)94 void obs_view_set_source(obs_view_t *view, uint32_t channel,
95 obs_source_t *source)
96 {
97 struct obs_source *prev_source;
98
99 assert(channel < MAX_CHANNELS);
100
101 if (!view)
102 return;
103 if (channel >= MAX_CHANNELS)
104 return;
105
106 pthread_mutex_lock(&view->channels_mutex);
107
108 obs_source_addref(source);
109
110 prev_source = view->channels[channel];
111 view->channels[channel] = source;
112
113 pthread_mutex_unlock(&view->channels_mutex);
114
115 if (source)
116 obs_source_activate(source, AUX_VIEW);
117
118 if (prev_source) {
119 obs_source_deactivate(prev_source, AUX_VIEW);
120 obs_source_release(prev_source);
121 }
122 }
123
obs_view_render(obs_view_t * view)124 void obs_view_render(obs_view_t *view)
125 {
126 if (!view)
127 return;
128
129 pthread_mutex_lock(&view->channels_mutex);
130
131 for (size_t i = 0; i < MAX_CHANNELS; i++) {
132 struct obs_source *source;
133
134 source = view->channels[i];
135
136 if (source) {
137 if (source->removed) {
138 obs_source_release(source);
139 view->channels[i] = NULL;
140 } else {
141 obs_source_video_render(source);
142 }
143 }
144 }
145
146 pthread_mutex_unlock(&view->channels_mutex);
147 }
148