Exemplo n.º 1
0
bool CStreamManager::Parse(int fd, stream_pids_t &pids, t_channel_id &chid)
{
	char cbuf[512];
	char *bp;

	FILE * fp = fdopen(fd, "r+");
	if(fp == NULL) {
		perror("fdopen");
		return false;
	}
	cbuf[0] = 0;
	bp = &cbuf[0];

	/* read one line */
	while (bp - &cbuf[0] < (int) sizeof(cbuf)) {
		unsigned char c;
		int res = read(fd, &c, 1);
		if(res < 0) {
			perror("read");
			return false;
		}
		if ((*bp++ = c) == '\n')
			break;
	}

	*bp++ = 0;
	bp = &cbuf[0];

	printf("CStreamManager::Parse: got %s\n", cbuf);

	/* send response to http client */
	if (!strncmp(cbuf, "GET /", 5)) {
		fprintf(fp, "HTTP/1.1 200 OK\r\nServer: streamts (%s)\r\n\r\n", "ts" /*&argv[1][1]*/);
		fflush(fp);
		bp += 5;
	} else {
		printf("Received garbage\n");
		return false;
	}

#ifndef ENABLE_MULTI_CHANNEL
	/* parse stdin / url path, start dmx filters */
	do {
		int pid;
		int res = sscanf(bp, "%x", &pid);
		if(res == 1) {
			printf("New pid: 0x%x\n", pid);
			pids.insert(pid);
		}
	}
	while ((bp = strchr(bp, ',')) && (bp++));
#endif

	chid = CZapit::getInstance()->GetCurrentChannelID();
	CZapitChannel * channel = CZapit::getInstance()->GetCurrentChannel();

	int mode = CNeutrinoApp::getInstance()->getMode();
	if (mode == NeutrinoMessages::mode_standby && streams.empty()) {
		printf("CStreamManager::Parse: wakeup zapit..\n");
		cpuFreq->SetCpuFreq(g_settings.cpufreq * 1000 * 1000);
		g_Zapit->setStandby(false);
		g_Zapit->getMode();
	}
	if(pids.empty()) {
#ifdef ENABLE_MULTI_CHANNEL
		t_channel_id tmpid;
		bp = &cbuf[5];
		if (sscanf(bp, "id=%llx", &tmpid) == 1) {
			printf("############################# channel_id %llx\n", tmpid);

			CZapitChannel * tmpchan = CServiceManager::getInstance()->FindChannel(tmpid);
			if (tmpchan && (tmpid != chid) && SAME_TRANSPONDER(tmpid, chid)) {
				printf("############################# channel_id %llx -> zap\n", tmpid);
				bool ret = g_Zapit->zapTo_record(tmpid) > 0;
				if (ret) {
					channel = tmpchan;
					chid = tmpid;
				}
			}
		}
		if(CRecordManager::getInstance()->RecordingStatus(chid)) {
			printf("CStreamManager::Parse: channel %llx recorded, aborting..\n", chid);
			return false;
		}
#ifdef ENABLE_PIP
		t_channel_id pip_channel_id = CZapit::getInstance()->GetPipChannelID();
		if ((chid == pip_channel_id) && (channel->getRecordDemux() == channel->getPipDemux())) {
			printf("CStreamManager::Parse: channel %llx used for pip, aborting..\n", chid);
			return false;
		}
#endif
#endif

		printf("CStreamManager::Parse: no pids in url, using channel %llx pids\n", chid);
		if(!channel)
			return false;
		//pids.insert(0);
		//pids.insert(channel->getPmtPid());
		pids.insert(channel->getVideoPid());
		for (int i = 0; i <  channel->getAudioChannelCount(); i++)
			pids.insert(channel->getAudioChannel(i)->pid);

	}
	CGenPsi psi;
	for (stream_pids_t::iterator it = pids.begin(); it != pids.end(); ++it) {
		if (*it == channel->getVideoPid()) {
			printf("CStreamManager::Parse: genpsi vpid %x (%d)\n", *it, channel->type);
			psi.addPid(*it, channel->type ? EN_TYPE_AVC : EN_TYPE_VIDEO, 0);
		} else {
			for (int i = 0; i <  channel->getAudioChannelCount(); i++) {
				if (*it == channel->getAudioChannel(i)->pid) {
					CZapitAudioChannel::ZapitAudioChannelType atype = channel->getAudioChannel(i)->audioChannelType;
					printf("CStreamManager::Parse: genpsi apid %x (%d)\n", *it, atype);
					if(channel->getAudioChannel(i)->audioChannelType == CZapitAudioChannel::EAC3){
						psi.addPid(*it, EN_TYPE_AUDIO_EAC3, atype, channel->getAudioChannel(i)->description.c_str());
					}else{
						psi.addPid(*it, EN_TYPE_AUDIO, atype, channel->getAudioChannel(i)->description.c_str());
					}
				}
			}
		}
	}
	//add pcr pid
	if(channel->getPcrPid() != channel->getVideoPid()){
		pids.insert(channel->getPcrPid());
		psi.addPid(channel->getPcrPid(), EN_TYPE_PCR, 0);
	}
	//add teletext pid
	if (g_settings.recording_stream_vtxt_pid && channel->getTeletextPid() != 0){
		pids.insert(channel->getTeletextPid());
		psi.addPid(channel->getTeletextPid(), EN_TYPE_TELTEX, 0, channel->getTeletextLang());
	}
	//add dvb sub pid
	if (g_settings.recording_stream_subtitle_pids){
		for (int i = 0 ; i < (int)channel->getSubtitleCount() ; ++i) {
			CZapitAbsSub* s = channel->getChannelSub(i);
			if (s->thisSubType == CZapitAbsSub::DVB) {
				if(i>9)//max sub pids
					break;

				CZapitDVBSub* sd = reinterpret_cast<CZapitDVBSub*>(s);
				pids.insert(sd->pId);
				psi.addPid( sd->pId, EN_TYPE_DVBSUB, 0, sd->ISO639_language_code.c_str() );
			}
		}

	}

	psi.genpsi(fd);

	return !pids.empty();
}
//-------------------------------------------------------------------------
// y-func : get_audio_pids_as_dropdown (from controlapi)
// prara: [apid] option value = apid-Value. Default apid-Index
//-------------------------------------------------------------------------
std::string  CNeutrinoYParser::func_get_audio_pids_as_dropdown(CyhookHandler *, std::string para)
{
	std::string yresult;
	static bool init_iso=true;
	bool idx_as_id=true;
	unsigned int selected_apid = 0;
	t_channel_id current_channel_id = 0;
	CZapitChannel * channel = NULL;
	if(para == "apid")
		idx_as_id=false;
	else if(!para.empty() && ("channel="== para.substr(0,8))){
		if (sscanf(para.c_str(), "channel=%" SCNx64 ":audio=%i:", &current_channel_id,&selected_apid) == 2) {
			if(current_channel_id != 0 && CZapit::getInstance()->GetCurrentChannelID() != current_channel_id){
				channel = CServiceManager::getInstance()->FindChannel(current_channel_id);
			}
		}
	}
	if(init_iso)
	{
		if(_initialize_iso639_map())
			init_iso=false;
	}
	if (channel){//check audio pid if current_channel != vlc live channel
		//wait for channel lock
		for (int i = 0; i < 30 && channel->getAudioChannelCount()==0;i++){
			usleep(100000);
		}
		for (unsigned int i = 0; i <  channel->getAudioChannelCount(); i++) {
			CZapitAudioChannel::ZapitAudioChannelType atype = channel->getAudioChannel(i)->audioChannelType;
			std::string a_desc;
			if(!(init_iso)){
				a_desc = _getISO639Description( channel->getAudioChannel(i)->description.c_str() );
			}else{
				a_desc = channel->getAudioChannel(i)->description.c_str();
			}
			if (channel->getAudioChannel(i)->audioChannelType == CZapitAudioChannel::EAC3) {
				yresult += string_printf("<option value=%05u %s>%s %s</option>\r\n",i
				, (i==selected_apid) ? "selected=\"selected\"" : ""
				, a_desc.c_str()
				,"(EAC3)");
			} else {
				yresult += string_printf("<option value=%05u %s>%s %s</option>\r\n",i
				, (i==selected_apid) ? "selected=\"selected\"" : ""
				,a_desc.c_str()
				,atype?"(AC3)":" ");
			}
		}
	}
	if( yresult.empty()){
		bool eit_not_ok=true;
		if(current_channel_id==0)
			current_channel_id = CZapit::getInstance()->GetCurrentChannelID();

		CZapitClient::responseGetPIDs pids;
		CSectionsdClient::ComponentTagList tags;
		pids.PIDs.vpid=0;
		NeutrinoAPI->Zapit->getPIDS(pids);

		CSectionsdClient::responseGetCurrentNextInfoChannelID currentNextInfo;
		CEitManager::getInstance()->getCurrentNextServiceKey(current_channel_id, currentNextInfo);
		if (CEitManager::getInstance()->getComponentTagsUniqueKey(currentNextInfo.current_uniqueKey,tags))
		{
			unsigned int tag = 0;
			for (unsigned int i=0; i< tags.size(); i++)
			{
				for (unsigned short j=0; j< pids.APIDs.size(); j++)
				{
					if ( pids.APIDs[j].component_tag == tags[i].componentTag )
					{
						if(!tags[i].component.empty())
						{
							if(!(isalnum(tags[i].component[0])))
								tags[i].component=tags[i].component.substr(1,tags[i].component.length()-1);
							yresult += string_printf("<option value=%05u %s>%s</option>\r\n",idx_as_id ? j : pids.APIDs[j].pid,(tag==selected_apid) ? "selected=\"selected\"" : "",tags[i].component.c_str());
							tag++;
						}
						else
						{
							if(!(init_iso))
							{
								strcpy( pids.APIDs[j].desc, _getISO639Description( pids.APIDs[j].desc ) );
							}
							yresult += string_printf("<option value=%05u %s>%s %s</option>\r\n",idx_as_id ? j : pids.APIDs[j].pid,(j==selected_apid) ? "selected=\"selected\"" : "",std::string(pids.APIDs[j].desc).c_str(),pids.APIDs[j].is_ac3 ? " (AC3)": pids.APIDs[j].is_aac ? "(AAC)" : pids.APIDs[j].is_eac3 ? "(EAC3)" : " ");
						}
						eit_not_ok=false;
						break;
					}
				}
			}
		}
		if(eit_not_ok)
		{
			unsigned short i = 0;
			for (CZapitClient::APIDList::iterator it = pids.APIDs.begin(); it!=pids.APIDs.end(); ++it)
			{
				if(!(init_iso))
				{
					strcpy( pids.APIDs[i].desc, _getISO639Description( pids.APIDs[i].desc ) );
				}
				yresult += string_printf("<option value=%05u %s>%s %s</option>\r\n",
							 idx_as_id ? i : it->pid, (i==selected_apid) ? "selected=\"selected\"" : "",pids.APIDs[i].desc,
							 pids.APIDs[i].is_ac3 ? " (AC3)": pids.APIDs[i].is_aac ? "(AAC)" : pids.APIDs[i].is_eac3 ? "(EAC3)" : " ");
				i++;
			}
		}
		if(pids.APIDs.empty())
			yresult = "00000"; // shouldnt happen, but print at least one apid
	}
	return yresult;
}