2 * Copyright 2004-2008, François Revol, <revol@free.fr>.
3 * Distributed under the terms of the MIT License.
7 * buffer based deframer
8 * buffers all packet until it finds a complete frame.
9 * simpler than StreamingDeframer, but doesn't work any better
10 * and hogs the cpu intermitently :^)
14 #include "CamBufferingDeframer.h"
15 #include "CamDevice.h"
18 #define MAX_TAG_LEN CAMDEFRAMER_MAX_TAG_LEN
19 #define MAXFRAMEBUF CAMDEFRAMER_MAX_QUEUED_FRAMES
21 #define IB fInputBuffs[fInputBuffIndex]
24 CamBufferingDeframer::CamBufferingDeframer(CamDevice
*device
)
25 : CamDeframer(device
),
31 CamBufferingDeframer::~CamBufferingDeframer()
37 CamBufferingDeframer::Write(const void *buffer
, size_t size
)
43 fMinFrameSize
= fDevice
->MinRawFrameSize();
44 fMaxFrameSize
= fDevice
->MaxRawFrameSize();
45 IB
.Write(buffer
, size
);
46 b
= (uint8
*)IB
.Buffer();
47 l
= IB
.BufferLength();
49 PRINT((CH
"(%p, %d), IB: %d" CT
, buffer
, size
, IB
.BufferLength()));
51 if (l
< (int)(fMinFrameSize
+ fSkipSOFTags
+ fSkipEOFTags
))
52 return size
; // not enough data anyway
56 if (fFrames
.CountItems() < MAXFRAMEBUF
)
57 fCurrentFrame
= AllocFrame();
59 PRINT((CH
"DROPPED %d bytes! (too many queued frames)" CT
, size
));
60 return size
; // drop XXX
64 for (s
= 0; (l
- s
> (int)fMinFrameSize
) && ((i
= FindSOF(b
+ s
, l
- fMinFrameSize
- s
, &which
)) > -1); s
++) {
66 if ((int)(s
+ fSkipSOFTags
+ fMinFrameSize
+ fSkipEOFTags
) > l
)
68 if (!fDevice
->ValidateStartOfFrameTag(b
+ s
, fSkipSOFTags
))
71 PRINT((CH
": SOF[%d] at offset %d" CT
, which
, s
));
72 PRINT((CH
": SOF: ... %02x %02x %02x %02x %02x %02x" CT
, b
[s
+6], b
[s
+7], b
[s
+8], b
[s
+9], b
[s
+10], b
[s
+11]));
74 for (e
= s
+ fSkipSOFTags
+ fMinFrameSize
;
75 ((e
<= (int)(s
+ fSkipSOFTags
+ fMaxFrameSize
)) &&
76 (e
< l
) && ((i
= 0*FindEOF(b
+ e
, l
- e
, &which
)) > -1));
80 //PRINT((CH ": EOF[%d] at offset %d" CT, which, s));
81 if (!fDevice
->ValidateEndOfFrameTag(b
+ e
, fSkipEOFTags
, e
- s
- fSkipSOFTags
))
86 PRINT((CH
": SOF= ... %02x %02x %02x %02x %02x %02x" CT
, b
[s
+6], b
[s
+7], b
[s
+8], b
[s
+9], b
[s
+10], b
[s
+11]));
92 fCurrentFrame
->Write(b
+ s
, e
- s
);
96 PRINT((CH
": Detaching a frame (%d bytes, %d to %d / %d)" CT
, (size_t)fCurrentFrame
->Position(), s
, e
, l
));
97 fCurrentFrame
->Seek(0LL, SEEK_SET
);
98 fFrames
.AddItem(fCurrentFrame
);
99 release_sem(fFrameSem
);
100 // next Write() will allocate a new one
101 fCurrentFrame
= NULL
;
102 // discard the frame and everything before it.
103 DiscardFromInput(e
+ fSkipEOFTags
);
113 CamBufferingDeframer::DiscardFromInput(size_t size
)
115 int next
= (fInputBuffIndex
+1)%2;
116 PRINT((CH
": %d bytes of %d from buffs[%d] (%d left)" CT
, size
, IB
.BufferLength(), fInputBuffIndex
, IB
.BufferLength() - size
));
117 fInputBuffs
[next
].Seek(0LL, SEEK_SET
);
118 fInputBuffs
[next
].SetSize(0);
119 uint8
*buff
= (uint8
*)IB
.Buffer();
120 if (IB
.BufferLength() > size
) {
122 fInputBuffs
[next
].Write(buff
, IB
.BufferLength() - size
);
124 IB
.Seek(0LL, SEEK_SET
);
126 fInputBuffIndex
= next
;