737cfd64df3b886b440822c0ad8d499f9315edb3
[platform/core/multimedia/libmm-wfd.git] / sink / mm_wfd_sink_manager.c
1 /*
2  * libmm-wfd
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>,
7  * Seungbae Shin <seungbae.shin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23
24 #include "mm_wfd_sink_manager.h"
25
26
27 static gpointer __mm_wfd_sink_manager_thread(gpointer data);
28
29 int _mm_wfd_sink_init_manager(mm_wfd_sink_t *wfd_sink)
30 {
31         wfd_sink_debug_fenter();
32
33         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
34
35         /* create capture mutex */
36         g_mutex_init(&(wfd_sink->manager_thread_mutex));
37
38         /* create capture cond */
39         g_cond_init(&(wfd_sink->manager_thread_cond));
40
41         wfd_sink->manager_thread_cmd = WFD_SINK_MANAGER_CMD_NONE;
42
43         /* create video capture thread */
44         wfd_sink->manager_thread =
45             g_thread_new("__mm_wfd_sink_manager_thread", __mm_wfd_sink_manager_thread, (gpointer)wfd_sink);
46         if (wfd_sink->manager_thread == NULL) {
47                 wfd_sink_error("failed to create manager thread\n");
48                 goto failed_to_init;
49         }
50
51         wfd_sink_debug_fleave();
52
53         return MM_ERROR_NONE;
54
55 failed_to_init:
56         g_mutex_clear(&(wfd_sink->manager_thread_mutex));
57         g_cond_clear(&(wfd_sink->manager_thread_cond));
58
59         return MM_ERROR_WFD_INTERNAL;
60 }
61
62 int _mm_wfd_sink_release_manager(mm_wfd_sink_t *wfd_sink)
63 {
64         wfd_sink_debug_fenter();
65
66         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
67
68         /* release capture thread */
69         if (wfd_sink->manager_thread) {
70                 WFD_SINK_MANAGER_LOCK(wfd_sink);
71                 WFD_SINK_MANAGER_SIGNAL_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_EXIT);
72                 WFD_SINK_MANAGER_UNLOCK(wfd_sink);
73
74                 wfd_sink_debug("waitting for manager thread exit");
75                 g_thread_join(wfd_sink->manager_thread);
76                 g_mutex_clear(&(wfd_sink->manager_thread_mutex));
77                 g_cond_clear(&(wfd_sink->manager_thread_cond));
78                 wfd_sink_debug("manager thread released");
79         }
80
81         wfd_sink_debug_fleave();
82
83         return MM_ERROR_NONE;
84 }
85
86 static gpointer
87 __mm_wfd_sink_manager_thread(gpointer data)
88 {
89         mm_wfd_sink_t *wfd_sink = (mm_wfd_sink_t *) data;
90         gboolean link_auido_bin = FALSE;
91         gboolean link_video_bin = FALSE;
92         gboolean set_ready_audio_bin = FALSE;
93         gboolean set_ready_video_bin = FALSE;
94
95
96         wfd_sink_debug_fenter();
97
98         wfd_sink_return_val_if_fail(wfd_sink, NULL);
99
100         if (wfd_sink->manager_thread_cmd & WFD_SINK_MANAGER_CMD_EXIT) {
101                 wfd_sink->manager_thread_cmd = WFD_SINK_MANAGER_CMD_EXIT;
102                 return NULL;
103         }
104
105         wfd_sink_debug("manager thread started. waiting for signal");
106
107         while (TRUE) {
108                 WFD_SINK_MANAGER_LOCK(wfd_sink);
109                 WFD_SINK_MANAGER_WAIT_CMD(wfd_sink);
110
111                 wfd_sink_debug("got command %x", wfd_sink->manager_thread_cmd);
112
113                 if (wfd_sink->manager_thread_cmd & WFD_SINK_MANAGER_CMD_EXIT) {
114                         wfd_sink_debug("exiting manager thread");
115                         goto EXIT;
116                 }
117
118                 /* check command */
119                 link_auido_bin = wfd_sink->manager_thread_cmd & WFD_SINK_MANAGER_CMD_LINK_A_BIN;
120                 link_video_bin = wfd_sink->manager_thread_cmd & WFD_SINK_MANAGER_CMD_LINK_V_BIN;
121                 set_ready_audio_bin = wfd_sink->manager_thread_cmd & WFD_SINK_MANAGER_CMD_PREPARE_A_BIN;
122                 if (set_ready_audio_bin && !link_auido_bin && !wfd_sink->audio_bin_is_linked) {
123                         wfd_sink_error("audio bin is not linked... wait for command for linking audiobin");
124                         WFD_SINK_MANAGER_UNLOCK(wfd_sink);
125                         continue;
126                 }
127                 set_ready_video_bin = wfd_sink->manager_thread_cmd & WFD_SINK_MANAGER_CMD_PREPARE_V_BIN;
128                 if (set_ready_video_bin && !link_video_bin && !wfd_sink->video_bin_is_linked) {
129                         wfd_sink_error("video bin is not linked... wait for command for linking videobin.");
130                         WFD_SINK_MANAGER_UNLOCK(wfd_sink);
131                         continue;
132                 }
133
134                 /* link audio bin*/
135                 if (link_auido_bin) {
136                         wfd_sink_debug("try to link audiobin.");
137                         if (MM_ERROR_NONE != __mm_wfd_sink_link_audiobin(wfd_sink)) {
138                                 wfd_sink_error("failed to link audiobin.....\n");
139                                 goto EXIT;
140                         }
141                 }
142
143                 /* link video bin*/
144                 if (link_video_bin) {
145                         wfd_sink_debug("try to link videobin.");
146                         if (MM_ERROR_NONE != __mm_wfd_sink_link_videobin(wfd_sink)) {
147                                 wfd_sink_error("failed to link videobin.....\n");
148                                 goto EXIT;
149                         }
150                 }
151
152                 if (set_ready_audio_bin) {
153                         wfd_sink_debug("try to prepare audiobin.");
154                         if (MM_ERROR_NONE != __mm_wfd_sink_prepare_audiobin(wfd_sink)) {
155                                 wfd_sink_error("failed to prepare audiobin.....\n");
156                                 goto EXIT;
157                         }
158                 }
159
160                 if (set_ready_video_bin) {
161                         wfd_sink_debug("try to prepare videobin.");
162                         if (MM_ERROR_NONE != __mm_wfd_sink_prepare_videobin(wfd_sink)) {
163                                 wfd_sink_error("failed to prepare videobin.....\n");
164                                 goto EXIT;
165                         }
166                 }
167
168                 wfd_sink->manager_thread_cmd = WFD_SINK_MANAGER_CMD_NONE;
169
170                 WFD_SINK_MANAGER_UNLOCK(wfd_sink);
171         }
172
173         wfd_sink_debug_fleave();
174
175         return NULL;
176
177 EXIT:
178         wfd_sink->manager_thread_cmd = WFD_SINK_MANAGER_CMD_EXIT;
179
180         WFD_SINK_MANAGER_UNLOCK(wfd_sink);
181
182         return NULL;
183 }
184