#pragma once #include #include #include class FrameAssembler { public: // ×·¼ÓÒ»¿éԭʼ×Ö½Ú void push(const std::vector& chunk) { buf_.insert(buf_.end(), chunk.begin(), chunk.end()); } void push(const uint8_t* p, size_t n) { buf_.insert(buf_.end(), p, p + n); } // ÌáÈ¡ÏÂÒ»Ö¡£»·µ»Ø true ±íʾ out Äõ½ÁËÒ»Ö¡ÍêÕûÊý¾Ý bool nextFrame(std::vector& out) { const uint8_t HEAD[4] = { 0x11,0x88,0x11,0x88 }; const uint8_t TAIL = 0x88; for (;;) { // ÐèÒªÖÁÉÙ 4B Í· + 4B dataId + 2B len + 1B β = 11B if (buf_.size() < 11) return false; // ÕÒͷͬ²½ size_t i = 0; while (i + 4 <= buf_.size() && !std::equal(HEAD, HEAD + 4, buf_.begin() + i)) ++i; if (i + 4 > buf_.size()) { // ûÕÒµ½Í·£¬Çå¿Õ buf_.clear(); return false; } if (i > 0) buf_.erase(buf_.begin(), buf_.begin() + i); // ¶ªÆúͷǰÔëÉù if (buf_.size() < 11) return false; // »¹²»¹»×îС֡ // ¶ÁÈ¡ÕýÎij¤¶È£¨´ó¶Ë£© uint16_t len = (uint16_t(buf_[8]) << 8) | buf_[9]; size_t total = 4 + 4 + 2 + size_t(len) + 1; // ÕûÖ¡³¤¶È if (buf_.size() < total) return false; // °ëÖ¡£¬µÈÏ´Π// УÑéβ if (buf_[total - 1] != TAIL) { // β²»¶Ô£º¶ªÆúÒ»¸ö×Ö½Ú£¬ÖØÐÂÕÒÍ·£¨±ÜÃâËÀËø£© buf_.erase(buf_.begin()); continue; } // È¡³öÍêÕûÖ¡ out.assign(buf_.begin(), buf_.begin() + total); buf_.erase(buf_.begin(), buf_.begin() + total); return true; } } void clear() { buf_.clear(); } private: std::vector buf_; };