1 /* 2 * Copyright 2004-2008, François Revol, <revol@free.fr>. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #define CD_COL "31" 7 #include "CamDeframer.h" 8 #include "CamDevice.h" 9 #include "CamDebug.h" 10 #include <Autolock.h> 11 #define MAX_TAG_LEN CAMDEFRAMER_MAX_TAG_LEN 12 #define MAXFRAMEBUF CAMDEFRAMER_MAX_QUEUED_FRAMES 13 14 15 CamDeframer::CamDeframer(CamDevice *device) 16 : CamFilterInterface(device), 17 fDevice(device), 18 fState(ST_SYNC), 19 fFrameSem(B_ERROR), 20 fLocker("CamDeframer Framelist lock", true), 21 fSOFTags(NULL), 22 fEOFTags(NULL), 23 fNumSOFTags(0), 24 fNumEOFTags(0), 25 fLenSOFTags(0), 26 fLenEOFTags(0), 27 fSkipSOFTags(0), 28 fSkipEOFTags(0) 29 { 30 fMinFrameSize = fDevice->MinRawFrameSize(); 31 fMaxFrameSize = fDevice->MaxRawFrameSize(); 32 fFrameSem = create_sem(0, "CamDeframer sem"); 33 fCurrentFrame = AllocFrame(); 34 } 35 36 37 CamDeframer::~CamDeframer() 38 { 39 delete_sem(fFrameSem); 40 BAutolock l(fLocker); 41 delete fCurrentFrame; 42 } 43 44 45 ssize_t 46 CamDeframer::Read(void *buffer, size_t size) 47 { 48 BAutolock l(fLocker); 49 CamFrame *f = (CamFrame *)fFrames.ItemAt(0); 50 if (!f) 51 return EIO; 52 return f->Read(buffer, size); 53 } 54 55 56 ssize_t 57 CamDeframer::ReadAt(off_t pos, void *buffer, size_t size) 58 { 59 BAutolock l(fLocker); 60 CamFrame *f = (CamFrame *)fFrames.ItemAt(0); 61 if (!f) 62 return EIO; 63 return f->ReadAt(pos, buffer, size); 64 } 65 66 67 off_t 68 CamDeframer::Seek(off_t position, uint32 seek_mode) 69 { 70 BAutolock l(fLocker); 71 CamFrame *f = (CamFrame *)fFrames.ItemAt(0); 72 if (!f) 73 return EIO; 74 return f->Seek(position, seek_mode); 75 } 76 77 78 off_t 79 CamDeframer::Position() const 80 { 81 BAutolock l((BLocker &)fLocker); // need to get rid of const here 82 CamFrame *f = (CamFrame *)fFrames.ItemAt(0); 83 if (!f) 84 return EIO; 85 return f->Position(); 86 } 87 88 89 status_t 90 CamDeframer::SetSize(off_t size) 91 { 92 (void)size; 93 return EINVAL; 94 } 95 96 97 ssize_t 98 CamDeframer::Write(const void *buffer, size_t size) 99 { 100 (void)buffer; 101 (void)size; 102 return EINVAL; 103 } 104 105 106 ssize_t 107 CamDeframer::WriteAt(off_t pos, const void *buffer, size_t size) 108 { 109 (void)pos; 110 (void)buffer; 111 (void)size; 112 return EINVAL; 113 } 114 115 116 status_t 117 CamDeframer::WaitFrame(bigtime_t timeout) 118 { 119 return acquire_sem_etc(fFrameSem, 1, B_RELATIVE_TIMEOUT, timeout); 120 } 121 122 123 status_t 124 CamDeframer::GetFrame(CamFrame **frame, bigtime_t *stamp) 125 { 126 PRINT((CH "()" CT)); 127 BAutolock l(fLocker); 128 CamFrame *f = (CamFrame *)fFrames.RemoveItem((int32)0); 129 if (!f) 130 return ENOENT; 131 *frame = f; 132 *stamp = f->Stamp(); 133 return B_OK; 134 } 135 136 137 status_t 138 CamDeframer::DropFrame() 139 { 140 PRINT((CH "()" CT)); 141 BAutolock l(fLocker); 142 CamFrame *f = (CamFrame *)fFrames.RemoveItem((int32)0); 143 if (!f) 144 return ENOENT; 145 delete f; 146 return B_OK; 147 } 148 149 150 status_t 151 CamDeframer::RegisterSOFTags(const uint8 **tags, int count, size_t len, size_t skip) 152 { 153 if (fSOFTags) 154 return EALREADY; 155 if (len > MAX_TAG_LEN) 156 return EINVAL; 157 if (count > 16) 158 return EINVAL; 159 fSOFTags = tags; 160 fNumSOFTags = count; 161 fLenSOFTags = len; 162 fSkipSOFTags = skip; 163 return B_OK; 164 } 165 166 167 status_t 168 CamDeframer::RegisterEOFTags(const uint8 **tags, int count, size_t len, size_t skip) 169 { 170 if (fEOFTags) 171 return EALREADY; 172 if (len > MAX_TAG_LEN) 173 return EINVAL; 174 if (count > 16) 175 return EINVAL; 176 fEOFTags = tags; 177 fNumEOFTags = count; 178 fLenEOFTags = len; 179 fSkipEOFTags = skip; 180 return B_OK; 181 } 182 183 184 int 185 CamDeframer::FindTags(const uint8 *buf, size_t buflen, const uint8 **tags, int tagcount, size_t taglen, size_t skiplen, int *which) 186 { 187 int i, t; 188 for (i = 0; i < (int)(buflen - skiplen + 1); i++) { 189 for (t = 0; t < tagcount; t++) { 190 if (!memcmp(buf+i, tags[t], taglen)) { 191 if (which) 192 *which = t; 193 return i; 194 } 195 } 196 } 197 return -1; 198 } 199 200 201 int 202 CamDeframer::FindSOF(const uint8 *buf, size_t buflen, int *which) 203 { 204 return FindTags(buf, buflen, fSOFTags, fNumSOFTags, fLenSOFTags, fSkipSOFTags, which); 205 } 206 207 208 int 209 CamDeframer::FindEOF(const uint8 *buf, size_t buflen, int *which) 210 { 211 return FindTags(buf, buflen, fEOFTags, fNumEOFTags, fLenEOFTags, fSkipEOFTags, which); 212 } 213 214 215 CamFrame * 216 CamDeframer::AllocFrame() 217 { 218 return new CamFrame(); 219 } 220 221