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_player_utils.h"
25 #include "mm_player_tracks.h"
27 /*---------------------------------------------------------------------------------------
28 | LOCAL FUNCTION PROTOTYPES: |
29 ---------------------------------------------------------------------------------------*/
30 static int __mmplayer_track_get_language(mm_player_t* player, MMPlayerTrackType type, gint stream_index, gchar **code);
33 /*=======================================================================================
34 | FUNCTION DEFINITIONS |
35 =======================================================================================*/
36 int _mmplayer_get_track_count(MMHandleType hplayer, MMPlayerTrackType type, int *count)
38 mm_player_t* player = (mm_player_t*) hplayer;
39 MMHandleType attrs = 0;
40 int ret = MM_ERROR_NONE;
44 /* check player handle */
45 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
46 MMPLAYER_RETURN_VAL_IF_FAIL(count, MM_ERROR_COMMON_INVALID_ARGUMENT);
47 MMPLAYER_RETURN_VAL_IF_FAIL((MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PAUSED)
48 || (MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PLAYING),
49 MM_ERROR_PLAYER_INVALID_STATE);
51 attrs = MMPLAYER_GET_ATTRS(player);
53 LOGE("cannot get content attribute");
54 return MM_ERROR_PLAYER_INTERNAL;
58 case MM_PLAYER_TRACK_TYPE_AUDIO:
60 /*if function called for normal file [no multi audio] */
61 if (player->selector[MM_PLAYER_TRACK_TYPE_AUDIO].total_track_num <= 0) {
65 ret = mm_attrs_get_int_by_name(attrs, "content_audio_track_num", count);
68 case MM_PLAYER_TRACK_TYPE_TEXT:
69 ret = mm_attrs_get_int_by_name(attrs, "content_text_track_num", count);
72 ret = MM_ERROR_COMMON_INVALID_ARGUMENT;
76 LOGD("%d track num : %d\n", type, *count);
83 int _mmplayer_select_track(MMHandleType hplayer, MMPlayerTrackType type, int index)
85 int ret = MM_ERROR_NONE;
86 mm_player_t* player = (mm_player_t*) hplayer;
87 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
90 MMPLAYER_SUBTITLE_INFO_LOCK(player);
92 if (type == MM_PLAYER_TRACK_TYPE_TEXT && player->subtitle_language_list) {
93 GstElement *subparse = NULL;
94 MMPlayerLangStruct *temp = NULL;
95 guint num_of_list = 0;
97 if (!player->pipeline || !player->pipeline->textbin[MMPLAYER_T_FAKE_SINK].gst) {
98 ret = MM_ERROR_PLAYER_NOT_INITIALIZED;
102 num_of_list = g_list_length(player->subtitle_language_list);
103 if (index < 0 || index >= num_of_list) {
104 LOGE("req track index is wrong");
105 ret = MM_ERROR_INVALID_ARGUMENT;
109 temp = g_list_nth_data(player->subtitle_language_list, index);
111 LOGE("fail to get lang from list");
112 ret = MM_ERROR_PLAYER_INTERNAL;
115 subparse = player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst;
116 LOGD("setting to language %s", temp->language_code);
117 g_object_set(G_OBJECT(subparse), "current-language", temp->language_key, NULL);
119 _mmplayer_sync_subtitle_pipeline(player);
122 ret = _mmplayer_change_track_language(hplayer, type, index);
126 MMPLAYER_SUBTITLE_INFO_UNLOCK(player);
132 int _mmplayer_track_add_subtitle_language(MMHandleType hplayer, int index)
134 int ret = MM_ERROR_NONE;
135 mm_player_t* player = (mm_player_t*) hplayer;
136 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
139 MMPLAYER_SUBTITLE_INFO_LOCK(player);
140 if (!player->pipeline || !player->pipeline->mainbin[MMPLAYER_M_T_SUBMUX_EXTERNAL].gst) {
141 ret = MM_ERROR_PLAYER_NOT_INITIALIZED;
145 if (player->subtitle_language_list) {
146 GstElement *subparse = NULL;
147 MMPlayerLangStruct *temp = NULL;
149 temp = g_list_nth_data(player->subtitle_language_list, index);
151 LOGE("fail to get lang from list");
152 ret = MM_ERROR_PLAYER_INTERNAL;
157 subparse = player->pipeline->mainbin[MMPLAYER_M_T_SUBMUX_EXTERNAL].gst;
158 LOGD("adding to language %s", temp->language_code);
159 g_object_set(G_OBJECT(subparse), "current-language", temp->language_key, NULL);
160 g_object_set(G_OBJECT(subparse), "lang-list", player->subtitle_language_list, NULL);
162 _mmplayer_sync_subtitle_pipeline(player);
164 LOGW("It is for just subtitle track");
165 ret = MM_ERROR_PLAYER_NO_OP;
170 MMPLAYER_SUBTITLE_INFO_UNLOCK(player);
175 int _mmplayer_track_remove_subtitle_language(MMHandleType hplayer, int index)
177 int ret = MM_ERROR_NONE;
178 mm_player_t* player = (mm_player_t*) hplayer;
179 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
182 MMPLAYER_SUBTITLE_INFO_LOCK(player);
183 if (!player->pipeline || !player->pipeline->mainbin[MMPLAYER_M_T_SUBMUX_EXTERNAL].gst) {
184 ret = MM_ERROR_PLAYER_NOT_INITIALIZED;
188 if (player->subtitle_language_list) {
189 GstElement *subparse = NULL;
190 MMPlayerLangStruct *temp = NULL;
192 temp = g_list_nth_data(player->subtitle_language_list, index);
194 LOGE("fail to get lang from list");
195 ret = MM_ERROR_PLAYER_INTERNAL;
198 temp->active = FALSE;
200 subparse = player->pipeline->mainbin[MMPLAYER_M_T_SUBMUX_EXTERNAL].gst;
201 LOGD("removing to language %s", temp->language_code);
202 g_object_set(G_OBJECT(subparse), "current-language", temp->language_key, NULL);
203 g_object_set(G_OBJECT(subparse), "lang-list", player->subtitle_language_list, NULL);
205 _mmplayer_sync_subtitle_pipeline(player);
207 LOGW("It is for just subtitle track");
208 ret = MM_ERROR_PLAYER_NO_OP;
213 MMPLAYER_SUBTITLE_INFO_UNLOCK(player);
218 int _mmplayer_get_current_track(MMHandleType hplayer, MMPlayerTrackType type, int *index)
220 int ret = MM_ERROR_NONE;
221 mm_player_t* player = (mm_player_t*) hplayer;
222 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
225 MMPLAYER_SUBTITLE_INFO_LOCK(player);
227 if (type >= MM_PLAYER_TRACK_TYPE_MAX) {
228 ret = MM_ERROR_INVALID_ARGUMENT;
229 LOGD("Not a proper type [type:%d] \n", type);
233 if (type == MM_PLAYER_TRACK_TYPE_TEXT && player->subtitle_language_list) {
234 GstElement *subparse = NULL;
235 int total_track_count = 0;
236 gchar* current_language = NULL;
237 MMPlayerLangStruct *temp = NULL;
238 MMHandleType attrs = 0;
240 attrs = MMPLAYER_GET_ATTRS(player);
242 LOGE("cannot get content attribute");
243 ret = MM_ERROR_PLAYER_INTERNAL;
247 mm_attrs_get_int_by_name(attrs, "content_text_track_num", &total_track_count);
249 subparse = player->pipeline->mainbin[MMPLAYER_M_SUBPARSE].gst;
250 g_object_get(G_OBJECT(subparse), "current-language", ¤t_language, NULL);
251 LOGD("current language is %s ", current_language);
252 while (total_track_count) {
253 temp = g_list_nth_data(player->subtitle_language_list, total_track_count - 1);
254 if (temp && current_language) {
255 LOGD("find the list");
256 if (!strcmp(temp->language_key, current_language)) {
257 *index = total_track_count - 1;
258 LOGD("current lang index is %d", *index);
265 if (total_track_count == 0) {
267 LOGE("failed to find current language index");
268 ret = MM_ERROR_PLAYER_INTERNAL;
272 if (player->selector[type].total_track_num <= 0) {
273 ret = MM_ERROR_PLAYER_NO_OP;
274 LOGD("there is no track information [type:%d] \n", type);
277 *index = player->selector[type].active_pad_index;
281 MMPLAYER_SUBTITLE_INFO_UNLOCK(player);
286 int _mmplayer_get_track_language_code(MMHandleType hplayer, MMPlayerTrackType type, int index, char **code)
288 int ret = MM_ERROR_NONE;
290 MMPLAYER_RETURN_VAL_IF_FAIL(hplayer, MM_ERROR_PLAYER_NOT_INITIALIZED);
291 mm_player_t* player = (mm_player_t*) hplayer;
294 MMPLAYER_SUBTITLE_INFO_LOCK(player);
296 if (type == MM_PLAYER_TRACK_TYPE_TEXT && player->subtitle_language_list) {
297 int language_code_size = 3;/*Size of ISO-639-1*/
298 MMPlayerLangStruct *language_list = NULL;
300 *code = (char*)malloc(language_code_size * sizeof(char));
302 ret = MM_ERROR_PLAYER_INTERNAL;
305 memset(*code, 0, language_code_size * sizeof(char));
307 language_list = g_list_nth_data(player->subtitle_language_list, index);
308 if (language_list == NULL) {
309 LOGD("%d is not a proper index \n", index);
312 strncpy(*code, language_list->language_code, language_code_size);
314 if (player->selector[type].total_track_num <= 0) {
315 ret = MM_ERROR_PLAYER_NO_OP;
316 LOGD("language list is not available. [type:%d] \n", type);
320 if (index < 0 || index >= player->selector[type].total_track_num) {
321 ret = MM_ERROR_INVALID_ARGUMENT;
322 LOGD("Not a proper index : %d \n", index);
326 ret = __mmplayer_track_get_language(player, type, index, code);
330 MMPLAYER_SUBTITLE_INFO_UNLOCK(player);
335 void __mmplayer_track_initialize(mm_player_t* player)
337 MMPlayerTrackType type = MM_PLAYER_TRACK_TYPE_AUDIO;
341 for (; type < MM_PLAYER_TRACK_TYPE_MAX ; type++) {
342 /* active_pad_index is initialized when player is created or destroyed.
343 and the value can be set by calling _mmplayer_change_track_language()
344 before pipeline is created.*/
345 player->selector[type].total_track_num = 0;
346 player->selector[type].channels = g_ptr_array_new();
350 void __mmplayer_track_destroy(mm_player_t* player)
352 MMPlayerTrackType type = MM_PLAYER_TRACK_TYPE_AUDIO;
353 MMHandleType attrs = 0;
356 attrs = MMPLAYER_GET_ATTRS(player);
358 mm_attrs_set_int_by_name(attrs, "content_audio_track_num", 0);
359 mm_attrs_set_int_by_name(attrs, "content_text_track_num", 0);
361 if (mm_attrs_commit_all(attrs))
362 LOGE("failed to commit.\n");
365 for (; type < MM_PLAYER_TRACK_TYPE_MAX ; type++) {
366 player->selector[type].active_pad_index = 0;
367 player->selector[type].total_track_num = 0;
369 if (player->selector[type].channels)
370 g_ptr_array_free(player->selector[type].channels, TRUE);
371 player->selector[type].channels = NULL;
375 void __mmplayer_track_update_info(mm_player_t* player, MMPlayerTrackType type, GstPad *sinkpad)
379 player->selector[type].total_track_num++;
380 g_ptr_array_add(player->selector[type].channels, sinkpad);
382 LOGD("type:%d, total track:%d\n", type, player->selector[type].total_track_num);
385 static int __mmplayer_track_get_language(mm_player_t* player, MMPlayerTrackType type, gint stream_index, gchar **code)
387 int ret = MM_ERROR_NONE;
389 GstTagList *tag_list = NULL;
391 GstPad *sinkpad = NULL;
392 gint language_code_size = 3; /*Size of ISO-639-1*/
396 *code = (char *)malloc(language_code_size*sizeof(char));
398 ret = MM_ERROR_PLAYER_INTERNAL;
401 memset(*code, 0, language_code_size*sizeof(char));
403 LOGD("total track num : %d , req idx : %d\n", player->selector[type].total_track_num, stream_index);
405 if (stream_index < player->selector[type].total_track_num) {
406 sinkpad = g_ptr_array_index(player->selector[type].channels, stream_index);
408 ret = MM_ERROR_INVALID_ARGUMENT;
412 g_object_get(sinkpad, "tags", &tag_list, NULL);
413 //SECURE_LOGD ("[%s]\n", gst_tag_list_to_string(tag_list));
415 gst_tag_list_get_string(tag_list, GST_TAG_LANGUAGE_CODE, &tag);
418 LOGD("there is no lang info - und\n");
419 strncpy(*code, "und", language_code_size);
421 LOGD("language information[%d] code: %s, len: %d \n", type, tag, strlen(tag));
422 strncpy(*code, tag, /*strlen(tag)*/language_code_size);
427 gst_tag_list_free(tag_list);
434 int _mmplayer_track_foreach_selected_subtitle_language(MMHandleType hplayer, _mmplayer_track_selected_subtitle_language_cb foreach_cb, void *user_data)
436 int ret = MM_ERROR_NONE;
437 mm_player_t* player = (mm_player_t*) hplayer;
438 MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_PLAYER_NOT_INITIALIZED);
442 MMPLAYER_SUBTITLE_INFO_LOCK(player);
444 if (player->subtitle_language_list) {
445 int total_track_count = 0;
446 MMPlayerLangStruct *temp = NULL;
447 MMHandleType attrs = 0;
449 attrs = MMPLAYER_GET_ATTRS(player);
451 LOGE("cannot get content attribute");
452 ret = MM_ERROR_PLAYER_INTERNAL;
455 mm_attrs_get_int_by_name(attrs, "content_text_track_num", &total_track_count);
457 if (!total_track_count) {
458 LOGW("There are no subtitle track selected.");
459 ret = MM_ERROR_PLAYER_NO_OP;
463 while (total_track_count) {
464 temp = g_list_nth_data(player->subtitle_language_list, total_track_count - 1);
466 LOGD("find the list");
468 index = total_track_count - 1;
469 LOGD("active subtitle track index is %d", index);
470 if (!foreach_cb(index, user_data)) {
471 ret = MM_ERROR_PLAYER_INTERNAL;
479 LOGD("we will return -1 for notifying the end to user");
481 /* After returning all selected indexs, we will return -1 for notifying the end to user */
482 if (!foreach_cb(-1, user_data)) {
483 ret = MM_ERROR_PLAYER_INTERNAL;
489 LOGE("foreach callback returned error");
492 MMPLAYER_SUBTITLE_INFO_UNLOCK(player);