diff --git a/app/videostreaming/android/lowlagdecoder.cpp b/app/videostreaming/android/lowlagdecoder.cpp index 7257aa8cd..3e5052d45 100644 --- a/app/videostreaming/android/lowlagdecoder.cpp +++ b/app/videostreaming/android/lowlagdecoder.cpp @@ -59,36 +59,45 @@ LowLagDecoder::LowLagDecoder(JNIEnv* env, bool verboseLogging, std::string logTa void LowLagDecoder::setOutputSurface(JNIEnv* env,jobject surface){ USE_SW_DECODER_INSTEAD=false; - if(surface==nullptr){ - //MLOGD<<"Set output surface to null"; - //assert(decoder.window!=nullptr); - if(decoder.window== nullptr){ - //MLOGD<<"Decoder window is already null"; - return; - } + + auto releaseDecoderResources = [this]() { std::lock_guard lock(mMutexInputPipe); inputPipeClosed=true; if(decoder.configured){ - AMediaCodec_stop(decoder.codec); - AMediaCodec_delete(decoder.codec); - decoder.codec=nullptr; + if (decoder.codec) { + AMediaCodec_stop(decoder.codec); + AMediaCodec_delete(decoder.codec); + decoder.codec=nullptr; + } mKeyFrameFinder.reset(); decoder.configured=false; - if(mCheckOutputThread->joinable()){ + if(mCheckOutputThread && mCheckOutputThread->joinable()){ mCheckOutputThread->join(); - mCheckOutputThread.reset(); } + mCheckOutputThread.reset(); + } + if (decoder.window) { + ANativeWindow_release(decoder.window); + decoder.window=nullptr; } - ANativeWindow_release(decoder.window); - decoder.window=nullptr; resetStatistics(); - }else{ - // Throw warning if the surface is set without clearing it first - assert(decoder.window==nullptr); - decoder.window=ANativeWindow_fromSurface(env,surface); - // open the input pipe - now the decoder will start as soon as enough data is available - inputPipeClosed=false; + }; + + if(surface==nullptr){ + if(decoder.window== nullptr){ + return; + } + releaseDecoderResources(); + return; } + + if(decoder.window!=nullptr){ + releaseDecoderResources(); + } + + decoder.window=ANativeWindow_fromSurface(env,surface); + // open the input pipe - now the decoder will start as soon as enough data is available + inputPipeClosed=false; } void LowLagDecoder::registerOnDecoderRatioChangedCallback(DECODER_RATIO_CHANGED decoderRatioChangedC) { @@ -167,6 +176,12 @@ void LowLagDecoder::configureStartDecoder(){ //MLOGD<<"Created decoder "<disconnect(this); + stopPlayback(); + } m_videoOut = videoOut; @@ -42,6 +44,7 @@ void QAndroidSecondaryMediaPlayer::setVideoOut(QSurfaceTexture *videoOut) stopPlayback(); } else { connect(m_videoOut.data(), &QSurfaceTexture::surfaceTextureChanged, this, [this] { + stopPlayback(); m_pendingPlayback = true; tryStartPlayback(); }); @@ -90,6 +93,16 @@ void QAndroidSecondaryMediaPlayer::tryStartPlayback() if (!m_videoOut) return; + if (m_playbackRunning) { + m_pendingPlayback = false; + return; + } + + const auto streamConfig = resolveStreamConfig(); + if (!streamConfig) { + return; + } + const auto streamConfig = resolveStreamConfig(); if (!streamConfig) { return; @@ -170,6 +183,7 @@ void QAndroidSecondaryMediaPlayer::startPlaybackOnAndroidThread(const QAndroidJn }); m_pendingPlayback = false; + m_playbackRunning = true; } void QAndroidSecondaryMediaPlayer::stopPlayback() @@ -188,4 +202,5 @@ void QAndroidSecondaryMediaPlayer::stopPlayback() m_activeConfig.reset(); m_pendingPlayback = false; + m_playbackRunning = false; } diff --git a/app/videostreaming/android/qandroidsecondarymediaplayer.h b/app/videostreaming/android/qandroidsecondarymediaplayer.h index 50a383337..281f5a366 100644 --- a/app/videostreaming/android/qandroidsecondarymediaplayer.h +++ b/app/videostreaming/android/qandroidsecondarymediaplayer.h @@ -41,6 +41,7 @@ class QAndroidSecondaryMediaPlayer : public QObject QPointer m_videoOut; bool m_pendingPlayback = false; + bool m_playbackRunning = false; std::optional m_activeConfig; std::unique_ptr m_lowLagDecoder; std::unique_ptr m_receiver;