Add unprepare audio/video cmd
[platform/core/multimedia/libmm-wfd.git] / src / 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 manager 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 = NULL;
42         wfd_sink->manager_thread_exit = FALSE;
43
44         /* create manager thread */
45         wfd_sink->manager_thread =
46             g_thread_new("__mm_wfd_sink_manager_thread", __mm_wfd_sink_manager_thread, (gpointer)wfd_sink);
47         if (wfd_sink->manager_thread == NULL) {
48                 wfd_sink_error("failed to create manager thread");
49                 goto failed_to_init;
50         }
51
52         wfd_sink_debug_fleave();
53
54         return MM_ERROR_NONE;
55
56 failed_to_init:
57         g_mutex_clear(&(wfd_sink->manager_thread_mutex));
58         g_cond_clear(&(wfd_sink->manager_thread_cond));
59
60         return MM_ERROR_WFD_INTERNAL;
61 }
62
63 int _mm_wfd_sink_release_manager(mm_wfd_sink_t *wfd_sink)
64 {
65         wfd_sink_debug_fenter();
66
67         wfd_sink_return_val_if_fail(wfd_sink, MM_ERROR_WFD_NOT_INITIALIZED);
68
69         /* release manager thread */
70         if (wfd_sink->manager_thread) {
71                 WFD_SINK_MANAGER_APPEND_CMD(wfd_sink, WFD_SINK_MANAGER_CMD_EXIT);
72                 WFD_SINK_MANAGER_SIGNAL_CMD(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         WFDSinkManagerCMDType cmd = WFD_SINK_MANAGER_CMD_NONE;
91         GList *walk = NULL;
92
93         wfd_sink_debug_fenter();
94
95         wfd_sink_return_val_if_fail(wfd_sink, NULL);
96
97         if (wfd_sink->manager_thread_exit) {
98                 wfd_sink_debug("exit manager thread...");
99                 return NULL;
100         }
101
102         wfd_sink_debug("manager thread started. waiting for signal");
103
104         while (TRUE) {
105                 WFD_SINK_MANAGER_LOCK(wfd_sink);
106                 WFD_SINK_MANAGER_WAIT_CMD(wfd_sink);
107
108                 for (walk = wfd_sink->manager_thread_cmd; walk; walk = g_list_next(walk)) {
109                         cmd = GPOINTER_TO_INT(walk->data);
110
111                         wfd_sink_debug("got command %d", cmd);
112
113                         switch (cmd) {
114                         case WFD_SINK_MANAGER_CMD_LINK_A_DECODEBIN:
115                                 wfd_sink_debug("try to link audio decodebin.");
116                                 if (MM_ERROR_NONE != __mm_wfd_sink_link_audio_decodebin(wfd_sink)) {
117                                         wfd_sink_error("failed to link audio decodebin.....");
118                                         goto EXIT;
119                                 }
120                                 break;
121                         case WFD_SINK_MANAGER_CMD_LINK_V_DECODEBIN:
122                                 wfd_sink_debug("try to link video decodebin.");
123                                 if (MM_ERROR_NONE != __mm_wfd_sink_link_video_decodebin(wfd_sink)) {
124                                         wfd_sink_error("failed to link video decodebin.....");
125                                         goto EXIT;
126                                 }
127                                 break;
128                         case WFD_SINK_MANAGER_CMD_PREPARE_A_PIPELINE:
129                                 wfd_sink_debug("try to prepare audio pipeline.");
130                                 if (MM_ERROR_NONE != __mm_wfd_sink_prepare_audio_pipeline(wfd_sink, NULL)) {
131                                         wfd_sink_error("failed to prepare audio pipeline.....");
132                                         goto EXIT;
133                                 }
134                                 break;
135                         case WFD_SINK_MANAGER_CMD_PREPARE_V_PIPELINE:
136                                 wfd_sink_debug("try to prepare video pipeline.");
137                                 if (MM_ERROR_NONE != __mm_wfd_sink_prepare_video_pipeline(wfd_sink, NULL)) {
138                                         wfd_sink_error("failed to prepare video pipeline.....");
139                                         goto EXIT;
140                                 }
141                                 break;
142                         case WFD_SINK_MANAGER_CMD_UNPREPARE_A_PIPELINE:
143                                 wfd_sink_debug("try to unprepare audio pipeline.");
144                                 if (MM_ERROR_NONE != __mm_wfd_sink_unprepare_audio_pipeline(wfd_sink)) {
145                                         wfd_sink_error("failed to unprepare audio pipeline.....");
146                                         goto EXIT;
147                                 }
148                                 break;
149                         case WFD_SINK_MANAGER_CMD_UNPREPARE_V_PIPELINE:
150                                 wfd_sink_debug("try to unprepare video pipeline.");
151                                 if (MM_ERROR_NONE != __mm_wfd_sink_unprepare_video_pipeline(wfd_sink)) {
152                                         wfd_sink_error("failed to unprepare video pipeline.....");
153                                         goto EXIT;
154                                 }
155                                 break;
156                         case WFD_SINK_MANAGER_CMD_EXIT:
157                                 wfd_sink_debug("exiting manager thread");
158                                 goto EXIT;
159                                 break;
160                         default:
161                                 break;
162                         }
163                 }
164
165                 g_list_free(wfd_sink->manager_thread_cmd);
166                 wfd_sink->manager_thread_cmd = NULL;
167
168                 WFD_SINK_MANAGER_UNLOCK(wfd_sink);
169         }
170
171         wfd_sink_debug_fleave();
172
173         return NULL;
174
175 EXIT:
176         wfd_sink->manager_thread_exit = TRUE;
177         g_list_free(wfd_sink->manager_thread_cmd);
178         wfd_sink->manager_thread_cmd = NULL;
179         WFD_SINK_MANAGER_UNLOCK(wfd_sink);
180
181         return NULL;
182 }
183