Ring Daemon 16.0.0
Loading...
Searching...
No Matches
videomanager.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2025 Savoir-faire Linux Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
19#include "videomanager.h"
20#include "localrecorder.h"
22#include "libav_utils.h"
23#include "video/video_input.h"
25#include "account.h"
26#include "logger.h"
27#include "manager.h"
29#ifdef ENABLE_VIDEO
30#include "video/sinkclient.h"
31#endif
32#include "client/ring_signal.h"
34#include "jami/media_const.h"
35#include "libav_utils.h"
36#include "call_const.h"
38
39#include <functional>
40#include <memory>
41#include <string>
42#include <vector>
43#include <new> // std::bad_alloc
44#include <algorithm>
45#include <cstdlib>
46#include <cstring> // std::memset
47#include <ciso646> // fix windows compiler bug
48
49extern "C" {
50#include <libavutil/display.h>
51}
52
53namespace libjami {
54
56 : frame_ {av_frame_alloc()}
57{
58 if (not frame_)
59 throw std::bad_alloc();
60}
61
62void
64{
65 reset();
66 if (o.frame_) {
67 av_frame_ref(frame_.get(), o.frame_.get());
68 av_frame_copy_props(frame_.get(), o.frame_.get());
69 }
70
71 if (o.packet_) {
72 packet_.reset(av_packet_alloc());
73 av_packet_ref(packet_.get(), o.packet_.get());
74 }
75}
76
77void
79{
80 if (frame_)
81 av_frame_unref(frame_.get());
82 packet_.reset();
83}
84
85void
87{
88 packet_ = std::move(pkt);
89}
90
91AudioFrame::AudioFrame(const jami::AudioFormat& format, size_t nb_samples)
92 : MediaFrame()
93{
94 setFormat(format);
95 if (nb_samples)
96 reserve(nb_samples);
97}
98
99void
100AudioFrame::setFormat(const jami::AudioFormat& format)
101{
102 auto d = pointer();
103 av_channel_layout_default(&d->ch_layout, format.nb_channels);
104 d->sample_rate = format.sample_rate;
105 d->format = format.sampleFormat;
106}
107
110{
111 return {(unsigned) frame_->sample_rate,
112 (unsigned) frame_->ch_layout.nb_channels,
113 (AVSampleFormat) frame_->format};
114}
115
116size_t
118{
119 return frame_->nb_samples;
120}
121
122void
123AudioFrame::reserve(size_t nb_samples)
124{
125 if (nb_samples != 0) {
126 auto d = pointer();
127 d->nb_samples = nb_samples;
128 int err;
129 if ((err = av_frame_get_buffer(d, 0)) < 0) {
130 throw std::bad_alloc();
131 }
132 }
133}
134
135void
137{
138 auto& f = *pointer();
139 auto& fIn = *frame.pointer();
140 if (f.ch_layout.nb_channels != fIn.ch_layout.nb_channels || f.format != fIn.format
141 || f.sample_rate != fIn.sample_rate) {
142 throw std::invalid_argument("Unable to mix frames with different formats");
143 }
144 if (f.nb_samples == 0) {
145 reserve(fIn.nb_samples);
147 } else if (f.nb_samples != fIn.nb_samples) {
148 throw std::invalid_argument("Unable to mix frames with different length");
149 }
150 AVSampleFormat fmt = (AVSampleFormat) f.format;
151 bool isPlanar = av_sample_fmt_is_planar(fmt);
152 unsigned samplesPerChannel = isPlanar ? f.nb_samples : f.nb_samples * f.ch_layout.nb_channels;
153 unsigned channels = isPlanar ? f.ch_layout.nb_channels : 1;
154 if (fmt == AV_SAMPLE_FMT_S16 || fmt == AV_SAMPLE_FMT_S16P) {
155 for (unsigned i = 0; i < channels; i++) {
156 auto c = (int16_t*) f.extended_data[i];
157 auto cIn = (int16_t*) fIn.extended_data[i];
158 for (unsigned s = 0; s < samplesPerChannel; s++) {
159 c[s] = std::clamp((int32_t) c[s] + (int32_t) cIn[s],
160 (int32_t) std::numeric_limits<int16_t>::min(),
161 (int32_t) std::numeric_limits<int16_t>::max());
162 }
163 }
164 } else if (fmt == AV_SAMPLE_FMT_FLT || fmt == AV_SAMPLE_FMT_FLTP) {
165 for (unsigned i = 0; i < channels; i++) {
166 auto c = (float*) f.extended_data[i];
167 auto cIn = (float*) fIn.extended_data[i];
168 for (unsigned s = 0; s < samplesPerChannel; s++) {
169 c[s] += cIn[s];
170 }
171 }
172 } else {
173 throw std::invalid_argument(std::string("Unsupported format for mixing: ")
174 + av_get_sample_fmt_name(fmt));
175 }
176}
177
178float
180{
181 double rms = 0.0;
182 auto fmt = static_cast<AVSampleFormat>(frame_->format);
183 bool planar = av_sample_fmt_is_planar(fmt);
184 int perChannel = planar ? frame_->nb_samples
185 : frame_->nb_samples * frame_->ch_layout.nb_channels;
186 int channels = planar ? frame_->ch_layout.nb_channels : 1;
187 if (fmt == AV_SAMPLE_FMT_S16 || fmt == AV_SAMPLE_FMT_S16P) {
188 for (int c = 0; c < channels; ++c) {
189 auto buf = reinterpret_cast<int16_t*>(frame_->extended_data[c]);
190 for (int i = 0; i < perChannel; ++i) {
191 auto sample = buf[i] * 0.000030517578125f;
192 rms += sample * sample;
193 }
194 }
195 } else if (fmt == AV_SAMPLE_FMT_FLT || fmt == AV_SAMPLE_FMT_FLTP) {
196 for (int c = 0; c < channels; ++c) {
197 auto buf = reinterpret_cast<float*>(frame_->extended_data[c]);
198 for (int i = 0; i < perChannel; ++i) {
199 rms += buf[i] * buf[i];
200 }
201 }
202 } else {
203 // Should not happen
204 JAMI_ERR() << "Unsupported format for getting volume level: "
205 << av_get_sample_fmt_name(fmt);
206 return 0.0;
207 }
208 // divide by the number of multi-byte samples
209 return sqrt(rms / (frame_->nb_samples * frame_->ch_layout.nb_channels));
210}
211
212#ifdef ENABLE_VIDEO
213
215{
216 if (releaseBufferCb_)
217 releaseBufferCb_(ptr_);
218}
219
220void
221VideoFrame::reset() noexcept
222{
224 allocated_ = false;
225 releaseBufferCb_ = {};
226}
227
228void
229VideoFrame::copyFrom(const VideoFrame& o)
230{
232 ptr_ = o.ptr_;
233 allocated_ = o.allocated_;
234}
235
236size_t
237VideoFrame::size() const noexcept
238{
239 return av_image_get_buffer_size((AVPixelFormat) frame_->format,
240 frame_->width,
241 frame_->height,
242 1);
243}
244
245int
246VideoFrame::format() const noexcept
247{
248 return frame_->format;
249}
250
251int
252VideoFrame::width() const noexcept
253{
254 return frame_->width;
255}
256
257int
258VideoFrame::height() const noexcept
259{
260 return frame_->height;
261}
262
263void
264VideoFrame::setGeometry(int format, int width, int height) noexcept
265{
266 frame_->format = format;
267 frame_->width = width;
268 frame_->height = height;
269}
270
271void
272VideoFrame::reserve(int format, int width, int height)
273{
274 auto libav_frame = frame_.get();
275
276 if (allocated_) {
277 // nothing to do if same properties
278 if (width == libav_frame->width and height == libav_frame->height
279 and format == libav_frame->format)
280 av_frame_unref(libav_frame);
281 }
282
283 setGeometry(format, width, height);
284 if (av_frame_get_buffer(libav_frame, 32))
285 throw std::bad_alloc();
286 allocated_ = true;
287 releaseBufferCb_ = {};
288}
289
290void
291VideoFrame::setFromMemory(uint8_t* ptr, int format, int width, int height) noexcept
292{
293 reset();
294 setGeometry(format, width, height);
295 if (not ptr)
296 return;
297 av_image_fill_arrays(frame_->data,
298 frame_->linesize,
299 (uint8_t*) ptr,
300 (AVPixelFormat) frame_->format,
301 width,
302 height,
303 1);
304}
305
306void
307VideoFrame::setFromMemory(uint8_t* ptr,
308 int format,
309 int width,
310 int height,
311 const std::function<void(uint8_t*)>& cb) noexcept
312{
313 setFromMemory(ptr, format, width, height);
314 if (cb) {
315 releaseBufferCb_ = cb;
316 ptr_ = ptr;
317 }
318}
319
320void
321VideoFrame::setReleaseCb(const std::function<void(uint8_t*)>& cb) noexcept
322{
323 if (cb) {
324 releaseBufferCb_ = cb;
325 }
326}
327
328void
330{
331 auto f = frame_.get();
332 if (f->data[0] == nullptr)
333 return;
334 for (std::size_t i = 0; i < size(); ++i) {
335 f->data[0][i] = std::rand() & 255;
336 }
337}
338
339int
341{
342 int32_t* matrix {nullptr};
343 if (auto p = packet()) {
344 matrix = reinterpret_cast<int32_t*>(
345 av_packet_get_side_data(p, AV_PKT_DATA_DISPLAYMATRIX, nullptr));
346 } else if (auto p = pointer()) {
347 if (AVFrameSideData* side_data = av_frame_get_side_data(p, AV_FRAME_DATA_DISPLAYMATRIX)) {
348 matrix = reinterpret_cast<int32_t*>(side_data->data);
349 }
350 }
351 if (matrix) {
352 double angle = av_display_rotation_get(matrix);
353 return std::isnan(angle) ? 0 : -(int) angle;
354 }
355 return 0;
356}
357
359getNewFrame(std::string_view id)
360{
361 if (auto vm = jami::Manager::instance().getVideoManager())
362 if (auto input = vm->getVideoInput(id))
363 return &input->getNewFrame();
364 JAMI_WARNING("getNewFrame: Unable to find input {}", id);
365 return nullptr;
366}
367
368void
369publishFrame(std::string_view id)
370{
371 if (auto vm = jami::Manager::instance().getVideoManager())
372 if (auto input = vm->getVideoInput(id))
373 input->publishFrame();
374}
375
376void
377registerVideoHandlers(const std::map<std::string, std::shared_ptr<CallbackWrapperBase>>& handlers)
378{
379 registerSignalHandlers(handlers);
380}
381
382std::vector<std::string>
384{
385 if (auto vm = jami::Manager::instance().getVideoManager())
386 return vm->videoDeviceMonitor.getDeviceList();
387 return {};
388}
389
391getCapabilities(const std::string& deviceId)
392{
393 if (auto vm = jami::Manager::instance().getVideoManager())
394 return vm->videoDeviceMonitor.getCapabilities(deviceId);
395 return {};
396}
397
398std::string
400{
401 if (auto vm = jami::Manager::instance().getVideoManager())
402 return vm->videoDeviceMonitor.getDefaultDevice();
403 return {};
404}
405
406void
407setDefaultDevice(const std::string& deviceId)
408{
409 JAMI_DBG("Setting default device to %s", deviceId.c_str());
410 if (auto vm = jami::Manager::instance().getVideoManager()) {
411 vm->videoDeviceMonitor.setDefaultDevice(deviceId);
413 }
414}
415
416void
417setDeviceOrientation(const std::string& deviceId, int angle)
418{
419 if (auto vm = jami::Manager::instance().getVideoManager())
420 vm->setDeviceOrientation(deviceId, angle);
421}
422
423std::map<std::string, std::string>
424getDeviceParams(const std::string& deviceId)
425{
426 if (auto vm = jami::Manager::instance().getVideoManager()) {
427 auto params = vm->videoDeviceMonitor.getDeviceParams(
428 deviceId);
429 std::ostringstream rate;
430 rate << params.framerate;
431 return {{"format", params.format},
432 {"width", std::to_string(params.width)},
433 {"height", std::to_string(params.height)},
434 {"rate", rate.str()}};
435 }
436 return {};
437}
438
439std::map<std::string, std::string>
440getSettings(const std::string& deviceId)
441{
442 if (auto vm = jami::Manager::instance().getVideoManager()) {
443 return vm->videoDeviceMonitor.getSettings(deviceId)
444 .to_map();
445 }
446 return {};
447}
448
449void
450applySettings(const std::string& deviceId, const std::map<std::string, std::string>& settings)
451{
452 if (auto vm = jami::Manager::instance().getVideoManager()) {
453 vm->videoDeviceMonitor.applySettings(deviceId, settings);
455 }
456}
457
458std::string
459openVideoInput(const std::string& path)
460{
461 if (auto vm = jami::Manager::instance().getVideoManager()) {
462 auto id = path.empty() ? vm->videoDeviceMonitor.getMRLForDefaultDevice() : path;
463 auto& input = vm->clientVideoInputs[id];
464 if (not input) {
465 input = jami::getVideoInput(id);
466 }
467 return id;
468 }
469 return {};
470}
471
472bool
473closeVideoInput(const std::string& id)
474{
475 if (auto vm = jami::Manager::instance().getVideoManager())
476 return vm->clientVideoInputs.erase(id) > 0;
477 return false;
478}
479#endif
480
481void
483{
485 if (auto vm = jami::Manager::instance().getVideoManager())
486 vm->audioPreview = newPreview;
487 newPreview->switchInput("");
488 }
489}
490
491void
493{
494 if (auto vm = jami::Manager::instance().getVideoManager())
495 vm->audioPreview.reset();
496}
497
498std::string
499startLocalMediaRecorder(const std::string& videoInputId, const std::string& filepath)
500{
501 auto rec = std::make_unique<jami::LocalRecorder>(videoInputId);
502 rec->setPath(filepath);
503
504 // retrieve final path (containing file extension)
505 auto path = rec->getPath();
506
507 auto& recordManager = jami::LocalRecorderManager::instance();
508
509 try {
510 recordManager.insertRecorder(path, std::move(rec));
511 } catch (const std::invalid_argument&) {
512 return "";
513 }
514
515 auto ret = recordManager.getRecorderByPath(path)->startRecording();
516 if (!ret) {
517 recordManager.removeRecorderByPath(filepath);
518 return "";
519 }
520
521 return path;
522}
523
524void
525stopLocalRecorder(const std::string& filepath)
526{
528 if (!rec) {
529 JAMI_WARN("Unable to stop non existing local recorder.");
530 return;
531 }
532
533 rec->stopRecording();
535}
536
537bool
538registerSinkTarget(const std::string& sinkId, SinkTarget target)
539{
540#ifdef ENABLE_VIDEO
541 if (auto sink = jami::Manager::instance().getSinkClient(sinkId)) {
542 sink->registerTarget(std::move(target));
543 return true;
544 } else
545 JAMI_WARN("No sink found for id '%s'", sinkId.c_str());
546#endif
547 return false;
548}
549
550#ifdef ENABLE_SHM
551void
552startShmSink(const std::string& sinkId, bool value)
553{
554#ifdef ENABLE_VIDEO
555 if (auto sink = jami::Manager::instance().getSinkClient(sinkId))
556 sink->enableShm(value);
557 else
558 JAMI_WARN("No sink found for id '%s'", sinkId.c_str());
559#endif
560}
561#endif
562
563std::map<std::string, std::string>
564getRenderer(const std::string& callId)
565{
566#ifdef ENABLE_VIDEO
567 if (auto sink = jami::Manager::instance().getSinkClient(callId))
568 return {
570 {libjami::Media::Details::SHM_PATH, sink->openedName()},
571 {libjami::Media::Details::WIDTH, std::to_string(sink->getWidth())},
572 {libjami::Media::Details::HEIGHT, std::to_string(sink->getHeight())},
573 };
574 else
575#endif
576 return {
581 };
582}
583
584std::string
585createMediaPlayer(const std::string& path)
586{
587 return jami::createMediaPlayer(path);
588}
589
590bool
591closeMediaPlayer(const std::string& id)
592{
593 return jami::closeMediaPlayer(id);
594}
595
596bool
597pausePlayer(const std::string& id, const bool& pause)
598{
599 return jami::pausePlayer(id, pause);
600}
601
602bool
603mutePlayerAudio(const std::string& id, const bool& mute)
604{
605 return jami::mutePlayerAudio(id, mute);
606}
607
608bool
609playerSeekToTime(const std::string& id, const int& time)
610{
611 return jami::playerSeekToTime(id, time);
612}
613
614int64_t
615getPlayerPosition(const std::string& id)
616{
617 return jami::getPlayerPosition(id);
618}
619
620int64_t
621getPlayerDuration(const std::string& id)
622{
623 return jami::getPlayerDuration(id);
624}
625
626void
627setAutoRestart(const std::string& id, const bool& restart)
628{
629 jami::setAutoRestart(id, restart);
630}
631
632bool
634{
635#ifdef RING_ACCEL
636 return jami::Manager::instance().videoPreferences.getDecodingAccelerated();
637#else
638 return false;
639#endif
640}
641
642void
644{
645#ifdef RING_ACCEL
646 JAMI_DBG("%s hardware acceleration", (state ? "Enabling" : "Disabling"));
647 if (jami::Manager::instance().videoPreferences.setDecodingAccelerated(state))
649#endif
650}
651
652bool
654{
655#ifdef RING_ACCEL
656 return jami::Manager::instance().videoPreferences.getEncodingAccelerated();
657#else
658 return false;
659#endif
660}
661
662void
664{
665#ifdef RING_ACCEL
666 JAMI_DBG("%s hardware acceleration", (state ? "Enabling" : "Disabling"));
667 if (jami::Manager::instance().videoPreferences.setEncodingAccelerated(state))
669 else
670 return;
671#endif
672 for (const auto& acc : jami::Manager::instance().getAllAccounts()) {
673 if (state)
674 acc->setCodecActive(AV_CODEC_ID_HEVC);
675 else
676 acc->setCodecInactive(AV_CODEC_ID_HEVC);
677 // Update and sort codecs
678 acc->setActiveCodecs(acc->getActiveCodecs());
680 }
681}
682
683#if defined(__ANDROID__) || (defined(TARGET_OS_IOS) && TARGET_OS_IOS)
684void
685addVideoDevice(const std::string& node,
686 const std::vector<std::map<std::string, std::string>>& devInfo)
687{
688 if (auto videoManager = jami::Manager::instance().getVideoManager()) {
689 videoManager->videoDeviceMonitor.addDevice(node, devInfo);
690 }
691}
692
693void
694removeVideoDevice(const std::string& node)
695{
696 if (auto videoManager = jami::Manager::instance().getVideoManager()) {
697 videoManager->videoDeviceMonitor.removeDevice(node);
698 }
699}
700#endif
701
702} // namespace libjami
703
704namespace jami {
705
706#ifdef ENABLE_VIDEO
707video::VideoDeviceMonitor*
709{
710 if (auto vm = jami::Manager::instance().getVideoManager())
711 return &vm->videoDeviceMonitor;
712 return {};
713}
714
715std::shared_ptr<video::VideoInput>
716getVideoInput(const std::string& resource, video::VideoInputMode inputMode, const std::string& sink)
717{
718 auto sinkId = sink.empty() ? resource : sink;
720 if (!vmgr)
721 return {};
722 std::lock_guard<std::mutex> lk(vmgr->videoMutex);
723 auto it = vmgr->videoInputs.find(sinkId);
724 if (it != vmgr->videoInputs.end()) {
725 if (auto input = it->second.lock()) {
726 return input;
727 }
728 }
729
730 auto input = std::make_shared<video::VideoInput>(inputMode, resource, sinkId);
731 vmgr->videoInputs[sinkId] = input;
732 return input;
733}
734
735void
736VideoManager::setDeviceOrientation(const std::string& deviceId, int angle)
737{
738 videoDeviceMonitor.setDeviceOrientation(deviceId, angle);
739}
740#endif
741
742std::shared_ptr<AudioInput>
743getAudioInput(const std::string& device)
744{
746 if (!vmgr)
747 return {};
748 std::lock_guard<std::mutex> lk(vmgr->audioMutex);
749
750 // erase expired audio inputs
751 for (auto it = vmgr->audioInputs.cbegin(); it != vmgr->audioInputs.cend();) {
752 if (it->second.expired())
753 it = vmgr->audioInputs.erase(it);
754 else
755 ++it;
756 }
757
758 auto it = vmgr->audioInputs.find(device);
759 if (it != vmgr->audioInputs.end()) {
760 if (auto input = it->second.lock()) {
761 return input;
762 }
763 }
764
765 auto input = std::make_shared<AudioInput>(device);
766 vmgr->audioInputs[device] = input;
767 return input;
768}
769
770bool
772{
773 if (auto vmgr = Manager::instance().getVideoManager())
774 return !vmgr->mediaPlayers.empty();
775 return false;
776}
777
778std::shared_ptr<MediaPlayer>
779getMediaPlayer(const std::string& id)
780{
781 if (auto vmgr = Manager::instance().getVideoManager()) {
782 auto it = vmgr->mediaPlayers.find(id);
783 if (it != vmgr->mediaPlayers.end()) {
784 return it->second;
785 }
786 }
787 return {};
788}
789
790std::string
791createMediaPlayer(const std::string& path)
792{
793 if (auto vmgr = Manager::instance().getVideoManager()) {
794 auto& player = vmgr->mediaPlayers[path];
795 if (!player) {
796 player = std::make_shared<MediaPlayer>(path);
797 }
798 return path;
799 }
800 return {};
801}
802
803bool
804pausePlayer(const std::string& id, bool pause)
805{
806 if (auto player = getMediaPlayer(id)) {
807 player->pause(pause);
808 return true;
809 }
810 return false;
811}
812
813bool
814closeMediaPlayer(const std::string& id)
815{
816 if (auto vm = Manager::instance().getVideoManager())
817 return vm->mediaPlayers.erase(id) > 0;
818 return false;
819}
820
821bool
822mutePlayerAudio(const std::string& id, bool mute)
823{
824 if (auto player = getMediaPlayer(id)) {
825 player->muteAudio(mute);
826 return true;
827 }
828 return false;
829}
830
831bool
832playerSeekToTime(const std::string& id, int time)
833{
834 if (auto player = getMediaPlayer(id))
835 return player->seekToTime(time);
836 return false;
837}
838
840getPlayerPosition(const std::string& id)
841{
842 if (auto player = getMediaPlayer(id))
843 return player->getPlayerPosition();
844 return -1;
845}
846
848getPlayerDuration(const std::string& id)
849{
850 if (auto player = getMediaPlayer(id))
851 return player->getPlayerDuration();
852 return -1;
853}
854
855void
856setAutoRestart(const std::string& id, bool restart)
857{
858 if (auto player = getMediaPlayer(id))
859 player->setAutoRestart(restart);
860}
861
862} // namespace jami
Interface to protocol account (ex: SIPAccount) It can be enable on loading or activate after.
static LocalRecorderManager & instance()
LocalRecorder * getRecorderByPath(const std::string &path)
Get local recorder instance with passed path as key.
void removeRecorderByPath(const std::string &path)
Remove given local recorder instance from the map.
void stopRecording() override
Stops recording.
std::vector< std::shared_ptr< T > > getAllAccounts() const
Get a list of account pointers of type T (baseclass Account)
Definition manager.h:731
static LIBJAMI_TEST_EXPORT Manager & instance()
Definition manager.cpp:676
void saveConfig()
Save config to file.
Definition manager.cpp:1751
VideoManager * getVideoManager() const
Definition manager.cpp:3175
static const char *const DEFAULT_ID
void mix(const AudioFrame &o)
size_t getFrameSize() const
jami::AudioFormat getFormat() const
float calcRMS() const
const AVFrame * pointer() const noexcept
void copyFrom(const MediaFrame &o)
void setPacket(PacketBuffer &&pkt)
virtual void reset() noexcept
AVPacket * packet() const noexcept
void reserve(int format, int width, int height)
std::size_t size() const noexcept
int format() const noexcept
void setFromMemory(uint8_t *data, int format, int width, int height) noexcept
int height() const noexcept
int getOrientation() const
int width() const noexcept
void setReleaseCb(const std::function< void(uint8_t *)> &cb) noexcept
void reset() noexcept override
void copyFrom(const VideoFrame &o)
#define JAMI_ERR(...)
Definition logger.h:218
#define JAMI_DBG(...)
Definition logger.h:216
#define JAMI_WARN(...)
Definition logger.h:217
#define JAMI_WARNING(formatstr,...)
Definition logger.h:227
void fillWithSilence(AVFrame *frame)
std::shared_ptr< MediaPlayer > getMediaPlayer(const std::string &id)
bool closeMediaPlayer(const std::string &id)
void emitSignal(Args... args)
Definition ring_signal.h:64
libjami::VideoFrame VideoFrame
Definition video_base.h:53
std::shared_ptr< AudioInput > getAudioInput(const std::string &device)
int64_t getPlayerDuration(const std::string &id)
void setAutoRestart(const std::string &id, bool restart)
bool playerSeekToTime(const std::string &id, int time)
int64_t getPlayerPosition(const std::string &id)
bool pausePlayer(const std::string &id, bool pause)
std::string createMediaPlayer(const std::string &path)
bool mutePlayerAudio(const std::string &id, bool mute)
static constexpr char SHM_PATH[]
Definition media_const.h:43
static constexpr char CALL_ID[]
Definition media_const.h:42
static constexpr char WIDTH[]
Definition media_const.h:44
static constexpr char HEIGHT[]
Definition media_const.h:45
LIBJAMI_PUBLIC void applySettings(const std::string &deviceId, const std::map< std::string, std::string > &settings)
LIBJAMI_PUBLIC std::map< std::string, std::string > getDeviceParams(const std::string &deviceId)
void stopAudioDevice()
bool closeMediaPlayer(const std::string &id)
LIBJAMI_PUBLIC std::string getDefaultDevice()
bool getEncodingAccelerated()
std::string startLocalMediaRecorder(const std::string &videoInputId, const std::string &filepath)
bool playerSeekToTime(const std::string &id, const int &time)
std::map< std::string, std::string > getRenderer(const std::string &callId)
LIBJAMI_PUBLIC VideoCapabilities getCapabilities(const std::string &deviceId)
void setEncodingAccelerated(bool state)
bool registerSinkTarget(const std::string &sinkId, SinkTarget target)
LIBJAMI_PUBLIC void setDefaultDevice(const std::string &deviceId)
LIBJAMI_PUBLIC std::map< std::string, std::string > getSettings(const std::string &deviceId)
std::unique_ptr< AVPacket, AVPacket_deleter > PacketBuffer
bool pausePlayer(const std::string &id, const bool &pause)
void registerSignalHandlers(const std::map< std::string, std::shared_ptr< CallbackWrapperBase > > &handlers)
LIBJAMI_PUBLIC void registerVideoHandlers(const std::map< std::string, std::shared_ptr< CallbackWrapperBase > > &)
std::string createMediaPlayer(const std::string &path)
void setDecodingAccelerated(bool state)
void stopLocalRecorder(const std::string &filepath)
LIBJAMI_PUBLIC std::vector< std::string > getDeviceList()
bool getDecodingAccelerated()
LIBJAMI_PUBLIC std::string openVideoInput(const std::string &path)
std::map< std::string, std::map< std::string, std::vector< std::string > > > VideoCapabilities
int64_t getPlayerPosition(const std::string &id)
int64_t getPlayerDuration(const std::string &id)
LIBJAMI_PUBLIC void setDeviceOrientation(const std::string &deviceId, int angle)
LIBJAMI_PUBLIC bool closeVideoInput(const std::string &id)
void setAutoRestart(const std::string &id, const bool &restart)
void startAudioDevice()
bool mutePlayerAudio(const std::string &id, const bool &mute)
Structure to hold sample rate and channel number associated with audio data.
AVSampleFormat sampleFormat