mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1448863: Stop sync dispatching in Decode. r=jesup
MozReview-Commit-ID: 3EK0zAsFpHz --HG-- extra : rebase_source : 0591c5a8fa4abbe46b789817fd9c617e9ef02da6
This commit is contained in:
parent
e2671eba43
commit
d0a45cf0c0
@ -770,14 +770,8 @@ WebrtcGmpVideoDecoder::GmpInitDone(GMPVideoDecoderProxy* aGMP,
|
||||
nsTArray<UniquePtr<GMPDecodeData>> temp;
|
||||
temp.SwapElements(mQueuedFrames);
|
||||
for (auto& queued : temp) {
|
||||
int rv = Decode_g(queued->mImage,
|
||||
queued->mMissingFrames,
|
||||
nullptr,
|
||||
nullptr,
|
||||
queued->mRenderTimeMs);
|
||||
if (rv) {
|
||||
return rv;
|
||||
}
|
||||
Decode_g(RefPtr<WebrtcGmpVideoDecoder>(this),
|
||||
nsAutoPtr<GMPDecodeData>(queued.release()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -805,61 +799,58 @@ WebrtcGmpVideoDecoder::Decode(const webrtc::EncodedImage& aInputImage,
|
||||
const webrtc::CodecSpecificInfo* aCodecSpecificInfo,
|
||||
int64_t aRenderTimeMs)
|
||||
{
|
||||
int32_t ret;
|
||||
MOZ_ASSERT(mGMPThread);
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
// Would be really nice to avoid this sync dispatch, but it would require a
|
||||
// copy of the frame, since it doesn't appear to actually have a refcount.
|
||||
// Passing 'this' is safe since this is synchronous.
|
||||
mozilla::SyncRunnable::DispatchToThread(mGMPThread,
|
||||
WrapRunnableRet(&ret, this,
|
||||
&WebrtcGmpVideoDecoder::Decode_g,
|
||||
aInputImage,
|
||||
aMissingFrames,
|
||||
aFragmentation,
|
||||
aCodecSpecificInfo,
|
||||
aRenderTimeMs));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t
|
||||
WebrtcGmpVideoDecoder::Decode_g(const webrtc::EncodedImage& aInputImage,
|
||||
bool aMissingFrames,
|
||||
const webrtc::RTPFragmentationHeader* aFragmentation,
|
||||
const webrtc::CodecSpecificInfo* aCodecSpecificInfo,
|
||||
int64_t aRenderTimeMs)
|
||||
{
|
||||
if (!mGMP) {
|
||||
if (mInitting) {
|
||||
// InitDone hasn't been called yet (race)
|
||||
GMPDecodeData *data = new GMPDecodeData(aInputImage,
|
||||
aMissingFrames,
|
||||
aRenderTimeMs);
|
||||
mQueuedFrames.AppendElement(data);
|
||||
return WEBRTC_VIDEO_CODEC_OK;
|
||||
}
|
||||
// destroyed via Terminate(), failed to init, or just not initted yet
|
||||
LOGD(("GMP Decode: not initted yet"));
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
}
|
||||
MOZ_ASSERT(mQueuedFrames.IsEmpty());
|
||||
MOZ_ASSERT(mHost);
|
||||
|
||||
if (!aInputImage._length) {
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
}
|
||||
|
||||
nsAutoPtr<GMPDecodeData> decodeData(new GMPDecodeData(aInputImage,
|
||||
aMissingFrames,
|
||||
aRenderTimeMs));
|
||||
|
||||
mGMPThread->Dispatch(WrapRunnableNM(&WebrtcGmpVideoDecoder::Decode_g,
|
||||
RefPtr<WebrtcGmpVideoDecoder>(this),
|
||||
decodeData),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
return WEBRTC_VIDEO_CODEC_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
// Using nsAutoPtr because WrapRunnable doesn't support move semantics
|
||||
void
|
||||
WebrtcGmpVideoDecoder::Decode_g(const RefPtr<WebrtcGmpVideoDecoder>& aThis,
|
||||
nsAutoPtr<GMPDecodeData> aDecodeData)
|
||||
{
|
||||
if (!aThis->mGMP) {
|
||||
if (aThis->mInitting) {
|
||||
// InitDone hasn't been called yet (race)
|
||||
aThis->mQueuedFrames.AppendElement(aDecodeData.forget());
|
||||
return;
|
||||
}
|
||||
// destroyed via Terminate(), failed to init, or just not initted yet
|
||||
LOGD(("GMP Decode: not initted yet"));
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aThis->mQueuedFrames.IsEmpty());
|
||||
MOZ_ASSERT(aThis->mHost);
|
||||
|
||||
GMPVideoFrame* ftmp = nullptr;
|
||||
GMPErr err = mHost->CreateFrame(kGMPEncodedVideoFrame, &ftmp);
|
||||
GMPErr err = aThis->mHost->CreateFrame(kGMPEncodedVideoFrame, &ftmp);
|
||||
if (err != GMPNoErr) {
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
LOG(LogLevel::Error, ("%s: CreateFrame failed (%u)!",
|
||||
__PRETTY_FUNCTION__, static_cast<unsigned>(err)));
|
||||
return;
|
||||
}
|
||||
|
||||
GMPUniquePtr<GMPVideoEncodedFrame> frame(static_cast<GMPVideoEncodedFrame*>(ftmp));
|
||||
err = frame->CreateEmptyFrame(aInputImage._length);
|
||||
err = frame->CreateEmptyFrame(aDecodeData->mImage._length);
|
||||
if (err != GMPNoErr) {
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
LOG(LogLevel::Error, ("%s: CreateEmptyFrame failed (%u)!",
|
||||
__PRETTY_FUNCTION__, static_cast<unsigned>(err)));
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX At this point, we only will get mode1 data (a single length and a buffer)
|
||||
@ -867,18 +858,20 @@ WebrtcGmpVideoDecoder::Decode_g(const webrtc::EncodedImage& aInputImage,
|
||||
*(reinterpret_cast<uint32_t*>(frame->Buffer())) = frame->Size();
|
||||
|
||||
// XXX It'd be wonderful not to have to memcpy the encoded data!
|
||||
memcpy(frame->Buffer()+4, aInputImage._buffer+4, frame->Size()-4);
|
||||
memcpy(frame->Buffer()+4, aDecodeData->mImage._buffer+4, frame->Size()-4);
|
||||
|
||||
frame->SetEncodedWidth(aInputImage._encodedWidth);
|
||||
frame->SetEncodedHeight(aInputImage._encodedHeight);
|
||||
frame->SetTimeStamp((aInputImage._timeStamp * 1000ll)/90); // rounds down
|
||||
frame->SetCompleteFrame(aInputImage._completeFrame);
|
||||
frame->SetEncodedWidth(aDecodeData->mImage._encodedWidth);
|
||||
frame->SetEncodedHeight(aDecodeData->mImage._encodedHeight);
|
||||
frame->SetTimeStamp((aDecodeData->mImage._timeStamp * 1000ll)/90); // rounds down
|
||||
frame->SetCompleteFrame(aDecodeData->mImage._completeFrame);
|
||||
frame->SetBufferType(GMP_BufferLength32);
|
||||
|
||||
GMPVideoFrameType ft;
|
||||
int32_t ret = WebrtcFrameTypeToGmpFrameType(aInputImage._frameType, &ft);
|
||||
int32_t ret = WebrtcFrameTypeToGmpFrameType(aDecodeData->mImage._frameType, &ft);
|
||||
if (ret != WEBRTC_VIDEO_CODEC_OK) {
|
||||
return ret;
|
||||
LOG(LogLevel::Error, ("%s: WebrtcFrameTypeToGmpFrameType failed (%u)!",
|
||||
__PRETTY_FUNCTION__, static_cast<unsigned>(ret)));
|
||||
return;
|
||||
}
|
||||
|
||||
// Bug XXXXXX: Set codecSpecific info
|
||||
@ -889,20 +882,23 @@ WebrtcGmpVideoDecoder::Decode_g(const webrtc::EncodedImage& aInputImage,
|
||||
nsTArray<uint8_t> codecSpecificInfo;
|
||||
codecSpecificInfo.AppendElements((uint8_t*)&info, sizeof(GMPCodecSpecificInfo));
|
||||
|
||||
LOGD(("GMP Decode: %" PRIu64 ", len %zu%s", frame->TimeStamp(), aInputImage._length,
|
||||
ft == kGMPKeyFrame ? ", KeyFrame" : ""));
|
||||
nsresult rv = mGMP->Decode(Move(frame),
|
||||
aMissingFrames,
|
||||
codecSpecificInfo,
|
||||
aRenderTimeMs);
|
||||
LOGD(("GMP Decode: %" PRIu64 ", len %zu%s", frame->TimeStamp(),
|
||||
aDecodeData->mImage._length, ft == kGMPKeyFrame ? ", KeyFrame" : ""));
|
||||
|
||||
nsresult rv = aThis->mGMP->Decode(Move(frame),
|
||||
aDecodeData->mMissingFrames,
|
||||
codecSpecificInfo,
|
||||
aDecodeData->mRenderTimeMs);
|
||||
if (NS_FAILED(rv)) {
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
LOG(LogLevel::Error, ("%s: Decode failed (rv=%u)!",
|
||||
__PRETTY_FUNCTION__, static_cast<unsigned>(rv)));
|
||||
}
|
||||
if(mDecoderStatus != GMPNoErr){
|
||||
mDecoderStatus = GMPNoErr;
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
|
||||
if(aThis->mDecoderStatus != GMPNoErr){
|
||||
aThis->mDecoderStatus = GMPNoErr;
|
||||
LOG(LogLevel::Error, ("%s: Decoder status is bad (%u)!",
|
||||
__PRETTY_FUNCTION__, static_cast<unsigned>(aThis->mDecoderStatus)));
|
||||
}
|
||||
return WEBRTC_VIDEO_CODEC_OK;
|
||||
}
|
||||
|
||||
int32_t
|
||||
|
@ -469,11 +469,8 @@ private:
|
||||
RefPtr<GmpInitDoneRunnable> mInitDone;
|
||||
};
|
||||
|
||||
virtual int32_t Decode_g(const webrtc::EncodedImage& aInputImage,
|
||||
bool aMissingFrames,
|
||||
const webrtc::RTPFragmentationHeader* aFragmentation,
|
||||
const webrtc::CodecSpecificInfo* aCodecSpecificInfo,
|
||||
int64_t aRenderTimeMs);
|
||||
static void Decode_g(const RefPtr<WebrtcGmpVideoDecoder>& aThis,
|
||||
nsAutoPtr<GMPDecodeData> aDecodeData);
|
||||
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mMPS;
|
||||
nsCOMPtr<nsIThread> mGMPThread;
|
||||
|
@ -5,6 +5,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
if CONFIG['MOZ_WEBRTC']:
|
||||
DEFINES['HAVE_UINT64_T'] = True
|
||||
|
||||
if CONFIG['OS_TARGET'] != 'WINNT':
|
||||
DEFINES['WEBRTC_POSIX'] = True
|
||||
DEFINES['WEBRTC_BUILD_LIBEVENT'] = True
|
||||
@ -21,5 +22,8 @@ if CONFIG['MOZ_WEBRTC']:
|
||||
elif CONFIG['OS_TARGET'] == 'Android':
|
||||
DEFINES['WEBRTC_ANDROID'] = True
|
||||
|
||||
if CONFIG['CC_TYPE'] in ('msvc', 'clang-cl'):
|
||||
DEFINES['__PRETTY_FUNCTION__'] = '__FUNCSIG__'
|
||||
|
||||
if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
|
||||
CXXFLAGS += ['-Wno-error=shadow']
|
||||
|
Loading…
Reference in New Issue
Block a user