e9f230ae4847aa528702dc6ab8a836907184f56e
[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 <gst/gst.h>
25 #include <gst/gstutils.h>
26 #include <glib.h>
27
28 int _mmplayer_360_set_enable(MMHandleType player, bool enable)
29 {
30         ((mm_player_t*) player)->is_video360_enabled = enable;
31
32         if (((mm_player_t*) player)->is_content_spherical &&
33                         ((mm_player_t*) player)->is_video360_plugin_used) {
34                 /* We will get here if player is pending ready or ready and above */
35                 g_object_set(G_OBJECT(((mm_player_t*) player)->pipeline->videobin[MMPLAYER_V_360].gst),
36                                 "passthrough", !enable, NULL);
37                 return MM_ERROR_NONE;
38         }
39
40         return ((mm_player_t*) player)->state < MM_PLAYER_STATE_READY ? MM_ERROR_NONE : MM_ERROR_PLAYER_INTERNAL;
41 }
42
43 int _mmplayer_360_is_enabled(MMHandleType player, bool *enabled)
44 {
45         if (((mm_player_t*) player)->state < MM_PLAYER_STATE_READY) {
46                 *enabled = ((mm_player_t*) player)->is_video360_enabled;
47                 return MM_ERROR_NONE;
48         }
49
50         if (((mm_player_t*) player)->is_content_spherical &&
51                         ((mm_player_t*) player)->is_video360_plugin_used) {
52                 g_object_get(G_OBJECT(((mm_player_t*) player)->pipeline->videobin[MMPLAYER_V_360].gst),
53                                 "passthrough", enabled, NULL);
54                 *enabled = !(*enabled);
55                 return MM_ERROR_NONE;
56         }
57
58         return MM_ERROR_PLAYER_INTERNAL;
59 }
60
61 int _mmplayer_360_set_direction_of_view(MMHandleType player, float yaw, float pitch)
62 {
63         if (yaw > M_PI || yaw < -M_PI || pitch > M_PI_2 || pitch < -M_PI_2)
64                 return MM_ERROR_INVALID_ARGUMENT;
65
66         ((mm_player_t*) player)->video360_yaw_radians = yaw;
67         ((mm_player_t*) player)->video360_pitch_radians = pitch;
68
69         if (((mm_player_t*) player)->is_content_spherical) {
70                 /* We will get here if player is pending ready or ready and above */
71                 if (((mm_player_t*) player)->is_video360_plugin_used) {
72                         g_object_set(G_OBJECT(((mm_player_t*) player)->pipeline->videobin[MMPLAYER_V_360].gst),
73                                         "pose-yaw", (int) (yaw * 180.0f / M_PI),
74                                         "pose-pitch", (int) (pitch * 180.0f / M_PI), NULL);
75                 }
76                 if (((mm_player_t*) player)->is_openal_plugin_used) {
77                         g_object_set(G_OBJECT(((mm_player_t*) player)->pipeline->audiobin[MMPLAYER_A_SINK].gst),
78                                         "source-orientation-y", (int) (yaw * 180.0f / M_PI),
79                                         "source-orientation-x", (int) (pitch * 180.0f / M_PI), NULL);
80                 }
81                 return MM_ERROR_NONE;
82         }
83
84         return ((mm_player_t*) player)->state < MM_PLAYER_STATE_READY ? MM_ERROR_NONE : MM_ERROR_PLAYER_INTERNAL;
85 }
86
87 int _mmplayer_360_get_direction_of_view(MMHandleType player, float *yaw, float *pitch)
88 {
89         int yaw_degrees, pitch_degrees;
90
91         if (((mm_player_t*) player)->state < MM_PLAYER_STATE_READY) {
92                 *yaw = ((mm_player_t*) player)->video360_yaw_radians;
93                 *pitch = ((mm_player_t*) player)->video360_pitch_radians;
94                 return MM_ERROR_NONE;
95         }
96
97         if (((mm_player_t*) player)->is_content_spherical &&
98                         ((mm_player_t*) player)->is_video360_plugin_used) {
99                 g_object_get(G_OBJECT(((mm_player_t*) player)->pipeline->videobin[MMPLAYER_V_360].gst),
100                                 "pose-yaw", &yaw_degrees, "pose-pitch", &pitch_degrees, NULL);
101                 *yaw = M_PI * yaw_degrees / 180.0f;
102                 *pitch = M_PI * pitch_degrees / 180.0f;
103                 return MM_ERROR_NONE;
104         }
105
106         return MM_ERROR_PLAYER_INTERNAL;
107 }
108
109 int _mmplayer_360_set_zoom(MMHandleType player, float level)
110 {
111         if (level < 1.0f || level > VIDEO360_MAX_ZOOM)
112                 return MM_ERROR_INVALID_ARGUMENT;
113
114         ((mm_player_t*) player)->video360_zoom = 1.0f / level;
115
116         if (((mm_player_t*) player)->is_content_spherical &&
117                         ((mm_player_t*) player)->is_video360_plugin_used) {
118                 /* We will get here if player is pending ready or ready and above */
119                 g_object_set(G_OBJECT(((mm_player_t*) player)->pipeline->videobin[MMPLAYER_V_360].gst),
120                                 "zoom", 1.0f / level, NULL);
121                 return MM_ERROR_NONE;
122         }
123
124         return ((mm_player_t*) player)->state < MM_PLAYER_STATE_READY ? MM_ERROR_NONE : MM_ERROR_PLAYER_INTERNAL;
125 }
126
127 int _mmplayer_360_get_zoom(MMHandleType player, float *level)
128 {
129         float current_zoom;
130
131         if (((mm_player_t*) player)->state < MM_PLAYER_STATE_READY) {
132                 *level = 1.0f / ((mm_player_t*) player)->video360_zoom;
133                 return MM_ERROR_NONE;
134         }
135
136         if (((mm_player_t*) player)->is_content_spherical &&
137                         ((mm_player_t*) player)->is_video360_plugin_used) {
138                 g_object_get(G_OBJECT(((mm_player_t*) player)->pipeline->videobin[MMPLAYER_V_360].gst),
139                                 "zoom", &current_zoom, NULL);
140                 *level = 1.0f / current_zoom;
141                 return MM_ERROR_NONE;
142         }
143
144         return MM_ERROR_PLAYER_INTERNAL;
145 }
146
147 int _mmplayer_360_set_field_of_view(MMHandleType player, int horizontal_degrees, int vertical_degrees)
148 {
149         if (horizontal_degrees < 1 || horizontal_degrees > 360 || vertical_degrees < 1 || vertical_degrees > 180)
150                 return MM_ERROR_INVALID_ARGUMENT;
151
152         ((mm_player_t*) player)->video360_horizontal_fov = horizontal_degrees;
153         ((mm_player_t*) player)->video360_vertical_fov = vertical_degrees;
154
155         if (((mm_player_t*) player)->is_content_spherical &&
156                         ((mm_player_t*) player)->is_video360_plugin_used) {
157                 /* We will get here if player is pending ready or ready and above */
158                 g_object_set(G_OBJECT(((mm_player_t*) player)->pipeline->videobin[MMPLAYER_V_360].gst),
159                                 "horizontal-fov", horizontal_degrees, "vertical-fov", vertical_degrees, NULL);
160                 return MM_ERROR_NONE;
161         }
162
163         return ((mm_player_t*) player)->state < MM_PLAYER_STATE_READY ? MM_ERROR_NONE : MM_ERROR_PLAYER_INTERNAL;
164 }
165
166 int _mmplayer_360_get_field_of_view(MMHandleType player, int *horizontal_degrees, int *vertical_degrees)
167 {
168         if (((mm_player_t*) player)->state < MM_PLAYER_STATE_READY) {
169                 *horizontal_degrees = ((mm_player_t*) player)->video360_horizontal_fov;
170                 *vertical_degrees = ((mm_player_t*) player)->video360_vertical_fov;
171                 return MM_ERROR_NONE;
172         }
173
174         if (((mm_player_t*) player)->is_content_spherical &&
175                         ((mm_player_t*) player)->is_video360_plugin_used) {
176                 g_object_get(G_OBJECT(((mm_player_t*) player)->pipeline->videobin[MMPLAYER_V_360].gst),
177                                 "horizontal-fov", horizontal_degrees, "vertical-fov", vertical_degrees, NULL);
178                 return MM_ERROR_NONE;
179         }
180
181         return MM_ERROR_PLAYER_INTERNAL;
182 }