Merge "Remove Profile Build Dependency (CAPI defrag + runtime)" into tizen
[platform/core/api/player.git] / src / player_internal.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <muse_core.h>
21 #include <muse_core_msg_json.h>
22 #include <muse_core_ipc.h>
23 #include <mm_error.h>
24 #include <dlog.h>
25 #include <Evas.h>
26 #include <Ecore_Evas.h>
27 #include <Ecore_Wayland.h>
28 #include <muse_player.h>
29 #include <muse_player_msg.h>
30 #include <storage-internal.h>
31 #include "player_private.h"
32 #include "player_msg.h"
33 #include "player_internal.h"
34 #include "player_display.h"
35
36 int player_set_pcm_extraction_mode(player_h player, bool sync, player_audio_pcm_extraction_cb callback, void *user_data)
37 {
38         PLAYER_INSTANCE_CHECK(player);
39         PLAYER_NULL_ARG_CHECK(callback);
40         int ret = PLAYER_ERROR_NONE;
41         muse_player_api_e api = MUSE_PLAYER_API_SET_PCM_EXTRACTION_MODE;
42         player_cli_s *pc = (player_cli_s *) player;
43         char *ret_buf = NULL;
44         muse_player_event_e event = MUSE_PLAYER_EVENT_TYPE_AUDIO_FRAME;
45
46         LOGD("ENTER");
47
48         player_msg_send1(api, pc, ret_buf, ret, INT, sync);
49
50         if (ret == PLAYER_ERROR_NONE) {
51                 pc->cb_info->user_cb[event] = callback;
52                 pc->cb_info->user_data[event] = user_data;
53                 LOGI("Event type : %d ", event);
54         }
55
56         g_free(ret_buf);
57         return ret;
58 }
59
60 int player_set_pcm_spec(player_h player, const char *format, int samplerate, int channel)
61 {
62         PLAYER_INSTANCE_CHECK(player);
63         int ret = PLAYER_ERROR_NONE;
64         muse_player_api_e api = MUSE_PLAYER_API_SET_PCM_SPEC;
65         player_cli_s *pc = (player_cli_s *) player;
66         char *ret_buf = NULL;
67
68         LOGD("ENTER");
69
70         player_msg_send3(api, pc, ret_buf, ret, STRING, format, INT, samplerate, INT, channel);
71
72         g_free(ret_buf);
73         return ret;
74 }
75
76 int player_set_streaming_playback_rate(player_h player, float rate)
77 {
78         PLAYER_INSTANCE_CHECK(player);
79         int ret = PLAYER_ERROR_NONE;
80         muse_player_api_e api = MUSE_PLAYER_API_SET_STREAMING_PLAYBACK_RATE;
81         player_cli_s *pc = (player_cli_s *) player;
82         char *ret_buf = NULL;
83
84         LOGD("ENTER");
85
86         player_msg_send1(api, pc, ret_buf, ret, DOUBLE, rate);
87         g_free(ret_buf);
88         return ret;
89 }
90
91 int player_set_media_stream_buffer_status_cb_ex(player_h player, player_stream_type_e stream_type, player_media_stream_buffer_status_cb_ex callback, void *user_data)
92 {
93         PLAYER_INSTANCE_CHECK(player);
94         PLAYER_NULL_ARG_CHECK(callback);
95         int ret = PLAYER_ERROR_NONE;
96         player_cli_s *pc = (player_cli_s *) player;
97         muse_player_api_e api = MUSE_PLAYER_API_SET_CALLBACK;
98         char *ret_buf = NULL;
99         muse_player_event_e type;
100         int set = 1;
101
102         LOGD("ENTER");
103
104         if (stream_type == PLAYER_STREAM_TYPE_VIDEO)
105                 type = MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_BUFFER_STATUS_WITH_INFO;
106         else if (stream_type == PLAYER_STREAM_TYPE_AUDIO)
107                 type = MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS_WITH_INFO;
108         else {
109                 LOGE("PLAYER_ERROR_INVALID_PARAMETER(type : %d)", stream_type);
110                 return PLAYER_ERROR_INVALID_PARAMETER;
111         }
112
113         player_msg_send2(api, pc, ret_buf, ret, INT, type, INT, set);
114
115         if (ret == PLAYER_ERROR_NONE) {
116                 pc->cb_info->user_cb[type] = callback;
117                 pc->cb_info->user_data[type] = user_data;
118                 LOGI("Event type : %d ", type);
119         }
120
121         g_free(ret_buf);
122         return ret;
123 }
124
125 static void set_null_user_cb(callback_cb_info_s * cb_info, muse_player_event_e event)
126 {
127         if (cb_info && event < MUSE_PLAYER_EVENT_TYPE_NUM) {
128                 cb_info->user_cb[event] = NULL;
129                 cb_info->user_data[event] = NULL;
130         }
131 }
132
133 static void set_null_user_cb_lock(callback_cb_info_s * cb_info, muse_player_event_e event)
134 {
135         bool lock = g_thread_self() != cb_info->event_queue.thread;
136
137         if (lock)
138                 g_mutex_lock(&cb_info->event_queue.mutex);
139
140         set_null_user_cb(cb_info, event);
141
142         if (lock)
143                 g_mutex_unlock(&cb_info->event_queue.mutex);
144 }
145
146 int player_unset_media_stream_buffer_status_cb_ex(player_h player, player_stream_type_e stream_type)
147 {
148         PLAYER_INSTANCE_CHECK(player);
149         int ret = PLAYER_ERROR_NONE;
150         player_cli_s *pc = (player_cli_s *) player;
151         muse_player_api_e api = MUSE_PLAYER_API_SET_CALLBACK;
152         char *ret_buf = NULL;
153         muse_player_event_e type;
154         int set = 0;
155
156         LOGD("ENTER");
157
158         if (stream_type == PLAYER_STREAM_TYPE_VIDEO)
159                 type = MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_VIDEO_BUFFER_STATUS_WITH_INFO;
160         else if (stream_type == PLAYER_STREAM_TYPE_AUDIO)
161                 type = MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS_WITH_INFO;
162         else {
163                 LOGE("PLAYER_ERROR_INVALID_PARAMETER(type : %d)", stream_type);
164                 return PLAYER_ERROR_INVALID_PARAMETER;
165         }
166
167         set_null_user_cb_lock(pc->cb_info, type);
168
169         player_msg_send2(api, pc, ret_buf, ret, INT, type, INT, set);
170
171         g_free(ret_buf);
172         return ret;
173 }
174
175 int player_set_media_stream_dynamic_resolution(player_h player, bool drc)
176 {
177         PLAYER_INSTANCE_CHECK(player);
178         int ret = PLAYER_ERROR_NONE;
179         muse_player_api_e api = MUSE_PLAYER_API_SET_MEDIA_STREAM_DYNAMIC_RESOLUTION;
180         player_cli_s *pc = (player_cli_s *) player;
181         char *ret_buf = NULL;
182
183         LOGD("ENTER");
184
185         player_msg_send1(api, pc, ret_buf, ret, INT, drc);
186         g_free(ret_buf);
187         return ret;
188 }
189
190 int player_set_ecore_wl_display(player_h player, player_display_type_e type, Ecore_Wl_Window *ecore_wl_window, int x, int y, int  width, int height)
191 {
192         PLAYER_INSTANCE_CHECK(player);
193         int ret = PLAYER_ERROR_NONE;
194         muse_player_api_e api = MUSE_PLAYER_API_SET_DISPLAY;
195         player_cli_s *pc = (player_cli_s *) player;
196         char *ret_buf = NULL;
197         wl_win_msg_type wl_win;
198         char *wl_win_msg = (char *)&wl_win;
199         unsigned int wl_surface_id;
200         struct wl_surface *wl_surface;
201         struct wl_display *wl_display;
202         Ecore_Wl_Window *wl_window = NULL;
203         player_private_display_type_e conv_type;
204
205         LOGD("ENTER");
206         ret = _player_convert_display_type(type, &conv_type);
207         if (ret != PLAYER_ERROR_NONE)
208                 return ret;
209
210         if (conv_type != PLAYER_PRIVATE_DISPLAY_TYPE_OVERLAY) {
211                 LOGE("Display type(%d) is not overlay", conv_type);
212                 return PLAYER_ERROR_INVALID_PARAMETER;
213         }
214         if (!ecore_wl_window)
215                 return PLAYER_ERROR_INVALID_PARAMETER;
216
217         LOGI("Wayland overlay surface type");
218         LOGD("Ecore Wayland Window handle(%p), size (%d, %d, %d, %d)", ecore_wl_window, x, y, width, height);
219         wl_window = ecore_wl_window;
220
221         /* set wl_win */
222         wl_win.type = conv_type;
223         wl_win.wl_window_x = x;
224         wl_win.wl_window_y = y;
225         wl_win.wl_window_width = width;
226         wl_win.wl_window_height = height;
227
228         wl_surface = (struct wl_surface *)ecore_wl_window_surface_get(wl_window);
229         /* get wl_display */
230         wl_display = (struct wl_display *)ecore_wl_display_get();
231
232         if (!pc->wlclient) {
233                 ret = _wl_client_create(&pc->wlclient);
234                 if (ret != MM_ERROR_NONE) {
235                         LOGE("Wayland client create failure");
236                         return ret;
237                 }
238         }
239
240         if (wl_surface && wl_display) {
241                 LOGD("surface = %p, wl_display = %p", wl_surface, wl_display);
242                 wl_surface_id = _wl_client_get_wl_window_wl_surface_id(pc->wlclient, wl_surface, wl_display);
243                 LOGD("wl_surface_id = %d", wl_surface_id);
244                 wl_win.wl_surface_id = wl_surface_id;
245                 LOGD("wl_win.wl_surface_id = %d", wl_win.wl_surface_id);
246         } else {
247                 LOGE("Fail to get wl_surface or wl_display");
248                 return PLAYER_ERROR_INVALID_OPERATION;
249         }
250
251         if (pc->wlclient) {
252                 g_free(pc->wlclient);
253                 pc->wlclient = NULL;
254         }
255
256         player_msg_send_array(api, pc, ret_buf, ret, wl_win_msg, sizeof(wl_win_msg_type), sizeof(char));
257
258         g_free(ret_buf);
259
260         return ret;
261 }
262
263 int player_set_next_uri(player_h player, const char *uri)
264 {
265         PLAYER_INSTANCE_CHECK(player);
266         PLAYER_NULL_ARG_CHECK(uri);
267         int ret = PLAYER_ERROR_NONE;
268         muse_player_api_e api = MUSE_PLAYER_API_SET_NEXT_URI;
269         player_cli_s *pc = (player_cli_s *) player;
270         char *ret_buf = NULL;
271         char path[MAX_URL_LEN] = {0, };
272
273         LOGD("ENTER");
274
275         if (_player_get_origin_internal_path(uri, path) != PLAYER_ERROR_NONE)
276                 return PLAYER_ERROR_INVALID_PARAMETER;
277
278         player_msg_send1(api, pc, ret_buf, ret, STRING, path);
279
280         g_free(ret_buf);
281         return ret;
282 }
283
284 int player_get_next_uri(player_h player, char **uri)
285 {
286         PLAYER_INSTANCE_CHECK(player);
287         PLAYER_NULL_ARG_CHECK(uri);
288         int ret = PLAYER_ERROR_NONE;
289         muse_player_api_e api = MUSE_PLAYER_API_GET_NEXT_URI;
290         player_cli_s *pc = (player_cli_s *) player;
291         char *ret_buf = NULL;
292         char next_uri[MUSE_MSG_MAX_LENGTH] = { 0, };
293
294         LOGD("ENTER");
295
296         player_msg_send(api, pc, ret_buf, ret);
297         if (ret == PLAYER_ERROR_NONE) {
298                 player_msg_get_string(next_uri, ret_buf);
299
300                 char dest[MUSE_MSG_MAX_LENGTH] = {0,};
301                 if (storage_get_compat_internal_path(next_uri, sizeof(dest), dest) < 0) {
302                         /* cannot convert path. use the original one. */
303                         *uri = strndup(next_uri, MUSE_MSG_MAX_LENGTH);
304                 } else {
305                         /* need to use converted path. */
306                         LOGD("Converted path : %s -> %s", next_uri, dest);
307                         *uri = strndup(dest, MUSE_MSG_MAX_LENGTH);
308                 }
309         }
310         g_free(ret_buf);
311         return ret;
312 }
313
314 int player_set_gapless(player_h player, bool gapless)
315 {
316         PLAYER_INSTANCE_CHECK(player);
317         int ret = PLAYER_ERROR_NONE;
318         muse_player_api_e api = MUSE_PLAYER_API_SET_GAPLESS;
319         player_cli_s *pc = (player_cli_s *) player;
320         char *ret_buf = NULL;
321
322         LOGD("ENTER");
323
324         player_msg_send1(api, pc, ret_buf, ret, INT, gapless);
325         g_free(ret_buf);
326         return ret;
327 }
328
329 int player_is_gapless(player_h player, bool *gapless)
330 {
331         PLAYER_INSTANCE_CHECK(player);
332         PLAYER_NULL_ARG_CHECK(gapless);
333         int ret = PLAYER_ERROR_NONE;
334         muse_player_api_e api = MUSE_PLAYER_API_IS_GAPLESS;
335         player_cli_s *pc = (player_cli_s *) player;
336         char *ret_buf = NULL;
337         int value = 0;
338
339         LOGD("ENTER");
340
341         player_msg_send(api, pc, ret_buf, ret);
342         if (ret == PLAYER_ERROR_NONE) {
343                 player_msg_get(value, ret_buf);
344                 *gapless = value;
345         }
346         g_free(ret_buf);
347         return ret;
348 }
349
350 int player_enable_tsurf_pool(player_h player, bool enable)
351 {
352         PLAYER_INSTANCE_CHECK(player);
353         int ret = PLAYER_ERROR_NONE;
354         player_cli_s *pc = (player_cli_s *) player;
355
356         LOGD("ENTER enable:%d", enable);
357
358         if (pc && pc->cb_info) {
359                 pc->cb_info->use_tsurf_pool = enable;
360         } else {
361                 LOGE("failed to enable the tbm surf pool");
362                 ret = PLAYER_ERROR_INVALID_OPERATION;
363         }
364
365         return ret;
366 }
367
368 int player_is_enabled_tsurf_pool(player_h player, bool *enabled)
369 {
370         PLAYER_INSTANCE_CHECK(player);
371         PLAYER_NULL_ARG_CHECK(enabled);
372         int ret = PLAYER_ERROR_NONE;
373         player_cli_s *pc = (player_cli_s *) player;
374
375         LOGD("ENTER");
376         if (pc && pc->cb_info) {
377                 *enabled = pc->cb_info->use_tsurf_pool;
378         } else {
379                 LOGE("failed to get the tbm surf pool state");
380                 ret = PLAYER_ERROR_INVALID_OPERATION;
381         }
382
383         return ret;
384 }
385
386 int player_get_media_packet_video_frame_pool_size(player_h player, int *size)
387 {
388         PLAYER_INSTANCE_CHECK(player);
389         PLAYER_NULL_ARG_CHECK(size);
390
391         int ret = PLAYER_ERROR_NONE;
392         muse_player_api_e api = MUSE_PLAYER_API_GET_MEDIA_PACKET_VIDEO_FRAME_POOL_SIZE;
393         player_cli_s *pc = (player_cli_s *) player;
394         char *ret_buf = NULL;
395         int value = 0;
396
397         LOGD("ENTER");
398
399         player_msg_send(api, pc, ret_buf, ret);
400         if (ret == PLAYER_ERROR_NONE) {
401                 player_msg_get(value, ret_buf);
402                 *size = value;
403                 pc->cb_info->video_frame_pool_size = value;
404                 LOGD("packet pool size : %d", *size);
405         }
406         g_free(ret_buf);
407         return ret;
408 }
409
410 int player_enable_media_packet_video_frame_decoded_cb(player_h player, bool enable)
411 {
412         PLAYER_INSTANCE_CHECK(player);
413         int ret = PLAYER_ERROR_NONE;
414         muse_player_api_e api = MUSE_PLAYER_API_ENABLE_MEDIA_PACKET_VIDEO_FRAME_DECODED_CB;
415         player_cli_s *pc = (player_cli_s *) player;
416         char *ret_buf = NULL;
417
418         LOGD("ENTER");
419
420         player_msg_send1(api, pc, ret_buf, ret, INT, enable);
421         g_free(ret_buf);
422         return ret;
423 }