1*2c9bd703SFrançois Revol /* 2*2c9bd703SFrançois Revol * buffer based deframer 3*2c9bd703SFrançois Revol * buffers all packet until it finds a complete frame. 4*2c9bd703SFrançois Revol * simpler than StreamingDeframer, but doesn't work any better 5*2c9bd703SFrançois Revol * and hogs the cpu intermitently :^) 6*2c9bd703SFrançois Revol */ 7*2c9bd703SFrançois Revol 8*2c9bd703SFrançois Revol #define CD_COL "31" 9*2c9bd703SFrançois Revol #include "CamBufferingDeframer.h" 10*2c9bd703SFrançois Revol #include "CamDevice.h" 11*2c9bd703SFrançois Revol #include "CamDebug.h" 12*2c9bd703SFrançois Revol #include <Autolock.h> 13*2c9bd703SFrançois Revol #define MAX_TAG_LEN CAMDEFRAMER_MAX_TAG_LEN 14*2c9bd703SFrançois Revol #define MAXFRAMEBUF CAMDEFRAMER_MAX_QUEUED_FRAMES 15*2c9bd703SFrançois Revol 16*2c9bd703SFrançois Revol #define IB fInputBuffs[fInputBuffIndex] 17*2c9bd703SFrançois Revol 18*2c9bd703SFrançois Revol CamBufferingDeframer::CamBufferingDeframer(CamDevice *device) 19*2c9bd703SFrançois Revol : CamDeframer(device), 20*2c9bd703SFrançois Revol fInputBuffIndex(0) 21*2c9bd703SFrançois Revol { 22*2c9bd703SFrançois Revol } 23*2c9bd703SFrançois Revol 24*2c9bd703SFrançois Revol CamBufferingDeframer::~CamBufferingDeframer() 25*2c9bd703SFrançois Revol { 26*2c9bd703SFrançois Revol } 27*2c9bd703SFrançois Revol 28*2c9bd703SFrançois Revol ssize_t 29*2c9bd703SFrançois Revol CamBufferingDeframer::Write(const void *buffer, size_t size) 30*2c9bd703SFrançois Revol { 31*2c9bd703SFrançois Revol uint8 *b; 32*2c9bd703SFrançois Revol int l; 33*2c9bd703SFrançois Revol int i, s, e; 34*2c9bd703SFrançois Revol int which; 35*2c9bd703SFrançois Revol fMinFrameSize = fDevice->MinRawFrameSize(); 36*2c9bd703SFrançois Revol fMaxFrameSize = fDevice->MaxRawFrameSize(); 37*2c9bd703SFrançois Revol IB.Write(buffer, size); 38*2c9bd703SFrançois Revol b = (uint8 *)IB.Buffer(); 39*2c9bd703SFrançois Revol l = IB.BufferLength(); 40*2c9bd703SFrançois Revol 41*2c9bd703SFrançois Revol PRINT((CH "(%p, %d), IB: %d" CT, buffer, size, IB.BufferLength())); 42*2c9bd703SFrançois Revol 43*2c9bd703SFrançois Revol if (l < fMinFrameSize + fSkipSOFTags + fSkipEOFTags) 44*2c9bd703SFrançois Revol return size; // not enough data anyway 45*2c9bd703SFrançois Revol 46*2c9bd703SFrançois Revol if (!fCurrentFrame) { 47*2c9bd703SFrançois Revol BAutolock l(fLocker); 48*2c9bd703SFrançois Revol if (fFrames.CountItems() < MAXFRAMEBUF) 49*2c9bd703SFrançois Revol fCurrentFrame = AllocFrame(); 50*2c9bd703SFrançois Revol else { 51*2c9bd703SFrançois Revol PRINT((CH "DROPPED %d bytes! (too many queued frames)" CT, size)); 52*2c9bd703SFrançois Revol return size; // drop XXX 53*2c9bd703SFrançois Revol } 54*2c9bd703SFrançois Revol } 55*2c9bd703SFrançois Revol 56*2c9bd703SFrançois Revol for (s = 0; (l - s > fMinFrameSize) && ((i = FindSOF(b + s, l - fMinFrameSize - s, &which)) > -1); s++) { 57*2c9bd703SFrançois Revol s += i; 58*2c9bd703SFrançois Revol if (s + fSkipSOFTags + fMinFrameSize + fSkipEOFTags > l) 59*2c9bd703SFrançois Revol break; 60*2c9bd703SFrançois Revol if (!fDevice->ValidateStartOfFrameTag(b + s, fSkipSOFTags)) 61*2c9bd703SFrançois Revol continue; 62*2c9bd703SFrançois Revol 63*2c9bd703SFrançois Revol PRINT((CH ": SOF[%d] at offset %d" CT, which, s)); 64*2c9bd703SFrançois Revol 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])); 65*2c9bd703SFrançois Revol 66*2c9bd703SFrançois Revol for (e = s + fSkipSOFTags + fMinFrameSize; 67*2c9bd703SFrançois Revol ((e <= s + fSkipSOFTags + fMaxFrameSize) && 68*2c9bd703SFrançois Revol (e < l) && ((i = 0*FindEOF(b + e, l - e, &which)) > -1)); 69*2c9bd703SFrançois Revol e++) { 70*2c9bd703SFrançois Revol e += i; 71*2c9bd703SFrançois Revol 72*2c9bd703SFrançois Revol //PRINT((CH ": EOF[%d] at offset %d" CT, which, s)); 73*2c9bd703SFrançois Revol if (!fDevice->ValidateEndOfFrameTag(b + e, fSkipEOFTags, e - s - fSkipSOFTags)) 74*2c9bd703SFrançois Revol continue; 75*2c9bd703SFrançois Revol 76*2c9bd703SFrançois Revol 77*2c9bd703SFrançois Revol 78*2c9bd703SFrançois Revol 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])); 79*2c9bd703SFrançois Revol 80*2c9bd703SFrançois Revol // we have one! 81*2c9bd703SFrançois Revol s += fSkipSOFTags; 82*2c9bd703SFrançois Revol 83*2c9bd703SFrançois Revol // fill it 84*2c9bd703SFrançois Revol fCurrentFrame->Write(b + s, e - s); 85*2c9bd703SFrançois Revol 86*2c9bd703SFrançois Revol // queue it 87*2c9bd703SFrançois Revol BAutolock f(fLocker); 88*2c9bd703SFrançois Revol PRINT((CH ": Detaching a frame (%d bytes, %d to %d / %d)" CT, (size_t)fCurrentFrame->Position(), s, e, l)); 89*2c9bd703SFrançois Revol fCurrentFrame->Seek(0LL, SEEK_SET); 90*2c9bd703SFrançois Revol fFrames.AddItem(fCurrentFrame); 91*2c9bd703SFrançois Revol release_sem(fFrameSem); 92*2c9bd703SFrançois Revol // next Write() will allocate a new one 93*2c9bd703SFrançois Revol fCurrentFrame = NULL; 94*2c9bd703SFrançois Revol // discard the frame and everything before it. 95*2c9bd703SFrançois Revol DiscardFromInput(e + fSkipEOFTags); 96*2c9bd703SFrançois Revol 97*2c9bd703SFrançois Revol return size; 98*2c9bd703SFrançois Revol } 99*2c9bd703SFrançois Revol } 100*2c9bd703SFrançois Revol return size; 101*2c9bd703SFrançois Revol } 102*2c9bd703SFrançois Revol 103*2c9bd703SFrançois Revol size_t 104*2c9bd703SFrançois Revol CamBufferingDeframer::DiscardFromInput(size_t size) 105*2c9bd703SFrançois Revol { 106*2c9bd703SFrançois Revol int next = (fInputBuffIndex+1)%2; 107*2c9bd703SFrançois Revol PRINT((CH ": %d bytes of %d from buffs[%d] (%d left)" CT, size, IB.BufferLength(), fInputBuffIndex, IB.BufferLength() - size)); 108*2c9bd703SFrançois Revol fInputBuffs[next].Seek(0LL, SEEK_SET); 109*2c9bd703SFrançois Revol fInputBuffs[next].SetSize(0); 110*2c9bd703SFrançois Revol uint8 *buff = (uint8 *)IB.Buffer(); 111*2c9bd703SFrançois Revol if (IB.BufferLength() > size) { 112*2c9bd703SFrançois Revol buff += size; 113*2c9bd703SFrançois Revol fInputBuffs[next].Write(buff, IB.BufferLength() - size); 114*2c9bd703SFrançois Revol } 115*2c9bd703SFrançois Revol IB.Seek(0LL, SEEK_SET); 116*2c9bd703SFrançois Revol IB.SetSize(0); 117*2c9bd703SFrançois Revol fInputBuffIndex = next; 118*2c9bd703SFrançois Revol 119*2c9bd703SFrançois Revol } 120*2c9bd703SFrançois Revol 121