mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 12:50:09 +00:00
Bug 1038615 - Report GMP decoding/encoding errors asynchronously. r=jesup
This commit is contained in:
parent
50fa9c92c0
commit
7b82110ed9
@ -96,6 +96,14 @@ GMPVideoDecoderChild::ResetComplete()
|
||||
SendResetComplete();
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoDecoderChild::Error(GMPErr aError)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
SendError(aError);
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoDecoderChild::CheckThread()
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user