]> git.vomp.tv Git - vompclient.git/blob - vvideolive.cc
Return to correct video mode after EPG. UP/DOWN trigger VLB
[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   epgmode=false;
37   videoMode = Video::getInstance()->getMode();
38   if (streamType == VDR::RADIO) player = new PlayerVideo(Command::getInstance(), 0, 1);
39   else                          player = new PlayerVideo(Command::getInstance(), 0, 0);
40
41   player->init();
42
43   Video* video = Video::getInstance();
44   create(video->getScreenWidth(), video->getScreenHeight());
45   Colour transparent(0, 0, 0, 0);
46   setBackgroundColour(transparent);
47 }
48
49 VVideoLive::~VVideoLive()
50 {
51   delete player;
52   instance = NULL;
53   Video::getInstance()->setDefaultAspect();
54 }
55
56 VVideoLive* VVideoLive::getInstance()
57 {
58   return instance;
59 }
60
61 void VVideoLive::draw()
62 {
63   View::draw();
64 }
65
66 int VVideoLive::handleCommand(int command)
67 {
68   switch(command)
69   {
70     case Remote::PLAY:
71     {
72       if (!unavailable) player->play(); // do resync
73       return 2;
74     }
75
76     case Remote::STOP:
77     case Remote::BACK:
78     case Remote::MENU:
79     {
80       if (unavailable) showUnavailable(0);
81       else stop();
82       return 4;
83     }
84     // Take up and down from new remote and do live banner
85     case Remote::UP:
86     case Remote::DOWN:
87     {
88       doBanner(true);
89       return 2;
90     }
91     case Remote::DF_UP:
92     case Remote::CHANNELUP:
93     {
94       if (unavailable) showUnavailable(0);
95       else stop();
96       channelChange(OFFSET, UP);
97       return 2;
98     }
99     case Remote::DF_DOWN:
100     case Remote::CHANNELDOWN:
101     {
102       if (unavailable) showUnavailable(0);
103       else stop();
104       channelChange(OFFSET, DOWN);
105       return 2;
106     }
107     case Remote::PREVCHANNEL:
108     {
109       if (unavailable) showUnavailable(0);
110       else stop();
111       channelChange(PREVIOUS, 0);
112       return 2;
113     }
114     case Remote::OK:
115     {
116       doBanner(true);
117       return 2;
118     }
119     case Remote::GUIDE:
120     case Remote::RED:
121     {
122       if (!epgmode)
123       {
124         showEPG();
125       }
126       epgmode=!epgmode;
127       return 2;
128     }
129
130     case Remote::ZERO ... Remote::NINE:
131     {
132       VChannelSelect* v = new VChannelSelect(this, command);
133       viewman->add(v);
134       v->draw();
135       v->show();
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     newChannel = channelIndexFromNumber(newData);
153   }
154   else if (changeType == OFFSET)
155   {
156     if (newData == UP) newChannel = upChannel();
157     else newChannel = downChannel();
158   }
159   else if (changeType == PREVIOUS)
160   {
161     newChannel = previousChannel;
162   }
163   else
164   {
165     return; // bad input!
166   }
167
168   previousChannel = currentChannel;
169   currentChannel = newChannel;
170
171   if (unavailable) showUnavailable(0);
172   else stop(1);
173   if(epgmode)
174     if(vepg)
175       vepg->setCurrentChannel((*chanList)[currentChannel]->name);
176   play();
177 }
178
179 void VVideoLive::processMessage(Message* m)
180 {
181   if (m->message == Message::CHANNEL_CHANGE)
182   {
183     channelChange(NUMBER, m->parameter);
184   }
185   else if (m->message == Message::CHANNEL_UP)
186   {
187     // this message is from vlivebanner
188     channelChange(OFFSET, UP);
189     if(!epgmode)
190     {
191       VLiveBanner* vlb = VLiveBanner::getInstance(); // guaranteed to be one
192       vlb->setChannel((*chanList)[currentChannel]);
193       vlb->draw();
194       vlb->show();
195     }
196   }
197   else if (m->message == Message::CHANNEL_DOWN)
198   {
199     // this message is from vlivebanner
200     channelChange(OFFSET, DOWN);
201     if(!epgmode)
202     {
203       VLiveBanner* vlb = VLiveBanner::getInstance(); // guaranteed to be one
204       vlb->setChannel((*chanList)[currentChannel]);
205       vlb->draw();
206       vlb->show();
207     }
208   }
209   else if (m->message == Message::STREAM_END)
210   {
211     Log::getInstance()->log("VVideoLive", Log::DEBUG, "streamEnd");
212     stop();
213     play(1);
214   }
215   else if (m->message == Message::EPG)
216   {
217     Log::getInstance()->log("VVideoLive", Log::DEBUG, "EPG requested from live banner");
218
219     if (!epgmode)
220     {
221       showEPG();
222       epgmode=!epgmode; // shouldn't this be within the braces? // same for above in handleCommand, ask Brian FIXME
223     }
224   }
225 }
226
227 void VVideoLive::doBanner(bool bannerTakesCommands)
228 {
229   if(epgmode)
230     return;
231
232   if (VLiveBanner::getInstance()) return; // there already is one
233
234   VLiveBanner* vlb = new VLiveBanner(this, (*chanList)[currentChannel], bannerTakesCommands);
235
236   Message* m = new Message();
237   m->from = this;
238   m->to = viewman;
239   m->message = Message::ADD_VIEW;
240   m->parameter = (ULONG)vlb;
241
242   viewman->postMessage(m);
243 }
244
245 void VVideoLive::showUnavailable(int active)
246 {
247   if (active == unavailable) return;
248
249   if (active)
250   {
251     unavailable = 1;
252
253     unavailableView = new VInfo();
254     unavailableView->create(400, 200);
255     if (Video::getInstance()->getFormat() == Video::PAL)
256     {
257       unavailableView->setScreenPos(170, 200);
258     }
259     else
260     {
261       unavailableView->setScreenPos(160, 150);
262     }
263     unavailableView->setTitleText((*chanList)[currentChannel]->name);
264     unavailableView->setOneLiner(tr("Channel unavailable"));
265     unavailableView->setDropThrough();
266
267     Message* m = new Message();
268     m->from = this;
269     m->to = viewman;
270     m->message = Message::ADD_VIEW;
271     m->parameter = (ULONG)unavailableView;
272
273     viewman->postMessage(m);
274   }
275   else
276   {
277     unavailable = 0;
278     ViewMan::getInstance()->removeView(unavailableView);
279     unavailableView = NULL;
280   }
281 }
282
283 void VVideoLive::play(int noShowVLB)
284 {
285   showUnavailable(0);
286
287   int available = vdr->streamChannel((*chanList)[currentChannel]->number);
288
289   if (!available)
290   {
291     showUnavailable(1);
292     if (!noShowVLB) doBanner(false);
293   }
294   else
295   {
296     if (!noShowVLB) doBanner(false);
297     player->play();
298   }
299 }
300
301 void VVideoLive::stop(int noRemoveVLB)
302 {
303   if (unavailable) return;
304   if (!noRemoveVLB && VLiveBanner::getInstance()) viewman->removeView(VLiveBanner::getInstance()); // if live banner is present, remove it. won't cause damage if its not present
305
306   player->stop();
307   Log::getInstance()->log("VVideoLive", Log::DEBUG, "Delay starts here due to time taken by plugin to stop");
308   vdr->stopStreaming();
309   Log::getInstance()->log("VVideoLive", Log::DEBUG, "Delay ends here due to time taken by plugin to stop");
310 }
311
312 UINT VVideoLive::upChannel()
313 {
314   if (currentChannel == (chanList->size() - 1)) // at the end
315     return 0; // so go to start
316   else
317     return currentChannel + 1;
318 }
319
320 UINT VVideoLive::downChannel()
321 {
322   if (currentChannel == 0) // at the start
323     return chanList->size() - 1; // so go to end
324   else
325     return currentChannel - 1;
326 }
327
328 UINT VVideoLive::channelIndexFromNumber(int number)
329 {
330   for(UINT i = 0; i < chanList->size(); i++)
331   {
332     if ((*chanList)[i]->number == (UINT)number) return i;
333   }
334   return 0;
335 }
336
337 UINT VVideoLive::getCurrentChannelIndex()
338 {
339   return channelIndexFromNumber(currentChannel);
340 }
341
342 void VVideoLive::showEPG()
343 {
344   if (unavailable) showUnavailable(0);
345   vepg = new VEpg(this, currentChannel);
346   ViewMan::getInstance()->add(vepg);
347   Video::getInstance()->setMode(Video::QUARTER);
348   Video::getInstance()->setPosition(170, 5); //TODO need to deal with 4:3 switching
349   vepg->draw();
350   vepg->show();
351 }
352
353 void VVideoLive::setEpgMode(bool mode)
354 {
355   epgmode = mode;
356
357   // Ok so we do need this function
358   // but FIXME improve this, integrate with live mode switching from remote
359   if (mode == FALSE)
360   {
361     Video::getInstance()->setMode(videoMode);
362   }
363 }