return GST_PAD_PROBE_OK;
}
+static void
+__mmplayer_gst_selector_update_start_time(mm_player_t* player, MMPlayerTrackType stream_type)
+{
+ gint64 stop_running_time = 0;
+ gint64 position_running_time = 0;
+ gint64 position = 0;
+ gint idx = 0;
+
+ for (idx = MM_PLAYER_TRACK_TYPE_AUDIO; idx < MM_PLAYER_TRACK_TYPE_TEXT; idx++) {
+ if ((player->gapless.update_segment[idx] == TRUE) ||
+ !(player->selector[idx].event_probe_id)) {
+ /* LOGW("[%d] skip", idx); */
+ continue;
+ }
+
+ if (GST_CLOCK_TIME_IS_VALID(player->gapless.segment[idx].stop)) {
+ stop_running_time =
+ gst_segment_to_running_time(&player->gapless.segment[idx],
+ GST_FORMAT_TIME, player->gapless.segment[idx].stop);
+ } else if (GST_CLOCK_TIME_IS_VALID(player->gapless.segment[idx].duration)) {
+ stop_running_time =
+ gst_segment_to_running_time(&player->gapless.segment[idx],
+ GST_FORMAT_TIME, player->gapless.segment[idx].duration);
+ } else {
+ LOGD("duration: %"GST_TIME_FORMAT, GST_TIME_ARGS(player->duration));
+ stop_running_time =
+ gst_segment_to_running_time(&player->gapless.segment[idx],
+ GST_FORMAT_TIME, player->duration);
+ }
+
+ position_running_time =
+ gst_segment_to_running_time(&player->gapless.segment[idx],
+ GST_FORMAT_TIME, player->gapless.segment[idx].position);
+
+ LOGD("[type:%d] time info %" GST_TIME_FORMAT " , %"
+ GST_TIME_FORMAT" , %" GST_TIME_FORMAT,
+ idx,
+ GST_TIME_ARGS(stop_running_time),
+ GST_TIME_ARGS(position_running_time),
+ GST_TIME_ARGS(gst_segment_to_running_time(&player->gapless.segment[idx],
+ GST_FORMAT_TIME, player->gapless.segment[idx].start)));
+
+ position_running_time = MAX(position_running_time, stop_running_time);
+ position_running_time -= gst_segment_to_running_time(&player->gapless.segment[idx],
+ GST_FORMAT_TIME, player->gapless.segment[idx].start);
+ position_running_time = MAX(0, position_running_time);
+ position = MAX(position, position_running_time);
+ }
+
+ if (position != 0) {
+ LOGD("[%d]GST_EVENT_STREAM_START: start_time from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
+ stream_type, GST_TIME_ARGS(player->gapless.start_time[stream_type]),
+ GST_TIME_ARGS(player->gapless.start_time[stream_type] + position));
+
+ player->gapless.start_time[stream_type] += position;
+ }
+
+ return;
+}
+
static GstPadProbeReturn
__mmplayer_gst_selector_event_probe(GstPad * pad, GstPadProbeInfo * info, gpointer data)
{
const gchar* name = NULL;
MMPlayerTrackType stream_type = MM_PLAYER_TRACK_TYPE_VIDEO;
-
- if (GST_EVENT_IS_DOWNSTREAM(event)) {
- if (GST_EVENT_TYPE(event) != GST_EVENT_STREAM_START &&
- GST_EVENT_TYPE(event) != GST_EVENT_FLUSH_STOP &&
- GST_EVENT_TYPE(event) != GST_EVENT_SEGMENT &&
- GST_EVENT_TYPE(event) != GST_EVENT_EOS)
- return ret;
- } else if (GST_EVENT_IS_UPSTREAM(event)) {
- if (GST_EVENT_TYPE(event) != GST_EVENT_QOS)
- return ret;
+ if (GST_EVENT_IS_DOWNSTREAM(event) &&
+ GST_EVENT_TYPE(event) != GST_EVENT_STREAM_START &&
+ GST_EVENT_TYPE(event) != GST_EVENT_FLUSH_STOP &&
+ GST_EVENT_TYPE(event) != GST_EVENT_SEGMENT &&
+ GST_EVENT_TYPE(event) != GST_EVENT_EOS) {
+ return ret;
+ } else if (GST_EVENT_IS_UPSTREAM(event) &&
+ GST_EVENT_TYPE(event) != GST_EVENT_QOS) {
+ return ret;
}
caps = gst_pad_query_caps(pad, NULL);
}
case GST_EVENT_STREAM_START:
{
- gint64 stop_running_time = 0;
- gint64 position_running_time = 0;
- gint64 position = 0;
- gint idx = 0;
-
- for (idx = MM_PLAYER_TRACK_TYPE_AUDIO; idx < MM_PLAYER_TRACK_TYPE_TEXT; idx++) {
- if ((player->gapless.update_segment[idx] == TRUE) ||
- !(player->selector[idx].event_probe_id)) {
- /* LOGW("[%d] skip", idx); */
- continue;
- }
-
- if (GST_CLOCK_TIME_IS_VALID(player->gapless.segment[idx].stop)) {
- stop_running_time =
- gst_segment_to_running_time(&player->gapless.segment[idx],
- GST_FORMAT_TIME, player->gapless.segment[idx].stop);
- } else if (GST_CLOCK_TIME_IS_VALID(player->gapless.segment[idx].duration)) {
- stop_running_time =
- gst_segment_to_running_time(&player->gapless.segment[idx],
- GST_FORMAT_TIME, player->gapless.segment[idx].duration);
- } else {
- LOGD("duration: %"GST_TIME_FORMAT, GST_TIME_ARGS(player->duration));
- stop_running_time =
- gst_segment_to_running_time(&player->gapless.segment[idx],
- GST_FORMAT_TIME, player->duration);
- }
-
- position_running_time =
- gst_segment_to_running_time(&player->gapless.segment[idx],
- GST_FORMAT_TIME, player->gapless.segment[idx].position);
-
- LOGD("[type:%d] time info %" GST_TIME_FORMAT " , %"
- GST_TIME_FORMAT" , %" GST_TIME_FORMAT,
- idx,
- GST_TIME_ARGS(stop_running_time),
- GST_TIME_ARGS(position_running_time),
- GST_TIME_ARGS(gst_segment_to_running_time(&player->gapless.segment[idx],
- GST_FORMAT_TIME, player->gapless.segment[idx].start)));
-
- position_running_time = MAX(position_running_time, stop_running_time);
- position_running_time -= gst_segment_to_running_time(&player->gapless.segment[idx],
- GST_FORMAT_TIME, player->gapless.segment[idx].start);
- position_running_time = MAX(0, position_running_time);
- position = MAX(position, position_running_time);
- }
-
- if (position != 0) {
- LOGD("[%d]GST_EVENT_STREAM_START: start_time from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
- stream_type, GST_TIME_ARGS(player->gapless.start_time[stream_type]),
- GST_TIME_ARGS(player->gapless.start_time[stream_type] + position));
-
- player->gapless.start_time[stream_type] += position;
- }
+ __mmplayer_gst_selector_update_start_time(player, stream_type);
break;
}
case GST_EVENT_FLUSH_STOP:
LOGD("[%d] GST_EVENT_SEGMENT", stream_type);
gst_event_copy_segment(event, &segment);
- if (segment.format == GST_FORMAT_TIME) {
- LOGD("segment base:%" GST_TIME_FORMAT ", offset:%" GST_TIME_FORMAT
- ", start:%" GST_TIME_FORMAT ", stop: %" GST_TIME_FORMAT
- ", time: %" GST_TIME_FORMAT ", pos: %" GST_TIME_FORMAT ", dur: %" GST_TIME_FORMAT,
- GST_TIME_ARGS(segment.base), GST_TIME_ARGS(segment.offset),
- GST_TIME_ARGS(segment.start), GST_TIME_ARGS(segment.stop),
- GST_TIME_ARGS(segment.time), GST_TIME_ARGS(segment.position), GST_TIME_ARGS(segment.duration));
+ if (segment.format != GST_FORMAT_TIME)
+ break;
- /* keep the all the segment ev to cover the seeking */
- gst_segment_copy_into(&segment, &player->gapless.segment[stream_type]);
- player->gapless.update_segment[stream_type] = TRUE;
+ LOGD("segment base:%" GST_TIME_FORMAT ", offset:%" GST_TIME_FORMAT
+ ", start:%" GST_TIME_FORMAT ", stop: %" GST_TIME_FORMAT
+ ", time: %" GST_TIME_FORMAT ", pos: %" GST_TIME_FORMAT ", dur: %" GST_TIME_FORMAT,
+ GST_TIME_ARGS(segment.base), GST_TIME_ARGS(segment.offset),
+ GST_TIME_ARGS(segment.start), GST_TIME_ARGS(segment.stop),
+ GST_TIME_ARGS(segment.time), GST_TIME_ARGS(segment.position), GST_TIME_ARGS(segment.duration));
- if (!player->gapless.running)
- break;
+ /* keep the all the segment ev to cover the seeking */
+ gst_segment_copy_into(&segment, &player->gapless.segment[stream_type]);
+ player->gapless.update_segment[stream_type] = TRUE;
- player->gapless.segment[stream_type].base = player->gapless.start_time[stream_type];
+ if (!player->gapless.running)
+ break;
- LOGD("[%d] new base: %" GST_TIME_FORMAT, stream_type, GST_TIME_ARGS(player->gapless.segment[stream_type].base));
+ player->gapless.segment[stream_type].base = player->gapless.start_time[stream_type];
+
+ LOGD("[%d] new base: %" GST_TIME_FORMAT, stream_type, GST_TIME_ARGS(player->gapless.segment[stream_type].base));
+
+ tmpev = gst_event_new_segment(&player->gapless.segment[stream_type]);
+ gst_event_set_seqnum(tmpev, gst_event_get_seqnum(event));
+ gst_event_unref(event);
+ GST_PAD_PROBE_INFO_DATA(info) = tmpev;
- tmpev = gst_event_new_segment(&player->gapless.segment[stream_type]);
- gst_event_set_seqnum(tmpev, gst_event_get_seqnum(event));
- gst_event_unref(event);
- GST_PAD_PROBE_INFO_DATA(info) = tmpev;
- }
break;
}
case GST_EVENT_QOS:
MMPLAYER_GENERATE_DOT_IF_ENABLED(player, "pipeline-status-complete");
}
+static int
+__mmplayer_check_profile(void)
+{
+ char *profileName;
+ static int profile_tv = -1;
+
+ if (__builtin_expect(profile_tv != -1, 1))
+ return profile_tv;
+
+ system_info_get_platform_string("http://tizen.org/feature/profile", &profileName);
+ switch (*profileName) {
+ case 't':
+ case 'T':
+ profile_tv = 1;
+ break;
+ default:
+ profile_tv = 0;
+ break;
+ }
+ free(profileName);
+
+ return profile_tv;
+}
+
static gboolean
-__mmplayer_verify_next_play_path(mm_player_t *player)
+__mmplayer_get_next_uri(mm_player_t *player)
{
- MMHandleType attrs = 0;
MMPlayerParseProfile profile;
- gint uri_idx = 0, check_cnt = 0;
+ gint uri_idx = 0;
+ guint num_of_list = 0;
char *uri = NULL;
+
+ num_of_list = g_list_length(player->uri_info.uri_list);
+ uri_idx = player->uri_info.uri_idx;
+
+ LOGD("num of uri list = %d, current uri idx %d", num_of_list, uri_idx);
+ for (uri_idx++; uri_idx < num_of_list; uri_idx++) {
+ uri = g_list_nth_data(player->uri_info.uri_list, uri_idx);
+ if (uri == NULL) {
+ LOGW("next uri does not exist");
+ continue;
+ }
+
+ if (__mmplayer_parse_profile((const char*)uri, NULL, &profile) != MM_ERROR_NONE) {
+ LOGE("failed to parse profile");
+ continue;
+ }
+
+ if ((profile.uri_type != MM_PLAYER_URI_TYPE_FILE) &&
+ (profile.uri_type != MM_PLAYER_URI_TYPE_URL_HTTP)) {
+ LOGW("uri type is not supported(%d)", profile.uri_type);
+ continue;
+ }
+
+ LOGD("success to find next uri %d", uri_idx);
+ break;
+ }
+
+ if (uri_idx == num_of_list) {
+ LOGE("failed to find next uri");
+ return FALSE;
+ }
+
+ player->uri_info.uri_idx = uri_idx;
+ mm_attrs_set_string_by_name(player->attrs, "profile_uri", uri);
+
+ if (mmf_attrs_commit(player->attrs)) {
+ LOGE("failed to commit");
+ return FALSE;
+ }
+
+ SECURE_LOGD("next playback uri: %s", uri);
+ return TRUE;
+}
+
+static gboolean
+__mmplayer_verify_next_play_path(mm_player_t *player)
+{
+#define REPEAT_COUNT_INFINITELY -1
+#define REPEAT_COUNT_MIN 2
+
+ MMHandleType attrs = 0;
gint mode = MM_PLAYER_PD_MODE_NONE;
gint video = 0;
gint count = 0;
gint gapless = 0;
guint num_of_list = 0;
- static int profile_tv = -1;
+ int profile_tv = -1;
MMPLAYER_FENTER();
- LOGD("checking for gapless play");
+ LOGD("checking for next play option");
if (player->pipeline->textbin) {
LOGE("subtitle path is enabled. gapless play is not supported.\n");
mm_attrs_get_int_by_name(attrs, "content_video_found", &video);
- if (__builtin_expect(profile_tv == -1, 0)) {
- char *profileName;
- system_info_get_platform_string("http://tizen.org/feature/profile", &profileName);
- switch (*profileName) {
- case 't':
- case 'T':
- profile_tv = 1;
- break;
- default:
- profile_tv = 0;
- }
- free(profileName);
- }
/* gapless playback is not supported in case of video at TV profile. */
+ profile_tv = __mmplayer_check_profile();
if (profile_tv && video) {
LOGW("not support video gapless playback");
goto ERROR;
}
if (mm_attrs_get_int_by_name(attrs, "profile_play_count", &count) != MM_ERROR_NONE)
- LOGE("can not get play count\n");
+ LOGE("failed to get play count");
if (mm_attrs_get_int_by_name(attrs, "gapless_mode", &gapless) != MM_ERROR_NONE)
- LOGE("can not get gapless mode\n");
-
- if (video && !gapless) {
- LOGW("not enabled video gapless playback");
- goto ERROR;
- }
-
- if ((count == -1 || count > 1)) /* enable gapless when looping or repeat */
- gapless = 1;
+ LOGE("failed to get gapless mode");
- if (!gapless) {
- LOGW("gapless is disabled\n"); /* FIXME: playlist(without gapless) is not implemented. */
+ /* check repeat count in case of audio */
+ if (!gapless &&
+ (video || (count != REPEAT_COUNT_INFINITELY && count < REPEAT_COUNT_MIN))) {
+ LOGW("gapless is disabled");
goto ERROR;
}
num_of_list = g_list_length(player->uri_info.uri_list);
- LOGD("repeat count = %d, num_of_list = %d\n", count, num_of_list);
+ LOGD("repeat count = %d, num_of_list = %d", count, num_of_list);
if (num_of_list == 0) {
- if (mm_attrs_get_string_by_name(player->attrs, "profile_uri", &uri) != MM_ERROR_NONE) {
- LOGE("can not get profile_uri\n");
- goto ERROR;
- }
+ /* audio looping path */
+ if (count >= REPEAT_COUNT_MIN) {
+ /* decrease play count */
+ /* we succeeded to rewind. update play count and then wait for next EOS */
+ count--;
- if (!uri) {
- LOGE("uri list is empty.\n");
- goto ERROR;
- }
-
- player->uri_info.uri_list = g_list_append(player->uri_info.uri_list, g_strdup(uri));
- LOGD("add original path : %s ", uri);
-
- num_of_list = 1;
- uri = NULL;
- }
-
- uri_idx = player->uri_info.uri_idx;
-
- while (TRUE) {
- check_cnt++;
+ mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
- if (check_cnt > num_of_list) {
- LOGE("there is no valid uri.");
+ /* commit attribute */
+ if (mmf_attrs_commit(attrs))
+ LOGE("failed to commit attribute");
+ } else if (count != REPEAT_COUNT_INFINITELY) {
+ LOGD("there is no next uri and no repeat");
goto ERROR;
}
- LOGD("uri idx : %d / %d\n", uri_idx, num_of_list);
-
- if (uri_idx < num_of_list-1) {
- uri_idx++;
- } else {
- if ((count <= 1) && (count != -1)) {
- LOGD("no repeat.");
- goto ERROR;
- } else if (count > 1) {
- /* decrease play count */
- /* we succeeded to rewind. update play count and then wait for next EOS */
- count--;
-
- mm_attrs_set_int_by_name(attrs, "profile_play_count", count);
-
- /* commit attribute */
- if (mmf_attrs_commit(attrs))
- LOGE("failed to commit attribute\n");
- }
-
- /* count < 0 : repeat continually */
- uri_idx = 0;
- }
-
- uri = g_list_nth_data(player->uri_info.uri_list, uri_idx);
- LOGD("uri idx : %d, uri = %s\n", uri_idx, uri);
-
- if (uri == NULL) {
- LOGW("next uri does not exist\n");
- continue;
- }
-
- if (__mmplayer_parse_profile((const char*)uri, NULL, &profile) != MM_ERROR_NONE) {
- LOGE("failed to parse profile\n");
- continue;
- }
-
- if ((profile.uri_type != MM_PLAYER_URI_TYPE_FILE) &&
- (profile.uri_type != MM_PLAYER_URI_TYPE_URL_HTTP)) {
- LOGW("uri type is not supported(%d).", profile.uri_type);
- continue;
+ LOGD("looping cnt %d", count);
+ } else {
+ /* gapless playback path */
+ if (!__mmplayer_get_next_uri(player)) {
+ LOGE("failed to get next uri");
+ goto ERROR;
}
-
- break;
}
- player->uri_info.uri_idx = uri_idx;
- mm_attrs_set_string_by_name(player->attrs, "profile_uri", uri);
-
- if (mmf_attrs_commit(player->attrs)) {
- LOGE("failed to commit.\n");
- goto ERROR;
- }
-
- LOGD("next uri %s(%d)\n", uri, uri_idx);
-
return TRUE;
ERROR:
-
- LOGE("unable to play next path. EOS will be posted soon.\n");
+ LOGE("unable to play next path. EOS will be posted soon");
return FALSE;
}