void ShmHolder::renderFrame(VideoFrame& src) noexcept { const auto width = src.width(); const auto height = src.height(); const auto format = VIDEO_PIXFMT_BGRA; const auto frameSize = videoFrameSize(format, width, height); if (!resizeArea(frameSize)) { RING_ERR("ShmHolder[%s]: could not resize area", openedName_.c_str()); return; } { VideoFrame dst; VideoScaler scaler; dst.setFromMemory(area_->data + area_->writeOffset, format, width, height); scaler.scale(src, dst); } { SemGuardLock lk {area_->mutex}; ++area_->frameGen; std::swap(area_->readOffset, area_->writeOffset); ::sem_post(&area_->frameGenMutex); } }
void SinkClient::update(Observable<std::shared_ptr<VideoFrame>>* /*obs*/, const std::shared_ptr<VideoFrame>& frame_p) { auto& f = *frame_p; #ifdef DEBUG_FPS auto currentTime = std::chrono::system_clock::now(); const std::chrono::duration<double> seconds = currentTime - lastFrameDebug_; ++frameCount_; if (seconds.count() > 1) { std::ostringstream fps; fps << frameCount_ / seconds.count(); // Send the framerate in smartInfo Smartools::getInstance().setFrameRate(id_, fps.str()); frameCount_ = 0; lastFrameDebug_ = currentTime; } #endif #if HAVE_SHM // Send the resolution in smartInfo Smartools::getInstance().setResolution(id_, f.width(), f.height()); shm_->renderFrame(f); #endif if (target_.pull) { VideoFrame dst; VideoScaler scaler; const int width = f.width(); const int height = f.height(); #if (defined(__ANDROID__) || defined(__APPLE__)) const int format = VIDEO_PIXFMT_RGBA; #else const int format = VIDEO_PIXFMT_BGRA; #endif const auto bytes = videoFrameSize(format, width, height); if (bytes > 0) { if (auto buffer_ptr = target_.pull(bytes)) { buffer_ptr->format = libav_utils::libav_pixel_format(format); buffer_ptr->width = width; buffer_ptr->height = height; dst.setFromMemory(buffer_ptr->ptr, format, width, height); scaler_->scale(f, dst); target_.push(std::move(buffer_ptr)); } } } }