Bug 1038615 - Report GMP decoding/encoding errors asynchronously. r=jesup

This commit is contained in:
Chris Pearce 2014-07-24 09:35:01 +12:00
parent 412b5055fe
commit 2f71387227
17 changed files with 112 additions and 52 deletions

View File

@ -96,6 +96,14 @@ GMPVideoDecoderChild::ResetComplete()
SendResetComplete();
}
void
GMPVideoDecoderChild::Error(GMPErr aError)
{
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
SendError(aError);
}
void
GMPVideoDecoderChild::CheckThread()
{

View File

@ -36,6 +36,7 @@ public:
virtual void InputDataExhausted() MOZ_OVERRIDE;
virtual void DrainComplete() MOZ_OVERRIDE;
virtual void ResetComplete() MOZ_OVERRIDE;
virtual void Error(GMPErr aError) MOZ_OVERRIDE;
// GMPSharedMemManager
virtual void CheckThread();

View File

@ -266,6 +266,19 @@ GMPVideoDecoderParent::RecvResetComplete()
return true;
}
bool
GMPVideoDecoderParent::RecvError(const GMPErr& aError)
{
if (!mCallback) {
return false;
}
// Ignore any return code. It is OK for this to fail without killing the process.
mCallback->Error(aError);
return true;
}
bool
GMPVideoDecoderParent::RecvParentShmemForPool(Shmem& aEncodedBuffer)
{

View File

@ -70,6 +70,7 @@ private:
virtual bool RecvInputDataExhausted() MOZ_OVERRIDE;
virtual bool RecvDrainComplete() MOZ_OVERRIDE;
virtual bool RecvResetComplete() MOZ_OVERRIDE;
virtual bool RecvError(const GMPErr& aError) MOZ_OVERRIDE;
virtual bool RecvParentShmemForPool(Shmem& aEncodedBuffer) MOZ_OVERRIDE;
virtual bool AnswerNeedShmem(const uint32_t& aFrameBufferSize,
Shmem* aMem) MOZ_OVERRIDE;

View File

@ -57,6 +57,14 @@ GMPVideoEncoderChild::Encoded(GMPVideoEncodedFrame* aEncodedFrame,
aEncodedFrame->Destroy();
}
void
GMPVideoEncoderChild::Error(GMPErr aError)
{
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
SendError(aError);
}
void
GMPVideoEncoderChild::CheckThread()
{

View File

@ -32,6 +32,7 @@ public:
virtual void Encoded(GMPVideoEncodedFrame* aEncodedFrame,
const uint8_t* aCodecSpecificInfo,
uint32_t aCodecSpecificInfoLength) MOZ_OVERRIDE;
virtual void Error(GMPErr aError) MOZ_OVERRIDE;
// GMPSharedMemManager
virtual void CheckThread();

View File

@ -219,6 +219,19 @@ GMPVideoEncoderParent::RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame
return true;
}
bool
GMPVideoEncoderParent::RecvError(const GMPErr& aError)
{
if (!mCallback) {
return false;
}
// Ignore any return code. It is OK for this to fail without killing the process.
mCallback->Error(aError);
return true;
}
bool
GMPVideoEncoderParent::RecvParentShmemForPool(Shmem& aFrameBuffer)
{

View File

@ -67,6 +67,7 @@ private:
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame,
const nsTArray<uint8_t>& aCodecSpecificInfo) MOZ_OVERRIDE;
virtual bool RecvError(const GMPErr& aError) MOZ_OVERRIDE;
virtual bool RecvParentShmemForPool(Shmem& aFrameBuffer) MOZ_OVERRIDE;
virtual bool AnswerNeedShmem(const uint32_t& aEncodedBufferSize,
Shmem* aMem) MOZ_OVERRIDE;

View File

@ -15,6 +15,7 @@ class GMPVideoEncoderCallbackProxy {
public:
virtual void Encoded(GMPVideoEncodedFrame* aEncodedFrame,
const nsTArray<uint8_t>& aCodecSpecificInfo) = 0;
virtual void Error(GMPErr aError) = 0;
};
// A proxy to GMPVideoEncoder in the child process.

View File

@ -7,6 +7,7 @@ include protocol PGMP;
include GMPTypes;
using GMPVideoCodec from "gmp-video-codec.h";
using GMPErr from "gmp-errors.h";
include "GMPMessageUtils.h";
@ -37,6 +38,7 @@ parent:
async InputDataExhausted();
async DrainComplete();
async ResetComplete();
async Error(GMPErr aErr);
async ParentShmemForPool(Shmem aEncodedBuffer);
// MUST be intr - if sync and we create a new Shmem, when the returned
// Shmem is received in the Child it will fail to Deserialize

View File

@ -8,6 +8,7 @@ include GMPTypes;
using GMPVideoCodec from "gmp-video-codec.h";
using GMPVideoFrameType from "gmp-video-frame-encoded.h";
using GMPErr from "gmp-errors.h";
include "GMPMessageUtils.h";
@ -35,6 +36,7 @@ parent:
async __delete__();
async Encoded(GMPVideoEncodedFrameData aEncodedFrame,
uint8_t[] aCodecSpecificInfo);
async Error(GMPErr aErr);
async ParentShmemForPool(Shmem aFrameBuffer);
// MUST be intr - if sync and we create a new Shmem, when the returned
// Shmem is received in the Child it will fail to Deserialize

View File

@ -35,6 +35,10 @@ public:
virtual void DrainComplete() = 0;
virtual void ResetComplete() = 0;
// Called when the decoder encounters a catestrophic error and cannot
// continue. Gecko will not send any more input for decoding.
virtual void Error(GMPErr aError) = 0;
};
// ALL METHODS MUST BE CALLED ON THE MAIN THREAD
@ -46,24 +50,24 @@ public:
// aCallback: Subclass should retain reference to it until DecodingComplete
// is called. Do not attempt to delete it, host retains ownership.
// TODO: Pass AudioHost so decoder can create GMPAudioEncodedFrame objects?
virtual GMPErr InitDecode(const GMPAudioCodec& aCodecSettings,
GMPAudioDecoderCallback* aCallback) = 0;
virtual void InitDecode(const GMPAudioCodec& aCodecSettings,
GMPAudioDecoderCallback* aCallback) = 0;
// Decode encoded audio frames (as a part of an audio stream). The decoded
// frames must be returned to the user through the decode complete callback.
virtual GMPErr Decode(GMPAudioSamples* aEncodedSamples) = 0;
virtual void Decode(GMPAudioSamples* aEncodedSamples) = 0;
// Reset decoder state and prepare for a new call to Decode(...).
// Flushes the decoder pipeline.
// The decoder should enqueue a task to run ResetComplete() on the main
// thread once the reset has finished.
virtual GMPErr Reset() = 0;
virtual void Reset() = 0;
// Output decoded frames for any data in the pipeline, regardless of ordering.
// All remaining decoded frames should be immediately returned via callback.
// The decoder should enqueue a task to run DrainComplete() on the main
// thread once the reset has finished.
virtual GMPErr Drain() = 0;
virtual void Drain() = 0;
// May free decoder memory.
virtual void DecodingComplete() = 0;

View File

@ -41,6 +41,10 @@ typedef enum {
GMPNotImplementedErr = 4,
GMPNotClosedErr = 5,
GMPQuotaExceededErr = 6,
GMPDecodeErr = 7,
GMPEncodeErr = 8,
GMPNoKeyErr = 9,
GMPCryptoErr = 10,
GMPLastErr // Placeholder, must be last. This enum's values must remain consecutive!
} GMPErr;

View File

@ -57,6 +57,10 @@ public:
virtual void DrainComplete() = 0;
virtual void ResetComplete() = 0;
// Called when the decoder encounters a catestrophic error and cannot
// continue. Gecko will not send any more input for decoding.
virtual void Error(GMPErr aError) = 0;
};
// ALL METHODS MUST BE CALLED ON THE MAIN THREAD
@ -72,11 +76,11 @@ public:
// - aCallback: Subclass should retain reference to it until DecodingComplete
// is called. Do not attempt to delete it, host retains ownership.
// aCoreCount: number of CPU cores.
virtual GMPErr InitDecode(const GMPVideoCodec& aCodecSettings,
const uint8_t* aCodecSpecific,
uint32_t aCodecSpecificLength,
GMPVideoDecoderCallback* aCallback,
int32_t aCoreCount) = 0;
virtual void InitDecode(const GMPVideoCodec& aCodecSettings,
const uint8_t* aCodecSpecific,
uint32_t aCodecSpecificLength,
GMPVideoDecoderCallback* aCallback,
int32_t aCoreCount) = 0;
// Decode encoded frame (as a part of a video stream). The decoded frame
// will be returned to the user through the decode complete callback.
@ -90,23 +94,23 @@ public:
// - aCodecSpecificInfoLength : number of bytes in aCodecSpecificInfo
// - renderTimeMs : System time to render in milliseconds. Only used by
// decoders with internal rendering.
virtual GMPErr Decode(GMPVideoEncodedFrame* aInputFrame,
bool aMissingFrames,
const uint8_t* aCodecSpecificInfo,
uint32_t aCodecSpecificInfoLength,
int64_t aRenderTimeMs = -1) = 0;
virtual void Decode(GMPVideoEncodedFrame* aInputFrame,
bool aMissingFrames,
const uint8_t* aCodecSpecificInfo,
uint32_t aCodecSpecificInfoLength,
int64_t aRenderTimeMs = -1) = 0;
// Reset decoder state and prepare for a new call to Decode(...).
// Flushes the decoder pipeline.
// The decoder should enqueue a task to run ResetComplete() on the main
// thread once the reset has finished.
virtual GMPErr Reset() = 0;
virtual void Reset() = 0;
// Output decoded frames for any data in the pipeline, regardless of ordering.
// All remaining decoded frames should be immediately returned via callback.
// The decoder should enqueue a task to run DrainComplete() on the main
// thread once the reset has finished.
virtual GMPErr Drain() = 0;
virtual void Drain() = 0;
// May free decoder memory.
virtual void DecodingComplete() = 0;

View File

@ -51,6 +51,10 @@ public:
virtual void Encoded(GMPVideoEncodedFrame* aEncodedFrame,
const uint8_t* aCodecSpecificInfo,
uint32_t aCodecSpecificInfoLength) = 0;
// Called when the encoder encounters a catestrophic error and cannot
// continue. Gecko will not send any more input for encoding.
virtual void Error(GMPErr aError) = 0;
};
// ALL METHODS MUST BE CALLED ON THE MAIN THREAD
@ -72,12 +76,12 @@ public:
// - aNnumberOfCores : Number of cores available for the encoder
// - aMaxPayloadSize : The maximum size each payload is allowed
// to have. Usually MTU - overhead.
virtual GMPErr InitEncode(const GMPVideoCodec& aCodecSettings,
const uint8_t* aCodecSpecific,
uint32_t aCodecSpecificLength,
GMPVideoEncoderCallback* aCallback,
int32_t aNumberOfCores,
uint32_t aMaxPayloadSize) = 0;
virtual void InitEncode(const GMPVideoCodec& aCodecSettings,
const uint8_t* aCodecSpecific,
uint32_t aCodecSpecificLength,
GMPVideoEncoderCallback* aCallback,
int32_t aNumberOfCores,
uint32_t aMaxPayloadSize) = 0;
// Encode an I420 frame (as a part of a video stream). The encoded frame
// will be returned to the user through the encode complete callback.
@ -90,11 +94,11 @@ public:
// - aCodecSpecificInfoLength : number of bytes in aCodecSpecific
// - aFrameTypes : The frame type to encode
// - aFrameTypesLength : The number of elements in aFrameTypes array.
virtual GMPErr Encode(GMPVideoi420Frame* aInputFrame,
const uint8_t* aCodecSpecificInfo,
uint32_t aCodecSpecificInfoLength,
const GMPVideoFrameType* aFrameTypes,
uint32_t aFrameTypesLength) = 0;
virtual void Encode(GMPVideoi420Frame* aInputFrame,
const uint8_t* aCodecSpecificInfo,
uint32_t aCodecSpecificInfoLength,
const GMPVideoFrameType* aFrameTypes,
uint32_t aFrameTypesLength) = 0;
// Inform the encoder about the packet loss and round trip time on the
// network used to decide the best pattern and signaling.
@ -102,19 +106,19 @@ public:
// - packetLoss : Fraction lost (loss rate in percent =
// 100 * packetLoss / 255)
// - rtt : Round-trip time in milliseconds
virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) = 0;
virtual void SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) = 0;
// Inform the encoder about the new target bit rate.
//
// - newBitRate : New target bit rate
// - frameRate : The target frame rate
virtual GMPErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) = 0;
virtual void SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) = 0;
// Use this function to enable or disable periodic key frames. Can be useful for codecs
// which have other ways of stopping error propagation.
//
// - enable : Enable or disable periodic key frames
virtual GMPErr SetPeriodicKeyFrames(bool aEnable) = 0;
virtual void SetPeriodicKeyFrames(bool aEnable) = 0;
// May free Encoder memory.
virtual void EncodingComplete() = 0;

View File

@ -121,7 +121,7 @@ class FakeVideoEncoder : public GMPVideoEncoder {
host_ (hostAPI),
callback_ (NULL) {}
virtual GMPErr InitEncode (const GMPVideoCodec& codecSettings,
virtual void InitEncode (const GMPVideoCodec& codecSettings,
const uint8_t* aCodecSpecific,
uint32_t aCodecSpecificSize,
GMPVideoEncoderCallback* callback,
@ -130,11 +130,9 @@ class FakeVideoEncoder : public GMPVideoEncoder {
callback_ = callback;
GMPLOG (GL_INFO, "Initialized encoder");
return GMPNoErr;
}
virtual GMPErr Encode (GMPVideoi420Frame* inputImage,
virtual void Encode (GMPVideoi420Frame* inputImage,
const uint8_t* aCodecSpecificInfo,
uint32_t aCodecSpecificInfoLength,
const GMPVideoFrameType* aFrameTypes,
@ -149,8 +147,6 @@ class FakeVideoEncoder : public GMPVideoEncoder {
g_platform_api->runonmainthread(new FakeEncoderTask(this,
inputImage,
aFrameTypes[0]));
return GMPGenericErr;
}
void Encode_m (GMPVideoi420Frame* inputImage,
@ -223,16 +219,13 @@ class FakeVideoEncoder : public GMPVideoEncoder {
GMPLOG (GL_DEBUG, "Callback called");
}
virtual GMPErr SetChannelParameters (uint32_t aPacketLoss, uint32_t aRTT) {
return GMPNoErr;
virtual void SetChannelParameters (uint32_t aPacketLoss, uint32_t aRTT) {
}
virtual GMPErr SetRates (uint32_t aNewBitRate, uint32_t aFrameRate) {
return GMPNoErr;
virtual void SetRates (uint32_t aNewBitRate, uint32_t aFrameRate) {
}
virtual GMPErr SetPeriodicKeyFrames (bool aEnable) {
return GMPNoErr;
virtual void SetPeriodicKeyFrames (bool aEnable) {
}
virtual void EncodingComplete() {
@ -283,7 +276,7 @@ class FakeVideoDecoder : public GMPVideoDecoder {
virtual ~FakeVideoDecoder() {
}
virtual GMPErr InitDecode (const GMPVideoCodec& codecSettings,
virtual void InitDecode (const GMPVideoCodec& codecSettings,
const uint8_t* aCodecSpecific,
uint32_t aCodecSpecificSize,
GMPVideoDecoderCallback* callback,
@ -291,10 +284,9 @@ class FakeVideoDecoder : public GMPVideoDecoder {
GMPLOG (GL_INFO, "InitDecode");
callback_ = callback;
return GMPNoErr;
}
virtual GMPErr Decode (GMPVideoEncodedFrame* inputFrame,
virtual void Decode (GMPVideoEncodedFrame* inputFrame,
bool missingFrames,
const uint8_t* aCodecSpecificInfo,
uint32_t aCodecSpecificInfoLength,
@ -303,16 +295,12 @@ class FakeVideoDecoder : public GMPVideoDecoder {
<< "Decoding frame size=" << inputFrame->Size()
<< " timestamp=" << inputFrame->TimeStamp());
g_platform_api->runonmainthread(new FakeDecoderTask(this, inputFrame, renderTimeMs));
return GMPNoErr;
}
virtual GMPErr Reset() {
return GMPNoErr;
virtual void Reset() {
}
virtual GMPErr Drain() {
return GMPNoErr;
virtual void Drain() {
}
virtual void DecodingComplete() {

View File

@ -71,6 +71,8 @@ public:
virtual void Encoded(GMPVideoEncodedFrame* aEncodedFrame,
const nsTArray<uint8_t>& aCodecSpecificInfo) MOZ_OVERRIDE;
virtual void Error(GMPErr aError) MOZ_OVERRIDE {
}
private:
virtual int32_t InitEncode_g(const webrtc::VideoCodec* aCodecSettings,
@ -140,6 +142,9 @@ public:
MOZ_CRASH();
}
virtual void Error(GMPErr aError) MOZ_OVERRIDE {
}
private:
virtual int32_t InitDecode_g(const webrtc::VideoCodec* aCodecSettings,
int32_t aNumberOfCores);