diff --git a/src/media/media_decoder.cpp b/src/media/media_decoder.cpp index febf35ad1febba5964d243fe5a9c93a9f9bc7dd5..694431ba6fe8bff37274fe785994954368313c53 100644 --- a/src/media/media_decoder.cpp +++ b/src/media/media_decoder.cpp @@ -325,11 +325,8 @@ MediaDemuxer::decode() } auto& cb = streams_[streamIndex]; - if (cb) { - DecodeStatus ret = cb(*packet.get()); - if (ret == DecodeStatus::FallBack) - return Status::FallBack; - } + if (cb) + cb(*packet.get()); return Status::Success; } @@ -338,7 +335,7 @@ MediaDecoder::MediaDecoder(const std::shared_ptr<MediaDemuxer>& demuxer, int ind avStream_(demuxer->getStream(index)) { demuxer->setStreamCallback(index, [this](AVPacket& packet) { - return decode(packet); + decode(packet); }); setupStream(); } @@ -349,7 +346,7 @@ MediaDecoder::MediaDecoder(const std::shared_ptr<MediaDemuxer>& demuxer, int ind callback_(std::move(observer)) { demuxer->setStreamCallback(index, [this](AVPacket& packet) { - return decode(packet); + decode(packet); }); setupStream(); } @@ -410,7 +407,7 @@ int MediaDecoder::setup(AVMediaType type) return -1; avStream_ = demuxer_->getStream(stream); demuxer_->setStreamCallback(stream, [this](AVPacket& packet) { - return decode(packet); + decode(packet); }); return setupStream(); } @@ -429,14 +426,14 @@ MediaDecoder::setupStream() // it has been disabled already by the video_receive_thread/video_input enableAccel_ &= Manager::instance().videoPreferences.getDecodingAccelerated(); - if (enableAccel_ and not fallback_) { + if (enableAccel_) { auto APIs = video::HardwareAccel::getCompatibleAccel(decoderCtx_->codec_id, decoderCtx_->width, decoderCtx_->height, CODEC_DECODER); for (const auto& it : APIs) { accel_ = std::make_unique<video::HardwareAccel>(it); // save accel auto ret = accel_->initAPI(false, nullptr); if (ret < 0) { - accel_.reset(); + accel_ = nullptr; continue; } if(prepareDecoderContext() < 0) @@ -511,20 +508,13 @@ MediaDecoder::updateStartTime(int64_t startTime) { startTime_ = startTime; } -DecodeStatus +MediaDecoder::Status MediaDecoder::decode(AVPacket& packet) { int frameFinished = 0; auto ret = avcodec_send_packet(decoderCtx_, &packet); - if ( accel_ && (ret == AVERROR(EINVAL) or ret == AVERROR(EPERM)) ) { - JAMI_WARN("Decoding error falling back to software"); - fallback_ = true; - accel_.reset(); - avcodec_flush_buffers(decoderCtx_); - setupStream(); - return DecodeStatus::FallBack; - } else if (ret < 0 && ret != AVERROR(EAGAIN)) { - return ret == AVERROR_EOF ? DecodeStatus::Success : DecodeStatus::DecodeError; + if (ret < 0 && ret != AVERROR(EAGAIN)) { + return ret == AVERROR_EOF ? Status::Success : Status::DecodeError; } auto f = (inputDecoder_->type == AVMEDIA_TYPE_VIDEO) @@ -533,7 +523,7 @@ MediaDecoder::decode(AVPacket& packet) auto frame = f->pointer(); ret = avcodec_receive_frame(decoderCtx_, frame); if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) { - return DecodeStatus::DecodeError; + return Status::DecodeError; } if (ret >= 0) frameFinished = 1; @@ -554,7 +544,7 @@ MediaDecoder::decode(AVPacket& packet) auto target_relative = static_cast<std::int64_t>(frame_time.real() * 1e6); auto target_absolute = startTime_ + target_relative; if (target_relative < seekTime_) { - return DecodeStatus::Success; + return Status::Success; } //required frame found. Reset seek time if (target_relative >= seekTime_) { @@ -568,9 +558,9 @@ MediaDecoder::decode(AVPacket& packet) if (callback_) callback_(std::move(f)); - return DecodeStatus::FrameFinished; + return Status::FrameFinished; } - return DecodeStatus::Success; + return Status::Success; } void @@ -599,7 +589,7 @@ MediaDecoder::enableAccel(bool enableAccel) } #endif -DecodeStatus +MediaDecoder::Status MediaDecoder::flush() { AVPacket inpacket; @@ -609,12 +599,12 @@ MediaDecoder::flush() int ret = 0; ret = avcodec_send_packet(decoderCtx_, &inpacket); if (ret < 0 && ret != AVERROR(EAGAIN)) - return ret == AVERROR_EOF ? DecodeStatus::Success : DecodeStatus::DecodeError; + return ret == AVERROR_EOF ? Status::Success : Status::DecodeError; auto result = std::make_shared<MediaFrame>(); ret = avcodec_receive_frame(decoderCtx_, result->pointer()); if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) - return DecodeStatus::DecodeError; + return Status::DecodeError; if (ret >= 0) frameFinished = 1; @@ -622,10 +612,10 @@ MediaDecoder::flush() av_packet_unref(&inpacket); if (callback_) callback_(std::move(result)); - return DecodeStatus::FrameFinished; + return Status::FrameFinished; } - return DecodeStatus::Success; + return Status::Success; } #endif // ENABLE_VIDEO diff --git a/src/media/media_decoder.h b/src/media/media_decoder.h index 48edd213f05f0a65915a27710f780639be4fae0c..c0e5b0cfdf5929f456d5e39094376f0f7bbf22fe 100644 --- a/src/media/media_decoder.h +++ b/src/media/media_decoder.h @@ -68,16 +68,6 @@ class Resampler; class MediaIOHandle; class MediaDecoder; -enum class DecodeStatus { - Success, - FrameFinished, - EndOfFile, - ReadError, - DecodeError, - RestartRequired, - FallBack -}; - class MediaDemuxer { public: MediaDemuxer(); @@ -87,15 +77,14 @@ public: Success, EndOfFile, ReadBufferOverflow, - ReadError, - FallBack + ReadError }; enum class CurrentState { Demuxing, Finished }; - using StreamCallback = std::function<DecodeStatus (AVPacket&)>; + using StreamCallback = std::function<void(AVPacket&)>; int openInput(const DeviceParams&); @@ -156,6 +145,14 @@ private: class MediaDecoder { public: + enum class Status { + Success, + FrameFinished, + EndOfFile, + ReadError, + DecodeError, + RestartRequired + }; MediaDecoder(); MediaDecoder(MediaObserver observer); @@ -175,7 +172,7 @@ public: int setupVideo() { return setup(AVMEDIA_TYPE_VIDEO); } MediaDemuxer::Status decode(); - DecodeStatus flush(); + Status flush(); int getWidth() const; int getHeight() const; @@ -199,7 +196,7 @@ public: private: NON_COPYABLE(MediaDecoder); - DecodeStatus decode(AVPacket&); + Status decode(AVPacket&); rational<unsigned> getTimeBase() const; diff --git a/src/media/socket_pair.cpp b/src/media/socket_pair.cpp index fcdc3796e21f69999a200f7ff8a202bb16c46ec1..24bd51041948ce9e7203a46911e34a8921894a7c 100644 --- a/src/media/socket_pair.cpp +++ b/src/media/socket_pair.cpp @@ -647,6 +647,12 @@ SocketPair::getLastLatency() return -1; } +void +SocketPair::setPacketLossCallback(std::function<void(void)> cb) +{ + packetLossCallback_ = std::move(cb); +} + void SocketPair::setRtpDelayCallback(std::function<void(int, int)> cb) { diff --git a/src/media/socket_pair.h b/src/media/socket_pair.h index b18631d6ccc586d8389926762afa93d6af5f5682..f9b0650297cdcb1031cf97fb721451c7aa519851 100644 --- a/src/media/socket_pair.h +++ b/src/media/socket_pair.h @@ -168,9 +168,7 @@ class SocketPair { bool waitForRTCP(std::chrono::seconds interval); double getLastLatency(); - void setPacketLossCallback(std::function<void(void)> cb) { - packetLossCallback_ = std::move(cb); - } + void setPacketLossCallback(std::function<void (void)> cb); void setRtpDelayCallback(std::function<void (int, int)> cb); int writeData(uint8_t* buf, int buf_size); diff --git a/src/media/video/accel.cpp b/src/media/video/accel.cpp index e8514cde08baa2bde36bf5dcdbb8957d55eb33e9..b76163629b8f11b119df3ac8e197d9b3e819272a 100644 --- a/src/media/video/accel.cpp +++ b/src/media/video/accel.cpp @@ -77,7 +77,9 @@ getFormatCb(AVCodecContext* codecCtx, const AVPixelFormat* formats) { auto accel = static_cast<HardwareAccel*>(codecCtx->opaque); + AVPixelFormat fallback = AV_PIX_FMT_NONE; for (int i = 0; formats[i] != AV_PIX_FMT_NONE; ++i) { + fallback = formats[i]; if (accel && formats[i] == accel->getFormat()) { // found hardware format for codec with api JAMI_DBG() << "Found compatible hardware format for " @@ -86,7 +88,9 @@ getFormatCb(AVCodecContext* codecCtx, const AVPixelFormat* formats) return formats[i]; } } - return AV_PIX_FMT_NONE; + + JAMI_WARN() << "Not using hardware decoding"; + return fallback; } int diff --git a/src/media/video/video_receive_thread.cpp b/src/media/video/video_receive_thread.cpp index 6a86e8f6877c29a246cb60044d59e6db1b892124..61625fab6d69067976c767e5e8462d96f2eafa97 100644 --- a/src/media/video/video_receive_thread.cpp +++ b/src/media/video/video_receive_thread.cpp @@ -192,10 +192,6 @@ void VideoReceiveThread::decodeFrame() status == MediaDemuxer::Status::ReadError) { loop_.stop(); } - if (status == MediaDemuxer::Status::FallBack) { - if (keyFrameRequestCallback_) - keyFrameRequestCallback_(); - } } void VideoReceiveThread::enterConference() diff --git a/src/media/video/video_receive_thread.h b/src/media/video/video_receive_thread.h index 757bd8829d1be9d25d8123867e37d96357c184c1..12521439eedea480d5d07f1c99704b790cae9999 100644 --- a/src/media/video/video_receive_thread.h +++ b/src/media/video/video_receive_thread.h @@ -55,9 +55,7 @@ public: void startLoop(const std::function<void(MediaType)>& cb); void addIOContext(SocketPair& socketPair); - void setRequestKeyFrameCallback(std::function<void (void)> cb) { - keyFrameRequestCallback_ = std::move(cb); - }; + void setRequestKeyFrameCallback(std::function<void (void)>); void enterConference(); void exitConference(); @@ -108,8 +106,6 @@ private: bool setup(); void process(); void cleanup(); - - std::function<void(void)> keyFrameRequestCallback_; }; }} // namespace jami::video diff --git a/src/media/video/video_rtp_session.cpp b/src/media/video/video_rtp_session.cpp index fcd86eafdef7b02b04273116456c41bbb15365fa..c42e7a0486319cb9d91ec49d25066f694a552075 100644 --- a/src/media/video/video_rtp_session.cpp +++ b/src/media/video/video_rtp_session.cpp @@ -85,7 +85,10 @@ VideoRtpSession::updateMedia(const MediaDescription& send, const MediaDescriptio void VideoRtpSession::setRequestKeyFrameCallback(std::function<void(void)> cb) { - cbKeyFrameRequest_ = std::move(cb); + if (socketPair_) + socketPair_->setPacketLossCallback(std::move(cb)); + else + JAMI_ERR("No socket pair, keyframe request callback not possible"); } void VideoRtpSession::startSender() @@ -141,9 +144,6 @@ void VideoRtpSession::startSender() send_, *socketPair_, initSeqVal_, mtu_)); if (changeOrientationCallback_) sender_->setChangeOrientationCallback(changeOrientationCallback_); - if (socketPair_) - socketPair_->setPacketLossCallback([this] (){ - cbKeyFrameRequest_();}); } catch (const MediaEncoderException &e) { JAMI_ERR("%s", e.what()); @@ -184,9 +184,6 @@ void VideoRtpSession::startReceiver() // XXX keyframe requests can timeout if unanswered receiveThread_->addIOContext(*socketPair_); receiveThread_->startLoop(onSuccessfulSetup_); - if (receiveThread_) - receiveThread_->setRequestKeyFrameCallback([this] (){ - cbKeyFrameRequest_();}); } else { JAMI_DBG("Video receiving disabled"); if (receiveThread_) diff --git a/src/media/video/video_rtp_session.h b/src/media/video/video_rtp_session.h index b98db1c407bdc80ffa22524da3c00c19ad220f03..9a3da8b1504353b643bdbb634d04ea49820ff4c2 100644 --- a/src/media/video/video_rtp_session.h +++ b/src/media/video/video_rtp_session.h @@ -169,8 +169,6 @@ private: unsigned remb_dec_cnt_ {0}; std::unique_ptr<CongestionControl> cc; - - std::function<void(void)> cbKeyFrameRequest_; }; }} // namespace jami::video