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,
57 int _mmplayer_360_is_content_spherical(MMHandleType hplayer, bool *is_spherical)
59 mm_player_t* player = (mm_player_t*) hplayer;
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);
65 LOGD("state %s, spherical info %d",
66 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
68 if (player->state < MM_PLAYER_STATE_READY) {
69 *is_spherical = false;
70 return MM_ERROR_PLAYER_INVALID_STATE;
73 *is_spherical = (bool)player->is_content_spherical;
79 int _mmplayer_360_set_enabled(MMHandleType hplayer, bool enabled)
81 mm_player_t* player = (mm_player_t*) hplayer;
84 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
86 LOGD("state %s, spherical info %d",
87 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
89 player->is_video360_enabled = (gboolean)enabled;
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);
102 int _mmplayer_360_is_enabled(MMHandleType hplayer, bool *enabled)
104 mm_player_t* player = (mm_player_t*) hplayer;
108 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
109 MMPLAYER_RETURN_VAL_IF_FAIL(enabled, MM_ERROR_INVALID_ARGUMENT);
111 LOGD("state %s, spherical info %d",
112 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
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);
119 *enabled = (bool)player->is_video360_enabled;
122 LOGD("get enabled %d", *enabled);
125 return MM_ERROR_NONE;
128 int _mmplayer_360_set_direction_of_view(MMHandleType hplayer, float yaw, float pitch)
130 mm_player_t* player = (mm_player_t*) hplayer;
133 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
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;
140 LOGD("state %s, spherical info %d",
141 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
143 player->video360_yaw_radians = yaw;
144 player->video360_pitch_radians = pitch;
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);
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);
162 return MM_ERROR_NONE;
165 int _mmplayer_360_get_direction_of_view(MMHandleType hplayer, float *yaw, float *pitch)
167 mm_player_t* player = (mm_player_t*) hplayer;
169 int pitch_degrees = 0;
172 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
173 MMPLAYER_RETURN_VAL_IF_FAIL(yaw && pitch, MM_ERROR_INVALID_ARGUMENT);
175 LOGD("state %s, spherical info %d",
176 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
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;
184 LOGD("get yaw %f, pitch %f", yaw, pitch);
185 return MM_ERROR_NONE;
188 *yaw = player->video360_yaw_radians;
189 *pitch = player->video360_pitch_radians;
192 return MM_ERROR_NONE;
195 int _mmplayer_360_set_zoom(MMHandleType hplayer, float level)
197 mm_player_t* player = (mm_player_t*) hplayer;
200 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
202 if (level < 1.0f || level > VIDEO360_MAX_ZOOM) {
203 LOGE("invalid argument %f", level);
204 return MM_ERROR_INVALID_ARGUMENT;
207 LOGD("state %s, spherical info %d",
208 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
210 player->video360_zoom = level;
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 */
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);
221 return MM_ERROR_NONE;
224 int _mmplayer_360_get_zoom(MMHandleType hplayer, float *level)
226 mm_player_t* player = (mm_player_t*) hplayer;
227 float current_zoom = 0.0;
230 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
231 MMPLAYER_RETURN_VAL_IF_FAIL(level, MM_ERROR_INVALID_ARGUMENT);
233 LOGD("state %s, spherical info %d",
234 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
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", ¤t_zoom, NULL);
239 *level = 1.0f / current_zoom;
241 LOGD("get level %f", *level);
242 return MM_ERROR_NONE;
245 *level = player->video360_zoom;
248 return MM_ERROR_NONE;
251 int _mmplayer_360_set_field_of_view(MMHandleType hplayer, int horizontal_degrees, int vertical_degrees)
253 mm_player_t* player = (mm_player_t*) hplayer;
256 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
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;
263 LOGD("state %s, spherical info %d",
264 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
266 player->video360_horizontal_fov = horizontal_degrees;
267 player->video360_vertical_fov = vertical_degrees;
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);
277 return MM_ERROR_NONE;
280 int _mmplayer_360_get_field_of_view(MMHandleType hplayer, int *horizontal_degrees, int *vertical_degrees)
282 mm_player_t* player = (mm_player_t*) hplayer;
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);
288 LOGD("state %s, spherical info %d",
289 MMPLAYER_STATE_GET_NAME(MMPLAYER_CURRENT_STATE(player)), player->is_content_spherical);
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);
295 LOGD("get h-fov %d, v-fov %d", *horizontal_degrees, *vertical_degrees);
296 return MM_ERROR_NONE;
299 *horizontal_degrees = player->video360_horizontal_fov;
300 *vertical_degrees = player->video360_vertical_fov;
303 return MM_ERROR_NONE;