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
15CamDeframer::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
37CamDeframer::~CamDeframer()
38{
39	delete_sem(fFrameSem);
40	BAutolock l(fLocker);
41	delete fCurrentFrame;
42}
43
44
45ssize_t
46CamDeframer::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
56ssize_t
57CamDeframer::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
67off_t
68CamDeframer::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
78off_t
79CamDeframer::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
89status_t
90CamDeframer::SetSize(off_t size)
91{
92	(void)size;
93	return EINVAL;
94}
95
96
97ssize_t
98CamDeframer::Write(const void *buffer, size_t size)
99{
100	(void)buffer;
101	(void)size;
102	return EINVAL;
103}
104
105
106ssize_t
107CamDeframer::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
116status_t
117CamDeframer::WaitFrame(bigtime_t timeout)
118{
119	return acquire_sem_etc(fFrameSem, 1, B_RELATIVE_TIMEOUT, timeout);
120}
121
122
123status_t
124CamDeframer::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
137status_t
138CamDeframer::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
150status_t
151CamDeframer::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
167status_t
168CamDeframer::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
184int
185CamDeframer::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
201int
202CamDeframer::FindSOF(const uint8 *buf, size_t buflen, int *which)
203{
204	return FindTags(buf, buflen, fSOFTags, fNumSOFTags, fLenSOFTags, fSkipSOFTags, which);
205}
206
207
208int
209CamDeframer::FindEOF(const uint8 *buf, size_t buflen, int *which)
210{
211	return FindTags(buf, buflen, fEOFTags, fNumEOFTags, fLenEOFTags, fSkipEOFTags, which);
212}
213
214
215CamFrame *
216CamDeframer::AllocFrame()
217{
218	return new CamFrame();
219}
220