]> git.vomp.tv Git - vompclient-marten.git/blob - vaudioselector.cc
Demuxer changes/fixes/improvements
[vompclient-marten.git] / vaudioselector.cc
1 /*
2     Copyright 2006 Chris Tallon, Marten Richter
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 "vaudioselector.h"
22
23 #include "remote.h"
24 #include "colour.h"
25 #include "video.h"
26 #include "boxstack.h"
27 #include "i18n.h"
28 #include "message.h"
29 #include "command.h"
30 #include "recinfo.h"
31 #include "log.h"
32 #include "channel.h"
33
34 VAudioSelector::VAudioSelector(void* tparent, bool* availableMpegAudioChannels,
35         bool* availableAc3AudioChannels, int currentAudioChannel, RecInfo* recInfo)
36 {
37   Log::getInstance()->log("VAS", Log::DEBUG, "%i", currentAudioChannel);
38
39   parent = tparent;
40
41   liveMode = false;
42
43   setSize(200, 120);
44   createBuffer();
45
46   sl.setPosition(40, 30);
47   sl.setSize(area.w - 45, area.h - 30);
48   add(&sl);
49
50   // Load data from availableAudioChannels, currentAudioChannel and recInfo
51
52   int i;
53
54   for (i = 0; i < PES_AUDIO_MAXCHANNELS; i++)
55   {
56     if (availableMpegAudioChannels[i])
57     {
58       AudioChannel* ac = new AudioChannel();
59       ac->type = 0;
60       ac->name = NULL;
61       ac->pestype = PES_AUDIO_START + i;
62       acl.push_back(ac);
63     }
64   }
65   if (availableAc3AudioChannels != NULL)
66   {
67     for (i = 0; i < PES_AUDIO_AC3_MAXCHANNELS; i++)
68     {
69       if (availableAc3AudioChannels[i])
70       {
71         AudioChannel* ac = new AudioChannel();
72         ac->type = 1;//ac3
73         ac->name = NULL;
74         ac->pestype = PES_AUDIO_AC3_START + i;
75         acl.push_back(ac);
76       }
77     }
78   }
79
80   unsigned char numchan_recinfo = recInfo->numComponents;
81   unsigned char numchan_siz = acl.size();
82   int mp_audcounter = 0;
83   int ac3_counter = 0;
84   int ac3_offset = 0;
85
86   for (i = 0; i < numchan_siz; i++)
87   {
88     AudioChannel* ac = acl[i];
89     if (ac)
90     {
91       if (ac->type==0)
92       {
93         ac3_offset++;
94       }
95     }
96   }
97
98   unsigned char type;
99   char* lang;
100   char* description;
101   int type_int;
102
103   for (i = 0; i < numchan_recinfo; i++)
104   {
105     if (recInfo->streams[i] != 2) continue; //not an audio component
106     type = recInfo->types[i];
107     lang = recInfo->languages[i];
108     description = recInfo->descriptions[i];
109     AudioChannel* ac = NULL;
110     type_int = 0;
111
112     switch (type)
113     {
114       case 1: //mpaudio mono
115       case 3: //mpaudio stereo
116         if (mp_audcounter < numchan_siz) ac = acl[mp_audcounter];
117         type_int = 0;
118         break;
119       case 5: //ac3
120         if (ac3_counter + ac3_offset < numchan_siz) ac = acl[ac3_counter + ac3_offset];
121         type_int = 1;
122         break;
123     }
124
125     if (ac)
126     {
127       if (ac->type == type_int)
128       {
129         if (description && (strlen(description) > 0))
130         {
131           ac->name = new char[strlen(description)+1];
132           strcpy(ac->name, description);
133         }
134         else if (lang && (strlen(lang) > 0))
135         {
136           ac->name = new char[strlen(lang)+1];
137           strcpy(ac->name, lang);
138         }
139       }
140     }
141
142     switch (type_int)
143     {
144       case 0: //mpaudio
145         mp_audcounter++;
146         break;
147       case 1: //ac3
148         ac3_counter++;
149         break;
150     }
151   }
152
153   // Now do display
154
155   char tempString[300];
156   int audioChannelListSize = acl.size();
157
158   if (audioChannelListSize)
159   {
160     for(i = 0; i < audioChannelListSize; i++)
161     {
162       AudioChannel* ac = acl[i];
163
164       if (ac->name)
165       {
166         sl.addOption(ac->name, (ULONG)ac, (ac->pestype == currentAudioChannel));
167       }
168       else
169       {
170         if (ac->type==0)
171         {
172           SNPRINTF(tempString, 299, "%lu", (ULONG)(ac->pestype - PES_AUDIO_START));
173         }
174         else if (ac->type==1)
175         {
176           SNPRINTF(tempString, 299, "ac3 %lu", (ULONG)(ac->pestype - PES_AUDIO_AC3_START));
177         }
178         else
179         {
180           SNPRINTF(tempString, 299, "unknown");
181         }
182         sl.addOption(tempString, (ULONG)ac, (ac->pestype == currentAudioChannel));
183       }
184     }
185   }
186   else
187   {
188     sl.addOption(tr("No audio channel data available"), 0, 1);
189   }
190 }
191
192 VAudioSelector::VAudioSelector(void* tparent, Channel* channel, int currentAudioChannel)
193 {
194   parent = tparent;
195
196   liveMode = true;
197
198   setSize(200, 120);
199   createBuffer();
200
201   sl.setPosition(40, 30);
202   sl.setSize(area.w - 45, area.h - 30);
203   add(&sl);
204
205   // Load data from availableAudioChannels, currentAudioChannel and recInfo
206
207   for (UINT i = 0; i < channel->numAPids; i++)
208   {
209     AudioChannel* ac = new AudioChannel();
210     ac->type = 0;
211     ac->name = new char[strlen(channel->apids[i].name) + 1];
212     strcpy(ac->name, channel->apids[i].name);
213     ac->pestype = channel->apids[i].pid;
214     acl.push_back(ac);
215   }
216     
217   int audioChannelListSize = acl.size();
218
219   if (audioChannelListSize)
220   {
221     for(int i = 0; i < audioChannelListSize; i++)
222     {
223       AudioChannel* ac = acl[i];
224       sl.addOption(ac->name, (ULONG)ac, (ac->pestype == currentAudioChannel));
225     }
226   }
227   else
228   {
229     sl.addOption(tr("No audio channel data available"), 0, 1);
230   }
231 }
232
233 VAudioSelector::~VAudioSelector()
234 {
235   int audioChannelListSize = acl.size();
236   for(int i = 0; i < audioChannelListSize; i++)
237   {
238     delete acl[i]; // FIXME memory leak - nobody is deleting audio channel name?
239   }
240   acl.clear();
241
242   sl.clear();
243
244   Message* m = new Message();
245   m->from = this;
246   m->to = parent;
247   m->message = Message::CHILD_CLOSE;
248   Command::getInstance()->postMessageNoLock(m);
249 }
250
251 void VAudioSelector::draw()
252 {
253   TBBoxx::draw();
254   
255   // FIXME bad drawing
256   
257   rectangle(0, 0, area.w, 30, Colour::TITLEBARBACKGROUND);
258   drawText(tr("Audio"), 45, 5, Colour::LIGHTTEXT);
259
260   sl.setBackgroundColour(backgroundColour);
261   sl.draw();
262 }
263
264 int VAudioSelector::handleCommand(int command)
265 {
266   switch (command)
267   {
268     case Remote::BACK:
269     case Remote::OK:
270     case Remote::GREEN:
271     {
272       return 4;
273     }
274     case Remote::DF_UP:
275     case Remote::UP:
276     {
277       sl.up();
278       sl.draw();
279
280       BoxStack::getInstance()->update(this);
281
282       Message* m = new Message();
283       m->from = this;
284       m->to = parent;
285       m->message = Message::AUDIO_CHANGE_CHANNEL;
286       m->parameter = ((AudioChannel*)sl.getCurrentOptionData())->pestype;
287       Command::getInstance()->postMessageNoLock(m);
288
289       return 2;
290     }
291     case Remote::DF_DOWN:
292     case Remote::DOWN:
293     {
294       sl.down();
295       sl.draw();
296
297       BoxStack::getInstance()->update(this);
298
299       Message* m = new Message();
300       m->from = this;
301       m->to = parent;
302       m->message = Message::AUDIO_CHANGE_CHANNEL;
303       m->parameter = ((AudioChannel*)sl.getCurrentOptionData())->pestype;
304       Command::getInstance()->postMessageNoLock(m);
305
306       return 2;
307     }
308   }
309
310   return 0;
311 }
312
313 void VAudioSelector::processMessage(Message* m)
314 {
315   if (m->message == Message::MOUSE_MOVE)
316   {
317     if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
318     {
319       sl.draw();
320       BoxStack::getInstance()->update(this);
321     }
322   }
323   else if (m->message == Message::MOUSE_LBDOWN)
324   {
325     if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY()))
326     {
327       BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press
328     }
329     else
330     { //check if press is outside this view! then simulate cancel
331       int x=(m->parameter>>16)-getScreenX();
332       int y=(m->parameter&0xFFFF)-getScreenY();
333       if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight())
334       {
335         BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press
336       }
337     }
338   }
339 }