- add ts recorder to dvb record service
[enigma2.git] / lib / service / servicedvbrecord.cpp
1 #include <lib/service/servicedvbrecord.h>
2 #include <lib/base/eerror.h>
3
4 #include <fcntl.h>
5
6 DEFINE_REF(eDVBServiceRecord);
7
8 eDVBServiceRecord::eDVBServiceRecord(const eServiceReferenceDVB &ref): m_ref(ref)
9 {
10         CONNECT(m_service_handler.serviceEvent, eDVBServiceRecord::serviceEvent);
11         m_recording = 0;
12 }
13
14 void eDVBServiceRecord::serviceEvent(int event)
15 {
16         eDebug("RECORD service event %d", event);
17         switch (event)
18         {
19         case eDVBServicePMTHandler::eventTuned:
20         {
21                 eDebug("tuned..");
22                 break;
23         }
24         case eDVBServicePMTHandler::eventNewProgramInfo:
25         {
26                         /* allocate a ts recorder if we don't already have one. */
27                 if (!m_recording)
28                 {
29                         ::remove("recordings.ts");
30                         int fd = ::open("recording.ts", O_WRONLY|O_CREAT, 0644);
31                         if (fd == -1)
32                         {
33                                 eDebug("eDVBServiceRecord - can't open hardcoded recording file!");
34                                 return;
35                         }
36                         ePtr<iDVBDemux> demux;
37                         if (m_service_handler.getDemux(demux))
38                         {
39                                 eDebug("eDVBServiceRecord - NO DEMUX available!");
40                                 return;
41                         }
42                         demux->createTSRecorder(m_record);
43                         if (!m_record)
44                         {
45                                 eDebug("eDVBServiceRecord - no ts recorder available.");
46                                 return;
47                         }
48                         m_record->setTargetFD(fd);
49                         m_pids_active.clear();
50                 } else
51                 {
52                                 /* when we're already recording, we already have a recorder allocated. */
53                         assert(m_record);
54                 }
55                 
56
57                 eDVBServicePMTHandler::program program;
58                 if (m_service_handler.getProgramInfo(program))
59                         eDebug("getting program info failed.");
60                 else
61                 {
62                         std::set<int> pids_to_record;
63                         
64                         eDebugNoNewLine("RECORD: have %d video stream(s)", program.videoStreams.size());
65                         if (!program.videoStreams.empty())
66                         {
67                                 eDebugNoNewLine(" (");
68                                 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
69                                         i(program.videoStreams.begin()); 
70                                         i != program.videoStreams.end(); ++i)
71                                 {
72                                         pids_to_record.insert(i->pid);
73                                         if (i != program.videoStreams.begin())
74                                                 eDebugNoNewLine(", ");
75                                         eDebugNoNewLine("%04x", i->pid);
76                                 }
77                                 eDebugNoNewLine(")");
78                         }
79                         eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size());
80                         if (!program.audioStreams.empty())
81                         {
82                                 eDebugNoNewLine(" (");
83                                 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
84                                         i(program.audioStreams.begin()); 
85                                         i != program.audioStreams.end(); ++i)
86                                 {
87                                         pids_to_record.insert(i->pid);
88                                         if (i != program.audioStreams.begin())
89                                                 eDebugNoNewLine(", ");
90                                         eDebugNoNewLine("%04x", i->pid);
91                                 }
92                                 eDebugNoNewLine(")");
93                         }
94                         eDebug(", and the pcr pid is %04x", program.pcrPid);
95                         if (program.pcrPid != 0x1fff)
96                                 pids_to_record.insert(program.pcrPid);
97                         
98                                 /* find out which pids are NEW and which pids are obsolete.. */
99                         std::set<int> new_pids, obsolete_pids;
100                         
101                         std::set_difference(pids_to_record.begin(), pids_to_record.end(), 
102                                         m_pids_active.begin(), m_pids_active.end(),
103                                         std::inserter(new_pids, new_pids.begin()));
104                         
105                         std::set_difference(
106                                         m_pids_active.begin(), m_pids_active.end(),
107                                         pids_to_record.begin(), pids_to_record.end(), 
108                                         std::inserter(new_pids, new_pids.begin())
109                                         );
110                         
111                         for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
112                         {
113                                 eDebug("ADD PID: %04x", *i);
114                                 m_record->addPID(*i);
115                         }
116                         for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
117                         {
118                                 eDebug("REMOVED PID: %04x", *i);
119                                 m_record->removePID(*i);
120                         }
121                         
122                         if (!m_recording)
123                         {
124                                 m_record->start();
125                                 m_recording = 1;
126                         }
127                 }
128                 
129                                 // notify record thread...              
130                 break;
131         }
132         }
133 }
134
135 RESULT eDVBServiceRecord::start()
136 {
137         eDebug("starting recording..");
138         return m_service_handler.tune(m_ref);
139 }
140
141 RESULT eDVBServiceRecord::stop()
142 {
143         eDebug("stop recording!!");
144         if (m_recording)
145         {
146                 m_record->stop();
147                 m_record = 0;
148                 m_recording = 0;
149         }
150         return 0;
151 }