#pragma once #include #include inline void Enforce(bool eval, const std::string& msg) { if (!eval) { throw std::runtime_error {msg}; } } inline void CopyNal(std::vector& v, const uint8_t* buf, size_t sz) noexcept { v.resize(sz+4); v[0] = 0; v[1] = 0; v[2] = 0; v[3] = 1; std::memcpy(&v[4], buf, sz); } struct Frame { std::vector Y; std::vector U; std::vector V; int32_t w, h; int32_t hw, hh; Frame() = default; Frame(uint8_t* yuv[3], const SBufferInfo& frame) { w = static_cast(frame.UsrData.sSystemBuffer.iWidth); h = static_cast(frame.UsrData.sSystemBuffer.iHeight); hw = w/2; hh = h/2; const auto ystride = static_cast(frame.UsrData.sSystemBuffer.iStride[0]); const auto uvstride = static_cast(frame.UsrData.sSystemBuffer.iStride[1]); Y.resize(w*h); for (int32_t y = 0; y < h; ++y) { const auto src = yuv[0] + y*ystride; const auto dst = Y.data() + y*w; std::memcpy(dst, src, w); } U.resize(hw*hh); V.resize(hw*hh); for (int32_t y = 0; y < hh; ++y) { const auto offset = y*uvstride; const auto srcu = yuv[1] + y*uvstride; const auto srcv = yuv[2] + y*uvstride; const auto dstu = U.data() + y*hw; const auto dstv = V.data() + y*hw; std::memcpy(dstu, srcu, hw); std::memcpy(dstv, srcv, hw); } } SSourcePicture GetSourcePic() noexcept { SSourcePicture ret; ret.iPicWidth = w; ret.iPicHeight = h; ret.iColorFormat = videoFormatI420; ret.iStride[0] = w; ret.iStride[1] = hw; ret.iStride[2] = hw; ret.pData[0] = Y.data(); ret.pData[1] = U.data(); ret.pData[2] = V.data(); return ret; } };