]> git.vomp.tv Git - vompclient.git/blob - vvideolive.cc
Big code cleanup
[vompclient.git] / vvideolive.cc
1 /*
2     Copyright 2004-2005 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "vvideolive.h"
22
23 VVideoLive* VVideoLive::instance = NULL;
24
25 VVideoLive::VVideoLive(ChannelList* tchanList, ULONG tstreamType)
26 {
27   instance = this;
28   vdr = VDR::getInstance();
29   viewman = ViewMan::getInstance();
30   chanList = tchanList;
31   currentChannel = 0;
32   previousChannel = 0;
33   unavailable = 0;
34   unavailableView = NULL;
35   streamType = tstreamType;
36   videoMode = Video::getInstance()->getMode();
37   if (streamType == VDR::RADIO) player = new PlayerVideo(Command::getInstance(), 0, 1);
38   else                          player = new PlayerVideo(Command::getInstance(), 0, 0);
39
40   player->init();
41
42   Video* video = Video::getInstance();
43   create(video->getScreenWidth(), video->getScreenHeight());
44   Colour transparent(0, 0, 0, 0);
45   setBackgroundColour(transparent);
46 }
47
48 VVideoLive::~VVideoLive()
49 {
50   delete player;
51   instance = NULL;
52   Video::getInstance()->setDefaultAspect();
53 }
54
55 VVideoLive* VVideoLive::getInstance()
56 {
57   return instance;
58 }
59
60 void VVideoLive::draw()
61 {
62   View::draw();
63 }
64
65 int VVideoLive::handleCommand(int command)
66 {
67   switch(command)
68   {
69     case Remote::PLAY:
70     {
71       if (!unavailable) player->play(); // do resync
72       return 2;
73     }
74     case Remote::PAUSE:
75     {
76       if (!unavailable) player->resyncAudio(); // do resync2
77       return 2;
78     }
79
80     case Remote::STOP:
81     case Remote::BACK:
82     case Remote::MENU:
83     {
84       if (unavailable) showUnavailable(0);
85       else stop();
86       return 4;
87     }
88     // Take up and down from new remote and do live banner
89     case Remote::UP:
90     case Remote::DOWN:
91     {
92       doBanner(true);
93       return 2;
94     }
95     case Remote::DF_UP:
96     case Remote::CHANNELUP:
97     {
98       if (unavailable) showUnavailable(0);
99       else stop();
100       channelChange(OFFSET, UP);
101       return 2;
102     }
103     case Remote::DF_DOWN:
104     case Remote::CHANNELDOWN:
105     {
106       if (unavailable) showUnavailable(0);
107       else stop();
108       channelChange(OFFSET, DOWN);
109       return 2;
110     }
111     case Remote::PREVCHANNEL:
112     {
113       if (unavailable) showUnavailable(0);
114       else stop();
115       channelChange(PREVIOUS, 0);
116       return 2;
117     }
118     case Remote::OK:
119     {
120       doBanner(true);
121       return 2;
122     }
123     case Remote::GUIDE:
124     case Remote::RED:
125     {
126       showEPG();
127       return 2;
128     }
129
130     case Remote::ZERO ... Remote::NINE:
131     {
132       VChannelSelect* v = new VChannelSelect(this, command);
133       v->draw();
134       viewman->add(v);
135       viewman->updateView(v);
136     }
137   }
138
139   return 1;
140 }
141
142 void VVideoLive::channelChange(UCHAR changeType, UINT newData)
143 {
144   UINT newChannel = 0;
145
146   if (changeType == INDEX)
147   {
148     newChannel = newData;
149   }
150   else if (changeType == NUMBER)
151   {
152     UINT i;
153     for(i = 0; i < chanList->size(); i++)
154     {
155       if ((*chanList)[i]->number == (UINT)newData)
156       {
157         newChannel = i;
158         break;
159       }
160     }
161
162     if (i == chanList->size())
163     {
164       doNoSuchChannel();
165       return;
166     }
167   }
168   else if (changeType == OFFSET)
169   {
170     if (newData == UP) newChannel = upChannel();
171     else newChannel = downChannel();
172   }
173   else if (changeType == PREVIOUS)
174   {
175     newChannel = previousChannel;
176   }
177   else
178   {
179     return; // bad input!
180   }
181
182   previousChannel = currentChannel;
183   currentChannel = newChannel;
184
185   if (unavailable) showUnavailable(0);
186   else stop(1);
187
188   VEpg* vepg = VEpg::getInstance();
189   if(vepg) vepg->setCurrentChannel((*chanList)[currentChannel]->name);
190
191   VLiveBanner* vlb = VLiveBanner::getInstance();
192   if (vlb)
193   {
194     vlb->setChannel((*chanList)[currentChannel]);
195     vlb->draw();
196     viewman->updateView(vlb);
197   }
198
199   play();
200 }
201
202 void VVideoLive::streamEnd()
203 {
204   Log::getInstance()->log("VVideoLive", Log::DEBUG, "streamEnd");
205   stop();
206   showUnavailable(1);
207 }
208
209 void VVideoLive::processMessage(Message* m)
210 {
211   if (m->message == Message::CHANNEL_CHANGE)
212   {
213     channelChange(NUMBER, m->parameter);
214   }
215   else if (m->message == Message::EPG)
216   {
217     Log::getInstance()->log("VVideoLive", Log::DEBUG, "EPG requested from live banner");
218     showEPG();
219   }
220   else if (m->message == Message::EPG_CLOSE)
221   {
222     Video::getInstance()->setMode(videoMode);
223     if (saveUnavailable) showUnavailable(1);
224   }
225 }
226
227 void VVideoLive::doBanner(bool bannerTakesCommands)
228 {
229   if (VEpg::getInstance()) return;
230
231   if (VLiveBanner::getInstance()) return; // there already is one
232
233   VLiveBanner* vlb = new VLiveBanner(this, (*chanList)[currentChannel], bannerTakesCommands);
234
235   vlb->draw();
236   viewman->add(vlb);
237   viewman->updateView(vlb);
238 }
239
240 void VVideoLive::doNoSuchChannel()
241 {
242   Log::getInstance()->log("VVideoLive", Log::ERR, "No such channel");
243   // FIXME do gui for this
244 }
245
246 void VVideoLive::showUnavailable(int active)
247 {
248   if (active == unavailable) return;
249
250   if (active)
251   {
252     unavailable = 1;
253
254     unavailableView = new VInfo();
255     unavailableView->create(400, 200);
256     if (Video::getInstance()->getFormat() == Video::PAL)
257     {
258       unavailableView->setScreenPos(170, 200);
259     }
260     else
261     {
262       unavailableView->setScreenPos(160, 150);
263     }
264     unavailableView->setTitleText((*chanList)[currentChannel]->name);
265     unavailableView->setOneLiner(tr("Channel unavailable"));
266     unavailableView->setDropThrough();
267     unavailableView->draw();
268     viewman->add(unavailableView);
269     viewman->updateView(unavailableView);
270   }
271   else
272   {
273     unavailable = 0;
274     viewman->removeView(unavailableView);
275     unavailableView = NULL;
276   }
277 }
278
279 void VVideoLive::play(int noShowVLB)
280 {
281   showUnavailable(0);
282
283   int available = vdr->streamChannel((*chanList)[currentChannel]->number);
284
285   if (!available)
286   {
287     if (!noShowVLB) doBanner(false);
288     showUnavailable(1);
289   }
290   else
291   {
292     if (!noShowVLB) doBanner(false);
293     player->play();
294   }
295 }
296
297 void VVideoLive::stop(int noRemoveVLB)
298 {
299   if (unavailable) return;
300   if (!noRemoveVLB && VLiveBanner::getInstance()) viewman->removeView(VLiveBanner::getInstance()); // if live banner is present, remove it. won't cause damage if its not present
301
302   player->stop();
303   Log::getInstance()->log("VVideoLive", Log::DEBUG, "Delay starts here due to time taken by plugin to stop");
304   vdr->stopStreaming();
305   Log::getInstance()->log("VVideoLive", Log::DEBUG, "Delay ends here due to time taken by plugin to stop");
306 }
307
308 UINT VVideoLive::upChannel()
309 {
310   if (currentChannel == (chanList->size() - 1)) // at the end
311     return 0; // so go to start
312   else
313     return currentChannel + 1;
314 }
315
316 UINT VVideoLive::downChannel()
317 {
318   if (currentChannel == 0) // at the start
319     return chanList->size() - 1; // so go to end
320   else
321     return currentChannel - 1;
322 }
323
324 void VVideoLive::showEPG()
325 {
326   saveUnavailable = unavailable;
327   if (unavailable) showUnavailable(0);
328
329   if (VEpg::getInstance()) return; // already showing!
330
331   Video::getInstance()->setMode(Video::QUARTER);
332   Video::getInstance()->setPosition(170, 5); //TODO need to deal with 4:3 switching
333
334   VEpg* vepg = new VEpg(this, currentChannel);
335   vepg->draw();
336
337   viewman->add(vepg);
338   viewman->updateView(vepg);
339 }