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