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