]> git.vomp.tv Git - vompclient.git/blob - videomvp.cc
Windows port
[vompclient.git] / videomvp.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 "videomvp.h"
22
23 VideoMVP::VideoMVP()
24 {
25   if (instance) return;
26 }
27
28 VideoMVP::~VideoMVP()
29 {
30   instance = NULL;
31 }
32
33 int VideoMVP::init(UCHAR tformat)
34 {
35   if (initted) return 0;
36   initted = 1;
37
38   if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
39
40   if (!setFormat(tformat))           { shutdown(); return 0; }
41   if (!setConnection(COMPOSITERGB))  { shutdown(); return 0; }
42   if (!setAspectRatio(ASPECT4X3))    { shutdown(); return 0; }
43   if (!setMode(NORMAL))              { shutdown(); return 0; }
44   if (!setSource())                  { shutdown(); return 0; }
45   if (!attachFrameBuffer())          { shutdown(); return 0; }
46
47   setTVsize(ASPECT4X3);
48
49   if (format == PAL) setLetterboxBorder("38");
50   else setLetterboxBorder("31");
51
52   stop();
53
54
55   return 1;
56 }
57
58 void VideoMVP::setLetterboxBorder(char* border)
59 {
60   FILE* fdlbox = fopen("/proc/lbox_border", "w");
61   if (!fdlbox) return;
62   fputs(border, fdlbox);
63   fclose(fdlbox);
64 }
65
66 int VideoMVP::setTVsize(UCHAR ttvsize)
67 {
68   tvsize = ttvsize;
69
70   // Override the aspect ratio usage, temporarily use to set the video chip mode
71   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
72   close(fdVideo);
73   if ((fdVideo = open("/dev/vdec_dev", O_WRONLY)) < 0) return 0;
74   if (!setSource())                  { shutdown(); return 0; }
75   if (!attachFrameBuffer())          { shutdown(); return 0; }
76
77   // Reopening the fd causes the scart aspect line to go back to 4:3
78   // Set this again to the same as the tv screen size
79   if (!setAspectRatio(tvsize))       { shutdown(); return 0; }
80
81   // mode == LETTERBOX is invalid if the TV is widescreen
82   if (tvsize == ASPECT16X9) setMode(NORMAL);
83
84   return 1;
85 }
86
87 int VideoMVP::setDefaultAspect()
88 {
89   return setAspectRatio(tvsize);
90 }
91
92 int VideoMVP::shutdown()
93 {
94   if (!initted) return 0;
95   initted = 0;
96   close(fdVideo);
97   return 1;
98 }
99
100 int VideoMVP::checkSCART()
101 {
102   // Returns 3 for SCART Composite out
103   // Returns 3 for SCART S-Video out
104   // Returns 2 for SCART RGB out
105   // Returns 3 for SCART not plugged in
106
107   // So, as you can have RGB and composite out simultaneously,
108   // and it can't detect S-Video, what is the point of this?
109
110   int scart;
111   if (ioctl(fdVideo, AV_CHK_SCART, &scart) != 0) return -10;
112
113   return scart;
114 }
115
116 int VideoMVP::setFormat(UCHAR tformat)
117 {
118   if (!initted) return 0;
119   if ((tformat != PAL) && (tformat != NTSC)) return 0;
120   format = tformat;
121
122   if (ioctl(fdVideo, AV_SET_VID_DISP_FMT, format) != 0) return 0;
123
124   if (format == NTSC)
125   {
126     screenWidth = 720;
127     screenHeight = 480;
128   }
129   if (format == PAL)
130   {
131     screenWidth = 720;
132     screenHeight = 576;
133   }
134
135   return 1;
136 }
137
138 int VideoMVP::setConnection(UCHAR tconnection)
139 {
140   if (!initted) return 0;
141   if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
142   connection = tconnection;
143
144   if (ioctl(fdVideo, AV_SET_VID_OUTPUT, connection) != 0) return 0;
145   return 1;
146 }
147
148 int VideoMVP::setAspectRatio(UCHAR taspectRatio)
149 {
150   if (!initted) return 0;
151   if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
152   aspectRatio = taspectRatio;
153
154   if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
155   return 1;
156 }
157
158 int VideoMVP::setMode(UCHAR tmode)
159 {
160   if (!initted) return 0;
161
162   if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
163
164   if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
165       && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
166   mode = tmode;
167
168   if (ioctl(fdVideo, AV_SET_VID_MODE, mode) != 0) return 0;
169   return 1;
170 }
171
172 int VideoMVP::signalOff()
173 {
174   if (ioctl(fdVideo, AV_SET_VID_DENC, 0) != 0) return 0;
175   return 1;
176 }
177
178 int VideoMVP::signalOn()
179 {
180   if (ioctl(fdVideo, AV_SET_VID_DENC, 1) != 0) return 0;
181   return 1;
182 }
183
184 int VideoMVP::setSource()
185 {
186   if (!initted) return 0;
187
188   // What does this do...
189   if (ioctl(fdVideo, AV_SET_VID_SRC, 1) != 0) return 0;
190   return 1;
191 }
192
193 int VideoMVP::setPosition(int x, int y)
194 {
195   if (!initted) return 0;
196
197 //  vid_pos_regs_t pos_d;
198 //  pos_d.x = x;
199 //  pos_d.y = y;
200
201   vid_pos_regs_t pos_d;
202
203   memset(&pos_d, 0, sizeof(pos_d));
204
205   pos_d.dest.y = y;
206   pos_d.dest.x = x;
207 /*
208 typedef struct {
209   int w;
210   int h;
211   int scale;
212   int x1;
213   int y;
214   int x;
215   int y2;
216   int x3;
217   int y3;
218   int x4;
219   int y4;
220 } vid_pos_regs_t;
221 */
222
223 /*
224   pos_d.w = 100;
225   pos_d.h = 30;
226   pos_d.scale = 2;
227   pos_d.x1 = 0;
228   pos_d.y = 100;            // Top left X
229   pos_d.x = 50;            // Top left Y
230   pos_d.y2 = 30;
231   pos_d.x3 = 60;
232   pos_d.y3 = 90;
233   pos_d.x4 = 120;
234   pos_d.y4 = 150;
235 */
236
237   if (ioctl(fdVideo, AV_SET_VID_POSITION, &pos_d) != 0) return 0;
238   return 1;
239 }
240
241 int VideoMVP::sync()
242 {
243   if (!initted) return 0;
244
245   if (ioctl(fdVideo, AV_SET_VID_SYNC, 2) != 0) return 0;
246   return 1;
247 }
248
249 int VideoMVP::play()
250 {
251   if (!initted) return 0;
252
253   if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
254   return 1;
255 }
256
257 int VideoMVP::stop()
258 {
259   if (!initted) return 0;
260
261   if (ioctl(fdVideo, AV_SET_VID_STOP, 0) != 0) return 0;
262   return 1;
263 }
264
265 int VideoMVP::reset()
266 {
267   if (!initted) return 0;
268
269   if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0;
270   return 1;
271 }
272
273 int VideoMVP::pause()
274 {
275   if (!initted) return 0;
276
277   if (ioctl(fdVideo, AV_SET_VID_PAUSE, 0) != 0) return 0;
278   return 1;
279 }
280
281 int VideoMVP::unPause() // FIXME get rid - same as play!!
282 {
283   if (!initted) return 0;
284   if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
285   return 1;
286 }
287
288 int VideoMVP::fastForward()
289 {
290   if (!initted) return 0;
291
292   if (ioctl(fdVideo, AV_SET_VID_FFWD, 1) != 0) return 0;
293   return 1;
294 }
295
296 int VideoMVP::unFastForward()
297 {
298   if (!initted) return 0;
299
300 //  if (ioctl(fdVideo, AV_SET_VID_RESET, 0x11) != 0) return 0; // don't need this.
301
302   if (ioctl(fdVideo, AV_SET_VID_PLAY, 0) != 0) return 0;
303   return 1;
304 }
305
306 int VideoMVP::attachFrameBuffer()
307 {
308   if (!initted) return 0;
309
310   if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
311   return 1;
312 }
313
314 int VideoMVP::blank(void)
315 {
316   if (ioctl(fdVideo, AV_SET_VID_FB, 1) != 0) return 0;
317   if (ioctl(fdVideo, AV_SET_VID_FB, 0) != 0) return 0;
318   return 1;
319 }
320
321 int VideoMVP::getFD()
322 {
323   if (!initted) return 0;
324
325   return fdVideo;
326 }
327
328 ULLONG VideoMVP::getCurrentTimestamp()
329 {
330   sync_data_t timestamps;
331   if (ioctl(fdVideo, AV_GET_VID_TIMESTAMPS, &timestamps) == 0)
332   {
333     // FIXME are these the right way around?
334
335     timestamps.stc = (timestamps.stc >> 31 ) | (timestamps.stc & 1);
336     timestamps.pts = (timestamps.pts >> 31 ) | (timestamps.pts & 1);
337
338     return timestamps.stc;
339   }
340   else
341   {
342     return 0;
343   }
344 }
345
346 ULONG VideoMVP::timecodeToFrameNumber(ULLONG timecode)
347 {
348   if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
349   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
350 }
351
352 #ifdef DEV
353 int VideoMVP::test()
354 {
355   return 0;
356
357 //  ULLONG stc = 0;
358 //  return ioctl(fdVideo, AV_SET_VID_STC, &stc);
359 /*
360  // reset();
361   return 1;
362 */
363 }
364
365 int VideoMVP::test2()
366 {
367   return 0;
368 }
369 #endif