| 46 | static inline float lerp(float a, float b, float t) { return a + (b - a) * t; } |
| 47 | |
| 48 | std::shared_ptr<Frame> AnalogTape::GetFrame(std::shared_ptr<Frame> frame, |
| 49 | int64_t frame_number) { |
| 50 | std::shared_ptr<QImage> img = frame->GetImage(); |
| 51 | int w = img->width(); |
| 52 | int h = img->height(); |
| 53 | int Uw = (w + 1) / 2; |
| 54 | int stride = img->bytesPerLine() / 4; |
| 55 | uint32_t *base = reinterpret_cast<uint32_t *>(img->bits()); |
| 56 | |
| 57 | if (w != last_w || h != last_h) { |
| 58 | last_w = w; |
| 59 | last_h = h; |
| 60 | Y.resize(w * h); |
| 61 | U.resize(Uw * h); |
| 62 | V.resize(Uw * h); |
| 63 | tmpY.resize(w * h); |
| 64 | tmpU.resize(Uw * h); |
| 65 | tmpV.resize(Uw * h); |
| 66 | dx.resize(h); |
| 67 | } |
| 68 | |
| 69 | |
| 70 | #ifdef _OPENMP |
| 71 | #pragma omp parallel for |
| 72 | #endif |
| 73 | for (int y = 0; y < h; ++y) { |
| 74 | uint32_t *row = base + y * stride; |
| 75 | float *yrow = &Y[y * w]; |
| 76 | float *urow = &U[y * Uw]; |
| 77 | float *vrow = &V[y * Uw]; |
| 78 | for (int x2 = 0; x2 < Uw; ++x2) { |
| 79 | int x0 = x2 * 2; |
| 80 | uint32_t p0 = row[x0]; |
| 81 | float r0 = ((p0 >> 16) & 0xFF) / 255.0f; |
| 82 | float g0 = ((p0 >> 8) & 0xFF) / 255.0f; |
| 83 | float b0 = (p0 & 0xFF) / 255.0f; |
| 84 | float y0 = 0.299f * r0 + 0.587f * g0 + 0.114f * b0; |
| 85 | float u0 = -0.14713f * r0 - 0.28886f * g0 + 0.436f * b0; |
| 86 | float v0 = 0.615f * r0 - 0.51499f * g0 - 0.10001f * b0; |
| 87 | yrow[x0] = y0; |
| 88 | |
| 89 | float u, v; |
| 90 | if (x0 + 1 < w) { |
| 91 | uint32_t p1 = row[x0 + 1]; |
| 92 | float r1 = ((p1 >> 16) & 0xFF) / 255.0f; |
| 93 | float g1 = ((p1 >> 8) & 0xFF) / 255.0f; |
| 94 | float b1 = (p1 & 0xFF) / 255.0f; |
| 95 | float y1 = 0.299f * r1 + 0.587f * g1 + 0.114f * b1; |
| 96 | float u1 = -0.14713f * r1 - 0.28886f * g1 + 0.436f * b1; |
| 97 | float v1 = 0.615f * r1 - 0.51499f * g1 - 0.10001f * b1; |
| 98 | yrow[x0 + 1] = y1; |
| 99 | u = (u0 + u1) * 0.5f; |
| 100 | v = (v0 + v1) * 0.5f; |
| 101 | } else { |
| 102 | u = u0; |
| 103 | v = v0; |
| 104 | } |
| 105 | urow[x2] = u; |