4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, naveen cherukuri <naveen.ch@samsung.com>,
7 * YeJin Cho <cho.yejin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
24 #include <mm_attrs_private.h>
25 #include "mm_player_utils.h"
26 #include "mm_player_tracks.h"
28 /*---------------------------------------------------------------------------------------
29 | LOCAL FUNCTION PROTOTYPES: |
30 ---------------------------------------------------------------------------------------*/
31 static int __mmplayer_track_get_language(mm_player_t* player, MMPlayerTrackType type, gint stream_index, gchar **code);
34 /*=======================================================================================
35 | FUNCTION DEFINITIONS |
36 =======================================================================================*/
37 int _mmplayer_get_track_count(MMHandleType hplayer, MMPlayerTrackType type, int *count)
39 mm_player_t* player = (mm_player_t*) hplayer;
40 MMHandleType attrs = 0;
41 int ret = MM_ERROR_NONE;
45 /* check player handle */
46 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
47 MMPLAYER_RETURN_VAL_IF_FAIL(count, MM_ERROR_COMMON_INVALID_ARGUMENT);
48 MMPLAYER_RETURN_VAL_IF_FAIL((MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PAUSED)
49 ||(MMPLAYER_CURRENT_STATE(player) != MM_PLAYER_STATE_PLAYING),
50 MM_ERROR_PLAYER_INVALID_STATE);
52 attrs = MMPLAYER_GET_ATTRS(player);
55 LOGE("cannot get content attribute");
56 return MM_ERROR_PLAYER_INTERNAL;
61 case MM_PLAYER_TRACK_TYPE_AUDIO:
63 /*if function called for normal file [no multi audio] */
64 if(player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num <= 0)
69 ret = mm_attrs_get_int_by_name(attrs, "content_audio_track_num", count);
72 case MM_PLAYER_TRACK_TYPE_TEXT:
73 ret = mm_attrs_get_int_by_name(attrs, "content_text_track_num", count);
76 ret = MM_ERROR_COMMON_INVALID_ARGUMENT;
80 LOGD ("%d track num : %d\n", type, *count);
87 int _mmplayer_select_track(MMHandleType hplayer, MMPlayerTrackType type, int index)
89 int ret = MM_ERROR_NONE;
90 mm_player_t* player = (mm_player_t*) hplayer;
91 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
95 if (type == MM_PLAYER_TRACK_TYPE_TEXT && player->subtitle_language_list)
97 GstElement *subparse = NULL;
98 MMPlayerLangStruct *temp = NULL;
99 unsigned long cur_time = 0;
100 guint num_of_list = 0;
102 if(!player->pipeline || !player->pipeline->textbin[MMPLAYER_T_FAKE_SINK].gst)
104 ret = MM_ERROR_PLAYER_NOT_INITIALIZED;
108 num_of_list = g_list_length(player->subtitle_language_list);
109 if (index < 0 || index >= num_of_list)
111 LOGE("req track index is wrong");
112 ret = MM_ERROR_INVALID_ARGUMENT;
116 _mmplayer_get_position (hplayer, MM_PLAYER_POS_FORMAT_TIME, &cur_time);
117 temp = g_list_nth_data (player->subtitle_language_list, index);
120 LOGE("fail to get lang from list");
121 ret = MM_ERROR_PLAYER_INTERNAL;
124 subparse = player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst;
125 LOGD("setting to language %s", temp->language_code);
126 g_object_set (G_OBJECT (subparse), "current-language", temp->language_key, NULL);
128 _mmplayer_sync_subtitle_pipeline(player);
133 ret = _mmplayer_change_track_language (hplayer, type, index);
142 int _mmplayer_track_add_subtitle_language(MMHandleType hplayer, int index)
144 int ret = MM_ERROR_NONE;
145 mm_player_t* player = (mm_player_t*) hplayer;
146 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
149 if(!player->pipeline || !player->pipeline->mainbin[MMPLAYER_M_T_SUBMUX_EXTERNAL].gst)
151 ret = MM_ERROR_PLAYER_NOT_INITIALIZED;
155 if (player->subtitle_language_list)
157 GstElement *subparse = NULL;
158 MMPlayerLangStruct *temp = NULL;
160 temp = g_list_nth_data (player->subtitle_language_list, index);
163 LOGE("fail to get lang from list");
164 ret = MM_ERROR_PLAYER_INTERNAL;
169 subparse = player->pipeline->mainbin[MMPLAYER_M_T_SUBMUX_EXTERNAL].gst;
170 LOGD("adding to language %s", temp->language_code);
171 g_object_set (G_OBJECT (subparse), "current-language", temp->language_key, NULL);
172 g_object_set (G_OBJECT (subparse), "lang-list", player->subtitle_language_list, NULL);
174 _mmplayer_sync_subtitle_pipeline(player);
178 LOGW("It is for just subtitle track");
179 ret = MM_ERROR_PLAYER_NO_OP;
188 int _mmplayer_track_remove_subtitle_language(MMHandleType hplayer, int index)
190 int ret = MM_ERROR_NONE;
191 mm_player_t* player = (mm_player_t*) hplayer;
192 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
195 if(!player->pipeline || !player->pipeline->mainbin[MMPLAYER_M_T_SUBMUX_EXTERNAL].gst)
197 ret = MM_ERROR_PLAYER_NOT_INITIALIZED;
201 if (player->subtitle_language_list)
203 GstElement *subparse = NULL;
204 MMPlayerLangStruct *temp = NULL;
206 temp = g_list_nth_data (player->subtitle_language_list, index);
209 LOGE("fail to get lang from list");
210 ret = MM_ERROR_PLAYER_INTERNAL;
213 temp->active = FALSE;
215 subparse = player->pipeline->mainbin[MMPLAYER_M_T_SUBMUX_EXTERNAL].gst;
216 LOGD("removing to language %s", temp->language_code);
217 g_object_set (G_OBJECT (subparse), "current-language", temp->language_key, NULL);
218 g_object_set (G_OBJECT (subparse), "lang-list", player->subtitle_language_list, NULL);
220 _mmplayer_sync_subtitle_pipeline(player);
224 LOGW("It is for just subtitle track");
225 ret = MM_ERROR_PLAYER_NO_OP;
234 int _mmplayer_get_current_track(MMHandleType hplayer, MMPlayerTrackType type, int *index)
236 int ret = MM_ERROR_NONE;
237 mm_player_t* player = (mm_player_t*) hplayer;
238 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
241 if (type >= MM_PLAYER_TRACK_TYPE_MAX)
243 ret = MM_ERROR_INVALID_ARGUMENT;
244 LOGD("Not a proper type [type:%d] \n", type);
248 if (type == MM_PLAYER_TRACK_TYPE_TEXT && player->subtitle_language_list)
250 GstElement *subparse = NULL;
251 int total_track_count = 0;
252 gchar* current_language = NULL;
253 MMPlayerLangStruct *temp = NULL;
254 MMHandleType attrs = 0;
256 attrs = MMPLAYER_GET_ATTRS(player);
259 LOGE("cannot get content attribute");
260 ret = MM_ERROR_PLAYER_INTERNAL;
264 mm_attrs_get_int_by_name(attrs, "content_text_track_num", &total_track_count);
266 subparse = player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst;
267 g_object_get (G_OBJECT (subparse), "current-language", ¤t_language, NULL);
268 LOGD("current language is %s ",current_language);
269 while (total_track_count)
271 temp = g_list_nth_data (player->subtitle_language_list, total_track_count - 1);
274 LOGD("find the list");
275 if (!strcmp(temp->language_key, current_language))
277 *index = total_track_count - 1;
278 LOGD("current lang index is %d", *index);
287 if (player->selector[type].total_track_num <= 0)
289 ret = MM_ERROR_PLAYER_NO_OP;
290 LOGD("there is no track information [type:%d] \n", type);
294 *index = player->selector[type].active_pad_index;
302 int _mmplayer_get_track_language_code(MMHandleType hplayer, MMPlayerTrackType type, int index, char **code)
304 int ret = MM_ERROR_NONE;
306 MMPLAYER_RETURN_VAL_IF_FAIL(hplayer, MM_ERROR_PLAYER_NOT_INITIALIZED);
307 mm_player_t* player = (mm_player_t*) hplayer;
310 if (type == MM_PLAYER_TRACK_TYPE_TEXT && player->subtitle_language_list)
312 int language_code_size = 3;/*Size of ISO-639-1*/
313 MMPlayerLangStruct *language_list = NULL;
315 *code = (char*)malloc(language_code_size * sizeof(char));
318 ret = MM_ERROR_PLAYER_INTERNAL;
321 memset(*code, 0, language_code_size * sizeof(char));
323 language_list = g_list_nth_data (player->subtitle_language_list, index);
324 if (language_list == NULL)
326 LOGD ("%d is not a proper index \n", index);
329 strncpy(*code, language_list->language_code, language_code_size);
333 if (player->selector[type].total_track_num <= 0)
335 ret = MM_ERROR_PLAYER_NO_OP;
336 LOGD("language list is not available. [type:%d] \n", type);
340 if(index < 0 || index >= player->selector[type].total_track_num)
342 ret = MM_ERROR_INVALID_ARGUMENT;
343 LOGD("Not a proper index : %d \n", index);
347 ret = __mmplayer_track_get_language(player, type, index, code);
355 void _mmplayer_track_initialize(mm_player_t* player)
357 MMPlayerTrackType type = MM_PLAYER_TRACK_TYPE_AUDIO;
361 for (;type<MM_PLAYER_TRACK_TYPE_MAX ; type++)
363 /* active_pad_index is initialized when player is created or destroyed.
364 and the value can be set by calling _mmplayer_change_track_language()
365 before pipeline is created.*/
366 player->selector[type].total_track_num = 0;
367 player->selector[type].channels = g_ptr_array_new();
371 void _mmplayer_track_destroy(mm_player_t* player)
373 MMPlayerTrackType type = MM_PLAYER_TRACK_TYPE_AUDIO;
374 MMHandleType attrs = 0;
377 attrs = MMPLAYER_GET_ATTRS(player);
380 mm_attrs_set_int_by_name(attrs, "content_audio_track_num", 0);
381 mm_attrs_set_int_by_name(attrs, "content_video_track_num", 0);
382 mm_attrs_set_int_by_name(attrs, "content_text_track_num", 0);
384 if (mmf_attrs_commit (attrs))
385 LOGE("failed to commit.\n");
388 for (;type<MM_PLAYER_TRACK_TYPE_MAX ; type++)
390 player->selector[type].active_pad_index = 0;
391 player->selector[type].total_track_num = 0;
393 if (player->selector[type].channels)
394 g_ptr_array_free (player->selector[type].channels, TRUE);
395 player->selector[type].channels = NULL;
399 void _mmplayer_track_update_info(mm_player_t* player, MMPlayerTrackType type, GstPad *sinkpad)
403 player->selector[type].total_track_num++;
404 g_ptr_array_add (player->selector[type].channels, sinkpad);
406 LOGD ("type:%d, total track:%d\n", type, player->selector[type].total_track_num);
409 static int __mmplayer_track_get_language(mm_player_t* player, MMPlayerTrackType type, gint stream_index, gchar **code)
411 int ret = MM_ERROR_NONE;
413 GstTagList *tag_list = NULL;
415 GstPad *sinkpad = NULL;
416 gint language_code_size = 3; /*Size of ISO-639-1*/
420 *code = (char *)malloc(language_code_size*sizeof(char));
423 ret = MM_ERROR_PLAYER_INTERNAL;
426 memset(*code,0,language_code_size*sizeof(char));
428 LOGD ("total track num : %d , req idx : %d\n", player->selector[type].total_track_num, stream_index);
430 if (stream_index < player->selector[type].total_track_num)
432 sinkpad = g_ptr_array_index (player->selector[type].channels, stream_index);
436 ret = MM_ERROR_INVALID_ARGUMENT;
440 g_object_get (sinkpad, "tags", &tag_list, NULL);
441 //SECURE_LOGD ("[%s]\n", gst_tag_list_to_string(tag_list));
443 gst_tag_list_get_string (tag_list, GST_TAG_LANGUAGE_CODE, &tag);
447 LOGD("there is no lang info - und\n");
448 strncpy(*code, "und", language_code_size);
452 LOGD("language information[%d] code: %s, len: %d \n", type, tag, strlen(tag));
453 strncpy(*code, tag, /*strlen(tag)*/language_code_size);
458 gst_tag_list_free (tag_list);
465 int _mmplayer_track_foreach_selected_subtitle_language(MMHandleType hplayer,_mmplayer_track_selected_subtitle_language_cb foreach_cb, void *user_data)
467 int ret = MM_ERROR_NONE;
468 mm_player_t* player = (mm_player_t*) hplayer;
469 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
474 if (player->subtitle_language_list)
476 int total_track_count = 0;
477 MMPlayerLangStruct *temp = NULL;
478 MMHandleType attrs = 0;
480 attrs = MMPLAYER_GET_ATTRS(player);
483 LOGE("cannot get content attribute");
484 ret = MM_ERROR_PLAYER_INTERNAL;
487 mm_attrs_get_int_by_name(attrs, "content_text_track_num", &total_track_count);
489 if(!total_track_count)
491 LOGW("There are no subtitle track selected.");
492 ret = MM_ERROR_PLAYER_NO_OP;
496 while (total_track_count)
498 temp = g_list_nth_data (player->subtitle_language_list, total_track_count - 1);
501 LOGD("find the list");
504 index = total_track_count - 1;
505 LOGD("active subtitle track index is %d", index);
506 if (!foreach_cb(index, user_data))
508 ret = MM_ERROR_PLAYER_INTERNAL;
516 LOGD("we will return -1 for notifying the end to user");
518 /* After returning all selected indexs, we will return -1 for notifying the end to user */
519 if (!foreach_cb(-1, user_data))
521 ret = MM_ERROR_PLAYER_INTERNAL;
527 LOGE("foreach callback returned error");