Example #1
0
bool ODBCStatementImpl::hasNext()
{
	if (hasData())
	{
		if (!extractions().size()) 
			makeInternalExtractors();

		if (!_prepared) doPrepare();

		if (_stepCalled) 
			return _stepCalled = nextRowReady();

		makeStep();

		if (!nextRowReady())
		{
			if (hasMoreDataSets()) activateNextDataSet();
			else return false;	

			if (SQL_NO_DATA == SQLMoreResults(_stmt)) 
				return false;

			addPreparation();
			doPrepare();
			fixupExtraction();
			makeStep();
		}
		else if (Utility::isError(_nextResponse))
			checkError(_nextResponse, "SQLFetch()");

		return true;
	}

	return false;
}
Example #2
0
void eDVBServiceRecord::serviceEvent(int event)
{
	eDebug("RECORD service event %d", event);
	switch (event)
	{
	case eDVBServicePMTHandler::eventTuned:
	{
		eDebug("tuned..");
		m_tuned = 1;

			/* start feeding EIT updates */
		ePtr<iDVBDemux> m_demux;
		if (!m_service_handler.getDataDemux(m_demux))
		{
			eServiceReferenceDVB &ref = (eServiceReferenceDVB&) m_ref;
			int sid = ref.getParentServiceID().get();
			if (!sid)
				sid = ref.getServiceID().get();
			if ( ref.getParentTransportStreamID().get() &&
				ref.getParentTransportStreamID() != ref.getTransportStreamID() )
				m_event_handler.startOther(m_demux, sid);
			else
				m_event_handler.start(m_demux, sid);
		}

		if (m_state == stateRecording && m_want_record)
			doRecord();
		m_event((iRecordableService*)this, evTunedIn);
		break;
	}
	case eDVBServicePMTHandler::eventTuneFailed:
	{
		eDebug("record failed to tune");
		m_event((iRecordableService*)this, evTuneFailed);
		break;
	}
	case eDVBServicePMTHandler::eventNewProgramInfo:
	{
		if (m_state == stateIdle)
			doPrepare();
		else if (m_want_record) /* doRecord can be called from Prepared and Recording state */
			doRecord();
		m_event((iRecordableService*)this, evNewProgramInfo);
		break;
	}
	case eDVBServicePMTHandler::eventMisconfiguration:
		m_error = errMisconfiguration;
		m_event((iRecordableService*)this, evTuneFailed);
		break;
	case eDVBServicePMTHandler::eventNoResources:
		m_error = errNoResources;
		m_event((iRecordableService*)this, evTuneFailed);
		break;
	case eDVBServicePMTHandler::eventStopped:
		/* recording data source has stopped, stop recording */
		stop();
		m_event((iRecordableService*)this, evRecordAborted);
		break;
	}
}
Example #3
0
RESULT eDVBServiceRecord::prepareStreaming()
{
	m_filename = "";
	m_streaming = 1;
	if (m_state == stateIdle)
		return doPrepare();
	return -1;
}
Example #4
0
int eDVBServiceStream::start(const char *serviceref, int fd)
{
	if (m_state != stateIdle) return -1;
	m_ref = eServiceReferenceDVB(serviceref);
	if (doPrepare() < 0) return -1;
	m_target_fd = fd;
	m_want_record = 1;
	return doRecord();
}
Example #5
0
RESULT eDVBServiceRecord::prepareStreaming(bool descramble, bool includeecm)
{
	m_filename = "";
	m_streaming = 1;
	m_descramble = descramble;
	m_record_ecm = includeecm;
	if (m_state == stateIdle)
		return doPrepare();
	return -1;
}
Example #6
0
RESULT eServiceHDMIRecord::prepare(const char *filename, time_t begTime, time_t endTime, int eit_event_id, const char *name, const char *descr, const char *tags, bool descramble, bool recordecm)
{
	m_filename = filename;

	if (m_state == stateIdle)
	{
		return doPrepare();
	}
	return -1;
}
Example #7
0
void eDVBServiceStream::serviceEvent(int event)
{
	eDebug("STREAM service event %d", event);
	switch (event)
	{
	case eDVBServicePMTHandler::eventTuned:
	{
		eDebug("tuned..");
		m_tuned = 1;

			/* start feeding EIT updates */
		ePtr<iDVBDemux> m_demux;
		if (!m_service_handler.getDataDemux(m_demux))
		{
			eServiceReferenceDVB &ref = (eServiceReferenceDVB&) m_ref;
			int sid = ref.getParentServiceID().get();
			if (!sid)
				sid = ref.getServiceID().get();
			if ( ref.getParentTransportStreamID().get() &&
				ref.getParentTransportStreamID() != ref.getTransportStreamID() )
				m_event_handler.startOther(m_demux, sid);
			else
				m_event_handler.start(m_demux, sid);
		}

		if (m_state == stateRecording && m_want_record)
			doRecord();
		break;
	}
	case eDVBServicePMTHandler::eventTuneFailed:
	{
		eDebug("stream failed to tune");
		tuneFailed();
		break;
	}
	case eDVBServicePMTHandler::eventNewProgramInfo:
	{
		if (m_state == stateIdle)
			doPrepare();
		else if (m_want_record) /* doRecord can be called from Prepared and Recording state */
			doRecord();
		break;
	}
	case eDVBServicePMTHandler::eventMisconfiguration:
		tuneFailed();
		break;
	case eDVBServicePMTHandler::eventNoResources:
		tuneFailed();
		break;
	}
}
Example #8
0
void eDVBServiceStream::serviceEvent(int event)
{
	eDebug("[eDVBServiceStream] STREAM service event %d", event);
	if(event == eDVBServicePMTHandler::eventTuneFailed || event == eDVBServicePMTHandler::eventMisconfiguration || event == eDVBServicePMTHandler::eventNoResources)
		eventUpdate(event);

	switch (event)
	{
	case eDVBServicePMTHandler::eventTuned:
	{
		eDebug("[eDVBServiceStream] tuned.. m_state %d m_want_record %d", m_state, m_want_record);
		m_tuned = 1;

			/* start feeding EIT updates */
		ePtr<iDVBDemux> m_demux;
		if (!m_service_handler.getDataDemux(m_demux))
		{
			eServiceReferenceDVB &ref = (eServiceReferenceDVB&) m_ref;
			m_event_handler.start(m_demux, ref);
		}

		if (m_state > stateIdle && m_want_record)
			doRecord();
		break;
	}
	case eDVBServicePMTHandler::eventTuneFailed:
	{
		eDebug("stream failed to tune");
		tuneFailed();
		break;
	}
	case eDVBServicePMTHandler::eventNewProgramInfo:
	{
		if (m_state == stateIdle)
			doPrepare();
		else if (m_want_record) /* doRecord can be called from Prepared and Recording state */
			doRecord();
		break;
	}
	case eDVBServicePMTHandler::eventMisconfiguration:
		tuneFailed();
		break;
	case eDVBServicePMTHandler::eventNoResources:
		tuneFailed();
		break;
	}
	if(event != eDVBServicePMTHandler::eventTuneFailed && event != eDVBServicePMTHandler::eventMisconfiguration && event != eDVBServicePMTHandler::eventNoResources)
		eventUpdate(event);
}
Example #9
0
int eServiceHDMIRecord::doRecord()
{
	int err = doPrepare();
	if (err)
	{
		m_error = errTuneFailed;
		m_event((iRecordableService*)this, evRecordFailed);
		return err;
	}

	if (!m_thread && !m_simulate)
	{
		eDebug("[eServiceHDMIRecord] Recording to %s...", m_filename.c_str());
		::remove(m_filename.c_str());
		int fd = ::open(m_filename.c_str(), O_WRONLY | O_CREAT | O_LARGEFILE | O_CLOEXEC, 0666);
		if (fd < 0)
		{
			eDebug("[eServiceHDMIRecord] can't open recording file: %m");
			m_error = errOpenRecordFile;
			m_event((iRecordableService*)this, evRecordFailed);
			return errOpenRecordFile;
		}

		m_thread = new eDVBRecordFileThread(188, 20);
		m_thread->setTargetFD(fd);

		m_target_fd = fd;
	}

	eDebug("[eServiceHDMIRecord] start recording...");

	if (m_state != stateRecording)
	{
		if (m_thread && m_encoder_fd >= 0)
		{
			m_thread->startSaveMetaInformation(m_filename);
			m_thread->start(m_encoder_fd);
		}
		m_state = stateRecording;
	}

	m_error = 0;
	m_event((iRecordableService*)this, evRecordRunning);
	return 0;
}
Example #10
0
void ODBCStatementImpl::compileImpl()
{
	if (!_canCompile) return;

	_stepCalled = false;
	_nextResponse = 0;

	if (_preparations.size())
		PreparationVec().swap(_preparations);

	addPreparation();

	Binder::ParameterBinding bind = session().getFeature("autoBind") ? 
		Binder::PB_IMMEDIATE : Binder::PB_AT_EXEC;

	TypeInfo* pDT = 0;
	try
	{
		Poco::Any dti = session().getProperty("dataTypeInfo");
		pDT = AnyCast<TypeInfo*>(dti);
	}catch (NotSupportedException&) { }

	std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
	
	_pBinder = new Binder(_stmt, maxFieldSize, bind, pDT);
	
	// This is a hack to conform to some ODBC drivers behavior (e.g. MS SQLServer) with 
	// stored procedure calls: driver refuses to report the number of columns, unless all 
	// parameters for the stored procedure are bound. Since number of columns is essential 
	// information for the internal extraction creation, in order to allow for querying it,
	// these calls must occur before.
	fixupBinding(); doBind(false, true);

	makeInternalExtractors();
	doPrepare();

	 _canCompile = false;
}
Example #11
0
RESULT eServiceMP3Record::prepare(const char *filename, time_t begTime, time_t endTime, int eit_event_id, const char *name, const char *descr, const char *tags, bool descramble, bool recordecm, int packetsize)
{
	eDebug("[eMP3ServiceRecord] prepare filename %s", filename);
	m_filename = filename;

	if (m_state == stateIdle)
	{
		int ret = doPrepare();
		if (!ret)
		{
			eDVBMetaParser meta;
			std::string service_data;

			meta.m_time_create = begTime;
			meta.m_ref = eServiceReferenceDVB(m_ref.toString());
			meta.m_data_ok = 1;
			meta.m_service_data = service_data;
			if (name)
				meta.m_name = name;
			if (descr)
				meta.m_description = descr;
			if (tags)
				meta.m_tags = tags;
			meta.m_scrambled = recordecm; /* assume we will record scrambled data, when ecm will be included in the recording */
			ret = meta.updateMeta(m_filename.c_str()) ? -255 : 0;
			if (!ret)
			{
				std::string fname = m_filename;
				fname.erase(fname.length()-6, 6);
				fname += "eit";
				eEPGCache::getInstance()->saveEventToFile(fname.c_str(), m_ref, eit_event_id, begTime, endTime);
			}
			m_state = statePrepared;
		}
		return ret;
	}
	return -1;
}
Example #12
0
int eServiceMP3Record::doRecord()
{
	int err = doPrepare();
	if (err)
	{
		m_error = errMisconfiguration;
		m_event((iRecordableService*)this, evRecordFailed);
		return err;
	}

	if (gst_element_set_state(m_recording_pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE)
	{
		eDebug("[eMP3ServiceRecord] doRecord error cannot set pipeline to state_playing");
		m_error = errMisconfiguration;
		m_event((iRecordableService*)this, evRecordFailed);
		return -1;
	}

	m_state = stateRecording;
	m_error = 0;
	m_event((iRecordableService*)this, evRecordRunning);
	return 0;
}
Example #13
0
RESULT eDVBServiceRecord::prepare(const char *filename, time_t begTime, time_t endTime, int eit_event_id, const char *name, const char *descr, const char *tags)
{
	m_filename = filename;
	m_streaming = 0;
	
	if (m_state == stateIdle)
	{
		int ret = doPrepare();
		if (!ret)
		{
			eServiceReferenceDVB ref = m_ref.getParentServiceReference();
			ePtr<eDVBResourceManager> res_mgr;
			eDVBMetaParser meta;
			std::string service_data;
			if (!ref.valid())
				ref = m_ref;
			if (!eDVBResourceManager::getInstance(res_mgr))
			{
				ePtr<iDVBChannelList> db;
				if (!res_mgr->getChannelList(db))
				{
					ePtr<eDVBService> service;
					if (!db->getService(ref, service))
					{
						char tmp[255];
						sprintf(tmp, "f:%x", service->m_flags);
						service_data += tmp;
						// cached pids
						for (int x=0; x < eDVBService::cacheMax; ++x)
						{
							int entry = service->getCacheEntry((eDVBService::cacheID)x);
							if (entry != -1)
							{
								sprintf(tmp, ",c:%02d%04x", x, entry);
								service_data += tmp;
							}
						}
					}
				}
			}
			meta.m_time_create = begTime;
			meta.m_ref = m_ref;
			meta.m_data_ok = 1;
			meta.m_service_data = service_data;
			if (name)
				meta.m_name = name;
			if (descr)
				meta.m_description = descr;
			if (tags)
				meta.m_tags = tags;
			ret = meta.updateMeta(filename) ? -255 : 0;
			if (!ret)
			{
				const eit_event_struct *event = 0;
				eEPGCache::getInstance()->Lock();
				if ( eit_event_id != -1 )
				{
					eDebug("query epg event id %d", eit_event_id);
					eEPGCache::getInstance()->lookupEventId(ref, eit_event_id, event);
				}
				if ( !event && (begTime != -1 && endTime != -1) )
				{
					time_t queryTime = begTime + ((endTime-begTime)/2);
					tm beg, end, query;
					localtime_r(&begTime, &beg);
					localtime_r(&endTime, &end);
					localtime_r(&queryTime, &query);
					eDebug("query stime %d:%d:%d, etime %d:%d:%d, qtime %d:%d:%d",
						beg.tm_hour, beg.tm_min, beg.tm_sec,
						end.tm_hour, end.tm_min, end.tm_sec,
						query.tm_hour, query.tm_min, query.tm_sec);
					eEPGCache::getInstance()->lookupEventTime(ref, queryTime, event);
				}
				if ( event )
				{
					eDebug("found event.. store to disc");
					std::string fname = filename;
					fname.erase(fname.length()-2, 2);
					fname+="eit";
					int fd = open(fname.c_str(), O_CREAT|O_WRONLY, 0777);
					if (fd>-1)
					{
						int evLen=HILO(event->descriptors_loop_length)+12/*EIT_LOOP_SIZE*/;
						int wr = ::write( fd, (unsigned char*)event, evLen );
						if ( wr != evLen )
							eDebug("eit write error (%m)");
						::close(fd);
					}
				}
				eEPGCache::getInstance()->Unlock();
			}
		}
		return ret;
	}
	return -1;
}
Example #14
0
int eDVBServiceStream::doRecord()
{
	int err = doPrepare();
	if (err)
	{
		return err;
	}
	
	if (!m_tuned)
		return 0; /* try it again when we are tuned in */
	
	if (!m_record && m_tuned)
	{
		ePtr<iDVBDemux> demux;
		if (m_service_handler.getDataDemux(demux))
		{
			eDebug("eDVBServiceStream - NO DEMUX available");
			return -1;
		}
		demux->createTSRecorder(m_record, /*packetsize*/ 188, /*streaming*/ true);
		if (!m_record)
		{
			eDebug("eDVBServiceStream - no ts recorder available.");
			return -1;
		}
		m_record->setTargetFD(m_target_fd);
		m_record->connectEvent(slot(*this, &eDVBServiceStream::recordEvent), m_con_record_event);
	}

	eDebug("start streaming...");

	eDVBServicePMTHandler::program program;
	if (m_service_handler.getProgramInfo(program))
	{
		eDebug("getting program info failed.");
	}
	else
	{
		std::set<int> pids_to_record;

		pids_to_record.insert(0); // PAT

		if (program.pmtPid != -1)
			pids_to_record.insert(program.pmtPid); // PMT

		int timing_pid = -1, timing_stream_type = -1;
		iDVBTSRecorder::timing_pid_type timing_pid_type = iDVBTSRecorder::none;

		eDebugNoNewLine("STREAM: have %zd video stream(s)", program.videoStreams.size());
		if (!program.videoStreams.empty())
		{
			eDebugNoNewLine(" (");
			for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
				i(program.videoStreams.begin()); 
				i != program.videoStreams.end(); ++i)
			{
				pids_to_record.insert(i->pid);
				
				if (timing_pid == -1)
				{
					timing_pid = i->pid;
					timing_stream_type = i->type;
					timing_pid_type = iDVBTSRecorder::video_pid;
				}
				
				if (i != program.videoStreams.begin())
						eDebugNoNewLine(", ");
				eDebugNoNewLine("%04x", i->pid);
			}
			eDebugNoNewLine(")");
		}
		eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size());
		if (!program.audioStreams.empty())
		{
			eDebugNoNewLine(" (");
			for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
				i(program.audioStreams.begin()); 
				i != program.audioStreams.end(); ++i)
			{
				pids_to_record.insert(i->pid);

				if (timing_pid == -1)
				{
					timing_pid = i->pid;
					timing_stream_type = i->type;
					timing_pid_type = iDVBTSRecorder::audio_pid;
				}
			
				if (i != program.audioStreams.begin())
					eDebugNoNewLine(", ");
				eDebugNoNewLine("%04x", i->pid);
			}
			eDebugNoNewLine(")");
		}
		if (!program.subtitleStreams.empty())
		{
			eDebugNoNewLine(" (");
			for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
				i(program.subtitleStreams.begin());
				i != program.subtitleStreams.end(); ++i)
			{
				pids_to_record.insert(i->pid);

				if (i != program.subtitleStreams.begin())
					eDebugNoNewLine(", ");
				eDebugNoNewLine("%04x", i->pid);
			}
			eDebugNoNewLine(")");
		}
		eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
		if (program.pcrPid >= 0 && program.pcrPid < 0x1fff)
			pids_to_record.insert(program.pcrPid);
		eDebug(", and the text pid is %04x", program.textPid);
		if (program.textPid != -1)
			pids_to_record.insert(program.textPid); // Videotext

		if (m_stream_ecm)
		{
			for (std::list<eDVBServicePMTHandler::program::capid_pair>::const_iterator i(program.caids.begin()); 
						i != program.caids.end(); ++i)
			{
				if (i->capid >= 0) pids_to_record.insert(i->capid);
			}
		}

		if (m_stream_ait)
		{
			if (program.aitPid >= 0) pids_to_record.insert(program.aitPid);
		}

		if (m_stream_eit)
		{
			pids_to_record.insert(0x12);
		}

		/* include TDT pid, really low bandwidth, should not hurt anyone */
		pids_to_record.insert(0x14);

			/* find out which pids are NEW and which pids are obsolete.. */
		std::set<int> new_pids, obsolete_pids;

		std::set_difference(pids_to_record.begin(), pids_to_record.end(), 
				m_pids_active.begin(), m_pids_active.end(),
				std::inserter(new_pids, new_pids.begin()));

		std::set_difference(
				m_pids_active.begin(), m_pids_active.end(),
				pids_to_record.begin(), pids_to_record.end(), 
				std::inserter(obsolete_pids, obsolete_pids.begin())
				);
		
		for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
		{
			eDebug("ADD PID: %04x", *i);
			m_record->addPID(*i);
		}

		for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
		{
			eDebug("REMOVED PID: %04x", *i);
			m_record->removePID(*i);
		}

		if (timing_pid != -1)
			m_record->setTimingPID(timing_pid, timing_pid_type, timing_stream_type);

		m_pids_active = pids_to_record;

		if (m_state != stateRecording)
		{
			m_record->start();
			m_state = stateRecording;
		}
	}

	return 0;
}
int eDVBServiceStream::doRecord()
{
	int err = doPrepare();
	if (err)
	{
		eDebug("[eDVBServiceStream] doPrerare err %d", err);
		return err;
	}

	if (!m_tuned)
	{
		eDebug("[eDVBServiceStream] try it again when we are tuned in");
		return 0; /* try it again when we are tuned in */
	}

	if (!m_record && m_tuned)
	{
		ePtr<iDVBDemux> demux;
		if (m_service_handler.getDataDemux(demux))
		{
			eDebug("[eDVBServiceStream] NO DEMUX available");
			return -1;
		}
		demux->createTSRecorder(m_record, /*packetsize*/ 188, /*streaming*/ true);
		if (!m_record)
		{
			eDebug("[eDVBServiceStream] no ts recorder available.");
			return -1;
		}
		m_record->setTargetFD(m_target_fd);
		m_record->connectEvent(slot(*this, &eDVBServiceStream::recordEvent), m_con_record_event);
	}

	eDebug("[eDVBServiceStream] start streaming...");

	if (recordCachedPids())
	{
		eDebug("[eDVBServiceStream] streaming pids from cache.");
		return 0;
	}

	eDVBServicePMTHandler::program program;
	if (m_service_handler.getProgramInfo(program))
	{
		eDebug("[eDVBServiceStream] getting program info failed.");
	}
	else
	{
		std::set<int> pids_to_record;

		pids_to_record.insert(0); // PAT

		if (program.pmtPid != -1)
			pids_to_record.insert(program.pmtPid); // PMT

		int timing_pid = -1, timing_stream_type = -1;
		iDVBTSRecorder::timing_pid_type timing_pid_type = iDVBTSRecorder::none;

		eDebugNoNewLineStart("[eDVBServiceStream] have %zd video stream(s)", program.videoStreams.size());
		if (!program.videoStreams.empty())
		{
			eDebugNoNewLine(" (");
			for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
				i(program.videoStreams.begin());
				i != program.videoStreams.end(); ++i)
			{
				pids_to_record.insert(i->pid);

				if (timing_pid == -1)
				{
					timing_pid = i->pid;
					timing_stream_type = i->type;
					timing_pid_type = iDVBTSRecorder::video_pid;
				}

				if (i != program.videoStreams.begin())
						eDebugNoNewLine(", ");
				eDebugNoNewLine("%04x", i->pid);
			}
			eDebugNoNewLine(")");
		}
		eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size());
		if (!program.audioStreams.empty())
		{
			eDebugNoNewLine(" (");
			for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
				i(program.audioStreams.begin());
				i != program.audioStreams.end(); ++i)
			{
				pids_to_record.insert(i->pid);

				if (timing_pid == -1)
				{
					timing_pid = i->pid;
					timing_stream_type = i->type;
					timing_pid_type = iDVBTSRecorder::audio_pid;
				}

				if (i != program.audioStreams.begin())
					eDebugNoNewLine(", ");
				eDebugNoNewLine("%04x", i->pid);
			}
			eDebugNoNewLine(")");
		}
		if (!program.subtitleStreams.empty())
		{
			eDebugNoNewLine(" (");
			for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
				i(program.subtitleStreams.begin());
				i != program.subtitleStreams.end(); ++i)
			{
				pids_to_record.insert(i->pid);

				if (i != program.subtitleStreams.begin())
					eDebugNoNewLine(", ");
				eDebugNoNewLine("%04x", i->pid);
			}
			eDebugNoNewLine(")");
		}
		eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
		if (program.pcrPid >= 0 && program.pcrPid < 0x1fff)
			pids_to_record.insert(program.pcrPid);
		eDebugNoNewLine(", and the text pid is %04x\n", program.textPid);
		if (program.textPid != -1)
			pids_to_record.insert(program.textPid); // Videotext

		if (m_stream_ecm)
		{
			for (std::list<eDVBServicePMTHandler::program::capid_pair>::const_iterator i(program.caids.begin());
						i != program.caids.end(); ++i)
			{
				if (i->capid >= 0) pids_to_record.insert(i->capid);
			}
		}

		if (m_stream_ait)
		{
			if (program.aitPid >= 0) pids_to_record.insert(program.aitPid);
		}

		if (m_stream_eit)
		{
			pids_to_record.insert(0x12);
		}

		/* include TDT pid, really low bandwidth, should not hurt anyone */
		pids_to_record.insert(0x14);

		recordPids(pids_to_record, timing_pid, timing_stream_type, timing_pid_type);
	}

	return 0;
}
Example #16
0
RESULT eDVBServiceRecord::prepare(const char *filename, time_t begTime, time_t endTime, int eit_event_id, const char *name, const char *descr, const char *tags, bool descramble, bool recordecm, int packetsize)
{
	bool config_recording_always_ecm = eConfigManager::getConfigBoolValue("config.recording.always_ecm", false);
	bool config_recording_never_decrypt = eConfigManager::getConfigBoolValue("config.recording.never_decrypt", false);

	m_filename = filename;
	m_streaming = 0;
	m_descramble = config_recording_never_decrypt ? false : descramble;
	m_record_ecm = config_recording_always_ecm ? true : recordecm;
	m_packet_size = packetsize;

	if (m_state == stateIdle)
	{
		int ret = doPrepare();
		if (!ret)
		{
			eServiceReferenceDVB ref = m_ref.getParentServiceReference();
			ePtr<eDVBService> service;
			eDVBMetaParser meta;
			std::string service_data;

			if (!ref.valid())
				ref = m_ref;

			if (!eDVBDB::getInstance()->getService(ref, service))
			{
				char tmp[255];
				sprintf(tmp, "f:%x", service->m_flags);
				service_data += tmp;
				// cached pids
				for (int x=0; x < eDVBService::cacheMax; ++x)
				{
					int entry = service->getCacheEntry((eDVBService::cacheID)x);
					if (entry != -1)
					{
						sprintf(tmp, ",c:%02d%04x", x, entry);
						service_data += tmp;
					}
				}
			}

			meta.m_time_create = begTime;
			meta.m_ref = m_ref;
			meta.m_data_ok = 1;
			meta.m_service_data = service_data;
			if (name)
				meta.m_name = name;
			if (descr)
				meta.m_description = descr;
			if (tags)
				meta.m_tags = tags;
			meta.m_scrambled = !m_descramble;
			meta.m_packet_size = m_packet_size;
			ret = meta.updateMeta(filename) ? -255 : 0;
			if (!ret)
			{
				std::string fname = filename;
				fname.erase(fname.length()-2, 2);
				fname += "eit";
				eEPGCache::getInstance()->saveEventToFile(fname.c_str(), ref, eit_event_id, begTime, endTime);
			}
		}
		return ret;
	}
	return -1;
}
Example #17
0
int eDVBServiceRecord::doRecord()
{
	int err = doPrepare();
	if (err)
	{
		m_error = errTuneFailed;
		m_event((iRecordableService*)this, evRecordFailed);
		return err;
	}
	
	if (!m_tuned)
		return 0; /* try it again when we are tuned in */
	
	if (!m_record && m_tuned && !m_streaming && !m_simulate)
	{
		eDebug("Recording to %s...", m_filename.c_str());
		::remove(m_filename.c_str());
		int fd = ::open(m_filename.c_str(), O_WRONLY|O_CREAT|O_LARGEFILE, 0666);
		if (fd == -1)
		{
			eDebug("eDVBServiceRecord - can't open recording file!");
			m_error = errOpenRecordFile;
			m_event((iRecordableService*)this, evRecordFailed);
			return errOpenRecordFile;
		}

		ePtr<iDVBDemux> demux;
		if (m_service_handler.getDataDemux(demux))
		{
			eDebug("eDVBServiceRecord - NO DEMUX available!");
			m_error = errNoDemuxAvailable;
			m_event((iRecordableService*)this, evRecordFailed);
			return errNoDemuxAvailable;
		}
		demux->createTSRecorder(m_record);
		if (!m_record)
		{
			eDebug("eDVBServiceRecord - no ts recorder available.");
			m_error = errNoTsRecorderAvailable;
			m_event((iRecordableService*)this, evRecordFailed);
			return errNoTsRecorderAvailable;
		}
		m_record->setTargetFD(fd);
		m_record->setTargetFilename(m_filename);
		m_record->connectEvent(slot(*this, &eDVBServiceRecord::recordEvent), m_con_record_event);

		m_target_fd = fd;
	}
	
	if (m_streaming)
	{
		m_state = stateRecording;
		eDebug("start streaming...");
	} else
	{
		eDebug("start recording...");

		eDVBServicePMTHandler::program program;
		if (m_service_handler.getProgramInfo(program))
			eDebug("getting program info failed.");
		else
		{
			std::set<int> pids_to_record;

			pids_to_record.insert(0); // PAT

			if (program.pmtPid != -1)
				pids_to_record.insert(program.pmtPid); // PMT

			int timing_pid = -1, timing_stream_type = -1;
			iDVBTSRecorder::timing_pid_type timing_pid_type = iDVBTSRecorder::none;

			eDebugNoNewLine("RECORD: have %zd video stream(s)", program.videoStreams.size());
			if (!program.videoStreams.empty())
			{
				eDebugNoNewLine(" (");
				for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
					i(program.videoStreams.begin()); 
					i != program.videoStreams.end(); ++i)
				{
					pids_to_record.insert(i->pid);
					
					if (timing_pid == -1)
					{
						timing_pid = i->pid;
						timing_stream_type = i->type;
						timing_pid_type = iDVBTSRecorder::video_pid;
					}
					
					if (i != program.videoStreams.begin())
							eDebugNoNewLine(", ");
					eDebugNoNewLine("%04x", i->pid);
				}
				eDebugNoNewLine(")");
			}
			eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size());
			if (!program.audioStreams.empty())
			{
				eDebugNoNewLine(" (");
				for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
					i(program.audioStreams.begin()); 
					i != program.audioStreams.end(); ++i)
				{
					pids_to_record.insert(i->pid);
	
					if (timing_pid == -1)
					{
						timing_pid = i->pid;
						timing_stream_type = i->type;
						timing_pid_type = iDVBTSRecorder::audio_pid;
					}
				
					if (i != program.audioStreams.begin())
						eDebugNoNewLine(", ");
					eDebugNoNewLine("%04x", i->pid);
				}
				eDebugNoNewLine(")");
			}
			if (!program.subtitleStreams.empty())
			{
				eDebugNoNewLine(" (");
				for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
					i(program.subtitleStreams.begin());
					i != program.subtitleStreams.end(); ++i)
				{
					pids_to_record.insert(i->pid);
	
					if (i != program.subtitleStreams.begin())
						eDebugNoNewLine(", ");
					eDebugNoNewLine("%04x", i->pid);
				}
				eDebugNoNewLine(")");
			}
			eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
			if (program.pcrPid >= 0 && program.pcrPid < 0x1fff)
				pids_to_record.insert(program.pcrPid);
			eDebug(", and the text pid is %04x", program.textPid);
			if (program.textPid != -1)
				pids_to_record.insert(program.textPid); // Videotext

			if (m_record_ecm)
			{
				for (std::list<eDVBServicePMTHandler::program::capid_pair>::const_iterator i(program.caids.begin()); 
							i != program.caids.end(); ++i)
				{
					if (i->capid >= 0) pids_to_record.insert(i->capid);
				}
			}

				/* find out which pids are NEW and which pids are obsolete.. */
			std::set<int> new_pids, obsolete_pids;

			std::set_difference(pids_to_record.begin(), pids_to_record.end(), 
					m_pids_active.begin(), m_pids_active.end(),
					std::inserter(new_pids, new_pids.begin()));

			std::set_difference(
					m_pids_active.begin(), m_pids_active.end(),
					pids_to_record.begin(), pids_to_record.end(), 
					std::inserter(obsolete_pids, obsolete_pids.begin())
					);
			
			for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
			{
				eDebug("ADD PID: %04x", *i);
				m_record->addPID(*i);
			}

			for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
			{
				eDebug("REMOVED PID: %04x", *i);
				m_record->removePID(*i);
			}

			if (timing_pid != -1)
				m_record->setTimingPID(timing_pid, timing_pid_type, timing_stream_type);

			m_pids_active = pids_to_record;

			if (m_state != stateRecording)
			{
				m_record->start();
				m_state = stateRecording;
			}
		}
	}
	m_error = 0;
	m_event((iRecordableService*)this, evRecordRunning);
	return 0;
}
Example #18
0
RESULT eDVBServiceRecord::prepare(const char *filename, time_t begTime, time_t endTime, int eit_event_id, const char *name, const char *descr, const char *tags, bool descramble, bool recordecm)
{
	m_filename = filename;
	m_streaming = 0;
	m_descramble = descramble;
	m_record_ecm = recordecm;

	if (m_state == stateIdle)
	{
		int ret = doPrepare();
		if (!ret)
		{
			eServiceReferenceDVB ref = m_ref.getParentServiceReference();
			ePtr<eDVBResourceManager> res_mgr;
			eDVBMetaParser meta;
			std::string service_data;
			if (!ref.valid())
				ref = m_ref;
			if (!eDVBResourceManager::getInstance(res_mgr))
			{
				ePtr<iDVBChannelList> db;
				if (!res_mgr->getChannelList(db))
				{
					ePtr<eDVBService> service;
					if (!db->getService(ref, service))
					{
						char tmp[255];
						sprintf(tmp, "f:%x", service->m_flags);
						service_data += tmp;
						// cached pids
						for (int x=0; x < eDVBService::cacheMax; ++x)
						{
							int entry = service->getCacheEntry((eDVBService::cacheID)x);
							if (entry != -1)
							{
								sprintf(tmp, ",c:%02d%04x", x, entry);
								service_data += tmp;
							}
						}
					}
				}
			}
			meta.m_time_create = begTime;
			meta.m_ref = m_ref;
			meta.m_data_ok = 1;
			meta.m_service_data = service_data;
			if (name)
				meta.m_name = name;
			if (descr)
				meta.m_description = descr;
			if (tags)
				meta.m_tags = tags;
			meta.m_scrambled = m_record_ecm; /* assume we will record scrambled data, when ecm will be included in the recording */
			ret = meta.updateMeta(filename) ? -255 : 0;
			if (!ret)
			{
				std::string fname = filename;
				fname.erase(fname.length()-2, 2);
				fname += "eit";
				eEPGCache::getInstance()->saveEventToFile(fname.c_str(), ref, eit_event_id, begTime, endTime);
			}
		}
		return ret;
	}
	return -1;
}
Example #19
0
int eDVBServiceStream::doRecord()
{
	int err = doPrepare();
	if (err)
	{
		eDebug("[eDVBServiceStream] doPrerare err %d", err);
		return err;
	}

	if (!m_tuned)
	{
		eDebug("[eDVBServiceStream] try it again when we are tuned in");
		return 0; /* try it again when we are tuned in */
	}

	if (!m_record && m_tuned)
	{
		ePtr<iDVBDemux> demux;
		if (m_service_handler.getDataDemux(demux))
		{
			eDebug("eDVBServiceStream - NO DEMUX available");
			return -1;
		}
		demux->createTSRecorder(m_record, /*packetsize*/ 188, /*streaming*/ true);
		if (!m_record)
		{
			eDebug("eDVBServiceStream - no ts recorder available.");
			return -1;
		}
		m_record->setTargetFD(m_target_fd);
		m_record->connectEvent(sigc::mem_fun(*this, &eDVBServiceStream::recordEvent), m_con_record_event);
	}

	eDebug("start streaming...");

	if (recordCachedPids())
	{
		eDebug("[eDVBServiceStream] streaming pids from cache.");
		return 0;
	}

	eDVBServicePMTHandler::program program;
	if (m_service_handler.getProgramInfo(program))
	{
		eDebug("getting program info failed.");
	}
	else
	{
		std::set<int> pids_to_record;

		eServiceReferenceDVB ref = m_ref.getParentServiceReference();
		ePtr<eDVBService> service;

		if (!ref.valid())
			ref = m_ref;

		if(!eDVBDB::getInstance()->getService(ref, service))
		{
			// cached pids
			for (int x = 0; x < eDVBService::cacheMax; ++x)
			{
				if (x == 5)
				{
					x += 3; // ignore cVTYPE, cACHANNEL, cAC3DELAY, cPCMDELAY
					continue;
				}
				int entry = service->getCacheEntry((eDVBService::cacheID)x);
				if (entry != -1)
				{
					if (eDVBService::cSUBTITLE == (eDVBService::cacheID)x)
					{
						entry = (entry&0xFFFF0000)>>16;
					}
					pids_to_record.insert(entry);
				}
			}
		}

		pids_to_record.insert(0); // PAT

		if (program.pmtPid != -1)
			pids_to_record.insert(program.pmtPid); // PMT

		int timing_pid = -1, timing_stream_type = -1;
		iDVBTSRecorder::timing_pid_type timing_pid_type = iDVBTSRecorder::none;

		eDebugNoNewLineStart("STREAM: have %zd video stream(s)", program.videoStreams.size());
		if (!program.videoStreams.empty())
		{
			eDebugNoNewLine(" (");
			for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
				i(program.videoStreams.begin());
				i != program.videoStreams.end(); ++i)
			{
				pids_to_record.insert(i->pid);

				if (timing_pid == -1)
				{
					timing_pid = i->pid;
					timing_stream_type = i->type;
					timing_pid_type = iDVBTSRecorder::video_pid;
				}

				if (i != program.videoStreams.begin())
						eDebugNoNewLine(", ");
				eDebugNoNewLine("%04x", i->pid);
			}
			eDebugNoNewLine(")");
		}
		eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size());
		if (!program.audioStreams.empty())
		{
			eDebugNoNewLine(" (");
			for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
				i(program.audioStreams.begin());
				i != program.audioStreams.end(); ++i)
			{
				pids_to_record.insert(i->pid);

				if (timing_pid == -1)
				{
					timing_pid = i->pid;
					timing_stream_type = i->type;
					timing_pid_type = iDVBTSRecorder::audio_pid;
				}

				if (i != program.audioStreams.begin())
					eDebugNoNewLine(", ");
				eDebugNoNewLine("%04x", i->pid);
			}
			eDebugNoNewLine(")");
		}
		if (!program.subtitleStreams.empty())
		{
			eDebugNoNewLine(" (");
			for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
				i(program.subtitleStreams.begin());
				i != program.subtitleStreams.end(); ++i)
			{
				pids_to_record.insert(i->pid);

				if (i != program.subtitleStreams.begin())
					eDebugNoNewLine(", ");
				eDebugNoNewLine("%04x", i->pid);
			}
			eDebugNoNewLine(")");
		}
		eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
		if (program.pcrPid >= 0 && program.pcrPid < 0x1fff)
			pids_to_record.insert(program.pcrPid);
		eDebugNoNewLineEnd(", and the text pid is %04x", program.textPid);
		if (program.textPid != -1)
			pids_to_record.insert(program.textPid); // Videotext

		if (m_stream_ecm)
		{
			for (std::list<eDVBServicePMTHandler::program::capid_pair>::const_iterator i(program.caids.begin());
						i != program.caids.end(); ++i)
			{
				if (i->capid >= 0) pids_to_record.insert(i->capid);
			}
		}

		if (m_stream_ait)
		{
			if (program.aitPid >= 0) pids_to_record.insert(program.aitPid);
		}

		if (m_stream_eit)
		{
			pids_to_record.insert(0x12);
		}

		/* include TDT pid, really low bandwidth, should not hurt anyone */
		pids_to_record.insert(0x14);

		recordPids(pids_to_record, timing_pid, timing_stream_type, timing_pid_type);
	}
Example #20
0
int eDVBServiceStream::doRecord()
{
	int err = doPrepare();
	if (err)
	{
		eDebug("[eDVBServiceStream] doPrerare err %d", err);
		return err;
	}

	if (!m_tuned)
	{
		eDebug("[eDVBServiceStream] try it again when we are tuned in");
		return 0; /* try it again when we are tuned in */
	}

	if (!m_record && m_tuned)
	{
		ePtr<iDVBDemux> demux;
		if (m_service_handler.getDataDemux(demux))
		{
			eDebug("eDVBServiceStream - NO DEMUX available");
			return -1;
		}
		demux->createTSRecorder(m_record, /*packetsize*/ 188, /*streaming*/ true);
		if (!m_record)
		{
			eDebug("eDVBServiceStream - no ts recorder available.");
			return -1;
		}
		m_record->setTargetFD(m_target_fd);
		m_record->connectEvent(sigc::mem_fun(*this, &eDVBServiceStream::recordEvent), m_con_record_event);
	}

	eDebug("start streaming...");

	if (recordCachedPids())
	{
		eDebug("[eDVBServiceStream] streaming pids from cache.");
		return 0;
	}

	eDVBServicePMTHandler::program program;
	if (m_service_handler.getProgramInfo(program))
	{
		eDebug("getting program info failed.");
	}
	else if(m_record_no_pids == 0)
	{
		std::set<int> pids_to_record;

		eServiceReferenceDVB ref = m_ref.getParentServiceReference();
		ePtr<eDVBService> service;

		if (!ref.valid())
			ref = m_ref;

		if(!eDVBDB::getInstance()->getService(ref, service))
		{
			// cached pids
			for (int x = 0; x < eDVBService::cacheMax; ++x)
			{
				if (x == 5)
				{
					x += 3; // ignore cVTYPE, cACHANNEL, cAC3DELAY, cPCMDELAY
					continue;
				}
				int entry = service->getCacheEntry((eDVBService::cacheID)x);
				if (entry != -1)
				{
					if (eDVBService::cSUBTITLE == (eDVBService::cacheID)x)
					{
						entry = (entry&0xFFFF0000)>>16;
					}
					pids_to_record.insert(entry);
				}
			}
		}
Example #21
0
 void EntityModel::prepare(const int minFilter, const int magFilter) {
     if (!m_prepared) {
         doPrepare(minFilter, magFilter);
         m_prepared = true;
     }
 }
Example #22
0
int eDVBServiceRecord::doRecord()
{
	int err = doPrepare();
	if (err)
	{
		m_error = errTuneFailed;
		m_event((iRecordableService*)this, evRecordFailed);
		return err;
	}
	
	if (!m_tuned)
		return 0; /* try it again when we are tuned in */
	
	if (!m_record && m_tuned && !m_streaming && !m_simulate)
	{
#if defined(__sh__) 
		int flags = O_WRONLY|O_CREAT|O_LARGEFILE;
		struct statfs sbuf;
#endif
		eDebug("Recording to %s...", m_filename.c_str());
		::remove(m_filename.c_str());
#if defined(__sh__)
		//nit2005, we must creat a file for statfs
 		int fd = ::open(m_filename.c_str(), O_WRONLY|O_CREAT|O_LARGEFILE, 0644);
		::close(fd);
		if (statfs(m_filename.c_str(), &sbuf) < 0) 
		{ 
			eDebug("eDVBServiceRecord - can't get fs type assuming none NFS!"); 
		} else 
		{ 
			if (sbuf.f_type == EXT3_SUPER_MAGIC) 
				eDebug("eDVBServiceRecord - Ext2/3/4 Filesystem\n"); 
			else 
			if (sbuf.f_type == NFS_SUPER_MAGIC) 
			{ 
				eDebug("eDVBServiceRecord - NFS Filesystem; add O_DIRECT to flags\n"); 
				flags |= O_DIRECT; 
			} 
			else 
			if (sbuf.f_type == USBDEVICE_SUPER_MAGIC) 
				eDebug("eDVBServiceRecord - USB Device\n"); 
			else 
			if (sbuf.f_type == SMB_SUPER_MAGIC) 
				eDebug("eDVBServiceRecord - SMBs Device\n"); 
			else 
			if (sbuf.f_type == MSDOS_SUPER_MAGIC) 
				eDebug("eDVBServiceRecord - MSDOS Device\n"); 
		} 

		fd = ::open(m_filename.c_str(), flags, 0644); 
#else
		int fd = ::open(m_filename.c_str(), O_WRONLY|O_CREAT|O_LARGEFILE, 0644);
#endif
		if (fd == -1)
		{
			eDebug("eDVBServiceRecord - can't open recording file!");
			m_error = errOpenRecordFile;
			m_event((iRecordableService*)this, evRecordFailed);
			return errOpenRecordFile;
		}

			/* turn off kernel caching strategies */
		posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);

		ePtr<iDVBDemux> demux;
		if (m_service_handler.getDataDemux(demux))
		{
			eDebug("eDVBServiceRecord - NO DEMUX available!");
			m_error = errNoDemuxAvailable;
			m_event((iRecordableService*)this, evRecordFailed);
			return errNoDemuxAvailable;
		}
		demux->createTSRecorder(m_record);
		if (!m_record)
		{
			eDebug("eDVBServiceRecord - no ts recorder available.");
			m_error = errNoTsRecorderAvailable;
			m_event((iRecordableService*)this, evRecordFailed);
			return errNoTsRecorderAvailable;
		}
		m_record->setTargetFD(fd);
		m_record->setTargetFilename(m_filename.c_str());
		m_record->connectEvent(slot(*this, &eDVBServiceRecord::recordEvent), m_con_record_event);

		m_target_fd = fd;
	}
	
	if (m_streaming)
	{
		m_state = stateRecording;
		eDebug("start streaming...");
	} else
	{
		eDebug("start recording...");

		eDVBServicePMTHandler::program program;
		if (m_service_handler.getProgramInfo(program))
			eDebug("getting program info failed.");
		else
		{
			std::set<int> pids_to_record;

			pids_to_record.insert(0); // PAT

			if (program.pmtPid != -1)
				pids_to_record.insert(program.pmtPid); // PMT

			int timing_pid = -1, timing_pid_type = -1;

			eDebugNoNewLine("RECORD: have %d video stream(s)", program.videoStreams.size());
			if (!program.videoStreams.empty())
			{
				eDebugNoNewLine(" (");
				for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
					i(program.videoStreams.begin()); 
					i != program.videoStreams.end(); ++i)
				{
					pids_to_record.insert(i->pid);
					
					if (timing_pid == -1)
					{
						timing_pid = i->pid;
						timing_pid_type = i->type;
					}
					
					if (i != program.videoStreams.begin())
							eDebugNoNewLine(", ");
					eDebugNoNewLine("%04x", i->pid);
				}
				eDebugNoNewLine(")");
			}
			eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size());
			if (!program.audioStreams.empty())
			{
				eDebugNoNewLine(" (");
				for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
					i(program.audioStreams.begin()); 
					i != program.audioStreams.end(); ++i)
				{
					pids_to_record.insert(i->pid);
	
					if (timing_pid == -1)
					{
						timing_pid = i->pid;
						timing_pid_type = -1;
					}
				
					if (i != program.audioStreams.begin())
						eDebugNoNewLine(", ");
					eDebugNoNewLine("%04x", i->pid);
				}
				eDebugNoNewLine(")");
			}
			if (!program.subtitleStreams.empty())
			{
				eDebugNoNewLine(" (");
				for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
					i(program.subtitleStreams.begin());
					i != program.subtitleStreams.end(); ++i)
				{
					pids_to_record.insert(i->pid);
	
					if (i != program.subtitleStreams.begin())
						eDebugNoNewLine(", ");
					eDebugNoNewLine("%04x", i->pid);
				}
				eDebugNoNewLine(")");
			}
			eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
			if (program.pcrPid != 0x1fff)
				pids_to_record.insert(program.pcrPid);
			eDebug(", and the text pid is %04x", program.textPid);
			if (program.textPid != -1)
				pids_to_record.insert(program.textPid); // Videotext

				/* find out which pids are NEW and which pids are obsolete.. */
			std::set<int> new_pids, obsolete_pids;

			std::set_difference(pids_to_record.begin(), pids_to_record.end(), 
					m_pids_active.begin(), m_pids_active.end(),
					std::inserter(new_pids, new_pids.begin()));

			std::set_difference(
					m_pids_active.begin(), m_pids_active.end(),
					pids_to_record.begin(), pids_to_record.end(), 
					std::inserter(obsolete_pids, obsolete_pids.begin())
					);
			
			for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
			{
				eDebug("ADD PID: %04x", *i);
				m_record->addPID(*i);
			}

			for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
			{
				eDebug("REMOVED PID: %04x", *i);
				m_record->removePID(*i);
			}

			if (timing_pid != -1)
				m_record->setTimingPID(timing_pid, timing_pid_type);

			m_pids_active = pids_to_record;

			if (m_state != stateRecording)
			{
				m_record->start();
				m_state = stateRecording;
			}
		}
	}
	m_error = 0;
	m_event((iRecordableService*)this, evRecordRunning);
	return 0;
}
Example #23
0
int eDVBServiceRecord::doRecord()
{
    int err = doPrepare();
    if (err)
    {
        m_error = errTuneFailed;
        m_event((iRecordableService*)this, evRecordFailed);
        return err;
    }

    if (!m_tuned)
        return 0; /* try it again when we are tuned in */

    if (!m_record && m_tuned && !m_streaming && !m_simulate)
    {
        eDebug("Recording to %s...", m_filename.c_str());
        ::remove(m_filename.c_str());
        int fd = ::open(m_filename.c_str(), O_WRONLY | O_CREAT | O_LARGEFILE | O_CLOEXEC, 0666);
        if (fd == -1)
        {
            eDebug("eDVBServiceRecord - can't open recording file!");
            m_error = errOpenRecordFile;
            m_event((iRecordableService*)this, evRecordFailed);
            return errOpenRecordFile;
        }

        ePtr<iDVBDemux> demux;
        if (m_service_handler.getDataDemux(demux))
        {
            eDebug("eDVBServiceRecord - NO DEMUX available!");
            m_error = errNoDemuxAvailable;
            m_event((iRecordableService*)this, evRecordFailed);
            return errNoDemuxAvailable;
        }
        demux->createTSRecorder(m_record);
        if (!m_record)
        {
            eDebug("eDVBServiceRecord - no ts recorder available.");
            m_error = errNoTsRecorderAvailable;
            m_event((iRecordableService*)this, evRecordFailed);
            return errNoTsRecorderAvailable;
        }
        m_record->setTargetFD(fd);
        m_record->setTargetFilename(m_filename);
        m_record->connectEvent(slot(*this, &eDVBServiceRecord::recordEvent), m_con_record_event);

        m_target_fd = fd;
    }

    if (m_streaming)
    {
        m_state = stateRecording;
        eDebug("start streaming...");
    } else
    {
        eDebugNoNewLineStart("start recording...");

        eDVBServicePMTHandler::program program;
        if (m_service_handler.getProgramInfo(program))
            eDebug("getting program info failed.");
        else
        {
            std::set<int> pids_to_record;

            eServiceReferenceDVB ref = m_ref.getParentServiceReference();
            ePtr<eDVBService> service;

            if (!ref.valid())
                ref = m_ref;

            if(!eDVBDB::getInstance()->getService(ref, service))
            {
                // cached pids
                for (int x = 0; x < eDVBService::cacheMax; ++x)
                {
                    if (x == 5)
                    {
                        x += 3; // ignore cVTYPE, cACHANNEL, cAC3DELAY, cPCMDELAY
                        continue;
                    }
                    int entry = service->getCacheEntry((eDVBService::cacheID)x);
                    if (entry != -1)
                    {
                        if (eDVBService::cSUBTITLE == (eDVBService::cacheID)x)
                        {
                            entry = (entry&0xFFFF0000)>>16;
                        }
                        pids_to_record.insert(entry);
                    }
                }
            }

            pids_to_record.insert(0); // PAT

            if (program.pmtPid != -1)
                pids_to_record.insert(program.pmtPid); // PMT

            int timing_pid = -1, timing_stream_type = -1;
            iDVBTSRecorder::timing_pid_type timing_pid_type = iDVBTSRecorder::none;

            eDebugNoNewLine("RECORD: have %zd video stream(s)", program.videoStreams.size());
            if (!program.videoStreams.empty())
            {
                eDebugNoNewLine(" (");
                for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
                        i(program.videoStreams.begin());
                        i != program.videoStreams.end(); ++i)
                {
                    pids_to_record.insert(i->pid);

                    if (timing_pid == -1)
                    {
                        timing_pid = i->pid;
                        timing_stream_type = i->type;
                        timing_pid_type = iDVBTSRecorder::video_pid;
                    }

                    if (i != program.videoStreams.begin())
                        eDebugNoNewLine(", ");
                    eDebugNoNewLine("%04x", i->pid);
                }
                eDebugNoNewLine(")");
            }
            eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size());
            if (!program.audioStreams.empty())
            {
                eDebugNoNewLine(" (");
                for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
                        i(program.audioStreams.begin());
                        i != program.audioStreams.end(); ++i)
                {
                    pids_to_record.insert(i->pid);

                    if (timing_pid == -1)
                    {
                        timing_pid = i->pid;
                        timing_stream_type = i->type;
                        timing_pid_type = iDVBTSRecorder::audio_pid;
                    }

                    if (i != program.audioStreams.begin())
                        eDebugNoNewLine(", ");
                    eDebugNoNewLine("%04x", i->pid);
                }
                eDebugNoNewLine(")");
            }
            if (!program.subtitleStreams.empty())
            {
                eDebugNoNewLine(" (");
                for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
                        i(program.subtitleStreams.begin());
                        i != program.subtitleStreams.end(); ++i)
                {
                    pids_to_record.insert(i->pid);

                    if (i != program.subtitleStreams.begin())
                        eDebugNoNewLine(", ");
                    eDebugNoNewLine("%04x", i->pid);
                }
                eDebugNoNewLine(")");
            }
            eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
            if (program.pcrPid >= 0 && program.pcrPid < 0x1fff)
                pids_to_record.insert(program.pcrPid);
            eDebugNoNewLineEnd(", and the text pid is %04x", program.textPid);
            if (program.textPid != -1)
                pids_to_record.insert(program.textPid); // Videotext

            if (m_record_ecm)
            {
                for (std::list<eDVBServicePMTHandler::program::capid_pair>::const_iterator i(program.caids.begin());
                        i != program.caids.end(); ++i)
                {
                    if (i->capid >= 0) pids_to_record.insert(i->capid);
                }
            }

            bool include_ait = eConfigManager::getConfigBoolValue("config.recording.include_ait");
            if (include_ait)
            {
                /* add AIT pid (if any) */
                if (program.aitPid >= 0) pids_to_record.insert(program.aitPid);
            }

            /* find out which pids are NEW and which pids are obsolete.. */
            std::set<int> new_pids, obsolete_pids;

            std::set_difference(pids_to_record.begin(), pids_to_record.end(),
                                m_pids_active.begin(), m_pids_active.end(),
                                std::inserter(new_pids, new_pids.begin()));

            std::set_difference(
                m_pids_active.begin(), m_pids_active.end(),
                pids_to_record.begin(), pids_to_record.end(),
                std::inserter(obsolete_pids, obsolete_pids.begin())
            );

            for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
            {
                eDebug("ADD PID: %04x", *i);
                m_record->addPID(*i);
            }

            for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
            {
                eDebug("REMOVED PID: %04x", *i);
                m_record->removePID(*i);
            }

            if (timing_pid != -1)
                m_record->setTimingPID(timing_pid, timing_pid_type, timing_stream_type);

            m_pids_active = pids_to_record;

            if (m_state != stateRecording)
            {
                m_record->start();
                m_state = stateRecording;
            }
        }
    }