Bug 1038615 - Report GMP decoding/encoding errors asynchronously. r=jesup
authorChris Pearce <cpearce@mozilla.com>
Thu, 24 Jul 2014 09:35:01 +1200
changeset 195806 fd72e28c6d38f815739560cbf0beeb18ed88897f
parent 195805 4119caa3ac8fdbe65ed90425768041f6e8f18d7f
child 195807 1b3e953be799cd83f5b36960a4bb6c4390a7ea55
push id27197
push usercbook@mozilla.com
push dateThu, 24 Jul 2014 13:25:44 +0000
treeherdermozilla-central@340ff53a5467 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs1038615
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1038615 - Report GMP decoding/encoding errors asynchronously. r=jesup
content/media/gmp/GMPVideoDecoderChild.cpp
content/media/gmp/GMPVideoDecoderChild.h
content/media/gmp/GMPVideoDecoderParent.cpp
content/media/gmp/GMPVideoDecoderParent.h
content/media/gmp/GMPVideoEncoderChild.cpp
content/media/gmp/GMPVideoEncoderChild.h
content/media/gmp/GMPVideoEncoderParent.cpp
content/media/gmp/GMPVideoEncoderParent.h
content/media/gmp/GMPVideoEncoderProxy.h
content/media/gmp/PGMPVideoDecoder.ipdl
content/media/gmp/PGMPVideoEncoder.ipdl
content/media/gmp/gmp-api/gmp-audio-decode.h
content/media/gmp/gmp-api/gmp-errors.h
content/media/gmp/gmp-api/gmp-video-decode.h
content/media/gmp/gmp-api/gmp-video-encode.h
dom/media/gmp-plugin/gmp-fake.cpp
media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.h
--- a/content/media/gmp/GMPVideoDecoderChild.cpp
+++ b/content/media/gmp/GMPVideoDecoderChild.cpp
@@ -92,16 +92,24 @@ void
 GMPVideoDecoderChild::ResetComplete()
 {
   MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
 
   SendResetComplete();
 }
 
 void
+GMPVideoDecoderChild::Error(GMPErr aError)
+{
+  MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
+
+  SendError(aError);
+}
+
+void
 GMPVideoDecoderChild::CheckThread()
 {
   MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
 }
 
 bool
 GMPVideoDecoderChild::RecvInitDecode(const GMPVideoCodec& aCodecSettings,
                                      const nsTArray<uint8_t>& aCodecSpecific,
--- a/content/media/gmp/GMPVideoDecoderChild.h
+++ b/content/media/gmp/GMPVideoDecoderChild.h
@@ -31,16 +31,17 @@ public:
 
   // GMPVideoDecoderCallback
   virtual void Decoded(GMPVideoi420Frame* decodedFrame) MOZ_OVERRIDE;
   virtual void ReceivedDecodedReferenceFrame(const uint64_t pictureId) MOZ_OVERRIDE;
   virtual void ReceivedDecodedFrame(const uint64_t pictureId) MOZ_OVERRIDE;
   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();
   virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem)
   {
 #ifndef SHMEM_ALLOC_IN_CHILD
     return CallNeedShmem(aSize, aMem);
 #else
--- a/content/media/gmp/GMPVideoDecoderParent.cpp
+++ b/content/media/gmp/GMPVideoDecoderParent.cpp
@@ -262,16 +262,29 @@ GMPVideoDecoderParent::RecvResetComplete
 
   // Ignore any return code. It is OK for this to fail without killing the process.
   mCallback->ResetComplete();
 
   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)
 {
   if (aEncodedBuffer.IsWritable()) {
     mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPEncodedData,
                                                aEncodedBuffer);
   }
   return true;
 }
--- a/content/media/gmp/GMPVideoDecoderParent.h
+++ b/content/media/gmp/GMPVideoDecoderParent.h
@@ -65,16 +65,17 @@ private:
   // PGMPVideoDecoderParent
   virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
   virtual bool RecvDecoded(const GMPVideoi420FrameData& aDecodedFrame) MOZ_OVERRIDE;
   virtual bool RecvReceivedDecodedReferenceFrame(const uint64_t& aPictureId) MOZ_OVERRIDE;
   virtual bool RecvReceivedDecodedFrame(const uint64_t& aPictureId) MOZ_OVERRIDE;
   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;
   virtual bool Recv__delete__() MOZ_OVERRIDE;
 
   bool mCanSendMessages;
   nsRefPtr<GMPParent> mPlugin;
   GMPVideoDecoderCallback* mCallback;
--- a/content/media/gmp/GMPVideoEncoderChild.cpp
+++ b/content/media/gmp/GMPVideoEncoderChild.cpp
@@ -53,16 +53,24 @@ GMPVideoEncoderChild::Encoded(GMPVideoEn
   nsTArray<uint8_t> codecSpecific;
   codecSpecific.AppendElements(aCodecSpecificInfo, aCodecSpecificInfoLength);
   SendEncoded(frameData, codecSpecific);
 
   aEncodedFrame->Destroy();
 }
 
 void
+GMPVideoEncoderChild::Error(GMPErr aError)
+{
+  MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
+
+  SendError(aError);
+}
+
+void
 GMPVideoEncoderChild::CheckThread()
 {
   MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
 }
 
 bool
 GMPVideoEncoderChild::RecvInitEncode(const GMPVideoCodec& aCodecSettings,
                                      const nsTArray<uint8_t>& aCodecSpecific,
--- a/content/media/gmp/GMPVideoEncoderChild.h
+++ b/content/media/gmp/GMPVideoEncoderChild.h
@@ -27,16 +27,17 @@ public:
 
   void Init(GMPVideoEncoder* aEncoder);
   GMPVideoHostImpl& Host();
 
   // GMPVideoEncoderCallback
   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();
   virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem)
   {
 #ifndef SHMEM_ALLOC_IN_CHILD
     return CallNeedShmem(aSize, aMem);
 #else
--- a/content/media/gmp/GMPVideoEncoderParent.cpp
+++ b/content/media/gmp/GMPVideoEncoderParent.cpp
@@ -215,16 +215,29 @@ GMPVideoEncoderParent::RecvEncoded(const
   mCallback->Encoded(f, aCodecSpecificInfo);
 
   // Return SHM to sender to recycle
   //SendEncodedReturn(aEncodedFrame, aCodecSpecificInfo);
   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)
 {
   if (aFrameBuffer.IsWritable()) {
     mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPFrameData,
                                                aFrameBuffer);
   }
   return true;
 }
--- a/content/media/gmp/GMPVideoEncoderParent.h
+++ b/content/media/gmp/GMPVideoEncoderParent.h
@@ -62,16 +62,17 @@ public:
 
 private:
   virtual ~GMPVideoEncoderParent();
 
   // PGMPVideoEncoderParent
   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;
   virtual bool Recv__delete__() MOZ_OVERRIDE;
 
   bool mCanSendMessages;
   nsRefPtr<GMPParent> mPlugin;
   GMPVideoEncoderCallbackProxy* mCallback;
--- a/content/media/gmp/GMPVideoEncoderProxy.h
+++ b/content/media/gmp/GMPVideoEncoderProxy.h
@@ -10,16 +10,17 @@
 #include "gmp-video-encode.h"
 #include "gmp-video-frame-i420.h"
 #include "gmp-video-frame-encoded.h"
 
 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.
 // GMPVideoEncoderParent exposes this to users the GMP.
 // This enables Gecko to pass nsTArrays to the child GMP and avoid
 // an extra copy when doing so.
 class GMPVideoEncoderProxy {
 public:
--- a/content/media/gmp/PGMPVideoDecoder.ipdl
+++ b/content/media/gmp/PGMPVideoDecoder.ipdl
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PGMP;
 include GMPTypes;
 
 using GMPVideoCodec from "gmp-video-codec.h";
+using GMPErr from "gmp-errors.h";
 
 include "GMPMessageUtils.h";
 
 namespace mozilla {
 namespace gmp {
 
 intr protocol PGMPVideoDecoder
 {
@@ -32,16 +33,17 @@ child:
 parent:
   async __delete__();
   async Decoded(GMPVideoi420FrameData aDecodedFrame);
   async ReceivedDecodedReferenceFrame(uint64_t aPictureId);
   async ReceivedDecodedFrame(uint64_t aPictureId);
   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
   intr NeedShmem(uint32_t aFrameBufferSize) returns (Shmem aMem);
 };
 
 } // namespace gmp
 } // namespace mozilla
--- a/content/media/gmp/PGMPVideoEncoder.ipdl
+++ b/content/media/gmp/PGMPVideoEncoder.ipdl
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PGMP;
 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";
 
 namespace mozilla {
 namespace gmp {
 
 intr protocol PGMPVideoEncoder
 {
@@ -30,16 +31,17 @@ child:
   async SetPeriodicKeyFrames(bool aEnable);
   async EncodingComplete();
   async ChildShmemForPool(Shmem aEncodedBuffer);
 
 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
   intr NeedShmem(uint32_t aEncodedBufferSize) returns (Shmem aMem);
 };
 
 } // namespace gmp
 } // namespace mozilla
--- a/content/media/gmp/gmp-api/gmp-audio-decode.h
+++ b/content/media/gmp/gmp-api/gmp-audio-decode.h
@@ -30,43 +30,47 @@ public:
 
   virtual void Decoded(GMPAudioSamples* aDecodedSamples) = 0;
 
   virtual void InputDataExhausted() = 0;
 
   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
 class GMPAudioDecoder
 {
 public:
   virtual ~GMPAudioDecoder() {}
 
   // 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;
 };
 
 #endif // GMP_VIDEO_DECODE_h_
--- a/content/media/gmp/gmp-api/gmp-errors.h
+++ b/content/media/gmp/gmp-api/gmp-errors.h
@@ -36,15 +36,19 @@
 typedef enum {
   GMPNoErr = 0,
   GMPGenericErr = 1,
   GMPClosedErr = 2,
   GMPAllocErr = 3,
   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;
 
 #define GMP_SUCCEEDED(x) ((x) == GMPNoErr)
 #define GMP_FAILED(x) ((x) != GMPNoErr)
 
 #endif // GMP_ERRORS_h_
--- a/content/media/gmp/gmp-api/gmp-video-decode.h
+++ b/content/media/gmp/gmp-api/gmp-video-decode.h
@@ -52,64 +52,68 @@ public:
 
   virtual void ReceivedDecodedFrame(const uint64_t aPictureId) = 0;
 
   virtual void InputDataExhausted() = 0;
 
   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
 class GMPVideoDecoder
 {
 public:
   virtual ~GMPVideoDecoder() {}
 
   // - aCodecSettings: Details of decoder to create.
   // - aCodecSpecific: codec specific data, cast to a GMPVideoCodecXXX struct
   //                   to get codec specific config data.
   // - aCodecSpecificLength: number of bytes in aCodecSpecific.
   // - 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.
   //
   // - aInputFrame: Frame to decode. Call Destroy() on frame when it's decoded.
   // - aMissingFrames: True if one or more frames have been lost since the
   //                   previous decode call.
   // - aCodecSpecificInfo : codec specific data, pointer to a
   //                        GMPCodecSpecificInfo structure appropriate for
   //                        this codec type.
   // - 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;
 };
 
 #endif // GMP_VIDEO_DECODE_h_
--- a/content/media/gmp/gmp-api/gmp-video-encode.h
+++ b/content/media/gmp/gmp-api/gmp-video-encode.h
@@ -46,16 +46,20 @@
 class GMPVideoEncoderCallback
 {
 public:
   virtual ~GMPVideoEncoderCallback() {}
 
   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
 class GMPVideoEncoder
 {
 public:
   virtual ~GMPVideoEncoder() {}
 
@@ -67,57 +71,57 @@ public:
   //                    GMPCodecSpecific structure appropriate for
   //                    this codec type.
   // - aCodecSpecificLength : number of bytes in aCodecSpecific
   // - aCallback: Subclass should retain reference to it until EncodingComplete
   //              is called. Do not attempt to delete it, host retains ownership.
   // - 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.
   //
   // Input:
   // - aInputFrame : Frame to be encoded
   // - aCodecSpecificInfo : codec specific data, pointer to a
   //                        GMPCodecSpecificInfo structure appropriate for
   //                        this codec type.
   // - 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.
   //
   // - 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;
 };
 
 #endif // GMP_VIDEO_ENCODE_h_
--- a/dom/media/gmp-plugin/gmp-fake.cpp
+++ b/dom/media/gmp-plugin/gmp-fake.cpp
@@ -116,46 +116,42 @@ class FakeEncoderTask : public GMPTask {
 };
 
 class FakeVideoEncoder : public GMPVideoEncoder {
  public:
   FakeVideoEncoder (GMPVideoHost* hostAPI) :
     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,
                              int32_t numberOfCores,
                              uint32_t maxPayloadSize) {
     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,
                          uint32_t aFrameTypesLength) {
     GMPLOG (GL_DEBUG,
             __FUNCTION__
             << " size="
             << inputImage->Width() << "x" << inputImage->Height());
 
     assert (aFrameTypesLength != 0);
 
     g_platform_api->runonmainthread(new FakeEncoderTask(this,
                                                         inputImage,
                                                         aFrameTypes[0]));
-
-    return GMPGenericErr;
   }
 
   void Encode_m (GMPVideoi420Frame* inputImage,
                  GMPVideoFrameType frame_type) {
     if (frame_type  == kGMPKeyFrame) {
       if (!inputImage)
         return;
     }
@@ -218,26 +214,23 @@ class FakeVideoEncoder : public GMPVideo
     info.mCodecType = kGMPVideoCodecH264;
     info.mBufferType = GMP_BufferLength32;
     info.mCodecSpecific.mH264.mSimulcastIdx = 0;
     GMPLOG (GL_DEBUG, "Calling callback");
     callback_->Encoded (f, reinterpret_cast<uint8_t*> (&info), sizeof(info));
     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() {
     delete this;
   }
 
  private:
   uint8_t AveragePlane(uint8_t* ptr, size_t len) {
@@ -278,46 +271,41 @@ class FakeVideoDecoder : public GMPVideo
  public:
   FakeVideoDecoder (GMPVideoHost* hostAPI) :
     host_ (hostAPI),
     callback_ (NULL) {}
 
   virtual ~FakeVideoDecoder() {
   }
 
-  virtual GMPErr InitDecode (const GMPVideoCodec& codecSettings,
+  virtual void InitDecode (const GMPVideoCodec& codecSettings,
                              const uint8_t* aCodecSpecific,
                              uint32_t aCodecSpecificSize,
                              GMPVideoDecoderCallback* callback,
                              int32_t coreCount) {
     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,
                          int64_t renderTimeMs = -1) {
     GMPLOG (GL_DEBUG, __FUNCTION__
             << "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() {
     delete this;
   }
 
   // Return the decoded data back to the parent.
   void Decode_m (GMPVideoEncodedFrame* inputFrame,
--- a/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.h
+++ b/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.h
@@ -66,16 +66,18 @@ public:
 
   virtual int32_t SetRates(uint32_t aNewBitRate,
                            uint32_t aFrameRate) MOZ_OVERRIDE;
 
   // GMPVideoEncoderCallback virtual functions.
   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,
                                int32_t aNumberOfCores,
                                uint32_t aMaxPayloadSize);
 
   virtual int32_t Encode_g(const webrtc::I420VideoFrame* aInputImage,
                            const webrtc::CodecSpecificInfo* aCodecSpecificInfo,
@@ -135,16 +137,19 @@ public:
   virtual void DrainComplete() MOZ_OVERRIDE {
     MOZ_CRASH();
   }
 
   virtual void ResetComplete() MOZ_OVERRIDE {
     MOZ_CRASH();
   }
 
+  virtual void Error(GMPErr aError) MOZ_OVERRIDE {
+  }
+
 private:
   virtual int32_t InitDecode_g(const webrtc::VideoCodec* aCodecSettings,
                                int32_t aNumberOfCores);
 
   virtual int32_t Decode_g(const webrtc::EncodedImage& aInputImage,
                            bool aMissingFrames,
                            const webrtc::RTPFragmentationHeader* aFragmentation,
                            const webrtc::CodecSpecificInfo* aCodecSpecificInfo,