63 explicit SemGuardLock(sem_t& mutex)
66 auto ret = ::sem_wait(&m_);
68 throw std::logic_error {fmt::format(
"SHM mutex@{} lock failed ({})", fmt::ptr(&m_), ret)};
72 ~SemGuardLock() { ::sem_post(&m_); }
81 ShmHolder(
const std::string& name = {});
84 std::string name() const noexcept {
return openedName_; }
86 void renderFrame(
const VideoFrame& src)
noexcept;
89 bool resizeArea(std::size_t desired_length)
noexcept;
90 char* getShmAreaDataPtr() noexcept;
92 void unMapShmArea() noexcept
94 if (area_ != MAP_FAILED and ::munmap(area_, areaSize_) < 0) {
95 JAMI_ERR(
"[ShmHolder:%s] munmap(%zu) failed with errno %d", openedName_.c_str(), areaSize_, errno);
100 std::size_t areaSize_ {0};
101 std::string openedName_;
105ShmHolder::ShmHolder(
const std::string& name)
111 throw std::runtime_error {fmt::format(
"ShmHolder[{}]: {} failed, errno={}",
openedName_,
what,
errno)};
114 if (
not name.empty()) {
120 for (
int i = 0;
fd_ < 0; ++
i) {
144ShmHolder::~ShmHolder()
156 area_->frameSize = 0;
164ShmHolder::resizeArea(std::size_t frameSize)
noexcept
167 frameSize = (frameSize + 15) & ~15;
196 area_->frameSize = frameSize;
202 auto p =
reinterpret_cast<std::uintptr_t
>(
area_->data);
203 area_->writeOffset = ((p + 15) & ~15) - p;
204 area_->readOffset =
area_->writeOffset + frameSize;
213 const auto width =
src.width();
214 const auto height =
src.height();
219 JAMI_ERR(
"[ShmHolder:%s] Unable to resize area size: %dx%d, format: %d",
239 std::swap(
area_->readOffset,
area_->writeOffset);
260 shm_ = std::make_shared<ShmHolder>();
262 }
catch (
const std::runtime_error&
e) {
263 JAMI_ERR(
"[Sink:%p] Failed to create shared memory: %s",
this,
e.what());
267 return static_cast<bool>(
shm_);
316SinkClient::configureFrameDirect(
const std::shared_ptr<jami::MediaFrame>&
frame_p)
321 if (crop_.w || crop_.h) {
329 std::shared_ptr<VideoFrame>
frame = std::make_shared<VideoFrame>();
333 }
catch (
const std::runtime_error&
e) {
334 JAMI_ERR(
"[Sink:%p] Transfer to hardware acceleration memory failed: %s",
this,
e.what());
363std::shared_ptr<VideoFrame>
366 std::shared_ptr<VideoFrame>
frame = std::make_shared<VideoFrame>();
372 }
catch (
const std::runtime_error&
e) {
373 JAMI_ERR(
"[Sink:%p] Transfer to hardware acceleration memory failed: %s",
this,
e.what());
381 if (
angle != rotation_) {
387 frame = std::static_pointer_cast<VideoFrame>(std::shared_ptr<MediaFrame>(filter_->readOutput()));
389 if (crop_.w || crop_.h) {
390 frame->pointer()->crop_top = crop_.y;
391 frame->pointer()->crop_bottom = (
size_t)
frame->height() - crop_.y - crop_.h;
392 frame->pointer()->crop_left = crop_.x;
403 auto currentTime = std::chrono::steady_clock::now();
406 if (
seconds > std::chrono::seconds(1)) {
414 std::unique_lock lock(mtx_);
440 auto frame = applyTransform(*std::static_pointer_cast<VideoFrame>(
frame_p));
444 notify(std::static_pointer_cast<MediaFrame>(
frame));
446 if (
frame->height() != height_ ||
frame->width() != width_) {
456 sendFrameTransformed(
frame->pointer());
465 if (width > 0
and height > 0) {
466 JAMI_DBG(
"[Sink:%p] Started - size=%dx%d, mixer=%s",
this, width, height, mixer_ ?
"Yes" :
"No");
469 }
else if (started_) {
470 JAMI_DBG(
"[Sink:%p] Stopped - size=%dx%d, mixer=%s",
this, width, height, mixer_ ?
"Yes" :
"No");
479 if (x != crop_.x || y != crop_.y || w != crop_.w || h != crop_.h) {
480 JAMI_DBG(
"[Sink:%p] Change crop to [%dx%d at (%d, %d)]",
this, w, h, x, y);
size_t getObserversCount()
static std::unique_ptr< VideoFrame > transferToMainMemory(const VideoFrame &frame, AVPixelFormat desiredFormat)
Transfers hardware frame to main memory.
void setCrop(int x, int y, int w, int h)
const std::string & getId() const noexcept
SinkClient(const std::string &id="", bool mixer=false)
void update(Observable< std::shared_ptr< jami::MediaFrame > > *, const std::shared_ptr< jami::MediaFrame > &) override
std::string openedName() const noexcept
void setFrameSize(int width, int height)
void setFromMemory(uint8_t *data, int format, int width, int height) noexcept
#define JAMI_WARNING(formatstr,...)
std::unique_ptr< MediaFilter > getTransposeFilter(int rotation, std::string inputName, int width, int height, int format, bool rescale)
const constexpr char FILTER_INPUT_NAME[]
void emitSignal(Args... args)
libjami::VideoFrame VideoFrame
std::unique_ptr< AVFrame, AVFrame_deleter > FrameBuffer
std::function< FrameBuffer()> pull
std::function< void(FrameBuffer)> push