65 explicit SemGuardLock(sem_t& mutex)
68 auto ret = ::sem_wait(&m_);
70 throw std::logic_error {fmt::format(
"SHM mutex@{} lock failed ({})", fmt::ptr(&m_), ret)};
74 ~SemGuardLock() { ::sem_post(&m_); }
83 ShmHolder(
const std::string& name = {});
86 std::string name() const noexcept {
return openedName_; }
88 void renderFrame(
const VideoFrame& src)
noexcept;
91 bool resizeArea(std::size_t desired_length)
noexcept;
92 char* getShmAreaDataPtr() noexcept;
94 void unMapShmArea() noexcept
96 if (area_ != MAP_FAILED and ::munmap(area_, areaSize_) < 0) {
97 JAMI_ERR(
"[ShmHolder:%s] munmap(%zu) failed with errno %d",
105 std::size_t areaSize_ {0};
106 std::string openedName_;
110ShmHolder::ShmHolder(
const std::string& name)
116 throw std::runtime_error {fmt::format(
"ShmHolder[{}]: {} failed, errno={}",
openedName_,
what,
errno)};
119 if (
not name.empty()) {
125 for (
int i = 0;
fd_ < 0; ++
i) {
149ShmHolder::~ShmHolder()
161 area_->frameSize = 0;
169ShmHolder::resizeArea(std::size_t frameSize)
noexcept
172 frameSize = (frameSize + 15) & ~15;
184 JAMI_ERR(
"[ShmHolder:%s] ftruncate(%zu) failed with errno %d",
196 JAMI_ERR(
"[ShmHolder:%s] mmap(%zu) failed with errno %d",
208 area_->frameSize = frameSize;
214 auto p =
reinterpret_cast<std::uintptr_t
>(
area_->data);
215 area_->writeOffset = ((p + 15) & ~15) - p;
216 area_->readOffset =
area_->writeOffset + frameSize;
225 const auto width =
src.width();
226 const auto height =
src.height();
231 JAMI_ERR(
"[ShmHolder:%s] Unable to resize area size: %dx%d, format: %d",
251 std::swap(
area_->readOffset,
area_->writeOffset);
272 shm_ = std::make_shared<ShmHolder>();
274 }
catch (
const std::runtime_error&
e) {
275 JAMI_ERR(
"[Sink:%p] Failed to create shared memory: %s",
this,
e.what());
279 return static_cast<bool>(
shm_);
328SinkClient::sendFrameDirect(
const std::shared_ptr<jami::MediaFrame>&
frame_p)
335 if (crop_.w || crop_.h) {
344 std::shared_ptr<VideoFrame>
frame = std::make_shared<VideoFrame>();
349 }
catch (
const std::runtime_error&
e) {
350 JAMI_ERR(
"[Sink:%p] Transfert to hardware acceleration memory failed: %s",
385std::shared_ptr<VideoFrame>
388 std::shared_ptr<VideoFrame>
frame = std::make_shared<VideoFrame>();
394 }
catch (
const std::runtime_error&
e) {
395 JAMI_ERR(
"[Sink:%p] Transfert to hardware acceleration memory failed: %s",
405 if (
angle != rotation_) {
416 frame = std::static_pointer_cast<VideoFrame>(
417 std::shared_ptr<MediaFrame>(filter_->readOutput()));
419 if (crop_.w || crop_.h) {
420 frame->pointer()->crop_top = crop_.y;
421 frame->pointer()->crop_bottom = (
size_t)
frame->height() - crop_.y - crop_.h;
422 frame->pointer()->crop_left = crop_.x;
431 const std::shared_ptr<MediaFrame>&
frame_p)
434 auto currentTime = std::chrono::steady_clock::now();
437 if (
seconds > std::chrono::seconds(1)) {
445 std::unique_lock lock(mtx_);
461 auto frame = applyTransform(*std::static_pointer_cast<VideoFrame>(
frame_p));
465 notify(std::static_pointer_cast<MediaFrame>(
frame));
467 if (
frame->height() != height_ ||
frame->width() != width_) {
477 sendFrameTransformed(
frame->pointer());
486 if (width > 0
and height > 0) {
487 JAMI_DBG(
"[Sink:%p] Started - size=%dx%d, mixer=%s",
491 mixer_ ?
"Yes" :
"No");
498 }
else if (started_) {
499 JAMI_DBG(
"[Sink:%p] Stopped - size=%dx%d, mixer=%s",
503 mixer_ ?
"Yes" :
"No");
512 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
Simple macro to hide class' copy constructor and assignment operator.
std::function< FrameBuffer()> pull
std::function< void(FrameBuffer)> push