Main frame processing
| 233 | |
| 234 | // Main frame processing |
| 235 | std::shared_ptr<Frame> Sharpen::GetFrame( |
| 236 | std::shared_ptr<Frame> frame, int64_t frame_number) |
| 237 | { |
| 238 | auto img = frame->GetImage(); |
| 239 | if (!img || img->isNull()) |
| 240 | return frame; |
| 241 | if (img->format() != QImage::Format_ARGB32) |
| 242 | *img = img->convertToFormat(QImage::Format_ARGB32); |
| 243 | |
| 244 | int W = img->width(); |
| 245 | int H = img->height(); |
| 246 | if (W <= 0 || H <= 0) |
| 247 | return frame; |
| 248 | |
| 249 | // Retrieve keyframe values |
| 250 | double amt = amount.GetValue(frame_number); // 0–40 |
| 251 | double rpx = radius.GetValue(frame_number); // px |
| 252 | double thrUI = threshold.GetValue(frame_number); // 0–1 |
| 253 | |
| 254 | // Sigma scaled against 720p reference |
| 255 | double sigma = std::max(0.1, rpx * H / 720.0); |
| 256 | |
| 257 | // Generate blurred image |
| 258 | QImage blur(W, H, QImage::Format_ARGB32); |
| 259 | gauss_blur(*img, blur, sigma); |
| 260 | |
| 261 | // Precompute maximum luma difference for adaptive threshold |
| 262 | int bplS = img->bytesPerLine(); |
| 263 | int bplB = blur.bytesPerLine(); |
| 264 | uchar* sBits = img->bits(); |
| 265 | uchar* bBits = blur.bits(); |
| 266 | |
| 267 | double maxDY = 0.0; |
| 268 | #pragma omp parallel for reduction(max:maxDY) |
| 269 | for (int y = 0; y < H; ++y) { |
| 270 | uchar* sRow = sBits + y * bplS; |
| 271 | uchar* bRow = bBits + y * bplB; |
| 272 | for (int x = 0; x < W; ++x) { |
| 273 | double dB = double(sRow[x*4+0]) - double(bRow[x*4+0]); |
| 274 | double dG = double(sRow[x*4+1]) - double(bRow[x*4+1]); |
| 275 | double dR = double(sRow[x*4+2]) - double(bRow[x*4+2]); |
| 276 | double dY = std::abs(0.114*dB + 0.587*dG + 0.299*dR); |
| 277 | maxDY = std::max(maxDY, dY); |
| 278 | } |
| 279 | } |
| 280 | |
| 281 | // Compute actual threshold in luma units |
| 282 | double thr = thrUI * maxDY; |
| 283 | |
| 284 | // Process pixels |
| 285 | #pragma omp parallel for |
| 286 | for (int y = 0; y < H; ++y) { |
| 287 | uchar* sRow = sBits + y * bplS; |
| 288 | uchar* bRow = bBits + y * bplB; |
| 289 | for (int x = 0; x < W; ++x) { |
| 290 | uchar* sp = sRow + x*4; |
| 291 | uchar* bp = bRow + x*4; |
| 292 |
nothing calls this directly
no test coverage detected