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