65 explicit SemGuardLock(sem_t& mutex)
68 auto ret = ::sem_wait(&m_);
70 std::ostringstream msg;
71 msg <<
"SHM mutex@" << &m_ <<
" lock failed (" << ret <<
")";
72 throw std::logic_error {msg.str()};
76 ~SemGuardLock() { ::sem_post(&m_); }
85 ShmHolder(
const std::string& name = {});
88 std::string name() const noexcept {
return openedName_; }
90 void renderFrame(
const VideoFrame& src)
noexcept;
93 bool resizeArea(std::size_t desired_length)
noexcept;
94 char* getShmAreaDataPtr() noexcept;
96 void unMapShmArea() noexcept
98 if (area_ != MAP_FAILED and ::munmap(area_, areaSize_) < 0) {
99 JAMI_ERR(
"[ShmHolder:%s] munmap(%zu) failed with errno %d",
107 std::size_t areaSize_ {0};
108 std::string openedName_;
112ShmHolder::ShmHolder(
const std::string& name)
118 std::ostringstream
msg;
120 throw std::runtime_error {
msg.str()};
123 if (
not name.empty()) {
129 for (
int i = 0;
fd_ < 0; ++
i) {
155ShmHolder::~ShmHolder()
167 area_->frameSize = 0;
175ShmHolder::resizeArea(std::size_t frameSize)
noexcept
178 frameSize = (frameSize + 15) & ~15;
190 JAMI_ERR(
"[ShmHolder:%s] ftruncate(%zu) failed with errno %d",
202 JAMI_ERR(
"[ShmHolder:%s] mmap(%zu) failed with errno %d",
214 area_->frameSize = frameSize;
220 auto p =
reinterpret_cast<std::uintptr_t
>(
area_->data);
221 area_->writeOffset = ((p + 15) & ~15) - p;
222 area_->readOffset =
area_->writeOffset + frameSize;
231 const auto width =
src.width();
232 const auto height =
src.height();
237 JAMI_ERR(
"[ShmHolder:%s] Unable to resize area size: %dx%d, format: %d",
257 std::swap(
area_->readOffset,
area_->writeOffset);
278 shm_ = std::make_shared<ShmHolder>();
280 }
catch (
const std::runtime_error&
e) {
281 JAMI_ERR(
"[Sink:%p] Failed to create shared memory: %s",
this,
e.what());
285 return static_cast<bool>(
shm_);
334SinkClient::sendFrameDirect(
const std::shared_ptr<jami::MediaFrame>&
frame_p)
341 if (crop_.w || crop_.h) {
350 std::shared_ptr<VideoFrame>
frame = std::make_shared<VideoFrame>();
355 }
catch (
const std::runtime_error&
e) {
356 JAMI_ERR(
"[Sink:%p] Transfert to hardware acceleration memory failed: %s",
391std::shared_ptr<VideoFrame>
394 std::shared_ptr<VideoFrame>
frame = std::make_shared<VideoFrame>();
400 }
catch (
const std::runtime_error&
e) {
401 JAMI_ERR(
"[Sink:%p] Transfert to hardware acceleration memory failed: %s",
411 if (
angle != rotation_) {
422 frame = std::static_pointer_cast<VideoFrame>(
423 std::shared_ptr<MediaFrame>(filter_->readOutput()));
425 if (crop_.w || crop_.h) {
426 frame->pointer()->crop_top = crop_.y;
427 frame->pointer()->crop_bottom = (
size_t)
frame->height() - crop_.y - crop_.h;
428 frame->pointer()->crop_left = crop_.x;
437 const std::shared_ptr<MediaFrame>&
frame_p)
440 auto currentTime = std::chrono::steady_clock::now();
443 if (
seconds > std::chrono::seconds(1)) {
451 std::unique_lock lock(mtx_);
467 auto frame = applyTransform(*std::static_pointer_cast<VideoFrame>(
frame_p));
471 notify(std::static_pointer_cast<MediaFrame>(
frame));
473 if (
frame->height() != height_ ||
frame->width() != width_) {
483 sendFrameTransformed(
frame->pointer());
492 if (width > 0
and height > 0) {
493 JAMI_DBG(
"[Sink:%p] Started - size=%dx%d, mixer=%s",
497 mixer_ ?
"Yes" :
"No");
504 }
else if (started_) {
505 JAMI_DBG(
"[Sink:%p] Stopped - size=%dx%d, mixer=%s",
509 mixer_ ?
"Yes" :
"No");
518 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