vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / media / media-add-ons / usb_webcam / AddOn.cpp
blob13fdb8b9dff430e6c318183f5cfb12ba956258cd
1 /*
2 * Copyright 2004-2008, François Revol, <revol@free.fr>.
3 * Distributed under the terms of the MIT License.
4 */
6 #include <support/Autolock.h>
7 #include <media/MediaFormats.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <unistd.h>
13 #include "AddOn.h"
14 #include "Producer.h"
15 #include "CamRoster.h"
16 #include "CamDebug.h"
17 #include "CamDevice.h"
20 WebCamMediaAddOn::WebCamMediaAddOn(image_id imid)
21 : BMediaAddOn(imid),
22 fInitStatus(B_NO_INIT),
23 fRoster(NULL)
25 PRINT((CH "()" CT));
26 fInternalIDCounter = 0;
27 /* Customize these parameters to match those of your node */
28 fMediaFormat.type = B_MEDIA_RAW_VIDEO;
29 fMediaFormat.u.raw_video = media_raw_video_format::wildcard;
30 fMediaFormat.u.raw_video.interlace = 1;
31 fMediaFormat.u.raw_video.display.format = B_RGB32;
32 FillDefaultFlavorInfo(&fDefaultFlavorInfo);
34 fRoster = new CamRoster(this);
35 fRoster->Start();
36 // if( fRoster->CountCameras() < 1 )
37 /* fInitStatus = B_ERROR;
38 else
40 fInitStatus = B_OK;
44 WebCamMediaAddOn::~WebCamMediaAddOn()
46 fRoster->Stop();
47 delete fRoster;
51 status_t
52 WebCamMediaAddOn::InitCheck(const char **out_failure_text)
54 if (fInitStatus < B_OK) {
55 *out_failure_text = "No cameras attached";
56 return fInitStatus;
59 return B_OK;
63 int32
64 WebCamMediaAddOn::CountFlavors()
66 PRINT((CH "()" CT));
67 int32 count;
68 if (!fRoster)
69 return B_NO_INIT;
70 if (fInitStatus < B_OK)
71 return fInitStatus;
73 /* This addon only supports a single flavor, as defined in the
74 * constructor */
75 count = fRoster->CountCameras();
76 return count;//(count > 0)?count:1;//1;
81 * The pointer to the flavor received only needs to be valid between
82 * successive calls to BMediaAddOn::GetFlavorAt().
84 status_t
85 WebCamMediaAddOn::GetFlavorAt(int32 n, const flavor_info **out_info)
87 PRINT((CH "(%d, ) roster %p is %lx" CT, n, fRoster, fInitStatus));
88 int32 count;
89 CamDevice* cam;
90 if (!fRoster)
91 return B_NO_INIT;
92 if (fInitStatus < B_OK)
93 return fInitStatus;
95 count = fRoster->CountCameras();
96 PRINT((CH ": %d cameras" CT, count));
97 if (n >= count)//(n != 0)
98 return B_BAD_INDEX;
100 fRoster->Lock();
101 cam = fRoster->CameraAt(n);
102 *out_info = &fDefaultFlavorInfo;
103 if (cam && cam->FlavorInfo())
104 *out_info = cam->FlavorInfo();
105 fRoster->Unlock();
106 PRINT((CH ": returning flavor for %d, internal_id %d" CT, n, (*out_info)->internal_id));
107 return B_OK;
111 BMediaNode *
112 WebCamMediaAddOn::InstantiateNodeFor(
113 const flavor_info *info, BMessage* /*_config*/, status_t* /*_out_error*/)
115 PRINT((CH "()" CT));
116 VideoProducer *node;
117 CamDevice *cam=NULL;
119 if (fInitStatus < B_OK)
120 return NULL;
122 fRoster->Lock();
123 for (uint32 i = 0; i < fRoster->CountCameras(); i++) {
124 CamDevice *c;
125 c = fRoster->CameraAt(i);
126 PRINT((CH ": cam[%d]: %d, %s" CT, i, c->FlavorInfo()->internal_id, c->BrandName()));
127 if (c && (c->FlavorInfo()->internal_id == info->internal_id)) {
128 cam = c;
129 break;
132 fRoster->Unlock();
133 if (!cam)
134 return NULL;
136 #if 0
137 fRoster->Lock();
138 cam = fRoster->CameraAt(n);
139 *out_info = &fDefaultFlavorInfo;
140 if (cam && cam->FlavorInfo())
141 *out_info = cam->FlavorInfo();
142 fRoster->Unlock();
143 #endif
144 /* At most one instance of the node should be instantiated at any given
145 * time. The locking for this restriction may be found in the VideoProducer
146 * class. */
147 node = new VideoProducer(this, cam, cam->FlavorInfo()->name, cam->FlavorInfo()->internal_id);
148 if (node && (node->InitCheck() < B_OK)) {
149 delete node;
150 node = NULL;
153 return node;
157 status_t
158 WebCamMediaAddOn::CameraAdded(CamDevice* device)
160 PRINT((CH "()" CT));
161 NotifyFlavorChange();
162 return B_OK;
166 status_t
167 WebCamMediaAddOn::CameraRemoved(CamDevice* device)
169 PRINT((CH "()" CT));
170 NotifyFlavorChange();
171 return B_OK;
175 void
176 WebCamMediaAddOn::FillDefaultFlavorInfo(flavor_info* info)
178 info->name = "USB Web Camera";
179 info->info = "USB Web Camera";
180 info->kinds = B_BUFFER_PRODUCER | B_CONTROLLABLE | B_PHYSICAL_INPUT;
181 info->flavor_flags = 0;//B_FLAVOR_IS_GLOBAL;
182 info->internal_id = atomic_add((int32*)&fInternalIDCounter, 1);
183 info->possible_count = 1;//0;
184 info->in_format_count = 0;
185 info->in_format_flags = 0;
186 info->in_formats = NULL;
187 info->out_format_count = 1;
188 info->out_format_flags = 0;
189 info->out_formats = &fMediaFormat;
193 BMediaAddOn *
194 make_media_addon(image_id id)
196 return new WebCamMediaAddOn(id);