void Yuv420pToBgr(const uint8_t * y, size_t yStride, const uint8_t * u, size_t uStride, const uint8_t * v, size_t vStride, size_t width, size_t height, uint8_t * bgr, size_t bgrStride) { assert((width%2 == 0) && (height%2 == 0) && (width >= 2) && (height >= 2)); for(size_t row = 0; row < height; row += 2) { for(size_t colUV = 0, colY = 0, colBgr = 0; colY < width; colY += 2, colUV++, colBgr += 6) { int u_ = u[colUV]; int v_ = v[colUV]; Yuv420pToBgr(y + colY, u_, v_, bgr + colBgr); Yuv420pToBgr(y + yStride + colY, u_, v_, bgr + bgrStride + colBgr); } y += 2*yStride; u += uStride; v += vStride; bgr += 2*bgrStride; } }
template <class A> SIMD_INLINE void Convert(const Frame<A> & src, Frame<A> & dst) { assert(EqualSize(src, dst) && src.format && dst.format); if (src.format == dst.format) { Copy(src, dst); return; } switch (src.format) { case Frame<A>::Nv12: switch (dst.format) { case Frame<A>::Yuv420p: Copy(src.planes[0], dst.planes[0]); DeinterleaveUv(src.planes[1], dst.planes[1], dst.planes[2]); break; case Frame<A>::Bgra32: { View<A> u(src.Size(), View<A>::Gray8), v(src.Size(), View<A>::Gray8); DeinterleaveUv(src.planes[1], u, v); Yuv420pToBgra(src.planes[0], u, v, dst.planes[0]); break; } case Frame<A>::Bgr24: { View<A> u(src.Size(), View<A>::Gray8), v(src.Size(), View<A>::Gray8); DeinterleaveUv(src.planes[1], u, v); Yuv420pToBgr(src.planes[0], u, v, dst.planes[0]); break; } case Frame<A>::Gray8: Copy(src.planes[0], dst.planes[0]); break; default: assert(0); } break; case Frame<A>::Yuv420p: switch (dst.format) { case Frame<A>::Nv12: Copy(src.planes[0], dst.planes[0]); InterleaveUv(src.planes[1], src.planes[2], dst.planes[1]); break; case Frame<A>::Bgra32: Yuv420pToBgra(src.planes[0], src.planes[1], src.planes[2], dst.planes[0]); break; case Frame<A>::Bgr24: Yuv420pToBgr(src.planes[0], src.planes[1], src.planes[2], dst.planes[0]); break; case Frame<A>::Gray8: Copy(src.planes[0], dst.planes[0]); break; default: assert(0); } break; case Frame<A>::Bgra32: switch (dst.format) { case Frame<A>::Nv12: { View<A> u(src.Size(), View<A>::Gray8), v(src.Size(), View<A>::Gray8); BgraToYuv420p(src.planes[0], dst.planes[0], u, v); InterleaveUv(u, v, dst.planes[1]); break; } case Frame<A>::Yuv420p: BgraToYuv420p(src.planes[0], dst.planes[0], dst.planes[1], dst.planes[2]); break; case Frame<A>::Bgr24: BgraToBgr(src.planes[0], dst.planes[0]); break; case Frame<A>::Gray8: BgraToGray(src.planes[0], dst.planes[0]); break; default: assert(0); } break; case Frame<A>::Bgr24: switch (dst.format) { case Frame<A>::Nv12: { View<A> u(src.Size(), View<A>::Gray8), v(src.Size(), View<A>::Gray8); BgrToYuv420p(src.planes[0], dst.planes[0], u, v); InterleaveUv(u, v, dst.planes[1]); break; } case Frame<A>::Yuv420p: BgrToYuv420p(src.planes[0], dst.planes[0], dst.planes[1], dst.planes[2]); break; case Frame<A>::Bgra32: BgrToBgra(src.planes[0], dst.planes[0]); break; case Frame<A>::Gray8: BgrToGray(src.planes[0], dst.planes[0]); break; default: assert(0); } break; case Frame<A>::Gray8: switch (dst.format) { case Frame<A>::Nv12: Copy(src.planes[0], dst.planes[0]); Fill(dst.planes[1], 128); case Frame<A>::Yuv420p: Copy(src.planes[0], dst.planes[0]); Fill(dst.planes[1], 128); Fill(dst.planes[2], 128); break; case Frame<A>::Bgra32: GrayToBgra(src.planes[0], dst.planes[0]); break; case Frame<A>::Bgr24: GrayToBgr(src.planes[0], dst.planes[0]); break; default: assert(0); } break; default: assert(0); } }