26#include <libavutil/display.h>
42 , sdpContext_(stream_.
str().size(),
false, &readFunction, 0, 0,
this)
49 JAMI_DBG(
"[%p] Instance created",
this);
55 JAMI_DBG(
"[%p] Instance destroyed",
this);
61 JAMI_DBG(
"[%p] Starting receiver’s loop",
this);
70 JAMI_DBG(
"[%p] Stopping receiver’s loop and waiting for the thread to exit…",
this);
73 JAMI_DBG(
"[%p] Receiver’s thread exited",
this);
79VideoReceiveThread::setup()
81 JAMI_DBG(
"[%p] Setting up video receiver",
this);
83 videoDecoder_.reset(
new MediaDecoder([
this](
const std::shared_ptr<MediaFrame>&
frame)
mutable {
86 std::lock_guard
l(rotationMtx_);
94 videoDecoder_->setContextCallback([
this]() {
95 if (recorderCallback_)
98 videoDecoder_->setResolutionChangedCallback([
this](
int width,
int height) {
101 sink_->setFrameSize(dstWidth_, dstHeight_);
104 dstWidth_ =
static_cast<int>(args_.
width);
105 dstHeight_ =
static_cast<int>(args_.
height);
107 static const std::string SDP_FILENAME =
"dummyFilename";
108 if (args_.
input.empty()) {
110 args_.
input = SDP_FILENAME;
111 }
else if (args_.
input.substr(0,
strlen(
"/dev/video")) ==
"/dev/video") {
115 args_.
format =
"video4linux2";
118 videoDecoder_->setInterruptCallback(interruptCb,
this);
120 if (args_.
input == SDP_FILENAME) {
125 if (stream_.str().empty()) {
130 videoDecoder_->setIOContext(&sdpContext_);
135 if (videoDecoder_->openInput(args_)) {
136 JAMI_ERR(
"Unable to open input \"%s\"", args_.
input.c_str());
140 videoDecoder_->setKeyFrameRequestCb(keyFrameRequestCallback_);
142 if (args_.
input == SDP_FILENAME) {
144 videoDecoder_->setIOContext(demuxContext_.get());
150VideoReceiveThread::cleanup()
152 JAMI_DBG(
"[%p] Stopping receiver",
this);
157 videoDecoder_.reset();
162VideoReceiveThread::interruptCb(
void* data)
165 return not context->loop_.isRunning();
174 auto count =
is.gcount();
176 return static_cast<int>(count);
184 demuxContext_.reset(
socketPair.createIOContext(mtu_));
190 recorderCallback_ =
cb;
192 videoDecoder_->setContextCallback([
this]() {
193 if (recorderCallback_)
204 if (
not isVideoConfigured_) {
205 if (!configureVideoOutput()) {
206 JAMI_ERROR(
"[{:p}] Failed to configure video output", fmt::ptr(
this));
209 JAMI_LOG(
"[{:p}] Decoder configured, starting decoding", fmt::ptr(
this));
212 auto status = videoDecoder_->decode();
214 JAMI_LOG(
"[{:p}] End of file", fmt::ptr(
this));
219 if (keyFrameRequestCallback_)
220 keyFrameRequestCallback_();
225VideoReceiveThread::configureVideoOutput()
229 JAMI_DBG(
"[%p] Configuring video output",
this);
232 JAMI_WARN(
"[%p] Unable to configure video output, the loop is not running!",
this);
236 if (videoDecoder_->setupVideo() < 0) {
237 JAMI_ERR(
"Decoder IO startup failed");
243 if (dstWidth_ == 0
and dstHeight_ == 0) {
244 dstWidth_ = videoDecoder_->getWidth();
245 dstHeight_ = videoDecoder_->getHeight();
248 if (
not sink_->start()) {
249 JAMI_ERR(
"RX: sink startup failed");
257 if (onSuccessfulSetup_)
260 return isVideoConfigured_ =
true;
266 JAMI_DBG(
"[%p] Stopping sink",
this);
272 sink_->setFrameSize(0, 0);
278 JAMI_DBG(
"[%p] Starting sink",
this);
283 if (dstWidth_ > 0
and dstHeight_ > 0
and attach(sink_.get()))
284 sink_->setFrameSize(dstWidth_, dstHeight_);
303 return videoDecoder_->getPixelFormat();
311 return videoDecoder_->getStream(
"v:remote");
320 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