4 * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include "mm_player_priv.h"
23 #include "mm_player_360.h"
24 #include "mm_player_utils.h"
26 #include <gst/gstutils.h>
30 __mmplayer_check_video_360_used(mm_player_t *player)
32 /* check video 360 plugin is created */
33 MMPLAYER_RETURN_VAL_IF_FAIL(player &&
35 player->pipeline->videobin &&
36 player->pipeline->videobin[MMPLAYER_V_BIN].gst &&
37 player->pipeline->videobin[MMPLAYER_V_360].gst,
44 __mmplayer_check_audio_sink(mm_player_t *player)
46 /* check audio sink is created */
47 MMPLAYER_RETURN_VAL_IF_FAIL(player &&
49 player->pipeline->videobin &&
50 player->pipeline->videobin[MMPLAYER_A_BIN].gst &&
51 player->pipeline->videobin[MMPLAYER_A_SINK].gst,
58 _mmplayer_360_is_content_spherical(MMHandleType hplayer, bool *is_spherical)
60 mm_player_t *player = (mm_player_t *)hplayer;
63 MMPLAYER_RETURN_VAL_IF_FAIL(player && player->pipeline, MM_ERROR_PLAYER_NOT_INITIALIZED);
64 MMPLAYER_RETURN_VAL_IF_FAIL(is_spherical, MM_ERROR_INVALID_ARGUMENT);
66 LOGD("state %s, spherical info %d",
67 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
69 if (player->state < MM_PLAYER_STATE_READY) {
70 *is_spherical = false;
71 return MM_ERROR_PLAYER_INVALID_STATE;
74 *is_spherical = (bool)player->is_content_spherical;
81 _mmplayer_360_set_enabled(MMHandleType hplayer, bool enabled)
83 mm_player_t *player = (mm_player_t *)hplayer;
86 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
88 LOGD("state %s, spherical info %d",
89 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
91 player->is_video360_enabled = (gboolean)enabled;
93 if (player->is_content_spherical && __mmplayer_check_video_360_used(player)) {
94 /* We will get here if player is pending ready or ready and above */
95 LOGD("set enabled %d", player->is_video360_enabled);
96 g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
97 "passthrough", !player->is_video360_enabled, NULL);
101 return MM_ERROR_NONE;
105 _mmplayer_360_is_enabled(MMHandleType hplayer, bool *enabled)
107 mm_player_t *player = (mm_player_t *)hplayer;
111 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
112 MMPLAYER_RETURN_VAL_IF_FAIL(enabled, MM_ERROR_INVALID_ARGUMENT);
114 LOGD("state %s, spherical info %d",
115 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
117 if (player->is_content_spherical && __mmplayer_check_video_360_used(player)) {
118 g_object_get(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
119 "passthrough", &is_enabled, NULL);
120 *enabled = !((bool)is_enabled);
122 *enabled = (bool)player->is_video360_enabled;
125 LOGD("get enabled %d", *enabled);
128 return MM_ERROR_NONE;
132 _mmplayer_360_set_direction_of_view(MMHandleType hplayer, float yaw, float pitch)
134 mm_player_t *player = (mm_player_t *)hplayer;
137 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
139 if (yaw > (float)(M_PI) || yaw < (float)(-M_PI) || pitch > (float)(M_PI_2) || pitch < (float)(-M_PI_2)) {
140 LOGE("invalid argument %f, %f", yaw, pitch);
141 return MM_ERROR_INVALID_ARGUMENT;
144 LOGD("state %s, spherical info %d",
145 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
147 player->video360_yaw_radians = yaw;
148 player->video360_pitch_radians = pitch;
150 if (player->is_content_spherical) {
151 /* We will get here if player is pending ready or ready and above */
152 if (__mmplayer_check_video_360_used(player)) {
153 LOGD("set yaw %f, pitch %f for video", yaw, pitch);
154 g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
155 "pose-yaw", (int)(yaw * 180.0f / M_PI),
156 "pose-pitch", (int)(pitch * 180.0f / M_PI), NULL);
158 if (player->is_openal_plugin_used && __mmplayer_check_audio_sink(player)) {
159 g_object_set(G_OBJECT(player->pipeline->audiobin[MMPLAYER_A_SINK].gst),
160 "source-orientation-y", (int)(yaw * 180.0f / M_PI),
161 "source-orientation-x", (int)(pitch * 180.0f / M_PI), NULL);
166 return MM_ERROR_NONE;
170 _mmplayer_360_get_direction_of_view(MMHandleType hplayer, float *yaw, float *pitch)
172 mm_player_t *player = (mm_player_t *)hplayer;
174 int pitch_degrees = 0;
177 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
178 MMPLAYER_RETURN_VAL_IF_FAIL(yaw && pitch, MM_ERROR_INVALID_ARGUMENT);
180 LOGD("state %s, spherical info %d",
181 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
183 if (player->is_content_spherical && __mmplayer_check_video_360_used(player)) {
184 g_object_get(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
185 "pose-yaw", &yaw_degrees, "pose-pitch", &pitch_degrees, NULL);
186 *yaw = M_PI * yaw_degrees / 180.0f;
187 *pitch = M_PI * pitch_degrees / 180.0f;
189 LOGD("get yaw %f, pitch %f", *yaw, *pitch);
190 return MM_ERROR_NONE;
193 *yaw = player->video360_yaw_radians;
194 *pitch = player->video360_pitch_radians;
197 return MM_ERROR_NONE;
201 _mmplayer_360_set_zoom(MMHandleType hplayer, float level)
203 mm_player_t *player = (mm_player_t *)hplayer;
206 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
208 if (level < 1.0f || level > VIDEO360_MAX_ZOOM) {
209 LOGE("invalid argument %f", level);
210 return MM_ERROR_INVALID_ARGUMENT;
213 LOGD("state %s, spherical info %d",
214 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
216 player->video360_zoom = level;
218 if (player->is_content_spherical && __mmplayer_check_video_360_used(player)) {
219 /* We will get here if player is pending ready or ready and above */
221 LOGD("set level %f", level);
222 g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
223 "zoom", 1.0f / level, NULL);
227 return MM_ERROR_NONE;
231 _mmplayer_360_get_zoom(MMHandleType hplayer, float *level)
233 mm_player_t *player = (mm_player_t *)hplayer;
234 float current_zoom = 0.0;
237 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
238 MMPLAYER_RETURN_VAL_IF_FAIL(level, MM_ERROR_INVALID_ARGUMENT);
240 LOGD("state %s, spherical info %d",
241 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
243 if (player->is_content_spherical && __mmplayer_check_video_360_used(player)) {
244 g_object_get(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
245 "zoom", ¤t_zoom, NULL);
246 *level = 1.0f / current_zoom;
248 LOGD("get level %f", *level);
249 return MM_ERROR_NONE;
252 *level = player->video360_zoom;
255 return MM_ERROR_NONE;
259 _mmplayer_360_set_field_of_view(MMHandleType hplayer, int horizontal_degrees, int vertical_degrees)
261 mm_player_t *player = (mm_player_t *)hplayer;
264 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
266 if (horizontal_degrees < 1 || horizontal_degrees > 360 || vertical_degrees < 1 || vertical_degrees > 180) {
267 LOGE("invalid argument %d, %d", horizontal_degrees, vertical_degrees);
268 return MM_ERROR_INVALID_ARGUMENT;
271 LOGD("state %s, spherical info %d",
272 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
274 player->video360_horizontal_fov = horizontal_degrees;
275 player->video360_vertical_fov = vertical_degrees;
277 if (player->is_content_spherical && __mmplayer_check_video_360_used(player)) {
278 /* We will get here if player is pending ready or ready and above */
279 LOGD("set h-fov %d, v-fov %d", horizontal_degrees, vertical_degrees);
280 g_object_set(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
281 "horizontal-fov", horizontal_degrees, "vertical-fov", vertical_degrees, NULL);
285 return MM_ERROR_NONE;
289 _mmplayer_360_get_field_of_view(MMHandleType hplayer, int *horizontal_degrees, int *vertical_degrees)
291 mm_player_t *player = (mm_player_t *)hplayer;
294 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
295 MMPLAYER_RETURN_VAL_IF_FAIL(horizontal_degrees && vertical_degrees, MM_ERROR_INVALID_ARGUMENT);
297 LOGD("state %s, spherical info %d",
298 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
300 if (player->is_content_spherical && __mmplayer_check_video_360_used(player)) {
301 g_object_get(G_OBJECT(player->pipeline->videobin[MMPLAYER_V_360].gst),
302 "horizontal-fov", horizontal_degrees, "vertical-fov", vertical_degrees, NULL);
304 LOGD("get h-fov %d, v-fov %d", *horizontal_degrees, *vertical_degrees);
305 return MM_ERROR_NONE;
308 *horizontal_degrees = player->video360_horizontal_fov;
309 *vertical_degrees = player->video360_vertical_fov;
312 return MM_ERROR_NONE;