예제 #1
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;
	}
}
예제 #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);

	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;
	}
}