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 if (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(deviceId);
428 return {{"format", params.format},
429 {"width", std::to_string(params.width)},
430 {"height", std::to_string(params.height)},
431 {"rate", params.framerate.to_string()}};
432 }
433 return {};
434}
435
436std::map<std::string, std::string>
437getSettings(const std::string& deviceId)
438{
439 if (auto vm = jami::Manager::instance().getVideoManager()) {
440 return vm->videoDeviceMonitor.getSettings(deviceId)
441 .to_map();
442 }
443 return {};
444}
445
446void
447applySettings(const std::string& deviceId, const std::map<std::string, std::string>& settings)
448{
449 if (auto vm = jami::Manager::instance().getVideoManager()) {
450 vm->videoDeviceMonitor.applySettings(deviceId, settings);
452 }
453}
454
455std::string
456openVideoInput(const std::string& path)
457{
458 if (auto vm = jami::Manager::instance().getVideoManager()) {
459 auto id = path.empty() ? vm->videoDeviceMonitor.getMRLForDefaultDevice() : path;
460 auto& input = vm->clientVideoInputs[id];
461 if (not input) {
462 input = jami::getVideoInput(id);
463 }
464 return id;
465 }
466 return {};
467}
468
469bool
470closeVideoInput(const std::string& id)
471{
472 if (auto vm = jami::Manager::instance().getVideoManager())
473 return vm->clientVideoInputs.erase(id) > 0;
474 return false;
475}
476#endif
477
478void
480{
482 if (auto vm = jami::Manager::instance().getVideoManager())
483 vm->audioPreview = newPreview;
484 newPreview->switchInput("");
485 }
486}
487
488void
490{
491 if (auto vm = jami::Manager::instance().getVideoManager())
492 vm->audioPreview.reset();
493}
494
495std::string
496startLocalMediaRecorder(const std::string& videoInputId, const std::string& filepath)
497{
498 auto rec = std::make_unique<jami::LocalRecorder>(videoInputId);
499 rec->setPath(filepath);
500
501 // retrieve final path (containing file extension)
502 auto path = rec->getPath();
503
504 auto& recordManager = jami::LocalRecorderManager::instance();
505
506 try {
507 recordManager.insertRecorder(path, std::move(rec));
508 } catch (const std::invalid_argument&) {
509 return "";
510 }
511
512 auto ret = recordManager.getRecorderByPath(path)->startRecording();
513 if (!ret) {
514 recordManager.removeRecorderByPath(filepath);
515 return "";
516 }
517
518 return path;
519}
520
521void
522stopLocalRecorder(const std::string& filepath)
523{
525 if (!rec) {
526 JAMI_WARN("Unable to stop non existing local recorder.");
527 return;
528 }
529
530 rec->stopRecording();
532}
533
534bool
535registerSinkTarget(const std::string& sinkId, SinkTarget target)
536{
537#ifdef ENABLE_VIDEO
538 if (auto sink = jami::Manager::instance().getSinkClient(sinkId)) {
539 sink->registerTarget(std::move(target));
540 return true;
541 } else
542 JAMI_WARN("No sink found for id '%s'", sinkId.c_str());
543#endif
544 return false;
545}
546
547#ifdef ENABLE_SHM
548void
549startShmSink(const std::string& sinkId, bool value)
550{
551#ifdef ENABLE_VIDEO
552 if (auto sink = jami::Manager::instance().getSinkClient(sinkId))
553 sink->enableShm(value);
554 else
555 JAMI_WARN("No sink found for id '%s'", sinkId.c_str());
556#endif
557}
558#endif
559
560std::map<std::string, std::string>
561getRenderer(const std::string& callId)
562{
563#ifdef ENABLE_VIDEO
564 if (auto sink = jami::Manager::instance().getSinkClient(callId))
565 return {
567 {libjami::Media::Details::SHM_PATH, sink->openedName()},
568 {libjami::Media::Details::WIDTH, std::to_string(sink->getWidth())},
569 {libjami::Media::Details::HEIGHT, std::to_string(sink->getHeight())},
570 };
571 else
572#endif
573 return {
578 };
579}
580
581std::string
582createMediaPlayer(const std::string& path)
583{
584 return jami::createMediaPlayer(path);
585}
586
587bool
588closeMediaPlayer(const std::string& id)
589{
590 return jami::closeMediaPlayer(id);
591}
592
593bool
594pausePlayer(const std::string& id, const bool& pause)
595{
596 return jami::pausePlayer(id, pause);
597}
598
599bool
600mutePlayerAudio(const std::string& id, const bool& mute)
601{
602 return jami::mutePlayerAudio(id, mute);
603}
604
605bool
606playerSeekToTime(const std::string& id, const int& time)
607{
608 return jami::playerSeekToTime(id, time);
609}
610
611int64_t
612getPlayerPosition(const std::string& id)
613{
614 return jami::getPlayerPosition(id);
615}
616
617int64_t
618getPlayerDuration(const std::string& id)
619{
620 return jami::getPlayerDuration(id);
621}
622
623void
624setAutoRestart(const std::string& id, const bool& restart)
625{
626 jami::setAutoRestart(id, restart);
627}
628
629bool
631{
632#ifdef RING_ACCEL
633 return jami::Manager::instance().videoPreferences.getDecodingAccelerated();
634#else
635 return false;
636#endif
637}
638
639void
641{
642#ifdef RING_ACCEL
643 JAMI_DBG("%s hardware acceleration", (state ? "Enabling" : "Disabling"));
644 if (jami::Manager::instance().videoPreferences.setDecodingAccelerated(state))
646#endif
647}
648
649bool
651{
652#ifdef RING_ACCEL
653 return jami::Manager::instance().videoPreferences.getEncodingAccelerated();
654#else
655 return false;
656#endif
657}
658
659void
661{
662#ifdef RING_ACCEL
663 JAMI_DBG("%s hardware acceleration", (state ? "Enabling" : "Disabling"));
664 if (jami::Manager::instance().videoPreferences.setEncodingAccelerated(state))
666 else
667 return;
668#endif
669 for (const auto& acc : jami::Manager::instance().getAllAccounts()) {
670 if (state)
671 acc->setCodecActive(AV_CODEC_ID_HEVC);
672 else
673 acc->setCodecInactive(AV_CODEC_ID_HEVC);
674 // Update and sort codecs
675 acc->setActiveCodecs(acc->getActiveCodecs());
677 }
678}
679
680#if defined(__ANDROID__) || (defined(TARGET_OS_IOS) && TARGET_OS_IOS)
681void
682addVideoDevice(const std::string& node,
683 const std::vector<std::map<std::string, std::string>>& devInfo)
684{
685 if (auto videoManager = jami::Manager::instance().getVideoManager()) {
686 videoManager->videoDeviceMonitor.addDevice(node, devInfo);
687 }
688}
689
690void
691removeVideoDevice(const std::string& node)
692{
693 if (auto videoManager = jami::Manager::instance().getVideoManager()) {
694 videoManager->videoDeviceMonitor.removeDevice(node);
695 }
696}
697#endif
698
699} // namespace libjami
700
701namespace jami {
702
703#ifdef ENABLE_VIDEO
704video::VideoDeviceMonitor*
706{
707 if (auto vm = jami::Manager::instance().getVideoManager())
708 return &vm->videoDeviceMonitor;
709 return {};
710}
711
712std::shared_ptr<video::VideoInput>
713getVideoInput(const std::string& resource, video::VideoInputMode inputMode, const std::string& sink)
714{
715 auto sinkId = sink.empty() ? resource : sink;
717 if (!vmgr)
718 return {};
719 std::lock_guard<std::mutex> lk(vmgr->videoMutex);
720 auto it = vmgr->videoInputs.find(sinkId);
721 if (it != vmgr->videoInputs.end()) {
722 if (auto input = it->second.lock()) {
723 return input;
724 }
725 }
726
727 auto input = std::make_shared<video::VideoInput>(inputMode, resource, sinkId);
728 vmgr->videoInputs[sinkId] = input;
729 return input;
730}
731
732void
733VideoManager::setDeviceOrientation(const std::string& deviceId, int angle)
734{
735 videoDeviceMonitor.setDeviceOrientation(deviceId, angle);
736}
737#endif
738
739std::shared_ptr<AudioInput>
740getAudioInput(const std::string& device)
741{
743 if (!vmgr)
744 return {};
745 std::lock_guard<std::mutex> lk(vmgr->audioMutex);
746
747 // erase expired audio inputs
748 for (auto it = vmgr->audioInputs.cbegin(); it != vmgr->audioInputs.cend();) {
749 if (it->second.expired())
750 it = vmgr->audioInputs.erase(it);
751 else
752 ++it;
753 }
754
755 auto it = vmgr->audioInputs.find(device);
756 if (it != vmgr->audioInputs.end()) {
757 if (auto input = it->second.lock()) {
758 return input;
759 }
760 }
761
762 auto input = std::make_shared<AudioInput>(device);
763 vmgr->audioInputs[device] = input;
764 return input;
765}
766
767bool
769{
770 if (auto vmgr = Manager::instance().getVideoManager())
771 return !vmgr->mediaPlayers.empty();
772 return false;
773}
774
775std::shared_ptr<MediaPlayer>
776getMediaPlayer(const std::string& id)
777{
778 if (auto vmgr = Manager::instance().getVideoManager()) {
779 auto it = vmgr->mediaPlayers.find(id);
780 if (it != vmgr->mediaPlayers.end()) {
781 return it->second;
782 }
783 }
784 return {};
785}
786
787std::string
788createMediaPlayer(const std::string& path)
789{
790 if (auto vmgr = Manager::instance().getVideoManager()) {
791 auto& player = vmgr->mediaPlayers[path];
792 if (!player) {
793 player = std::make_shared<MediaPlayer>(path);
794 }
795 return path;
796 }
797 return {};
798}
799
800bool
801pausePlayer(const std::string& id, bool pause)
802{
803 if (auto player = getMediaPlayer(id)) {
804 player->pause(pause);
805 return true;
806 }
807 return false;
808}
809
810bool
811closeMediaPlayer(const std::string& id)
812{
813 if (auto vm = Manager::instance().getVideoManager())
814 return vm->mediaPlayers.erase(id) > 0;
815 return false;
816}
817
818bool
819mutePlayerAudio(const std::string& id, bool mute)
820{
821 if (auto player = getMediaPlayer(id)) {
822 player->muteAudio(mute);
823 return true;
824 }
825 return false;
826}
827
828bool
829playerSeekToTime(const std::string& id, int time)
830{
831 if (auto player = getMediaPlayer(id))
832 return player->seekToTime(time);
833 return false;
834}
835
837getPlayerPosition(const std::string& id)
838{
839 if (auto player = getMediaPlayer(id))
840 return player->getPlayerPosition();
841 return -1;
842}
843
845getPlayerDuration(const std::string& id)
846{
847 if (auto player = getMediaPlayer(id))
848 return player->getPlayerDuration();
849 return -1;
850}
851
852void
853setAutoRestart(const std::string& id, bool restart)
854{
855 if (auto player = getMediaPlayer(id))
856 player->setAutoRestart(restart);
857}
858
859} // 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:1750
VideoManager * getVideoManager() const
Definition manager.cpp:3174
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