28#include <libavutil/display.h>
41 const std::string&
sdp,
48 , sdpContext_(stream_.
str().size(),
false, &readFunction, 0, 0,
this)
55 JAMI_DBG(
"[%p] Instance created",
this);
61 JAMI_DBG(
"[%p] Instance destroyed",
this);
67 JAMI_DBG(
"[%p] Starting receiver’s loop",
this);
76 JAMI_DBG(
"[%p] Stopping receiver’s loop and waiting for the thread to exit…",
this);
79 JAMI_DBG(
"[%p] Receiver’s thread exited",
this);
85VideoReceiveThread::setup()
87 JAMI_DBG(
"[%p] Setting up video receiver",
this);
89 videoDecoder_.reset(
new MediaDecoder([
this](
const std::shared_ptr<MediaFrame>&
frame)
mutable {
92 std::lock_guard
l(rotationMtx_);
102 videoDecoder_->setContextCallback([
this]() {
103 if (recorderCallback_)
106 videoDecoder_->setResolutionChangedCallback([
this](
int width,
int height) {
109 sink_->setFrameSize(dstWidth_, dstHeight_);
112 dstWidth_ = args_.
width;
113 dstHeight_ = args_.
height;
115 static const std::string SDP_FILENAME =
"dummyFilename";
116 if (args_.
input.empty()) {
118 args_.
input = SDP_FILENAME;
119 }
else if (args_.
input.substr(0,
strlen(
"/dev/video")) ==
"/dev/video") {
123 args_.
format =
"video4linux2";
126 videoDecoder_->setInterruptCallback(interruptCb,
this);
128 if (args_.
input == SDP_FILENAME) {
133 if (stream_.str().empty()) {
138 videoDecoder_->setIOContext(&sdpContext_);
143 if (videoDecoder_->openInput(args_)) {
144 JAMI_ERR(
"Unable to open input \"%s\"", args_.
input.c_str());
148 if (args_.
input == SDP_FILENAME) {
150 videoDecoder_->setIOContext(demuxContext_.get());
156VideoReceiveThread::cleanup()
158 JAMI_DBG(
"[%p] Stopping receiver",
this);
163 videoDecoder_.reset();
168VideoReceiveThread::interruptCb(
void* data)
171 return not context->loop_.isRunning();
180 auto count =
is.gcount();
190 demuxContext_.reset(
socketPair.createIOContext(mtu_));
197 recorderCallback_ =
cb;
199 videoDecoder_->setContextCallback([
this]() {
200 if (recorderCallback_)
211 if (
not isVideoConfigured_) {
212 if (!configureVideoOutput()) {
213 JAMI_ERROR(
"[{:p}] Failed to configure video output", fmt::ptr(
this));
216 JAMI_LOG(
"[{:p}] Decoder configured, starting decoding", fmt::ptr(
this));
219 auto status = videoDecoder_->decode();
221 JAMI_LOG(
"[{:p}] End of file", fmt::ptr(
this));
228 if (keyFrameRequestCallback_)
229 keyFrameRequestCallback_();
234VideoReceiveThread::configureVideoOutput()
238 JAMI_DBG(
"[%p] Configuring video output",
this);
241 JAMI_WARN(
"[%p] Unable to configure video output, the loop is not running!",
this);
245 if (videoDecoder_->setupVideo() < 0) {
246 JAMI_ERR(
"Decoder IO startup failed");
252 if (dstWidth_ == 0
and dstHeight_ == 0) {
253 dstWidth_ = videoDecoder_->getWidth();
254 dstHeight_ = videoDecoder_->getHeight();
257 if (
not sink_->start()) {
258 JAMI_ERR(
"RX: sink startup failed");
266 if (onSuccessfulSetup_)
269 return isVideoConfigured_ =
true;
275 JAMI_DBG(
"[%p] Stopping sink",
this);
281 sink_->setFrameSize(0, 0);
287 JAMI_DBG(
"[%p] Starting sink",
this);
292 if (dstWidth_ > 0
and dstHeight_ > 0
and attach(sink_.get()))
293 sink_->setFrameSize(dstWidth_, dstHeight_);
312 return videoDecoder_->getPixelFormat();
320 return videoDecoder_->getStream(
"v:remote");
329 std::lock_guard
l(rotationMtx_);
Manager (controller) of daemon.
bool attach(Observer< std::shared_ptr< MediaFrame > > *o)
bool detach(Observer< std::shared_ptr< MediaFrame > > *o)
bool isStopping() const noexcept
bool isRunning() const noexcept
MediaStream getInfo() const
AVPixelFormat getPixelFormat() const
void setRotation(int angle)
Set angle of rotation to apply to the video by the decoder.
void setRecorderCallback(const std::function< void(const MediaStream &ms)> &cb)
void addIOContext(SocketPair &socketPair)
VideoReceiveThread(const std::string &id, bool useSink, const std::string &sdp, uint16_t mtu)
AVFrameSideData * av_frame_new_side_data_from_buf(AVFrame *frame, enum AVFrameSideDataType type, AVBufferRef *buf)
#define JAMI_ERROR(formatstr,...)
#define JAMI_LOG(formatstr,...)
std::unique_ptr< AVBufferRef, AVBufferRef_deleter > AVBufferPtr
void emitSignal(Args... args)
bool disable_dts_probe_delay