2 * Copyright 2004-2008, François Revol, <revol@free.fr>.
3 * Distributed under the terms of the MIT License.
7 * stream based deframer
8 * has a state machine and handles each packet separately.
9 * much more complex than the buffering one, and I thought it didn't work,
10 * but since I fixed the rest it seems to be working even better without
11 * taking the cpu over like the other one.
15 #include "CamStreamingDeframer.h"
16 #include "CamDevice.h"
19 #define MAX_TAG_LEN CAMDEFRAMER_MAX_TAG_LEN
20 #define MAXFRAMEBUF CAMDEFRAMER_MAX_QUEUED_FRAMES
23 CamStreamingDeframer::CamStreamingDeframer(CamDevice
*device
)
29 CamStreamingDeframer::~CamStreamingDeframer()
35 CamStreamingDeframer::Write(const void *buffer
, size_t size
)
41 const uint8
*buf
= (const uint8
*)buffer
;
45 //PRINT((CH "(%p, %d); state=%s framesz=%u queued=%u" CT, buffer, size, (fState==ST_SYNC)?"sync":"frame", (size_t)(fCurrentFrame?(fCurrentFrame->Position()):-1), (size_t)fInputBuff.Position()));
48 if (fFrames
.CountItems() < MAXFRAMEBUF
)
49 fCurrentFrame
= AllocFrame();
51 PRINT((CH
"DROPPED %d bytes! (too many queued frames)" CT
, size
));
52 return size
; // drop XXX
56 // update in case resolution changed
57 fMinFrameSize
= fDevice
->MinRawFrameSize();
58 fMaxFrameSize
= fDevice
->MaxRawFrameSize();
60 if (fInputBuff
.Position()) {
61 // residual data ? append to it
62 fInputBuff
.Write(buffer
, size
);
63 // and use it as input buf
64 buf
= (uint8
*)fInputBuff
.Buffer();
65 bufsize
= fInputBuff
.BufferLength();
68 // whole buffer belongs to a frame, simple
69 if ((fState
== ST_FRAME
) && (fCurrentFrame
->Position() + bufsize
< fMinFrameSize
)) {
70 // no residual data, and
71 fCurrentFrame
->Write(buf
, bufsize
);
72 fInputBuff
.Seek(0LL, SEEK_SET
);
73 fInputBuff
.SetSize(0);
77 // waiting for a frame...
78 if (fState
== ST_SYNC
) {
80 while ((j
= FindSOF(buf
+i
, bufsize
-i
, &which
)) > -1) {
82 if (fDevice
->ValidateStartOfFrameTag(buf
+i
, fSkipSOFTags
))
88 PRINT((CH
": SOF[%d] at offset %d" CT
, which
, i
));
89 //PRINT((CH ": SOF: ... %02x %02x %02x %02x %02x %02x" CT, buf[i+6], buf[i+7], buf[i+8], buf[i+9], buf[i+10], buf[i+11]));
90 int start
= i
+ fSkipSOFTags
;
98 // check for end of frame
99 if (fState
== ST_FRAME
) {
104 while ((j
= FindEOF(buf
+ k
, bufsize
- k
, &which
)) > -1) {
106 //PRINT((CH "| EOF[%d] at offset %d; pos %Ld" CT, which, k, fCurrentFrame->Position()));
107 if (fCurrentFrame
->Position()+k
>= fMinFrameSize
) {
118 if (fCurrentFrame
->Position() < fMinFrameSize
) {
119 if (fCurrentFrame
->Position() + bufsize
>= fMinFrameSize
)
120 i
= (fMinFrameSize
- (size_t)fCurrentFrame
->Position());
124 PRINT((CH
": checking for EOF; bufsize=%d i=%d" CT
, bufsize
, i
));
126 if (i
+ (int)fSkipEOFTags
> bufsize
) { // not enough room to check for EOF, leave it for next time
128 i
= -1; // don't detach yet
130 PRINT((CH
": EOF? %02x [%02x %02x %02x %02x] %02x" CT
, buf
[i
-1], buf
[i
], buf
[i
+1], buf
[i
+2], buf
[i
+3], buf
[i
+4]));
131 while ((j
= FindEOF(buf
+ i
, bufsize
- i
, &which
)) > -1) {
133 PRINT((CH
"| EOF[%d] at offset %d; pos %Ld" CT
, which
, i
, fCurrentFrame
->Position()));
134 if (fCurrentFrame
->Position()+i
>= fMaxFrameSize
) {
140 if (fDevice
->ValidateEndOfFrameTag(buf
+i
, fSkipEOFTags
, fCurrentFrame
->Position()+i
))
153 PRINT((CH
": EOF[%d] at offset %d" CT
, which
, i
));
157 PRINT((CH
": writing %d bytes" CT
, end
));
159 fCurrentFrame
->Write(buf
, end
);
160 if (fCurrentFrame
->Position() > fMaxFrameSize
) {
161 fCurrentFrame
->SetSize(fMaxFrameSize
);
165 BAutolock
f(fLocker
);
166 PRINT((CH
": Detaching a frame (%d bytes, end = %d, )" CT
, (size_t)fCurrentFrame
->Position(), end
));
167 fCurrentFrame
->Seek(0LL, SEEK_SET
);
169 delete fCurrentFrame
;
171 fFrames
.AddItem(fCurrentFrame
);
172 release_sem(fFrameSem
);
174 fCurrentFrame
= NULL
;
175 if (fFrames
.CountItems() < MAXFRAMEBUF
) {
176 fCurrentFrame
= AllocFrame();
185 // put the remainder in input buff, discarding old data
187 fInputBuff
.Seek(0LL, SEEK_SET
);
188 if (bufsize
- end
> 0)
189 fInputBuff
.Write(buf
+end
, bufsize
- end
);
192 m
.Write(buf
+end
, bufsize
- end
);
193 fInputBuff
.Seek(0LL, SEEK_SET
);
194 if (bufsize
- end
> 0)
195 fInputBuff
.Write(m
.Buffer(), bufsize
- end
);
196 fInputBuff
.SetSize(bufsize
- end
);