diff --git a/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp b/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp index d61ce978a520..2307dffac629 100644 --- a/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp +++ b/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp @@ -789,6 +789,17 @@ WebrtcGmpVideoDecoder::GmpInitDone(GMPVideoDecoderProxy* aGMP, } } + // This is an ugly solution to asynchronous decoding errors + // from Decode_g() not being returned to the synchronous Decode() method. + // If we don't return an error code at this point, our caller ultimately won't know to request + // a PLI and the video stream will remain frozen unless an IDR happens to arrive for other reasons. + // Bug 1492852 tracks implementing a proper solution. + if(mDecoderStatus != GMPNoErr){ + LOG(LogLevel::Error, ("%s: Decoder status is bad (%u)!", + __PRETTY_FUNCTION__, static_cast(mDecoderStatus))); + return WEBRTC_VIDEO_CODEC_ERROR; + } + return WEBRTC_VIDEO_CODEC_OK; } @@ -819,6 +830,11 @@ WebrtcGmpVideoDecoder::Decode(const webrtc::EncodedImage& aInputImage, return WEBRTC_VIDEO_CODEC_ERROR; } + // This is an ugly solution to asynchronous decoding errors + // from Decode_g() not being returned to the synchronous Decode() method. + // If we don't return an error code at this point, our caller ultimately won't know to request + // a PLI and the video stream will remain frozen unless an IDR happens to arrive for other reasons. + // Bug 1492852 tracks implementing a proper solution. nsAutoPtr decodeData(new GMPDecodeData(aInputImage, aMissingFrames, aRenderTimeMs)); @@ -828,6 +844,12 @@ WebrtcGmpVideoDecoder::Decode(const webrtc::EncodedImage& aInputImage, decodeData), NS_DISPATCH_NORMAL); + if(mDecoderStatus != GMPNoErr){ + LOG(LogLevel::Error, ("%s: Decoder status is bad (%u)!", + __PRETTY_FUNCTION__, static_cast(mDecoderStatus))); + return WEBRTC_VIDEO_CODEC_ERROR; + } + return WEBRTC_VIDEO_CODEC_OK; } @@ -845,6 +867,8 @@ WebrtcGmpVideoDecoder::Decode_g(const RefPtr& aThis, } // destroyed via Terminate(), failed to init, or just not initted yet LOGD(("GMP Decode: not initted yet")); + + aThis->mDecoderStatus = GMPDecodeErr; return; } @@ -856,6 +880,7 @@ WebrtcGmpVideoDecoder::Decode_g(const RefPtr& aThis, if (err != GMPNoErr) { LOG(LogLevel::Error, ("%s: CreateFrame failed (%u)!", __PRETTY_FUNCTION__, static_cast(err))); + aThis->mDecoderStatus = err; return; } @@ -864,6 +889,7 @@ WebrtcGmpVideoDecoder::Decode_g(const RefPtr& aThis, if (err != GMPNoErr) { LOG(LogLevel::Error, ("%s: CreateEmptyFrame failed (%u)!", __PRETTY_FUNCTION__, static_cast(err))); + aThis->mDecoderStatus = err; return; } @@ -885,6 +911,7 @@ WebrtcGmpVideoDecoder::Decode_g(const RefPtr& aThis, if (ret != WEBRTC_VIDEO_CODEC_OK) { LOG(LogLevel::Error, ("%s: WebrtcFrameTypeToGmpFrameType failed (%u)!", __PRETTY_FUNCTION__, static_cast(ret))); + aThis->mDecoderStatus = GMPDecodeErr; return; } @@ -906,13 +933,11 @@ WebrtcGmpVideoDecoder::Decode_g(const RefPtr& aThis, if (NS_FAILED(rv)) { LOG(LogLevel::Error, ("%s: Decode failed (rv=%u)!", __PRETTY_FUNCTION__, static_cast(rv))); + aThis->mDecoderStatus = GMPDecodeErr; + return; } - if(aThis->mDecoderStatus != GMPNoErr){ - aThis->mDecoderStatus = GMPNoErr; - LOG(LogLevel::Error, ("%s: Decoder status is bad (%u)!", - __PRETTY_FUNCTION__, static_cast(aThis->mDecoderStatus))); - } + aThis->mDecoderStatus = GMPNoErr; } int32_t diff --git a/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.h b/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.h index 92b5a270267e..f675a62e65f3 100644 --- a/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.h +++ b/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.h @@ -484,7 +484,7 @@ private: Mutex mCallbackMutex; webrtc::DecodedImageCallback* mCallback; Atomic mCachedPluginId; - GMPErr mDecoderStatus; + Atomic mDecoderStatus; std::string mPCHandle; };