xref: /haiku/src/add-ons/media/media-add-ons/usb_webcam/CamDeframer.cpp (revision b55a57da7173b9af0432bd3e148d03f06161d036)
1 /*
2  * Copyright 2004-2008, François Revol, <revol@free.fr>.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #define CD_COL "31"
7 #include "CamDeframer.h"
8 #include "CamDevice.h"
9 #include "CamDebug.h"
10 #include <Autolock.h>
11 #define MAX_TAG_LEN CAMDEFRAMER_MAX_TAG_LEN
12 #define MAXFRAMEBUF CAMDEFRAMER_MAX_QUEUED_FRAMES
13 
14 
15 CamDeframer::CamDeframer(CamDevice *device)
16 : CamFilterInterface(device),
17 fDevice(device),
18 fState(ST_SYNC),
19 fFrameSem(B_ERROR),
20 fLocker("CamDeframer Framelist lock", true),
21 fSOFTags(NULL),
22 fEOFTags(NULL),
23 fNumSOFTags(0),
24 fNumEOFTags(0),
25 fLenSOFTags(0),
26 fLenEOFTags(0),
27 fSkipSOFTags(0),
28 fSkipEOFTags(0)
29 {
30 	fMinFrameSize = fDevice->MinRawFrameSize();
31 	fMaxFrameSize = fDevice->MaxRawFrameSize();
32 	fFrameSem = create_sem(0, "CamDeframer sem");
33 	fCurrentFrame = AllocFrame();
34 }
35 
36 
37 CamDeframer::~CamDeframer()
38 {
39 	delete_sem(fFrameSem);
40 	BAutolock l(fLocker);
41 	delete fCurrentFrame;
42 }
43 
44 
45 ssize_t
46 CamDeframer::Read(void *buffer, size_t size)
47 {
48 	BAutolock l(fLocker);
49 	CamFrame *f = (CamFrame *)fFrames.ItemAt(0);
50 	if (!f)
51 		return EIO;
52 	return f->Read(buffer, size);
53 }
54 
55 
56 ssize_t
57 CamDeframer::ReadAt(off_t pos, void *buffer, size_t size)
58 {
59 	BAutolock l(fLocker);
60 	CamFrame *f = (CamFrame *)fFrames.ItemAt(0);
61 	if (!f)
62 		return EIO;
63 	return f->ReadAt(pos, buffer, size);
64 }
65 
66 
67 off_t
68 CamDeframer::Seek(off_t position, uint32 seek_mode)
69 {
70 	BAutolock l(fLocker);
71 	CamFrame *f = (CamFrame *)fFrames.ItemAt(0);
72 	if (!f)
73 		return EIO;
74 	return f->Seek(position, seek_mode);
75 }
76 
77 
78 off_t
79 CamDeframer::Position() const
80 {
81 	BAutolock l((BLocker &)fLocker); // need to get rid of const here
82 	CamFrame *f = (CamFrame *)fFrames.ItemAt(0);
83 	if (!f)
84 		return EIO;
85 	return f->Position();
86 }
87 
88 
89 status_t
90 CamDeframer::SetSize(off_t size)
91 {
92 	(void)size;
93 	return EINVAL;
94 }
95 
96 
97 ssize_t
98 CamDeframer::Write(const void *buffer, size_t size)
99 {
100 	(void)buffer;
101 	(void)size;
102 	return EINVAL;
103 }
104 
105 
106 ssize_t
107 CamDeframer::WriteAt(off_t pos, const void *buffer, size_t size)
108 {
109 	(void)pos;
110 	(void)buffer;
111 	(void)size;
112 	return EINVAL;
113 }
114 
115 
116 status_t
117 CamDeframer::WaitFrame(bigtime_t timeout)
118 {
119 	return acquire_sem_etc(fFrameSem, 1, B_RELATIVE_TIMEOUT, timeout);
120 }
121 
122 
123 status_t
124 CamDeframer::GetFrame(CamFrame **frame, bigtime_t *stamp)
125 {
126 	PRINT((CH "()" CT));
127 	BAutolock l(fLocker);
128 	CamFrame *f = (CamFrame *)fFrames.RemoveItem((int32)0);
129 	if (!f)
130 		return ENOENT;
131 	*frame = f;
132 	*stamp = f->Stamp();
133 	return B_OK;
134 }
135 
136 
137 status_t
138 CamDeframer::DropFrame()
139 {
140 	PRINT((CH "()" CT));
141 	BAutolock l(fLocker);
142 	CamFrame *f = (CamFrame *)fFrames.RemoveItem((int32)0);
143 	if (!f)
144 		return ENOENT;
145 	delete f;
146 	return B_OK;
147 }
148 
149 
150 status_t
151 CamDeframer::RegisterSOFTags(const uint8 **tags, int count, size_t len, size_t skip)
152 {
153 	if (fSOFTags)
154 		return EALREADY;
155 	if (len > MAX_TAG_LEN)
156 		return EINVAL;
157 	if (count > 16)
158 		return EINVAL;
159 	fSOFTags = tags;
160 	fNumSOFTags = count;
161 	fLenSOFTags = len;
162 	fSkipSOFTags = skip;
163 	return B_OK;
164 }
165 
166 
167 status_t
168 CamDeframer::RegisterEOFTags(const uint8 **tags, int count, size_t len, size_t skip)
169 {
170 	if (fEOFTags)
171 		return EALREADY;
172 	if (len > MAX_TAG_LEN)
173 		return EINVAL;
174 	if (count > 16)
175 		return EINVAL;
176 	fEOFTags = tags;
177 	fNumEOFTags = count;
178 	fLenEOFTags = len;
179 	fSkipEOFTags = skip;
180 	return B_OK;
181 }
182 
183 
184 int
185 CamDeframer::FindTags(const uint8 *buf, size_t buflen, const uint8 **tags, int tagcount, size_t taglen, size_t skiplen, int *which)
186 {
187 	int i, t;
188 	for (i = 0; i < (int)(buflen - skiplen + 1); i++) {
189 		for (t = 0; t < tagcount; t++) {
190 			if (!memcmp(buf+i, tags[t], taglen)) {
191 				if (which)
192 					*which = t;
193 				return i;
194 			}
195 		}
196 	}
197 	return -1;
198 }
199 
200 
201 int
202 CamDeframer::FindSOF(const uint8 *buf, size_t buflen, int *which)
203 {
204 	return FindTags(buf, buflen, fSOFTags, fNumSOFTags, fLenSOFTags, fSkipSOFTags, which);
205 }
206 
207 
208 int
209 CamDeframer::FindEOF(const uint8 *buf, size_t buflen, int *which)
210 {
211 	return FindTags(buf, buflen, fEOFTags, fNumEOFTags, fLenEOFTags, fSkipEOFTags, which);
212 }
213 
214 
215 CamFrame *
216 CamDeframer::AllocFrame()
217 {
218 	return new CamFrame();
219 }
220 
221