/* * Copyright 2004-2008, François Revol, . * Distributed under the terms of the MIT License. */ #define CD_COL "31" #include "CamDeframer.h" #include "CamDevice.h" #include "CamDebug.h" #include #define MAX_TAG_LEN CAMDEFRAMER_MAX_TAG_LEN #define MAXFRAMEBUF CAMDEFRAMER_MAX_QUEUED_FRAMES CamDeframer::CamDeframer(CamDevice *device) : CamFilterInterface(device), fDevice(device), fState(ST_SYNC), fFrameSem(B_ERROR), fLocker("CamDeframer Framelist lock", true), fSOFTags(NULL), fEOFTags(NULL), fNumSOFTags(0), fNumEOFTags(0), fLenSOFTags(0), fLenEOFTags(0), fSkipSOFTags(0), fSkipEOFTags(0) { fMinFrameSize = fDevice->MinRawFrameSize(); fMaxFrameSize = fDevice->MaxRawFrameSize(); fFrameSem = create_sem(0, "CamDeframer sem"); fCurrentFrame = AllocFrame(); } CamDeframer::~CamDeframer() { delete_sem(fFrameSem); BAutolock l(fLocker); delete fCurrentFrame; } ssize_t CamDeframer::Read(void *buffer, size_t size) { BAutolock l(fLocker); CamFrame *f = (CamFrame *)fFrames.ItemAt(0); if (!f) return EIO; return f->Read(buffer, size); } ssize_t CamDeframer::ReadAt(off_t pos, void *buffer, size_t size) { BAutolock l(fLocker); CamFrame *f = (CamFrame *)fFrames.ItemAt(0); if (!f) return EIO; return f->ReadAt(pos, buffer, size); } off_t CamDeframer::Seek(off_t position, uint32 seek_mode) { BAutolock l(fLocker); CamFrame *f = (CamFrame *)fFrames.ItemAt(0); if (!f) return EIO; return f->Seek(position, seek_mode); } off_t CamDeframer::Position() const { BAutolock l((BLocker &)fLocker); // need to get rid of const here CamFrame *f = (CamFrame *)fFrames.ItemAt(0); if (!f) return EIO; return f->Position(); } status_t CamDeframer::SetSize(off_t size) { (void)size; return EINVAL; } ssize_t CamDeframer::Write(const void *buffer, size_t size) { (void)buffer; (void)size; return EINVAL; } ssize_t CamDeframer::WriteAt(off_t pos, const void *buffer, size_t size) { (void)pos; (void)buffer; (void)size; return EINVAL; } status_t CamDeframer::WaitFrame(bigtime_t timeout) { return acquire_sem_etc(fFrameSem, 1, B_RELATIVE_TIMEOUT, timeout); } status_t CamDeframer::GetFrame(CamFrame **frame, bigtime_t *stamp) { PRINT((CH "()" CT)); BAutolock l(fLocker); CamFrame *f = (CamFrame *)fFrames.RemoveItem((int32)0); if (!f) return ENOENT; *frame = f; *stamp = f->Stamp(); return B_OK; } status_t CamDeframer::DropFrame() { PRINT((CH "()" CT)); BAutolock l(fLocker); CamFrame *f = (CamFrame *)fFrames.RemoveItem((int32)0); if (!f) return ENOENT; delete f; return B_OK; } status_t CamDeframer::RegisterSOFTags(const uint8 **tags, int count, size_t len, size_t skip) { if (fSOFTags) return EALREADY; if (len > MAX_TAG_LEN) return EINVAL; if (count > 16) return EINVAL; fSOFTags = tags; fNumSOFTags = count; fLenSOFTags = len; fSkipSOFTags = skip; return B_OK; } status_t CamDeframer::RegisterEOFTags(const uint8 **tags, int count, size_t len, size_t skip) { if (fEOFTags) return EALREADY; if (len > MAX_TAG_LEN) return EINVAL; if (count > 16) return EINVAL; fEOFTags = tags; fNumEOFTags = count; fLenEOFTags = len; fSkipEOFTags = skip; return B_OK; } int CamDeframer::FindTags(const uint8 *buf, size_t buflen, const uint8 **tags, int tagcount, size_t taglen, size_t skiplen, int *which) { int i, t; for (i = 0; i < (int)(buflen - skiplen + 1); i++) { for (t = 0; t < tagcount; t++) { if (!memcmp(buf+i, tags[t], taglen)) { if (which) *which = t; return i; } } } return -1; } int CamDeframer::FindSOF(const uint8 *buf, size_t buflen, int *which) { return FindTags(buf, buflen, fSOFTags, fNumSOFTags, fLenSOFTags, fSkipSOFTags, which); } int CamDeframer::FindEOF(const uint8 *buf, size_t buflen, int *which) { return FindTags(buf, buflen, fEOFTags, fNumEOFTags, fLenEOFTags, fSkipEOFTags, which); } CamFrame * CamDeframer::AllocFrame() { return new CamFrame(); }