aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Domke <tmbinc@elitedvb.net>2005-05-04 15:57:32 +0000
committerFelix Domke <tmbinc@elitedvb.net>2005-05-04 15:57:32 +0000
commit1d7e5720b3e8653604323b981e37af1f6aa61709 (patch)
tree0f021854a6676f6e98e3c99fddbe26a1237020cf
parent07fe46ca847778b88745244d6c8113ee6ba3de14 (diff)
downloadenigma2-1d7e5720b3e8653604323b981e37af1f6aa61709.tar.gz
enigma2-1d7e5720b3e8653604323b981e37af1f6aa61709.zip
- improve record support
-rw-r--r--lib/nav/core.cpp23
-rw-r--r--lib/nav/core.h5
-rw-r--r--lib/nav/pcore.cpp9
-rw-r--r--lib/nav/pcore.h3
-rw-r--r--lib/service/iservice.h1
-rw-r--r--lib/service/servicedvb.cpp2
-rw-r--r--lib/service/servicedvbrecord.cpp253
-rw-r--r--lib/service/servicedvbrecord.h6
8 files changed, 160 insertions, 142 deletions
diff --git a/lib/nav/core.cpp b/lib/nav/core.cpp
index 2dfe630d..45771f15 100644
--- a/lib/nav/core.cpp
+++ b/lib/nav/core.cpp
@@ -115,31 +115,16 @@ RESULT eNavigation::stopService(void)
return 0;
}
-RESULT eNavigation::recordService(const eServiceReference &service)
+RESULT eNavigation::recordService(const eServiceReference &ref, ePtr<iRecordableService> &service)
{
- if (m_recordingService)
- endRecording();
-
assert(m_servicehandler);
- RESULT res = m_servicehandler->record(service, m_recordingService);
- if (m_recordingService)
- {
- res = m_recordingService->start();
- }
+ RESULT res = m_servicehandler->record(ref, service);
+ eDebug("record: %d", res);
if (res)
- m_recordingService = 0;
+ service = 0;
return res;
}
-RESULT eNavigation::endRecording()
-{
- if (!m_recordingService)
- return -1;
- m_recordingService->stop();
- m_recordingService = 0;
- return 0;
-}
-
RESULT eNavigation::pause(int dop)
{
if (!m_runningService)
diff --git a/lib/nav/core.h b/lib/nav/core.h
index c4306e39..8b9502d3 100644
--- a/lib/nav/core.h
+++ b/lib/nav/core.h
@@ -12,8 +12,6 @@ class eNavigation: public iObject, public Object
private:
ePtr<iPlayableService> m_runningService;
- ePtr<iRecordableService> m_recordingService;
-
ePtr<iServiceHandler> m_servicehandler;
Signal2<void,eNavigation*,int> m_event;
ePtr<eConnection> m_service_event_conn;
@@ -38,8 +36,7 @@ public:
RESULT getPlaylist(ePtr<ePlaylist> &playlist);
RESULT stopService(void);
- RESULT recordService(const eServiceReference &service);
- RESULT endRecording();
+ RESULT recordService(const eServiceReference &ref, ePtr<iRecordableService> &service);
RESULT pause(int p);
eNavigation(iServiceHandler *serviceHandler);
diff --git a/lib/nav/pcore.cpp b/lib/nav/pcore.cpp
index 23df0030..6a849f89 100644
--- a/lib/nav/pcore.cpp
+++ b/lib/nav/pcore.cpp
@@ -21,14 +21,9 @@ RESULT pNavigation::playService(const eServiceReference &service)
return m_core->playService(service);
}
-RESULT pNavigation::recordService(const eServiceReference &service)
+RESULT pNavigation::recordService(const eServiceReference &ref, ePtr<iRecordableService> &service)
{
- return m_core->recordService(service);
-}
-
-RESULT pNavigation::endRecording()
-{
- return m_core->endRecording();
+ return m_core->recordService(ref, service);
}
RESULT pNavigation::enqueueService(const eServiceReference &service)
diff --git a/lib/nav/pcore.h b/lib/nav/pcore.h
index 018209bc..5da59d08 100644
--- a/lib/nav/pcore.h
+++ b/lib/nav/pcore.h
@@ -24,8 +24,7 @@ public:
pNavigation();
RESULT playService(const eServiceReference &service);
- RESULT recordService(const eServiceReference &service);
- RESULT endRecording();
+ RESULT recordService(const eServiceReference &ref, ePtr<iRecordableService> &service);
RESULT enqueueService(const eServiceReference &service);
RESULT getCurrentService(ePtr<iPlayableService> &service);
diff --git a/lib/service/iservice.h b/lib/service/iservice.h
index c58421ed..4379fbb8 100644
--- a/lib/service/iservice.h
+++ b/lib/service/iservice.h
@@ -190,6 +190,7 @@ TEMPLATE_TYPEDEF(ePtr<iPlayableService>, iPlayableServicePtr);
class iRecordableService: public iObject
{
public:
+ virtual RESULT prepare()=0;
virtual RESULT start()=0;
virtual RESULT stop()=0;
};
diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp
index 40e26365..2fb051c1 100644
--- a/lib/service/servicedvb.cpp
+++ b/lib/service/servicedvb.cpp
@@ -88,7 +88,7 @@ RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr<iPlayableServ
RESULT eServiceFactoryDVB::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
{
ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref);
- return -1;
+ return 0;
}
RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
diff --git a/lib/service/servicedvbrecord.cpp b/lib/service/servicedvbrecord.cpp
index c72b81d3..773aeb39 100644
--- a/lib/service/servicedvbrecord.cpp
+++ b/lib/service/servicedvbrecord.cpp
@@ -8,7 +8,8 @@ DEFINE_REF(eDVBServiceRecord);
eDVBServiceRecord::eDVBServiceRecord(const eServiceReferenceDVB &ref): m_ref(ref)
{
CONNECT(m_service_handler.serviceEvent, eDVBServiceRecord::serviceEvent);
- m_recording = 0;
+ m_state = stateIdle;
+ m_want_record = 0;
}
void eDVBServiceRecord::serviceEvent(int event)
@@ -23,129 +24,163 @@ void eDVBServiceRecord::serviceEvent(int event)
}
case eDVBServicePMTHandler::eventNewProgramInfo:
{
- /* allocate a ts recorder if we don't already have one. */
- if (!m_recording)
- {
- ::remove("recordings.ts");
- int fd = ::open("recording.ts", O_WRONLY|O_CREAT, 0644);
- if (fd == -1)
- {
- eDebug("eDVBServiceRecord - can't open hardcoded recording file!");
- return;
- }
- ePtr<iDVBDemux> demux;
- if (m_service_handler.getDemux(demux))
- {
- eDebug("eDVBServiceRecord - NO DEMUX available!");
- return;
- }
- demux->createTSRecorder(m_record);
- if (!m_record)
- {
- eDebug("eDVBServiceRecord - no ts recorder available.");
- return;
- }
- m_record->setTargetFD(fd);
- m_pids_active.clear();
- } else
- {
- /* when we're already recording, we already have a recorder allocated. */
- assert(m_record);
- }
-
-
- eDVBServicePMTHandler::program program;
- if (m_service_handler.getProgramInfo(program))
- eDebug("getting program info failed.");
- else
- {
- std::set<int> pids_to_record;
-
- 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 (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 (i != program.audioStreams.begin())
- eDebugNoNewLine(", ");
- eDebugNoNewLine("%04x", i->pid);
- }
- eDebugNoNewLine(")");
- }
- eDebug(", and the pcr pid is %04x", program.pcrPid);
- if (program.pcrPid != 0x1fff)
- pids_to_record.insert(program.pcrPid);
-
- /* 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(new_pids, new_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 (!m_recording)
- {
- m_record->start();
- m_recording = 1;
- }
- }
-
- // notify record thread...
+ if (m_state == stateIdle)
+ doPrepare();
+ else if (m_want_record) /* doRecord can be called from Prepared and Recording state */
+ doRecord();
break;
}
}
}
+
+RESULT eDVBServiceRecord::prepare()
+{
+ if (m_state == stateIdle)
+ return m_service_handler.tune(m_ref);
+ else
+ return -1;
+}
+
RESULT eDVBServiceRecord::start()
{
- eDebug("starting recording..");
- return m_service_handler.tune(m_ref);
+ m_want_record = 1;
+ /* when tune wasn't yet successfully, doRecord stays in "prepared"-state which is fine. */
+ return doRecord();
}
+
RESULT eDVBServiceRecord::stop()
{
eDebug("stop recording!!");
- if (m_recording)
+ if (m_state == stateRecording)
{
m_record->stop();
+ m_state = statePrepared;
+ }
+
+ if (m_state == statePrepared)
+ {
m_record = 0;
- m_recording = 0;
+ m_state = stateIdle;
+ }
+ return 0;
+}
+
+
+int eDVBServiceRecord::doPrepare()
+{
+ /* allocate a ts recorder if we don't already have one. */
+ if (m_state == stateIdle)
+ {
+ ::remove("recordings.ts");
+ int fd = ::open("recording.ts", O_WRONLY|O_CREAT, 0644);
+ if (fd == -1)
+ {
+ eDebug("eDVBServiceRecord - can't open hardcoded recording file!");
+ return -1;
+ }
+ ePtr<iDVBDemux> demux;
+ if (m_service_handler.getDemux(demux))
+ {
+ eDebug("eDVBServiceRecord - NO DEMUX available!");
+ return -2;
+ }
+ demux->createTSRecorder(m_record);
+ if (!m_record)
+ {
+ eDebug("eDVBServiceRecord - no ts recorder available.");
+ return -3;
+ }
+ m_record->setTargetFD(fd);
+ m_pids_active.clear();
+ m_state = statePrepared;
+ } else if ((m_state == statePrepared) || (m_state == stateRecording))
+ {
+ /* when we're already recording, we already have a recorder allocated. */
+ assert(m_record);
+ }
+ return 0;
+}
+
+int eDVBServiceRecord::doRecord()
+{
+ int err = doPrepare();
+ if (err)
+ return err;
+
+ eDebug("starting recording..");
+
+ eDVBServicePMTHandler::program program;
+ if (m_service_handler.getProgramInfo(program))
+ eDebug("getting program info failed.");
+ else
+ {
+ std::set<int> pids_to_record;
+
+ 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 (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 (i != program.audioStreams.begin())
+ eDebugNoNewLine(", ");
+ eDebugNoNewLine("%04x", i->pid);
+ }
+ eDebugNoNewLine(")");
+ }
+ eDebug(", and the pcr pid is %04x", program.pcrPid);
+ if (program.pcrPid != 0x1fff)
+ pids_to_record.insert(program.pcrPid);
+
+ /* 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(new_pids, new_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 (m_state != stateRecording)
+ {
+ m_record->start();
+ m_state = stateRecording;
+ }
}
return 0;
}
diff --git a/lib/service/servicedvbrecord.h b/lib/service/servicedvbrecord.h
index 6bd9fb96..c90d0c92 100644
--- a/lib/service/servicedvbrecord.h
+++ b/lib/service/servicedvbrecord.h
@@ -14,9 +14,12 @@ class eDVBServiceRecord: public iRecordableService, public Object
{
DECLARE_REF(eDVBServiceRecord);
public:
+ RESULT prepare();
RESULT start();
RESULT stop();
private:
+ enum { stateIdle, statePrepared, stateRecording };
+ int m_state, m_want_record;
friend class eServiceFactoryDVB;
eDVBServiceRecord(const eServiceReferenceDVB &ref);
@@ -28,6 +31,9 @@ private:
int m_recording;
std::set<int> m_pids_active;
+
+ int doPrepare();
+ int doRecord();
};
#endif