Ejemplo n.º 1
0
//-------------------------------------------------------------------------
bool CVCRControl::CVCRDevice::Record(const t_channel_id channel_id, int mode, const event_id_t epgid,
				     const std::string& /*epgTitle*/, unsigned char apids, const time_t /*epg_time*/)
{
	printf("Record channel_id: "
	       PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS
	       " epg: %llx, apids 0x%X mode \n",
	       channel_id,
	       epgid,
	       apids);
	// leave menu (if in any)
	g_RCInput->postMsg( CRCInput::RC_timeout, 0 );
	
	last_mode = CNeutrinoApp::getInstance()->getMode();
	if(mode != last_mode)
	{
		CNeutrinoApp::getInstance()->handleMsg( NeutrinoMessages::CHANGEMODE , mode | NeutrinoMessages::norezap );
	}
	
	if(channel_id != 0)		// wenn ein channel angegeben ist
	{
		if(g_Zapit->getCurrentServiceID() != channel_id)	// und momentan noch nicht getuned ist
		{
			g_Zapit->zapTo_serviceID(channel_id);		// dann umschalten
		}
	}
	if(! (apids & TIMERD_APIDS_STD)) // nicht std apid
	{
		APIDList apid_list;
		getAPIDs(apids,apid_list);
		if(!apid_list.empty())
		{
			if(!apid_list.begin()->ac3)
				g_Zapit->setAudioChannel(apid_list.begin()->index);
			else
				g_Zapit->setAudioChannel(0); //sonst apid 0, also auf jeden fall ac3 aus !
		}
		else
			g_Zapit->setAudioChannel(0); //sonst apid 0, also auf jeden fall ac3 aus !
	}
	else
		g_Zapit->setAudioChannel(0); //sonst apid 0, also auf jeden fall ac3 aus !

	if(SwitchToScart)
	{
		// Auf Scart schalten
		CNeutrinoApp::getInstance()->handleMsg( NeutrinoMessages::VCR_ON, 0 );
		// Das ganze nochmal in die queue, da obiges RC_timeout erst in der naechsten ev. loop ausgef�hrt wird
		// und dann das menu widget das display falsch r�cksetzt
		g_RCInput->postMsg( NeutrinoMessages::VCR_ON, 0 );
	}

	deviceState = CMD_VCR_RECORD;
#ifdef ENABLE_LIRC
	// Send IR
	CIRSend irs("record");
	return irs.Send();
#else
	return true;
#endif
}
Ejemplo n.º 2
0
bool CVCRControl::CFileDevice::Record(const t_channel_id channel_id, int mode, const event_id_t epgid, const std::string& epgTitle, unsigned char apids, const time_t epg_time) 
{
printf("Record channel_id: " PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS " epg: %llx, apids 0x%X mode %d\n",
	       channel_id, epgid, apids, mode);

	CutBackNeutrino(channel_id, mode);

#define MAXPIDS		64
	unsigned short pids[MAXPIDS];
	unsigned int numpids;
	unsigned int pos;

	CZapitClient::CCurrentServiceInfo si = g_Zapit->getCurrentServiceInfo();
	numpids = 0;

	if (si.vpid != 0)
		transfer_pids(si.vpid, si.vtype ? EN_TYPE_AVC : EN_TYPE_VIDEO, 0);

        APIDList apid_list;
        getAPIDs(apids,apid_list);
        for(APIDList::iterator it = apid_list.begin(); it != apid_list.end(); it++) {
                pids[numpids++] = it->apid;
		transfer_pids(it->apid, EN_TYPE_AUDIO, it->ac3 ? 1 : 0);
        }
#if 0 // FIXME : why this needed ?
        if(!apid_list.empty())
                g_Zapit->setAudioChannel(apid_list.begin()->index);
#endif
        CZapitClient::responseGetPIDs allpids;
        g_Zapit->getPIDS(allpids);

	if ((StreamVTxtPid) && (si.vtxtpid != 0)) {
		pids[numpids++] = si.vtxtpid;
	}
        if ((StreamPmtPid) && (si.pmtpid != 0)) {
                pids[numpids++] = si.pmtpid;
        }
	char filename[512]; // UTF-8

	// Create filename for recording
	pos = Directory.size();
	strcpy(filename, Directory.c_str());
	
	if ((pos == 0) || (filename[pos - 1] != '/')) {
		filename[pos] = '/';
		pos++;
		filename[pos] = '\0';
	}
	pos = strlen(filename);
#if 0
	time_t t = time(NULL);
	strftime(&(filename[pos]), sizeof(filename) - pos - 1, "%Y%m%d_%H%M%S", localtime(&t));
	strcat(filename, "_");
	pos = strlen(filename);
#endif
	ext_channel_name = g_Zapit->getChannelName(channel_id);
	if (!(ext_channel_name.empty()))
	{
		strcpy(&(filename[pos]), UTF8_TO_FILESYSTEM_ENCODING(ext_channel_name.c_str()));
		char * p_act = &(filename[pos]);
		do {
			p_act += strcspn(p_act, "/ \"%&-\t`'´!,:;");
			if (*p_act) {
				*p_act++ = '_';
			}
		} while (*p_act);
		if (!autoshift && g_settings.recording_save_in_channeldir) {
			struct stat statInfo;
			int res = stat(filename,&statInfo);
			if (res == -1) {
				if (errno == ENOENT) {
					//res = mkdir(filename,0755);
					res = safe_mkdir(filename);
					if (res == 0) {
						strcat(filename,"/");
					} else {
						perror("[vcrcontrol] mkdir");
					}
						
				} else {
					perror("[vcrcontrol] stat");
				}
			} else {
				// directory exists
				strcat(filename,"/");
			}	
					
		} else
			strcat(filename, "_");
	}

	pos = strlen(filename);
	if (g_settings.recording_epg_for_filename) { 
		if(epgid != 0) {
			CShortEPGData epgdata;
			//if (g_Sectionsd->getEPGidShort(epgid, &epgdata))
			if(sectionsd_getEPGidShort(epgid, &epgdata))
			{
				if (!(epgdata.title.empty()))
				{
					strcpy(&(filename[pos]), epgdata.title.c_str());
					char * p_act = &(filename[pos]);
					do {
						p_act +=  strcspn(p_act, "/ \"%&-\t`'~<>!,:;?^°$\\=*#@¤|");
						if (*p_act) {
							*p_act++ = '_';
						}
					} while (*p_act);
				}
			}
		} else if (!epgTitle.empty()) {
			strcpy(&(filename[pos]), epgTitle.c_str());
			char * p_act = &(filename[pos]);
			do {
				p_act +=  strcspn(p_act, "/ \"%&-\t`'~<>!,:;?^°$\\=*#@¤|");
				if (*p_act) {
					*p_act++ = '_';
				}
			} while (*p_act);
		}
	}
#if 1
	pos = strlen(filename);
	time_t t = time(NULL);
	strftime(&(filename[pos]), sizeof(filename) - pos - 1, "%Y%m%d_%H%M%S", localtime(&t));
	//pos = strlen(filename);
#endif

	start_time = time(0);
	stream2file_error_msg_t error_msg = ::start_recording(filename,
			      getMovieInfoString(CMD_VCR_RECORD, channel_id, epgid, epgTitle, apid_list, epg_time).c_str(), 
			      si.vpid, pids, numpids);

	if (error_msg == STREAM2FILE_OK) {
		deviceState = CMD_VCR_RECORD;
		return true;
	}
	else {
		RestoreNeutrino();

		printf("[vcrcontrol] stream2file error code: %d\n", error_msg);
#warning FIXME: Use better error message
		DisplayErrorMessage(g_Locale->getText(
				      error_msg == STREAM2FILE_BUSY ? LOCALE_STREAMING_BUSY :
				      error_msg == STREAM2FILE_INVALID_DIRECTORY ? LOCALE_STREAMING_DIR_NOT_WRITABLE :
				      LOCALE_STREAMINGSERVER_NOCONNECT
				      )); // UTF-8

		return false;
	}
}
Ejemplo n.º 3
0
std::string CVCRControl::CFileAndServerDevice::getCommandString(const CVCRCommand command, const t_channel_id channel_id, const event_id_t epgid, const std::string& epgTitle, unsigned char apids)
{
	char tmp[40];
	std::string apids_selected;
	const char * extCommand;
	std::string info1, info2;

	std::string extMessage = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<neutrino commandversion=\"1\">\n\t<record command=\"";
	switch(command)
	{
	case CMD_VCR_RECORD:
		extCommand = "record";
		break;
	case CMD_VCR_STOP:
		extCommand = "stop";
		break;
	case CMD_VCR_PAUSE:
		extCommand = "pause";
		break;
	case CMD_VCR_RESUME:
		extCommand = "resume";
		break;
	case CMD_VCR_AVAILABLE:
		extCommand = "available";
		break;
	case CMD_VCR_UNKNOWN:
	default:
		extCommand = "unknown";
		printf("[CVCRControl] Unknown Command\n");
	}

	extMessage += extCommand;
	extMessage += 
		"\">\n"
		"\t\t<channelname>";
	
	CZapitClient::responseGetPIDs pids;
	g_Zapit->getPIDS (pids);
	CZapitClient::CCurrentServiceInfo si = g_Zapit->getCurrentServiceInfo ();

        APIDList apid_list;
        getAPIDs(apids,apid_list);
        apids_selected="";
        for(APIDList::iterator it = apid_list.begin(); it != apid_list.end(); it++)
        {
                if(it != apid_list.begin())
                        apids_selected += " ";
                sprintf(tmp, "%u", it->apid);
                apids_selected += tmp;
        }

	std::string tmpstring = g_Zapit->getChannelName(channel_id);
	if (tmpstring.empty())
		extMessage += "unknown";
	else
		extMessage += ZapitTools::UTF8_to_UTF8XML(tmpstring.c_str());
	
	extMessage += "</channelname>\n\t\t<epgtitle>";
	
	tmpstring = "not available";
	if (epgid != 0)
	{
		CShortEPGData epgdata;
		//if (g_Sectionsd->getEPGidShort(epgid, &epgdata)) {
		if(sectionsd_getEPGidShort(epgid, &epgdata)) {
//#warning fixme sectionsd should deliver data in UTF-8 format
			tmpstring = epgdata.title;
			info1 = epgdata.info1;
			info2 = epgdata.info2;
		}
	} else if (!epgTitle.empty()) {
		tmpstring = epgTitle;
	}
	extMessage += ZapitTools::UTF8_to_UTF8XML(tmpstring.c_str());
	
	extMessage += "</epgtitle>\n\t\t<id>";
	
	sprintf(tmp, PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, channel_id);
	extMessage += tmp;
	
	extMessage += "</id>\n\t\t<info1>";
	extMessage += ZapitTools::UTF8_to_UTF8XML(info1.c_str());
	extMessage += "</info1>\n\t\t<info2>";
	extMessage += ZapitTools::UTF8_to_UTF8XML(info2.c_str());
	extMessage += "</info2>\n\t\t<epgid>";
	sprintf(tmp, "%llu", epgid);
	extMessage += tmp;
	extMessage += "</epgid>\n\t\t<mode>";
	sprintf(tmp, "%d", g_Zapit->getMode());
	extMessage += tmp;
	extMessage += "</mode>\n\t\t<videopid>";
	sprintf(tmp, "%u", si.vpid);
	extMessage += tmp;
	extMessage += "</videopid>\n\t\t<audiopids selected=\"";
	extMessage += apids_selected;
	extMessage += "\">\n";
	// super hack :-), der einfachste weg an die apid descriptions ranzukommen
	g_RemoteControl->current_PIDs = pids;
	g_RemoteControl->processAPIDnames();

	for(unsigned int i= 0; i< pids.APIDs.size(); i++)
	{
		extMessage += "\t\t\t<audio pid=\"";
		sprintf(tmp, "%u", pids.APIDs[i].pid);
		extMessage += tmp;
		extMessage += "\" name=\"";
		extMessage += ZapitTools::UTF8_to_UTF8XML(g_RemoteControl->current_PIDs.APIDs[i].desc);
		extMessage += "\"/>\n";
	}
	extMessage += 
		"\t\t</audiopids>\n"
		"\t\t<vtxtpid>";
	sprintf(tmp, "%u", si.vtxtpid);
	extMessage += tmp;
	extMessage +=
		"</vtxtpid>\n"
		"\t</record>\n"
		"</neutrino>\n";

	return extMessage;
}
Ejemplo n.º 4
0
bool CVCRControl::CFileDevice::Record(const t_channel_id channel_id, int mode, const event_id_t epgid, const std::string &epgTitle, unsigned char apids,const time_t epg_time) 
{
	printf("Record channel_id: "
	       PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS
	       " epg: %llx, apids 0x%X mode %d\n",
	       channel_id,
	       epgid,
	       apids,
	       mode);

	CutBackNeutrino(channel_id, mode);

	int repeatcount=0;
#ifndef HAVE_DREAMBOX_HARDWARE
	int actmode=g_Zapit->PlaybackState(); // get actual decoder mode
	bool sptsmode=g_settings.misc_spts;   // take default from settings

	// aviaEXT is loaded, actual mode is not SPTS and switchoption is set , only in tvmode
	if ((actmode == 0) && g_settings.recording_in_spts_mode && mode == 1)
	{
		g_Zapit->PlaybackSPTS();
		while ((repeatcount++ < 10) && (g_Zapit->PlaybackState() != 1)) {
			sleep(1); 
		}
		sptsmode = true;
	}
	else if(mode==2)
	{
		if(actmode== 1)
		{
			g_Zapit->PlaybackPES();
			while ((repeatcount++ < 10) && (g_Zapit->PlaybackState() != 0)) {
				sleep(1); 
			}
		}
		sptsmode = false;
	}

	if (actmode == 1 && g_settings.recording_in_spts_mode && !sptsmode && mode == 1) {
		sptsmode = true;
	}
#else
	bool sptsmode = g_settings.recording_in_spts_mode;
#endif
#define MAXPIDS		64
	unsigned short pids[MAXPIDS];
	unsigned int numpids;
	unsigned int pos;

	CZapitClient::CCurrentServiceInfo si = g_Zapit->getCurrentServiceInfo();
	if (si.vpid != 0)
	{
		pids[0] = si.vpid;
		numpids = 1;
		if(sptsmode)
			transfer_pids(si.vpid,0x00,0);
	}
	else
	{
		/* no video pid */
		numpids = 0;
	}
	APIDList apid_list;
	getAPIDs(apids,apid_list);
	for(APIDList::iterator it = apid_list.begin(); it != apid_list.end(); it++)
	{
		pids[numpids++] = it->apid;
		if(sptsmode)
			transfer_pids(it->apid,0x01, it->ac3 ? 1 : 0);
	}
	if(!apid_list.empty())
		g_Zapit->setAudioChannel(apid_list.begin()->index);
	
	CZapitClient::responseGetPIDs allpids;
	g_Zapit->getPIDS(allpids);
	if ((StreamVTxtPid) && (si.vtxtpid != 0))
	{
		pids[numpids++] = si.vtxtpid;
	}

	if ((StreamSubtitlePid) && (allpids.SubPIDs.size() > 0)) {
		// Add ttx-pid only once
		unsigned txtdone = 0;
		if (StreamVTxtPid) {
			txtdone = si.vtxtpid;
		}
		for (unsigned ii = 0 ; ii < allpids.SubPIDs.size() ; ++ii) {
			if (allpids.SubPIDs[ii].pid != txtdone) {
				pids[numpids++] = allpids.SubPIDs[ii].pid;
			}
			if (allpids.SubPIDs[ii].pid == si.vtxtpid) {
				txtdone = si.vtxtpid;
			}
		}
	}
	
	char filename[512]; // UTF-8

	// Create filename for recording
	pos = Directory.size();
	strcpy(filename, Directory.c_str());
	
	if ((pos == 0) ||
	    (filename[pos - 1] != '/'))
	{
		filename[pos] = '/';
		pos++;
		filename[pos] = '\0';
	}
	
	time_t t = time(NULL);
	
	// %C == channel, %T == title, %I == info1, %d == date, %t == time
	if (FilenameTemplate.empty())
	{
		if (g_settings.recording_epg_for_filename)
			FilenameTemplate = "%C_%T_";
		FilenameTemplate += "%d_%t";
	}
	
	std::string expandedTemplate;
	if (CreateTemplateDirectories)
	{	
		expandedTemplate = FilenameTemplate;
	} else
	{
		expandedTemplate = std::string(basename(FilenameTemplate.c_str()));
	}
	unsigned int searchPos = std::string::npos;
	unsigned int startAt = 0;
	unsigned int dataLength = 0;
	char buf[256];
	buf[255] = '\0';
	
	if (g_settings.recording_epg_for_filename) {
		appendChannelName(buf,255,channel_id);
		dataLength = strlen(buf);
		
		while ((searchPos = expandedTemplate.find("%C",startAt)) != std::string::npos) {
			expandedTemplate.erase(searchPos,2);
			expandedTemplate.insert(searchPos,buf);
			startAt = searchPos + dataLength;
		}
		startAt = 0;
		appendEPGTitle(buf, 255, epgid, epgTitle);
		dataLength = strlen(buf);
		while ((searchPos = expandedTemplate.find("%T",startAt)) != std::string::npos) {
			expandedTemplate.erase(searchPos,2);
			expandedTemplate.insert(searchPos,buf);
			startAt = searchPos + dataLength;
		}
		startAt = 0;
		appendEPGInfo(buf, 255, epgid);
		dataLength = strlen(buf);
		while ((searchPos = expandedTemplate.find("%I",startAt)) != std::string::npos) {
			expandedTemplate.erase(searchPos,2);
			expandedTemplate.insert(searchPos,buf);
			startAt = searchPos + dataLength;
		}
	}
	
	strftime(buf,11,"%Y-%m-%d",localtime(&t));
	dataLength = strlen(buf);
	startAt = 0;
	while ((searchPos = expandedTemplate.find("%d",startAt)) != std::string::npos) {
		expandedTemplate.erase(searchPos,2);
		expandedTemplate.insert(searchPos,buf);
		startAt = searchPos + dataLength;
	}
	
	strftime(buf,7,"%H%M%S",localtime(&t));
	dataLength = strlen(buf);
	startAt = 0;
	while ((searchPos = expandedTemplate.find("%t",startAt)) != std::string::npos) {
		expandedTemplate.erase(searchPos,2);
		expandedTemplate.insert(searchPos,buf);
		startAt = searchPos + dataLength;
	}
	//printf("[CFileDevice] filename: %s, expandedTemplate: %s\n",filename,expandedTemplate.c_str());
	
	strncpy(&(filename[pos]),expandedTemplate.c_str(),511-pos);

	stream2file_error_msg_t error_msg;
	if (CreateTemplateDirectories && !createRecordingDir(filename))
	{
		error_msg = STREAM2FILE_INVALID_DIRECTORY;
	} else
	{
		error_msg = ::start_recording(filename,
					      getMovieInfoString(channel_id, epgid, epg_time).c_str(),
					      Use_O_Sync,
					      Use_Fdatasync,
					      ((unsigned long long)SplitSize) * 1048576ULL,
					      numpids,
					      pids,
					      sptsmode,
					      RingBuffers);
	}
	CreateTemplateDirectories = true;
	if (error_msg == STREAM2FILE_OK)
	{
		deviceState = CMD_VCR_RECORD;
		return true;
	}
	else
	{
		RestoreNeutrino();

		printf("[CFileDevice] stream2file error code: %d\n", error_msg);
#warning FIXME: Use better error message
		DisplayErrorMessage(g_Locale->getText(
						      error_msg == STREAM2FILE_BUSY ? LOCALE_STREAMING_BUSY :
						      error_msg == STREAM2FILE_INVALID_DIRECTORY ? LOCALE_STREAMING_DIR_NOT_WRITABLE :
						      error_msg == STREAM2FILE_RECORDING_THREADS_FAILED ? LOCALE_STREAMING_OUT_OF_MEMORY :
						      LOCALE_STREAMINGSERVER_NOCONNECT
						      )); // UTF-8

		return false;
	}
}
Ejemplo n.º 5
0
std::string CVCRControl::CFileAndServerDevice::getMovieInfoString(const t_channel_id channel_id,
								  const event_id_t epgid, const time_t epg_time,
								  const std::string& epgTitle, unsigned char apids,
								  const bool save_vtxt_pid, const bool save_sub_pids)
{
	std::string extMessage;
	CMovieInfo cMovieInfo;
	MI_MOVIE_INFO movieInfo;
	std::string info1, info2;
	event_id_t epg_id = epgid;

	cMovieInfo.clearMovieInfo(&movieInfo);
	CZapitClient::responseGetPIDs pids;
	g_Zapit->getPIDS (pids);
	CZapitClient::CCurrentServiceInfo si = g_Zapit->getCurrentServiceInfo ();

	std::string tmpstring = g_Zapit->getChannelName(channel_id);
	if (tmpstring.empty())
		movieInfo.epgChannel = "unknown";
	else
		movieInfo.epgChannel = tmpstring;

	tmpstring = (epgTitle.empty()) ? "not available" : Latin1_to_UTF8(epgTitle);
	if (epg_id != 0)
	{
//#define SHORT_EPG
#ifdef SHORT_EPG
		CShortEPGData epgdata;
		if (g_Sectionsd->getEPGidShort(epg_id, &epgdata))
		{
#warning fixme sectionsd should deliver data in UTF-8 format
			tmpstring = Latin1_to_UTF8(epgdata.title);
			info1 = Latin1_to_UTF8(epgdata.info1);
			info2 = Latin1_to_UTF8(epgdata.info2);
		}
#else
		CEPGData epgdata;
		bool has_epgdata = g_Sectionsd->getEPGid(epg_id, epg_time, &epgdata);
		if (!has_epgdata)
		{
			has_epgdata = g_Sectionsd->getActualEPGServiceKey(channel_id, &epgdata);
			if (has_epgdata && !epgTitle.empty() && epgTitle != epgdata.title)
				has_epgdata = false;
			if (has_epgdata)
				epg_id = epgdata.eventID;
		}
		if (has_epgdata)
		{
#warning fixme sectionsd should deliver data in UTF-8 format
			tmpstring = Latin1_to_UTF8(epgdata.title);
			info1 = Latin1_to_UTF8(epgdata.info1);
			info2 = Latin1_to_UTF8(epgdata.info2);
			
			movieInfo.parentalLockAge = epgdata.fsk;
			if (!epgdata.contentClassification.empty())
				movieInfo.genreMajor = epgdata.contentClassification[0];
				
			movieInfo.length = epgdata.epg_times.dauer	/ 60;
				
			printf("fsk:%d, Genre:%d, Dauer: %d\r\n",movieInfo.parentalLockAge,movieInfo.genreMajor,movieInfo.length);	
		}
#endif
	}
	movieInfo.epgTitle = 	tmpstring;
	movieInfo.epgId = 		channel_id;
	movieInfo.epgInfo1 = 	info1;
	movieInfo.epgInfo2 = 	info2;
	movieInfo.epgEpgId =  	epg_id;
	movieInfo.epgMode = 	g_Zapit->getMode();
	movieInfo.epgVideoPid = si.vpid;

	EPG_AUDIO_PIDS audio_pids;
	// super hack :-), der einfachste weg an die apid descriptions ranzukommen
	g_RemoteControl->current_EPGid = epg_id;
	g_RemoteControl->current_PIDs = pids;
	g_RemoteControl->processAPIDnames();
	APIDList apid_list;
	getAPIDs(apids,apid_list);
	for(APIDList::iterator it = apid_list.begin(); it != apid_list.end(); ++it)
	{
		audio_pids.epgAudioPid = it->apid;
		audio_pids.epgAudioPidName = g_RemoteControl->current_PIDs.APIDs[it->index].desc;
		movieInfo.audioPids.push_back(audio_pids);
	}

	if (save_vtxt_pid)
		movieInfo.epgVTXPID = si.vtxtpid;

	if (save_sub_pids)
	{
		SUB_PIDS sub_pids;
		for (unsigned int i = 0; i < pids.SubPIDs.size(); i++)
		{
			sub_pids.subPid = pids.SubPIDs[i].pid;
			sub_pids.subPage = pids.SubPIDs[i].composition_page;
			sub_pids.subName = getISO639Description(pids.SubPIDs[i].desc);
			movieInfo.subPids.push_back(sub_pids);
		}
	}

	cMovieInfo.encodeMovieInfoXml(&extMessage,movieInfo);

	return extMessage;
}