зеркало из https://github.com/mozilla/gecko-dev.git
Bug 992568 - Part 2: Refactor RtspChannel to support redirection. r=sworkman
This commit is contained in:
Родитель
2ea30d25e4
Коммит
f2d1f8c08a
|
@ -15,6 +15,10 @@
|
|||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIStreamingProtocolService.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
#include "mozilla/net/RtspChannelChild.h"
|
||||
#endif
|
||||
using namespace mozilla::net;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PRLogModuleInfo* gRtspMediaResourceLog;
|
||||
|
@ -354,21 +358,21 @@ RtspMediaResource::RtspMediaResource(MediaDecoder* aDecoder,
|
|||
, mIsConnected(false)
|
||||
, mRealTime(false)
|
||||
{
|
||||
nsCOMPtr<nsIStreamingProtocolControllerService> mediaControllerService =
|
||||
do_GetService(MEDIASTREAMCONTROLLERSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(mediaControllerService);
|
||||
if (mediaControllerService) {
|
||||
mediaControllerService->Create(mChannel,
|
||||
getter_AddRefs(mMediaStreamController));
|
||||
MOZ_ASSERT(mMediaStreamController);
|
||||
mListener = new Listener(this);
|
||||
mMediaStreamController->AsyncOpen(mListener);
|
||||
}
|
||||
#ifndef NECKO_PROTOCOL_rtsp
|
||||
MOZ_CRASH("Should not be called except for B2G platform");
|
||||
#else
|
||||
MOZ_ASSERT(aChannel);
|
||||
mMediaStreamController =
|
||||
static_cast<RtspChannelChild*>(aChannel)->GetController();
|
||||
MOZ_ASSERT(mMediaStreamController);
|
||||
mListener = new Listener(this);
|
||||
mMediaStreamController->AsyncOpen(mListener);
|
||||
#ifdef PR_LOGGING
|
||||
if (!gRtspMediaResourceLog) {
|
||||
gRtspMediaResourceLog = PR_NewLogModule("RtspMediaResource");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
RtspMediaResource::~RtspMediaResource()
|
||||
|
@ -634,6 +638,9 @@ RtspMediaResource::OnDisconnected(uint8_t aTrackIdx, nsresult aReason)
|
|||
void RtspMediaResource::Suspend(bool aCloseImmediately)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
|
||||
if (NS_WARN_IF(!mDecoder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
|
||||
NS_ENSURE_TRUE_VOID(owner);
|
||||
|
@ -647,6 +654,9 @@ void RtspMediaResource::Suspend(bool aCloseImmediately)
|
|||
void RtspMediaResource::Resume()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
|
||||
if (NS_WARN_IF(!mDecoder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
|
||||
NS_ENSURE_TRUE_VOID(owner);
|
||||
|
|
|
@ -175,6 +175,7 @@ LOCAL_INCLUDES += [
|
|||
'/content/base/src',
|
||||
'/layout/generic',
|
||||
'/layout/xul',
|
||||
'/netwerk/base/src',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_DIRECTSHOW']:
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
include protocol PHttpChannel;
|
||||
include protocol PFTPChannel;
|
||||
include protocol PRtspChannel;
|
||||
include URIParams;
|
||||
include InputStreamParams;
|
||||
|
||||
|
@ -89,5 +90,15 @@ union ChannelDiverterArgs
|
|||
PFTPChannel;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RTSP IPDL structs
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct RtspChannelConnectArgs
|
||||
{
|
||||
URIParams uri;
|
||||
uint32_t channelId;
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "mozilla/dom/network/UDPSocketChild.h"
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
#include "mozilla/net/RtspControllerChild.h"
|
||||
#include "mozilla/net/RtspChannelChild.h"
|
||||
#endif
|
||||
#include "SerializedLoadContext.h"
|
||||
|
||||
|
@ -181,6 +182,23 @@ NeckoChild::DeallocPRtspControllerChild(PRtspControllerChild* child)
|
|||
return true;
|
||||
}
|
||||
|
||||
PRtspChannelChild*
|
||||
NeckoChild::AllocPRtspChannelChild(const RtspChannelConnectArgs& aArgs)
|
||||
{
|
||||
NS_NOTREACHED("AllocPRtspController should not be called");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
NeckoChild::DeallocPRtspChannelChild(PRtspChannelChild* child)
|
||||
{
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
RtspChannelChild* p = static_cast<RtspChannelChild*>(child);
|
||||
p->ReleaseIPDLReference();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
PTCPSocketChild*
|
||||
NeckoChild::AllocPTCPSocketChild()
|
||||
{
|
||||
|
|
|
@ -62,6 +62,10 @@ protected:
|
|||
virtual bool DeallocPRemoteOpenFileChild(PRemoteOpenFileChild*) MOZ_OVERRIDE;
|
||||
virtual PRtspControllerChild* AllocPRtspControllerChild() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPRtspControllerChild(PRtspControllerChild*) MOZ_OVERRIDE;
|
||||
virtual PRtspChannelChild*
|
||||
AllocPRtspChannelChild(const RtspChannelConnectArgs& aArgs)
|
||||
MOZ_OVERRIDE;
|
||||
virtual bool DeallocPRtspChannelChild(PRtspChannelChild*) MOZ_OVERRIDE;
|
||||
virtual PChannelDiverterChild*
|
||||
AllocPChannelDiverterChild(const ChannelDiverterArgs& channel) MOZ_OVERRIDE;
|
||||
virtual bool
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "mozilla/net/WebSocketChannelParent.h"
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
#include "mozilla/net/RtspControllerParent.h"
|
||||
#include "mozilla/net/RtspChannelParent.h"
|
||||
#endif
|
||||
#include "mozilla/net/DNSRequestParent.h"
|
||||
#include "mozilla/net/RemoteOpenFileParent.h"
|
||||
|
@ -336,6 +337,42 @@ NeckoParent::DeallocPRtspControllerParent(PRtspControllerParent* actor)
|
|||
return true;
|
||||
}
|
||||
|
||||
PRtspChannelParent*
|
||||
NeckoParent::AllocPRtspChannelParent(const RtspChannelConnectArgs& aArgs)
|
||||
{
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
nsCOMPtr<nsIURI> uri = DeserializeURI(aArgs.uri());
|
||||
RtspChannelParent *p = new RtspChannelParent(uri);
|
||||
p->AddRef();
|
||||
return p;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
NeckoParent::RecvPRtspChannelConstructor(
|
||||
PRtspChannelParent* aActor,
|
||||
const RtspChannelConnectArgs& aConnectArgs)
|
||||
{
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
RtspChannelParent* p = static_cast<RtspChannelParent*>(aActor);
|
||||
return p->Init(aConnectArgs);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
NeckoParent::DeallocPRtspChannelParent(PRtspChannelParent* actor)
|
||||
{
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
RtspChannelParent* p = static_cast<RtspChannelParent*>(actor);
|
||||
p->Release();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
PTCPSocketParent*
|
||||
NeckoParent::AllocPTCPSocketParent()
|
||||
{
|
||||
|
|
|
@ -144,6 +144,15 @@ protected:
|
|||
virtual PRtspControllerParent* AllocPRtspControllerParent() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPRtspControllerParent(PRtspControllerParent*) MOZ_OVERRIDE;
|
||||
|
||||
virtual PRtspChannelParent*
|
||||
AllocPRtspChannelParent(const RtspChannelConnectArgs& aArgs)
|
||||
MOZ_OVERRIDE;
|
||||
virtual bool
|
||||
RecvPRtspChannelConstructor(PRtspChannelParent* aActor,
|
||||
const RtspChannelConnectArgs& aArgs)
|
||||
MOZ_OVERRIDE;
|
||||
virtual bool DeallocPRtspChannelParent(PRtspChannelParent*) MOZ_OVERRIDE;
|
||||
|
||||
virtual PChannelDiverterParent*
|
||||
AllocPChannelDiverterParent(const ChannelDiverterArgs& channel) MOZ_OVERRIDE;
|
||||
virtual bool
|
||||
|
|
|
@ -22,6 +22,7 @@ include protocol PBlob; //FIXME: bug #792908
|
|||
include protocol PFileDescriptorSet;
|
||||
|
||||
include protocol PRtspController;
|
||||
include protocol PRtspChannel;
|
||||
include URIParams;
|
||||
include InputStreamParams;
|
||||
include NeckoChannelParams;
|
||||
|
@ -47,6 +48,7 @@ sync protocol PNecko
|
|||
manages PDNSRequest;
|
||||
manages PRemoteOpenFile;
|
||||
manages PRtspController;
|
||||
manages PRtspChannel;
|
||||
manages PChannelDiverter;
|
||||
|
||||
parent:
|
||||
|
@ -71,6 +73,7 @@ parent:
|
|||
HTMLDNSPrefetch(nsString hostname, uint16_t flags);
|
||||
CancelHTMLDNSPrefetch(nsString hostname, uint16_t flags, nsresult reason);
|
||||
PRtspController();
|
||||
PRtspChannel(RtspChannelConnectArgs args);
|
||||
PChannelDiverter(ChannelDiverterArgs channel);
|
||||
|
||||
both:
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
|
||||
|
||||
/* 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 PNecko;
|
||||
include URIParams;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
async protocol PRtspChannel
|
||||
{
|
||||
manager PNecko;
|
||||
|
||||
parent:
|
||||
// Note: channels are opened during construction, so no open method here:
|
||||
// see PNecko.ipdl
|
||||
__delete__();
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
|
@ -34,6 +34,7 @@ IPDL_SOURCES = [
|
|||
'PChannelDiverter.ipdl',
|
||||
'PNecko.ipdl',
|
||||
'PRemoteOpenFile.ipdl',
|
||||
'PRtspChannel.ipdl',
|
||||
'PRtspController.ipdl',
|
||||
]
|
||||
|
||||
|
|
|
@ -5,42 +5,72 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "RtspChannelChild.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsStandardURL.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(RtspChannelChild,
|
||||
nsBaseChannel,
|
||||
nsIChannel)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RtspChannelChild::nsIChannel
|
||||
// RtspChannelChild
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
|
||||
RtspChannelChild::RtspChannelChild(nsIURI *aUri)
|
||||
: mIPCOpen(false)
|
||||
, mCanceled(false)
|
||||
{
|
||||
MOZ_ASSERT(aListener);
|
||||
|
||||
nsCOMPtr<nsIURI> uri = nsBaseChannel::URI();
|
||||
NS_ENSURE_TRUE(uri, NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
nsAutoCString uriSpec;
|
||||
uri->GetSpec(uriSpec);
|
||||
|
||||
mListener = aListener;
|
||||
mListenerContext = aContext;
|
||||
|
||||
// Call OnStartRequest directly. mListener is expected to create/load an
|
||||
// RtspMediaResource which will create an RtspMediaController. This controller
|
||||
// manages the control and data streams to and from the network.
|
||||
mListener->OnStartRequest(this, aContext);
|
||||
return NS_OK;
|
||||
nsBaseChannel::SetURI(aUri);
|
||||
}
|
||||
|
||||
RtspChannelChild::~RtspChannelChild()
|
||||
{
|
||||
}
|
||||
|
||||
nsIStreamingProtocolController*
|
||||
RtspChannelChild::GetController()
|
||||
{
|
||||
return mMediaStreamController;
|
||||
}
|
||||
|
||||
void
|
||||
RtspChannelChild::ReleaseController()
|
||||
{
|
||||
if (mMediaStreamController) {
|
||||
mMediaStreamController = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// IPDL
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
RtspChannelChild::AddIPDLReference()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!mIPCOpen,
|
||||
"Attempt to retain more than one IPDL reference");
|
||||
mIPCOpen = true;
|
||||
AddRef();
|
||||
}
|
||||
|
||||
void
|
||||
RtspChannelChild::ReleaseIPDLReference()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference");
|
||||
mIPCOpen = false;
|
||||
Release();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsISupports
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(RtspChannelChild,
|
||||
nsBaseChannel,
|
||||
nsIChannel,
|
||||
nsIChildChannel)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::GetContentType(nsACString& aContentType)
|
||||
{
|
||||
|
@ -48,15 +78,194 @@ RtspChannelChild::GetContentType(nsACString& aContentType)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::Init(nsIURI* aUri)
|
||||
class CallListenerOnStartRequestEvent : public nsRunnable
|
||||
{
|
||||
MOZ_ASSERT(aUri);
|
||||
public:
|
||||
CallListenerOnStartRequestEvent(nsIStreamListener *aListener,
|
||||
nsIRequest *aRequest, nsISupports *aContext)
|
||||
: mListener(aListener)
|
||||
, mRequest(aRequest)
|
||||
, mContext(aContext)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aListener);
|
||||
}
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mListener->OnStartRequest(mRequest, mContext);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsRefPtr<nsIStreamListener> mListener;
|
||||
nsRefPtr<nsIRequest> mRequest;
|
||||
nsRefPtr<nsISupports> mContext;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
|
||||
{
|
||||
// Precondition checks.
|
||||
MOZ_ASSERT(aListener);
|
||||
nsCOMPtr<nsIURI> uri = nsBaseChannel::URI();
|
||||
NS_ENSURE_TRUE(uri, NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
// Create RtspController.
|
||||
nsCOMPtr<nsIStreamingProtocolControllerService> mediaControllerService =
|
||||
do_GetService(MEDIASTREAMCONTROLLERSERVICE_CONTRACTID);
|
||||
MOZ_RELEASE_ASSERT(mediaControllerService,
|
||||
"Cannot proceed if media controller service is unavailable!");
|
||||
mediaControllerService->Create(this, getter_AddRefs(mMediaStreamController));
|
||||
MOZ_ASSERT(mMediaStreamController);
|
||||
|
||||
// Add ourselves to the load group.
|
||||
if (mLoadGroup) {
|
||||
mLoadGroup->AddRequest(this, nullptr);
|
||||
}
|
||||
|
||||
// Dispatch mListener's OnStartRequest directly. mListener is expected to
|
||||
// create an RtspMediaResource and use the RtspController we just created to
|
||||
// manage the control and data streams to and from the network.
|
||||
mListener = aListener;
|
||||
mListenerContext = aContext;
|
||||
NS_DispatchToMainThread(
|
||||
new CallListenerOnStartRequestEvent(mListener, this, mListenerContext));
|
||||
|
||||
nsBaseChannel::Init();
|
||||
nsBaseChannel::SetURI(aUri);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla::net
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
|
||||
nsresult aStatusCode)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIStreamListener
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::OnDataAvailable(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsIInputStream *aInputStream,
|
||||
uint64_t aOffset,
|
||||
uint32_t aCount)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIChannel::nsIRequest
|
||||
//-----------------------------------------------------------------------------
|
||||
class CallListenerOnStopRequestEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
CallListenerOnStopRequestEvent(nsIStreamListener *aListener,
|
||||
nsIRequest *aRequest,
|
||||
nsISupports *aContext, nsresult aStatus)
|
||||
: mListener(aListener)
|
||||
, mRequest(aRequest)
|
||||
, mContext(aContext)
|
||||
, mStatus(aStatus)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aListener);
|
||||
}
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mListener->OnStopRequest(mRequest, mContext, mStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsRefPtr<nsIStreamListener> mListener;
|
||||
nsRefPtr<nsIRequest> mRequest;
|
||||
nsRefPtr<nsISupports> mContext;
|
||||
nsresult mStatus;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::Cancel(nsresult status)
|
||||
{
|
||||
if (mCanceled) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mCanceled = true;
|
||||
// Stop RtspController.
|
||||
if (mMediaStreamController) {
|
||||
mMediaStreamController->Stop();
|
||||
}
|
||||
|
||||
// Call mListener's OnStopRequest to do clean up.
|
||||
NS_DispatchToMainThread(
|
||||
new CallListenerOnStopRequestEvent(mListener, this,
|
||||
mListenerContext, status));
|
||||
mListener = nullptr;
|
||||
mListenerContext = nullptr;
|
||||
|
||||
// Remove ourselves from the load group.
|
||||
if (mLoadGroup) {
|
||||
mLoadGroup->RemoveRequest(this, nullptr, status);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::Suspend()
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::Resume()
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::OpenContentStream(bool aAsync,
|
||||
nsIInputStream **aStream,
|
||||
nsIChannel **aChannel)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsIChildChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::ConnectParent(uint32_t id)
|
||||
{
|
||||
// Create RtspChannelParent for redirection.
|
||||
AddIPDLReference();
|
||||
RtspChannelConnectArgs connectArgs;
|
||||
SerializeURI(nsBaseChannel::URI(), connectArgs.uri());
|
||||
connectArgs.channelId() = id;
|
||||
if (!gNeckoChild->SendPRtspChannelConstructor(this, connectArgs)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::CompleteRedirectSetup(nsIStreamListener *aListener,
|
||||
nsISupports *aContext)
|
||||
{
|
||||
return AsyncOpen(aListener, aContext);
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -7,69 +7,82 @@
|
|||
#ifndef RtspChannelChild_h
|
||||
#define RtspChannelChild_h
|
||||
|
||||
#include "mozilla/net/PRtspChannelChild.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "nsBaseChannel.h"
|
||||
#include "nsIChildChannel.h"
|
||||
#include "nsIStreamingProtocolController.h"
|
||||
#include "nsIStreamingProtocolService.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RtspChannelChild is a dummy channel used to aid MediaResource creation in
|
||||
// HTMLMediaElement. Actual network control and data flows are managed by an
|
||||
// RtspController object created and owned by RtspMediaResource.
|
||||
// Therefore, when RtspChannelChild::AsyncOpen is called, mListener->OnStartRequest
|
||||
// will be called immediately. It is expected that an RtspMediaResource object
|
||||
// will be created in that calling context or after; the RtspController object
|
||||
// will be created internally by RtspMediaResource."
|
||||
// HTMLMediaElement. Network control and data flows are managed by an
|
||||
// RtspController object, which is created by us and manipulated by
|
||||
// RtspMediaResource. This object is also responsible for inter-process
|
||||
// communication with the parent process.
|
||||
// When RtspChannelChild::AsyncOpen is called, it should create an
|
||||
// RtspController object, dispatch an OnStartRequest and immediately return.
|
||||
// We expect an RtspMediaResource object will be created in the calling context
|
||||
// and it will use the RtpController we create.
|
||||
|
||||
class RtspChannelChild : public nsBaseChannel
|
||||
class RtspChannelChild : public PRtspChannelChild
|
||||
, public nsBaseChannel
|
||||
, public nsIChildChannel
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICHILDCHANNEL
|
||||
|
||||
RtspChannelChild() { }
|
||||
RtspChannelChild(nsIURI *aUri);
|
||||
~RtspChannelChild();
|
||||
|
||||
~RtspChannelChild() { }
|
||||
|
||||
// Overrides nsBaseChannel::AsyncOpen and call listener's OnStartRequest immediately.
|
||||
NS_IMETHOD AsyncOpen(nsIStreamListener *listener,
|
||||
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL;
|
||||
// Set Rtsp URL.
|
||||
NS_IMETHOD Init(nsIURI* uri);
|
||||
// Overrides nsBaseChannel::GetContentType, return streaming protocol type "RTSP".
|
||||
// nsBaseChannel::nsIChannel
|
||||
NS_IMETHOD GetContentType(nsACString & aContentType) MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
|
||||
MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
NS_IMETHOD OpenContentStream(bool aAsync,
|
||||
nsIInputStream **aStream,
|
||||
nsIChannel **aChannel) MOZ_OVERRIDE MOZ_FINAL
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// nsIRequestObserver
|
||||
NS_IMETHOD OnStartRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
|
||||
NS_IMETHOD OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
|
||||
MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD OnStopRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsresult aStatusCode) MOZ_OVERRIDE MOZ_FINAL
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
nsresult aStatusCode) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// nsIStreamListener
|
||||
// nsBaseChannel::nsIStreamListener
|
||||
NS_IMETHOD OnDataAvailable(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsIInputStream *aInputStream,
|
||||
uint64_t aOffset,
|
||||
uint32_t aCount) MOZ_OVERRIDE MOZ_FINAL
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
uint32_t aCount) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// nsBaseChannel::nsIChannel::nsIRequest
|
||||
NS_IMETHOD Cancel(nsresult status) MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD Suspend() MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD Resume() MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// nsBaseChannel
|
||||
NS_IMETHOD OpenContentStream(bool aAsync,
|
||||
nsIInputStream **aStream,
|
||||
nsIChannel **aChannel) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// IPDL
|
||||
void AddIPDLReference();
|
||||
void ReleaseIPDLReference();
|
||||
|
||||
// RtspChannelChild
|
||||
nsIStreamingProtocolController* GetController();
|
||||
void ReleaseController();
|
||||
|
||||
private:
|
||||
bool mIPCOpen;
|
||||
bool mCanceled;
|
||||
nsCOMPtr<nsIStreamingProtocolController> mMediaStreamController;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mozilla::net
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // RtspChannelChild_h
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
/* 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 "RtspChannelParent.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RtspChannelParent
|
||||
//-----------------------------------------------------------------------------
|
||||
RtspChannelParent::RtspChannelParent(nsIURI *aUri)
|
||||
: mIPCClosed(false)
|
||||
{
|
||||
nsBaseChannel::SetURI(aUri);
|
||||
}
|
||||
|
||||
RtspChannelParent::~RtspChannelParent()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RtspChannelParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
mIPCClosed = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsISupports
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(RtspChannelParent,
|
||||
nsBaseChannel,
|
||||
nsIParentChannel)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RtspChannelParent methods
|
||||
//-----------------------------------------------------------------------------
|
||||
bool
|
||||
RtspChannelParent::Init(const RtspChannelConnectArgs& aArgs)
|
||||
{
|
||||
return ConnectChannel(aArgs.channelId());
|
||||
}
|
||||
|
||||
bool
|
||||
RtspChannelParent::ConnectChannel(const uint32_t& channelId)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::GetContentType(nsACString& aContentType)
|
||||
{
|
||||
aContentType.AssignLiteral("RTSP");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::OnStartRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::OnStopRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsresult aStatusCode)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIStreamListener
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::OnDataAvailable(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsIInputStream *aInputStream,
|
||||
uint64_t aOffset,
|
||||
uint32_t aCount)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIChannel::nsIRequeset
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::Cancel(nsresult status)
|
||||
{
|
||||
// FIXME: This method will be called by
|
||||
// nsXMLHttpRequest::CloseRequestWithError while closing the browser app.
|
||||
// However, the root cause is RtspChannelParent will be created by
|
||||
// nsXMLHttpRequest::Open when we navigate away from an RTSP web page.
|
||||
// We should find out why it happens and decide how to fix it.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::Suspend()
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::Resume()
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::OpenContentStream(bool aAsync,
|
||||
nsIInputStream **aStream,
|
||||
nsIChannel **aChannel)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsIParentChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::SetParentListener(HttpChannelParentListener *aListener)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::Delete()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,84 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef RtspChannelParent_h
|
||||
#define RtspChannelParent_h
|
||||
|
||||
#include "mozilla/net/PRtspChannelParent.h"
|
||||
#include "mozilla/net/NeckoParent.h"
|
||||
#include "nsBaseChannel.h"
|
||||
#include "nsIParentChannel.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Note: RtspChannel doesn't transport streams as normal channel does.
|
||||
// (See RtspChannelChild.h for detail).
|
||||
// The reason for the existence of RtspChannelParent is to support HTTP->RTSP
|
||||
// redirection.
|
||||
// When redirection happens, two instances of RtspChannelParent will be created:
|
||||
// - One will be created when HTTP creates the new channel for redirects, and
|
||||
// will be registered as an nsIChannel.
|
||||
// - The other will be created via IPDL by RtspChannelChild, and will be
|
||||
// registered as an nsIParentChannel.
|
||||
class RtspChannelParent : public PRtspChannelParent
|
||||
, public nsBaseChannel
|
||||
, public nsIParentChannel
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPARENTCHANNEL
|
||||
|
||||
RtspChannelParent(nsIURI *aUri);
|
||||
~RtspChannelParent();
|
||||
|
||||
// nsBaseChannel::nsIChannel
|
||||
NS_IMETHOD GetContentType(nsACString & aContentType) MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD AsyncOpen(nsIStreamListener *listener,
|
||||
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
|
||||
NS_IMETHOD OnStartRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD OnStopRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsresult aStatusCode) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// nsBaseChannel::nsIStreamListener
|
||||
NS_IMETHOD OnDataAvailable(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsIInputStream *aInputStream,
|
||||
uint64_t aOffset,
|
||||
uint32_t aCount) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// nsBaseChannel::nsIChannel::nsIRequest
|
||||
NS_IMETHOD Cancel(nsresult status) MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD Suspend() MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD Resume() MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// nsBaseChannel
|
||||
NS_IMETHOD OpenContentStream(bool aAsync,
|
||||
nsIInputStream **aStream,
|
||||
nsIChannel **aChannel) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// RtspChannelParent
|
||||
bool Init(const RtspChannelConnectArgs& aArgs);
|
||||
|
||||
protected:
|
||||
// Used to connect redirected-to channel in parent with just created
|
||||
// ChildChannel. Used during HTTP->RTSP redirection.
|
||||
bool ConnectChannel(const uint32_t& channelId);
|
||||
|
||||
private:
|
||||
bool mIPCClosed;
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // RtspChannelParent_h
|
|
@ -5,6 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "RtspChannelChild.h"
|
||||
#include "RtspChannelParent.h"
|
||||
#include "RtspHandler.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
|
@ -68,15 +69,19 @@ NS_IMETHODIMP
|
|||
RtspHandler::NewChannel(nsIURI *aURI, nsIChannel **aResult)
|
||||
{
|
||||
bool isRtsp = false;
|
||||
nsRefPtr<RtspChannelChild> rtspChannel;
|
||||
nsRefPtr<nsBaseChannel> rtspChannel;
|
||||
|
||||
nsresult rv = aURI->SchemeIs("rtsp", &isRtsp);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(isRtsp, NS_ERROR_UNEXPECTED);
|
||||
|
||||
rtspChannel = new RtspChannelChild();
|
||||
if (IsNeckoChild()) {
|
||||
rtspChannel = new RtspChannelChild(aURI);
|
||||
} else {
|
||||
rtspChannel = new RtspChannelParent(aURI);
|
||||
}
|
||||
|
||||
rv = rtspChannel->Init(aURI);
|
||||
rv = rtspChannel->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rtspChannel.forget(aResult);
|
||||
|
|
|
@ -78,6 +78,12 @@ RtspControllerChild::~RtspControllerChild()
|
|||
LOG(("RtspControllerChild::~RtspControllerChild()"));
|
||||
}
|
||||
|
||||
void
|
||||
RtspControllerChild::ReleaseChannel()
|
||||
{
|
||||
static_cast<RtspChannelChild*>(mChannel.get())->ReleaseController();
|
||||
}
|
||||
|
||||
bool
|
||||
RtspControllerChild::OKToSendIPC()
|
||||
{
|
||||
|
@ -174,6 +180,7 @@ RtspControllerChild::RecvOnDisconnected(
|
|||
if (mListener) {
|
||||
mListener->OnDisconnected(index, reason);
|
||||
}
|
||||
ReleaseChannel();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -185,6 +192,7 @@ RtspControllerChild::RecvAsyncOpenFailed(const nsresult& reason)
|
|||
if (mListener) {
|
||||
mListener->OnDisconnected(0, NS_ERROR_CONNECTION_REFUSED);
|
||||
}
|
||||
ReleaseChannel();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/net/RtspChannelChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
@ -70,6 +71,8 @@ class RtspControllerChild : public nsIStreamingProtocolController
|
|||
uint32_t mTotalTracks;
|
||||
// Current suspension depth for this channel object
|
||||
uint32_t mSuspendCount;
|
||||
// Detach channel-controller relationship.
|
||||
void ReleaseChannel();
|
||||
};
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -10,6 +10,7 @@ EXPORTS.mozilla.net += [
|
|||
'controller/RtspMetaData.h',
|
||||
'rtsp/RTSPSource.h',
|
||||
'RtspChannelChild.h',
|
||||
'RtspChannelParent.h',
|
||||
'RtspHandler.h',
|
||||
]
|
||||
|
||||
|
@ -20,6 +21,7 @@ SOURCES += [
|
|||
'controller/RtspControllerParent.cpp',
|
||||
'controller/RtspMetaData.cpp',
|
||||
'RtspChannelChild.cpp',
|
||||
'RtspChannelParent.cpp',
|
||||
'RtspHandler.cpp',
|
||||
]
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче