xref: /haiku/src/add-ons/media/media-add-ons/usb_vision/AddOn.cpp (revision 1d9d47fc72028bb71b5f232a877231e59cfe2438)
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 
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 
52 MediaAddOn::~MediaAddOn()
53 {
54   if(fInitStatus == B_OK){
55     USBVisionUninit();
56   }
57 }
58 
59 
60 status_t
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
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
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 *
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 *
125 make_media_addon(image_id imid)
126 {
127   return new MediaAddOn(imid);
128 }
129 
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 
139 void MediaAddOn::USBVisionUninit()
140 {  //TODO - correct work on detach device from usb port ...
141   close(fDriverFD);
142 }
143 
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 
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