From: Felix Domke Date: Wed, 4 May 2005 15:57:32 +0000 (+0000) Subject: - improve record support X-Git-Tag: 2.6.0~5879 X-Git-Url: https://git.cweiske.de/enigma2.git/commitdiff_plain/1d7e5720b3e8653604323b981e37af1f6aa61709 - improve record support --- 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 &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 m_runningService; - ePtr m_recordingService; - ePtr m_servicehandler; Signal2 m_event; ePtr m_service_event_conn; @@ -38,8 +36,7 @@ public: RESULT getPlaylist(ePtr &playlist); RESULT stopService(void); - RESULT recordService(const eServiceReference &service); - RESULT endRecording(); + RESULT recordService(const eServiceReference &ref, ePtr &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 &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 &service); RESULT enqueueService(const eServiceReference &service); RESULT getCurrentService(ePtr &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, 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 &ptr) { ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref); - return -1; + return 0; } RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr &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 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 pids_to_record; - - eDebugNoNewLine("RECORD: have %d video stream(s)", program.videoStreams.size()); - if (!program.videoStreams.empty()) - { - eDebugNoNewLine(" ("); - for (std::vector::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::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 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::iterator i(new_pids.begin()); i != new_pids.end(); ++i) - { - eDebug("ADD PID: %04x", *i); - m_record->addPID(*i); - } - for (std::set::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 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 pids_to_record; + + eDebugNoNewLine("RECORD: have %d video stream(s)", program.videoStreams.size()); + if (!program.videoStreams.empty()) + { + eDebugNoNewLine(" ("); + for (std::vector::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::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 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::iterator i(new_pids.begin()); i != new_pids.end(); ++i) + { + eDebug("ADD PID: %04x", *i); + m_record->addPID(*i); + } + for (std::set::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 m_pids_active; + + int doPrepare(); + int doRecord(); }; #endif