2
Phlips webcam INDI driver
3
Copyright (C) 2003-2005 by Jasem Mutlaq
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Lesser General Public
7
License as published by the Free Software Foundation; either
8
version 2.1 of the License, or (at your option) any later version.
10
This library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Lesser General Public License for more details.
15
You should have received a copy of the GNU Lesser General Public
16
License along with this library; if not, write to the Free Software
17
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
2005.04.29 JM: There is no need for this file for Video 4 Linux 2. It is kept for V4L 1 compatibility.
23
#include "v4lphilips.h"
24
#include "webcam/pwc-ioctl.h"
26
V4L_Philips::V4L_Philips() : V4L_Driver()
31
V4L_Philips::~V4L_Philips()
36
void V4L_Philips::initCamBase()
38
#ifdef HAVE_LINUX_VIDEODEV2_H
39
v4l_base = new V4L2_Base();
41
v4l_pwc = new V4L1_PWC();
42
v4l_base = (V4L1_Base *) v4l_pwc;
46
void V4L_Philips::initProperties(const char *dev)
50
V4L_Driver::initProperties(dev);
52
IUFillSwitch(&BackLightS[0], "ON", "", ISS_OFF);
53
IUFillSwitch(&BackLightS[1], "OFF", "", ISS_ON);
54
IUFillSwitchVector(&BackLightSP, BackLightS, NARRAY(BackLightS), dev, "Back Light", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0 , IPS_IDLE);
56
IUFillSwitch(&AntiFlickerS[0], "ON", "", ISS_OFF);
57
IUFillSwitch(&AntiFlickerS[1], "OFF", "", ISS_ON);
58
IUFillSwitchVector(&AntiFlickerSP, AntiFlickerS, NARRAY(AntiFlickerS), dev, "Anti Flicker", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0 , IPS_IDLE);
60
IUFillSwitch(&NoiseReductionS[0], "None", "", ISS_ON);
61
IUFillSwitch(&NoiseReductionS[1], "Low", "", ISS_OFF);
62
IUFillSwitch(&NoiseReductionS[2], "Medium", "", ISS_OFF);
63
IUFillSwitch(&NoiseReductionS[3], "High", "", ISS_OFF);
64
IUFillSwitchVector(&NoiseReductionSP, NoiseReductionS, NARRAY(NoiseReductionS), dev, "Noise Reduction", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
66
IUFillSwitch(&CamSettingS[0], "Save", "", ISS_OFF);
67
IUFillSwitch(&CamSettingS[1], "Restore", "", ISS_OFF);
68
IUFillSwitch(&CamSettingS[2], "Factory", "", ISS_OFF);
69
IUFillSwitchVector(&CamSettingSP, CamSettingS, NARRAY(CamSettingS), dev, "Settings", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
71
IUFillSwitch(&WhiteBalanceModeS[0], "Auto" , "", ISS_ON);
72
IUFillSwitch(&WhiteBalanceModeS[1], "Manual" , "", ISS_OFF);
73
IUFillSwitch(&WhiteBalanceModeS[2], "Indoor" , "", ISS_OFF);
74
IUFillSwitch(&WhiteBalanceModeS[3], "Outdoor" , "", ISS_OFF);
75
IUFillSwitch(&WhiteBalanceModeS[4], "Fluorescent" , "", ISS_OFF);
77
IUFillSwitchVector(&WhiteBalanceModeSP, WhiteBalanceModeS, NARRAY(WhiteBalanceModeS), dev, "White Balance Mode", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
79
IUFillNumber(&WhiteBalanceN[0], "Manual Red", "", "%0.f", 0., 256., 1., 0.);
80
IUFillNumber(&WhiteBalanceN[1], "Manual Blue", "", "%0.f", 0., 256., 1., 0.);
81
IUFillNumberVector(&WhiteBalanceNP, WhiteBalanceN, NARRAY(WhiteBalanceN), dev, "White Balance", "", IMAGE_CONTROL, IP_RW, 60, IPS_IDLE);
83
IUFillNumber(&ShutterSpeedN[0], "Speed", "", "%0.f", 0., 65535., 100., 0.);
84
IUFillNumberVector(&ShutterSpeedNP, ShutterSpeedN, NARRAY(ShutterSpeedN), dev, "Shutter Speed", "", COMM_GROUP, IP_RW, 60, IPS_IDLE);
88
void V4L_Philips::ISGetProperties (const char *dev)
91
if (dev && strcmp (device_name, dev))
94
#ifdef HAVE_LINUX_VIDEODEV2_H
95
V4L_Driver::ISGetProperties(dev);
100
IDDefSwitch(&PowerSP, NULL);
101
IDDefText(&PortTP, NULL);
102
IDDefText(&camNameTP, NULL);
103
IDDefSwitch(&StreamSP, NULL);
104
IDDefNumber(&FrameRateNP, NULL);
105
IDDefNumber(&ExposeTimeNP, NULL);
106
IDDefNumber(&ShutterSpeedNP, NULL);
107
IDDefBLOB(&imageBP, NULL);
110
IDDefSwitch(&CompressSP, NULL);
111
IDDefSwitch(&ImageTypeSP, NULL);
112
IDDefNumber(&FrameNP, NULL);
113
IDDefNumber(&ImageAdjustNP, NULL);
116
IDDefSwitch(&WhiteBalanceModeSP, NULL);
117
IDDefNumber(&WhiteBalanceNP, NULL);
118
IDDefSwitch(&BackLightSP, NULL);
119
IDDefSwitch(&AntiFlickerSP, NULL);
120
IDDefSwitch(&NoiseReductionSP, NULL);
121
IDDefSwitch(&CamSettingSP, NULL);
125
void V4L_Philips::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
127
/* ignore if not ours */
128
if (dev && strcmp (device_name, dev))
132
if (!strcmp (name, PowerSP.name))
134
IUResetSwitch(&PowerSP);
135
IUUpdateSwitch(&PowerSP, states, names, n);
141
#ifndef HAVE_LINUX_VIDEODEV2_H
142
/* Anti Flicker control */
143
if (!strcmp (AntiFlickerSP.name, name))
145
if (checkPowerS(&AntiFlickerSP))
148
AntiFlickerSP.s = IPS_IDLE;
150
IUResetSwitch(&AntiFlickerSP);
151
IUUpdateSwitch(&AntiFlickerSP, states, names, n);
153
if (AntiFlickerS[0].s == ISS_ON)
155
if (v4l_pwc->setFlicker(true, errmsg) < 0)
157
AntiFlickerS[0].s = ISS_OFF;
158
AntiFlickerS[1].s = ISS_ON;
159
IDSetSwitch(&AntiFlickerSP, "%s", errmsg);
163
AntiFlickerSP.s = IPS_OK;
164
IDSetSwitch(&AntiFlickerSP, NULL);
168
if (v4l_pwc->setFlicker(false, errmsg) < 0)
170
AntiFlickerS[0].s = ISS_ON;
171
AntiFlickerS[1].s = ISS_OFF;
172
IDSetSwitch(&AntiFlickerSP, "%s", errmsg);
176
IDSetSwitch(&AntiFlickerSP, NULL);
182
/* Back light compensation */
183
if (!strcmp (BackLightSP.name, name))
185
if (checkPowerS(&BackLightSP))
188
BackLightSP.s = IPS_IDLE;
190
IUResetSwitch(&BackLightSP);
191
IUUpdateSwitch(&BackLightSP, states, names, n);
193
if (BackLightS[0].s == ISS_ON)
195
if (v4l_pwc->setBackLight(true, errmsg) < 0)
197
BackLightS[0].s = ISS_OFF;
198
BackLightS[1].s = ISS_ON;
199
IDSetSwitch(&BackLightSP, "%s", errmsg);
203
BackLightSP.s = IPS_OK;
204
IDSetSwitch(&BackLightSP, NULL);
208
if (v4l_pwc->setBackLight(false, errmsg) < 0)
210
BackLightS[0].s = ISS_ON;
211
BackLightS[1].s = ISS_OFF;
212
IDSetSwitch(&BackLightSP, "%s", errmsg);
216
IDSetSwitch(&BackLightSP, NULL);
222
/* Noise reduction control */
223
if (!strcmp (NoiseReductionSP.name, name))
225
if (checkPowerS(&NoiseReductionSP))
228
NoiseReductionSP.s = IPS_IDLE;
230
IUResetSwitch(&NoiseReductionSP);
231
IUUpdateSwitch(&NoiseReductionSP, states, names, n);
233
for (int i=0; i < 4; i++)
234
if (NoiseReductionS[i].s == ISS_ON)
240
if (v4l_pwc->setNoiseRemoval(index, errmsg) < 0)
242
IUResetSwitch(&NoiseReductionSP);
243
NoiseReductionS[0].s = ISS_ON;
244
IDSetSwitch(&NoiseReductionSP, "%s", errmsg);
248
NoiseReductionSP.s = IPS_OK;
250
IDSetSwitch(&NoiseReductionSP, NULL);
254
/* White balace mode */
255
if (!strcmp (WhiteBalanceModeSP.name, name))
257
if (checkPowerS(&WhiteBalanceModeSP))
260
WhiteBalanceModeSP.s = IPS_IDLE;
262
IUResetSwitch(&WhiteBalanceModeSP);
263
IUUpdateSwitch(&WhiteBalanceModeSP, states, names, n);
265
for (int i=0; i < 5; i++)
266
if (WhiteBalanceModeS[i].s == ISS_ON)
276
if (v4l_pwc->setWhiteBalanceMode(PWC_WB_AUTO, errmsg) < 0)
278
IUResetSwitch(&WhiteBalanceModeSP),
279
WhiteBalanceModeS[0].s = ISS_ON;
280
IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg);
287
if (v4l_pwc->setWhiteBalanceMode(PWC_WB_MANUAL, errmsg) < 0)
289
IUResetSwitch(&WhiteBalanceModeSP),
290
WhiteBalanceModeS[0].s = ISS_ON;
291
IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg);
298
if (v4l_pwc->setWhiteBalanceMode(PWC_WB_INDOOR, errmsg) < 0)
300
IUResetSwitch(&WhiteBalanceModeSP),
301
WhiteBalanceModeS[0].s = ISS_ON;
302
IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg);
309
if (v4l_pwc->setWhiteBalanceMode(PWC_WB_OUTDOOR, errmsg) < 0)
311
IUResetSwitch(&WhiteBalanceModeSP),
312
WhiteBalanceModeS[0].s = ISS_ON;
313
IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg);
320
if (v4l_pwc->setWhiteBalanceMode(PWC_WB_FL, errmsg) < 0)
322
IUResetSwitch(&WhiteBalanceModeSP),
323
WhiteBalanceModeS[0].s = ISS_ON;
324
IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg);
331
WhiteBalanceModeSP.s = IPS_OK;
332
IDSetSwitch(&WhiteBalanceModeSP, NULL);
337
/* Camera setttings */
338
if (!strcmp (CamSettingSP.name, name))
341
if (checkPowerS(&CamSettingSP))
344
CamSettingSP.s = IPS_IDLE;
346
IUResetSwitch(&CamSettingSP);
347
IUUpdateSwitch(&CamSettingSP, states, names, n);
349
if (CamSettingS[0].s == ISS_ON)
351
if (v4l_pwc->saveSettings(errmsg) < 0)
353
IUResetSwitch(&CamSettingSP);
354
IDSetSwitch(&CamSettingSP, "%s", errmsg);
358
CamSettingSP.s = IPS_OK;
359
IDSetSwitch(&CamSettingSP, "Settings saved.");
363
if (CamSettingS[1].s == ISS_ON)
365
v4l_pwc->restoreSettings();
366
IUResetSwitch(&CamSettingSP);
367
CamSettingSP.s = IPS_OK;
368
IDSetSwitch(&CamSettingSP, "Settings restored.");
369
updateV4L1Controls();
373
if (CamSettingS[2].s == ISS_ON)
375
v4l_pwc->restoreFactorySettings();
376
IUResetSwitch(&CamSettingSP);
377
CamSettingSP.s = IPS_OK;
378
IDSetSwitch(&CamSettingSP, "Factory settings restored.");
379
updateV4L1Controls();
386
V4L_Driver::ISNewSwitch(dev, name, states, names, n);
392
void V4L_Philips::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
395
V4L_Driver::ISNewText(dev, name, texts, names, n);
399
void V4L_Philips::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
402
// Nothing for V4L 2 to do here
403
#ifndef HAVE_LINUX_VIDEODEV2_H
404
char errmsg[ERRMSGSIZ];
407
if (!strcmp (FrameRateNP.name, name))
409
if (checkPowerN(&FrameRateNP))
412
FrameRateNP.s = IPS_IDLE;
414
int oldFP = (int) FrameRateN[0].value;
416
if (IUUpdateNumber(&FrameRateNP, values, names, n) < 0)
419
if (v4l_pwc->setFrameRate( (int) FrameRateN[0].value, errmsg) < 0)
421
FrameRateN[0].value = oldFP;
422
IDSetNumber(&FrameRateNP, "%s", errmsg);
426
FrameRateNP.s = IPS_OK;
427
IDSetNumber(&FrameRateNP, NULL);
431
if (!strcmp (ShutterSpeedNP.name, name))
433
if (checkPowerN(&ShutterSpeedNP))
436
ShutterSpeedNP.s = IPS_IDLE;
438
if (v4l_pwc->setExposure( (int) values[0], errmsg) < 0)
440
IDSetNumber(&ShutterSpeedNP, "%s", errmsg);
444
ShutterSpeedN[0].value = values[0];
445
ShutterSpeedNP.s = IPS_OK;
446
IDSetNumber(&ShutterSpeedNP, NULL);
451
if (!strcmp (WhiteBalanceNP.name, name))
453
if (checkPowerN(&WhiteBalanceNP))
456
WhiteBalanceNP.s = IPS_IDLE;
459
oldBalance[0] = (int) WhiteBalanceN[0].value;
460
oldBalance[1] = (int) WhiteBalanceN[1].value;
462
if (IUUpdateNumber(&WhiteBalanceNP, values, names, n) < 0)
465
if (v4l_pwc->setWhiteBalanceRed( (int) WhiteBalanceN[0].value * 256, errmsg))
467
WhiteBalanceN[0].value = oldBalance[0];
468
WhiteBalanceN[1].value = oldBalance[1];
469
IDSetNumber(&WhiteBalanceNP, "%s", errmsg);
472
if (v4l_pwc->setWhiteBalanceBlue( (int) WhiteBalanceN[1].value * 256, errmsg))
474
WhiteBalanceN[0].value = oldBalance[0];
475
WhiteBalanceN[1].value = oldBalance[1];
476
IDSetNumber(&WhiteBalanceNP, "%s", errmsg);
480
IUResetSwitch(&WhiteBalanceModeSP);
481
WhiteBalanceModeS[1].s = ISS_ON;
482
WhiteBalanceModeSP.s = IPS_OK;
483
WhiteBalanceNP.s = IPS_OK;
484
IDSetSwitch(&WhiteBalanceModeSP, NULL);
485
IDSetNumber(&WhiteBalanceNP, NULL);
492
V4L_Driver::ISNewNumber(dev, name, values, names, n);
496
void V4L_Philips::connectCamera()
498
char errmsg[ERRMSGSIZ];
504
#ifdef HAVE_LINUX_VIDEODEV2_H
505
if (v4l_base->connectCam(PortT[0].text, errmsg, V4L2_PIX_FMT_YUV420) < 0)
507
if (v4l_base->connectCam(PortT[0].text, errmsg) < 0)
510
PowerSP.s = IPS_IDLE;
511
PowerS[0].s = ISS_OFF;
512
PowerS[1].s = ISS_ON;
513
IDSetSwitch(&PowerSP, "Error: unable to open device");
514
IDLog("Error: %s\n", errmsg);
519
PowerS[0].s = ISS_ON;
520
PowerS[1].s = ISS_OFF;
522
IDSetSwitch(&PowerSP, "Philips Webcam is online. Retrieving basic data.");
524
v4l_base->registerCallback(newFrame, this);
526
IDLog("Philips Webcam is online. Retrieving basic data.\n");
532
PowerS[0].s = ISS_OFF;
533
PowerS[1].s = ISS_ON;
534
PowerSP.s = IPS_IDLE;
536
v4l_base->disconnectCam();
538
IDSetSwitch(&PowerSP, "Philips Webcam is offline.");
544
#ifndef HAVE_LINUX_VIDEODEV2_H
545
/* Retrieves basic data from the device upon connection.*/
546
void V4L_Philips::getBasicData()
549
char errmsg[ERRMSGSIZ];
551
int xmax, ymax, xmin, ymin, index;
553
v4l_pwc->getMaxMinSize(xmax, ymax, xmin, ymin);
555
IDLog("X (%d,%d), Y (%d,%d)\n", xmin, xmax, ymin, ymax);
558
FrameN[2].value = v4l_pwc->getWidth();
559
FrameN[2].min = xmin;
560
FrameN[2].max = xmax;
563
FrameN[3].value = v4l_pwc->getHeight();
564
FrameN[3].min = ymin;
565
FrameN[3].max = ymax;
567
IDSetNumber(&FrameNP, NULL);
568
IUUpdateMinMax(&FrameNP);
570
IUSaveText(&camNameT[0], v4l_pwc->getDeviceName());
571
IDSetText(&camNameTP, NULL);
573
IDLog("Raw values\n Contrast: %d \n Brightness %d \n Color %d \n Sharpness %d \n Gain %d \n Gamma %d \n", v4l_pwc->getContrast(), v4l_pwc->getBrightness(), v4l_pwc->getColor(), v4l_pwc->getSharpness(), v4l_pwc->getGain(), v4l_pwc->getGama());
575
updateV4L1Controls();
577
if (v4l_pwc->setFrameRate( (int) FrameRateN[0].value, errmsg) < 0)
579
FrameRateNP.s = IPS_ALERT;
580
IDSetNumber(&FrameRateNP, "%s", errmsg);
584
FrameRateNP.s = IPS_OK;
585
IDSetNumber(&FrameRateNP, NULL);
588
result = v4l_pwc->getBackLight();
591
BackLightS[0].s = ISS_ON;
592
BackLightS[1].s = ISS_OFF;
596
BackLightS[0].s = ISS_OFF;
597
BackLightS[1].s = ISS_ON;
599
IDSetSwitch(&BackLightSP, NULL);
601
result = v4l_pwc->getFlicker();
604
AntiFlickerS[0].s = ISS_ON;
605
AntiFlickerS[1].s = ISS_OFF;
609
AntiFlickerS[0].s = ISS_OFF;
610
AntiFlickerS[1].s = ISS_ON;
612
IDSetSwitch(&AntiFlickerSP, NULL);
614
index = v4l_pwc->getNoiseRemoval();
615
IUResetSwitch(&NoiseReductionSP);
616
NoiseReductionS[index].s = ISS_ON;
617
IDSetSwitch(&NoiseReductionSP, NULL);
619
index = v4l_pwc->getWhiteBalance();
620
IUResetSwitch(&WhiteBalanceModeSP);
624
WhiteBalanceModeS[0].s = ISS_ON;
627
WhiteBalanceModeS[1].s = ISS_ON;
630
WhiteBalanceModeS[2].s = ISS_ON;
633
WhiteBalanceModeS[3].s = ISS_ON;
636
WhiteBalanceModeS[3].s = ISS_ON;
639
IDSetSwitch(&WhiteBalanceModeSP, NULL);
644
#ifndef HAVE_LINUX_VIDEODEV2_H
645
void V4L_Philips::updateV4L1Controls()
649
ImageAdjustN[0].value = v4l_pwc->getContrast() / 256.;
650
ImageAdjustN[1].value = v4l_pwc->getBrightness() / 256.;
651
ImageAdjustN[2].value = v4l_pwc->getColor() / 256.;
652
index = v4l_pwc->getSharpness();
654
ImageAdjustN[3].value = -1;
656
ImageAdjustN[3].value = v4l_pwc->getSharpness() / 256.;
658
ImageAdjustN[4].value = v4l_pwc->getGain() / 256.;
659
ImageAdjustN[5].value = v4l_pwc->getGama() / 256.;
661
ImageAdjustNP.s = IPS_OK;
662
IDSetNumber(&ImageAdjustNP, NULL);