Example #1
0
static GF_Err MPD_ClientQuery(GF_InputService *ifce, GF_NetworkCommand *param)
{
	u32 i;
	GF_MPD_In *mpdin = (GF_MPD_In *) ifce->proxy_udta;
    if (!param || !ifce || !ifce->proxy_udta) return GF_BAD_PARAM;

	/*gets byte range of init segment (for local validation)*/
	if (param->command_type==GF_NET_SERVICE_QUERY_INIT_RANGE) {
		param->url_query.next_url = NULL;
		param->url_query.start_range = 0;
		param->url_query.end_range = 0;

		mpdin->in_seek = 0;

		for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) {
			GF_MPDGroup *group;
			if (!gf_dash_is_group_selected(mpdin->dash, i)) continue;
			group = gf_dash_get_group_udta(mpdin->dash, i);
			if (group->segment_ifce == ifce) {
				gf_dash_group_get_segment_init_url(mpdin->dash, i, &param->url_query.start_range, &param->url_query.end_range);
				return GF_OK;
			}
		}
		return GF_SERVICE_ERROR;
	}

	/*gets URL and byte range of next segment - if needed, adds butstream switching segment info*/
	if (param->command_type==GF_NET_SERVICE_QUERY_NEXT) {
		Bool group_done;
		u32 nb_segments_cached;
		u32 group_idx=0;
		GF_MPDGroup *group=NULL;
		const char *src_url;
		Bool discard_first_cache_entry = 1;
        u32 timer = gf_sys_clock();
		GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Service Query Next request from input service %s\n", ifce->module_name));


		param->url_query.discontinuity_type = 0;
		if (mpdin->in_seek) {
			mpdin->in_seek = 0;
			param->url_query.discontinuity_type = 2;
			discard_first_cache_entry = 0;
		}
		for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) {
			if (!gf_dash_is_group_selected(mpdin->dash, i)) continue;
			group = gf_dash_get_group_udta(mpdin->dash, i);
			if (group->segment_ifce == ifce) {
				group_idx = i;
				break;
			}
			group=NULL;
		}

		if (!group) {
			return GF_SERVICE_ERROR;
		}

		while (gf_dash_is_running(mpdin->dash) ) {
			group_done=0;
			nb_segments_cached = gf_dash_group_get_num_segments_ready(mpdin->dash, group_idx, &group_done);
			if (nb_segments_cached>=2)
				break;

			if (group_done) {
				if (!gf_dash_get_period_switch_status(mpdin->dash) && !gf_dash_in_last_period(mpdin->dash) ) {
					GF_NetworkCommand com;
					memset(&com, 0, sizeof(GF_NetworkCommand));
					com.command_type = GF_NET_BUFFER_QUERY;
					while (gf_dash_get_period_switch_status(mpdin->dash) != 1) {
						gf_term_on_command(mpdin->service, &com, GF_OK);
						if (!com.buffer.occupancy) {
							gf_dash_request_period_switch(mpdin->dash);
							break;
						}
						gf_sleep(20);
					}
				}
				return GF_EOS;
			}
            gf_sleep(16);
        }

		nb_segments_cached = gf_dash_group_get_num_segments_ready(mpdin->dash, group_idx, &group_done);
        if (nb_segments_cached < 2) {
            GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] No more file in cache, EOS\n"));
            return GF_EOS;
        } else {
            GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Had to wait for %u ms for the only cache file to be downloaded\n", (gf_sys_clock() - timer)));
        }

		if (discard_first_cache_entry) {
			gf_dash_group_discard_segment(mpdin->dash, group_idx);
		}

		gf_dash_group_get_next_segment_location(mpdin->dash, group_idx, &param->url_query.next_url, &param->url_query.start_range, &param->url_query.end_range,
								&param->url_query.next_url_init_or_switch_segment, &param->url_query.switch_start_range , &param->url_query.switch_end_range,
								&src_url);

        {
            u32 timer2 = gf_sys_clock() - timer ;
            if (timer2 > 1000) {
                GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Waiting for download to end took a long time : %u ms\n", timer2));
            }
			if (param->url_query.end_range) {
				GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] Switching segment playback to %s (Media Range: "LLD"-"LLD")\n", src_url, param->url_query.start_range, param->url_query.end_range));
			} else {
	            GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] Switching segment playback to %s\n", src_url));
			}
            GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] segment start time %g sec\n", gf_dash_group_current_segment_start_time(mpdin->dash, group_idx) ));

			GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Waited %d ms - Elements in cache: %u/%u\n\tCache file name %s\n", timer2, gf_dash_group_get_num_segments_ready(mpdin->dash, group_idx, &group_done), gf_dash_group_get_max_segments_in_cache(mpdin->dash, group_idx), param->url_query.next_url ));
        }
	    return GF_OK;
    }


    return GF_OK;
}
Example #2
0
static GF_Err MPD_ClientQuery(GF_InputService *ifce, GF_NetworkCommand *param)
{
	u32 i;
	GF_Err e;
	GF_MPD_In *mpdin = (GF_MPD_In *) ifce->proxy_udta;
	if (!param || !ifce || !ifce->proxy_udta) return GF_BAD_PARAM;

	mpdin->in_seek = 0;

	/*gets byte range of init segment (for local validation)*/
	if (param->command_type==GF_NET_SERVICE_QUERY_INIT_RANGE) {
		param->url_query.next_url = NULL;
		param->url_query.start_range = 0;
		param->url_query.end_range = 0;

		for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) {
			GF_MPDGroup *group;
			if (!gf_dash_is_group_selectable(mpdin->dash, i)) continue;
			group = gf_dash_get_group_udta(mpdin->dash, i);
			if (group->segment_ifce == ifce) {
				gf_dash_group_get_segment_init_url(mpdin->dash, i, &param->url_query.start_range, &param->url_query.end_range);
				param->url_query.current_download = 0;
				return GF_OK;
			}
		}
		return GF_SERVICE_ERROR;
	}

	/*gets URL and byte range of next segment - if needed, adds bitstream switching segment info*/
	if (param->command_type==GF_NET_SERVICE_QUERY_NEXT) {
		Bool group_done;
		u32 nb_segments_cached;
		u32 group_idx=0;
		GF_MPDGroup *group=NULL;
		const char *src_url;
		Bool discard_first_cache_entry = param->url_query.drop_first_segment;
		Bool check_current_download = param->url_query.current_download;
		u32 timer = gf_sys_clock();
		GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Service Query Next request from input service %s\n", ifce->module_name));


		param->url_query.current_download = 0;
		param->url_query.discontinuity_type = 0;

		for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) {
			if (!gf_dash_is_group_selected(mpdin->dash, i)) continue;
			group = gf_dash_get_group_udta(mpdin->dash, i);
			if (group->segment_ifce == ifce) {
				group_idx = i;
				break;
			}
			group=NULL;
		}

		if (!group) {
			return GF_SERVICE_ERROR;
		}

		if (group->in_seek) {
			group->in_seek = 0;
			param->url_query.discontinuity_type = 2;
			discard_first_cache_entry = 0;
		}

		//update group idx
		if (group->idx != group_idx) {
			group->idx = group_idx;
			GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] New AdaptationSet detected after MPD update ?\n"));
		}

		if (discard_first_cache_entry) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Discarding first segment in cache\n"));
			gf_dash_group_discard_segment(mpdin->dash, group_idx);
		}

		while (gf_dash_is_running(mpdin->dash) ) {
			group_done=0;
			nb_segments_cached = gf_dash_group_get_num_segments_ready(mpdin->dash, group_idx, &group_done);
			if (nb_segments_cached>=1)
				break;

			if (group_done) {
				if (!gf_dash_get_period_switch_status(mpdin->dash) && !gf_dash_in_last_period(mpdin->dash) ) {
					GF_NetworkCommand com;
					param->url_query.in_end_of_period = 1;
					memset(&com, 0, sizeof(GF_NetworkCommand));
					com.command_type = GF_NET_BUFFER_QUERY;
					if (gf_dash_get_period_switch_status(mpdin->dash) != 1) {
						gf_service_command(mpdin->service, &com, GF_OK);
						//we only switch period once no more data is in our buffers
						if (!com.buffer.occupancy) {
							param->url_query.in_end_of_period = 0;
							gf_dash_request_period_switch(mpdin->dash);
						}
					}
					if (param->url_query.in_end_of_period)
						return GF_BUFFER_TOO_SMALL;
				} else {
					return GF_EOS;
				}
			}

			if (check_current_download && mpdin->use_low_latency) {
				Bool is_switched=GF_FALSE;
				gf_dash_group_probe_current_download_segment_location(mpdin->dash, group_idx, &param->url_query.next_url, NULL, &param->url_query.next_url_init_or_switch_segment, &src_url, &is_switched);

				if (param->url_query.next_url) {
					param->url_query.current_download = 1;
					param->url_query.has_new_data = group->has_new_data;
					param->url_query.discontinuity_type = is_switched ? 1 : 0;
					if (gf_dash_group_loop_detected(mpdin->dash, group_idx))
						param->url_query.discontinuity_type = 2;
					group->has_new_data = 0;
					return GF_OK;
				}
				return GF_BUFFER_TOO_SMALL;
			}
			return GF_BUFFER_TOO_SMALL;
		}

		param->url_query.current_download = 0;
		nb_segments_cached = gf_dash_group_get_num_segments_ready(mpdin->dash, group_idx, &group_done);
		if (nb_segments_cached < 1) {
			GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] No more file in cache, EOS\n"));
			return GF_EOS;
		} else {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Had to wait for %u ms for the only cache file to be downloaded\n", (gf_sys_clock() - timer)));
		}

		e = gf_dash_group_get_next_segment_location(mpdin->dash, group_idx, param->url_query.dependent_representation_index, &param->url_query.next_url, &param->url_query.start_range, &param->url_query.end_range,
		        NULL, &param->url_query.next_url_init_or_switch_segment, &param->url_query.switch_start_range , &param->url_query.switch_end_range,
		        &src_url, &param->url_query.has_next);
		if (e)
			return e;

		if (gf_dash_group_loop_detected(mpdin->dash, group_idx))
			param->url_query.discontinuity_type = 2;


#ifndef GPAC_DISABLE_LOG
		{
			u32 timer2 = gf_sys_clock() - timer ;
			if (timer2 > 1000) {
				GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Waiting for download to end took a long time : %u ms\n", timer2));
			}
			if (param->url_query.end_range) {
				GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] Next Segment is %s bytes "LLD"-"LLD"\n", src_url, param->url_query.start_range, param->url_query.end_range));
			} else {
				GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[MPD_IN] Next Segment is %s\n", src_url));
			}
			GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Waited %d ms - Elements in cache: %u/%u\n\tCache file name %s\n\tsegment start time %g sec\n", timer2, gf_dash_group_get_num_segments_ready(mpdin->dash, group_idx, &group_done), gf_dash_group_get_max_segments_in_cache(mpdin->dash, group_idx), param->url_query.next_url, gf_dash_group_current_segment_start_time(mpdin->dash, group_idx)  ));
		}
#endif
	}


	return GF_OK;
}