1 #include <lib/service/servicedvbrecord.h>
2 #include <lib/base/eerror.h>
6 DEFINE_REF(eDVBServiceRecord);
8 eDVBServiceRecord::eDVBServiceRecord(const eServiceReferenceDVB &ref): m_ref(ref)
10 CONNECT(m_service_handler.serviceEvent, eDVBServiceRecord::serviceEvent);
15 void eDVBServiceRecord::serviceEvent(int event)
17 eDebug("RECORD service event %d", event);
20 case eDVBServicePMTHandler::eventTuned:
25 case eDVBServicePMTHandler::eventNewProgramInfo:
27 if (m_state == stateIdle)
29 else if (m_want_record) /* doRecord can be called from Prepared and Recording state */
37 RESULT eDVBServiceRecord::prepare()
39 if (m_state == stateIdle)
40 return m_service_handler.tune(m_ref);
45 RESULT eDVBServiceRecord::start()
48 /* when tune wasn't yet successfully, doRecord stays in "prepared"-state which is fine. */
53 RESULT eDVBServiceRecord::stop()
55 eDebug("stop recording!!");
56 if (m_state == stateRecording)
59 m_state = statePrepared;
62 if (m_state == statePrepared)
71 int eDVBServiceRecord::doPrepare()
73 /* allocate a ts recorder if we don't already have one. */
74 if (m_state == stateIdle)
76 ::remove("recordings.ts");
77 int fd = ::open("recording.ts", O_WRONLY|O_CREAT, 0644);
80 eDebug("eDVBServiceRecord - can't open hardcoded recording file!");
83 ePtr<iDVBDemux> demux;
84 if (m_service_handler.getDemux(demux))
86 eDebug("eDVBServiceRecord - NO DEMUX available!");
89 demux->createTSRecorder(m_record);
92 eDebug("eDVBServiceRecord - no ts recorder available.");
95 m_record->setTargetFD(fd);
96 m_pids_active.clear();
97 m_state = statePrepared;
98 } else if ((m_state == statePrepared) || (m_state == stateRecording))
100 /* when we're already recording, we already have a recorder allocated. */
106 int eDVBServiceRecord::doRecord()
108 int err = doPrepare();
112 eDebug("starting recording..");
114 eDVBServicePMTHandler::program program;
115 if (m_service_handler.getProgramInfo(program))
116 eDebug("getting program info failed.");
119 std::set<int> pids_to_record;
121 eDebugNoNewLine("RECORD: have %d video stream(s)", program.videoStreams.size());
122 if (!program.videoStreams.empty())
124 eDebugNoNewLine(" (");
125 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
126 i(program.videoStreams.begin());
127 i != program.videoStreams.end(); ++i)
129 pids_to_record.insert(i->pid);
130 if (i != program.videoStreams.begin())
131 eDebugNoNewLine(", ");
132 eDebugNoNewLine("%04x", i->pid);
134 eDebugNoNewLine(")");
136 eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size());
137 if (!program.audioStreams.empty())
139 eDebugNoNewLine(" (");
140 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
141 i(program.audioStreams.begin());
142 i != program.audioStreams.end(); ++i)
144 pids_to_record.insert(i->pid);
145 if (i != program.audioStreams.begin())
146 eDebugNoNewLine(", ");
147 eDebugNoNewLine("%04x", i->pid);
149 eDebugNoNewLine(")");
151 eDebug(", and the pcr pid is %04x", program.pcrPid);
152 if (program.pcrPid != 0x1fff)
153 pids_to_record.insert(program.pcrPid);
155 /* find out which pids are NEW and which pids are obsolete.. */
156 std::set<int> new_pids, obsolete_pids;
158 std::set_difference(pids_to_record.begin(), pids_to_record.end(),
159 m_pids_active.begin(), m_pids_active.end(),
160 std::inserter(new_pids, new_pids.begin()));
163 m_pids_active.begin(), m_pids_active.end(),
164 pids_to_record.begin(), pids_to_record.end(),
165 std::inserter(new_pids, new_pids.begin())
168 for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
170 eDebug("ADD PID: %04x", *i);
171 m_record->addPID(*i);
173 for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
175 eDebug("REMOVED PID: %04x", *i);
176 m_record->removePID(*i);
179 if (m_state != stateRecording)
182 m_state = stateRecording;