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