Bug 1368904 - Handle unexpected error callback from GeckoHlsPlayer.
MozReview-Commit-ID: CQDjFXiFDrQ
--- a/dom/media/hls/HLSDemuxer.cpp
+++ b/dom/media/hls/HLSDemuxer.cpp
@@ -77,39 +77,46 @@ public:
: mMutex("HLSDemuxerCallbacksSupport")
, mDemuxer(aDemuxer)
{
MOZ_ASSERT(mDemuxer);
}
void OnInitialized(bool aHasAudio, bool aHasVideo)
{
- HLS_DEBUG("HLSDemuxerCallbacksSupport",
- "OnInitialized");
+ HLS_DEBUG("HLSDemuxerCallbacksSupport", "OnInitialized");
MutexAutoLock lock(mMutex);
if (!mDemuxer) { return; }
RefPtr<HLSDemuxerCallbacksSupport> self = this;
mDemuxer->GetTaskQueue()->Dispatch(NS_NewRunnableFunction(
"HLSDemuxer::HLSDemuxerCallbacksSupport::OnInitialized",
[=] () {
MutexAutoLock lock(self->mMutex);
if (self->mDemuxer) {
self->mDemuxer->OnInitialized(aHasAudio, aHasVideo);
}
}));
}
- // TODO: Handle the unexpected error signal from the java implementation
- // in bug 1368904.
void OnError(int aErrorCode)
{
- HLS_DEBUG("HLSDemuxerCallbacksSupport",
- "Got error(%d) from java side",
- aErrorCode);
+ HLS_DEBUG("HLSDemuxerCallbacksSupport", "Got error(%d) from java side", aErrorCode);
+ MutexAutoLock lock(mMutex);
+ if (!mDemuxer) { return; }
+ RefPtr<HLSDemuxerCallbacksSupport> self = this;
+ mDemuxer->GetTaskQueue()->Dispatch(NS_NewRunnableFunction(
+ "HLSDemuxer::HLSDemuxerCallbacksSupport::OnError",
+ [=] () {
+ MutexAutoLock lock(self->mMutex);
+ if (self->mDemuxer) {
+ self->mDemuxer->OnError(aErrorCode);
+ }
+ }));
}
+
void Detach()
{
MutexAutoLock lock(mMutex);
mDemuxer = nullptr;
}
Mutex mMutex;
private:
@@ -146,16 +153,23 @@ HLSDemuxer::OnInitialized(bool aHasAudio
}
if (aHasVideo) {
UpdateVideoInfo(0);
}
mInitPromise.ResolveIfExists(NS_OK, __func__);
}
+void
+HLSDemuxer::OnError(int aErrorCode)
+{
+ MOZ_ASSERT(OnTaskQueue());
+ mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
+}
+
RefPtr<HLSDemuxer::InitPromise>
HLSDemuxer::Init()
{
RefPtr<HLSDemuxer> self = this;
return InvokeAsync(GetTaskQueue(), __func__,
[self](){
RefPtr<InitPromise> p = self->mInitPromise.Ensure(__func__);
return p;
--- a/dom/media/hls/HLSDemuxer.h
+++ b/dom/media/hls/HLSDemuxer.h
@@ -45,16 +45,17 @@ public:
UniquePtr<EncryptionInfo> GetCrypto() override;
bool ShouldComputeStartTime() const override { return true; }
void NotifyDataArrived() override;
AutoTaskQueue* GetTaskQueue() const { return mTaskQueue; }
void OnInitialized(bool aHasAudio, bool aHasVideo);
+ void OnError(int aErrorCode);
private:
media::TimeUnit GetNextKeyFrameTime();
void UpdateVideoInfo(int index);
void UpdateAudioInfo(int index);
bool OnTaskQueue() const;
TrackInfo* GetTrackInfo(TrackInfo::TrackType);
~HLSDemuxer();
--- a/dom/media/hls/HLSResource.cpp
+++ b/dom/media/hls/HLSResource.cpp
@@ -13,63 +13,89 @@ namespace mozilla {
HLSResourceCallbacksSupport::HLSResourceCallbacksSupport(HLSResource* aResource)
{
MOZ_ASSERT(aResource);
mResource = aResource;
}
void
+HLSResourceCallbacksSupport::Detach()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+ mResource = nullptr;
+}
+
+void
HLSResourceCallbacksSupport::OnDataArrived()
{
- MOZ_ASSERT(mResource);
- mResource->onDataAvailable();
+ MOZ_ASSERT(NS_IsMainThread());
+ if (mResource) {
+ mResource->onDataAvailable();
+ }
}
void
HLSResourceCallbacksSupport::OnError(int aErrorCode)
{
- MOZ_ASSERT(mResource);
+ MOZ_ASSERT(NS_IsMainThread());
+ if (mResource) {
+ mResource->onError(aErrorCode);
+ }
}
HLSResource::HLSResource(MediaResourceCallback* aCallback,
nsIChannel* aChannel,
nsIURI* aURI,
const MediaContainerType& aContainerType)
: mCallback(aCallback)
, mChannel(aChannel)
, mURI(aURI)
, mContainerType(aContainerType)
{
nsCString spec;
nsresult rv = aURI->GetSpec(spec);
(void)rv;
HLSResourceCallbacksSupport::Init();
mJavaCallbacks = GeckoHLSResourceWrapper::Callbacks::New();
- HLSResourceCallbacksSupport::AttachNative(mJavaCallbacks,
- mozilla::MakeUnique<HLSResourceCallbacksSupport>(this));
+ mCallbackSupport = new HLSResourceCallbacksSupport(this);
+ HLSResourceCallbacksSupport::AttachNative(mJavaCallbacks, mCallbackSupport);
mHLSResourceWrapper = java::GeckoHLSResourceWrapper::Create(NS_ConvertUTF8toUTF16(spec),
mJavaCallbacks);
MOZ_ASSERT(mHLSResourceWrapper);
}
void
HLSResource::onDataAvailable()
{
MOZ_ASSERT(mCallback);
HLS_DEBUG("HLSResource", "onDataAvailable");
mCallback->NotifyDataArrived();
}
+void
+HLSResource::onError(int aErrorCode)
+{
+ MOZ_ASSERT(mCallback);
+ HLS_DEBUG("HLSResource", "onError(%d)", aErrorCode);
+ // Since HLS source should be from the Internet, we treat all resource errors
+ // from GeckoHlsPlayer as network errors.
+ mCallback->NotifyNetworkError();
+}
+
HLSResource::~HLSResource()
{
+ HLS_DEBUG("HLSResource", "~HLSResource()");
+ if (mCallbackSupport) {
+ mCallbackSupport->Detach();
+ mCallbackSupport = nullptr;
+ }
if (mJavaCallbacks) {
HLSResourceCallbacksSupport::DisposeNative(mJavaCallbacks);
mJavaCallbacks = nullptr;
}
if (mHLSResourceWrapper) {
mHLSResourceWrapper->Destroy();
mHLSResourceWrapper = nullptr;
}
- HLS_DEBUG("HLSResource", "Destroy");
}
} // namespace mozilla
--- a/dom/media/hls/HLSResource.h
+++ b/dom/media/hls/HLSResource.h
@@ -18,26 +18,29 @@ using namespace mozilla::java;
namespace mozilla {
class HLSResource;
class HLSResourceCallbacksSupport
: public GeckoHLSResourceWrapper::Callbacks::Natives<HLSResourceCallbacksSupport>
{
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(HLSResourceCallbacksSupport)
public:
typedef GeckoHLSResourceWrapper::Callbacks::Natives<HLSResourceCallbacksSupport> NativeCallbacks;
using NativeCallbacks::DisposeNative;
using NativeCallbacks::AttachNative;
HLSResourceCallbacksSupport(HLSResource* aResource);
+ void Detach();
void OnDataArrived();
void OnError(int aErrorCode);
private:
+ ~HLSResourceCallbacksSupport() {}
HLSResource* mResource;
};
class HLSResource final : public MediaResource
{
public:
HLSResource(MediaResourceCallback* aCallback,
nsIChannel* aChannel,
@@ -101,16 +104,17 @@ public:
java::GeckoHLSResourceWrapper::GlobalRef GetResourceWrapper() {
return mHLSResourceWrapper;
}
private:
friend class HLSResourceCallbacksSupport;
void onDataAvailable();
+ void onError(int aErrorCode);
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
{
size_t size = MediaResource::SizeOfExcludingThis(aMallocSizeOf);
size += mContainerType.SizeOfExcludingThis(aMallocSizeOf);
return size;
}
@@ -121,12 +125,13 @@ private:
}
RefPtr<MediaResourceCallback> mCallback;
nsCOMPtr<nsIChannel> mChannel;
nsCOMPtr<nsIURI> mURI;
const MediaContainerType mContainerType;
java::GeckoHLSResourceWrapper::GlobalRef mHLSResourceWrapper;
java::GeckoHLSResourceWrapper::Callbacks::GlobalRef mJavaCallbacks;
+ RefPtr<HLSResourceCallbacksSupport> mCallbackSupport;
};
} // namespace mozilla
#endif /* HLSResource_h_ */