[0.6.155] Changed variable type bool to gboolean type
[platform/core/multimedia/libmm-player.git] / src / mm_player_360.c
1 /*
2  * libmm-player
3  *
4  * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <mm_attrs.h>
21 #include <mm_error.h>
22 #include "mm_player_priv.h"
23 #include "mm_player_360.h"
24 #include "mm_player_utils.h"
25 #include <gst/gst.h>
26 #include <gst/gstutils.h>
27 #include <glib.h>
28
29 static bool
30 __mmplayer_check_video_360_used(mm_player_t* player)
31 {
32         /* check video 360 plugin is created */
33         MMPLAYER_RETURN_VAL_IF_FAIL(player &&
34                 player->pipeline &&
35                 player->pipeline->videobin &&
36                 player->pipeline->videobin[MMPLAYER_V_BIN].gst &&
37                 player->pipeline->videobin[MMPLAYER_V_360].gst,
38                 false);
39
40         return true;
41 }
42
43 static bool
44 __mmplayer_check_audio_sink(mm_player_t* player)
45 {
46         /* check audio sink is created */
47         MMPLAYER_RETURN_VAL_IF_FAIL(player &&
48                 player->pipeline &&
49                 player->pipeline->videobin &&
50                 player->pipeline->videobin[MMPLAYER_A_BIN].gst &&
51                 player->pipeline->videobin[MMPLAYER_A_SINK].gst,
52                 false);
53
54         return true;
55 }
56
57 int _mmplayer_360_is_content_spherical(MMHandleType hplayer, bool *is_spherical)
58 {
59         mm_player_t* player = (mm_player_t*) hplayer;
60
61         MMPLAYER_FENTER();
62         MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
63         MMPLAYER_RETURN_VAL_IF_FAIL(is_spherical, MM_ERROR_INVALID_ARGUMENT);
64
65         LOGD("state %s, spherical info %d",
66                         MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
67
68         if (player->state < MM_PLAYER_STATE_READY) {
69                 *is_spherical = false;
70                 return MM_ERROR_PLAYER_INVALID_STATE;
71         }
72
73         *is_spherical = (bool)player->is_content_spherical;
74
75         MMPLAYER_FLEAVE();
76         return MM_ERROR_NONE;
77 }
78
79 int _mmplayer_360_set_enabled(MMHandleType hplayer, bool enabled)
80 {
81         mm_player_t* player = (mm_player_t*) hplayer;
82
83         MMPLAYER_FENTER();
84         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
85
86         LOGD("state %s, spherical info %d",
87                         MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
88
89         player->is_video360_enabled = (gboolean)enabled;
90
91         if (player->is_content_spherical && __mmplayer_check_video_360_used(player)) {
92                 /* We will get here if player is pending ready or ready and above */
93                 LOGD("set enabled %d", player->is_video360_enabled);
94                 g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
95                                 "passthrough", !player->is_video360_enabled, NULL);
96         }
97
98         MMPLAYER_FLEAVE();
99         return MM_ERROR_NONE;
100 }
101
102 int _mmplayer_360_is_enabled(MMHandleType hplayer, bool *enabled)
103 {
104         mm_player_t* player = (mm_player_t*) hplayer;
105         gboolean is_enabled;
106
107         MMPLAYER_FENTER();
108         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
109         MMPLAYER_RETURN_VAL_IF_FAIL(enabled, MM_ERROR_INVALID_ARGUMENT);
110
111         LOGD("state %s, spherical info %d",
112                         MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
113
114         if (player->is_content_spherical && __mmplayer_check_video_360_used(player)) {
115                 g_object_get(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
116                                 "passthrough", &is_enabled, NULL);
117                 *enabled = !((bool)is_enabled);
118         } else {
119                 *enabled = (bool)player->is_video360_enabled;
120         }
121
122         LOGD("get enabled %d", *enabled);
123
124         MMPLAYER_FLEAVE();
125         return MM_ERROR_NONE;
126 }
127
128 int _mmplayer_360_set_direction_of_view(MMHandleType hplayer, float yaw, float pitch)
129 {
130         mm_player_t* player = (mm_player_t*) hplayer;
131
132         MMPLAYER_FENTER();
133         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
134
135         if (yaw > (float)(M_PI) || yaw < (float)(-M_PI) || pitch > (float)(M_PI_2) || pitch < (float)(-M_PI_2)) {
136                 LOGE("invalid argument %f, %f", yaw, pitch);
137                 return MM_ERROR_INVALID_ARGUMENT;
138         }
139
140         LOGD("state %s, spherical info %d",
141                         MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
142
143         player->video360_yaw_radians = yaw;
144         player->video360_pitch_radians = pitch;
145
146         if (player->is_content_spherical) {
147                 /* We will get here if player is pending ready or ready and above */
148                 if (__mmplayer_check_video_360_used(player)) {
149                         LOGD("set yaw %f, pitch %f for video", yaw, pitch);
150                         g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
151                                         "pose-yaw", (int) (yaw * 180.0f / M_PI),
152                                         "pose-pitch", (int) (pitch * 180.0f / M_PI), NULL);
153                 }
154                 if (player->is_openal_plugin_used && __mmplayer_check_audio_sink(player)) {
155                         g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst),
156                                         "source-orientation-y", (int) (yaw * 180.0f / M_PI),
157                                         "source-orientation-x", (int) (pitch * 180.0f / M_PI), NULL);
158                 }
159         }
160
161         MMPLAYER_FLEAVE();
162         return MM_ERROR_NONE;
163 }
164
165 int _mmplayer_360_get_direction_of_view(MMHandleType hplayer, float *yaw, float *pitch)
166 {
167         mm_player_t* player = (mm_player_t*) hplayer;
168         int yaw_degrees = 0;
169         int pitch_degrees = 0;
170
171         MMPLAYER_FENTER();
172         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
173         MMPLAYER_RETURN_VAL_IF_FAIL(yaw && pitch, MM_ERROR_INVALID_ARGUMENT);
174
175         LOGD("state %s, spherical info %d",
176                         MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
177
178         if (player->is_content_spherical && __mmplayer_check_video_360_used(player)) {
179                 g_object_get(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
180                                 "pose-yaw", &yaw_degrees, "pose-pitch", &pitch_degrees, NULL);
181                 *yaw = M_PI * yaw_degrees / 180.0f;
182                 *pitch = M_PI * pitch_degrees / 180.0f;
183
184                 LOGD("get yaw %f, pitch %f", yaw, pitch);
185                 return MM_ERROR_NONE;
186         }
187
188         *yaw = player->video360_yaw_radians;
189         *pitch = player->video360_pitch_radians;
190
191         MMPLAYER_FLEAVE();
192         return MM_ERROR_NONE;
193 }
194
195 int _mmplayer_360_set_zoom(MMHandleType hplayer, float level)
196 {
197         mm_player_t* player = (mm_player_t*) hplayer;
198
199         MMPLAYER_FENTER();
200         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
201
202         if (level < 1.0f || level > VIDEO360_MAX_ZOOM) {
203                 LOGE("invalid argument %f", level);
204                 return MM_ERROR_INVALID_ARGUMENT;
205         }
206
207         LOGD("state %s, spherical info %d",
208                         MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
209
210         player->video360_zoom = level;
211
212         if (player->is_content_spherical && __mmplayer_check_video_360_used(player)) {
213                 /* We will get here if player is pending ready or ready and above */
214
215                 LOGD("set level %f", level);
216                 g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
217                                 "zoom", 1.0f / level, NULL);
218         }
219
220         MMPLAYER_FLEAVE();
221         return MM_ERROR_NONE;
222 }
223
224 int _mmplayer_360_get_zoom(MMHandleType hplayer, float *level)
225 {
226         mm_player_t* player = (mm_player_t*) hplayer;
227         float current_zoom = 0.0;
228
229         MMPLAYER_FENTER();
230         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
231         MMPLAYER_RETURN_VAL_IF_FAIL(level, MM_ERROR_INVALID_ARGUMENT);
232
233         LOGD("state %s, spherical info %d",
234                         MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
235
236         if (player->is_content_spherical && __mmplayer_check_video_360_used(player)) {
237                 g_object_get(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
238                                 "zoom", &current_zoom, NULL);
239                 *level = 1.0f / current_zoom;
240
241                 LOGD("get level %f", *level);
242                 return MM_ERROR_NONE;
243         }
244
245         *level = player->video360_zoom;
246
247         MMPLAYER_FLEAVE();
248         return MM_ERROR_NONE;
249 }
250
251 int _mmplayer_360_set_field_of_view(MMHandleType hplayer, int horizontal_degrees, int vertical_degrees)
252 {
253         mm_player_t* player = (mm_player_t*) hplayer;
254
255         MMPLAYER_FENTER();
256         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
257
258         if (horizontal_degrees < 1 || horizontal_degrees > 360 || vertical_degrees < 1 || vertical_degrees > 180) {
259                 LOGE("invalid argument %d, %d", horizontal_degrees, vertical_degrees);
260                 return MM_ERROR_INVALID_ARGUMENT;
261         }
262
263         LOGD("state %s, spherical info %d",
264                         MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
265
266         player->video360_horizontal_fov = horizontal_degrees;
267         player->video360_vertical_fov = vertical_degrees;
268
269         if (player->is_content_spherical && __mmplayer_check_video_360_used(player)) {
270                 /* We will get here if player is pending ready or ready and above */
271                 LOGD("set h-fov %d, v-fov %d", horizontal_degrees, vertical_degrees);
272                 g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
273                                 "horizontal-fov", horizontal_degrees, "vertical-fov", vertical_degrees, NULL);
274         }
275
276         MMPLAYER_FLEAVE();
277         return MM_ERROR_NONE;
278 }
279
280 int _mmplayer_360_get_field_of_view(MMHandleType hplayer, int *horizontal_degrees, int *vertical_degrees)
281 {
282         mm_player_t* player = (mm_player_t*) hplayer;
283
284         MMPLAYER_FENTER();
285         MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
286         MMPLAYER_RETURN_VAL_IF_FAIL(horizontal_degrees && vertical_degrees, MM_ERROR_INVALID_ARGUMENT);
287
288         LOGD("state %s, spherical info %d",
289                         MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
290
291         if (player->is_content_spherical && __mmplayer_check_video_360_used(player)) {
292                 g_object_get(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
293                                 "horizontal-fov", horizontal_degrees, "vertical-fov", vertical_degrees, NULL);
294
295                 LOGD("get h-fov %d, v-fov %d", *horizontal_degrees, *vertical_degrees);
296                 return MM_ERROR_NONE;
297         }
298
299         *horizontal_degrees = player->video360_horizontal_fov;
300         *vertical_degrees = player->video360_vertical_fov;
301
302         MMPLAYER_FLEAVE();
303         return MM_ERROR_NONE;
304 }