]>
Commit | Line | Data |
---|---|---|
b91fb912 | 1 | === libs/libmythtv/dvbcam.h |
2 | Index: libs/libmythtv/dvbcam.cpp | |
3 | =================================================================== | |
4 | --- libs/libmythtv/dvbcam.cpp.orig 2006-06-20 17:32:47.000000000 -0400 | |
5 | +++ libs/libmythtv/dvbcam.cpp 2006-06-20 17:39:50.000000000 -0400 | |
6 | @@ -36,6 +36,8 @@ | |
7 | #include <qdatetime.h> | |
8 | #include <qvariant.h> | |
9 | ||
10 | +#include <qdir.h> | |
11 | + | |
12 | #include <iostream> | |
13 | #include <vector> | |
14 | #include <map> | |
15 | @@ -84,6 +86,10 @@ | |
16 | ||
17 | bool DVBCam::Start() | |
18 | { | |
19 | + | |
20 | + if(useExternalCam()) | |
21 | + return true; | |
22 | + | |
23 | if (numslots == 0) | |
24 | return false; | |
25 | ||
26 | @@ -114,6 +120,9 @@ | |
27 | ||
28 | bool DVBCam::Stop() | |
29 | { | |
30 | + | |
31 | + stopExternalCam(); | |
32 | + | |
33 | if (ciThreadRunning) | |
34 | { | |
35 | exitCiThread = true; | |
36 | @@ -256,6 +265,9 @@ | |
37 | void DVBCam::SetPMT(const PMTObject *pmt) | |
38 | { | |
39 | GENERAL(QString("CA: SetPMT for ServiceID=%1").arg(pmt->ServiceID)); | |
40 | + | |
41 | + sendExternalCam(pmt); | |
42 | + | |
43 | pthread_mutex_lock(&pmt_lock); | |
44 | PMTList.clear(); | |
45 | PMTList += *pmt; | |
46 | @@ -343,3 +355,149 @@ | |
47 | } | |
48 | } | |
49 | ||
50 | +bool DVBCam::useExternalCam() | |
51 | +{ | |
52 | + skThreadRunning = false; | |
53 | + exitSkThread = false; | |
54 | + external_cam_fd = -1; | |
55 | + QString extCam = QDir::homeDirPath() + | |
56 | + QString("/.mythtv/externcam_%1").arg(cardnum); | |
57 | + if (QFileInfo(extCam).isDir()) | |
58 | + { | |
59 | + QString cmd = gContext->GetSetting("ExternalCamApp",""); | |
60 | + if(cmd == "") { | |
61 | + ERROR("CAM - No external app set in SQL db."); | |
62 | + return false; | |
63 | + } | |
64 | + cmd += " --dir " + extCam + QString(" --card %1").arg(cardnum); | |
65 | + | |
66 | + QString keyFifo = QDir::homeDirPath() + | |
67 | + QString("/.mythtv/externcam_%1/keyfifo").arg(cardnum); | |
68 | + unlink(keyFifo.ascii()); | |
69 | + | |
70 | + int tmppid[2]; | |
71 | + if (pipe(tmppid) < 0) | |
72 | + { | |
73 | + perror("Failed to create pipe\n"); | |
74 | + return false; | |
75 | + } | |
76 | + | |
77 | + int child = fork(); | |
78 | + if (child < 0) | |
79 | + { | |
80 | + perror("Failed to fork\n"); | |
81 | + return false; | |
82 | + } | |
83 | + if (child == 0) | |
84 | + { | |
85 | + dup2(tmppid[0],fileno(stdin)); | |
86 | + for(int i = 3; i < sysconf(_SC_OPEN_MAX) - 1; ++i) | |
87 | + close(i); | |
88 | + execl("/bin/sh", "sh", "-c", cmd.ascii(), NULL); | |
89 | + perror("exec"); | |
90 | + _exit(1); | |
91 | + } | |
92 | + close(tmppid[0]); | |
93 | + external_cam_fd=tmppid[1]; | |
94 | + | |
95 | + //we need to fake ciThreadRunning in oreder to get PMTs | |
96 | + ciThreadRunning = true; | |
97 | + return true; | |
98 | + } | |
99 | + return false; | |
100 | +} | |
101 | + | |
102 | +void DVBCam::sendExternalCam(const PMTObject *pmt) | |
103 | +{ | |
104 | + if (external_cam_fd < 0) | |
105 | + return; | |
106 | + | |
107 | + unsigned char newpmt[512]; | |
108 | + int hdr[34]; //Allow for up to 16 PIDs | |
109 | + int pmtlen=0, hdrlen = 0; | |
110 | + bool need_pcrpid = false; | |
111 | + | |
112 | + hdr[hdrlen++]=pmt->ServiceID; | |
113 | + hdr[hdrlen++]=1; //Place holder for transportID (future) | |
114 | + for (CAList::const_iterator ca = pmt->CA.begin(); ca != pmt->CA.end(); ++ca) | |
115 | + { | |
116 | + newpmt[pmtlen++] = 0x09; | |
117 | + newpmt[pmtlen++] = (*ca).Data_Length + | |
118 | + sizeof((*ca).CASystemID) + sizeof((*ca).PID); | |
119 | + newpmt[pmtlen++] = ((*ca).CASystemID) >> 8; | |
120 | + newpmt[pmtlen++] = ((*ca).CASystemID) & 0xff; | |
121 | + newpmt[pmtlen++] = ((*ca).PID) >> 8; | |
122 | + newpmt[pmtlen++] = ((*ca).PID) & 0xff; | |
123 | + for (int x = 0; x < (*ca).Data_Length; x++) | |
124 | + newpmt[pmtlen++] = ((*ca).Data[x]); | |
125 | + } | |
126 | + for (ComponentList::const_iterator e = pmt->Components.begin(); | |
127 | + e != pmt->Components.end(); ++e) | |
128 | + { | |
129 | + int type; | |
130 | + switch ((*e).Type) | |
131 | + { | |
132 | + case ES_TYPE_AUDIO_MPEG1: case ES_TYPE_AUDIO_MPEG2: | |
133 | + case ES_TYPE_AUDIO_AC3: case ES_TYPE_AUDIO_DTS: | |
134 | + case ES_TYPE_AUDIO_AAC: | |
135 | + type = 0; | |
136 | + break; | |
137 | + case ES_TYPE_VIDEO_MPEG1: case ES_TYPE_VIDEO_MPEG2: | |
138 | + case ES_TYPE_VIDEO_MPEG4: case ES_TYPE_VIDEO_H264: | |
139 | + if (pmt->PCRPID != 0 && pmt->PCRPID != (*e).PID) | |
140 | + { | |
141 | + hdr[hdrlen++] = pmt->PCRPID; //pid | |
142 | + hdr[hdrlen++] = 2; //stream type | |
143 | + } | |
144 | + type = 1; | |
145 | + break; | |
146 | + case ES_TYPE_TELETEXT: | |
147 | + type = 3; | |
148 | + break; | |
149 | + default: | |
150 | + type = 5; | |
151 | + } | |
152 | + hdr[hdrlen++] = (*e).PID; //pid | |
153 | + hdr[hdrlen++] = type; //stream type | |
154 | + for (CAList::const_iterator ca = (*e).CA.begin(); | |
155 | + ca != (*e).CA.end(); ++ca) | |
156 | + { | |
157 | + newpmt[pmtlen++] = 0x09; | |
158 | + newpmt[pmtlen++] = (*ca).Data_Length + | |
159 | + sizeof((*ca).CASystemID) + sizeof((*ca).PID); | |
160 | + newpmt[pmtlen++] = ((*ca).CASystemID) >> 8; | |
161 | + newpmt[pmtlen++] = ((*ca).CASystemID) & 0xff; | |
162 | + newpmt[pmtlen++] = ((*ca).PID) >> 8; | |
163 | + newpmt[pmtlen++] = ((*ca).PID) & 0xff; | |
164 | + for (int x = 0; x < (*ca).Data_Length; x++) | |
165 | + newpmt[pmtlen++] = (*ca).Data[x]; | |
166 | + } | |
167 | + } | |
168 | + if (pmtlen) { | |
169 | + QString temp = QString("SID: %1 TID: %2").arg(hdr[0]).arg(hdr[1]); | |
170 | + for (int x = 2; x < hdrlen; x += 2) | |
171 | + temp += QString(" (%1 %2)").arg(hdr[x]).arg(hdr[x + 1]); | |
172 | + GENERAL(temp); | |
173 | + temp = QString("Found CA Descriptors: (%1)").arg(pmtlen); | |
174 | + for (int x = 0; x < pmtlen; x++) | |
175 | + temp += QString(" %1").arg(newpmt[x],2,16); | |
176 | + GENERAL(temp); | |
177 | + write(external_cam_fd, &hdrlen, sizeof(hdrlen)); | |
178 | + write(external_cam_fd, &hdr, hdrlen * sizeof(int)); | |
179 | + write(external_cam_fd, &pmtlen, sizeof(pmtlen)); | |
180 | + write(external_cam_fd, &newpmt, pmtlen); | |
181 | + } | |
182 | +} | |
183 | + | |
184 | +void DVBCam::stopExternalCam() | |
185 | +{ | |
186 | + if(external_cam_fd != -1) { | |
187 | + close(external_cam_fd); | |
188 | + ciThreadRunning = false; | |
189 | + if (skThreadRunning) | |
190 | + { | |
191 | + exitSkThread = true; | |
192 | + pthread_join(externSoftkeyThread, NULL); | |
193 | + } | |
194 | + } | |
195 | +} | |
196 | Index: libs/libmythtv/dvbcam.h | |
197 | =================================================================== | |
198 | --- libs/libmythtv/dvbcam.h.orig 2006-06-20 17:32:47.000000000 -0400 | |
199 | +++ libs/libmythtv/dvbcam.h 2006-06-20 17:39:50.000000000 -0400 | |
200 | @@ -42,6 +42,15 @@ | |
201 | bool pmt_sent; | |
202 | bool pmt_updated; | |
203 | bool pmt_added; | |
204 | + | |
205 | + bool exitSkThread; | |
206 | + bool skThreadRunning; | |
207 | + pthread_t externSoftkeyThread; | |
208 | + int external_cam_fd; | |
209 | + void sendExternalCam(const PMTObject *pmt); | |
210 | + bool useExternalCam(); | |
211 | + void stopExternalCam(); | |
212 | + | |
213 | }; | |
214 | ||
215 | #endif // DVBCAM_H |