81 lines
1.9 KiB
C++
81 lines
1.9 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <cstring>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <codec/api/wels/codec_api.h>
|
|
|
|
|
|
inline void Enforce(bool eval, const std::string& msg) {
|
|
if (!eval) {
|
|
throw std::runtime_error {msg};
|
|
}
|
|
}
|
|
|
|
inline void CopyNal(std::vector<uint8_t>& 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<uint8_t> Y;
|
|
std::vector<uint8_t> U;
|
|
std::vector<uint8_t> V;
|
|
|
|
int32_t w, h;
|
|
int32_t hw, hh;
|
|
|
|
Frame() = default;
|
|
Frame(uint8_t* yuv[3], const SBufferInfo& frame) {
|
|
w = static_cast<int32_t>(frame.UsrData.sSystemBuffer.iWidth);
|
|
h = static_cast<int32_t>(frame.UsrData.sSystemBuffer.iHeight);
|
|
hw = w/2;
|
|
hh = h/2;
|
|
|
|
const auto ystride = static_cast<int32_t>(frame.UsrData.sSystemBuffer.iStride[0]);
|
|
const auto uvstride = static_cast<int32_t>(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;
|
|
}
|
|
};
|