To avoid 64bit build error
[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 <dlog.h>
21
22 #include <mm.h>
23 #include <mm_player.h>
24 #include <mm_player_internal.h>
25 #include <mm_player_mused.h>
26 #include <mm_types.h>
27 #include <player.h>
28 #include <player_internal.h>
29 #include <player_private.h>
30
31
32 /*
33 * Internal Macros
34 */
35 #define PLAYER_SET_CALLBACK(event_type, handle, callback, user_data) \
36 do \
37 { \
38         PLAYER_INSTANCE_CHECK(handle); \
39         PLAYER_NULL_ARG_CHECK(callback); \
40         handle->user_cb[event_type] = callback; \
41         handle->user_data[event_type] = user_data; \
42         LOGI("[%s] Event type : %d ",__FUNCTION__, event_type); \
43 }while(0) \
44
45 bool  __audio_stream_callback_ex(MMPlayerAudioStreamDataType *stream, void *user_data)
46 {
47         player_s * handle = (player_s*)user_data;
48         if( handle->user_cb[_PLAYER_EVENT_TYPE_AUDIO_FRAME] )
49         {
50                 if(handle->state==PLAYER_STATE_PLAYING || handle->state==PLAYER_STATE_PAUSED)
51                 {
52                         ((player_audio_pcm_extraction_cb)handle->user_cb[_PLAYER_EVENT_TYPE_AUDIO_FRAME])((player_audio_raw_data_s *)stream, handle->user_data[_PLAYER_EVENT_TYPE_AUDIO_FRAME]);
53                 }
54                 else
55                 {
56                         LOGE("[%s] Skip stream - current state : %d", __FUNCTION__,handle->state);
57                 }
58         }
59         return TRUE;
60 }
61
62 int player_set_pcm_extraction_mode(player_h player, bool sync, player_audio_pcm_extraction_cb callback, void *user_data)
63 {
64         PLAYER_INSTANCE_CHECK(player);
65         PLAYER_NULL_ARG_CHECK(callback);
66         player_s * handle = (player_s *) player;
67         int ret = MM_ERROR_NONE;
68
69         PLAYER_STATE_CHECK(handle, PLAYER_STATE_IDLE);
70
71         ret = mm_player_set_attribute(handle->mm_handle, NULL, "pcm_extraction",TRUE, "pcm_extraction_start_msec", 0, "pcm_extraction_end_msec", 0, NULL);
72         if(ret != MM_ERROR_NONE)
73                 return __player_convert_error_code(ret,(char*)__FUNCTION__);
74
75         ret = mm_player_set_audio_stream_callback_ex(handle->mm_handle, sync,  __audio_stream_callback_ex, (void*)handle);
76         if(ret != MM_ERROR_NONE)
77                 return __player_convert_error_code(ret,(char*)__FUNCTION__);
78
79         PLAYER_SET_CALLBACK(_PLAYER_EVENT_TYPE_AUDIO_FRAME, handle, callback, user_data);
80         return PLAYER_ERROR_NONE;
81 }
82
83 int player_set_pcm_spec(player_h player, const char *format, int samplerate, int channel)
84 {
85         PLAYER_INSTANCE_CHECK(player);
86
87         player_s * handle = (player_s *) player;
88         int ret = MM_ERROR_NONE;
89
90         LOGE("[%s] player_set_pcm_spec %s %d %d", __FUNCTION__, format, samplerate, channel);
91         ret = mm_player_set_attribute(handle->mm_handle, NULL, "pcm_audioformat", format , strlen(format), NULL);
92         if(ret != MM_ERROR_NONE)
93                 return __player_convert_error_code(ret,(char*)__FUNCTION__);
94
95         ret = mm_player_set_pcm_spec(handle->mm_handle, samplerate, channel);
96         if(ret != MM_ERROR_NONE)
97                 return __player_convert_error_code(ret,(char*)__FUNCTION__);
98
99         return PLAYER_ERROR_NONE;
100 }
101
102 /*
103 * Internal Implementation for mused
104 */
105 int player_set_shm_stream_path_for_mused (player_h player, const char *stream_path)
106 {
107         PLAYER_INSTANCE_CHECK(player);
108         PLAYER_NULL_ARG_CHECK(stream_path);
109
110         player_s * handle = (player_s *) player;
111
112         if(mm_player_set_shm_stream_path(handle->mm_handle, stream_path)
113                         != MM_ERROR_NONE) {
114                 LOGE("Fail to set attribute stream path");
115                 return PLAYER_ERROR_INVALID_OPERATION;
116         }
117         return PLAYER_ERROR_NONE;
118 }
119
120 static MMDisplaySurfaceType __player_mused_convet_display_type(player_display_type_e type)
121 {
122         switch(type) {
123         case PLAYER_DISPLAY_TYPE_OVERLAY:
124                 return MM_DISPLAY_SURFACE_REMOTE;
125 #ifdef TIZEN_MOBILE
126         case PLAYER_DISPLAY_TYPE_EVAS:
127                 return MM_DISPLAY_SURFACE_EVAS;
128 #endif
129         case PLAYER_DISPLAY_TYPE_NONE:
130                 return MM_DISPLAY_SURFACE_NULL;
131         default :
132                 return MM_DISPLAY_SURFACE_NULL;
133         }
134 }
135
136
137 #ifdef HAVE_WAYLAND
138 int player_set_display_wl_for_mused(player_h player, player_display_type_e type, intptr_t surface,
139                 int x, int y, int w, int h)
140 {
141         PLAYER_INSTANCE_CHECK(player);
142         player_s * handle = (player_s *) player;
143         void *set_handle = NULL;
144         MMDisplaySurfaceType mmType = __player_mused_convet_display_type(type);
145
146         int ret;
147         if (!__player_state_validate(handle, PLAYER_STATE_IDLE))
148         {
149                 LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state);
150                 return PLAYER_ERROR_INVALID_STATE;
151         }
152         if (handle->is_set_pixmap_cb)
153         {
154                 if (handle->state < PLAYER_STATE_READY)
155                 {
156                         /* just set below and go to "changing surface case" */
157                         handle->is_set_pixmap_cb = false;
158                 }
159                 else
160                 {
161                         LOGE("[%s] pixmap callback was set, try it again after calling player_unprepare()" ,__FUNCTION__,PLAYER_ERROR_INVALID_OPERATION);
162                         LOGE("[%s] PLAYER_ERROR_INVALID_OPERATION(0x%08x)" ,__FUNCTION__,PLAYER_ERROR_INVALID_OPERATION);
163                         return PLAYER_ERROR_INVALID_OPERATION;
164                 }
165         }
166
167         void* temp = NULL;
168         if (type == PLAYER_DISPLAY_TYPE_NONE)
169         {
170                 /* NULL surface */
171                 handle->display_handle = 0;
172                 handle->display_type = type;
173                 set_handle = NULL;
174         }
175         else
176         {
177                 /* get handle from overlay or evas surface */
178                 temp = handle->display_handle;
179                 if (type == PLAYER_DISPLAY_TYPE_OVERLAY)
180                 {
181                         LOGI("Wayland overlay surface type");
182                         handle->display_handle = (void *)surface;
183                         set_handle = &(handle->display_handle);
184                 } else {
185                         LOGE("invalid surface type");
186                         return PLAYER_ERROR_INVALID_PARAMETER;
187                 }
188         }
189
190         /* set display handle */
191         if (handle->display_type == PLAYER_DISPLAY_TYPE_NONE || type == handle->display_type) // first time or same type
192         {
193                 LOGW("first time or same type");
194                 ret = mm_player_set_attribute(handle->mm_handle, NULL,
195                         "display_surface_type", mmType,
196                         "display_overlay", set_handle,
197                         sizeof(void *), (char*)NULL);
198
199                 if (ret != MM_ERROR_NONE)
200                 {
201                         handle->display_handle = temp;
202                         LOGE("[%s] Failed to display surface change :%d",__FUNCTION__,ret);
203                 }
204                 else
205                 {
206                         if (type != PLAYER_DISPLAY_TYPE_NONE)
207                         {
208                                 handle->display_type = type;
209                                 LOGI("[%s] video display has been changed- type :%d, addr : 0x%x",
210                                         __FUNCTION__,handle->display_type, handle->display_handle);
211                         }
212                         else
213                                 LOGI("NULL surface");
214                 }
215                 LOGI("get window rectangle: x(%d) y(%d) width(%d) height(%d)", x, y, w, h);
216                 ret = mm_player_set_attribute(handle->mm_handle, NULL,
217                         "wl_window_render_x", x,
218                         "wl_window_render_y", y,
219                         "wl_window_render_width", w,
220                         "wl_window_render_height", h,
221                         (char*)NULL);
222
223                 if (ret != MM_ERROR_NONE)
224                 {
225                         handle->display_handle = temp;
226                         LOGE("[%s] Failed to set wl_window render rectangle :%d",__FUNCTION__,ret);
227                 }
228         }
229         else //changing surface case
230         {
231                 ret = mm_player_change_videosink(handle->mm_handle, mmType, set_handle);
232                 if (ret != MM_ERROR_NONE)
233                 {
234                         handle->display_handle = temp;
235                         if(ret == MM_ERROR_NOT_SUPPORT_API)
236                         {
237                                 LOGE("[%s] change video sink is not available.",__FUNCTION__);
238                                 ret = PLAYER_ERROR_NONE;
239                         }
240                         else
241                         {
242                                 LOGE("[%s] Failed to display surface change :%d",__FUNCTION__,ret);
243                         }
244                 }
245                 else
246                 {
247                         handle->display_type = type;
248                         LOGI("[%s] video display has been changed- type :%d, addr : 0x%x",
249                                 __FUNCTION__,handle->display_type, handle->display_handle);
250                 }
251         }
252
253         if(ret != MM_ERROR_NONE)
254         {
255                 handle->display_type = PLAYER_DISPLAY_TYPE_NONE;
256                 return __player_convert_error_code(ret,(char*)__FUNCTION__);
257         }
258         else
259         {
260                 return PLAYER_ERROR_NONE;
261         }
262 }
263
264 #else
265
266 int player_set_display_for_mused(player_h player, player_display_type_e type, unsigned int xhandle)
267 {
268         PLAYER_INSTANCE_CHECK(player);
269         player_s * handle = (player_s *) player;
270         void *set_handle = NULL;
271         MMDisplaySurfaceType mmType = __player_mused_convet_display_type(type);
272
273         int ret;
274         if (!__player_state_validate(handle, PLAYER_STATE_IDLE))
275         {
276                 LOGE("[%s] PLAYER_ERROR_INVALID_STATE(0x%08x) : current state - %d" ,__FUNCTION__,PLAYER_ERROR_INVALID_STATE, handle->state);
277                 return PLAYER_ERROR_INVALID_STATE;
278         }
279
280         if (handle->is_set_pixmap_cb)
281         {
282                 if (handle->state < PLAYER_STATE_READY)
283                 {
284                         /* just set below and go to "changing surface case" */
285                         handle->is_set_pixmap_cb = false;
286                 }
287                 else
288                 {
289                         LOGE("[%s] pixmap callback was set, try it again after calling player_unprepare()" ,__FUNCTION__,PLAYER_ERROR_INVALID_OPERATION);
290                         LOGE("[%s] PLAYER_ERROR_INVALID_OPERATION(0x%08x)" ,__FUNCTION__,PLAYER_ERROR_INVALID_OPERATION);
291                         return PLAYER_ERROR_INVALID_OPERATION;
292                 }
293         }
294
295         void* temp = NULL;
296         if (type == PLAYER_DISPLAY_TYPE_NONE)
297         {
298                 /* NULL surface */
299                 handle->display_handle = 0;
300                 handle->display_type = PLAYER_DISPLAY_TYPE_NONE;
301                 set_handle = NULL;
302         }
303         else
304         {
305                 /* get handle from overlay or evas surface */
306                 temp = handle->display_handle;
307                 if (type == PLAYER_DISPLAY_TYPE_OVERLAY /*&& !strcmp(object_type, "elm_win")*/)
308                 {
309                         /* x window overlay surface */
310                         LOGI("overlay surface type");
311                         handle->display_handle = (void *)xhandle;
312                         set_handle = &(handle->display_handle);
313                 }
314                 else
315                 {
316                         LOGE("invalid surface type");
317                         return PLAYER_ERROR_INVALID_PARAMETER;
318                 }
319         }
320
321         /* set display handle */
322         if (handle->display_type == PLAYER_DISPLAY_TYPE_NONE || type == handle->display_type) // first time or same type
323         {
324                 ret = mm_player_set_attribute(handle->mm_handle, NULL,
325                         "display_surface_type", mmType,
326                         "display_overlay", set_handle,
327                         sizeof(xhandle), (char*)NULL);
328
329                 if (ret != MM_ERROR_NONE)
330                 {
331                         handle->display_handle = temp;
332                         LOGE("[%s] Failed to display surface change :%d",__FUNCTION__,ret);
333                 }
334                 else
335                 {
336                         if (type != PLAYER_DISPLAY_TYPE_NONE)
337                         {
338                                 handle->display_type = type;
339                                 LOGI("[%s] video display has been changed- type :%d, addr : 0x%x",
340                                         __FUNCTION__,handle->display_type, handle->display_handle);
341                         }
342                         else
343                                 LOGI("NULL surface");
344                 }
345         }
346         else //changing surface case
347         {
348                 ret = mm_player_change_videosink(handle->mm_handle, mmType, set_handle);
349                 if (ret != MM_ERROR_NONE)
350                 {
351                         handle->display_handle = temp;
352                         if(ret == MM_ERROR_NOT_SUPPORT_API)
353                         {
354                                 LOGE("[%s] change video sink is not available.",__FUNCTION__);
355                                 ret = PLAYER_ERROR_NONE;
356                         }
357                         else
358                         {
359                                 LOGE("[%s] Failed to display surface change :%d",__FUNCTION__,ret);
360                         }
361                 }
362                 else
363                 {
364                         handle->display_type = type;
365                         LOGI("[%s] video display has been changed- type :%d, addr : 0x%x",
366                                 __FUNCTION__,handle->display_type, handle->display_handle);
367                 }
368         }
369
370         if(ret != MM_ERROR_NONE)
371         {
372                 handle->display_type = PLAYER_DISPLAY_TYPE_NONE;
373                 return __player_convert_error_code(ret,(char*)__FUNCTION__);
374         }
375         else
376         {
377                 return PLAYER_ERROR_NONE;
378         }
379 }
380 #endif
381
382 int player_get_raw_video_caps(player_h player, char **caps)
383 {
384         int ret;
385         PLAYER_INSTANCE_CHECK(player);
386         PLAYER_NULL_ARG_CHECK(caps);
387         player_s * handle = (player_s *) player;
388
389         if (handle->display_type == PLAYER_DISPLAY_TYPE_NONE)
390                 return PLAYER_ERROR_INVALID_STATE;
391
392         ret = mm_player_get_raw_video_caps(handle->mm_handle, caps);
393         if(ret != MM_ERROR_NONE) {
394                 return __player_convert_error_code(ret,(char*)__FUNCTION__);
395         }
396
397         return PLAYER_ERROR_NONE;
398 }