1 /*
2 * Copyright (c) 2003 by Siarzuk Zharski <imker@gmx.li>
3 *
4 * This file may be used under the terms of the BSD License
5 *
6 * Skeletal part of this code was inherired from original BeOS sample code,
7 * that is distributed under the terms of the Be Sample Code License.
8 *
9 */
10
11 #include <support/Autolock.h>
12 #include <media/MediaFormats.h>
13 #include <Drivers.h>
14
15 #include <stdio.h>
16 #include <string.h>
17 #include <unistd.h>
18
19 #include "AddOn.h"
20 #include "Producer.h"
21
22 #include "nt100x.h"
23
MediaAddOn(image_id imid)24 MediaAddOn::MediaAddOn(image_id imid)
25 : BMediaAddOn(imid)
26 {
27 /* Customize these parameters to match those of your node */
28 fFlavorInfo.name = "USB Vision";
29 fFlavorInfo.info = "USB Vision";
30 fFlavorInfo.kinds = B_BUFFER_PRODUCER | B_CONTROLLABLE | B_PHYSICAL_INPUT;
31 fFlavorInfo.flavor_flags = 0;
32 fFlavorInfo.internal_id = 0;
33 fFlavorInfo.possible_count = 1;
34 fFlavorInfo.in_format_count = 0;
35 fFlavorInfo.in_format_flags = 0;
36 fFlavorInfo.in_formats = NULL;
37 fFlavorInfo.out_format_count = 1;
38 fFlavorInfo.out_format_flags = 0;
39 fMediaFormat.type = B_MEDIA_RAW_VIDEO;
40 fMediaFormat.u.raw_video = media_raw_video_format::wildcard;
41 fMediaFormat.u.raw_video.interlace = 1;
42 fMediaFormat.u.raw_video.display.format = B_RGB32;
43 fFlavorInfo.out_formats = &fMediaFormat;
44
45 fInitStatus = B_NO_INIT;
46 fDriverFD = -1;
47 if(USBVisionInit()){
48 fInitStatus = B_OK;
49 }
50 }
51
~MediaAddOn()52 MediaAddOn::~MediaAddOn()
53 {
54 if(fInitStatus == B_OK){
55 USBVisionUninit();
56 }
57 }
58
59
60 status_t
InitCheck(const char ** out_failure_text)61 MediaAddOn::InitCheck(const char **out_failure_text)
62 {
63 if (fInitStatus < B_OK) {
64 *out_failure_text = "Unknown error";
65 return fInitStatus;
66 }
67
68 return B_OK;
69 }
70
71 int32
CountFlavors()72 MediaAddOn::CountFlavors()
73 {
74 if (fInitStatus < B_OK)
75 return fInitStatus;
76
77 /* This addon only supports a single flavor, as defined in the
78 * constructor */
79 return 1;
80 }
81
82 /*
83 * The pointer to the flavor received only needs to be valid between
84 * successive calls to BMediaAddOn::GetFlavorAt().
85 */
86 status_t
GetFlavorAt(int32 n,const flavor_info ** out_info)87 MediaAddOn::GetFlavorAt(int32 n, const flavor_info **out_info)
88 {
89 if (fInitStatus < B_OK)
90 return fInitStatus;
91
92 if (n != 0)
93 return B_BAD_INDEX;
94
95 /* Return the flavor defined in the constructor */
96 *out_info = &fFlavorInfo;
97 return B_OK;
98 }
99
100 BMediaNode *
InstantiateNodeFor(const flavor_info * info,BMessage * config,status_t * out_error)101 MediaAddOn::InstantiateNodeFor(
102 const flavor_info *info, BMessage *config, status_t *out_error)
103 {
104 VideoProducer *node;
105
106 if (fInitStatus < B_OK)
107 return NULL;
108
109 if (info->internal_id != fFlavorInfo.internal_id)
110 return NULL;
111
112 /* At most one instance of the node should be instantiated at any given
113 * time. The locking for this restriction may be found in the VideoProducer
114 * class. */
115 node = new VideoProducer(this, fFlavorInfo.name, fFlavorInfo.internal_id);
116 if (node && (node->InitCheck() < B_OK)) {
117 delete node;
118 node = NULL;
119 }
120
121 return node;
122 }
123
124 BMediaAddOn *
make_media_addon(image_id imid)125 make_media_addon(image_id imid)
126 {
127 return new MediaAddOn(imid);
128 }
129
USBVisionInit()130 bool MediaAddOn::USBVisionInit()
131 {
132 //TODO - support for multiple devices !!!
133 fDriverFD = open("/dev/video/usb_vision/0", O_RDWR);
134 if(fDriverFD < 0)
135 fInitStatus = ENODEV;
136 return (fDriverFD >= 0);
137 }
138
USBVisionUninit()139 void MediaAddOn::USBVisionUninit()
140 { //TODO - correct work on detach device from usb port ...
141 close(fDriverFD);
142 }
143
USBVisionWriteRegister(uint8 reg,uint8 * data,uint8 len)144 status_t MediaAddOn::USBVisionWriteRegister(uint8 reg, uint8 *data, uint8 len /*= sizeof(uint8)*/)
145 {
146 status_t status = ENODEV;
147 if(fDriverFD >= 0){
148 xet_nt100x_reg ri = {reg, len};
149 memcpy(ri.data, data, len);
150 status = ioctl(fDriverFD, NT_IOCTL_WRITE_REGISTER, &ri, sizeof(ri));
151 }
152 return status;
153 }
154
USBVisionReadRegister(uint8 reg,uint8 * data,uint8 len)155 status_t MediaAddOn::USBVisionReadRegister(uint8 reg, uint8 *data, uint8 len /* = sizeof(uint8)*/)
156 {
157 status_t status = ENODEV;
158 if(fDriverFD >= 0){
159 xet_nt100x_reg ri = {reg, len};
160 if((status = ioctl(fDriverFD, NT_IOCTL_READ_REGISTER, &ri, sizeof(ri))) == B_OK){
161 memcpy(data, ri.data, ri.data_length);
162 }
163 }
164 return status;
165 }
166