Example #1
0
void RP_SetupObjects(RTPClient *rtp)
{
	GF_ObjectDescriptor *od;
	RTPStream *ch;
	u32 i;

	/*add everything*/
	i=0;
	while ((ch = (RTPStream *)gf_list_enum(rtp->channels, &i))) {
		if (ch->control && !strnicmp(ch->control, "data:", 5)) continue;
		if (ch->prev_stream) continue;

		if (!rtp->media_type) {
			od = RP_GetChannelOD(ch, i);
			if (!od) continue;
			gf_term_add_media(rtp->service, (GF_Descriptor*)od, 1);
		} else if (rtp->media_type==ch->depacketizer->sl_map.StreamType) {
			od = RP_GetChannelOD(ch, i);
			if (!od) continue;
			gf_term_add_media(rtp->service, (GF_Descriptor*)od, 1);
			rtp->media_type = 0;
			break;
		}
	}
	gf_term_add_media(rtp->service, NULL, 0);
}
Example #2
0
static void MP2TS_DeclareStream(M2TSIn *m2ts, GF_M2TS_PES *stream, char *dsi, u32 dsi_size)
{
    GF_ObjectDescriptor *od = MP2TS_GetOD(m2ts, stream, dsi, dsi_size, NULL);
    if (!od) return;
    /*declare but don't regenerate scene*/
    gf_term_add_media(m2ts->service, (GF_Descriptor*)od, 1);
}
Example #3
0
static void tti_setup_object(TTIn *tti)
{
    GF_ObjectDescriptor *od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
    GF_ESD *esd = tti_get_esd(tti);
    od->objectDescriptorID = esd->ESID;
    gf_list_add(od->ESDescriptors, esd);
    gf_term_add_media(tti->service, (GF_Descriptor *)od, 0);
}
Example #4
0
static void AC3_SetupObject(AC3Reader *read)
{
	GF_ESD *esd;
	GF_ObjectDescriptor *od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
	od->objectDescriptorID = 1;
	esd = AC3_GetESD(read);
	esd->OCRESID = 0;
	gf_list_add(od->ESDescriptors, esd);
	gf_term_add_media(read->service, (GF_Descriptor*)od, 0);
}
Example #5
0
static u32 ext_media_load_th(void *par) {
	GF_HYBMEDIA *self = (GF_HYBMEDIA*) par;
	/*declare object to terminal*/
	GF_ObjectDescriptor *od = (GF_ObjectDescriptor*)gf_odf_desc_new(GF_ODF_OD_TAG);
	od->URLString = gf_strdup("http://gpac.sourceforge.net/screenshots/lion.jpg");
	od->objectDescriptorID = 0;
	gf_sleep(2000); //TODO: remove the sleep
	gf_term_add_media(self->owner, (GF_Descriptor*)od, 0);
	return 0;
}
Example #6
0
static void mp3_setup_object(MP3Reader *read)
{
	if (read->is_inline) {
		GF_ESD *esd;
		GF_ObjectDescriptor *od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
		od->objectDescriptorID = 1;
		esd = MP3_GetESD(read);
		gf_list_add(od->ESDescriptors, esd);
		gf_term_add_media(read->service, (GF_Descriptor*)od, 0);
	}
}
Example #7
0
static void FFD_SetupObjects(FFDemux *ffd)
{
	GF_ESD *esd;
	GF_ObjectDescriptor *od;
	u32 audio_esid = 0;

	if ((ffd->audio_st>=0) && (ffd->service_type != 1)) {
		od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
		esd = FFD_GetESDescriptor(ffd, 1);
		od->objectDescriptorID = esd->ESID;
		audio_esid = esd->ESID;
		gf_list_add(od->ESDescriptors, esd);
		gf_term_add_media(ffd->service, (GF_Descriptor*)od, (ffd->video_st>=0) ? 1 : 0);
	}
	if ((ffd->video_st>=0) && (ffd->service_type != 2)) {
		od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
		esd = FFD_GetESDescriptor(ffd, 0);
		od->objectDescriptorID = esd->ESID;
		esd->OCRESID = audio_esid;
		gf_list_add(od->ESDescriptors, esd);
		gf_term_add_media(ffd->service, (GF_Descriptor*)od, 0);
	}
}
Example #8
0
static GF_Err HYB_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url)
{
	u32 i;
	GF_Err e = GF_OK;
	const size_t nb_masters = sizeof(hyb_masters) / sizeof(GF_HYBMEDIA*);

	GF_HYB_In *hyb_in = (GF_HYB_In*)plug->priv;

	GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[HYB_IN] Received Connection request from service %p for %s\n", serv, url));

	if (!hyb_in || !serv || !url) return GF_BAD_PARAM;
	hyb_in->service = serv;

	/*choose the master service*/
	for (i=0; i<nb_masters; i++) {
		if (hyb_masters[i]->CanHandleURL(url)) {
			hyb_in->master = hyb_masters[i];
			break;
		}
	}
	assert(hyb_in->master);

	/*sanity check about the master*/
	e = hybmedia_sanity_check(hyb_in->master);
	if (e) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[HYB_IN] Error - object \"%s\" failed the sanity checks\n", hyb_in->master->name));
		gf_term_on_connect(hyb_in->service, NULL, e);
		return e;
	}
	GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[HYB_IN] Selected master object \"%s\" for URL: %s\n", hyb_in->master->name, url));

	/*connect the master*/
	e = hyb_in->master->Connect(hyb_in->master, hyb_in->service, url);
	if (e) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[HYB_IN] Error - cannot connect service, wrong URL %s\n", url));
		gf_term_on_connect(hyb_in->service, NULL, GF_BAD_PARAM);
		return e;
	}
	gf_term_on_connect(hyb_in->service, NULL, GF_OK);
	gf_term_add_media(hyb_in->service, (GF_Descriptor*)hyb_in->master->GetOD(), 0);

	return GF_OK;
}
Example #9
0
static void MP2TS_SetupProgram(M2TSIn *m2ts, GF_M2TS_Program *prog, Bool regenerate_scene, Bool no_declare)
{
	u32 i, count;

	count = gf_list_count(prog->streams);
#ifdef GPAC_HAS_LINUX_DVB
	if (m2ts->ts->tuner) {
		Bool found = 0;
		for (i=0; i<count; i++) {
			GF_M2TS_PES *pes = gf_list_get(prog->streams, i);
			if (pes->pid==m2ts->ts->tuner->vpid) found = 1;
			else if (pes->pid==m2ts->ts->tuner->apid) found = 1;
		}
		if (!found) return;
	}
#endif

	/*TS is a file, start regulation regardless of how the TS is access (with or without fragment URI)*/
	if (m2ts->ts->file || m2ts->ts->dnload || m2ts->owner->query_proxy)
		m2ts->ts->file_regulate = 1;

	for (i=0; i<count; i++) {
		GF_M2TS_ES *es = gf_list_get(prog->streams, i);
		if (es->pid==prog->pmt_pid) continue;
		if ((es->flags & GF_M2TS_ES_IS_PES) && ((GF_M2TS_PES *)es)->depends_on_pid )
			continue;

		/*move to skip mode for all ES until asked for playback*/
		if (!es->user)
			gf_m2ts_set_pes_framing((GF_M2TS_PES *)es, GF_M2TS_PES_FRAMING_SKIP);

		if (!prog->pmt_iod && !no_declare) {
			MP2TS_DeclareStream(m2ts, (GF_M2TS_PES *)es, NULL, 0);
		}
		/*if IOD, streams not declared through OD framework are refered to by pid:// scheme, and will be declared upon
		request by the terminal through GetServiceDesc*/
	}

	/*force scene regeneration*/
	if (!prog->pmt_iod && regenerate_scene)
		gf_term_add_media(m2ts->service, NULL, 0);
}
Example #10
0
void isor_declare_objects(ISOMReader *read)
{
	GF_ObjectDescriptor *od;
	GF_ESD *esd;
	const char *tag;
	u32 i, count, ocr_es_id, tlen, base_track, j, track_id;
	Bool highest_stream;
	char *opt;
	Bool add_ps_lower = GF_TRUE;

	ocr_es_id = 0;
	opt = (char*) gf_modules_get_option((GF_BaseInterface *)read->input, "ISOReader", "DeclareScalableXPS");
	if (!opt) {
		gf_modules_set_option((GF_BaseInterface *)read->input, "ISOReader", "DeclareScalableXPS", "yes");
	} else if (!strcmp(opt, "no")) {
		add_ps_lower = GF_FALSE;
	}

	/*TODO check for alternate tracks*/
	count = gf_isom_get_track_count(read->mov);
	for (i=0; i<count; i++) {
		if (!gf_isom_is_track_enabled(read->mov, i+1)) continue;

		switch (gf_isom_get_media_type(read->mov, i+1)) {
		case GF_ISOM_MEDIA_AUDIO:
		case GF_ISOM_MEDIA_VISUAL:
		case GF_ISOM_MEDIA_TEXT:
		case GF_ISOM_MEDIA_SUBT:
		case GF_ISOM_MEDIA_SCENE:
		case GF_ISOM_MEDIA_SUBPIC:
			break;
		default:
			continue;
		}

		/*we declare only the highest video track (i.e the track we play)*/
		highest_stream = GF_TRUE;
		track_id = gf_isom_get_track_id(read->mov, i+1);
		for (j = 0; j < count; j++) {
			if (gf_isom_has_track_reference(read->mov, j+1, GF_ISOM_REF_SCAL, track_id) > 0) {
				highest_stream = GF_FALSE;
				break;
			}
		}
		if ((gf_isom_get_media_type(read->mov, i+1) == GF_ISOM_MEDIA_VISUAL) && !highest_stream)
			continue;
		esd = gf_media_map_esd(read->mov, i+1);
		if (esd) {
			gf_isom_get_reference(read->mov, i+1, GF_ISOM_REF_BASE, 1, &base_track);
			esd->has_ref_base = base_track ? GF_TRUE : GF_FALSE;
			/*FIXME: if we declare only SPS/PPS of the highest layer, we have a problem in decoding even though we have all SPS/PPS inband (OpenSVC bug ?)*/
			/*so we add by default the SPS/PPS of the lower layers to this esd*/
			if (esd->has_ref_base && add_ps_lower) {
				u32 count, refIndex, ref_track, num_sps, num_pps, t;
				GF_AVCConfig *cfg = gf_odf_avc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength);
				GF_AVCConfig *avccfg, *svccfg;

				count = gf_isom_get_reference_count(read->mov, i+1, GF_ISOM_REF_SCAL);
				for (refIndex = count; refIndex != 0; refIndex--) {
					gf_isom_get_reference(read->mov, i+1, GF_ISOM_REF_SCAL, refIndex, &ref_track);
					avccfg = gf_isom_avc_config_get(read->mov, ref_track, 1);
					svccfg = gf_isom_svc_config_get(read->mov, ref_track, 1);
					if (avccfg) {
						num_sps = gf_list_count(avccfg->sequenceParameterSets);
						for (t = 0; t < num_sps; t++) {
							GF_AVCConfigSlot *slc = gf_list_get(avccfg->sequenceParameterSets, t);
							GF_AVCConfigSlot *sl = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot));
							sl->id = slc->id;
							sl->size = slc->size;
							sl->data = (char*)gf_malloc(sizeof(char)*sl->size);
							memcpy(sl->data, slc->data, sizeof(char)*sl->size);
							gf_list_insert(cfg->sequenceParameterSets, sl, 0);
						}
						num_pps = gf_list_count(avccfg->pictureParameterSets);
						for (t = 0; t < num_sps; t++) {
							GF_AVCConfigSlot *slc = gf_list_get(avccfg->pictureParameterSets, t);
							GF_AVCConfigSlot *sl = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot));
							sl->id = slc->id;
							sl->size = slc->size;
							sl->data = (char*)gf_malloc(sizeof(char)*sl->size);
							memcpy(sl->data, slc->data, sizeof(char)*sl->size);
							gf_list_insert(cfg->pictureParameterSets, sl, 0);
						}
						gf_odf_avc_cfg_del(avccfg);
					}
					if (svccfg) {
						num_sps = gf_list_count(svccfg->sequenceParameterSets);
						for (t = 0; t < num_sps; t++) {
							GF_AVCConfigSlot *slc = gf_list_get(svccfg->sequenceParameterSets, t);
							GF_AVCConfigSlot *sl = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot));
							sl->id = slc->id;
							sl->size = slc->size;
							sl->data = (char*)gf_malloc(sizeof(char)*sl->size);
							memcpy(sl->data, slc->data, sizeof(char)*sl->size);
							gf_list_insert(cfg->sequenceParameterSets, sl, 0);
						}
						num_pps = gf_list_count(svccfg->pictureParameterSets);
						for (t = 0; t < num_pps; t++) {
							GF_AVCConfigSlot *slc = gf_list_get(svccfg->pictureParameterSets, t);
							GF_AVCConfigSlot *sl = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot));
							sl->id = slc->id;
							sl->size = slc->size;
							sl->data = (char*)gf_malloc(sizeof(char)*sl->size);
							memcpy(sl->data, slc->data, sizeof(char)*sl->size);
							gf_list_insert(cfg->pictureParameterSets, sl, 0);
						}
						gf_odf_avc_cfg_del(svccfg);
					}
				}

				if (esd->decoderConfig->decoderSpecificInfo->data) gf_free(esd->decoderConfig->decoderSpecificInfo->data);
				gf_odf_avc_cfg_write(cfg, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength);
				gf_odf_avc_cfg_del(cfg);
			}

			od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
			od->service_ifce = read->input;
			od->objectDescriptorID = 0;
			if (!ocr_es_id) ocr_es_id = esd->ESID;
			esd->OCRESID = ocr_es_id;
			gf_list_add(od->ESDescriptors, esd);
			if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) {
				send_proxy_command(read, GF_FALSE, GF_TRUE, GF_OK, (GF_Descriptor*)od, NULL);
			} else {
				gf_term_add_media(read->service, (GF_Descriptor*)od, GF_TRUE);
			}
		}
	}
	/*if cover art, extract it in cache*/
	if (gf_isom_apple_get_tag(read->mov, GF_ISOM_ITUNE_COVER_ART, &tag, &tlen)==GF_OK) {
		const char *cdir = gf_modules_get_option((GF_BaseInterface *)gf_term_get_service_interface(read->service), "General", "CacheDirectory");
		if (cdir) {
			char szName[GF_MAX_PATH];
			const char *sep;
			FILE *t;
			sep = strrchr(gf_isom_get_filename(read->mov), '\\');
			if (!sep) sep = strrchr(gf_isom_get_filename(read->mov), '/');
			if (!sep) sep = gf_isom_get_filename(read->mov);

			if ((cdir[strlen(cdir)-1] != '\\') && (cdir[strlen(cdir)-1] != '/')) {
				sprintf(szName, "%s/%s_cover.%s", cdir, sep, (tlen & 0x80000000) ? "png" : "jpg");
			} else {
				sprintf(szName, "%s%s_cover.%s", cdir, sep, (tlen & 0x80000000) ? "png" : "jpg");
			}

			t = gf_f64_open(szName, "wb");

			if (t) {
				Bool isom_contains_video = GF_FALSE;

				/*write cover data*/
				assert(!(tlen & 0x80000000));
				gf_fwrite(tag, tlen & 0x7FFFFFFF, 1, t);
				fclose(t);

				/*don't display cover art when video is present*/
				for (i=0; i<gf_isom_get_track_count(read->mov); i++) {
					if (!gf_isom_is_track_enabled(read->mov, i+1))
						continue;
					if (gf_isom_get_media_type(read->mov, i+1) == GF_ISOM_MEDIA_VISUAL) {
						isom_contains_video = GF_TRUE;
						break;
					}
				}

				if (!isom_contains_video) {
					od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
					od->service_ifce = read->input;
					od->objectDescriptorID = GF_MEDIA_EXTERNAL_ID;
					od->URLString = gf_strdup(szName);
					if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) {
						send_proxy_command(read, GF_FALSE, GF_TRUE, GF_OK, (GF_Descriptor*)od, NULL);
					} else {
						gf_term_add_media(read->service, (GF_Descriptor*)od, GF_TRUE);
					}
				}
			}
		}
	}
	if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) {
		send_proxy_command(read, GF_FALSE, GF_TRUE, GF_OK, NULL, NULL);
	} else {
		gf_term_add_media(read->service, NULL, GF_FALSE);
	}
}
Example #11
0
static void M2TS_OnEvent(GF_M2TS_Demuxer *ts, u32 evt_type, void *param)
{
    GF_Event evt;
    M2TSIn *m2ts = (M2TSIn *) ts->user;

    switch (evt_type) {
    case GF_M2TS_EVT_PAT_UPDATE:
        /*	example code showing how to forward an event from MPEG-2 TS input service to GPAC user*/
#if 0
    {
        GF_Event evt;
        evt.type = GF_EVENT_FORWARDED;
        evt.forwarded_event.forward_type = GF_EVT_FORWARDED_MPEG2;
        evt.forwarded_event.forward_type = GF_EVT_FORWARDED_MPEG2;
        evt.forwarded_event.service_event_type = evt_type;
        evt.forwarded_event.param = param;
        gf_term_on_service_event(m2ts->service, &evt);
    }
#endif
    break;
    case GF_M2TS_EVT_AIT_FOUND:
        evt.type = GF_EVENT_FORWARDED;
        evt.forwarded_event.forward_type = GF_EVT_FORWARDED_MPEG2;
        evt.forwarded_event.service_event_type = evt_type;
        evt.forwarded_event.param = param;
        gf_term_on_service_event(m2ts->service, &evt);
        break;
    case GF_M2TS_EVT_PAT_FOUND:
        /* In case the TS has one program, wait for the PMT to send connect, in case of IOD in PMT */
        if (gf_list_count(m2ts->ts->programs) != 1) {
            gf_term_on_connect(m2ts->service, NULL, GF_OK);
            m2ts->is_connected = 1;
        }
        /* Send the TS to the a user if needed. Useful to check the number of received programs*/
        evt.type = GF_EVENT_FORWARDED;
        evt.forwarded_event.forward_type = GF_M2TS_EVT_PAT_FOUND;
        evt.forwarded_event.service_event_type = evt_type;
        evt.forwarded_event.param = ts;
        gf_term_on_service_event(m2ts->service, &evt);
        break;
    case GF_M2TS_EVT_PMT_FOUND:
        if (gf_list_count(m2ts->ts->programs) == 1) {
            gf_term_on_connect(m2ts->service, NULL, GF_OK);
            m2ts->is_connected = 1;
        }

        /*do not declare if  single program was requested for playback*/
        MP2TS_SetupProgram(m2ts, param, m2ts->request_all_pids, m2ts->request_all_pids ? 0 : 1);
        M2TS_FlushRequested(m2ts);
        break;
    case GF_M2TS_EVT_PMT_REPEAT:
//	case GF_M2TS_EVT_PMT_UPDATE:
        M2TS_FlushRequested(m2ts);
        break;
    case GF_M2TS_EVT_SDT_REPEAT:
    case GF_M2TS_EVT_SDT_UPDATE:
    case GF_M2TS_EVT_SDT_FOUND:
        M2TS_FlushRequested(m2ts);
        break;
    case GF_M2TS_EVT_DVB_GENERAL:
        if (m2ts->eit_channel) {
            GF_M2TS_SL_PCK *pck = (GF_M2TS_SL_PCK *)param;
            gf_term_on_sl_packet(m2ts->service, m2ts->eit_channel, pck->data, pck->data_len, NULL, GF_OK);
        }
        break;
    case GF_M2TS_EVT_PES_PCK:
        MP2TS_SendPacket(m2ts, param);
        break;
    case GF_M2TS_EVT_SL_PCK:
        MP2TS_SendSLPacket(m2ts, param);
        break;
    case GF_M2TS_EVT_AAC_CFG:
    {
        GF_M2TS_PES_PCK *pck = (GF_M2TS_PES_PCK*)param;
        if (!pck->stream->first_dts) {
            gf_m2ts_set_pes_framing(pck->stream, GF_M2TS_PES_FRAMING_SKIP_NO_RESET);
            MP2TS_DeclareStream(m2ts, pck->stream, pck->data, pck->data_len);
            if (ts->file || ts->dnload) ts->file_regulate = 1;
            pck->stream->first_dts=1;
            /*force scene regeneration*/
            gf_term_add_media(m2ts->service, NULL, 0);
        }
    }
    break;
    case GF_M2TS_EVT_PES_PCR:
        /*send pcr*/
        if (((GF_M2TS_PES_PCK *) param)->stream && ((GF_M2TS_PES_PCK *) param)->stream->user) {
            GF_SLHeader slh;
            memset(&slh, 0, sizeof(GF_SLHeader) );
            slh.OCRflag = 1;
            slh.m2ts_pcr = ( ((GF_M2TS_PES_PCK *) param)->flags & GF_M2TS_PES_PCK_DISCONTINUITY) ? 2 : 1;
            slh.objectClockReference = ((GF_M2TS_PES_PCK *) param)->PTS;
            gf_term_on_sl_packet(m2ts->service, ((GF_M2TS_PES_PCK *) param)->stream->user, NULL, 0, &slh, GF_OK);
        }
        ((GF_M2TS_PES_PCK *) param)->stream->program->first_dts = 1;

        if ( ((GF_M2TS_PES_PCK *) param)->flags & GF_M2TS_PES_PCK_DISCONTINUITY) {
#if 0
            if (ts->pcr_last) {
                ts->pcr_last = ((GF_M2TS_PES_PCK *) param)->PTS;
                ts->stb_at_last_pcr = gf_sys_clock();
            }
#endif
            GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TS In] PCR discontinuity - switching from old STB "LLD" to new one "LLD"\n", ts->pcr_last, ((GF_M2TS_PES_PCK *) param)->PTS));
            /*FIXME - we need to find a way to treat PCR discontinuities correctly while ignoring broken PCR discontinuities
            seen in many HLS solutions*/
            return;
        }

        if (ts->file_regulate) {
            u64 pcr = ((GF_M2TS_PES_PCK *) param)->PTS;
            u32 stb = gf_sys_clock();

            if (m2ts->regulation_pcr_pid==0) {
                /*we pick the first PCR PID for file regulation - we don't need to make sure this is the PCR of a program being plyaed as we
                only check buffer levels, not DTS/PTS of the streams in the regulation step*/
                m2ts->regulation_pcr_pid = ((GF_M2TS_PES_PCK *) param)->stream->pid;
            } else if (m2ts->regulation_pcr_pid != ((GF_M2TS_PES_PCK *) param)->stream->pid) {
                return;
            }


            if (ts->pcr_last) {
                s32 diff;
                if (pcr < ts->pcr_last) {
                    GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TS In] PCR "LLU" less than previous PCR "LLU"\n", ((GF_M2TS_PES_PCK *) param)->PTS, ts->pcr_last));
                    ts->pcr_last = pcr;
                    ts->stb_at_last_pcr = gf_sys_clock();
                    diff = 0;
                } else {
                    u64 pcr_diff = (pcr - ts->pcr_last);
                    pcr_diff /= 27000;
                    if (pcr_diff>1000) {
                        GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[M2TS In] PCR diff too big: "LLU" ms - PCR "LLU" - previous PCR "LLU" - error in TS ?\n", pcr_diff, ((GF_M2TS_PES_PCK *) param)->PTS, ts->pcr_last));
                        diff = 100;
                    } else {
                        diff = (u32) pcr_diff - (stb - ts->stb_at_last_pcr);
                    }
                }
                if (diff<0) {
                    GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[M2TS In] Demux not going fast enough according to PCR (drift %d, pcr: "LLU", last pcr: "LLU")\n", diff, pcr, ts->pcr_last));
                } else if (diff>0) {
                    u32 sleep_for=1;
#ifndef GPAC_DISABLE_LOG
                    u32 nb_sleep=0;
#endif
                    /*query buffer level, don't sleep if too low*/
                    GF_NetworkCommand com;
                    com.command_type = GF_NET_BUFFER_QUERY;
                    while (ts->run_state) {
                        gf_term_on_command(m2ts->service, &com, GF_OK);
                        if (com.buffer.occupancy < M2TS_BUFFER_MAX) {
                            GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[M2TS In] Demux not going to sleep: buffer occupancy %d ms\n", com.buffer.occupancy));
                            break;
                        }
                        /*We don't sleep for the entire buffer occupancy, because we would take
                        the risk of starving the audio chains. We try to keep buffers half full*/
#ifndef GPAC_DISABLE_LOG
                        if (!nb_sleep) {
                            GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[M2TS In] Demux going to sleep (buffer occupancy %d ms)\n", com.buffer.occupancy));
                        }
                        nb_sleep++;
#endif
                        gf_sleep(sleep_for);
                    }
#ifndef GPAC_DISABLE_LOG
                    if (nb_sleep) {
                        GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[M2TS In] Demux resume after %d ms - current buffer occupancy %d ms\n", sleep_for*nb_sleep, com.buffer.occupancy));
                    }
#endif
                    ts->nb_pck = 0;
                    ts->pcr_last = pcr;
                    ts->stb_at_last_pcr = gf_sys_clock();
                } else {
                    GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TS In] Demux drift according to PCR (drift %d, pcr: "LLD", last pcr: "LLD")\n", diff, pcr, ts->pcr_last));
                }
            } else {
                ts->pcr_last = pcr;
                ts->stb_at_last_pcr = gf_sys_clock();
            }
        }
        break;
    case GF_M2TS_EVT_TDT:
        if (m2ts->hybrid_on) {
            u32 i, count;
            GF_M2TS_TDT_TOT *tdt = (GF_M2TS_TDT_TOT *)param;
            GF_NetworkCommand com;
            memset(&com, 0, sizeof(com));
            com.command_type = GF_NET_CHAN_MAP_TIME;
            com.map_time.media_time = tdt->hour*3600+tdt->minute*60+tdt->second;
            com.map_time.reset_buffers = 0;
            count = gf_list_count(ts->programs);
            for (i=0; i<count; i++) {
                GF_M2TS_Program *prog = gf_list_get(ts->programs, i);
                u32 j, count2;
                if (prog->tdt_found || !prog->last_pcr_value) /*map TDT one time, after we received a PCR*/
                    continue;
                prog->tdt_found = 1;
                count2 = gf_list_count(prog->streams);
                com.map_time.timestamp = prog->last_pcr_value/300;
                for (j=0; j<count2; j++) {
                    GF_M2TS_ES * stream = gf_list_get(prog->streams, j);
                    if (stream->user) {
                        com.base.on_channel = stream->user;
                        gf_term_on_command(m2ts->service, &com, GF_OK);
                    }
                }
                GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TS In] Mapping TDT Time %04d/%02d/%02d %02d:%02d:%02d and PCR time "LLD" on program %d\n",
                                                       tdt->year, tdt->month, tdt->day, tdt->hour, tdt->minute, tdt->second, com.map_time.timestamp, prog->number));
            }
        }
        break;
    case GF_M2TS_EVT_TOT:
        break;
    }
}
Example #12
0
static void M2TS_FlushRequested(M2TSIn *m2ts)
{
    u32 i, j, req_prog_count, count, prog_id, found;

    gf_mx_p(m2ts->mx);

    found = 0;
    count = gf_list_count(m2ts->ts->requested_pids);
    for (i=0; i<count; i++) {
        M2TSIn_Prog *req_pid = gf_list_get(m2ts->ts->requested_pids, i);
        GF_M2TS_ES *es = m2ts->ts->ess[req_pid->pid];
        if (es==NULL) continue;

        /*move to skip mode for all PES until asked for playback*/
        if (!(es->flags & GF_M2TS_ES_IS_SECTION) && !es->user)
            gf_m2ts_set_pes_framing((GF_M2TS_PES *)es, GF_M2TS_PES_FRAMING_SKIP);
        MP2TS_DeclareStream(m2ts, (GF_M2TS_PES *)es, NULL, 0);
        gf_list_rem(m2ts->ts->requested_pids, i);
        gf_free(req_pid);
        i--;
        count--;
        found++;
    }
    req_prog_count = gf_list_count(m2ts->ts->requested_progs);
    for (i = 0; i < req_prog_count; i++) {
        M2TSIn_Prog *req_prog = gf_list_get(m2ts->ts->requested_progs, i);
        prog_id = atoi(req_prog->fragment);
        count = gf_list_count(m2ts->ts->SDTs);
        for (j=0; j<count; j++) {
            GF_M2TS_SDT *sdt = gf_list_get(m2ts->ts->SDTs, j);
            if (!stricmp(sdt->service, req_prog->fragment)) req_prog->id = sdt->service_id;
            else if (sdt->service_id==prog_id)  req_prog->id = sdt->service_id;
        }
        if (req_prog->id) {
            GF_M2TS_Program *ts_prog;
            count = gf_list_count(m2ts->ts->programs);
            for (j=0; j<count; j++) {
                ts_prog = gf_list_get(m2ts->ts->programs, j);
                if (ts_prog->number==req_prog->id) {
                    MP2TS_SetupProgram(m2ts, ts_prog, 0, 0);
                    found++;
                    gf_free(req_prog->fragment);
                    gf_free(req_prog);
                    gf_list_rem(m2ts->ts->requested_progs, i);
                    req_prog_count--;
                    i--;
                    break;
                }
            }
        }
    }

    if (m2ts->epg_requested) {
        if (!m2ts->has_eit) {
            GF_ObjectDescriptor *od = M2TS_GenerateEPG_OD(m2ts);
            /*declare but don't regenerate scene*/
            gf_term_add_media(m2ts->service, (GF_Descriptor*)od, 0);
            m2ts->has_eit = 1;
        }
    } else {
        /*force scene regeneration only when EPG is not requested*/
        if (found)
            gf_term_add_media(m2ts->service, NULL, 0);
    }

    gf_mx_v(m2ts->mx);
}
Example #13
0
GF_Err LIBPLAYER_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url)
{
	LibPlayerIn *read = (LibPlayerIn *) plug->priv;
#ifndef TEST_LIBPLAYER
	unsigned long prop;
	mrl_t *mrl = NULL;
#endif
	printf("[LibPlayerIN]connecting\n");
	if (!read || !serv || !url) return GF_BAD_PARAM;

	if (!strnicmp(url, "libplayer://", 12)) url+=12;
  
	if (!read->init) {
		read->init=1;
		/* libplayer init */
		read->url = url;
		read->player_id = libplayer_id;
#ifndef TEST_LIBPLAYER
		read->player = player_init(PLAYER_TYPE_DUMMY, PLAYER_AO_AUTO, PLAYER_VO_AUTO, PLAYER_MSG_INFO, read->player_id, on_libplayer_event);
		//~ read->width = 0;
		//~ read->height = 0;
		
		if (!read->player) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[LibPlayerIN]�Failed to instanciate libplayer instance %d\n", read->player_id));
			gf_term_on_connect(serv, NULL, GF_REMOTE_SERVICE_ERROR);
			return GF_OK;
		}
#endif
		libplayer_id++;
		GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerIN] Opening URL %s for Player instance %d\n", url, read->player_id));
		//~ player_local_location_set(read->player, url);
		
	}
	
#ifndef TEST_LIBPLAYER
	mrl = NULL;
	if (!strnicmp(url, "dvb://", 6)) {
	}
	else if (!strnicmp(url, "file://", 7) || !strstr(url, "://")) {
		mrl_resource_local_args_t *mrl_args;
		mrl_args = calloc(1, sizeof(mrl_resource_local_args_t));
		if (!strnicmp(url, "file://", 7)) {
			mrl_args->location = strdup(url + 7);
		}  else {
			mrl_args->location = strdup(url);
		}
		mrl = mrl_new (read->player, MRL_RESOURCE_FILE, mrl_args);
	}
	else {
	}

	if (!mrl) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[LibPlayerIN]�Failed to create MRL for url %s\n", url));
		gf_term_on_connect(serv, NULL, GF_URL_ERROR);
		return GF_OK;
	}
    player_mrl_set(read->player, mrl);

#endif
	read->state = 0;
	read->service = serv;

	/*ACK connection is OK*/
	gf_term_on_connect(serv, NULL, GF_OK);


	/*setup LIBPLAYER object descriptor*/
	{
		GF_ESD *esd;
		GF_ObjectDescriptor *od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
		od->objectDescriptorID = 1+read->player_id;

		esd = gf_odf_desc_esd_new(0);
		esd->ESID = 1+read->player_id;
		esd->slConfig->timestampResolution = 1000;
		esd->decoderConfig->streamType = GF_STREAM_PRIVATE_MEDIA;
		esd->decoderConfig->objectTypeIndication = GPAC_OTI_PRIVATE_MEDIA_LIBPLAYER;
#ifndef TEST_LIBPLAYER
		esd->decoderConfig->decoderSpecificInfo->data = read;
#endif

		gf_list_add(od->ESDescriptors, esd);
		gf_term_add_media(read->service, (GF_Descriptor*)od, 0);
	}

	return GF_OK;
}
Example #14
0
static void SAF_NetIO(void *cbk, GF_NETIO_Parameter *param)
{
	GF_Err e;
	Bool is_rap, go;
	SAFChannel *ch;
	u32 cts, au_sn, au_size, type, i, stream_id;
	u64 bs_pos;
	GF_BitStream *bs;
	GF_SLHeader sl_hdr;

	SAFIn *read = (SAFIn *) cbk;

	e = param->error;
	/*done*/
	if (param->msg_type==GF_NETIO_DATA_TRANSFERED) {
		if (read->stream && (read->saf_type==SAF_FILE_REMOTE)) read->saf_type = SAF_FILE_LOCAL;
		return;
	} else {
		/*handle service message*/
		gf_term_download_update_stats(read->dnload);
		if (param->msg_type!=GF_NETIO_DATA_EXCHANGE) {
			if (e<0) {
				if (read->needs_connection) {
					read->needs_connection = 0;
					gf_term_on_connect(read->service, NULL, e);
				}
				return;
			}
			if (read->needs_connection) {
				u32 total_size;
				gf_dm_sess_get_stats(read->dnload, NULL, NULL, &total_size, NULL, NULL, NULL);
				if (!total_size) read->saf_type = SAF_LIVE_STREAM;
			}
			return;
		}
	}
	if (!param->size) return;

	if (!read->run_state) return;

	if (read->alloc_size < read->saf_size + param->size) {
		read->saf_data = (char*)gf_realloc(read->saf_data, sizeof(char)*(read->saf_size + param->size) );
		read->alloc_size = read->saf_size + param->size;
	}
	memcpy(read->saf_data + read->saf_size, param->data, sizeof(char)*param->size);
	read->saf_size += param->size;

	/*first AU not complete yet*/
	if (read->saf_size<10) return;

	bs = gf_bs_new(read->saf_data, read->saf_size, GF_BITSTREAM_READ);
	bs_pos = 0;

	go = 1;
	while (go) {
		u64 avail = gf_bs_available(bs);
		bs_pos = gf_bs_get_position(bs);

		if (avail<10) break;

		is_rap = gf_bs_read_int(bs, 1);
		au_sn = gf_bs_read_int(bs, 15);
		gf_bs_read_int(bs, 2);
		cts = gf_bs_read_int(bs, 30);
		au_size = gf_bs_read_int(bs, 16);
		avail-=8;

		if (au_size > avail) break;
		assert(au_size>=2);

		is_rap = 1;

		type = gf_bs_read_int(bs, 4);
		stream_id = gf_bs_read_int(bs, 12);
		au_size -= 2;

		ch = saf_get_channel(read, stream_id, NULL);
		switch (type) {
		case 1:
		case 2:
		case 7:
			if (ch) {
				gf_bs_skip_bytes(bs, au_size);
			} else {
				SAFChannel *first = (SAFChannel *)gf_list_get(read->channels, 0);
				GF_SAFEALLOC(ch, SAFChannel);
				ch->stream_id = stream_id;
				ch->esd = gf_odf_desc_esd_new(0);
				ch->esd->ESID = stream_id;
				ch->esd->OCRESID = first ? first->stream_id : stream_id;
				ch->esd->slConfig->useRandomAccessPointFlag = 1;
				ch->esd->slConfig->AUSeqNumLength = 0;
				ch->esd->decoderConfig->objectTypeIndication = gf_bs_read_u8(bs);
				ch->esd->decoderConfig->streamType = gf_bs_read_u8(bs);
				ch->ts_res = ch->esd->slConfig->timestampResolution = gf_bs_read_u24(bs);
				ch->esd->decoderConfig->bufferSizeDB = gf_bs_read_u16(bs);
				au_size -= 7;
				if ((ch->esd->decoderConfig->objectTypeIndication == 0xFF) && (ch->esd->decoderConfig->streamType == 0xFF) ) {
					u16 mimeLen = gf_bs_read_u16(bs);
					gf_bs_skip_bytes(bs, mimeLen);
					au_size -= mimeLen+2;
				}
				if (type==7) {
					u16 urlLen = gf_bs_read_u16(bs);
					ch->esd->URLString = (char*)gf_malloc(sizeof(char)*(urlLen+1));
					gf_bs_read_data(bs, ch->esd->URLString, urlLen);
					ch->esd->URLString[urlLen] = 0;
					au_size -= urlLen+2;
				}
				if (au_size) {
					ch->esd->decoderConfig->decoderSpecificInfo->dataLength = au_size;
					ch->esd->decoderConfig->decoderSpecificInfo->data = (char*)gf_malloc(sizeof(char)*au_size);
					gf_bs_read_data(bs, ch->esd->decoderConfig->decoderSpecificInfo->data, au_size);
				}
				if (ch->esd->decoderConfig->streamType==4) ch->buffer_min=100;
				else if (ch->esd->decoderConfig->streamType==5) ch->buffer_min=400;
				else ch->buffer_min=0;

				if (read->needs_connection && (ch->esd->decoderConfig->streamType==GF_STREAM_SCENE)) {
					gf_list_add(read->channels, ch);
					read->needs_connection = 0;
					gf_term_on_connect(read->service, NULL, GF_OK);
				} else if (read->needs_connection) {
					gf_odf_desc_del((GF_Descriptor *) ch->esd);
					gf_free(ch);
					ch = NULL;
				} else {
					GF_ObjectDescriptor *od;
					gf_list_add(read->channels, ch);

					od = (GF_ObjectDescriptor*)gf_odf_desc_new(GF_ODF_OD_TAG);
					gf_list_add(od->ESDescriptors, ch->esd);
					ch->esd = NULL;
					od->objectDescriptorID = ch->stream_id;
					gf_term_add_media(read->service, (GF_Descriptor*)od, 0);

				}
			}
			break;
		case 4:
			if (ch) {
				bs_pos = gf_bs_get_position(bs);
				memset(&sl_hdr, 0, sizeof(GF_SLHeader));
				sl_hdr.accessUnitLength = au_size;
				sl_hdr.AU_sequenceNumber = au_sn;
				sl_hdr.compositionTimeStampFlag = 1;
				sl_hdr.compositionTimeStamp = cts;
				sl_hdr.randomAccessPointFlag = is_rap;
				if (read->start_range && (read->start_range*ch->ts_res>cts*1000)) {
					sl_hdr.compositionTimeStamp = read->start_range*ch->ts_res/1000;
				}
				gf_term_on_sl_packet(read->service, ch->ch, read->saf_data+bs_pos, au_size, &sl_hdr, GF_OK);
			}
			gf_bs_skip_bytes(bs, au_size);
			break;
		case 3:
			if (ch) gf_term_on_sl_packet(read->service, ch->ch, NULL, 0, NULL, GF_EOS);
			break;
		case 5:
			go = 0;
			read->run_state = 0;
			i=0;
			while ((ch = (SAFChannel *)gf_list_enum(read->channels, &i))) {
				gf_term_on_sl_packet(read->service, ch->ch, NULL, 0, NULL, GF_EOS);
			}
			break;
		}
	}

	gf_bs_del(bs);
	if (bs_pos) {
		u32 remain = (u32) (read->saf_size - bs_pos);
		if (remain) memmove(read->saf_data, read->saf_data+bs_pos, sizeof(char)*remain);
		read->saf_size = remain;
	}
	SAF_Regulate(read);
}