]> git.vomp.tv Git - vompclient.git/blob - vvideolive.cc
Widescreen support, segfault fix on livetv interrupt
[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   unavailable = 0;
33   unavailableView = NULL;
34   streamType = tstreamType;
35   if (streamType == VDR::VIDEO)
36   {
37     player = new PlayerVideo(Command::getInstance(), 0);
38   }
39   else
40   {
41     player = new PlayerRadio();
42   }
43   player->init();
44
45   Video* video = Video::getInstance();
46   setDimensions(video->getScreenWidth(), video->getScreenHeight());
47   Colour transparent(0, 0, 0, 0);
48   setBackgroundColour(transparent);
49 }
50
51 VVideoLive::~VVideoLive()
52 {
53   delete player;
54   instance = NULL;
55 }
56
57 VVideoLive* VVideoLive::getInstance()
58 {
59   return instance;
60 }
61
62 void VVideoLive::draw()
63 {
64   View::draw();
65 }
66
67 int VVideoLive::handleCommand(int command)
68 {
69   switch(command)
70   {
71     case Remote::PLAY:
72     {
73       if (!unavailable) player->play(); // do resync
74       return 2;
75     }
76
77     case Remote::STOP:
78     case Remote::BACK:
79     case Remote::MENU:
80     {
81       if (unavailable) showUnavailable(0);
82       else stop();
83       return 4;
84     }
85     case Remote::DF_UP:
86     case Remote::CHANNELUP:
87     {
88       if (unavailable) showUnavailable(0);
89       else stop();
90       upChannel();
91       play();
92       return 2;
93     }
94     case Remote::DF_DOWN:
95     case Remote::CHANNELDOWN:
96     {
97       if (unavailable) showUnavailable(0);
98       else stop();
99       downChannel();
100       play();
101       return 2;
102     }
103     case Remote::OK:
104     {
105       doBanner();
106       return 2;
107     }
108
109     case Remote::ZERO ... Remote::NINE:
110     {
111       VChannelSelect* v = new VChannelSelect(this, command);
112       viewman->addNoLock(v);
113 //      ViewMan::getInstance()->timedDelete(v, 4, 0);
114       v->draw();
115       v->show();
116     }
117   }
118
119   return 1;
120 }
121
122 void VVideoLive::processMessage(Message* m)
123 {
124   if (m->message == Message::CHANNEL_CHANGE)
125   {
126     // check channel number is valid
127     currentChannel = channelIndexFromNumber(m->parameter);
128     if (unavailable) showUnavailable(0);
129     else stop();
130     play();
131   }
132   else if (m->message == Message::CHANNEL_UP)
133   {
134     // from vlivebanner
135     if (unavailable) showUnavailable(0);
136     else stop(1);
137     upChannel();
138     play(1);
139     vlb->setChannel((*chanList)[currentChannel]);
140     vlb->draw();
141     vlb->show();
142   }
143   else if (m->message == Message::CHANNEL_DOWN)
144   {
145     // from vlivebanner
146     if (unavailable) showUnavailable(0);
147     else stop(1);
148     downChannel();
149     play(1);
150     vlb->setChannel((*chanList)[currentChannel]);
151     vlb->draw();
152     vlb->show();
153   }
154   else if (m->message == Message::STREAM_END)
155   {
156     Log::getInstance()->log("VVideoLive", Log::DEBUG, "streamEnd");
157     stop();
158     play(1);
159   }
160 }
161
162 void VVideoLive::doBanner()
163 {
164   vlb = new VLiveBanner(this, (*chanList)[currentChannel]);
165   viewman->timedDelete(vlb, 4, 0);
166
167   Message* m = new Message();
168   m->from = this;
169   m->to = viewman;
170   m->message = Message::ADD_VIEW;
171   m->parameter = (ULONG)vlb;
172
173   viewman->postMessage(m);
174 }
175
176 void VVideoLive::showUnavailable(int active)
177 {
178   if (active == unavailable) return;
179
180   if (active)
181   {
182     unavailable = 1;
183
184     unavailableView = new VInfo();
185     unavailableView->setDimensions(400, 200);
186     if (Video::getInstance()->getFormat() == Video::PAL)
187     {
188       unavailableView->setScreenPos(170, 200);
189     }
190     else
191     {
192       unavailableView->setScreenPos(160, 150);
193     }
194     unavailableView->setTitleText((*chanList)[currentChannel]->name);
195     unavailableView->setMainText("\n                    Channel unavailable");
196     unavailableView->setDropThrough();
197
198     Message* m = new Message();
199     m->from = this;
200     m->to = viewman;
201     m->message = Message::ADD_VIEW;
202     m->parameter = (ULONG)unavailableView;
203
204     viewman->postMessage(m);
205   }
206   else
207   {
208     unavailable = 0;
209     ViewMan::getInstance()->removeView(unavailableView, 1);
210     unavailableView = NULL;
211   }
212 }
213
214 void VVideoLive::setChannel(int number)
215 {
216   currentChannel = channelIndexFromNumber(number);
217   play();
218 }
219
220 void VVideoLive::play(int noShowVLB)
221 {
222   showUnavailable(0);
223
224   int available = vdr->streamChannel((*chanList)[currentChannel]->number);
225
226   if (!available)
227   {
228     showUnavailable(1);
229     if (!noShowVLB) doBanner();
230   }
231   else
232   {
233     if (!noShowVLB) doBanner();
234     player->play();
235   }
236 }
237
238 void VVideoLive::stop(int noRemoveVLB)
239 {
240   if (unavailable) return;
241   if (!noRemoveVLB) viewman->removeView(vlb, 1, 1); // if live banner is present, remove it. won't cause damage if its not present
242
243   player->stop();
244   vdr->stopStreaming();
245 }
246
247 int VVideoLive::upChannel()
248 {
249   if (currentChannel == (chanList->size() - 1)) return 0; // at the end
250
251   ++currentChannel;
252   return 1;
253 }
254
255 int VVideoLive::downChannel()
256 {
257   if (currentChannel == 0) return 0; // at the start
258
259   --currentChannel;
260   return 1;
261 }
262
263 UINT VVideoLive::channelIndexFromNumber(int number)
264 {
265   for(UINT i = 0; i < chanList->size(); i++)
266   {
267     if ((*chanList)[i]->number == (UINT)number) return i;
268   }
269   return 0;
270 }
271