1 /* 2 * Copyright 2004-2008, François Revol, <revol@free.fr>. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 /* 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 :^) 11 */ 12 13 #define CD_COL "31" 14 #include "CamBufferingDeframer.h" 15 #include "CamDevice.h" 16 #include "CamDebug.h" 17 #include <Autolock.h> 18 #define MAX_TAG_LEN CAMDEFRAMER_MAX_TAG_LEN 19 #define MAXFRAMEBUF CAMDEFRAMER_MAX_QUEUED_FRAMES 20 21 #define IB fInputBuffs[fInputBuffIndex] 22 23 24 CamBufferingDeframer::CamBufferingDeframer(CamDevice *device) 25 : CamDeframer(device), 26 fInputBuffIndex(0) 27 { 28 } 29 30 31 CamBufferingDeframer::~CamBufferingDeframer() 32 { 33 } 34 35 36 ssize_t 37 CamBufferingDeframer::Write(const void *buffer, size_t size) 38 { 39 uint8 *b; 40 int l; 41 int i, s, e; 42 int which; 43 fMinFrameSize = fDevice->MinRawFrameSize(); 44 fMaxFrameSize = fDevice->MaxRawFrameSize(); 45 IB.Write(buffer, size); 46 b = (uint8 *)IB.Buffer(); 47 l = IB.BufferLength(); 48 49 PRINT((CH "(%p, %d), IB: %d" CT, buffer, size, IB.BufferLength())); 50 51 if (l < (int)(fMinFrameSize + fSkipSOFTags + fSkipEOFTags)) 52 return size; // not enough data anyway 53 54 if (!fCurrentFrame) { 55 BAutolock l(fLocker); 56 if (fFrames.CountItems() < MAXFRAMEBUF) 57 fCurrentFrame = AllocFrame(); 58 else { 59 PRINT((CH "DROPPED %d bytes! (too many queued frames)" CT, size)); 60 return size; // drop XXX 61 } 62 } 63 64 for (s = 0; (l - s > (int)fMinFrameSize) && ((i = FindSOF(b + s, l - fMinFrameSize - s, &which)) > -1); s++) { 65 s += i; 66 if ((int)(s + fSkipSOFTags + fMinFrameSize + fSkipEOFTags) > l) 67 break; 68 if (!fDevice->ValidateStartOfFrameTag(b + s, fSkipSOFTags)) 69 continue; 70 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])); 73 74 for (e = s + fSkipSOFTags + fMinFrameSize; 75 ((e <= (int)(s + fSkipSOFTags + fMaxFrameSize)) && 76 (e < l) && ((i = 0*FindEOF(b + e, l - e, &which)) > -1)); 77 e++) { 78 e += i; 79 80 //PRINT((CH ": EOF[%d] at offset %d" CT, which, s)); 81 if (!fDevice->ValidateEndOfFrameTag(b + e, fSkipEOFTags, e - s - fSkipSOFTags)) 82 continue; 83 84 85 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])); 87 88 // we have one! 89 s += fSkipSOFTags; 90 91 // fill it 92 fCurrentFrame->Write(b + s, e - s); 93 94 // queue it 95 BAutolock f(fLocker); 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); 104 105 return size; 106 } 107 } 108 return size; 109 } 110 111 112 size_t 113 CamBufferingDeframer::DiscardFromInput(size_t size) 114 { 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) { 121 buff += size; 122 fInputBuffs[next].Write(buff, IB.BufferLength() - size); 123 } 124 IB.Seek(0LL, SEEK_SET); 125 IB.SetSize(0); 126 fInputBuffIndex = next; 127 return size; 128 } 129