deleted file mode 100644
--- a/netwerk/protocol/rtsp/RtspChannelChild.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/* -*- 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 "nsContentSecurityManager.h"
-#include "nsContentUtils.h"
-#include "RtspChannelChild.h"
-#include "mozilla/ipc/URIUtils.h"
-#include "nsServiceManagerUtils.h"
-
-using namespace mozilla::ipc;
-
-namespace mozilla {
-namespace net {
-
-//-----------------------------------------------------------------------------
-// RtspChannelChild
-//-----------------------------------------------------------------------------
-RtspChannelChild::RtspChannelChild(nsIURI *aUri)
- : mIPCOpen(false)
- , mCanceled(false)
-{
- nsBaseChannel::SetURI(aUri);
- DisallowThreadRetargeting();
-}
-
-RtspChannelChild::~RtspChannelChild()
-{
-}
-
-nsIStreamingProtocolController*
-RtspChannelChild::GetController()
-{
- return mMediaStreamController;
-}
-
-void
-RtspChannelChild::ReleaseController()
-{
- if (mMediaStreamController) {
- mMediaStreamController = nullptr;
- }
-}
-
-//-----------------------------------------------------------------------------
-// IPDL
-//-----------------------------------------------------------------------------
-void
-RtspChannelChild::AddIPDLReference()
-{
- MOZ_ASSERT(!mIPCOpen,
- "Attempt to retain more than one IPDL reference");
- mIPCOpen = true;
- AddRef();
-}
-
-void
-RtspChannelChild::ReleaseIPDLReference()
-{
- MOZ_ASSERT(mIPCOpen, "Attempt to release nonexistent IPDL reference");
- mIPCOpen = false;
- Release();
-}
-
-//-----------------------------------------------------------------------------
-// nsISupports
-//-----------------------------------------------------------------------------
-NS_IMPL_ISUPPORTS_INHERITED(RtspChannelChild,
- nsBaseChannel,
- nsIChannel,
- nsIChildChannel)
-
-//-----------------------------------------------------------------------------
-// nsBaseChannel::nsIChannel
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspChannelChild::GetContentType(nsACString& aContentType)
-{
- aContentType.AssignLiteral("RTSP");
- return NS_OK;
-}
-
-class CallListenerOnStartRequestEvent : public Runnable
-{
-public:
- CallListenerOnStartRequestEvent(nsIStreamListener *aListener,
- nsIRequest *aRequest, nsISupports *aContext)
- : mListener(aListener)
- , mRequest(aRequest)
- , mContext(aContext)
- {
- MOZ_RELEASE_ASSERT(aListener);
- }
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
- mListener->OnStartRequest(mRequest, mContext);
- return NS_OK;
- }
-private:
- RefPtr<nsIStreamListener> mListener;
- RefPtr<nsIRequest> mRequest;
- RefPtr<nsISupports> mContext;
-};
-
-NS_IMETHODIMP
-RtspChannelChild::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
-{
- MOZ_ASSERT(!mLoadInfo ||
- mLoadInfo->GetSecurityMode() == 0 ||
- mLoadInfo->GetInitialSecurityCheckDone() ||
- (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL &&
- nsContentUtils::IsSystemPrincipal(mLoadInfo->LoadingPrincipal())),
- "security flags in loadInfo but asyncOpen2() not called");
-
- // 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));
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspChannelChild::AsyncOpen2(nsIStreamListener *aListener)
-{
- nsCOMPtr<nsIStreamListener> listener = aListener;
- nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
- NS_ENSURE_SUCCESS(rv, rv);
- return AsyncOpen(listener, nullptr);
-}
-
-//-----------------------------------------------------------------------------
-// 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 Runnable
-{
-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() override
- {
- MOZ_ASSERT(NS_IsMainThread());
- mListener->OnStopRequest(mRequest, mContext, mStatus);
- return NS_OK;
- }
-private:
- RefPtr<nsIStreamListener> mListener;
- RefPtr<nsIRequest> mRequest;
- RefPtr<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)
-{
- if (mLoadInfo && mLoadInfo->GetEnforceSecurity()) {
- MOZ_ASSERT(!aContext, "aContext should be null!");
- return AsyncOpen2(aListener);
- }
- return AsyncOpen(aListener, aContext);
-}
-
-} // namespace net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/rtsp/RtspChannelChild.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- 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 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. 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 PRtspChannelChild
- , public nsBaseChannel
- , public nsIChildChannel
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSICHILDCHANNEL
-
- RtspChannelChild(nsIURI *aUri);
-
- // nsBaseChannel::nsIChannel
- NS_IMETHOD GetContentType(nsACString & aContentType) override final;
- NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
- override final;
- NS_IMETHOD AsyncOpen2(nsIStreamListener *listener) override final;
-
- // nsBaseChannel::nsIStreamListener::nsIRequestObserver
- NS_IMETHOD OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
- override final;
- NS_IMETHOD OnStopRequest(nsIRequest *aRequest,
- nsISupports *aContext,
- nsresult aStatusCode) override final;
-
- // nsBaseChannel::nsIStreamListener
- NS_IMETHOD OnDataAvailable(nsIRequest *aRequest,
- nsISupports *aContext,
- nsIInputStream *aInputStream,
- uint64_t aOffset,
- uint32_t aCount) override final;
-
- // nsBaseChannel::nsIChannel::nsIRequest
- NS_IMETHOD Cancel(nsresult status) override final;
- NS_IMETHOD Suspend() override final;
- NS_IMETHOD Resume() override final;
-
- // nsBaseChannel
- NS_IMETHOD OpenContentStream(bool aAsync,
- nsIInputStream **aStream,
- nsIChannel **aChannel) override final;
-
- // IPDL
- void AddIPDLReference();
- void ReleaseIPDLReference();
-
- // RtspChannelChild
- nsIStreamingProtocolController* GetController();
- void ReleaseController();
-
-protected:
- ~RtspChannelChild();
-
-private:
- bool mIPCOpen;
- bool mCanceled;
- nsCOMPtr<nsIStreamingProtocolController> mMediaStreamController;
-};
-
-} // namespace net
-} // namespace mozilla
-
-#endif // RtspChannelChild_h
deleted file mode 100644
--- a/netwerk/protocol/rtsp/RtspChannelParent.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/* -*- 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"
-#include "nsContentSecurityManager.h"
-
-using namespace mozilla::ipc;
-
-namespace mozilla {
-namespace net {
-
-//-----------------------------------------------------------------------------
-// RtspChannelParent
-//-----------------------------------------------------------------------------
-RtspChannelParent::RtspChannelParent(nsIURI *aUri)
- : mIPCClosed(false)
-{
- nsBaseChannel::SetURI(aUri);
- DisallowThreadRetargeting();
-}
-
-RtspChannelParent::~RtspChannelParent()
-{
-}
-
-void
-RtspChannelParent::ActorDestroy(ActorDestroyReason why)
-{
- mIPCClosed = true;
-}
-
-//-----------------------------------------------------------------------------
-// nsISupports
-//-----------------------------------------------------------------------------
-NS_IMPL_ISUPPORTS_INHERITED(RtspChannelParent,
- nsBaseChannel,
- nsIParentChannel)
-
-//-----------------------------------------------------------------------------
-// RtspChannelParent methods
-//-----------------------------------------------------------------------------
-bool
-RtspChannelParent::Init(const RtspChannelConnectArgs& aArgs)
-{
- return ConnectChannel(aArgs.channelId());
-}
-
-bool
-RtspChannelParent::ConnectChannel(const uint32_t& channelId)
-{
- nsCOMPtr<nsIChannel> channel;
- 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;
-}
-
-NS_IMETHODIMP
-RtspChannelParent::AsyncOpen2(nsIStreamListener *aListener)
-{
- 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::NotifyTrackingProtectionDisabled()
-{
- // One day, this should probably be filled in.
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspChannelParent::Delete()
-{
- return NS_OK;
-}
-
-} // namespace net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/rtsp/RtspChannelParent.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- 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);
-
- // nsBaseChannel::nsIChannel
- NS_IMETHOD GetContentType(nsACString & aContentType) override final;
- NS_IMETHOD AsyncOpen(nsIStreamListener *listener,
- nsISupports *aContext) override final;
- NS_IMETHOD AsyncOpen2(nsIStreamListener *listener) override final;
-
- // nsBaseChannel::nsIStreamListener::nsIRequestObserver
- NS_IMETHOD OnStartRequest(nsIRequest *aRequest,
- nsISupports *aContext) override final;
- NS_IMETHOD OnStopRequest(nsIRequest *aRequest,
- nsISupports *aContext,
- nsresult aStatusCode) override final;
-
- // nsBaseChannel::nsIStreamListener
- NS_IMETHOD OnDataAvailable(nsIRequest *aRequest,
- nsISupports *aContext,
- nsIInputStream *aInputStream,
- uint64_t aOffset,
- uint32_t aCount) override final;
-
- // nsBaseChannel::nsIChannel::nsIRequest
- NS_IMETHOD Cancel(nsresult status) override final;
- NS_IMETHOD Suspend() override final;
- NS_IMETHOD Resume() override final;
-
- // nsBaseChannel
- NS_IMETHOD OpenContentStream(bool aAsync,
- nsIInputStream **aStream,
- nsIChannel **aChannel) override final;
-
- // RtspChannelParent
- bool Init(const RtspChannelConnectArgs& aArgs);
-
-protected:
- ~RtspChannelParent();
-
- // 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) override;
-};
-
-} // namespace net
-} // namespace mozilla
-
-#endif // RtspChannelParent_h
deleted file mode 100644
--- a/netwerk/protocol/rtsp/RtspHandler.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- 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 "RtspChannelChild.h"
-#include "RtspChannelParent.h"
-#include "RtspHandler.h"
-#include "nsILoadGroup.h"
-#include "nsIInterfaceRequestor.h"
-#include "nsIURI.h"
-#include "nsAutoPtr.h"
-#include "nsStandardURL.h"
-#include "mozilla/net/NeckoChild.h"
-
-namespace mozilla {
-namespace net {
-
-NS_IMPL_ISUPPORTS(RtspHandler, nsIProtocolHandler)
-
-//-----------------------------------------------------------------------------
-// RtspHandler::nsIProtocolHandler
-//-----------------------------------------------------------------------------
-
-NS_IMETHODIMP
-RtspHandler::GetScheme(nsACString &aScheme)
-{
- aScheme.AssignLiteral("rtsp");
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspHandler::GetDefaultPort(int32_t *aDefaultPort)
-{
- *aDefaultPort = kDefaultRtspPort;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspHandler::GetProtocolFlags(uint32_t *aProtocolFlags)
-{
- *aProtocolFlags = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_ANYONE |
- URI_NON_PERSISTABLE | URI_SYNC_LOAD_IS_OK;
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspHandler::NewURI(const nsACString & aSpec,
- const char *aOriginCharset,
- nsIURI *aBaseURI, nsIURI **aResult)
-{
- int32_t port;
-
- nsresult rv = GetDefaultPort(&port);
- NS_ENSURE_SUCCESS(rv, rv);
-
- RefPtr<nsStandardURL> url = new nsStandardURL();
- rv = url->Init(nsIStandardURL::URLTYPE_AUTHORITY, port, aSpec,
- aOriginCharset, aBaseURI);
- NS_ENSURE_SUCCESS(rv, rv);
-
- url.forget(aResult);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspHandler::NewChannel2(nsIURI* aURI,
- nsILoadInfo* aLoadInfo,
- nsIChannel** aResult)
-{
- bool isRtsp = false;
- RefPtr<nsBaseChannel> rtspChannel;
-
- nsresult rv = aURI->SchemeIs("rtsp", &isRtsp);
- NS_ENSURE_SUCCESS(rv, rv);
- NS_ENSURE_TRUE(isRtsp, NS_ERROR_UNEXPECTED);
-
- if (IsNeckoChild()) {
- rtspChannel = new RtspChannelChild(aURI);
- } else {
- rtspChannel = new RtspChannelParent(aURI);
- }
-
- rv = rtspChannel->Init();
- NS_ENSURE_SUCCESS(rv, rv);
-
- // set the loadInfo on the new channel
- rv = rtspChannel->SetLoadInfo(aLoadInfo);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rtspChannel.forget(aResult);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspHandler::NewChannel(nsIURI *aURI, nsIChannel **aResult)
-{
- return NewChannel2(aURI, nullptr, aResult);
-}
-
-NS_IMETHODIMP
-RtspHandler::AllowPort(int32_t port, const char *scheme, bool *aResult)
-{
- // Do not override any blacklisted ports.
- *aResult = false;
- return NS_OK;
-}
-
-} // namespace net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/rtsp/RtspHandler.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- 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 RtspHandler_h
-#define RtspHandler_h
-
-#include "nsIProtocolHandler.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-
-namespace mozilla {
-namespace net {
-
-
-class RtspHandler final : public nsIProtocolHandler
-{
- public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIPROTOCOLHANDLER
-
- RtspHandler() { }
- const static int32_t kDefaultRtspPort = 554;
-
-protected:
- ~RtspHandler() { }
-};
-
-} // namespace net
-} // namespace mozilla
-
-#endif // RtspHandler_h
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspController.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-/* -*- 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 "RtspController.h"
-#include "RtspMetaData.h"
-#include "nsIURI.h"
-#include "nsICryptoHash.h"
-#include "nsIRunnable.h"
-#include "nsIPrefBranch.h"
-#include "nsIPrefService.h"
-#include "nsICancelable.h"
-#include "nsIStreamConverterService.h"
-#include "nsIIOService2.h"
-#include "nsIProtocolProxyService.h"
-#include "nsIProxyInfo.h"
-#include "nsIProxiedChannel.h"
-#include "nsIHttpProtocolHandler.h"
-
-#include "nsAutoPtr.h"
-#include "nsStandardURL.h"
-#include "nsNetCID.h"
-#include "nsServiceManagerUtils.h"
-#include "nsXPIDLString.h"
-#include "nsCRT.h"
-#include "nsThreadUtils.h"
-#include "nsError.h"
-#include "nsStringStream.h"
-#include "nsAlgorithm.h"
-#include "nsProxyRelease.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/Telemetry.h"
-#include "mozilla/TimeStamp.h"
-#include "mozilla/Logging.h"
-
-#include "plbase64.h"
-#include "prmem.h"
-#include "prnetdb.h"
-#include "zlib.h"
-#include <algorithm>
-#include "nsDebug.h"
-
-namespace mozilla {
-namespace net {
-extern LazyLogModule gRtspLog;
-#undef LOG
-#define LOG(args) MOZ_LOG(mozilla::net::gRtspLog, mozilla::LogLevel::Debug, args)
-
-//-----------------------------------------------------------------------------
-// RtspController
-//-----------------------------------------------------------------------------
-NS_IMPL_ISUPPORTS(RtspController,
- nsIStreamingProtocolController)
-
-RtspController::RtspController(nsIChannel *channel)
- : mState(INIT)
-{
- LOG(("RtspController::RtspController()"));
-}
-
-RtspController::~RtspController()
-{
- LOG(("RtspController::~RtspController()"));
- if (mRtspSource.get()) {
- mRtspSource.clear();
- }
-}
-
-//-----------------------------------------------------------------------------
-// nsIStreamingProtocolController
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspController::GetTrackMetaData(uint8_t index,
- nsIStreamingProtocolMetaData * *_retval)
-{
- LOG(("RtspController::GetTrackMetaData()"));
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspController::Play(void)
-{
- LOG(("RtspController::Play()"));
- if (!mRtspSource.get()) {
- MOZ_ASSERT(mRtspSource.get(), "mRtspSource should not be null!");
- return NS_ERROR_NOT_INITIALIZED;
- }
-
- if (mState != CONNECTED) {
- return NS_ERROR_NOT_CONNECTED;
- }
-
- mRtspSource->play();
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspController::Pause(void)
-{
- LOG(("RtspController::Pause()"));
- if (!mRtspSource.get()) {
- MOZ_ASSERT(mRtspSource.get(), "mRtspSource should not be null!");
- return NS_ERROR_NOT_INITIALIZED;
- }
-
- if (mState != CONNECTED) {
- return NS_ERROR_NOT_CONNECTED;
- }
-
- mRtspSource->pause();
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspController::Resume(void)
-{
- return Play();
-}
-
-NS_IMETHODIMP
-RtspController::Suspend(void)
-{
- return Pause();
-}
-
-NS_IMETHODIMP
-RtspController::Seek(uint64_t seekTimeUs)
-{
- LOG(("RtspController::Seek() %llu", seekTimeUs));
- if (!mRtspSource.get()) {
- MOZ_ASSERT(mRtspSource.get(), "mRtspSource should not be null!");
- return NS_ERROR_NOT_INITIALIZED;
- }
-
- if (mState != CONNECTED) {
- return NS_ERROR_NOT_CONNECTED;
- }
-
- mRtspSource->seek(seekTimeUs);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspController::Stop()
-{
- LOG(("RtspController::Stop()"));
- mState = INIT;
- if (!mRtspSource.get()) {
- MOZ_ASSERT(mRtspSource.get(), "mRtspSource should not be null!");
- return NS_ERROR_NOT_INITIALIZED;
- }
-
- mRtspSource->stop();
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspController::GetTotalTracks(uint8_t *aTracks)
-{
- LOG(("RtspController::GetTotalTracks()"));
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-RtspController::AsyncOpen(nsIStreamingProtocolListener *aListener)
-{
- if (!aListener) {
- LOG(("RtspController::AsyncOpen() illegal listener"));
- return NS_ERROR_NOT_INITIALIZED;
- }
-
- mListener = aListener;
-
- if (!mURI) {
- LOG(("RtspController::AsyncOpen() illegal URI"));
- return NS_ERROR_ILLEGAL_VALUE;
- }
-
- nsAutoCString uriSpec;
- mURI->GetSpec(uriSpec);
- LOG(("RtspController AsyncOpen uri=%s", uriSpec.get()));
-
- if (!mRtspSource.get()) {
- mRtspSource = new android::RTSPSource(this, uriSpec.get(),
- mUserAgent.get(), false, 0);
- }
- // Connect to Rtsp Server.
- mRtspSource->start();
-
- return NS_OK;
-}
-
-//-----------------------------------------------------------------------------
-// nsIStreamingProtocolListener
-//-----------------------------------------------------------------------------
-class SendMediaDataTask : public Runnable
-{
-public:
- SendMediaDataTask(nsIStreamingProtocolListener *listener,
- uint8_t index,
- const nsACString & data,
- uint32_t length,
- uint32_t offset,
- nsIStreamingProtocolMetaData *meta)
- : mIndex(index)
- , mLength(length)
- , mOffset(offset)
- , mMetaData(meta)
- , mListener(listener)
- {
- mData.Assign(data);
- }
-
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
- mListener->OnMediaDataAvailable(mIndex, mData, mLength,
- mOffset, mMetaData);
- return NS_OK;
- }
-
-private:
- uint8_t mIndex;
- nsCString mData;
- uint32_t mLength;
- uint32_t mOffset;
- RefPtr<nsIStreamingProtocolMetaData> mMetaData;
- nsCOMPtr<nsIStreamingProtocolListener> mListener;
-};
-
-NS_IMETHODIMP
-RtspController::OnMediaDataAvailable(uint8_t index,
- const nsACString & data,
- uint32_t length,
- uint32_t offset,
- nsIStreamingProtocolMetaData *meta)
-{
- if (mListener && mState == CONNECTED) {
- RefPtr<SendMediaDataTask> task =
- new SendMediaDataTask(mListener, index, data, length, offset, meta);
- return NS_DispatchToMainThread(task);
- }
- return NS_ERROR_NOT_AVAILABLE;
-}
-
-class SendOnConnectedTask : public Runnable
-{
-public:
- SendOnConnectedTask(nsIStreamingProtocolListener *listener,
- uint8_t index,
- nsIStreamingProtocolMetaData *meta)
- : mListener(listener)
- , mIndex(index)
- , mMetaData(meta)
- { }
-
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
- mListener->OnConnected(mIndex, mMetaData);
- return NS_OK;
- }
-
-private:
- nsCOMPtr<nsIStreamingProtocolListener> mListener;
- uint8_t mIndex;
- RefPtr<nsIStreamingProtocolMetaData> mMetaData;
-};
-
-
-NS_IMETHODIMP
-RtspController::OnConnected(uint8_t index,
- nsIStreamingProtocolMetaData *meta)
-{
- LOG(("RtspController::OnConnected()"));
- mState = CONNECTED;
- if (mListener) {
- RefPtr<SendOnConnectedTask> task =
- new SendOnConnectedTask(mListener, index, meta);
- return NS_DispatchToMainThread(task);
- }
- return NS_ERROR_NOT_AVAILABLE;
-}
-
-class SendOnDisconnectedTask : public Runnable
-{
-public:
- SendOnDisconnectedTask(nsIStreamingProtocolListener *listener,
- uint8_t index,
- nsresult reason)
- : mListener(listener)
- , mIndex(index)
- , mReason(reason)
- { }
-
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
- mListener->OnDisconnected(mIndex, mReason);
- return NS_OK;
- }
-
-private:
- nsCOMPtr<nsIStreamingProtocolListener> mListener;
- uint8_t mIndex;
- nsresult mReason;
-};
-
-NS_IMETHODIMP
-RtspController::OnDisconnected(uint8_t index,
- nsresult reason)
-{
- LOG(("RtspController::OnDisconnected() for track %d reason = 0x%x", index, reason));
- mState = DISCONNECTED;
-
- if (mListener) {
- RefPtr<SendOnDisconnectedTask> task =
- new SendOnDisconnectedTask(mListener, index, reason);
- // Break the cycle reference between the Listener (RtspControllerParent) and
- // us.
- mListener = nullptr;
- return NS_DispatchToMainThread(task);
- }
- return NS_ERROR_NOT_AVAILABLE;
-}
-
-NS_IMETHODIMP
-RtspController::Init(nsIURI *aURI)
-{
- nsresult rv;
-
- if (!aURI) {
- LOG(("RtspController::Init() - invalid URI"));
- return NS_ERROR_NOT_INITIALIZED;
- }
-
- nsAutoCString host;
- int32_t port = -1;
-
- rv = aURI->GetAsciiHost(host);
- if (NS_FAILED(rv)) return rv;
-
- // Reject the URL if it doesn't specify a host
- if (host.IsEmpty())
- return NS_ERROR_MALFORMED_URI;
-
- rv = aURI->GetPort(&port);
- if (NS_FAILED(rv)) return rv;
-
- rv = aURI->GetAsciiSpec(mSpec);
- if (NS_FAILED(rv)) return rv;
-
- mURI = aURI;
-
- // Get User-Agent.
- nsCOMPtr<nsIHttpProtocolHandler>
- service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
- rv = service->GetUserAgent(mUserAgent);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspController::PlaybackEnded()
-{
- LOG(("RtspController::PlaybackEnded()"));
- if (!mRtspSource.get()) {
- MOZ_ASSERT(mRtspSource.get(), "mRtspSource should not be null!");
- return NS_ERROR_NOT_INITIALIZED;
- }
-
- mRtspSource->playbackEnded();
- return NS_OK;
-}
-
-} // namespace mozilla::net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspController.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- 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 RtspController_h
-#define RtspController_h
-
-#include "nsIStreamingProtocolController.h"
-#include "nsIChannel.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-#include "RTSPSource.h"
-
-namespace mozilla {
-namespace net {
-
-class RtspController final : public nsIStreamingProtocolController
- , public nsIStreamingProtocolListener
-{
-public:
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSISTREAMINGPROTOCOLCONTROLLER
- NS_DECL_NSISTREAMINGPROTOCOLLISTENER
-
- RtspController(nsIChannel *channel);
-
-protected:
- ~RtspController();
-
-private:
- enum State {
- INIT,
- CONNECTED,
- DISCONNECTED
- };
-
- // RTSP URL refer to a stream or an aggregate of streams.
- nsCOMPtr<nsIURI> mURI;
- // The nsIStreamingProtocolListener implementation.
- nsCOMPtr<nsIStreamingProtocolListener> mListener;
- // ASCII encoded URL spec.
- nsCString mSpec;
- // UserAgent string.
- nsCString mUserAgent;
- // Indicate the connection state between the
- // media streaming server and the Rtsp client.
- State mState;
- // Rtsp Streaming source.
- android::sp<android::RTSPSource> mRtspSource;
-};
-
-}
-
-} // namespace mozilla::net
-
-#endif
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspControllerChild.cpp
+++ /dev/null
@@ -1,613 +0,0 @@
-/* -*- 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 "RtspControllerChild.h"
-#include "RtspMetaData.h"
-#include "mozilla/dom/TabChild.h"
-#include "mozilla/net/NeckoChild.h"
-#include "nsITabChild.h"
-#include "nsILoadContext.h"
-#include "mozilla/ipc/InputStreamUtils.h"
-#include "mozilla/ipc/URIUtils.h"
-#include "nsStringStream.h"
-#include "mozilla/Logging.h"
-
-const uint32_t kRtspTotalTracks = 2;
-const unsigned long kRtspCommandDelayMs = 200;
-
-using namespace mozilla::ipc;
-
-namespace mozilla {
-namespace net {
-
-static LazyLogModule gRtspChildLog("nsRtspChild");
-#undef LOG
-#define LOG(args) MOZ_LOG(mozilla::net::gRtspChildLog, mozilla::LogLevel::Debug, args)
-
-NS_IMPL_ADDREF(RtspControllerChild)
-
-NS_IMETHODIMP_(nsrefcnt) RtspControllerChild::Release()
-{
- NS_PRECONDITION(0 != mRefCnt, "dup release");
- // Enable this to find non-threadsafe destructors:
- // NS_ASSERT_OWNINGTHREAD(RtspControllerChild);
- --mRefCnt;
- NS_LOG_RELEASE(this, mRefCnt, "RtspControllerChild");
-
- if (mRefCnt == 1 && mIPCOpen) {
- Send__delete__(this);
- return mRefCnt;
- }
-
- if (mRefCnt == 0) {
- mRefCnt = 1; /* stabilize */
- delete this;
- return 0;
- }
- return mRefCnt;
-}
-
-NS_INTERFACE_MAP_BEGIN(RtspControllerChild)
- NS_INTERFACE_MAP_ENTRY(nsIStreamingProtocolController)
- NS_INTERFACE_MAP_ENTRY(nsIStreamingProtocolListener)
- NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStreamingProtocolController)
-NS_INTERFACE_MAP_END
-
-//-----------------------------------------------------------------------------
-// RtspControllerChild methods
-//-----------------------------------------------------------------------------
-RtspControllerChild::RtspControllerChild(nsIChannel *channel)
- : mIPCOpen(false)
- , mIPCAllowed(false)
- , mChannel(channel)
- , mTotalTracks(0)
- , mSuspendCount(0)
- , mTimerLock("RtspControllerChild.mTimerLock")
- , mPlayTimer(nullptr)
- , mPauseTimer(nullptr)
-{
- AddIPDLReference();
- gNeckoChild->SendPRtspControllerConstructor(this);
-}
-
-RtspControllerChild::~RtspControllerChild()
-{
- LOG(("RtspControllerChild::~RtspControllerChild()"));
-}
-
-void
-RtspControllerChild::ReleaseChannel()
-{
- static_cast<RtspChannelChild*>(mChannel.get())->ReleaseController();
-}
-
-bool
-RtspControllerChild::OKToSendIPC()
-{
- MOZ_ASSERT(NS_IsMainThread());
- if (mIPCOpen == false) {
- return false;
- }
- return mIPCAllowed;
-}
-
-void
-RtspControllerChild::AllowIPC()
-{
- MOZ_ASSERT(NS_IsMainThread());
- mIPCAllowed = true;
-}
-
-void
-RtspControllerChild::DisallowIPC()
-{
- MOZ_ASSERT(NS_IsMainThread());
- mIPCAllowed = false;
-}
-
-void
-RtspControllerChild::StopPlayAndPauseTimer()
-{
- MutexAutoLock lock(mTimerLock);
- if (mPlayTimer) {
- mPlayTimer->Cancel();
- mPlayTimer = nullptr;
- }
- if (mPauseTimer) {
- mPauseTimer->Cancel();
- mPauseTimer = nullptr;
- }
-}
-
-//-----------------------------------------------------------------------------
-// RtspControllerChild::PRtspControllerChild
-//-----------------------------------------------------------------------------
-bool
-RtspControllerChild::RecvOnMediaDataAvailable(
- const uint8_t& index,
- const nsCString& data,
- const uint32_t& length,
- const uint32_t& offset,
- InfallibleTArray<RtspMetadataParam>&& metaArray)
-{
- RefPtr<RtspMetaData> meta = new RtspMetaData();
- nsresult rv = meta->DeserializeRtspMetaData(metaArray);
- NS_ENSURE_SUCCESS(rv, true);
-
- if (mListener) {
- mListener->OnMediaDataAvailable(index, data, length, offset, meta.get());
- }
- return true;
-}
-
-void
-RtspControllerChild::AddMetaData(
- already_AddRefed<nsIStreamingProtocolMetaData>&& meta)
-{
- mMetaArray.AppendElement(mozilla::Move(meta));
-}
-
-int
-RtspControllerChild::GetMetaDataLength()
-{
- return mMetaArray.Length();
-}
-
-bool
-RtspControllerChild::RecvOnConnected(
- const uint8_t& index,
- InfallibleTArray<RtspMetadataParam>&& metaArray)
-{
- // Deserialize meta data.
- RefPtr<RtspMetaData> meta = new RtspMetaData();
- nsresult rv = meta->DeserializeRtspMetaData(metaArray);
- NS_ENSURE_SUCCESS(rv, true);
- meta->GetTotalTracks(&mTotalTracks);
- if (mTotalTracks <= 0) {
- LOG(("RtspControllerChild::RecvOnConnected invalid tracks %d", mTotalTracks));
- // Set the default value.
- mTotalTracks = kRtspTotalTracks;
- }
- AddMetaData(meta.forget().downcast<nsIStreamingProtocolMetaData>());
-
- // Notify the listener when meta data of tracks are available.
- if ((static_cast<uint32_t>(index) + 1) == mTotalTracks) {
- // The controller provide |GetTrackMetaData| method for his client.
- if (mListener) {
- mListener->OnConnected(index, nullptr);
- }
- }
- return true;
-}
-
-bool
-RtspControllerChild::RecvOnDisconnected(
- const uint8_t& index,
- const nsresult& reason)
-{
- StopPlayAndPauseTimer();
- DisallowIPC();
- LOG(("RtspControllerChild::RecvOnDisconnected for track %d reason = 0x%x", index, reason));
- if (mListener) {
- mListener->OnDisconnected(index, reason);
- }
- ReleaseChannel();
- return true;
-}
-
-bool
-RtspControllerChild::RecvAsyncOpenFailed(const nsresult& reason)
-{
- StopPlayAndPauseTimer();
- DisallowIPC();
- LOG(("RtspControllerChild::RecvAsyncOpenFailed reason = 0x%x", reason));
- if (mListener) {
- mListener->OnDisconnected(0, NS_ERROR_CONNECTION_REFUSED);
- }
- ReleaseChannel();
- return true;
-}
-
-void
-RtspControllerChild::AddIPDLReference()
-{
- MOZ_ASSERT(!mIPCOpen,
- "Attempt to retain more than one IPDL reference");
- mIPCOpen = true;
- AllowIPC();
- AddRef();
-}
-
-void
-RtspControllerChild::ReleaseIPDLReference()
-{
- MOZ_ASSERT(mIPCOpen, "Attempt to release nonexistent IPDL reference");
- mIPCOpen = false;
- DisallowIPC();
- Release();
-}
-
-NS_IMETHODIMP
-RtspControllerChild::GetTrackMetaData(
- uint8_t index,
- nsIStreamingProtocolMetaData **result)
-{
- if (GetMetaDataLength() <= 0 || index >= GetMetaDataLength()) {
- LOG(("RtspControllerChild:: meta data is not available"));
- return NS_ERROR_NOT_INITIALIZED;
- }
- LOG(("RtspControllerChild::GetTrackMetaData() %d", index));
- NS_IF_ADDREF(*result = mMetaArray[index]);
- return NS_OK;
-}
-
-enum IPCEvent
-{
- SendNoneEvent = 0,
- SendPlayEvent,
- SendPauseEvent,
- SendSeekEvent,
- SendStopEvent,
- SendPlaybackEndedEvent
-};
-
-class SendIPCEvent : public Runnable
-{
-public:
- SendIPCEvent(RtspControllerChild *aController, IPCEvent aEvent)
- : mController(aController)
- , mEvent(aEvent)
- , mSeekTime(0)
- {
- }
-
- SendIPCEvent(RtspControllerChild *aController,
- IPCEvent aEvent,
- uint64_t aSeekTime)
- : mController(aController)
- , mEvent(aEvent)
- , mSeekTime(aSeekTime)
- {
- }
-
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
- if (mController->OKToSendIPC() == false) {
- // Don't send any more IPC events; no guarantee that parent objects are
- // still alive.
- return NS_ERROR_FAILURE;
- }
- bool rv = true;
-
- if (mEvent == SendPlayEvent) {
- rv = mController->SendPlay();
- } else if (mEvent == SendPauseEvent) {
- rv = mController->SendPause();
- } else if (mEvent == SendSeekEvent) {
- rv = mController->SendSeek(mSeekTime);
- } else if (mEvent == SendStopEvent) {
- rv = mController->SendStop();
- } else if (mEvent == SendPlaybackEndedEvent) {
- rv = mController->SendPlaybackEnded();
- } else {
- LOG(("RtspControllerChild::SendIPCEvent"));
- }
- if (!rv) {
- return NS_ERROR_FAILURE;
- }
- return NS_OK;
- }
-private:
- RefPtr<RtspControllerChild> mController;
- IPCEvent mEvent;
- uint64_t mSeekTime;
-};
-
-//-----------------------------------------------------------------------------
-// RtspControllerChild::nsIStreamingProtocolController
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspControllerChild::Play(void)
-{
- LOG(("RtspControllerChild::Play()"));
-
- MutexAutoLock lock(mTimerLock);
- // Cancel the pause timer if it is active because successive pause-play in a
- // short duration is unncessary but could impair playback smoothing.
- if (mPauseTimer) {
- mPauseTimer->Cancel();
- mPauseTimer = nullptr;
- }
-
- // Start a timer to delay the play operation for a short duration.
- if (!mPlayTimer) {
- mPlayTimer = do_CreateInstance("@mozilla.org/timer;1");
- if (!mPlayTimer) {
- return NS_ERROR_NOT_INITIALIZED;
- }
- // We have to dispatch the timer callback to the main thread because the
- // decoder thread is a thread from nsIThreadPool and cannot be the timer
- // target. Furthermore, IPC send functions should only be called from the
- // main thread.
- nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
- mPlayTimer->SetTarget(mainThread);
- mPlayTimer->InitWithFuncCallback(
- RtspControllerChild::PlayTimerCallback,
- this, kRtspCommandDelayMs,
- nsITimer::TYPE_ONE_SHOT);
- }
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::Pause(void)
-{
- LOG(("RtspControllerChild::Pause()"));
-
- MutexAutoLock lock(mTimerLock);
- // Cancel the play timer if it is active because successive play-pause in a
- // shrot duration is unnecessary but could impair playback smoothing.
- if (mPlayTimer) {
- mPlayTimer->Cancel();
- mPlayTimer = nullptr;
- }
-
- // Start a timer to delay the pause operation for a short duration.
- if (!mPauseTimer) {
- mPauseTimer = do_CreateInstance("@mozilla.org/timer;1");
- if (!mPauseTimer) {
- return NS_ERROR_NOT_INITIALIZED;
- }
- // We have to dispatch the timer callback to the main thread because the
- // decoder thread is a thread from nsIThreadPool and cannot be the timer
- // target.
- nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
- mPauseTimer->SetTarget(mainThread);
- mPauseTimer->InitWithFuncCallback(
- RtspControllerChild::PauseTimerCallback,
- this, kRtspCommandDelayMs,
- nsITimer::TYPE_ONE_SHOT);
- }
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::Resume(void)
-{
- LOG(("RtspControllerChild::Resume()"));
- NS_ENSURE_TRUE(mSuspendCount > 0, NS_ERROR_UNEXPECTED);
-
- if (!--mSuspendCount) {
- return Play();
- }
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::Suspend(void)
-{
- LOG(("RtspControllerChild::Suspend()"));
-
- if (!mSuspendCount++) {
- return Pause();
- }
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::Seek(uint64_t seekTimeUs)
-{
- LOG(("RtspControllerChild::Seek() %llu", seekTimeUs));
-
- if (NS_IsMainThread()) {
- if (!OKToSendIPC() || !SendSeek(seekTimeUs)) {
- return NS_ERROR_FAILURE;
- }
- } else {
- nsresult rv = NS_DispatchToMainThread(
- new SendIPCEvent(this, SendSeekEvent, seekTimeUs));
- NS_ENSURE_SUCCESS(rv, rv);
- }
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::Stop()
-{
- LOG(("RtspControllerChild::Stop()"));
- StopPlayAndPauseTimer();
-
- if (NS_IsMainThread()) {
- if (!OKToSendIPC() || !SendStop()) {
- return NS_ERROR_FAILURE;
- }
- DisallowIPC();
- } else {
- nsresult rv = NS_DispatchToMainThread(
- new SendIPCEvent(this, SendStopEvent));
- NS_ENSURE_SUCCESS(rv, rv);
- }
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::GetTotalTracks(uint8_t *aTracks)
-{
- NS_ENSURE_ARG_POINTER(aTracks);
- *aTracks = kRtspTotalTracks;
- if (mTotalTracks) {
- *aTracks = mTotalTracks;
- }
- LOG(("RtspControllerChild::GetTracks() %d", *aTracks));
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::PlaybackEnded()
-{
- LOG(("RtspControllerChild::PlaybackEnded"));
-
- StopPlayAndPauseTimer();
-
- if (NS_IsMainThread()) {
- if (!OKToSendIPC() || !SendPlaybackEnded()) {
- return NS_ERROR_FAILURE;
- }
- } else {
- nsresult rv = NS_DispatchToMainThread(
- new SendIPCEvent(this, SendPlaybackEndedEvent));
- NS_ENSURE_SUCCESS(rv, rv);
- }
-
- return NS_OK;
-}
-
-//-----------------------------------------------------------------------------
-// RtspControllerChild::nsIStreamingProtocolListener
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspControllerChild::OnMediaDataAvailable(uint8_t index,
- const nsACString & data,
- uint32_t length,
- uint32_t offset,
- nsIStreamingProtocolMetaData *meta)
-{
- LOG(("RtspControllerChild::OnMediaDataAvailable()"));
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::OnConnected(uint8_t index,
- nsIStreamingProtocolMetaData *meta)
-
-{
- LOG(("RtspControllerChild::OnConnected()"));
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::OnDisconnected(uint8_t index,
- nsresult reason)
-{
- LOG(("RtspControllerChild::OnDisconnected() reason = 0x%x", reason));
- return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-//-----------------------------------------------------------------------------
-// RtspControllerChild::nsIStreamingProtocoController
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspControllerChild::Init(nsIURI *aURI)
-{
- nsresult rv;
-
- if (!aURI) {
- LOG(("RtspControllerChild::Init() - invalid URI"));
- return NS_ERROR_NOT_INITIALIZED;
- }
-
- nsAutoCString host;
- int32_t port = -1;
-
- rv = aURI->GetAsciiHost(host);
- if (NS_FAILED(rv)) return rv;
-
- // Reject the URL if it doesn't specify a host
- if (host.IsEmpty())
- return NS_ERROR_MALFORMED_URI;
-
- rv = aURI->GetPort(&port);
- if (NS_FAILED(rv)) return rv;
-
- rv = aURI->GetAsciiSpec(mSpec);
- if (NS_FAILED(rv)) return rv;
-
- if (!strncmp(mSpec.get(), "rtsp:", 5) == 0)
- return NS_ERROR_UNEXPECTED;
-
- mURI = aURI;
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::AsyncOpen(nsIStreamingProtocolListener *aListener)
-{
- LOG(("RtspControllerChild::AsyncOpen()"));
- if (!aListener) {
- LOG(("RtspControllerChild::AsyncOpen() - invalid listener"));
- return NS_ERROR_NOT_INITIALIZED;
- }
- mListener = aListener;
-
- if (!mChannel) {
- LOG(("RtspControllerChild::AsyncOpen() - invalid URI"));
- return NS_ERROR_NOT_INITIALIZED;
- }
-
- nsCOMPtr<nsIURI> uri;
- URIParams uriParams;
- mChannel->GetURI(getter_AddRefs(uri));
- if (!uri) {
- LOG(("RtspControllerChild::AsyncOpen() - invalid URI"));
- return NS_ERROR_NOT_INITIALIZED;
- }
- SerializeURI(uri, uriParams);
-
- if (!OKToSendIPC() || !SendAsyncOpen(uriParams)) {
- return NS_ERROR_FAILURE;
- }
- return NS_OK;
-}
-
-//-----------------------------------------------------------------------------
-// RtspControllerChild static member methods
-//-----------------------------------------------------------------------------
-//static
-void
-RtspControllerChild::PlayTimerCallback(nsITimer *aTimer, void *aClosure)
-{
- MOZ_ASSERT(aTimer);
- MOZ_ASSERT(aClosure);
- MOZ_ASSERT(NS_IsMainThread());
-
- RtspControllerChild *self = static_cast<RtspControllerChild*>(aClosure);
-
- MutexAutoLock lock(self->mTimerLock);
- if (!self->mPlayTimer || !self->OKToSendIPC()) {
- return;
- }
- self->SendPlay();
- self->mPlayTimer = nullptr;
-}
-
-//static
-void
-RtspControllerChild::PauseTimerCallback(nsITimer *aTimer, void *aClosure)
-{
- MOZ_ASSERT(aTimer);
- MOZ_ASSERT(aClosure);
- MOZ_ASSERT(NS_IsMainThread());
-
- RtspControllerChild *self = static_cast<RtspControllerChild*>(aClosure);
-
- MutexAutoLock lock(self->mTimerLock);
- if (!self->mPauseTimer || !self->OKToSendIPC()) {
- return;
- }
- self->SendPause();
- self->mPauseTimer = nullptr;
-}
-
-} // namespace net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspControllerChild.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* -*- 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 RtspControllerChild_h
-#define RtspControllerChild_h
-
-#include "mozilla/net/PRtspControllerChild.h"
-#include "nsIStreamingProtocolController.h"
-#include "nsIChannel.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-#include "nsTArray.h"
-#include "mozilla/net/RtspChannelChild.h"
-#include "mozilla/Mutex.h"
-#include "nsITimer.h"
-
-namespace mozilla {
-namespace net {
-
-class RtspControllerChild : public nsIStreamingProtocolController
- , public nsIStreamingProtocolListener
- , public PRtspControllerChild
-{
- public:
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSISTREAMINGPROTOCOLCONTROLLER
- NS_DECL_NSISTREAMINGPROTOCOLLISTENER
-
- RtspControllerChild(nsIChannel *channel);
-
- bool RecvOnConnected(const uint8_t& index,
- InfallibleTArray<RtspMetadataParam>&& meta);
-
- bool RecvOnMediaDataAvailable(
- const uint8_t& index,
- const nsCString& data,
- const uint32_t& length,
- const uint32_t& offset,
- InfallibleTArray<RtspMetadataParam>&& meta);
-
- bool RecvOnDisconnected(const uint8_t& index,
- const nsresult& reason);
-
- bool RecvAsyncOpenFailed(const nsresult& reason);
- void AddIPDLReference();
- void ReleaseIPDLReference();
- void AddMetaData(already_AddRefed<nsIStreamingProtocolMetaData>&& meta);
- int GetMetaDataLength();
- bool OKToSendIPC();
- void AllowIPC();
- void DisallowIPC();
-
- // These callbacks will be called when mPlayTimer/mPauseTimer fires.
- static void PlayTimerCallback(nsITimer *aTimer, void *aClosure);
- static void PauseTimerCallback(nsITimer *aTimer, void *aClosure);
-
- protected:
- ~RtspControllerChild();
-
- private:
- bool mIPCOpen;
- // The intention of this variable is just to avoid any IPC message to be sent
- // when this flag is set as false. Nothing more.
- bool mIPCAllowed;
- // Dummy channel used to aid MediaResource creation in HTMLMediaElement.
- nsCOMPtr<nsIChannel> mChannel;
- // The nsIStreamingProtocolListener implementation.
- nsCOMPtr<nsIStreamingProtocolListener> mListener;
- // RTSP URL refer to a stream or an aggregate of streams.
- nsCOMPtr<nsIURI> mURI;
- // Array refer to metadata of the media stream.
- nsTArray<nsCOMPtr<nsIStreamingProtocolMetaData>> mMetaArray;
- // ASCII encoded URL spec
- nsCString mSpec;
- // The total tracks for the given media stream session.
- uint32_t mTotalTracks;
- // Current suspension depth for this channel object
- uint32_t mSuspendCount;
- // Detach channel-controller relationship.
- void ReleaseChannel();
- // This lock protects mPlayTimer and mPauseTimer.
- Mutex mTimerLock;
- // Timers to delay the play and pause operations.
- // They are used for optimization and to avoid sending unnecessary requests to
- // the server.
- nsCOMPtr<nsITimer> mPlayTimer;
- nsCOMPtr<nsITimer> mPauseTimer;
- // Timers should be stopped if we are going to terminate, such as when
- // receiving Stop command or OnDisconnected event.
- void StopPlayAndPauseTimer();
-};
-
-} // namespace net
-} // namespace mozilla
-
-#endif // RtspControllerChild_h
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspControllerParent.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/* -*- 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 "RtspControllerParent.h"
-#include "RtspController.h"
-#include "nsIAuthPromptProvider.h"
-#include "nsThreadUtils.h"
-#include "nsProxyRelease.h"
-#include "mozilla/ipc/InputStreamUtils.h"
-#include "mozilla/ipc/URIUtils.h"
-#include "mozilla/unused.h"
-#include "mozilla/Logging.h"
-
-#include <sys/types.h>
-
-#define SEND_DISCONNECT_IF_ERROR(rv) \
- if (NS_FAILED(rv) && mIPCOpen && mTotalTracks > 0ul) { \
- for (uint32_t i = 0; i < mTotalTracks; i++) { \
- Unused << SendOnDisconnected(i, rv); \
- } \
- }
-
-using namespace mozilla::ipc;
-
-namespace mozilla {
-namespace net {
-
-LazyLogModule gRtspLog("nsRtsp");
-#undef LOG
-#define LOG(args) MOZ_LOG(mozilla::net::gRtspLog, mozilla::LogLevel::Debug, args)
-
-void
-RtspControllerParent::Destroy()
-{
- // If we're being destroyed on a non-main thread, we AddRef again and use a
- // proxy to release the RtspControllerParent on the main thread, where the
- // RtspControllerParent is deleted. This ensures we only delete the
- // RtspControllerParent on the main thread.
- if (!NS_IsMainThread()) {
- RefPtr<RtspControllerParent> doomed(this);
- NS_ReleaseOnMainThread(doomed.forget(), true);
- } else {
- delete this;
- }
-}
-
-NS_IMPL_ADDREF(RtspControllerParent)
-NS_IMPL_RELEASE_WITH_DESTROY(RtspControllerParent, Destroy())
-NS_IMPL_QUERY_INTERFACE(RtspControllerParent,
- nsIStreamingProtocolListener)
-
-RtspControllerParent::RtspControllerParent()
- : mIPCOpen(true)
- , mTotalTracks(0)
-{
-}
-
-RtspControllerParent::~RtspControllerParent()
-{
-}
-
-void
-RtspControllerParent::ActorDestroy(ActorDestroyReason why)
-{
- LOG(("RtspControllerParent::ActorDestroy()"));
- mIPCOpen = false;
-
- NS_ENSURE_TRUE_VOID(mController);
- if (mController) {
- mController->Stop();
- mController = nullptr;
- }
-}
-
-bool
-RtspControllerParent::RecvAsyncOpen(const URIParams& aURI)
-{
- LOG(("RtspControllerParent::RecvAsyncOpen()"));
-
- mURI = DeserializeURI(aURI);
-
- mController = new RtspController(nullptr);
- mController->Init(mURI);
- nsresult rv = mController->AsyncOpen(this);
- if (NS_SUCCEEDED(rv)) return true;
-
- mController = nullptr;
- return SendAsyncOpenFailed(rv);
-}
-
-bool
-RtspControllerParent::RecvPlay()
-{
- LOG(("RtspControllerParent::RecvPlay()"));
- NS_ENSURE_TRUE(mController, true);
-
- nsresult rv = mController->Play();
- SEND_DISCONNECT_IF_ERROR(rv)
- return true;
-}
-
-bool
-RtspControllerParent::RecvPause()
-{
- LOG(("RtspControllerParent::RecvPause()"));
- NS_ENSURE_TRUE(mController, true);
-
- nsresult rv = mController->Pause();
- SEND_DISCONNECT_IF_ERROR(rv)
- return true;
-}
-
-bool
-RtspControllerParent::RecvResume()
-{
- LOG(("RtspControllerParent::RecvResume()"));
- NS_ENSURE_TRUE(mController, true);
-
- nsresult rv = mController->Resume();
- SEND_DISCONNECT_IF_ERROR(rv)
- return true;
-}
-
-bool
-RtspControllerParent::RecvSuspend()
-{
- LOG(("RtspControllerParent::RecvSuspend()"));
- NS_ENSURE_TRUE(mController, true);
-
- nsresult rv = mController->Suspend();
- SEND_DISCONNECT_IF_ERROR(rv)
- return true;
-}
-
-bool
-RtspControllerParent::RecvSeek(const uint64_t& offset)
-{
- LOG(("RtspControllerParent::RecvSeek()"));
- NS_ENSURE_TRUE(mController, true);
-
- nsresult rv = mController->Seek(offset);
- SEND_DISCONNECT_IF_ERROR(rv)
- return true;
-}
-
-bool
-RtspControllerParent::RecvStop()
-{
- LOG(("RtspControllerParent::RecvStop()"));
- NS_ENSURE_TRUE(mController, true);
-
- nsresult rv = mController->Stop();
- NS_ENSURE_SUCCESS(rv, true);
- return true;
-}
-
-bool
-RtspControllerParent::RecvPlaybackEnded()
-{
- LOG(("RtspControllerParent::RecvPlaybackEnded()"));
- NS_ENSURE_TRUE(mController, true);
-
- nsresult rv = mController->PlaybackEnded();
- SEND_DISCONNECT_IF_ERROR(rv)
- return true;
-}
-
-NS_IMETHODIMP
-RtspControllerParent::OnMediaDataAvailable(uint8_t index,
- const nsACString & data,
- uint32_t length,
- uint32_t offset,
- nsIStreamingProtocolMetaData *meta)
-{
- NS_ENSURE_ARG_POINTER(meta);
- uint32_t int32Value;
- uint64_t int64Value;
-
- nsresult rv = meta->GetTimeStamp(&int64Value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-
- LOG(("RtspControllerParent:: OnMediaDataAvailable %d:%d time %lld",
- index, length, int64Value));
-
- // Serialize meta data.
- nsCString name;
- name.AssignLiteral("TIMESTAMP");
- InfallibleTArray<RtspMetadataParam> metaData;
- metaData.AppendElement(RtspMetadataParam(name, int64Value));
-
- name.AssignLiteral("FRAMETYPE");
- rv = meta->GetFrameType(&int32Value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- metaData.AppendElement(RtspMetadataParam(name, int32Value));
-
- nsCString stream;
- stream.Assign(data);
- if (!mIPCOpen ||
- !SendOnMediaDataAvailable(index, stream, length, offset, metaData)) {
- return NS_ERROR_FAILURE;
- }
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerParent::OnConnected(uint8_t index,
- nsIStreamingProtocolMetaData *meta)
-{
- NS_ENSURE_ARG_POINTER(meta);
- uint32_t int32Value;
- uint64_t int64Value;
-
- LOG(("RtspControllerParent:: OnConnected"));
- // Serialize meta data.
- InfallibleTArray<RtspMetadataParam> metaData;
- nsCString name;
- name.AssignLiteral("TRACKS");
- nsresult rv = meta->GetTotalTracks(&mTotalTracks);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- metaData.AppendElement(RtspMetadataParam(name, mTotalTracks));
-
- name.AssignLiteral("MIMETYPE");
- nsCString mimeType;
- rv = meta->GetMimeType(mimeType);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- metaData.AppendElement(RtspMetadataParam(name, mimeType));
-
- name.AssignLiteral("WIDTH");
- rv = meta->GetWidth(&int32Value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- metaData.AppendElement(RtspMetadataParam(name, int32Value));
-
- name.AssignLiteral("HEIGHT");
- rv = meta->GetHeight(&int32Value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- metaData.AppendElement(RtspMetadataParam(name, int32Value));
-
- name.AssignLiteral("DURATION");
- rv = meta->GetDuration(&int64Value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- metaData.AppendElement(RtspMetadataParam(name, int64Value));
-
- name.AssignLiteral("SAMPLERATE");
- rv = meta->GetSampleRate(&int32Value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- metaData.AppendElement(RtspMetadataParam(name, int32Value));
-
- name.AssignLiteral("TIMESTAMP");
- rv = meta->GetTimeStamp(&int64Value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- metaData.AppendElement(RtspMetadataParam(name, int64Value));
-
- name.AssignLiteral("CHANNELCOUNT");
- rv = meta->GetChannelCount(&int32Value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- metaData.AppendElement(RtspMetadataParam(name, int32Value));
-
- nsCString esds;
- rv = meta->GetEsdsData(esds);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- name.AssignLiteral("ESDS");
- metaData.AppendElement(RtspMetadataParam(name, esds));
-
- nsCString avcc;
- rv = meta->GetAvccData(avcc);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- name.AssignLiteral("AVCC");
- metaData.AppendElement(RtspMetadataParam(name, avcc));
-
- if (!mIPCOpen || !SendOnConnected(index, metaData)) {
- return NS_ERROR_FAILURE;
- }
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerParent::OnDisconnected(uint8_t index,
- nsresult reason)
-{
- LOG(("RtspControllerParent::OnDisconnected() for track %d reason = 0x%x", index, reason));
- if (!mIPCOpen || !SendOnDisconnected(index, reason)) {
- return NS_ERROR_FAILURE;
- }
- if (mController) {
- mController = nullptr;
- }
- return NS_OK;
-}
-
-} // namespace net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspControllerParent.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- 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 RtspControllerParent_h
-#define RtspControllerParent_h
-
-#include "mozilla/net/PRtspControllerParent.h"
-#include "mozilla/net/NeckoParent.h"
-#include "nsIStreamingProtocolController.h"
-#include "nsILoadContext.h"
-#include "nsIURI.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-
-namespace mozilla {
-namespace net {
-
-class RtspControllerParent : public PRtspControllerParent
- , public nsIStreamingProtocolListener
-{
- public:
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSISTREAMINGPROTOCOLLISTENER
-
- RtspControllerParent();
-
- bool RecvAsyncOpen(const URIParams& aURI);
- bool RecvPlay();
- bool RecvPause();
- bool RecvResume();
- bool RecvSuspend();
- bool RecvSeek(const uint64_t& offset);
- bool RecvStop();
- bool RecvPlaybackEnded();
-
- protected:
- ~RtspControllerParent();
-
- private:
- bool mIPCOpen;
- void ActorDestroy(ActorDestroyReason why);
- // RTSP URL refer to a stream or an aggregate of streams.
- nsCOMPtr<nsIURI> mURI;
- // The nsIStreamingProtocolController implementation.
- nsCOMPtr<nsIStreamingProtocolController> mController;
- uint32_t mTotalTracks;
- // Ensure we are destroyed on the main thread.
- void Destroy();
-};
-
-} // namespace net
-} // namespace mozilla
-
-#endif // RtspControllerParent_h
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspMetaData.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/* -*- 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 "RtspMetaData.h"
-#include "mozilla/Logging.h"
-
-using namespace mozilla;
-
-namespace mozilla {
-namespace net {
-
-NS_IMPL_ISUPPORTS(RtspMetaData, nsIStreamingProtocolMetaData)
-
-RtspMetaData::RtspMetaData()
- : mIndex(0)
- , mWidth(0)
- , mHeight(0)
- , mDuration(0)
- , mSampleRate(0)
- , mCurrentTimeStamp(0)
- , mChannelCount(0)
-{
- mMimeType.AssignLiteral("NONE");
-}
-
-RtspMetaData::~RtspMetaData()
-{
-
-}
-
-nsresult
-RtspMetaData::DeserializeRtspMetaData(const InfallibleTArray<RtspMetadataParam>& metaArray)
-{
- nsresult rv;
-
- // Deserialize meta data.
- for (uint32_t i = 0; i < metaArray.Length(); i++) {
- const RtspMetaValue& value = metaArray[i].value();
- const nsCString& name = metaArray[i].name();
-
- if (name.EqualsLiteral("FRAMETYPE")) {
- rv = SetFrameType(value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- } else if (name.EqualsLiteral("TIMESTAMP")) {
- rv = SetTimeStamp(value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- } else if (name.EqualsLiteral("TRACKS")) {
- rv = SetTotalTracks(value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- } else if(name.EqualsLiteral("MIMETYPE")) {
- rv = SetMimeType(value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- } else if (name.EqualsLiteral("WIDTH")) {
- rv = SetWidth(value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- } else if (name.EqualsLiteral("HEIGHT")) {
- rv = SetHeight(value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- } else if (name.EqualsLiteral("SAMPLERATE")) {
- rv = SetSampleRate(value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- } else if(name.EqualsLiteral("DURATION")) {
- rv = SetDuration(value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- } else if (name.EqualsLiteral("CHANNELCOUNT")) {
- rv = SetChannelCount(value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- } else if (name.EqualsLiteral("ESDS")) {
- rv = SetEsdsData(value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- } else if (name.EqualsLiteral("AVCC")) {
- rv = SetAvccData(value);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
- }
- }
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetFrameType(uint32_t *aFrameType)
-{
- NS_ENSURE_ARG_POINTER(aFrameType);
- *aFrameType = mFrameType;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetFrameType(uint32_t aFrameType)
-{
- mFrameType = aFrameType;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetTotalTracks(uint32_t *aTracks)
-{
- NS_ENSURE_ARG_POINTER(aTracks);
- *aTracks = mTotalTracks;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetTotalTracks(uint32_t aTracks)
-{
- mTotalTracks = aTracks;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetMimeType(nsACString & aMimeType)
-{
- aMimeType.Assign(mMimeType);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetMimeType(const nsACString & aMimeType)
-{
- mMimeType.Assign(aMimeType);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetWidth(uint32_t *aWidth)
-{
- NS_ENSURE_ARG_POINTER(aWidth);
- *aWidth = mWidth;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetWidth(uint32_t aWidth)
-{
- mWidth = aWidth;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetHeight(uint32_t *aHeight)
-{
- NS_ENSURE_ARG_POINTER(aHeight);
- *aHeight = mHeight;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetHeight(uint32_t aHeight)
-{
- mHeight = aHeight;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetDuration(uint64_t *aDuration)
-{
- NS_ENSURE_ARG_POINTER(aDuration);
- *aDuration = mDuration;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetDuration(uint64_t aDuration)
-{
- mDuration = aDuration;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetSampleRate(uint32_t *aSampleRate)
-{
- NS_ENSURE_ARG_POINTER(aSampleRate);
- *aSampleRate = mSampleRate;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetSampleRate(uint32_t aSampleRate)
-{
- mSampleRate = aSampleRate;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetTimeStamp(uint64_t *aTimeStamp)
-{
- NS_ENSURE_ARG_POINTER(aTimeStamp);
- *aTimeStamp = mCurrentTimeStamp;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetTimeStamp(uint64_t aTimeStamp)
-{
- mCurrentTimeStamp = aTimeStamp;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetChannelCount(uint32_t *aChannelCount)
-{
- NS_ENSURE_ARG_POINTER(aChannelCount);
- *aChannelCount = mChannelCount;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetChannelCount(uint32_t aChannelCount)
-{
- mChannelCount = aChannelCount;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetEsdsData(nsACString & aESDS)
-{
- aESDS.Assign(mESDS);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetEsdsData(const nsACString & aESDS)
-{
- mESDS.Assign(aESDS);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetAvccData(nsACString & aAVCC)
-{
- aAVCC.Assign(mAVCC);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetAvccData(const nsACString & aAVCC)
-{
- mAVCC.Assign(aAVCC);
- return NS_OK;
-}
-
-} // namespace mozilla::net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspMetaData.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- 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 RtspMetaData_h
-#define RtspMetaData_h
-
-#include "mozilla/net/PRtspController.h"
-#include "nsIStreamingProtocolController.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-
-namespace mozilla {
-namespace net {
-
-class RtspMetaData final : public nsIStreamingProtocolMetaData
-{
- public:
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSISTREAMINGPROTOCOLMETADATA
-
- RtspMetaData();
-
- nsresult DeserializeRtspMetaData(const InfallibleTArray<RtspMetadataParam>& metaArray);
-
- protected:
- ~RtspMetaData();
-
- private:
- uint32_t mFrameType;
- uint32_t mIndex;
- uint32_t mTotalTracks;
- uint32_t mWidth;
- uint32_t mHeight;
- uint64_t mDuration;
- uint32_t mSampleRate;
- uint64_t mCurrentTimeStamp;
- uint32_t mChannelCount;
- nsCString mMimeType;
- nsCString mESDS;
- nsCString mAVCC;
-};
-
-} // namespace net
-} // namespace mozilla
-
-#endif // RtspMetaData_h
deleted file mode 100644
--- a/netwerk/protocol/rtsp/moz.build
+++ /dev/null
@@ -1,73 +0,0 @@
-# vim: set filetype=python:
-# 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/.
-
-EXPORTS.mozilla.net += [
- 'controller/RtspController.h',
- 'controller/RtspControllerChild.h',
- 'controller/RtspControllerParent.h',
- 'controller/RtspMetaData.h',
- 'rtsp/RTSPSource.h',
- 'RtspChannelChild.h',
- 'RtspChannelParent.h',
- 'RtspHandler.h',
-]
-
-UNIFIED_SOURCES += [
- 'controller/RtspController.cpp',
- 'controller/RtspControllerChild.cpp',
- 'controller/RtspControllerParent.cpp',
- 'controller/RtspMetaData.cpp',
- 'RtspChannelChild.cpp',
- 'RtspChannelParent.cpp',
- 'RtspHandler.cpp',
-]
-
-# Android sources
-SOURCES += [
- 'rtsp/AAMRAssembler.cpp',
- 'rtsp/AAVCAssembler.cpp',
- 'rtsp/AH263Assembler.cpp',
- 'rtsp/AMPEG4AudioAssembler.cpp',
- 'rtsp/AMPEG4ElementaryAssembler.cpp',
- 'rtsp/APacketSource.cpp',
- 'rtsp/ARawAudioAssembler.cpp',
- 'rtsp/ARTPAssembler.cpp',
- 'rtsp/ARTPConnection.cpp',
- 'rtsp/ARTPSource.cpp',
- 'rtsp/ARTPWriter.cpp',
- 'rtsp/ARTSPConnection.cpp',
- 'rtsp/ASessionDescription.cpp',
- 'rtsp/RTSPSource.cpp',
-]
-
-include('/ipc/chromium/chromium-config.mozbuild')
-
-# Suppress some GCC warnings being treated as errors:
-# - about attributes on forward declarations for types that are already
-# defined, which complains about an important MOZ_EXPORT for android::AString
-if CONFIG['GNU_CC']:
- CXXFLAGS += ['-Wno-error=attributes']
-
-FINAL_LIBRARY = 'xul'
-
-DEFINES['IMPL_NS_NET'] = True
-DEFINES['FORCE_PR_LOG'] = True
-
-LOCAL_INCLUDES += [
- '/dom/base',
- '/netwerk/base',
- 'controller',
- 'rtsp',
-]
-
-for var in ('IMPL_NS_NET', 'FORCE_PR_LOG'):
- DEFINES[var] = True
-
-if CONFIG['ANDROID_VERSION'] == '15':
- LOCAL_INCLUDES += ['%' + '%s/frameworks/base/media/libstagefright/mpeg2ts' % CONFIG['ANDROID_SOURCE']]
-else:
- LOCAL_INCLUDES += ['%' + '%s/frameworks/av/media/libstagefright/mpeg2ts' % CONFIG['ANDROID_SOURCE']]
-
-CXXFLAGS += ['-Wno-multichar']
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AAMRAssembler.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AAMRAssembler"
-#include "RtspPrlog.h"
-
-#include "AAMRAssembler.h"
-
-#include "ARTPSource.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/Utils.h>
-
-namespace android {
-
-static bool GetAttribute(const char *s, const char *key, AString *value) {
- value->clear();
-
- size_t keyLen = strlen(key);
-
- for (;;) {
- const char *colonPos = strchr(s, ';');
-
- size_t len =
- (colonPos == NULL) ? strlen(s) : colonPos - s;
-
- if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
- value->setTo(&s[keyLen + 1], len - keyLen - 1);
- return true;
- }
- if (len == keyLen && !strncmp(s, key, keyLen)) {
- value->setTo("1");
- return true;
- }
-
- if (colonPos == NULL) {
- return false;
- }
-
- s = colonPos + 1;
- }
-}
-
-AAMRAssembler::AAMRAssembler(
- const sp<AMessage> ¬ify, bool isWide, const AString ¶ms)
- : mIsWide(isWide),
- mNotifyMsg(notify),
- mNextExpectedSeqNoValid(false),
- mNextExpectedSeqNo(0) {
- AString value;
- CHECK(GetAttribute(params.c_str(), "octet-align", &value) && value == "1");
- CHECK(!GetAttribute(params.c_str(), "crc", &value) || value == "0");
- CHECK(!GetAttribute(params.c_str(), "interleaving", &value));
-}
-
-AAMRAssembler::~AAMRAssembler() {
-}
-
-ARTPAssembler::AssemblyStatus AAMRAssembler::assembleMore(
- const sp<ARTPSource> &source) {
- return addPacket(source);
-}
-
-static size_t getFrameSize(bool isWide, unsigned FT) {
- static const size_t kFrameSizeNB[9] = {
- 95, 103, 118, 134, 148, 159, 204, 244, 39
- };
- static const size_t kFrameSizeWB[10] = {
- 132, 177, 253, 285, 317, 365, 397, 461, 477, 40
- };
-
- if (FT == 15) {
- return 1;
- }
-
- size_t frameSize = isWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT];
-
- // Round up bits to bytes and add 1 for the header byte.
- frameSize = (frameSize + 7) / 8 + 1;
-
- return frameSize;
-}
-
-ARTPAssembler::AssemblyStatus AAMRAssembler::addPacket(
- const sp<ARTPSource> &source) {
- List<sp<ABuffer> > *queue = source->queue();
-
- if (queue->empty()) {
- return NOT_ENOUGH_DATA;
- }
-
- if (mNextExpectedSeqNoValid) {
- List<sp<ABuffer> >::iterator it = queue->begin();
- while (it != queue->end()) {
- if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
- break;
- }
-
- it = queue->erase(it);
- }
-
- if (queue->empty()) {
- return NOT_ENOUGH_DATA;
- }
- }
-
- sp<ABuffer> buffer = *queue->begin();
-
- if (!mNextExpectedSeqNoValid) {
- mNextExpectedSeqNoValid = true;
- mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
- } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
- LOGV("Not the sequence number I expected");
-
- return WRONG_SEQUENCE_NUMBER;
- }
-
- // hexdump(buffer->data(), buffer->size());
-
- if (buffer->size() < 1) {
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- LOGW("AMR packet too short.");
-
- return MALFORMED_PACKET;
- }
-
- unsigned payloadHeader = buffer->data()[0];
- if ((payloadHeader & 0x0f) != 0u) {
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- LOGW("Wrong payload header");
-
- return MALFORMED_PACKET;
- }
-
- Vector<uint8_t> tableOfContents;
-
- size_t offset = 1;
- size_t totalSize = 0;
- for (;;) {
- if (offset >= buffer->size()) {
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- LOGW("Unable to parse TOC.");
-
- return MALFORMED_PACKET;
- }
-
- uint8_t toc = buffer->data()[offset++];
-
- unsigned FT = (toc >> 3) & 0x0f;
- if ((toc & 3) != 0
- || (mIsWide && FT > 9 && FT != 15)
- || (!mIsWide && FT > 8 && FT != 15)) {
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- LOGW("Illegal TOC entry.");
-
- return MALFORMED_PACKET;
- }
-
- totalSize += getFrameSize(mIsWide, (toc >> 3) & 0x0f);
-
- tableOfContents.push(toc);
-
- if (0 == (toc & 0x80)) {
- break;
- }
- }
-
- sp<ABuffer> accessUnit = new ABuffer(totalSize);
- if (!CopyTimes(accessUnit, buffer)) {
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- return MALFORMED_PACKET;
- }
-
- size_t dstOffset = 0;
- for (size_t i = 0; i < tableOfContents.size(); ++i) {
- uint8_t toc = tableOfContents[i];
-
- size_t frameSize = getFrameSize(mIsWide, (toc >> 3) & 0x0f);
-
- if (offset + frameSize - 1 > buffer->size()) {
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- LOGW("AMR packet too short.");
-
- return MALFORMED_PACKET;
- }
-
- accessUnit->data()[dstOffset++] = toc;
- memcpy(accessUnit->data() + dstOffset,
- buffer->data() + offset, frameSize - 1);
-
- offset += frameSize - 1;
- dstOffset += frameSize - 1;
- }
-
- sp<AMessage> msg = mNotifyMsg->dup();
- msg->setObject("access-unit", accessUnit);
- msg->post();
-
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- return OK;
-}
-
-void AAMRAssembler::packetLost() {
- CHECK(mNextExpectedSeqNoValid);
- ++mNextExpectedSeqNo;
-}
-
-void AAMRAssembler::onByeReceived() {
- sp<AMessage> msg = mNotifyMsg->dup();
- msg->setInt32("eos", true);
- msg->post();
-}
-
-} // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AAMRAssembler.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_AMR_ASSEMBLER_H_
-
-#define A_AMR_ASSEMBLER_H_
-
-#include "mozilla/Types.h"
-#include "ARTPAssembler.h"
-
-#include <utils/List.h>
-
-#include <stdint.h>
-
-namespace android {
-
-struct MOZ_EXPORT AMessage;
-struct MOZ_EXPORT AString;
-
-struct AAMRAssembler : public ARTPAssembler {
- AAMRAssembler(
- const sp<AMessage> ¬ify, bool isWide,
- const AString ¶ms);
-
-protected:
- virtual ~AAMRAssembler();
-
- virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source);
- virtual void onByeReceived();
- virtual void packetLost();
-
-private:
- bool mIsWide;
-
- sp<AMessage> mNotifyMsg;
- bool mNextExpectedSeqNoValid;
- uint32_t mNextExpectedSeqNo;
-
- AssemblyStatus addPacket(const sp<ARTPSource> &source);
-
- DISALLOW_EVIL_CONSTRUCTORS(AAMRAssembler);
-};
-
-} // namespace android
-
-#endif // A_AMR_ASSEMBLER_H_
-
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AAVCAssembler.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AAVCAssembler"
-#include "RtspPrlog.h"
-
-#include "AAVCAssembler.h"
-
-#include "ARTPSource.h"
-
-#include "mozilla/Assertions.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/hexdump.h>
-
-#include <stdint.h>
-
-namespace android {
-
-// static
-AAVCAssembler::AAVCAssembler(const sp<AMessage> ¬ify)
- : mNotifyMsg(notify),
- mAccessUnitRTPTime(0),
- mNextExpectedSeqNoValid(false),
- mNextExpectedSeqNo(0),
- mAccessUnitDamaged(false) {
-}
-
-AAVCAssembler::~AAVCAssembler() {
-}
-
-ARTPAssembler::AssemblyStatus AAVCAssembler::addNALUnit(
- const sp<ARTPSource> &source) {
- List<sp<ABuffer> > *queue = source->queue();
-
- if (queue->empty()) {
- return NOT_ENOUGH_DATA;
- }
-
- if (mNextExpectedSeqNoValid) {
- List<sp<ABuffer> >::iterator it = queue->begin();
- while (it != queue->end()) {
- if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
- break;
- }
-
- it = queue->erase(it);
- }
-
- if (queue->empty()) {
- return NOT_ENOUGH_DATA;
- }
- }
-
- sp<ABuffer> buffer = *queue->begin();
-
- if (!mNextExpectedSeqNoValid) {
- mNextExpectedSeqNoValid = true;
- mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
- } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
- LOGV("Not the sequence number I expected");
-
- return WRONG_SEQUENCE_NUMBER;
- }
-
- const uint8_t *data = buffer->data();
- size_t size = buffer->size();
-
- if (size < 1 || (data[0] & 0x80)) {
- // Corrupt.
-
- LOGW("Ignoring corrupt buffer.");
- queue->erase(queue->begin());
-
- ++mNextExpectedSeqNo;
- return MALFORMED_PACKET;
- }
-
- unsigned nalType = data[0] & 0x1f;
- if (nalType >= 1 && nalType <= 23) {
- bool success = addSingleNALUnit(buffer);
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- return success ? OK : MALFORMED_PACKET;
- } else if (nalType == 28) {
- // FU-A
- return addFragmentedNALUnit(queue);
- } else if (nalType == 24) {
- // STAP-A
- bool success = addSingleTimeAggregationPacket(buffer);
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- return success ? OK : MALFORMED_PACKET;
- } else {
- LOGV("Ignoring unsupported buffer (nalType=%d)", nalType);
-
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- return MALFORMED_PACKET;
- }
-}
-
-bool AAVCAssembler::addSingleNALUnit(const sp<ABuffer> &buffer) {
- LOGV("addSingleNALUnit of size %d", buffer->size());
-#if !LOG_NDEBUG
- hexdump(buffer->data(), buffer->size());
-#endif
-
- uint32_t rtpTime;
- if (!buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)) {
- LOGW("Cannot find rtp-time");
- return false;
- }
-
- if (!mNALUnits.empty() && rtpTime != mAccessUnitRTPTime) {
- if (!submitAccessUnit()) {
- LOGW("Cannot find rtp-time. Malformed packet.");
-
- return false;
- }
- }
- mAccessUnitRTPTime = rtpTime;
-
- mNALUnits.push_back(buffer);
- return true;
-}
-
-bool AAVCAssembler::addSingleTimeAggregationPacket(const sp<ABuffer> &buffer) {
- const uint8_t *data = buffer->data();
- size_t size = buffer->size();
-
- if (size < 3) {
- LOGV("Discarding too small STAP-A packet.");
- return false;
- }
-
- ++data;
- --size;
- while (size >= 2) {
- size_t nalSize = (data[0] << 8) | data[1];
-
- if (size < nalSize + 2) {
- LOGV("Discarding malformed STAP-A packet.");
- return false;
- }
-
- sp<ABuffer> unit = new ABuffer(nalSize);
- memcpy(unit->data(), &data[2], nalSize);
-
- if (!CopyTimes(unit, buffer)) {
- return false;
- }
-
- if (!addSingleNALUnit(unit)) {
- LOGW("addSingleNALUnit() failed");
- return false;
- }
-
- data += 2 + nalSize;
- size -= 2 + nalSize;
- }
-
- if (size != 0) {
- LOGV("Unexpected padding at end of STAP-A packet.");
- }
-
- return true;
-}
-
-ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit(
- List<sp<ABuffer> > *queue) {
- MOZ_ASSERT(!queue->empty());
-
- sp<ABuffer> buffer = *queue->begin();
- const uint8_t *data = buffer->data();
- size_t size = buffer->size();
-
- if (size <= 0) {
- LOGW("Buffer is empty");
-
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
- return MALFORMED_PACKET;
- }
- unsigned indicator = data[0];
-
- if ((indicator & 0x1f) != 28) {
- LOGW("Indicator is wrong");
-
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
- return MALFORMED_PACKET;
- }
-
- if (size < 2) {
- LOGW("Ignoring malformed FU buffer (size = %d)", size);
-
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
- return MALFORMED_PACKET;
- }
-
- if (!(data[1] & 0x80)) {
- // Start bit not set on the first buffer.
-
- LOGW("Start bit not set on first buffer");
-
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
- return MALFORMED_PACKET;
- }
-
- uint32_t nalType = data[1] & 0x1f;
- uint32_t nri = (data[0] >> 5) & 3;
-
- uint32_t expectedSeqNo = (uint32_t)buffer->int32Data() + 1;
- size_t totalSize = size - 2;
- size_t totalCount = 1;
- bool complete = false;
-
- if (data[1] & 0x40) {
- // Huh? End bit also set on the first buffer.
-
- LOGV("Grrr. This isn't fragmented at all.");
-
- complete = true;
- } else {
- List<sp<ABuffer> >::iterator it = ++queue->begin();
- while (it != queue->end()) {
- LOGV("sequence length %d", totalCount);
-
- const sp<ABuffer> &buffer = *it;
-
- const uint8_t *data = buffer->data();
- size_t size = buffer->size();
-
- if ((uint32_t)buffer->int32Data() != expectedSeqNo) {
- LOGV("sequence not complete, expected seqNo %d, got %d",
- expectedSeqNo, (uint32_t)buffer->int32Data());
-
- return WRONG_SEQUENCE_NUMBER;
- }
-
- if (size < 2
- || data[0] != indicator
- || (data[1] & 0x1f) != nalType
- || (data[1] & 0x80)) {
- LOGW("Ignoring malformed FU buffer.");
-
- // Delete the whole start of the FU.
-
- it = queue->begin();
- for (size_t i = 0; i <= totalCount; ++i) {
- it = queue->erase(it);
- }
-
- mNextExpectedSeqNo = expectedSeqNo + 1;
-
- return MALFORMED_PACKET;
- }
-
- totalSize += size - 2;
- ++totalCount;
-
- expectedSeqNo = expectedSeqNo + 1;
-
- if (data[1] & 0x40) {
- // This is the last fragment.
- complete = true;
- break;
- }
-
- ++it;
- }
- }
-
- if (!complete) {
- return NOT_ENOUGH_DATA;
- }
-
- mNextExpectedSeqNo = expectedSeqNo;
-
- // We found all the fragments that make up the complete NAL unit.
-
- // Leave room for the header. So far totalSize did not include the
- // header byte.
- ++totalSize;
-
- sp<ABuffer> unit = new ABuffer(totalSize);
- if (!CopyTimes(unit, *queue->begin())) {
- return MALFORMED_PACKET;
- }
-
- unit->data()[0] = (nri << 5) | nalType;
-
- size_t offset = 1;
- List<sp<ABuffer> >::iterator it = queue->begin();
- for (size_t i = 0; i < totalCount; ++i) {
- const sp<ABuffer> &buffer = *it;
-
- LOGV("piece #%d/%d", i + 1, totalCount);
-#if !LOG_NDEBUG
- hexdump(buffer->data(), buffer->size());
-#endif
-
- memcpy(unit->data() + offset, buffer->data() + 2, buffer->size() - 2);
- offset += buffer->size() - 2;
-
- it = queue->erase(it);
- }
-
- unit->setRange(0, totalSize);
-
- if (!addSingleNALUnit(unit)) {
- return MALFORMED_PACKET;
- }
-
- LOGV("successfully assembled a NAL unit from fragments.");
-
- return OK;
-}
-
-bool AAVCAssembler::submitAccessUnit() {
- MOZ_ASSERT(!mNALUnits.empty());
-
- LOGV("Access unit complete (%d nal units)", mNALUnits.size());
-
- size_t totalSize = 0;
- for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
- it != mNALUnits.end(); ++it) {
- totalSize += 4 + (*it)->size();
- }
-
- sp<ABuffer> accessUnit = new ABuffer(totalSize);
- size_t offset = 0;
- for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
- it != mNALUnits.end(); ++it) {
- memcpy(accessUnit->data() + offset, "\x00\x00\x00\x01", 4);
- offset += 4;
-
- sp<ABuffer> nal = *it;
- memcpy(accessUnit->data() + offset, nal->data(), nal->size());
- offset += nal->size();
- }
-
- if (!CopyTimes(accessUnit, *mNALUnits.begin())) {
- return false;
- }
-
-#if 0
- printf(mAccessUnitDamaged ? "X" : ".");
- fflush(stdout);
-#endif
-
- if (mAccessUnitDamaged) {
- accessUnit->meta()->setInt32("damaged", true);
- }
-
- mNALUnits.clear();
- mAccessUnitDamaged = false;
-
- sp<AMessage> msg = mNotifyMsg->dup();
- msg->setObject("access-unit", accessUnit);
- msg->post();
- return true;
-}
-
-ARTPAssembler::AssemblyStatus AAVCAssembler::assembleMore(
- const sp<ARTPSource> &source) {
- AssemblyStatus status = addNALUnit(source);
- if (status == MALFORMED_PACKET) {
- mAccessUnitDamaged = true;
- }
- return status;
-}
-
-void AAVCAssembler::packetLost() {
- CHECK(mNextExpectedSeqNoValid);
- LOGV("packetLost (expected %d)", mNextExpectedSeqNo);
-
- ++mNextExpectedSeqNo;
-
- mAccessUnitDamaged = true;
-}
-
-void AAVCAssembler::onByeReceived() {
- sp<AMessage> msg = mNotifyMsg->dup();
- msg->setInt32("eos", true);
- msg->post();
-}
-
-} // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AAVCAssembler.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_AVC_ASSEMBLER_H_
-
-#define A_AVC_ASSEMBLER_H_
-
-#include "mozilla/Types.h"
-#include "ARTPAssembler.h"
-
-#include <utils/List.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-struct MOZ_EXPORT ABuffer;
-struct MOZ_EXPORT AMessage;
-
-struct AAVCAssembler : public ARTPAssembler {
- AAVCAssembler(const sp<AMessage> ¬ify);
-
-protected:
- virtual ~AAVCAssembler();
-
- virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source);
- virtual void onByeReceived();
- virtual void packetLost();
-
-private:
- sp<AMessage> mNotifyMsg;
-
- uint32_t mAccessUnitRTPTime;
- bool mNextExpectedSeqNoValid;
- uint32_t mNextExpectedSeqNo;
- bool mAccessUnitDamaged;
- List<sp<ABuffer> > mNALUnits;
-
- AssemblyStatus addNALUnit(const sp<ARTPSource> &source);
- bool addSingleNALUnit(const sp<ABuffer> &buffer);
- AssemblyStatus addFragmentedNALUnit(List<sp<ABuffer> > *queue);
- bool addSingleTimeAggregationPacket(const sp<ABuffer> &buffer);
-
- bool submitAccessUnit();
-
- DISALLOW_EVIL_CONSTRUCTORS(AAVCAssembler);
-};
-
-} // namespace android
-
-#endif // A_AVC_ASSEMBLER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AH263Assembler.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "AH263Assembler.h"
-
-#include "ARTPSource.h"
-#include "RtspPrlog.h"
-
-#include "mozilla/Assertions.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/Utils.h>
-
-namespace android {
-
-AH263Assembler::AH263Assembler(const sp<AMessage> ¬ify)
- : mNotifyMsg(notify),
- mAccessUnitRTPTime(0),
- mNextExpectedSeqNoValid(false),
- mNextExpectedSeqNo(0),
- mAccessUnitDamaged(false) {
-}
-
-AH263Assembler::~AH263Assembler() {
-}
-
-ARTPAssembler::AssemblyStatus AH263Assembler::assembleMore(
- const sp<ARTPSource> &source) {
- AssemblyStatus status = addPacket(source);
- if (status == MALFORMED_PACKET) {
- mAccessUnitDamaged = true;
- }
- return status;
-}
-
-ARTPAssembler::AssemblyStatus AH263Assembler::addPacket(
- const sp<ARTPSource> &source) {
- List<sp<ABuffer> > *queue = source->queue();
-
- if (queue->empty()) {
- return NOT_ENOUGH_DATA;
- }
-
- if (mNextExpectedSeqNoValid) {
- List<sp<ABuffer> >::iterator it = queue->begin();
- while (it != queue->end()) {
- if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
- break;
- }
-
- it = queue->erase(it);
- }
-
- if (queue->empty()) {
- return NOT_ENOUGH_DATA;
- }
- }
-
- sp<ABuffer> buffer = *queue->begin();
-
- if (!mNextExpectedSeqNoValid) {
- mNextExpectedSeqNoValid = true;
- mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
- } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
-#if VERBOSE
- LOG(VERBOSE) << "Not the sequence number I expected";
-#endif
-
- return WRONG_SEQUENCE_NUMBER;
- }
-
- uint32_t rtpTime;
- if (!buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)) {
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- LOGW("Cannot find rtp-time. Malformed packet.");
-
- return MALFORMED_PACKET;
- }
-
- if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
- if (!submitAccessUnit()) {
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- LOGW("Cannot find rtp-time. Malformed packet.");
-
- return MALFORMED_PACKET;
- }
- }
- mAccessUnitRTPTime = rtpTime;
-
- // hexdump(buffer->data(), buffer->size());
-
- if (buffer->size() < 2) {
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- return MALFORMED_PACKET;
- }
-
- // RFC 4629, Sec. 5.1 General H.263+ Payload Header.
- // The H.263+ payload header is structured as follows:
- // 0 1
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | RR |P|V| PLEN |PEBIT|
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- //
- // RR: 5 bits
- // Reserved bits. It SHALL be zero and MUST be ignored by receivers.
- // P: 1 bit
- // Indicates the picture start or a picture segment (GOB/Slice) start or
- // a video sequence end (EOS or EOSBS). Two bytes of zero bits then have
- // to be prefixed to the payload of such a packet to compose a complete
- // picture/GOB/slice/EOS/EOSBS start code. This bit allows the omission
- // of the two first bytes of the start code, thus improving the
- // compression ratio.
- // V: 1 bit
- // Indicates the presence of an 8-bit field containing information for
- // Video Redundancy Coding (VRC), which follows immediately after the
- // initial 16 bits of the payload header.
- // PLEN: 6 bits
- // Length, in bytes, of the extra picture header. If no extra picture
- // header is attached, PLEN is 0. If PLEN>0, the extra picture header is
- // attached immediately following the rest of the payload header. Note
- // that the length reflects the omission of the first two bytes of the
- // picture start code (PSC).
- // PEBIT: 3 bits
- // Indicates the number of bits that shall be ignored in the last byte
- // of the picture header. If PLEN is not zero, the ignored bits shall be
- // the least significant bits of the byte. If PLEN is zero, then PEBIT
- // shall also be zero.
-
- unsigned payloadHeader = U16_AT(buffer->data());
- unsigned P = (payloadHeader >> 10) & 1;
- unsigned V = (payloadHeader >> 9) & 1;
- unsigned PLEN = (payloadHeader >> 3) & 0x3f;
- unsigned PEBIT = payloadHeader & 7;
-
- // V = 0
- // We do not support VRC header extension for now, so just discard it if
- // present.
- if (V != 0u) {
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
- LOGW("Packet discarded due to VRC (V != 0)");
- return MALFORMED_PACKET;
- }
-
- // If PLEN is zero, then PEBIT shall also be zero.
- if (PLEN == 0u && PEBIT != 0u) {
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
- LOGW("Packet discarded (PEBIT != 0)");
- return MALFORMED_PACKET;
- }
-
- size_t skip = PLEN + (P ? 0: 2);
-
- buffer->setRange(buffer->offset() + skip, buffer->size() - skip);
-
- if (P) {
- buffer->data()[0] = 0x00;
- buffer->data()[1] = 0x00;
- }
-
- mPackets.push_back(buffer);
-
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- return OK;
-}
-
-bool AH263Assembler::submitAccessUnit() {
- MOZ_ASSERT(!mPackets.empty());
-
-#if VERBOSE
- LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)";
-#endif
-
- size_t totalSize = 0;
- List<sp<ABuffer> >::iterator it = mPackets.begin();
- while (it != mPackets.end()) {
- const sp<ABuffer> &unit = *it;
-
- totalSize += unit->size();
- ++it;
- }
-
- sp<ABuffer> accessUnit = new ABuffer(totalSize);
- size_t offset = 0;
- it = mPackets.begin();
- while (it != mPackets.end()) {
- const sp<ABuffer> &unit = *it;
-
- memcpy((uint8_t *)accessUnit->data() + offset,
- unit->data(), unit->size());
-
- offset += unit->size();
-
- ++it;
- }
-
- if (!CopyTimes(accessUnit, *mPackets.begin())) {
- return false;
- }
-
-#if 0
- printf(mAccessUnitDamaged ? "X" : ".");
- fflush(stdout);
-#endif
-
- if (mAccessUnitDamaged) {
- accessUnit->meta()->setInt32("damaged", true);
- }
-
- mPackets.clear();
- mAccessUnitDamaged = false;
-
- sp<AMessage> msg = mNotifyMsg->dup();
- msg->setObject("access-unit", accessUnit);
- msg->post();
-
- return true;
-}
-
-void AH263Assembler::packetLost() {
- CHECK(mNextExpectedSeqNoValid);
- ++mNextExpectedSeqNo;
-
- mAccessUnitDamaged = true;
-}
-
-void AH263Assembler::onByeReceived() {
- sp<AMessage> msg = mNotifyMsg->dup();
- msg->setInt32("eos", true);
- msg->post();
-}
-
-} // namespace android
-
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AH263Assembler.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_H263_ASSEMBLER_H_
-
-#define A_H263_ASSEMBLER_H_
-
-#include "mozilla/Types.h"
-#include "ARTPAssembler.h"
-
-#include <utils/List.h>
-
-#include <stdint.h>
-
-namespace android {
-
-struct MOZ_EXPORT AMessage;
-
-struct AH263Assembler : public ARTPAssembler {
- AH263Assembler(const sp<AMessage> ¬ify);
-
-protected:
- virtual ~AH263Assembler();
-
- virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source);
- virtual void onByeReceived();
- virtual void packetLost();
-
-private:
- sp<AMessage> mNotifyMsg;
- uint32_t mAccessUnitRTPTime;
- bool mNextExpectedSeqNoValid;
- uint32_t mNextExpectedSeqNo;
- bool mAccessUnitDamaged;
- List<sp<ABuffer> > mPackets;
-
- AssemblyStatus addPacket(const sp<ARTPSource> &source);
- bool submitAccessUnit();
-
- DISALLOW_EVIL_CONSTRUCTORS(AH263Assembler);
-};
-
-} // namespace android
-
-#endif // A_H263_ASSEMBLER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AMPEG4AudioAssembler.cpp
+++ /dev/null
@@ -1,640 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AMPEG4AudioAssembler"
-#include "RtspPrlog.h"
-
-#include "AMPEG4AudioAssembler.h"
-
-#include "ARTPSource.h"
-
-#include "mozilla/Assertions.h"
-
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/foundation/ABitReader.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/MediaErrors.h>
-
-#include <ctype.h>
-
-namespace android {
-
-static bool GetAttribute(const char *s, const char *key, AString *value) {
- value->clear();
-
- size_t keyLen = strlen(key);
-
- for (;;) {
- while (isspace(*s)) {
- ++s;
- }
-
- const char *colonPos = strchr(s, ';');
-
- size_t len =
- (colonPos == NULL) ? strlen(s) : colonPos - s;
-
- if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
- value->setTo(&s[keyLen + 1], len - keyLen - 1);
- return true;
- }
-
- if (colonPos == NULL) {
- return false;
- }
-
- s = colonPos + 1;
- }
-}
-
-static sp<ABuffer> decodeHex(const AString &s) {
- if ((s.size() % 2) != 0) {
- return NULL;
- }
-
- size_t outLen = s.size() / 2;
- sp<ABuffer> buffer = new ABuffer(outLen);
- uint8_t *out = buffer->data();
-
- uint8_t accum = 0;
- for (size_t i = 0; i < s.size(); ++i) {
- char c = s.c_str()[i];
- unsigned value;
- if (c >= '0' && c <= '9') {
- value = c - '0';
- } else if (c >= 'a' && c <= 'f') {
- value = c - 'a' + 10;
- } else if (c >= 'A' && c <= 'F') {
- value = c - 'A' + 10;
- } else {
- return NULL;
- }
-
- accum = (accum << 4) | value;
-
- if (i & 1) {
- *out++ = accum;
-
- accum = 0;
- }
- }
-
- return buffer;
-}
-
-static status_t parseAudioObjectType(
- ABitReader *bits, unsigned *audioObjectType) {
- *audioObjectType = bits->getBits(5);
- if ((*audioObjectType) == 31) {
- *audioObjectType = 32 + bits->getBits(6);
- }
-
- return OK;
-}
-
-static status_t parseGASpecificConfig(
- ABitReader *bits,
- unsigned audioObjectType, unsigned channelConfiguration) {
- /*unsigned frameLengthFlag = */bits->getBits(1);
- unsigned dependsOnCoreCoder = bits->getBits(1);
- if (dependsOnCoreCoder) {
- /* unsigned coreCoderDelay = */bits->getBits(1);
- }
- unsigned extensionFlag = bits->getBits(1);
-
- if (!channelConfiguration) {
- // program_config_element
- return ERROR_UNSUPPORTED; // XXX to be implemented
- }
-
- if (audioObjectType == 6 || audioObjectType == 20) {
- /* unsigned layerNr = */bits->getBits(3);
- }
-
- if (extensionFlag) {
- if (audioObjectType == 22) {
- /* unsigned numOfSubFrame = */bits->getBits(5);
- /* unsigned layerLength = */bits->getBits(11);
- } else if (audioObjectType == 17 || audioObjectType == 19
- || audioObjectType == 20 || audioObjectType == 23) {
- /* unsigned aacSectionDataResilienceFlag = */bits->getBits(1);
- /* unsigned aacScalefactorDataResilienceFlag = */bits->getBits(1);
- /* unsigned aacSpectralDataResilienceFlag = */bits->getBits(1);
- }
-
- unsigned extensionFlag3 = bits->getBits(1);
- if (extensionFlag3 != 0u) {
- return ERROR_UNSUPPORTED; // TBD in version 3
- }
- }
-
- return OK;
-}
-
-static status_t parseAudioSpecificConfig(ABitReader *bits, sp<ABuffer> *asc) {
- const uint8_t *dataStart = bits->data();
- size_t totalNumBits = bits->numBitsLeft();
-
- unsigned audioObjectType;
- if (parseAudioObjectType(bits, &audioObjectType) != (status_t)OK) {
- return ERROR_UNSUPPORTED;
- }
-
- unsigned samplingFreqIndex = bits->getBits(4);
- if (samplingFreqIndex == 0x0f) {
- /* unsigned samplingFrequency = */bits->getBits(24);
- }
-
- unsigned channelConfiguration = bits->getBits(4);
-
- unsigned extensionAudioObjectType = 0;
- unsigned sbrPresent = 0;
-
- if (audioObjectType == 5) {
- extensionAudioObjectType = audioObjectType;
- sbrPresent = 1;
- unsigned extensionSamplingFreqIndex = bits->getBits(4);
- if (extensionSamplingFreqIndex == 0x0f) {
- /* unsigned extensionSamplingFrequency = */bits->getBits(24);
- }
- if (parseAudioObjectType(bits, &audioObjectType) != (status_t)OK) {
- return ERROR_UNSUPPORTED;
- }
- }
-
- if (!((audioObjectType >= 1 && audioObjectType <= 4) ||
- (audioObjectType >= 6 && audioObjectType <= 7) ||
- audioObjectType == 17 ||
- (audioObjectType >= 19 && audioObjectType <= 23))) {
- return ERROR_UNSUPPORTED;
- }
-
- if (parseGASpecificConfig(bits, audioObjectType, channelConfiguration)
- != (status_t)OK) {
- return ERROR_UNSUPPORTED;
- }
-
- if (audioObjectType == 17
- || (audioObjectType >= 19 && audioObjectType <= 27)) {
- unsigned epConfig = bits->getBits(2);
- if (epConfig == 2 || epConfig == 3) {
- // ErrorProtectionSpecificConfig
- return ERROR_UNSUPPORTED; // XXX to be implemented
-
- if (epConfig == 3) {
- unsigned directMapping = bits->getBits(1);
- if (directMapping != 1u) {
- return ERROR_UNSUPPORTED;
- }
- }
- }
- }
-
- if (extensionAudioObjectType != 5 && bits->numBitsLeft() >= 16) {
- size_t numBitsLeftAtStart = bits->numBitsLeft();
-
- unsigned syncExtensionType = bits->getBits(11);
- if (syncExtensionType == 0x2b7) {
- LOGI("found syncExtension");
-
- if (parseAudioObjectType(bits, &extensionAudioObjectType)
- != (status_t)OK) {
- return ERROR_UNSUPPORTED;
- }
-
- sbrPresent = bits->getBits(1);
-
- if (sbrPresent == 1) {
- unsigned extensionSamplingFreqIndex = bits->getBits(4);
- if (extensionSamplingFreqIndex == 0x0f) {
- /* unsigned extensionSamplingFrequency = */bits->getBits(24);
- }
- }
-
- size_t numBitsInExtension =
- numBitsLeftAtStart - bits->numBitsLeft();
-
- if (numBitsInExtension & 7) {
- // Apparently an extension is always considered an even
- // multiple of 8 bits long.
-
- LOGI("Skipping %d bits after sync extension",
- 8 - (numBitsInExtension & 7));
-
- bits->skipBits(8 - (numBitsInExtension & 7));
- }
- } else {
- bits->putBits(syncExtensionType, 11);
- }
- }
-
- if (asc != NULL) {
- size_t bitpos = totalNumBits & 7;
-
- ABitReader bs(dataStart, (totalNumBits + 7) / 8);
-
- totalNumBits -= bits->numBitsLeft();
-
- size_t numBytes = (totalNumBits + 7) / 8;
-
- *asc = new ABuffer(numBytes);
-
- if (bitpos & 7) {
- bs.skipBits(8 - (bitpos & 7));
- }
-
- uint8_t *dstPtr = (*asc)->data();
- while (numBytes > 0) {
- *dstPtr++ = bs.getBits(8);
- --numBytes;
- }
- }
-
- return OK;
-}
-
-static status_t parseStreamMuxConfig(
- ABitReader *bits,
- unsigned *numSubFrames,
- unsigned *frameLengthType,
- ssize_t *fixedFrameLength,
- bool *otherDataPresent,
- unsigned *otherDataLenBits) {
- unsigned audioMuxVersion = bits->getBits(1);
-
- unsigned audioMuxVersionA = 0;
- if (audioMuxVersion == 1) {
- audioMuxVersionA = bits->getBits(1);
- }
-
- if (audioMuxVersionA != 0u) {
- return ERROR_UNSUPPORTED; // future spec
- }
-
- if (audioMuxVersion != 0u) {
- return ERROR_UNSUPPORTED; // XXX to be implemented;
- }
-
- unsigned allStreamsSameTimeFraming = bits->getBits(1);
- if (allStreamsSameTimeFraming != 1u) {
- return ERROR_UNSUPPORTED; // There's only one stream.
- }
-
- *numSubFrames = bits->getBits(6);
- unsigned numProgram = bits->getBits(4);
- if (numProgram != 0u) {
- return ERROR_UNSUPPORTED; // disabled in RTP LATM
- }
-
- unsigned numLayer = bits->getBits(3);
- if (numLayer != 0u) {
- return ERROR_UNSUPPORTED; // disabled in RTP LATM
- }
-
- if (audioMuxVersion == 0) {
- // AudioSpecificConfig
- if (parseAudioSpecificConfig(bits, NULL /* asc */) != (status_t)OK) {
- return ERROR_UNSUPPORTED;
- }
- } else {
- return ERROR_UNSUPPORTED; // XXX to be implemented
- }
-
- *frameLengthType = bits->getBits(3);
- *fixedFrameLength = -1;
-
- switch (*frameLengthType) {
- case 0:
- {
- /* unsigned bufferFullness = */bits->getBits(8);
-
- // The "coreFrameOffset" does not apply since there's only
- // a single layer.
- break;
- }
-
- case 1:
- {
- *fixedFrameLength = bits->getBits(9);
- break;
- }
-
- case 2:
- {
- // reserved
- TRESPASS();
- break;
- }
-
- case 3:
- case 4:
- case 5:
- {
- /* unsigned CELPframeLengthTableIndex = */bits->getBits(6);
- break;
- }
-
- case 6:
- case 7:
- {
- /* unsigned HVXCframeLengthTableIndex = */bits->getBits(1);
- break;
- }
-
- default:
- break;
- }
-
- *otherDataPresent = bits->getBits(1);
- *otherDataLenBits = 0;
- if (*otherDataPresent) {
- if (audioMuxVersion == 1) {
- return ERROR_UNSUPPORTED; // XXX to be implemented
- } else {
- *otherDataLenBits = 0;
-
- unsigned otherDataLenEsc;
- do {
- (*otherDataLenBits) <<= 8;
- otherDataLenEsc = bits->getBits(1);
- unsigned otherDataLenTmp = bits->getBits(8);
- (*otherDataLenBits) += otherDataLenTmp;
- } while (otherDataLenEsc);
- }
- }
-
- unsigned crcCheckPresent = bits->getBits(1);
- if (crcCheckPresent) {
- /* unsigned crcCheckSum = */bits->getBits(8);
- }
-
- return OK;
-}
-
-sp<ABuffer> AMPEG4AudioAssembler::removeLATMFraming(const sp<ABuffer> &buffer) {
- if (mMuxConfigPresent) {
- return NULL; // XXX to be implemented
- }
-
- sp<ABuffer> out = new ABuffer(buffer->size());
- out->setRange(0, 0);
-
- size_t offset = 0;
- uint8_t *ptr = buffer->data();
-
- for (size_t i = 0; i <= mNumSubFrames; ++i) {
- // parse PayloadLengthInfo
-
- unsigned payloadLength = 0;
-
- switch (mFrameLengthType) {
- case 0:
- {
- unsigned muxSlotLengthBytes = 0;
- unsigned tmp;
- do {
- if (offset >= buffer->size()) {
- LOGI("Malformed packet found in removeLATMFraming");
- mAccessUnitDamaged = true;
- return out;
- }
- tmp = ptr[offset++];
- muxSlotLengthBytes += tmp;
- } while (tmp == 0xff);
-
- payloadLength = muxSlotLengthBytes;
- break;
- }
-
- case 2:
- {
- // reserved
-
- TRESPASS();
- break;
- }
-
- default:
- {
- if (mFixedFrameLength < 0) {
- return NULL;
- }
-
- payloadLength = mFixedFrameLength;
- break;
- }
- }
-
- if ((offset + payloadLength) > buffer->size()) {
- LOGI("Malformed packet found in removeLATMFraming");
- mAccessUnitDamaged = true;
- return out;
- }
-
- memcpy(out->data() + out->size(), &ptr[offset], payloadLength);
- out->setRange(0, out->size() + payloadLength);
-
- offset += payloadLength;
-
- if (mOtherDataPresent) {
- // We want to stay byte-aligned.
-
- if (mOtherDataLenBits % 8 != 0) {
- mAccessUnitDamaged = true;
- return out;
- }
- if (offset + (mOtherDataLenBits / 8) > buffer->size()) {
- mAccessUnitDamaged = true;
- return out;
- }
- offset += mOtherDataLenBits / 8;
- }
- }
-
- if (offset < buffer->size()) {
- LOGI("ignoring %d bytes of trailing data", buffer->size() - offset);
- }
- CHECK_LE(offset, buffer->size());
-
- return out;
-}
-
-AMPEG4AudioAssembler::AMPEG4AudioAssembler(
- const sp<AMessage> ¬ify, const AString ¶ms)
- : mNotifyMsg(notify),
- mMuxConfigPresent(false),
- mAccessUnitRTPTime(0),
- mNextExpectedSeqNoValid(false),
- mNextExpectedSeqNo(0),
- mAccessUnitDamaged(false) {
- AString val;
- if (!GetAttribute(params.c_str(), "cpresent", &val)) {
- mMuxConfigPresent = true;
- } else if (val == "0") {
- mMuxConfigPresent = false;
- } else {
- CHECK(val == "1");
- mMuxConfigPresent = true;
- }
-
- CHECK(GetAttribute(params.c_str(), "config", &val));
-
- sp<ABuffer> config = decodeHex(val);
- CHECK(config != NULL);
-
- ABitReader bits(config->data(), config->size());
- status_t err = parseStreamMuxConfig(
- &bits, &mNumSubFrames, &mFrameLengthType,
- &mFixedFrameLength,
- &mOtherDataPresent, &mOtherDataLenBits);
-
- CHECK_EQ(err, (status_t)NO_ERROR);
-}
-
-AMPEG4AudioAssembler::~AMPEG4AudioAssembler() {
-}
-
-ARTPAssembler::AssemblyStatus AMPEG4AudioAssembler::assembleMore(
- const sp<ARTPSource> &source) {
- AssemblyStatus status = addPacket(source);
- if (status == MALFORMED_PACKET) {
- mAccessUnitDamaged = true;
- }
- return status;
-}
-
-ARTPAssembler::AssemblyStatus AMPEG4AudioAssembler::addPacket(
- const sp<ARTPSource> &source) {
- List<sp<ABuffer> > *queue = source->queue();
-
- if (queue->empty()) {
- return NOT_ENOUGH_DATA;
- }
-
- if (mNextExpectedSeqNoValid) {
- List<sp<ABuffer> >::iterator it = queue->begin();
- while (it != queue->end()) {
- if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
- break;
- }
-
- it = queue->erase(it);
- }
-
- if (queue->empty()) {
- return NOT_ENOUGH_DATA;
- }
- }
-
- sp<ABuffer> buffer = *queue->begin();
-
- if (!mNextExpectedSeqNoValid) {
- mNextExpectedSeqNoValid = true;
- mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
- } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
-#if VERBOSE
- LOG(VERBOSE) << "Not the sequence number I expected";
-#endif
-
- return WRONG_SEQUENCE_NUMBER;
- }
-
- uint32_t rtpTime;
- if (!buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)) {
- LOGW("Cannot find rtp-time. Malformed packet.");
-
- return MALFORMED_PACKET;
- }
-
- if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
- if (!submitAccessUnit()) {
- LOGW("Cannot find rtp-time. Malformed packet.");
- return MALFORMED_PACKET;
- }
- }
- mAccessUnitRTPTime = rtpTime;
-
- mPackets.push_back(buffer);
-
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- return OK;
-}
-
-bool AMPEG4AudioAssembler::submitAccessUnit() {
- MOZ_ASSERT(!mPackets.empty());
-
-#if VERBOSE
- LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)";
-#endif
-
- size_t totalSize = 0;
- List<sp<ABuffer> >::iterator it = mPackets.begin();
- while (it != mPackets.end()) {
- const sp<ABuffer> &unit = *it;
-
- totalSize += unit->size();
- ++it;
- }
-
- sp<ABuffer> accessUnit = new ABuffer(totalSize);
- size_t offset = 0;
- it = mPackets.begin();
- while (it != mPackets.end()) {
- const sp<ABuffer> &unit = *it;
-
- memcpy((uint8_t *)accessUnit->data() + offset,
- unit->data(), unit->size());
-
- offset += unit->size();
- ++it;
- }
-
- accessUnit = removeLATMFraming(accessUnit);
- if (!accessUnit.get() || !CopyTimes(accessUnit, *mPackets.begin())) {
- return false;
- }
-
- if (mAccessUnitDamaged) {
- accessUnit->meta()->setInt32("damaged", true);
- }
-
- mPackets.clear();
- mAccessUnitDamaged = false;
-
- sp<AMessage> msg = mNotifyMsg->dup();
- msg->setObject("access-unit", accessUnit);
- msg->post();
- return true;
-}
-
-void AMPEG4AudioAssembler::packetLost() {
- CHECK(mNextExpectedSeqNoValid);
- ++mNextExpectedSeqNo;
-
- mAccessUnitDamaged = true;
-}
-
-void AMPEG4AudioAssembler::onByeReceived() {
- sp<AMessage> msg = mNotifyMsg->dup();
- msg->setInt32("eos", true);
- msg->post();
-}
-
-} // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AMPEG4AudioAssembler.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_MPEG4_AUDIO_ASSEMBLER_H_
-
-#define A_MPEG4_AUDIO_ASSEMBLER_H_
-
-#include "mozilla/Types.h"
-#include "ARTPAssembler.h"
-
-#include <utils/List.h>
-
-#include <stdint.h>
-
-namespace android {
-
-struct MOZ_EXPORT AMessage;
-struct MOZ_EXPORT AString;
-
-struct AMPEG4AudioAssembler : public ARTPAssembler {
- AMPEG4AudioAssembler(
- const sp<AMessage> ¬ify, const AString ¶ms);
-
-protected:
- virtual ~AMPEG4AudioAssembler();
-
- virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source);
- virtual void onByeReceived();
- virtual void packetLost();
-
-private:
- sp<AMessage> mNotifyMsg;
-
- bool mMuxConfigPresent;
- unsigned mNumSubFrames;
- unsigned mFrameLengthType;
- ssize_t mFixedFrameLength;
- bool mOtherDataPresent;
- unsigned mOtherDataLenBits;
-
- uint32_t mAccessUnitRTPTime;
- bool mNextExpectedSeqNoValid;
- uint32_t mNextExpectedSeqNo;
- bool mAccessUnitDamaged;
- List<sp<ABuffer> > mPackets;
-
- AssemblyStatus addPacket(const sp<ARTPSource> &source);
- bool submitAccessUnit();
-
- sp<ABuffer> removeLATMFraming(const sp<ABuffer> &buffer);
-
- DISALLOW_EVIL_CONSTRUCTORS(AMPEG4AudioAssembler);
-};
-
-} // namespace android
-
-#endif // A_MPEG4_AUDIO_ASSEMBLER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AMPEG4ElementaryAssembler.cpp
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AMPEG4ElementaryAssembler"
-#include "RtspPrlog.h"
-
-#include "AMPEG4ElementaryAssembler.h"
-
-#include "ARTPSource.h"
-
-#include "mozilla/Assertions.h"
-
-#include <media/stagefright/foundation/ABitReader.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/Utils.h>
-
-#include <ctype.h>
-#include <stdint.h>
-
-namespace android {
-
-static bool GetAttribute(const char *s, const char *key, AString *value) {
- value->clear();
-
- size_t keyLen = strlen(key);
-
- for (;;) {
- while (isspace(*s)) {
- ++s;
- }
-
- const char *colonPos = strchr(s, ';');
-
- size_t len =
- (colonPos == NULL) ? strlen(s) : colonPos - s;
-
- if (len >= keyLen + 1 && s[keyLen] == '='
- && !strncasecmp(s, key, keyLen)) {
- value->setTo(&s[keyLen + 1], len - keyLen - 1);
- return true;
- }
-
- if (colonPos == NULL) {
- return false;
- }
-
- s = colonPos + 1;
- }
-}
-
-static bool GetIntegerAttribute(
- const char *s, const char *key, unsigned *x) {
- *x = 0;
-
- AString val;
- if (!GetAttribute(s, key, &val)) {
- return false;
- }
-
- s = val.c_str();
- char *end;
- unsigned y = strtoul(s, &end, 10);
-
- if (end == s || *end != '\0') {
- return false;
- }
-
- *x = y;
-
- return true;
-}
-
-// static
-AMPEG4ElementaryAssembler::AMPEG4ElementaryAssembler(
- const sp<AMessage> ¬ify, const AString &desc, const AString ¶ms)
- : mNotifyMsg(notify),
- mIsGeneric(false),
- mParams(params),
- mSizeLength(0),
- mIndexLength(0),
- mIndexDeltaLength(0),
- mCTSDeltaLength(0),
- mDTSDeltaLength(0),
- mRandomAccessIndication(false),
- mStreamStateIndication(0),
- mAuxiliaryDataSizeLength(0),
- mConstantDuration(0),
- mPreviousAUCount(0),
- mHasAUHeader(false),
- mAccessUnitRTPTime(0),
- mNextExpectedSeqNoValid(false),
- mNextExpectedSeqNo(0),
- mAccessUnitDamaged(false) {
- mIsGeneric = !strncasecmp(desc.c_str(),"mpeg4-generic/", 14);
-
- if (mIsGeneric) {
- AString value;
- CHECK(GetAttribute(params.c_str(), "mode", &value));
-
- if (!GetIntegerAttribute(params.c_str(), "sizeLength", &mSizeLength)) {
- mSizeLength = 0;
- }
-
- if (!GetIntegerAttribute(
- params.c_str(), "indexLength", &mIndexLength)) {
- mIndexLength = 0;
- }
-
- if (!GetIntegerAttribute(
- params.c_str(), "indexDeltaLength", &mIndexDeltaLength)) {
- mIndexDeltaLength = 0;
- }
-
- if (!GetIntegerAttribute(
- params.c_str(), "CTSDeltaLength", &mCTSDeltaLength)) {
- mCTSDeltaLength = 0;
- }
-
- if (!GetIntegerAttribute(
- params.c_str(), "DTSDeltaLength", &mDTSDeltaLength)) {
- mDTSDeltaLength = 0;
- }
-
- unsigned x;
- if (!GetIntegerAttribute(
- params.c_str(), "randomAccessIndication", &x)) {
- mRandomAccessIndication = false;
- } else {
- CHECK(x == 0 || x == 1);
- mRandomAccessIndication = (x != 0);
- }
-
- if (!GetIntegerAttribute(
- params.c_str(), "streamStateIndication",
- &mStreamStateIndication)) {
- mStreamStateIndication = 0;
- }
-
- if (!GetIntegerAttribute(
- params.c_str(), "auxiliaryDataSizeLength",
- &mAuxiliaryDataSizeLength)) {
- mAuxiliaryDataSizeLength = 0;
- }
-
- if (!GetIntegerAttribute(
- params.c_str(), "constantDuration",
- &mConstantDuration)) {
- mConstantDuration = 0;
- }
-
- mHasAUHeader =
- mSizeLength > 0
- || mIndexLength > 0
- || mIndexDeltaLength > 0
- || mCTSDeltaLength > 0
- || mDTSDeltaLength > 0
- || mRandomAccessIndication
- || mStreamStateIndication > 0;
- }
-}
-
-AMPEG4ElementaryAssembler::~AMPEG4ElementaryAssembler() {
-}
-
-struct AUHeader {
- unsigned mSize;
- unsigned mSerial;
-};
-
-ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket(
- const sp<ARTPSource> &source) {
- List<sp<ABuffer> > *queue = source->queue();
-
- if (queue->empty()) {
- return NOT_ENOUGH_DATA;
- }
-
- if (mNextExpectedSeqNoValid) {
- List<sp<ABuffer> >::iterator it = queue->begin();
- while (it != queue->end()) {
- if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
- break;
- }
-
- it = queue->erase(it);
- }
-
- if (queue->empty()) {
- return NOT_ENOUGH_DATA;
- }
- }
-
- sp<ABuffer> buffer = *queue->begin();
-
- if (!mNextExpectedSeqNoValid) {
- mNextExpectedSeqNoValid = true;
- mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
- } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
- LOGV("Not the sequence number I expected");
-
- return WRONG_SEQUENCE_NUMBER;
- }
-
- uint32_t rtpTime;
- if (!buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)) {
- LOGW("Cannot find rtp-time. Malformed packet.");
-
- return MALFORMED_PACKET;
- }
-
- if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
- if (!submitAccessUnit()) {
- LOGW("Cannot find rtp-time. Malformed packet.");
-
- return MALFORMED_PACKET;
- }
- }
-
- // If constantDuration and CTSDelta are not present. We should assume the
- // stream has fixed duration and calculate the mConstantDuration.
- if (!mConstantDuration && !mCTSDeltaLength && mPreviousAUCount
- && rtpTime > mAccessUnitRTPTime) {
- mConstantDuration = (rtpTime - mAccessUnitRTPTime) / mPreviousAUCount;
- }
-
- mAccessUnitRTPTime = rtpTime;
-
- if (!mIsGeneric) {
- mPackets.push_back(buffer);
- } else {
- // hexdump(buffer->data(), buffer->size());
-
- if (buffer->size() < 2u) {
- LOGW("Payload format error. Malformed packet.");
-
- return MALFORMED_PACKET;
- }
- unsigned AU_headers_length = U16_AT(buffer->data()); // in bits
-
- if (buffer->size() < 2 + (AU_headers_length + 7) / 8) {
- LOGW("Payload format error. Malformed packet.");
-
- return MALFORMED_PACKET;
- }
-
- List<AUHeader> headers;
-
- ABitReader bits(buffer->data() + 2, buffer->size() - 2);
- unsigned numBitsLeft = AU_headers_length;
-
- unsigned AU_serial = 0;
- for (;;) {
- if (numBitsLeft < mSizeLength) { break; }
-
- unsigned AU_size = bits.getBits(mSizeLength);
- numBitsLeft -= mSizeLength;
-
- size_t n = headers.empty() ? mIndexLength : mIndexDeltaLength;
- if (numBitsLeft < n) { break; }
-
- unsigned AU_index = bits.getBits(n);
- numBitsLeft -= n;
-
- if (headers.empty()) {
- AU_serial = AU_index;
- } else {
- AU_serial += 1 + AU_index;
- }
-
- if (mCTSDeltaLength > 0) {
- if (numBitsLeft < 1) {
- break;
- }
- --numBitsLeft;
- if (bits.getBits(1)) {
- if (numBitsLeft < mCTSDeltaLength) {
- break;
- }
- bits.skipBits(mCTSDeltaLength);
- numBitsLeft -= mCTSDeltaLength;
- }
- }
-
- if (mDTSDeltaLength > 0) {
- if (numBitsLeft < 1) {
- break;
- }
- --numBitsLeft;
- if (bits.getBits(1)) {
- if (numBitsLeft < mDTSDeltaLength) {
- break;
- }
- bits.skipBits(mDTSDeltaLength);
- numBitsLeft -= mDTSDeltaLength;
- }
- }
-
- if (mRandomAccessIndication) {
- if (numBitsLeft < 1) {
- break;
- }
- bits.skipBits(1);
- --numBitsLeft;
- }
-
- if (mStreamStateIndication > 0) {
- if (numBitsLeft < mStreamStateIndication) {
- break;
- }
- bits.skipBits(mStreamStateIndication);
- }
-
- AUHeader header;
- header.mSize = AU_size;
- header.mSerial = AU_serial;
- headers.push_back(header);
- }
-
- size_t offset = 2 + (AU_headers_length + 7) / 8;
-
- if (mAuxiliaryDataSizeLength > 0) {
- ABitReader bits(buffer->data() + offset, buffer->size() - offset);
-
- unsigned auxSize = bits.getBits(mAuxiliaryDataSizeLength);
-
- offset += (mAuxiliaryDataSizeLength + auxSize + 7) / 8;
- }
-
- mPreviousAUCount = 0;
- for (List<AUHeader>::iterator it = headers.begin();
- it != headers.end(); ++it) {
- mPreviousAUCount++;
- const AUHeader &header = *it;
- const AUHeader &first = *headers.begin();
- if (offset + header.mSize > buffer->size()) {
- LOGW("Payload format error. Malformed packet.");
-
- return MALFORMED_PACKET;
- }
-
- sp<ABuffer> accessUnit = new ABuffer(header.mSize);
- memcpy(accessUnit->data(), buffer->data() + offset, header.mSize);
-
- offset += header.mSize;
-
- int rtpTime = mAccessUnitRTPTime +
- mConstantDuration * (header.mSerial - first.mSerial);
- accessUnit->meta()->setInt32("rtp-time", rtpTime);
- accessUnit->setInt32Data(buffer->int32Data());
-
- mPackets.push_back(accessUnit);
- }
-
- if (offset != buffer->size()) {
- LOGW("Payload format error. Malformed packet.");
-
- return MALFORMED_PACKET;
- }
- }
-
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- return OK;
-}
-
-bool AMPEG4ElementaryAssembler::submitAccessUnit() {
- MOZ_ASSERT(mPackets.empty());
-
- LOGV("Access unit complete (%d nal units)", mPackets.size());
-
- if (mIsGeneric) {
- /*
- * Bug 877116.
- * In order to remedy a latency problem caused by hardware decoder for
- * mpeg4-generic audios, we artificially divide AUs into more smaller
- * AUs before feeding them to decoder.
- *
- * TODO: However, we are not sure this solution is appropriate to video
- * or not. Need more investigation on this. Refer to RFC 3640.
- */
- for (List<sp<ABuffer> >::iterator it = mPackets.begin();
- it != mPackets.end(); ++it) {
- sp<ABuffer> accessUnit = new ABuffer((*it)->size());
- sp<ABuffer> nal = *it;
- memcpy(accessUnit->data(), nal->data(), nal->size());
- if (!CopyTimes(accessUnit, nal)) {
- return false;
- }
-
- if (mAccessUnitDamaged) {
- accessUnit->meta()->setInt32("damaged", true);
- }
-
- sp<AMessage> msg = mNotifyMsg->dup();
- msg->setObject("access-unit", accessUnit);
- msg->post();
- }
- } else {
- /*
- * For MP4V-ES (MPEG-4 Visual Elementary Streams), NAL units with the
- * same RTP timestamp are assembled into an AU, which results in one
- * decoded picture (RFC 6416).
- */
- size_t totalSize = 0;
-
- for (List<sp<ABuffer> >::iterator it = mPackets.begin();
- it != mPackets.end(); ++it) {
- totalSize += (*it)->size();
- }
- sp<ABuffer> accessUnit = new ABuffer(totalSize);
- size_t offset = 0;
- for (List<sp<ABuffer> >::iterator it = mPackets.begin();
- it != mPackets.end(); ++it) {
- sp<ABuffer> nal = *it;
- memcpy(accessUnit->data() + offset, nal->data(), nal->size());
- offset += nal->size();
- }
- if (!CopyTimes(accessUnit, *mPackets.begin())) {
- return false;
- }
-
- if (mAccessUnitDamaged) {
- accessUnit->meta()->setInt32("damaged", true);
- }
-
- sp<AMessage> msg = mNotifyMsg->dup();
- msg->setObject("access-unit", accessUnit);
- msg->post();
- }
-
- mPackets.clear();
- mAccessUnitDamaged = false;
- return true;
-}
-
-ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::assembleMore(
- const sp<ARTPSource> &source) {
- AssemblyStatus status = addPacket(source);
- if (status == MALFORMED_PACKET) {
- mAccessUnitDamaged = true;
- }
- return status;
-}
-
-void AMPEG4ElementaryAssembler::packetLost() {
- CHECK(mNextExpectedSeqNoValid);
- LOGV("packetLost (expected %d)", mNextExpectedSeqNo);
-
- ++mNextExpectedSeqNo;
-
- mAccessUnitDamaged = true;
-
- mPreviousAUCount = 0;
-}
-
-void AMPEG4ElementaryAssembler::onByeReceived() {
- sp<AMessage> msg = mNotifyMsg->dup();
- msg->setInt32("eos", true);
- msg->post();
-}
-
-} // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AMPEG4ElementaryAssembler.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_MPEG4_ELEM_ASSEMBLER_H_
-
-#define A_MPEG4_ELEM_ASSEMBLER_H_
-
-#include "mozilla/Types.h"
-#include "ARTPAssembler.h"
-
-#include <media/stagefright/foundation/AString.h>
-
-#include <utils/List.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-struct MOZ_EXPORT ABuffer;
-struct MOZ_EXPORT AMessage;
-
-struct AMPEG4ElementaryAssembler : public ARTPAssembler {
- AMPEG4ElementaryAssembler(
- const sp<AMessage> ¬ify, const AString &desc,
- const AString ¶ms);
-
-protected:
- virtual ~AMPEG4ElementaryAssembler();
-
- virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source);
- virtual void onByeReceived();
- virtual void packetLost();
-
-private:
- sp<AMessage> mNotifyMsg;
- bool mIsGeneric;
- AString mParams;
-
- unsigned mSizeLength;
- unsigned mIndexLength;
- unsigned mIndexDeltaLength;
- unsigned mCTSDeltaLength;
- unsigned mDTSDeltaLength;
- bool mRandomAccessIndication;
- unsigned mStreamStateIndication;
- unsigned mAuxiliaryDataSizeLength;
- unsigned mConstantDuration;
- unsigned mPreviousAUCount;
- bool mHasAUHeader;
-
- uint32_t mAccessUnitRTPTime;
- bool mNextExpectedSeqNoValid;
- uint32_t mNextExpectedSeqNo;
- bool mAccessUnitDamaged;
- List<sp<ABuffer> > mPackets;
-
- AssemblyStatus addPacket(const sp<ARTPSource> &source);
- bool submitAccessUnit();
-
- DISALLOW_EVIL_CONSTRUCTORS(AMPEG4ElementaryAssembler);
-};
-
-} // namespace android
-
-#endif // A_MPEG4_ELEM_ASSEMBLER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/APacketSource.cpp
+++ /dev/null
@@ -1,640 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "APacketSource"
-#include "RtspPrlog.h"
-
-#include "APacketSource.h"
-
-#include "ARawAudioAssembler.h"
-#include "ASessionDescription.h"
-
-#include "avc_utils.h"
-
-#include <ctype.h>
-
-#include <media/stagefright/foundation/ABitReader.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/foundation/base64.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-static bool GetAttribute(const char *s, const char *key, AString *value) {
- value->clear();
-
- size_t keyLen = strlen(key);
-
- for (;;) {
- while (isspace(*s)) {
- ++s;
- }
-
- const char *colonPos = strchr(s, ';');
-
- size_t len =
- (colonPos == NULL) ? strlen(s) : colonPos - s;
-
- if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
- value->setTo(&s[keyLen + 1], len - keyLen - 1);
- return true;
- }
-
- if (colonPos == NULL) {
- return false;
- }
-
- s = colonPos + 1;
- }
-}
-
-static sp<ABuffer> decodeHex(const AString &s) {
- if ((s.size() % 2) != 0) {
- return NULL;
- }
-
- size_t outLen = s.size() / 2;
- sp<ABuffer> buffer = new ABuffer(outLen);
- uint8_t *out = buffer->data();
-
- uint8_t accum = 0;
- for (size_t i = 0; i < s.size(); ++i) {
- char c = s.c_str()[i];
- unsigned value;
- if (c >= '0' && c <= '9') {
- value = c - '0';
- } else if (c >= 'a' && c <= 'f') {
- value = c - 'a' + 10;
- } else if (c >= 'A' && c <= 'F') {
- value = c - 'A' + 10;
- } else {
- return NULL;
- }
-
- accum = (accum << 4) | value;
-
- if (i & 1) {
- *out++ = accum;
-
- accum = 0;
- }
- }
-
- return buffer;
-}
-
-static sp<ABuffer> MakeAVCCodecSpecificData(
- const char *params, int32_t *width, int32_t *height) {
- *width = 0;
- *height = 0;
-
- AString val;
- if (!GetAttribute(params, "profile-level-id", &val)) {
- return NULL;
- }
-
- sp<ABuffer> profileLevelID = decodeHex(val);
- if (!profileLevelID.get() || profileLevelID->size() != 3u) {
- LOGW("Format error in profile-level-id");
-
- return NULL;
- }
-
- Vector<sp<ABuffer> > paramSets;
-
- size_t numSeqParameterSets = 0;
- size_t totalSeqParameterSetSize = 0;
- size_t numPicParameterSets = 0;
- size_t totalPicParameterSetSize = 0;
-
- if (!GetAttribute(params, "sprop-parameter-sets", &val)) {
- return NULL;
- }
-
- size_t start = 0;
- for (;;) {
- ssize_t commaPos = val.find(",", start);
- size_t end = (commaPos < 0) ? val.size() : commaPos;
-
- AString nalString(val, start, end - start);
- sp<ABuffer> nal = decodeBase64(nalString);
- if (!nal.get() || nal->size() <= 0u || nal->size() > 65535u) {
- return NULL;
- }
-
- uint8_t nalType = nal->data()[0] & 0x1f;
- if (numSeqParameterSets == 0) {
- if ((unsigned)nalType != 7u) {
- return NULL;
- }
- } else if (numPicParameterSets > 0) {
- if ((unsigned)nalType != 8u) {
- return NULL;
- }
- }
- if (nalType == 7) {
- ++numSeqParameterSets;
- totalSeqParameterSetSize += nal->size();
- } else {
- if ((unsigned)nalType != 8u) {
- return NULL;
- }
- ++numPicParameterSets;
- totalPicParameterSetSize += nal->size();
- }
-
- paramSets.push(nal);
-
- if (commaPos < 0) {
- break;
- }
-
- start = commaPos + 1;
- }
-
- if (numSeqParameterSets >= 32u) {
- return NULL;
- }
- if (numPicParameterSets > 255u) {
- return NULL;
- }
-
- size_t csdSize =
- 1 + 3 + 1 + 1
- + 2 * numSeqParameterSets + totalSeqParameterSetSize
- + 1 + 2 * numPicParameterSets + totalPicParameterSetSize;
-
- sp<ABuffer> csd = new ABuffer(csdSize);
- uint8_t *out = csd->data();
-
- *out++ = 0x01; // configurationVersion
- memcpy(out, profileLevelID->data(), 3);
- out += 3;
- *out++ = (0x3f << 2) | 1; // lengthSize == 2 bytes
- *out++ = 0xe0 | numSeqParameterSets;
-
- for (size_t i = 0; i < numSeqParameterSets; ++i) {
- sp<ABuffer> nal = paramSets.editItemAt(i);
-
- *out++ = nal->size() >> 8;
- *out++ = nal->size() & 0xff;
-
- memcpy(out, nal->data(), nal->size());
-
- out += nal->size();
-
- if (i == 0) {
- FindAVCDimensions(nal, width, height);
- LOGI("dimensions %dx%d", *width, *height);
- }
- }
-
- *out++ = numPicParameterSets;
-
- for (size_t i = 0; i < numPicParameterSets; ++i) {
- sp<ABuffer> nal = paramSets.editItemAt(i + numSeqParameterSets);
-
- *out++ = nal->size() >> 8;
- *out++ = nal->size() & 0xff;
-
- memcpy(out, nal->data(), nal->size());
-
- out += nal->size();
- }
-
- // hexdump(csd->data(), csd->size());
-
- return csd;
-}
-
-sp<ABuffer> MakeAACCodecSpecificData(const char *params) {
- if (!params || !strlen(params)) {
- return NULL;
- }
- AString val;
- if (!GetAttribute(params, "config", &val)) {
- return NULL;
- }
-
- sp<ABuffer> config = decodeHex(val);
- if (!config.get()) {
- return NULL;
- }
- if (config->size() < 4u) {
- return NULL;
- }
-
- const uint8_t *data = config->data();
- uint32_t x = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
- x = (x >> 1) & 0xffff;
-
- static const uint8_t kStaticESDS[] = {
- 0x03, 22,
- 0x00, 0x00, // ES_ID
- 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag
-
- 0x04, 17,
- 0x40, // Audio ISO/IEC 14496-3
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
-
- 0x05, 2,
- // AudioSpecificInfo follows
- };
-
- sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2);
- memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS));
- csd->data()[sizeof(kStaticESDS)] = (x >> 8) & 0xff;
- csd->data()[sizeof(kStaticESDS) + 1] = x & 0xff;
-
- // hexdump(csd->data(), csd->size());
-
- return csd;
-}
-
-// From mpeg4-generic configuration data.
-sp<ABuffer> MakeAACCodecSpecificData2(const char *params) {
- AString val;
- unsigned long objectType;
- if (GetAttribute(params, "objectType", &val)) {
- const char *s = val.c_str();
- char *end;
- objectType = strtoul(s, &end, 10);
- if (end <= s || *end != '\0') {
- return NULL;
- }
- } else {
- objectType = 0x40; // Audio ISO/IEC 14496-3
- }
-
- if (!GetAttribute(params, "config", &val)) {
- LOGW("Cannot find attribute config");
-
- return NULL;
- }
-
- sp<ABuffer> config = decodeHex(val);
- if (!config.get()) {
- return NULL;
- }
-
- // Make sure size fits into a single byte and doesn't have to
- // be encoded.
- if (20 + config->size() >= 128u) {
- return NULL;
- }
-
- static const uint8_t kStaticESDS[] = {
- 0x03, 22,
- 0x00, 0x00, // ES_ID
- 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag
-
- 0x04, 17,
- 0x40, // Audio ISO/IEC 14496-3
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
-
- 0x05, 2,
- // AudioSpecificInfo follows
- };
-
- sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + config->size());
- uint8_t *dst = csd->data();
- *dst++ = 0x03;
- *dst++ = 20 + config->size();
- *dst++ = 0x00; // ES_ID
- *dst++ = 0x00;
- *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag
- *dst++ = 0x04;
- *dst++ = 15 + config->size();
- *dst++ = objectType;
- for (int i = 0; i < 12; ++i) { *dst++ = 0x00; }
- *dst++ = 0x05;
- *dst++ = config->size();
- memcpy(dst, config->data(), config->size());
-
- // hexdump(csd->data(), csd->size());
-
- return csd;
-}
-
-static size_t GetSizeWidth(size_t x) {
- size_t n = 1;
- while (x > 127) {
- ++n;
- x >>= 7;
- }
- return n;
-}
-
-static uint8_t *EncodeSize(uint8_t *dst, size_t x) {
- while (x > 127) {
- *dst++ = (x & 0x7f) | 0x80;
- x >>= 7;
- }
- *dst++ = x;
- return dst;
-}
-
-static bool ExtractDimensionsMPEG4Config(
- const sp<ABuffer> &config, int32_t *width, int32_t *height) {
- *width = 0;
- *height = 0;
-
- const uint8_t *ptr = config->data();
- size_t offset = 0;
- bool foundVOL = false;
- while (offset + 3 < config->size()) {
- if (memcmp("\x00\x00\x01", &ptr[offset], 3)
- || (ptr[offset + 3] & 0xf0) != 0x20) {
- ++offset;
- continue;
- }
-
- foundVOL = true;
- break;
- }
-
- if (!foundVOL) {
- return false;
- }
-
- return ExtractDimensionsFromVOLHeader(
- &ptr[offset], config->size() - offset, width, height);
-}
-
-static sp<ABuffer> MakeMPEG4VideoCodecSpecificData(
- const char *params, int32_t *width, int32_t *height) {
- *width = 0;
- *height = 0;
-
- AString val;
- if (!GetAttribute(params, "config", &val)) {
- LOGW("Cannot find attribute config");
-
- return NULL;
- }
-
- sp<ABuffer> config = decodeHex(val);
- if (!config.get()) {
- return NULL;
- }
-
- if (!ExtractDimensionsMPEG4Config(config, width, height)) {
- return NULL;
- }
-
- LOGI("VOL dimensions = %dx%d", *width, *height);
-
- size_t len1 = config->size() + GetSizeWidth(config->size()) + 1;
- size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13;
- size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3;
-
- sp<ABuffer> csd = new ABuffer(len3);
- uint8_t *dst = csd->data();
- *dst++ = 0x03;
- dst = EncodeSize(dst, len2 + 3);
- *dst++ = 0x00; // ES_ID
- *dst++ = 0x00;
- *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag
-
- *dst++ = 0x04;
- dst = EncodeSize(dst, len1 + 13);
- *dst++ = 0x01; // Video ISO/IEC 14496-2 Simple Profile
- for (size_t i = 0; i < 12; ++i) {
- *dst++ = 0x00;
- }
-
- *dst++ = 0x05;
- dst = EncodeSize(dst, config->size());
- memcpy(dst, config->data(), config->size());
- dst += config->size();
-
- // hexdump(csd->data(), csd->size());
-
- return csd;
-}
-
-APacketSource::APacketSource(
- const sp<ASessionDescription> &sessionDesc, size_t index)
- : mInitCheck(NO_INIT),
- mFormat(new MetaData) {
- unsigned long PT;
- AString desc;
- AString params;
-
- if (!sessionDesc->getFormatType(index, &PT, &desc, ¶ms)) {
- mInitCheck = ERROR_UNSUPPORTED;
- return;
- }
-
- int64_t durationUs;
- if (sessionDesc->getDurationUs(&durationUs)) {
- mFormat->setInt64(kKeyDuration, durationUs);
- } else {
- // Set its value to zero(long long) to indicate that this is a live stream.
- mFormat->setInt64(kKeyDuration, 0ll);
- }
-
- mInitCheck = OK;
- if (!strncmp(desc.c_str(), "H264/", 5)) {
- mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
-
- int32_t width, height;
- if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
- width = -1;
- height = -1;
- }
-
- int32_t encWidth, encHeight;
- sp<ABuffer> codecSpecificData =
- MakeAVCCodecSpecificData(params.c_str(), &encWidth, &encHeight);
-
- if (codecSpecificData != NULL) {
- if (width < 0) {
- // If no explicit width/height given in the sdp, use the dimensions
- // extracted from the first sequence parameter set.
- width = encWidth;
- height = encHeight;
- }
-
- mFormat->setData(
- kKeyAVCC, 0,
- codecSpecificData->data(), codecSpecificData->size());
- } else if (width < 0) {
- mInitCheck = ERROR_UNSUPPORTED;
- return;
- }
-
- mFormat->setInt32(kKeyWidth, width);
- mFormat->setInt32(kKeyHeight, height);
- } else if (!strncmp(desc.c_str(), "H263-2000/", 10)
- || !strncmp(desc.c_str(), "H263-1998/", 10)) {
- mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
-
- int32_t width, height;
- if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
- mInitCheck = ERROR_UNSUPPORTED;
- return;
- }
-
- mFormat->setInt32(kKeyWidth, width);
- mFormat->setInt32(kKeyHeight, height);
- } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
- mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
-
- int32_t sampleRate, numChannels;
- if (!ASessionDescription::ParseFormatDesc(
- desc.c_str(), &sampleRate, &numChannels)) {
- mInitCheck = ERROR_UNSUPPORTED;
- return;
- }
-
- mFormat->setInt32(kKeySampleRate, sampleRate);
- mFormat->setInt32(kKeyChannelCount, numChannels);
-
- sp<ABuffer> codecSpecificData =
- MakeAACCodecSpecificData(params.c_str());
- if (!codecSpecificData.get()) {
- mInitCheck = ERROR_UNSUPPORTED;
- return;
- }
-
- mFormat->setData(
- kKeyESDS, 0,
- codecSpecificData->data(), codecSpecificData->size());
- } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
- mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
-
- int32_t sampleRate, numChannels;
- if (!ASessionDescription::ParseFormatDesc(
- desc.c_str(), &sampleRate, &numChannels)) {
- mInitCheck = ERROR_UNSUPPORTED;
- return;
- }
-
- mFormat->setInt32(kKeySampleRate, sampleRate);
- mFormat->setInt32(kKeyChannelCount, numChannels);
-
- if (sampleRate != 8000 || numChannels != 1) {
- mInitCheck = ERROR_UNSUPPORTED;
- }
- } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
- mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
-
- int32_t sampleRate, numChannels;
- if (!ASessionDescription::ParseFormatDesc(
- desc.c_str(), &sampleRate, &numChannels)) {
- mInitCheck = ERROR_UNSUPPORTED;
- return;
- }
-
- mFormat->setInt32(kKeySampleRate, sampleRate);
- mFormat->setInt32(kKeyChannelCount, numChannels);
-
- if (sampleRate != 16000 || numChannels != 1) {
- mInitCheck = ERROR_UNSUPPORTED;
- }
- } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)) {
- mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
-
- int32_t width, height;
- if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
- width = -1;
- height = -1;
- }
-
- int32_t encWidth, encHeight;
- sp<ABuffer> codecSpecificData =
- MakeMPEG4VideoCodecSpecificData(
- params.c_str(), &encWidth, &encHeight);
-
- if (codecSpecificData != NULL) {
- mFormat->setData(
- kKeyESDS, 0,
- codecSpecificData->data(), codecSpecificData->size());
-
- if (width < 0) {
- width = encWidth;
- height = encHeight;
- }
- } else if (width < 0) {
- mInitCheck = ERROR_UNSUPPORTED;
- return;
- }
-
- mFormat->setInt32(kKeyWidth, width);
- mFormat->setInt32(kKeyHeight, height);
- } else if (!strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
- AString val;
- if (!GetAttribute(params.c_str(), "mode", &val)
- || (strcasecmp(val.c_str(), "AAC-lbr")
- && strcasecmp(val.c_str(), "AAC-hbr"))) {
- mInitCheck = ERROR_UNSUPPORTED;
- return;
- }
-
- mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
-
- int32_t sampleRate, numChannels;
- if (!ASessionDescription::ParseFormatDesc(
- desc.c_str(), &sampleRate, &numChannels)) {
- mInitCheck = ERROR_UNSUPPORTED;
- return;
- }
-
- mFormat->setInt32(kKeySampleRate, sampleRate);
- mFormat->setInt32(kKeyChannelCount, numChannels);
-
- sp<ABuffer> codecSpecificData =
- MakeAACCodecSpecificData2(params.c_str());
- if (!codecSpecificData.get()) {
- mInitCheck = ERROR_UNSUPPORTED;
- return;
- }
- mFormat->setData(
- kKeyESDS, 0,
- codecSpecificData->data(), codecSpecificData->size());
- } else if (ARawAudioAssembler::Supports(desc.c_str())) {
- if (!ARawAudioAssembler::MakeFormat(desc.c_str(), mFormat)) {
- mInitCheck = ERROR_UNSUPPORTED;
- }
- } else {
- mInitCheck = ERROR_UNSUPPORTED;
- }
-}
-
-APacketSource::~APacketSource() {
-}
-
-status_t APacketSource::initCheck() const {
- return mInitCheck;
-}
-
-sp<MetaData> APacketSource::getFormat() {
- return mFormat;
-}
-
-} // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/APacketSource.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_PACKET_SOURCE_H_
-
-#define A_PACKET_SOURCE_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <media/stagefright/MetaData.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-struct ASessionDescription;
-
-struct APacketSource : public RefBase {
- APacketSource(const sp<ASessionDescription> &sessionDesc, size_t index);
-
- status_t initCheck() const;
-
- virtual sp<MetaData> getFormat();
-
-protected:
- virtual ~APacketSource();
-
-private:
- status_t mInitCheck;
-
- sp<MetaData> mFormat;
-
- DISALLOW_EVIL_CONSTRUCTORS(APacketSource);
-};
-
-
-} // namespace android
-
-#endif // A_PACKET_SOURCE_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTPAssembler.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "ARTPAssembler.h"
-
-#include "RtspPrlog.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-
-#include <stdint.h>
-
-namespace android {
-
-static int64_t getNowUs() {
- struct timeval tv;
- gettimeofday(&tv, NULL);
-
- return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll;
-}
-
-ARTPAssembler::ARTPAssembler()
- : mFirstFailureTimeUs(-1) {
-}
-
-void ARTPAssembler::onPacketReceived(const sp<ARTPSource> &source) {
- AssemblyStatus status;
- for (;;) {
- status = assembleMore(source);
-
- if (status == WRONG_SEQUENCE_NUMBER) {
- if (mFirstFailureTimeUs >= 0) {
- if (getNowUs() - mFirstFailureTimeUs > 10000ll) {
- mFirstFailureTimeUs = -1;
-
- // LOG(VERBOSE) << "waited too long for packet.";
- packetLost();
- continue;
- }
- } else {
- mFirstFailureTimeUs = getNowUs();
- }
- break;
- } else {
- mFirstFailureTimeUs = -1;
-
- if (status == NOT_ENOUGH_DATA) {
- break;
- }
- }
- }
-}
-
-// static
-bool ARTPAssembler::CopyTimes(const sp<ABuffer> &to, const sp<ABuffer> &from) {
- uint32_t rtpTime;
- if (!from->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)) {
- LOGW("CopyTimes: Cannot find rtp-time");
-
- return false;
- }
-
- to->meta()->setInt32("rtp-time", rtpTime);
-
- // Copy the seq number.
- to->setInt32Data(from->int32Data());
- return true;
-}
-
-} // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTPAssembler.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_RTP_ASSEMBLER_H_
-
-#define A_RTP_ASSEMBLER_H_
-
-#include "mozilla/Types.h"
-#include <media/stagefright/foundation/ABase.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-struct MOZ_EXPORT ABuffer;
-struct ARTPSource;
-
-struct ARTPAssembler : public RefBase {
- enum AssemblyStatus {
- MALFORMED_PACKET,
- WRONG_SEQUENCE_NUMBER,
- NOT_ENOUGH_DATA,
- OK
- };
-
- ARTPAssembler();
-
- void onPacketReceived(const sp<ARTPSource> &source);
- virtual void onByeReceived() = 0;
-
-protected:
- virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source) = 0;
- virtual void packetLost() = 0;
-
- static bool CopyTimes(const sp<ABuffer> &to, const sp<ABuffer> &from);
-
-private:
- int64_t mFirstFailureTimeUs;
-
- DISALLOW_EVIL_CONSTRUCTORS(ARTPAssembler);
-};
-
-} // namespace android
-
-#endif // A_RTP_ASSEMBLER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTPConnection.cpp
+++ /dev/null
@@ -1,727 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ARTPConnection"
-#include "RtspPrlog.h"
-
-#include "ARTPConnection.h"
-
-#include "ARTPSource.h"
-#include "ASessionDescription.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/foundation/hexdump.h>
-
-#include <arpa/inet.h>
-
-#include "mozilla/mozalloc.h"
-#include "nsTArray.h"
-#include "prnetdb.h"
-#include "prerr.h"
-#include "prerror.h"
-#include "NetworkActivityMonitor.h"
-
-using namespace mozilla::net;
-
-namespace android {
-
-static const size_t kMaxUDPSize = 1500;
-
-static uint16_t u16at(const uint8_t *data) {
- return data[0] << 8 | data[1];
-}
-
-static uint32_t u32at(const uint8_t *data) {
- return u16at(data) << 16 | u16at(&data[2]);
-}
-
-static uint64_t u64at(const uint8_t *data) {
- return (uint64_t)(u32at(data)) << 32 | u32at(&data[4]);
-}
-
-// static
-const uint32_t ARTPConnection::kSocketPollTimeoutUs = 1000ll;
-
-struct ARTPConnection::StreamInfo {
- PRFileDesc *mRTPSocket;
- PRFileDesc *mRTCPSocket;
- int mInterleavedRTPIdx;
- int mInterleavedRTCPIdx;
- sp<ASessionDescription> mSessionDesc;
- size_t mIndex;
- sp<AMessage> mNotifyMsg;
- KeyedVector<uint32_t, sp<ARTPSource> > mSources;
-
- int64_t mNumRTCPPacketsReceived;
- int64_t mNumRTPPacketsReceived;
- PRNetAddr mRemoteRTCPAddr;
-
- bool mIsInjected;
-};
-
-ARTPConnection::ARTPConnection(uint32_t flags)
- : mFlags(flags),
- mPollEventPending(false),
- mLastReceiverReportTimeUs(-1) {
-}
-
-ARTPConnection::~ARTPConnection() {
-}
-
-void ARTPConnection::addStream(
- PRFileDesc *rtpSocket, PRFileDesc *rtcpSocket,
- int interleavedRTPIdx, int interleavedRTCPIdx,
- const sp<ASessionDescription> &sessionDesc,
- size_t index,
- const sp<AMessage> ¬ify,
- bool injected) {
- sp<AMessage> msg = new AMessage(kWhatAddStream, id());
- msg->setPointer("rtp-socket", rtpSocket);
- msg->setPointer("rtcp-socket", rtcpSocket);
- msg->setInt32("interleaved-rtp", interleavedRTPIdx);
- msg->setInt32("interleaved-rtcp", interleavedRTCPIdx);
- msg->setObject("session-desc", sessionDesc);
- msg->setSize("index", index);
- msg->setMessage("notify", notify);
- msg->setInt32("injected", injected);
- msg->post();
-}
-
-void ARTPConnection::removeStream(PRFileDesc *rtpSocket, PRFileDesc *rtcpSocket) {
- sp<AMessage> msg = new AMessage(kWhatRemoveStream, id());
- msg->setPointer("rtp-socket", rtpSocket);
- msg->setPointer("rtcp-socket", rtcpSocket);
-
- // Since the caller will close the sockets after this function
- // returns, we need to use a blocking post to prevent from polling
- // closed sockets.
- sp<AMessage> response;
- msg->postAndAwaitResponse(&response);
-}
-
-static void bumpSocketBufferSize(PRFileDesc *s) {
- uint32_t size = 256 * 1024;
- PRSocketOptionData opt;
-
- opt.option = PR_SockOpt_RecvBufferSize;
- opt.value.recv_buffer_size = size;
- CHECK_EQ(PR_SetSocketOption(s, &opt), PR_SUCCESS);
-}
-
-// static
-void ARTPConnection::MakePortPair(
- PRFileDesc **rtpSocket, PRFileDesc **rtcpSocket, uint16_t *rtpPort) {
- *rtpSocket = PR_OpenUDPSocket(PR_AF_INET);
- if (!*rtpSocket) {
- TRESPASS();
- }
-
- bumpSocketBufferSize(*rtpSocket);
-
- *rtcpSocket = PR_OpenUDPSocket(PR_AF_INET);
- if (!*rtcpSocket) {
- TRESPASS();
- }
-
- bumpSocketBufferSize(*rtcpSocket);
-
- NetworkActivityMonitor::AttachIOLayer(*rtpSocket);
- NetworkActivityMonitor::AttachIOLayer(*rtcpSocket);
-
- // Reduce the chance of using duplicate port numbers.
- srand(time(NULL));
- // rand() * 1000 may overflow int type, use long long.
- unsigned start = (unsigned)((rand() * 1000ll) / RAND_MAX) + 15550;
- start &= ~1;
-
- for (uint32_t port = start; port < 65536; port += 2) {
- PRNetAddr addr;
- addr.inet.family = PR_AF_INET;
- addr.inet.ip = PR_htonl(PR_INADDR_ANY);
- addr.inet.port = PR_htons(port);
-
- if (PR_Bind(*rtpSocket, &addr) == PR_FAILURE) {
- continue;
- }
-
- addr.inet.port = PR_htons(port + 1);
-
- if (PR_Bind(*rtcpSocket, &addr) == PR_SUCCESS) {
- *rtpPort = port;
- return;
- }
- }
-
- TRESPASS();
-}
-
-void ARTPConnection::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatAddStream:
- {
- onAddStream(msg);
- break;
- }
-
- case kWhatRemoveStream:
- {
- onRemoveStream(msg);
- sp<AMessage> ack = new AMessage;
- uint32_t replyID;
- CHECK(msg->senderAwaitsResponse(&replyID));
- ack->postReply(replyID);
- break;
- }
-
- case kWhatPollStreams:
- {
- onPollStreams();
- break;
- }
-
- case kWhatInjectPacket:
- {
- onInjectPacket(msg);
- break;
- }
-
- default:
- {
- TRESPASS();
- break;
- }
- }
-}
-
-void ARTPConnection::onAddStream(const sp<AMessage> &msg) {
- mStreams.push_back(StreamInfo());
- StreamInfo *info = &*--mStreams.end();
-
- void *s;
- CHECK(msg->findPointer("rtp-socket", &s));
- info->mRTPSocket = (PRFileDesc*)s;
- CHECK(msg->findPointer("rtcp-socket", &s));
- info->mRTCPSocket = (PRFileDesc*)s;
-
- CHECK(msg->findInt32("interleaved-rtp", &info->mInterleavedRTPIdx));
- CHECK(msg->findInt32("interleaved-rtcp", &info->mInterleavedRTCPIdx));
-
- int32_t injected;
- CHECK(msg->findInt32("injected", &injected));
-
- info->mIsInjected = injected;
-
- sp<RefBase> obj;
- CHECK(msg->findObject("session-desc", &obj));
- info->mSessionDesc = static_cast<ASessionDescription *>(obj.get());
-
- CHECK(msg->findSize("index", &info->mIndex));
- CHECK(msg->findMessage("notify", &info->mNotifyMsg));
-
- info->mNumRTCPPacketsReceived = 0;
- info->mNumRTPPacketsReceived = 0;
- PR_InitializeNetAddr(PR_IpAddrNull, 0, &info->mRemoteRTCPAddr);
-
- if (!injected) {
- postPollEvent();
- }
-}
-
-void ARTPConnection::onRemoveStream(const sp<AMessage> &msg) {
- PRFileDesc *rtpSocket = nullptr, *rtcpSocket = nullptr;
- void *s;
- CHECK(msg->findPointer("rtp-socket", &s));
- rtpSocket = (PRFileDesc*)s;
- CHECK(msg->findPointer("rtcp-socket", &s));
- rtcpSocket = (PRFileDesc*)s;
-
- List<StreamInfo>::iterator it = mStreams.begin();
- while (it != mStreams.end()
- && (it->mRTPSocket != rtpSocket || it->mRTCPSocket != rtcpSocket)) {
- ++it;
- }
-
- if (it == mStreams.end()) {
- return;
- }
-
- mStreams.erase(it);
-}
-
-void ARTPConnection::postPollEvent() {
- if (mPollEventPending) {
- return;
- }
-
- sp<AMessage> msg = new AMessage(kWhatPollStreams, id());
- msg->post();
-
- mPollEventPending = true;
-}
-
-void ARTPConnection::onPollStreams() {
- mPollEventPending = false;
-
- if (mStreams.empty()) {
- return;
- }
-
- uint32_t pollCount = mStreams.size() * 2;
- nsTArray<PRPollDesc> pollList;
- pollList.AppendElements(pollCount);
- memset(pollList.Elements(), 0, sizeof(PRPollDesc) * pollCount);
-
- // |pollIndex| is used to map different RTP & RTCP socket pairs.
- uint32_t numSocketsToPoll = 0, pollIndex = 0;
- for (List<StreamInfo>::iterator it = mStreams.begin();
- it != mStreams.end(); ++it, pollIndex += 2) {
- if (pollIndex >= pollCount) {
- // |pollIndex| should never equal or exceed |pollCount|.
- TRESPASS();
- }
-
- if ((*it).mIsInjected) {
- continue;
- }
-
- if (it->mRTPSocket) {
- pollList[pollIndex].fd = it->mRTPSocket;
- pollList[pollIndex].in_flags = PR_POLL_READ;
- pollList[pollIndex].out_flags = 0;
- numSocketsToPoll++;
- }
- if (it->mRTCPSocket) {
- pollList[pollIndex + 1].fd = it->mRTCPSocket;
- pollList[pollIndex + 1].in_flags = PR_POLL_READ;
- pollList[pollIndex + 1].out_flags = 0;
- numSocketsToPoll++;
- }
- }
-
- if (numSocketsToPoll == 0) {
- // No sockets need to poll. return.
- return;
- }
-
- const int32_t numSocketsReadyToRead =
- PR_Poll(pollList.Elements(), pollList.Length(),
- PR_MicrosecondsToInterval(kSocketPollTimeoutUs));
-
- if (numSocketsReadyToRead > 0) {
- pollIndex = 0;
- List<StreamInfo>::iterator it = mStreams.begin();
- while (it != mStreams.end()) {
- if ((*it).mIsInjected) {
- ++it;
- pollIndex += 2;
- continue;
- }
-
- status_t err = OK;
- if (pollList[pollIndex].out_flags != 0) {
- err = receive(&*it, true);
- }
- if (err == OK && pollList[pollIndex + 1].out_flags != 0) {
- err = receive(&*it, false);
- }
-
- if (err == -ECONNRESET) {
- // socket failure, this stream is dead, Jim.
-
- LOGW("failed to receive RTP/RTCP datagram.");
- it = mStreams.erase(it);
- pollIndex += 2;
- continue;
- }
-
- ++it;
- pollIndex += 2;
- }
- }
-
- int64_t nowUs = ALooper::GetNowUs();
- if (mLastReceiverReportTimeUs <= 0
- || mLastReceiverReportTimeUs + 5000000ll <= nowUs) {
- sp<ABuffer> buffer = new ABuffer(kMaxUDPSize);
- List<StreamInfo>::iterator it = mStreams.begin();
- while (it != mStreams.end()) {
- StreamInfo *s = &*it;
-
- if (s->mIsInjected) {
- ++it;
- continue;
- }
-
- if (s->mNumRTCPPacketsReceived == 0) {
- // We have never received any RTCP packets on this stream,
- // we don't even know where to send a report.
- ++it;
- continue;
- }
-
- buffer->setRange(0, 0);
-
- for (size_t i = 0; i < s->mSources.size(); ++i) {
- sp<ARTPSource> source = s->mSources.valueAt(i);
-
- source->addReceiverReport(buffer);
-
- if (mFlags & kRegularlyRequestFIR) {
- source->addFIR(buffer);
- }
- }
-
- if (buffer->size() > 0) {
- LOGV("Sending RR...");
-
- ssize_t n;
- PRErrorCode errorCode;
- do {
- n = PR_SendTo(s->mRTCPSocket, buffer->data(), buffer->size(),
- 0, &s->mRemoteRTCPAddr, PR_INTERVAL_NO_WAIT);
- errorCode = PR_GetError();
- } while (n < 0 && errorCode == PR_PENDING_INTERRUPT_ERROR);
-
- if (n <= 0) {
- LOGW("failed to send RTCP receiver report (%s).",
- n == 0 ? "connection gone" : "interrupt error");
-
- it = mStreams.erase(it);
- continue;
- }
-
- CHECK_EQ(n, (ssize_t)buffer->size());
-
- mLastReceiverReportTimeUs = nowUs;
- }
-
- ++it;
- }
- }
-
- if (!mStreams.empty()) {
- postPollEvent();
- }
-}
-
-status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) {
- LOGV("receiving %s", receiveRTP ? "RTP" : "RTCP");
-
- CHECK(!s->mIsInjected);
-
- sp<ABuffer> buffer = new ABuffer(65536);
-
- int32_t remoteAddrLen =
- (!receiveRTP && s->mNumRTCPPacketsReceived == 0)
- ? sizeof(s->mRemoteRTCPAddr) : 0;
-
- ssize_t nbytes;
- PRErrorCode errorCode;
- do {
- nbytes = PR_RecvFrom(receiveRTP ? s->mRTPSocket : s->mRTCPSocket,
- buffer->data(),
- buffer->size(),
- 0,
- remoteAddrLen > 0 ? &s->mRemoteRTCPAddr : NULL,
- PR_INTERVAL_NO_WAIT);
- errorCode = PR_GetError();
- } while (nbytes < 0 && errorCode == PR_PENDING_INTERRUPT_ERROR);
-
- if (nbytes <= 0) {
- return -PR_CONNECT_RESET_ERROR;
- }
-
- buffer->setRange(0, nbytes);
-
- // LOGI("received %d bytes.", buffer->size());
-
- status_t err;
- if (receiveRTP) {
- err = parseRTP(s, buffer);
- } else {
- err = parseRTCP(s, buffer);
- }
-
- return err;
-}
-
-status_t ARTPConnection::parseRTP(StreamInfo *s, const sp<ABuffer> &buffer) {
- if (s->mNumRTPPacketsReceived++ == 0) {
- sp<AMessage> notify = s->mNotifyMsg->dup();
- notify->setInt32("first-rtp", true);
- notify->post();
- }
-
- size_t size = buffer->size();
-
- if (size < 12) {
- // Too short to be a valid RTP header.
- return -1;
- }
-
- const uint8_t *data = buffer->data();
-
- if ((data[0] >> 6) != 2) {
- // Unsupported version.
- return -1;
- }
-
- if (data[0] & 0x20) {
- // Padding present.
-
- size_t paddingLength = data[size - 1];
-
- if (paddingLength + 12 > size) {
- // If we removed this much padding we'd end up with something
- // that's too short to be a valid RTP header.
- return -1;
- }
-
- size -= paddingLength;
- }
-
- int numCSRCs = data[0] & 0x0f;
-
- size_t payloadOffset = 12 + 4 * numCSRCs;
-
- if (size < payloadOffset) {
- // Not enough data to fit the basic header and all the CSRC entries.
- return -1;
- }
-
- if (data[0] & 0x10) {
- // Header eXtension present.
-
- if (size < payloadOffset + 4) {
- // Not enough data to fit the basic header, all CSRC entries
- // and the first 4 bytes of the extension header.
-
- return -1;
- }
-
- const uint8_t *extensionData = &data[payloadOffset];
-
- size_t extensionLength =
- 4 * (extensionData[2] << 8 | extensionData[3]);
-
- if (size < payloadOffset + 4 + extensionLength) {
- return -1;
- }
-
- payloadOffset += 4 + extensionLength;
- }
-
- uint32_t srcId = u32at(&data[8]);
-
- sp<ARTPSource> source = findSource(s, srcId);
-
- uint32_t rtpTime = u32at(&data[4]);
-
- sp<AMessage> meta = buffer->meta();
- meta->setInt32("ssrc", srcId);
- meta->setInt32("rtp-time", rtpTime);
- meta->setInt32("PT", data[1] & 0x7f);
- meta->setInt32("M", data[1] >> 7);
-
- buffer->setInt32Data(u16at(&data[2]));
- buffer->setRange(payloadOffset, size - payloadOffset);
-
- source->processRTPPacket(buffer);
-
- return OK;
-}
-
-status_t ARTPConnection::parseRTCP(StreamInfo *s, const sp<ABuffer> &buffer) {
- if (s->mNumRTCPPacketsReceived++ == 0) {
- sp<AMessage> notify = s->mNotifyMsg->dup();
- notify->setInt32("first-rtcp", true);
- notify->post();
- }
-
- const uint8_t *data = buffer->data();
- size_t size = buffer->size();
-
- while (size > 0) {
- if (size < 8) {
- // Too short to be a valid RTCP header
- return -1;
- }
-
- if ((data[0] >> 6) != 2) {
- // Unsupported version.
- return -1;
- }
-
- if (data[0] & 0x20) {
- // Padding present.
-
- size_t paddingLength = data[size - 1];
-
- if (paddingLength + 12 > size) {
- // If we removed this much padding we'd end up with something
- // that's too short to be a valid RTP header.
- return -1;
- }
-
- size -= paddingLength;
- }
-
- size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
-
- if (size < headerLength) {
- // Only received a partial packet?
- return -1;
- }
-
- switch (data[1]) {
- case 200:
- {
- parseSR(s, data, headerLength);
- break;
- }
-
- case 201: // RR
- case 202: // SDES
- case 204: // APP
- break;
-
- case 205: // TSFB (transport layer specific feedback)
- case 206: // PSFB (payload specific feedback)
- // hexdump(data, headerLength);
- break;
-
- case 203:
- {
- parseBYE(s, data, headerLength);
- break;
- }
-
- default:
- {
- LOGW("Unknown RTCP packet type %u of size %d",
- (unsigned)data[1], headerLength);
- break;
- }
- }
-
- data += headerLength;
- size -= headerLength;
- }
-
- return OK;
-}
-
-status_t ARTPConnection::parseBYE(
- StreamInfo *s, const uint8_t *data, size_t size) {
- size_t SC = data[0] & 0x3f;
-
- if (SC == 0 || size < (4 + SC * 4)) {
- // Packet too short for the minimal BYE header.
- return -1;
- }
-
- uint32_t id = u32at(&data[4]);
-
- sp<ARTPSource> source = findSource(s, id);
-
- source->byeReceived();
-
- return OK;
-}
-
-status_t ARTPConnection::parseSR(
- StreamInfo *s, const uint8_t *data, size_t size) {
- size_t RC = data[0] & 0x1f;
-
- if (size < (7 + RC * 6) * 4) {
- // Packet too short for the minimal SR header.
- return -1;
- }
-
- uint32_t id = u32at(&data[4]);
- uint64_t ntpTime = u64at(&data[8]);
- uint32_t rtpTime = u32at(&data[16]);
-
-#if 0
- LOGI("XXX timeUpdate: ssrc=0x%08x, rtpTime %u == ntpTime %.3f",
- id,
- rtpTime,
- (ntpTime >> 32) + (double)(ntpTime & 0xffffffff) / (1ll << 32));
-#endif
-
- sp<ARTPSource> source = findSource(s, id);
-
- source->timeUpdate(rtpTime, ntpTime);
-
- return 0;
-}
-
-sp<ARTPSource> ARTPConnection::findSource(StreamInfo *info, uint32_t srcId) {
- sp<ARTPSource> source;
- ssize_t index = info->mSources.indexOfKey(srcId);
- if (index < 0) {
- index = info->mSources.size();
-
- source = new ARTPSource(
- srcId, info->mSessionDesc, info->mIndex, info->mNotifyMsg);
-
- info->mSources.add(srcId, source);
- } else {
- source = info->mSources.valueAt(index);
- }
-
- return source;
-}
-
-void ARTPConnection::injectPacket(int index, const sp<ABuffer> &buffer) {
- sp<AMessage> msg = new AMessage(kWhatInjectPacket, id());
- msg->setInt32("index", index);
- msg->setObject("buffer", buffer);
- msg->post();
-}
-
-void ARTPConnection::onInjectPacket(const sp<AMessage> &msg) {
- int32_t index;
- CHECK(msg->findInt32("index", &index));
-
- sp<RefBase> obj;
- CHECK(msg->findObject("buffer", &obj));
-
- sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
-
- List<StreamInfo>::iterator it = mStreams.begin();
- while (it != mStreams.end()
- && it->mInterleavedRTPIdx != index && it->mInterleavedRTCPIdx != index) {
- ++it;
- }
-
- if (it == mStreams.end()) {
- TRESPASS();
- }
-
- StreamInfo *s = &*it;
-
- if (it->mInterleavedRTPIdx == index) {
- parseRTP(s, buffer);
- } else {
- parseRTCP(s, buffer);
- }
-}
-
-} // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTPConnection.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_RTP_CONNECTION_H_
-
-#define A_RTP_CONNECTION_H_
-
-#include "mozilla/Types.h"
-#include <media/stagefright/foundation/AHandler.h>
-#include <utils/List.h>
-
-#include "prio.h"
-
-namespace android {
-
-struct MOZ_EXPORT ABuffer;
-struct ARTPSource;
-struct ASessionDescription;
-
-struct ARTPConnection : public AHandler {
- enum Flags {
- kRegularlyRequestFIR = 2,
- };
-
- ARTPConnection(uint32_t flags = 0);
-
- void addStream(
- PRFileDesc *rtpSocket, PRFileDesc *rtcpSocket,
- int interleavedRTPIdx, int interleavedRTCPIdx,
- const sp<ASessionDescription> &sessionDesc, size_t index,
- const sp<AMessage> ¬ify,
- bool injected);
-
- void removeStream(PRFileDesc *rtpSocket, PRFileDesc *rtcpSocket);
-
- void injectPacket(int index, const sp<ABuffer> &buffer);
-
- // Creates a pair of UDP datagram sockets bound to adjacent ports
- // (the rtpSocket is bound to an even port, the rtcpSocket to the
- // next higher port).
- static void MakePortPair(
- PRFileDesc **rtpSocket, PRFileDesc **rtcpSocket, uint16_t *rtpPort);
-
-protected:
- virtual ~ARTPConnection();
- virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
- enum {
- kWhatAddStream,
- kWhatRemoveStream,
- kWhatPollStreams,
- kWhatInjectPacket,
- };
-
- static const uint32_t kSocketPollTimeoutUs;
-
- uint32_t mFlags;
-
- struct StreamInfo;
- List<StreamInfo> mStreams;
-
- bool mPollEventPending;
- int64_t mLastReceiverReportTimeUs;
-
- void onAddStream(const sp<AMessage> &msg);
- void onRemoveStream(const sp<AMessage> &msg);
- void onPollStreams();
- void onInjectPacket(const sp<AMessage> &msg);
- void onSendReceiverReports();
-
- status_t receive(StreamInfo *info, bool receiveRTP);
-
- status_t parseRTP(StreamInfo *info, const sp<ABuffer> &buffer);
- status_t parseRTCP(StreamInfo *info, const sp<ABuffer> &buffer);
- status_t parseSR(StreamInfo *info, const uint8_t *data, size_t size);
- status_t parseBYE(StreamInfo *info, const uint8_t *data, size_t size);
-
- sp<ARTPSource> findSource(StreamInfo *info, uint32_t id);
-
- void postPollEvent();
-
- DISALLOW_EVIL_CONSTRUCTORS(ARTPConnection);
-};
-
-} // namespace android
-
-#endif // A_RTP_CONNECTION_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTPSession.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ARTPSession"
-#include <utils/Log.h>
-
-#include "ARTPSession.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/hexdump.h>
-
-#include <ctype.h>
-#include <arpa/inet.h>
-
-#include "APacketSource.h"
-#include "ARTPConnection.h"
-#include "ASessionDescription.h"
-
-#include "prnetdb.h"
-#include "prerr.h"
-#include "NetworkActivityMonitor.h"
-
-using namespace mozilla::net;
-
-namespace android {
-
-ARTPSession::ARTPSession()
- : mInitCheck(NO_INIT) {
-}
-
-status_t ARTPSession::setup(const sp<ASessionDescription> &desc) {
- if (mInitCheck != (status_t)NO_INIT) {
- LOGE("Unexpected mInitCheck");
- return NO_INIT;
- }
-
- mDesc = desc;
-
- mRTPConn = new ARTPConnection(ARTPConnection::kRegularlyRequestFIR);
-
- looper()->registerHandler(mRTPConn);
-
- for (size_t i = 1; i < mDesc->countTracks(); ++i) {
- AString connection;
- if (!mDesc->findAttribute(i, "c=", &connection)) {
- // No per-stream connection information, try global fallback.
- if (!mDesc->findAttribute(0, "c=", &connection)) {
- LOGE("Unable to find connection attribute.");
- return mInitCheck;
- }
- }
- if (!(connection == "IN IP4 127.0.0.1")) {
- LOGE("We only support localhost connections for now.");
- return mInitCheck;
- }
-
- unsigned port;
- if (!validateMediaFormat(i, &port) || (port & 1) != 0) {
- LOGE("Invalid media format.");
- return mInitCheck;
- }
-
- sp<APacketSource> source = new APacketSource(mDesc, i);
- if (source->initCheck() != OK) {
- LOGE("Unsupported format.");
- return mInitCheck;
- }
-
- mTracks.push(TrackInfo());
- TrackInfo *info = &mTracks.editItemAt(mTracks.size() - 1);
- MakeUDPSocket(&info->mRTPSocket, port);
- MakeUDPSocket(&info->mRTCPSocket, port + 1);
-
- sp<AMessage> notify = new AMessage(kWhatAccessUnitComplete, id());
- notify->setSize("track-index", mTracks.size() - 1);
-
- mRTPConn->addStream(
- info->mRTPSocket, info->mRTCPSocket,
- 0, 0, mDesc, i, notify, false /* injected */);
-
- info->mPacketSource = source;
- }
-
- mInitCheck = OK;
-
- return OK;
-}
-
-// static
-void ARTPSession::MakeUDPSocket(PRFileDesc **s, unsigned port) {
- *s = PR_OpenUDPSocket(PR_AF_INET);
- if (!*s) {
- TRESPASS();
- }
-
- NetworkActivityMonitor::AttachIOLayer(*s);
-
- PRNetAddr addr;
- addr.inet.family = PR_AF_INET;
- addr.inet.ip = PR_htonl(PR_INADDR_ANY);
- addr.inet.port = PR_htons(port);
-
- if (PR_Bind(*s, &addr) == PR_FAILURE) {
- TRESPASS();
- }
-}
-
-ARTPSession::~ARTPSession() {
- for (size_t i = 0; i < mTracks.size(); ++i) {
- TrackInfo *info = &mTracks.editItemAt(i);
-
- info->mPacketSource->signalEOS(UNKNOWN_ERROR);
-
- if (info->mRTPSocket) {
- PR_Close(info->mRTPSocket);
- }
-
- if (info->mRTCPSocket) {
- PR_Close(info->mRTCPSocket);
- }
- }
-}
-
-void ARTPSession::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatAccessUnitComplete:
- {
- int32_t firstRTCP;
- if (msg->findInt32("first-rtcp", &firstRTCP)) {
- // There won't be an access unit here, it's just a notification
- // that the data communication worked since we got the first
- // rtcp packet.
- break;
- }
-
- size_t trackIndex;
- CHECK(msg->findSize("track-index", &trackIndex));
-
- int32_t eos;
- if (msg->findInt32("eos", &eos) && eos) {
- TrackInfo *info = &mTracks.editItemAt(trackIndex);
- info->mPacketSource->signalEOS(ERROR_END_OF_STREAM);
- break;
- }
-
- sp<RefBase> obj;
- CHECK(msg->findObject("access-unit", &obj));
- if (!msg->findObject("access-unit", &obj)) {
- LOGW("Cannot find access-unit");
-
- break;
- }
-
- sp<ABuffer> accessUnit = static_cast<ABuffer *>(obj.get());
-
- uint64_t ntpTime;
- if (!accessUnit->meta()->findInt64(
- "ntp-time", (int64_t *)&ntpTime)) {
- LOGW("Cannot find ntp-time");
-
- break;
- }
-
-#if 0
-#if 0
- printf("access unit complete size=%d\tntp-time=0x%016llx\n",
- accessUnit->size(), ntpTime);
-#else
- LOGI("access unit complete, size=%d, ntp-time=%llu",
- accessUnit->size(), ntpTime);
- hexdump(accessUnit->data(), accessUnit->size());
-#endif
-#endif
-
-#if 0
- CHECK_GE(accessUnit->size(), 5u);
- CHECK(!memcmp("\x00\x00\x00\x01", accessUnit->data(), 4));
- unsigned x = accessUnit->data()[4];
-
- LOGI("access unit complete: nalType=0x%02x, nalRefIdc=0x%02x",
- x & 0x1f, (x & 0x60) >> 5);
-#endif
-
- accessUnit->meta()->setInt64("ntp-time", ntpTime);
- accessUnit->meta()->setInt64("timeUs", 0);
-
-#if 0
- int32_t damaged;
- if (accessUnit->meta()->findInt32("damaged", &damaged)
- && damaged != 0) {
- LOGI("ignoring damaged AU");
- } else
-#endif
- {
- TrackInfo *info = &mTracks.editItemAt(trackIndex);
- info->mPacketSource->queueAccessUnit(accessUnit);
- }
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
-}
-
-bool ARTPSession::validateMediaFormat(size_t index, unsigned *port) const {
- AString format;
- mDesc->getFormat(index, &format);
-
- ssize_t i = format.find(" ");
- if (i < 0) {
- return false;
- }
-
- ++i;
- size_t j = i;
- while (isdigit(format.c_str()[j])) {
- ++j;
- }
- if (format.c_str()[j] != ' ') {
- return false;
- }
-
- AString portString(format, i, j - i);
-
- char *end;
- unsigned long x = strtoul(portString.c_str(), &end, 10);
- if (end == portString.c_str() || *end != '\0') {
- return false;
- }
-
- if (x == 0 || x > 65535) {
- return false;
- }
-
- *port = x;
-
- return true;
-}
-
-size_t ARTPSession::countTracks() {
- return mTracks.size();
-}
-
-sp<MediaSource> ARTPSession::trackAt(size_t index) {
- CHECK_LT(index, mTracks.size());
- return mTracks.editItemAt(index).mPacketSource;
-}
-
-} // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTPSession.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_RTP_SESSION_H_
-
-#define A_RTP_SESSION_H_
-
-#include "mozilla/Types.h"
-#include <media/stagefright/foundation/AHandler.h>
-
-#include "prio.h"
-
-namespace android {
-
-struct APacketSource;
-struct ARTPConnection;
-struct ASessionDescription;
-struct MOZ_EXPORT MediaSource;
-
-struct ARTPSession : public AHandler {
- ARTPSession();
-
- status_t setup(const sp<ASessionDescription> &desc);
-
- size_t countTracks();
- sp<MediaSource> trackAt(size_t index);
-
-protected:
- virtual void onMessageReceived(const sp<AMessage> &msg);
-
- virtual ~ARTPSession();
-
-private:
- enum {
- kWhatAccessUnitComplete = 1
- };
-
- struct TrackInfo {
- PRFileDesc *mRTPSocket;
- PRFileDesc *mRTCPSocket;
-
- sp<APacketSource> mPacketSource;
- };
-
- status_t mInitCheck;
- sp<ASessionDescription> mDesc;
- sp<ARTPConnection> mRTPConn;
-
- Vector<TrackInfo> mTracks;
-
- bool validateMediaFormat(size_t index, unsigned *port) const;
- static int MakeUDPSocket(unsigned port);
-
- DISALLOW_EVIL_CONSTRUCTORS(ARTPSession);
-};
-
-} // namespace android
-
-#endif // A_RTP_SESSION_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTPSource.cpp
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ARTPSource"
-#include "RtspPrlog.h"
-
-#include "ARTPSource.h"
-
-#include "AAMRAssembler.h"
-#include "AAVCAssembler.h"
-#include "AH263Assembler.h"
-#include "AMPEG4AudioAssembler.h"
-#include "AMPEG4ElementaryAssembler.h"
-#include "ARawAudioAssembler.h"
-#include "ASessionDescription.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-
-namespace android {
-
-static const uint32_t kSourceID = 0xdeadbeef;
-
-ARTPSource::ARTPSource(
- uint32_t id,
- const sp<ASessionDescription> &sessionDesc, size_t index,
- const sp<AMessage> ¬ify)
- : mID(id),
- mHighestSeqNumber(0),
- mNumBuffersReceived(0),
- mLastNTPTime(0),
- mLastNTPTimeUpdateUs(0),
- mIssueFIRRequests(false),
- mLastFIRRequestUs(-1),
- mNextFIRSeqNo((rand() * 256.0) / RAND_MAX),
- mNotify(notify) {
- unsigned long PT;
- AString desc;
- AString params;
- sessionDesc->getFormatType(index, &PT, &desc, ¶ms);
-
- if (!strncmp(desc.c_str(), "H264/", 5)) {
- mAssembler = new AAVCAssembler(notify);
- mIssueFIRRequests = true;
- } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
- mAssembler = new AMPEG4AudioAssembler(notify, params);
- } else if (!strncmp(desc.c_str(), "H263-1998/", 10)
- || !strncmp(desc.c_str(), "H263-2000/", 10)) {
- mAssembler = new AH263Assembler(notify);
- mIssueFIRRequests = true;
- } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
- mAssembler = new AAMRAssembler(notify, false /* isWide */, params);
- } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
- mAssembler = new AAMRAssembler(notify, true /* isWide */, params);
- } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)
- || !strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
- mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params);
- mIssueFIRRequests = true;
- } else if (ARawAudioAssembler::Supports(desc.c_str())) {
- mAssembler = new ARawAudioAssembler(notify, desc.c_str(), params);
- } else {
- TRESPASS();
- }
-}
-
-static uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) {
- return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1;
-}
-
-void ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) {
- if (queuePacket(buffer) && mAssembler != NULL) {
- mAssembler->onPacketReceived(this);
- }
-}
-
-void ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) {
- mLastNTPTime = ntpTime;
- mLastNTPTimeUpdateUs = ALooper::GetNowUs();
-
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("time-update", true);
- notify->setInt32("rtp-time", rtpTime);
- notify->setInt64("ntp-time", ntpTime);
- notify->post();
-}
-
-bool ARTPSource::queuePacket(const sp<ABuffer> &buffer) {
- uint32_t seqNum = (uint32_t)buffer->int32Data();
-
- if (mNumBuffersReceived++ == 0) {
- mHighestSeqNumber = seqNum;
- mQueue.push_back(buffer);
- return true;
- }
-
- // Only the lower 16-bit of the sequence numbers are transmitted,
- // derive the high-order bits by choosing the candidate closest
- // to the highest sequence number (extended to 32 bits) received so far.
-
- uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000);
- uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000);
- uint32_t seq3 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000);
- uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber);
- uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber);
- uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber);
-
- if (diff1 < diff2) {
- if (diff1 < diff3) {
- // diff1 < diff2 ^ diff1 < diff3
- seqNum = seq1;
- } else {
- // diff3 <= diff1 < diff2
- seqNum = seq3;
- }
- } else if (diff2 < diff3) {
- // diff2 <= diff1 ^ diff2 < diff3
- seqNum = seq2;
- } else {
- // diff3 <= diff2 <= diff1
- seqNum = seq3;
- }
-
- if (seqNum > mHighestSeqNumber) {
- mHighestSeqNumber = seqNum;
- }
-
- buffer->setInt32Data(seqNum);
-
- List<sp<ABuffer> >::iterator it = mQueue.begin();
- while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) {
- ++it;
- }
-
- if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) {
- LOGW("Discarding duplicate buffer");
- return false;
- }
-
- mQueue.insert(it, buffer);
-
- return true;
-}
-
-void ARTPSource::byeReceived() {
- mAssembler->onByeReceived();
-}
-
-void ARTPSource::addFIR(const sp<ABuffer> &buffer) {
- if (!mIssueFIRRequests) {
- return;
- }
-
- int64_t nowUs = ALooper::GetNowUs();
- if (mLastFIRRequestUs >= 0 && mLastFIRRequestUs + 5000000ll > nowUs) {
- // Send FIR requests at most every 5 secs.
- return;
- }
-
- mLastFIRRequestUs = nowUs;
-
- if (buffer->size() + 20 > buffer->capacity()) {
- LOGW("RTCP buffer too small to accomodate FIR.");
- return;
- }
-
- uint8_t *data = buffer->data() + buffer->size();
-
- data[0] = 0x80 | 4;
- data[1] = 206; // PSFB
- data[2] = 0;
- data[3] = 4;
- data[4] = kSourceID >> 24;
- data[5] = (kSourceID >> 16) & 0xff;
- data[6] = (kSourceID >> 8) & 0xff;
- data[7] = kSourceID & 0xff;
-
- data[8] = 0x00; // SSRC of media source (unused)
- data[9] = 0x00;
- data[10] = 0x00;
- data[11] = 0x00;
-
- data[12] = mID >> 24;
- data[13] = (mID >> 16) & 0xff;
- data[14] = (mID >> 8) & 0xff;
- data[15] = mID & 0xff;
-
- data[16] = mNextFIRSeqNo++; // Seq Nr.
-
- data[17] = 0x00; // Reserved
- data[18] = 0x00;
- data[19] = 0x00;
-
- buffer->setRange(buffer->offset(), buffer->size() + 20);
-
- LOGV("Added FIR request.");
-}
-
-void ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) {
- if (buffer->size() + 32 > buffer->capacity()) {
- LOGW("RTCP buffer too small to accomodate RR.");
- return;
- }
-
- uint8_t *data = buffer->data() + buffer->size();
-
- data[0] = 0x80 | 1;
- data[1] = 201; // RR
- data[2] = 0;
- data[3] = 7;
- data[4] = kSourceID >> 24;
- data[5] = (kSourceID >> 16) & 0xff;
- data[6] = (kSourceID >> 8) & 0xff;
- data[7] = kSourceID & 0xff;
-
- data[8] = mID >> 24;
- data[9] = (mID >> 16) & 0xff;
- data[10] = (mID >> 8) & 0xff;
- data[11] = mID & 0xff;
-
- data[12] = 0x00; // fraction lost
-
- data[13] = 0x00; // cumulative lost
- data[14] = 0x00;
- data[15] = 0x00;
-
- data[16] = mHighestSeqNumber >> 24;
- data[17] = (mHighestSeqNumber >> 16) & 0xff;
- data[18] = (mHighestSeqNumber >> 8) & 0xff;
- data[19] = mHighestSeqNumber & 0xff;
-
- data[20] = 0x00; // Interarrival jitter
- data[21] = 0x00;
- data[22] = 0x00;
- data[23] = 0x00;
-
- uint32_t LSR = 0;
- uint32_t DLSR = 0;
- if (mLastNTPTime != 0) {
- LSR = (mLastNTPTime >> 16) & 0xffffffff;
-
- DLSR = (uint32_t)
- ((ALooper::GetNowUs() - mLastNTPTimeUpdateUs) * 65536.0 / 1E6);
- }
-
- data[24] = LSR >> 24;
- data[25] = (LSR >> 16) & 0xff;
- data[26] = (LSR >> 8) & 0xff;
- data[27] = LSR & 0xff;
-
- data[28] = DLSR >> 24;
- data[29] = (DLSR >> 16) & 0xff;
- data[30] = (DLSR >> 8) & 0xff;
- data[31] = DLSR & 0xff;
-
- buffer->setRange(buffer->offset(), buffer->size() + 32);
-}
-
-} // namespace android
-
-
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTPSource.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_RTP_SOURCE_H_
-
-#define A_RTP_SOURCE_H_
-
-#include "mozilla/Types.h"
-#include <stdint.h>
-
-#include <media/stagefright/foundation/ABase.h>
-#include <utils/List.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-struct MOZ_EXPORT ABuffer;
-struct MOZ_EXPORT AMessage;
-struct ARTPAssembler;
-struct ASessionDescription;
-
-struct ARTPSource : public RefBase {
- ARTPSource(
- uint32_t id,
- const sp<ASessionDescription> &sessionDesc, size_t index,
- const sp<AMessage> ¬ify);
-
- void processRTPPacket(const sp<ABuffer> &buffer);
- void timeUpdate(uint32_t rtpTime, uint64_t ntpTime);
- void byeReceived();
-
- List<sp<ABuffer> > *queue() { return &mQueue; }
-
- void addReceiverReport(const sp<ABuffer> &buffer);
- void addFIR(const sp<ABuffer> &buffer);
-
-private:
- uint32_t mID;
- uint32_t mHighestSeqNumber;
- int32_t mNumBuffersReceived;
-
- List<sp<ABuffer> > mQueue;
- sp<ARTPAssembler> mAssembler;
-
- uint64_t mLastNTPTime;
- int64_t mLastNTPTimeUpdateUs;
-
- bool mIssueFIRRequests;
- int64_t mLastFIRRequestUs;
- uint8_t mNextFIRSeqNo;
-
- sp<AMessage> mNotify;
-
- bool queuePacket(const sp<ABuffer> &buffer);
-
- DISALLOW_EVIL_CONSTRUCTORS(ARTPSource);
-};
-
-} // namespace android
-
-#endif // A_RTP_SOURCE_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTPWriter.cpp
+++ /dev/null
@@ -1,847 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ARTPWriter"
-#include "RtspPrlog.h"
-
-#include "ARTPWriter.h"
-
-#include <fcntl.h>
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/MetaData.h>
-#include <utils/ByteOrder.h>
-
-#include "NetworkActivityMonitor.h"
-
-using namespace mozilla::net;
-
-#define PT 97
-#define PT_STR "97"
-
-namespace android {
-
-// static const size_t kMaxPacketSize = 65507; // maximum payload in UDP over IP
-static const size_t kMaxPacketSize = 1500;
-
-static int UniformRand(int limit) {
- return ((double)rand() * limit) / RAND_MAX;
-}
-
-ARTPWriter::ARTPWriter(int fd)
- : mFlags(0),
- mFd(dup(fd)),
- mLooper(new ALooper),
- mReflector(new AHandlerReflector<ARTPWriter>(this)) {
- CHECK_GE(fd, 0);
-
- mLooper->setName("rtp writer");
- mLooper->registerHandler(mReflector);
- mLooper->start();
-
- mSocket = PR_OpenUDPSocket(PR_AF_INET);
- if (!mSocket) {
- TRESPASS();
- }
-
- NetworkActivityMonitor::AttachIOLayer(mSocket);
-
- mRTPAddr.inet.family = PR_AF_INET;
-
-#if 1
- mRTPAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
-#else
- PR_StringToNetAddr("172.19.18.246", &mRTPAddr);
-#endif
-
- mRTPAddr.inet.port = PR_htons(5634);
- CHECK_EQ(0, PR_ntohs(mRTPAddr.inet.port) & 1);
-
- mRTCPAddr = mRTPAddr;
- mRTCPAddr.inet.port = PR_htons(PR_ntohs(mRTPAddr.inet.port) | 1);
-
-#if LOG_TO_FILES
- mRTPFd = open(
- "/data/misc/rtpout.bin",
- O_WRONLY | O_CREAT | O_TRUNC,
- 0644);
- CHECK_GE(mRTPFd, 0);
-
- mRTCPFd = open(
- "/data/misc/rtcpout.bin",
- O_WRONLY | O_CREAT | O_TRUNC,
- 0644);
- CHECK_GE(mRTCPFd, 0);
-#endif
-}
-
-ARTPWriter::~ARTPWriter() {
-#if LOG_TO_FILES
- close(mRTCPFd);
- mRTCPFd = -1;
-
- close(mRTPFd);
- mRTPFd = -1;
-#endif
-
- if (mSocket) {
- PR_Close(mSocket);
- mSocket = nullptr;
- }
-
- close(mFd);
- mFd = -1;
-}
-
-status_t ARTPWriter::addSource(const sp<MediaSource> &source) {
- mSource = source;
- return OK;
-}
-
-bool ARTPWriter::reachedEOS() {
- Mutex::Autolock autoLock(mLock);
- return (mFlags & kFlagEOS) != 0;
-}
-
-status_t ARTPWriter::start(MetaData *params) {
- Mutex::Autolock autoLock(mLock);
- if (mFlags & kFlagStarted) {
- return INVALID_OPERATION;
- }
-
- mFlags &= ~kFlagEOS;
- mSourceID = rand();
- mSeqNo = UniformRand(65536);
- mRTPTimeBase = rand();
- mNumRTPSent = 0;
- mNumRTPOctetsSent = 0;
- mLastRTPTime = 0;
- mLastNTPTime = 0;
- mNumSRsSent = 0;
-
- const char *mime;
- if (!mSource->getFormat()->findCString(kKeyMIMEType, &mime)) {
- return ERROR_UNSUPPORTED;
- }
-
- mMode = INVALID;
- if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
- mMode = H264;
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) {
- mMode = H263;
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
- mMode = AMR_NB;
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
- mMode = AMR_WB;
- } else {
- TRESPASS();
- }
-
- (new AMessage(kWhatStart, mReflector->id()))->post();
-
- while (!(mFlags & kFlagStarted)) {
- mCondition.wait(mLock);
- }
-
- return OK;
-}
-
-status_t ARTPWriter::stop() {
- Mutex::Autolock autoLock(mLock);
- if (!(mFlags & kFlagStarted)) {
- return OK;
- }
-
- (new AMessage(kWhatStop, mReflector->id()))->post();
-
- while (mFlags & kFlagStarted) {
- mCondition.wait(mLock);
- }
- return OK;
-}
-
-status_t ARTPWriter::pause() {
- return OK;
-}
-
-static void StripStartcode(MediaBuffer *buffer) {
- if (buffer->range_length() < 4) {
- return;
- }
-
- const uint8_t *ptr =
- (const uint8_t *)buffer->data() + buffer->range_offset();
-
- if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) {
- buffer->set_range(
- buffer->range_offset() + 4, buffer->range_length() - 4);
- }
-}
-
-void ARTPWriter::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatStart:
- {
- CHECK_EQ(mSource->start(), (status_t)OK);
-
-#if 0
- if (mMode == H264) {
- MediaBuffer *buffer;
- CHECK_EQ(mSource->read(&buffer), (status_t)OK);
-
- StripStartcode(buffer);
- makeH264SPropParamSets(buffer);
- buffer->release();
- buffer = NULL;
- }
-
- dumpSessionDesc();
-#endif
-
- {
- Mutex::Autolock autoLock(mLock);
- mFlags |= kFlagStarted;
- mCondition.signal();
- }
-
- (new AMessage(kWhatRead, mReflector->id()))->post();
- (new AMessage(kWhatSendSR, mReflector->id()))->post();
- break;
- }
-
- case kWhatStop:
- {
- CHECK_EQ(mSource->stop(), (status_t)OK);
-
- sendBye();
-
- {
- Mutex::Autolock autoLock(mLock);
- mFlags &= ~kFlagStarted;
- mCondition.signal();
- }
- break;
- }
-
- case kWhatRead:
- {
- {
- Mutex::Autolock autoLock(mLock);
- if (!(mFlags & kFlagStarted)) {
- break;
- }
- }
-
- onRead(msg);
- break;
- }
-
- case kWhatSendSR:
- {
- {
- Mutex::Autolock autoLock(mLock);
- if (!(mFlags & kFlagStarted)) {
- break;
- }
- }
-
- onSendSR(msg);
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
-}
-
-void ARTPWriter::onRead(const sp<AMessage> &msg) {
- MediaBuffer *mediaBuf;
- status_t err = mSource->read(&mediaBuf);
-
- if (err != OK) {
- LOGI("reached EOS.");
-
- Mutex::Autolock autoLock(mLock);
- mFlags |= kFlagEOS;
- return;
- }
-
- if (mediaBuf->range_length() > 0) {
- LOGV("read buffer of size %d", mediaBuf->range_length());
-
- if (mMode == H264) {
- StripStartcode(mediaBuf);
- sendAVCData(mediaBuf);
- } else if (mMode == H263) {
- sendH263Data(mediaBuf);
- } else if (mMode == AMR_NB || mMode == AMR_WB) {
- sendAMRData(mediaBuf);
- }
- }
-
- mediaBuf->release();
- mediaBuf = NULL;
-
- msg->post();
-}
-
-void ARTPWriter::onSendSR(const sp<AMessage> &msg) {
- sp<ABuffer> buffer = new ABuffer(65536);
- buffer->setRange(0, 0);
-
- addSR(buffer);
- addSDES(buffer);
-
- send(buffer, true /* isRTCP */);
-
- ++mNumSRsSent;
- msg->post(3000000);
-}
-
-void ARTPWriter::send(const sp<ABuffer> &buffer, bool isRTCP) {
- ssize_t n = PR_SendTo(
- mSocket, buffer->data(), buffer->size(), 0,
- (isRTCP ? &mRTCPAddr : &mRTPAddr), PR_INTERVAL_NO_WAIT);
-
- CHECK_EQ(n, (ssize_t)buffer->size());
-
-#if LOG_TO_FILES
- int fd = isRTCP ? mRTCPFd : mRTPFd;
-
- uint32_t ms = tolel(ALooper::GetNowUs() / 1000ll);
- uint32_t length = tolel(buffer->size());
- write(fd, &ms, sizeof(ms));
- write(fd, &length, sizeof(length));
- write(fd, buffer->data(), buffer->size());
-#endif
-}
-
-void ARTPWriter::addSR(const sp<ABuffer> &buffer) {
- uint8_t *data = buffer->data() + buffer->size();
-
- data[0] = 0x80 | 0;
- data[1] = 200; // SR
- data[2] = 0;
- data[3] = 6;
- data[4] = mSourceID >> 24;
- data[5] = (mSourceID >> 16) & 0xff;
- data[6] = (mSourceID >> 8) & 0xff;
- data[7] = mSourceID & 0xff;
-
- data[8] = mLastNTPTime >> (64 - 8);
- data[9] = (mLastNTPTime >> (64 - 16)) & 0xff;
- data[10] = (mLastNTPTime >> (64 - 24)) & 0xff;
- data[11] = (mLastNTPTime >> 32) & 0xff;
- data[12] = (mLastNTPTime >> 24) & 0xff;
- data[13] = (mLastNTPTime >> 16) & 0xff;
- data[14] = (mLastNTPTime >> 8) & 0xff;
- data[15] = mLastNTPTime & 0xff;
-
- data[16] = (mLastRTPTime >> 24) & 0xff;
- data[17] = (mLastRTPTime >> 16) & 0xff;
- data[18] = (mLastRTPTime >> 8) & 0xff;
- data[19] = mLastRTPTime & 0xff;
-
- data[20] = mNumRTPSent >> 24;
- data[21] = (mNumRTPSent >> 16) & 0xff;
- data[22] = (mNumRTPSent >> 8) & 0xff;
- data[23] = mNumRTPSent & 0xff;
-
- data[24] = mNumRTPOctetsSent >> 24;
- data[25] = (mNumRTPOctetsSent >> 16) & 0xff;
- data[26] = (mNumRTPOctetsSent >> 8) & 0xff;
- data[27] = mNumRTPOctetsSent & 0xff;
-
- buffer->setRange(buffer->offset(), buffer->size() + 28);
-}
-
-void ARTPWriter::addSDES(const sp<ABuffer> &buffer) {
- uint8_t *data = buffer->data() + buffer->size();
- data[0] = 0x80 | 1;
- data[1] = 202; // SDES
- data[4] = mSourceID >> 24;
- data[5] = (mSourceID >> 16) & 0xff;
- data[6] = (mSourceID >> 8) & 0xff;
- data[7] = mSourceID & 0xff;
-
- size_t offset = 8;
-
- data[offset++] = 1; // CNAME
-
- static const char *kCNAME = "someone@somewhere";
- data[offset++] = strlen(kCNAME);
-
- memcpy(&data[offset], kCNAME, strlen(kCNAME));
- offset += strlen(kCNAME);
-
- data[offset++] = 7; // NOTE
-
- static const char *kNOTE = "Hell's frozen over.";
- data[offset++] = strlen(kNOTE);
-
- memcpy(&data[offset], kNOTE, strlen(kNOTE));
- offset += strlen(kNOTE);
-
- data[offset++] = 0;
-
- if ((offset % 4) > 0) {
- size_t count = 4 - (offset % 4);
- switch (count) {
- case 3:
- data[offset++] = 0;
- case 2:
- data[offset++] = 0;
- case 1:
- data[offset++] = 0;
- }
- }
-
- size_t numWords = (offset / 4) - 1;
- data[2] = numWords >> 8;
- data[3] = numWords & 0xff;
-
- buffer->setRange(buffer->offset(), buffer->size() + offset);
-}
-
-// static
-uint64_t ARTPWriter::GetNowNTP() {
- uint64_t nowUs = ALooper::GetNowUs();
-
- nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
-
- uint64_t hi = nowUs / 1000000ll;
- uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
-
- return (hi << 32) | lo;
-}
-
-void ARTPWriter::dumpSessionDesc() {
- AString sdp;
- sdp = "v=0\r\n";
-
- sdp.append("o=- ");
-
- uint64_t ntp = GetNowNTP();
- sdp.append(ntp);
- sdp.append(" ");
- sdp.append(ntp);
- sdp.append(" IN IP4 127.0.0.0\r\n");
-
- sdp.append(
- "s=Sample\r\n"
- "i=Playing around\r\n"
- "c=IN IP4 ");
-
- PRNetAddr addr;
- addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
-
- char buf[256];
- PR_NetAddrToString(&addr, buf, sizeof(buf));
- sdp.append(buf);
-
- sdp.append(
- "\r\n"
- "t=0 0\r\n"
- "a=range:npt=now-\r\n");
-
- sp<MetaData> meta = mSource->getFormat();
-
- if (mMode == H264 || mMode == H263) {
- sdp.append("m=video ");
- } else {
- sdp.append("m=audio ");
- }
-
- sdp.append(StringPrintf("%d", PR_ntohs(mRTPAddr.inet.port)));
- sdp.append(
- " RTP/AVP " PT_STR "\r\n"
- "b=AS 320000\r\n"
- "a=rtpmap:" PT_STR " ");
-
- if (mMode == H264) {
- sdp.append("H264/90000");
- } else if (mMode == H263) {
- sdp.append("H263-1998/90000");
- } else if (mMode == AMR_NB || mMode == AMR_WB) {
- int32_t sampleRate, numChannels;
- CHECK(mSource->getFormat()->findInt32(kKeySampleRate, &sampleRate));
- CHECK(mSource->getFormat()->findInt32(kKeyChannelCount, &numChannels));
-
- CHECK_EQ(numChannels, 1);
- CHECK_EQ(sampleRate, (mMode == AMR_NB) ? 8000 : 16000);
-
- sdp.append(mMode == AMR_NB ? "AMR" : "AMR-WB");
- sdp.append(StringPrintf("/%d/%d", sampleRate, numChannels));
- } else {
- TRESPASS();
- }
-
- sdp.append("\r\n");
-
- if (mMode == H264 || mMode == H263) {
- int32_t width, height;
- CHECK(meta->findInt32(kKeyWidth, &width));
- CHECK(meta->findInt32(kKeyHeight, &height));
-
- sdp.append("a=cliprect 0,0,");
- sdp.append(height);
- sdp.append(",");
- sdp.append(width);
- sdp.append("\r\n");
-
- sdp.append(
- "a=framesize:" PT_STR " ");
- sdp.append(width);
- sdp.append("-");
- sdp.append(height);
- sdp.append("\r\n");
- }
-
- if (mMode == H264) {
- sdp.append(
- "a=fmtp:" PT_STR " profile-level-id=");
- sdp.append(mProfileLevel);
- sdp.append(";sprop-parameter-sets=");
-
- sdp.append(mSeqParamSet);
- sdp.append(",");
- sdp.append(mPicParamSet);
- sdp.append(";packetization-mode=1\r\n");
- } else if (mMode == AMR_NB || mMode == AMR_WB) {
- sdp.append("a=fmtp:" PT_STR " octed-align\r\n");
- }
-
- LOGI("%s", sdp.c_str());
-}
-
-void ARTPWriter::makeH264SPropParamSets(MediaBuffer *buffer) {
- static const char kStartCode[] = "\x00\x00\x00\x01";
-
- const uint8_t *data =
- (const uint8_t *)buffer->data() + buffer->range_offset();
- size_t size = buffer->range_length();
-
- CHECK_GE(size, 0u);
-
- size_t startCodePos = 0;
- while (startCodePos + 3 < size
- && memcmp(kStartCode, &data[startCodePos], 4)) {
- ++startCodePos;
- }
-
- CHECK_LT(startCodePos + 3, size);
-
- CHECK_EQ((unsigned)data[0], 0x67u);
-
- mProfileLevel =
- StringPrintf("%02X%02X%02X", data[1], data[2], data[3]);
-
- encodeBase64(data, startCodePos, &mSeqParamSet);
-
- encodeBase64(&data[startCodePos + 4], size - startCodePos - 4,
- &mPicParamSet);
-}
-
-void ARTPWriter::sendBye() {
- sp<ABuffer> buffer = new ABuffer(8);
- uint8_t *data = buffer->data();
- *data++ = (2 << 6) | 1;
- *data++ = 203;
- *data++ = 0;
- *data++ = 1;
- *data++ = mSourceID >> 24;
- *data++ = (mSourceID >> 16) & 0xff;
- *data++ = (mSourceID >> 8) & 0xff;
- *data++ = mSourceID & 0xff;
- buffer->setRange(0, 8);
-
- send(buffer, true /* isRTCP */);
-}
-
-void ARTPWriter::sendAVCData(MediaBuffer *mediaBuf) {
- // 12 bytes RTP header + 2 bytes for the FU-indicator and FU-header.
- CHECK_GE(kMaxPacketSize, 12u + 2u);
-
- int64_t timeUs;
- CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs));
-
- uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll);
-
- const uint8_t *mediaData =
- (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset();
-
- sp<ABuffer> buffer = new ABuffer(kMaxPacketSize);
- if (mediaBuf->range_length() + 12 <= buffer->capacity()) {
- // The data fits into a single packet
- uint8_t *data = buffer->data();
- data[0] = 0x80;
- data[1] = (1 << 7) | PT; // M-bit
- data[2] = (mSeqNo >> 8) & 0xff;
- data[3] = mSeqNo & 0xff;
- data[4] = rtpTime >> 24;
- data[5] = (rtpTime >> 16) & 0xff;
- data[6] = (rtpTime >> 8) & 0xff;
- data[7] = rtpTime & 0xff;
- data[8] = mSourceID >> 24;
- data[9] = (mSourceID >> 16) & 0xff;
- data[10] = (mSourceID >> 8) & 0xff;
- data[11] = mSourceID & 0xff;
-
- memcpy(&data[12],
- mediaData, mediaBuf->range_length());
-
- buffer->setRange(0, mediaBuf->range_length() + 12);
-
- send(buffer, false /* isRTCP */);
-
- ++mSeqNo;
- ++mNumRTPSent;
- mNumRTPOctetsSent += buffer->size() - 12;
- } else {
- // FU-A
-
- unsigned nalType = mediaData[0];
- size_t offset = 1;
-
- bool firstPacket = true;
- while (offset < mediaBuf->range_length()) {
- size_t size = mediaBuf->range_length() - offset;
- bool lastPacket = true;
- if (size + 12 + 2 > buffer->capacity()) {
- lastPacket = false;
- size = buffer->capacity() - 12 - 2;
- }
-
- uint8_t *data = buffer->data();
- data[0] = 0x80;
- data[1] = (lastPacket ? (1 << 7) : 0x00) | PT; // M-bit
- data[2] = (mSeqNo >> 8) & 0xff;
- data[3] = mSeqNo & 0xff;
- data[4] = rtpTime >> 24;
- data[5] = (rtpTime >> 16) & 0xff;
- data[6] = (rtpTime >> 8) & 0xff;
- data[7] = rtpTime & 0xff;
- data[8] = mSourceID >> 24;
- data[9] = (mSourceID >> 16) & 0xff;
- data[10] = (mSourceID >> 8) & 0xff;
- data[11] = mSourceID & 0xff;
-
- data[12] = 28 | (nalType & 0xe0);
-
- CHECK(!firstPacket || !lastPacket);
-
- data[13] =
- (firstPacket ? 0x80 : 0x00)
- | (lastPacket ? 0x40 : 0x00)
- | (nalType & 0x1f);
-
- memcpy(&data[14], &mediaData[offset], size);
-
- buffer->setRange(0, 14 + size);
-
- send(buffer, false /* isRTCP */);
-
- ++mSeqNo;
- ++mNumRTPSent;
- mNumRTPOctetsSent += buffer->size() - 12;
-
- firstPacket = false;
- offset += size;
- }
- }
-
- mLastRTPTime = rtpTime;
- mLastNTPTime = GetNowNTP();
-}
-
-void ARTPWriter::sendH263Data(MediaBuffer *mediaBuf) {
- CHECK_GE(kMaxPacketSize, 12u + 2u);
-
- int64_t timeUs;
- CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs));
-
- uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll);
-
- const uint8_t *mediaData =
- (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset();
-
- // hexdump(mediaData, mediaBuf->range_length());
-
- CHECK_EQ((unsigned)mediaData[0], 0u);
- CHECK_EQ((unsigned)mediaData[1], 0u);
-
- size_t offset = 2;
- size_t size = mediaBuf->range_length();
-
- while (offset < size) {
- sp<ABuffer> buffer = new ABuffer(kMaxPacketSize);
- // CHECK_LE(mediaBuf->range_length() -2 + 14, buffer->capacity());
-
- size_t remaining = size - offset;
- bool lastPacket = (remaining + 14 <= buffer->capacity());
- if (!lastPacket) {
- remaining = buffer->capacity() - 14;
- }
-
- uint8_t *data = buffer->data();
- data[0] = 0x80;
- data[1] = (lastPacket ? 0x80 : 0x00) | PT; // M-bit
- data[2] = (mSeqNo >> 8) & 0xff;
- data[3] = mSeqNo & 0xff;
- data[4] = rtpTime >> 24;
- data[5] = (rtpTime >> 16) & 0xff;
- data[6] = (rtpTime >> 8) & 0xff;
- data[7] = rtpTime & 0xff;
- data[8] = mSourceID >> 24;
- data[9] = (mSourceID >> 16) & 0xff;
- data[10] = (mSourceID >> 8) & 0xff;
- data[11] = mSourceID & 0xff;
-
- data[12] = (offset == 2) ? 0x04 : 0x00; // P=?, V=0
- data[13] = 0x00; // PLEN = PEBIT = 0
-
- memcpy(&data[14], &mediaData[offset], remaining);
- offset += remaining;
-
- buffer->setRange(0, remaining + 14);
-
- send(buffer, false /* isRTCP */);
-
- ++mSeqNo;
- ++mNumRTPSent;
- mNumRTPOctetsSent += buffer->size() - 12;
- }
-
- mLastRTPTime = rtpTime;
- mLastNTPTime = GetNowNTP();
-}
-
-static size_t getFrameSize(bool isWide, unsigned FT) {
- static const size_t kFrameSizeNB[8] = {
- 95, 103, 118, 134, 148, 159, 204, 244
- };
- static const size_t kFrameSizeWB[9] = {
- 132, 177, 253, 285, 317, 365, 397, 461, 477
- };
-
- size_t frameSize = isWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT];
-
- // Round up bits to bytes and add 1 for the header byte.
- frameSize = (frameSize + 7) / 8 + 1;
-
- return frameSize;
-}
-
-void ARTPWriter::sendAMRData(MediaBuffer *mediaBuf) {
- const uint8_t *mediaData =
- (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset();
-
- size_t mediaLength = mediaBuf->range_length();
-
- CHECK_GE(kMaxPacketSize, 12u + 1u + mediaLength);
-
- const bool isWide = (mMode == AMR_WB);
-
- int64_t timeUs;
- CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs));
- uint32_t rtpTime = mRTPTimeBase + (timeUs / (isWide ? 250 : 125));
-
- // hexdump(mediaData, mediaLength);
-
- Vector<uint8_t> tableOfContents;
- size_t srcOffset = 0;
- while (srcOffset < mediaLength) {
- uint8_t toc = mediaData[srcOffset];
-
- unsigned FT = (toc >> 3) & 0x0f;
- CHECK((isWide && FT <= 8) || (!isWide && FT <= 7));
-
- tableOfContents.push(toc);
- srcOffset += getFrameSize(isWide, FT);
- }
- CHECK_EQ(srcOffset, mediaLength);
-
- sp<ABuffer> buffer = new ABuffer(kMaxPacketSize);
- CHECK_LE(mediaLength + 12 + 1, buffer->capacity());
-
- // The data fits into a single packet
- uint8_t *data = buffer->data();
- data[0] = 0x80;
- data[1] = PT;
- if (mNumRTPSent == 0) {
- // Signal start of talk-spurt.
- data[1] |= 0x80; // M-bit
- }
- data[2] = (mSeqNo >> 8) & 0xff;
- data[3] = mSeqNo & 0xff;
- data[4] = rtpTime >> 24;
- data[5] = (rtpTime >> 16) & 0xff;
- data[6] = (rtpTime >> 8) & 0xff;
- data[7] = rtpTime & 0xff;
- data[8] = mSourceID >> 24;
- data[9] = (mSourceID >> 16) & 0xff;
- data[10] = (mSourceID >> 8) & 0xff;
- data[11] = mSourceID & 0xff;
-
- data[12] = 0xf0; // CMR=15, RR=0
-
- size_t dstOffset = 13;
-
- for (size_t i = 0; i < tableOfContents.size(); ++i) {
- uint8_t toc = tableOfContents[i];
-
- if (i + 1 < tableOfContents.size()) {
- toc |= 0x80;
- } else {
- toc &= ~0x80;
- }
-
- data[dstOffset++] = toc;
- }
-
- srcOffset = 0;
- for (size_t i = 0; i < tableOfContents.size(); ++i) {
- uint8_t toc = tableOfContents[i];
- unsigned FT = (toc >> 3) & 0x0f;
- size_t frameSize = getFrameSize(isWide, FT);
-
- ++srcOffset; // skip toc
- memcpy(&data[dstOffset], &mediaData[srcOffset], frameSize - 1);
- srcOffset += frameSize - 1;
- dstOffset += frameSize - 1;
- }
-
- buffer->setRange(0, dstOffset);
-
- send(buffer, false /* isRTCP */);
-
- ++mSeqNo;
- ++mNumRTPSent;
- mNumRTPOctetsSent += buffer->size() - 12;
-
- mLastRTPTime = rtpTime;
- mLastNTPTime = GetNowNTP();
-}
-
-} // namespace android
-
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTPWriter.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_RTP_WRITER_H_
-
-#define A_RTP_WRITER_H_
-
-#include "mozilla/Types.h"
-#include <media/stagefright/foundation/ABase.h>
-#include <media/stagefright/foundation/AHandlerReflector.h>
-#include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/foundation/base64.h>
-#include <media/stagefright/MediaWriter.h>
-
-#include <arpa/inet.h>
-
-#include "prio.h"
-#include "prnetdb.h"
-
-#define LOG_TO_FILES 0
-
-namespace android {
-
-struct MOZ_EXPORT ABuffer;
-struct MOZ_EXPORT MediaBuffer;
-
-struct ARTPWriter : public MediaWriter {
- ARTPWriter(int fd);
-
- virtual status_t addSource(const sp<MediaSource> &source);
- virtual bool reachedEOS();
- virtual status_t start(MetaData *params);
- virtual status_t stop();
- virtual status_t pause();
-
- virtual void onMessageReceived(const sp<AMessage> &msg);
-
-protected:
- virtual ~ARTPWriter();
-
-private:
- enum {
- kWhatStart = 1,
- kWhatStop,
- kWhatRead,
- kWhatSendSR,
- };
-
- enum {
- kFlagStarted = 1,
- kFlagEOS = 2,
- };
-
- Mutex mLock;
- Condition mCondition;
- uint32_t mFlags;
-
- int mFd;
-
-#if LOG_TO_FILES
- int mRTPFd;
- int mRTCPFd;
-#endif
-
- sp<MediaSource> mSource;
- sp<ALooper> mLooper;
- sp<AHandlerReflector<ARTPWriter> > mReflector;
-
- PRFileDesc *mSocket;
- PRNetAddr mRTPAddr;
- PRNetAddr mRTCPAddr;
-
- AString mProfileLevel;
- AString mSeqParamSet;
- AString mPicParamSet;
-
- uint32_t mSourceID;
- uint32_t mSeqNo;
- uint32_t mRTPTimeBase;
- uint32_t mNumRTPSent;
- uint32_t mNumRTPOctetsSent;
- uint32_t mLastRTPTime;
- uint64_t mLastNTPTime;
-
- int32_t mNumSRsSent;
-
- enum {
- INVALID,
- H264,
- H263,
- AMR_NB,
- AMR_WB,
- } mMode;
-
- static uint64_t GetNowNTP();
-
- void onRead(const sp<AMessage> &msg);
- void onSendSR(const sp<AMessage> &msg);
-
- void addSR(const sp<ABuffer> &buffer);
- void addSDES(const sp<ABuffer> &buffer);
-
- void makeH264SPropParamSets(MediaBuffer *buffer);
- void dumpSessionDesc();
-
- void sendBye();
- void sendAVCData(MediaBuffer *mediaBuf);
- void sendH263Data(MediaBuffer *mediaBuf);
- void sendAMRData(MediaBuffer *mediaBuf);
-
- void send(const sp<ABuffer> &buffer, bool isRTCP);
-
- DISALLOW_EVIL_CONSTRUCTORS(ARTPWriter);
-};
-
-} // namespace android
-
-#endif // A_RTP_WRITER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTSPConnection.cpp
+++ /dev/null
@@ -1,1109 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ARTSPConnection"
-#include "RtspPrlog.h"
-
-#include "ARTSPConnection.h"
-
-#include <cutils/properties.h>
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/base64.h>
-#include <media/stagefright/MediaErrors.h>
-
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <netdb.h>
-
-#include "nsCOMPtr.h"
-#include "nsString.h"
-#include "nsNetCID.h"
-#include "nsIServiceManager.h"
-#include "nsICryptoHash.h"
-
-#include "prnetdb.h"
-#include "prerr.h"
-#include "prerror.h"
-#include "NetworkActivityMonitor.h"
-
-using namespace mozilla::net;
-
-namespace android {
-
-// static
-const uint32_t ARTSPConnection::kSocketPollTimeoutUs = 1000;
-const uint32_t ARTSPConnection::kSocketPollTimeoutRetries = 10000;
-const uint32_t ARTSPConnection::kSocketBlokingRecvTimeout = 10;
-
-ARTSPConnection::ARTSPConnection(bool uidValid, uid_t uid)
- : mUIDValid(uidValid),
- mUID(uid),
- mState(DISCONNECTED),
- mAuthType(NONE),
- mConnectionID(0),
- mNextCSeq(0),
- mReceiveResponseEventPending(false),
- mSocket(nullptr),
- mNumSocketPollTimeoutRetries(0) {
-}
-
-ARTSPConnection::~ARTSPConnection() {
- if (mSocket) {
- LOGE("Connection is still open, closing the socket.");
- closeSocket();
- }
-}
-
-void ARTSPConnection::connect(const char *url, const sp<AMessage> &reply) {
- sp<AMessage> msg = new AMessage(kWhatConnect, id());
- msg->setString("url", url);
- msg->setMessage("reply", reply);
- msg->post();
-}
-
-void ARTSPConnection::disconnect(const sp<AMessage> &reply) {
- int32_t result;
- sp<AMessage> msg = new AMessage(kWhatDisconnect, id());
- msg->setMessage("reply", reply);
- if (reply->findInt32("result", &result)) {
- msg->setInt32("result", result);
- } else {
- msg->setInt32("result", OK);
- }
- msg->post();
-}
-
-void ARTSPConnection::sendRequest(
- const char *request, const sp<AMessage> &reply) {
- sp<AMessage> msg = new AMessage(kWhatSendRequest, id());
- msg->setString("request", request);
- msg->setMessage("reply", reply);
- msg->post();
-}
-
-void ARTSPConnection::observeBinaryData(const sp<AMessage> &reply) {
- sp<AMessage> msg = new AMessage(kWhatObserveBinaryData, id());
- msg->setMessage("reply", reply);
- msg->post();
-}
-
-void ARTSPConnection::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatConnect:
- onConnect(msg);
- break;
-
- case kWhatDisconnect:
- onDisconnect(msg);
- break;
-
- case kWhatCompleteConnection:
- onCompleteConnection(msg);
- break;
-
- case kWhatSendRequest:
- onSendRequest(msg);
- break;
-
- case kWhatReceiveResponse:
- onReceiveResponse();
- break;
-
- case kWhatObserveBinaryData:
- {
- CHECK(msg->findMessage("reply", &mObserveBinaryMessage));
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
-}
-
-// static
-bool ARTSPConnection::ParseURL(
- const char *url, AString *host, uint16_t *port, AString *path,
- AString *user, AString *pass) {
- host->clear();
- *port = 0;
- path->clear();
- user->clear();
- pass->clear();
-
- if (strncasecmp("rtsp://", url, 7)) {
- return false;
- }
-
- const char *slashPos = strchr(&url[7], '/');
-
- if (slashPos == NULL) {
- host->setTo(&url[7]);
- path->setTo("/");
- } else {
- host->setTo(&url[7], slashPos - &url[7]);
- path->setTo(slashPos);
- }
-
- ssize_t atPos = host->find("@");
-
- if (atPos >= 0) {
- // Split of user:pass@ from hostname.
-
- AString userPass(*host, 0, atPos);
- host->erase(0, atPos + 1);
-
- ssize_t colonPos = userPass.find(":");
-
- if (colonPos < 0) {
- *user = userPass;
- } else {
- user->setTo(userPass, 0, colonPos);
- pass->setTo(userPass, colonPos + 1, userPass.size() - colonPos - 1);
- }
- }
-
- const char *colonPos = strchr(host->c_str(), ':');
-
- if (colonPos != NULL) {
- unsigned long x;
- if (!ParseSingleUnsignedLong(colonPos + 1, &x) || x >= 65536) {
- return false;
- }
-
- *port = x;
-
- size_t colonOffset = colonPos - host->c_str();
- size_t trailing = host->size() - colonOffset;
- host->erase(colonOffset, trailing);
- } else {
- *port = 554;
- }
-
- return true;
-}
-
-void ARTSPConnection::MakeUserAgent(const char *userAgent) {
- mUserAgent.clear();
- mUserAgent.setTo("User-Agent: ");
- mUserAgent.append(userAgent);
- mUserAgent.append("\r\n");
-}
-
-static status_t MakeSocketBlocking(PRFileDesc *fd, bool blocking) {
- // Check if socket is closed.
- if (!fd) {
- return UNKNOWN_ERROR;
- }
-
- PRStatus rv = PR_FAILURE;
- PRSocketOptionData opt;
-
- opt.option = PR_SockOpt_Nonblocking;
- opt.value.non_blocking = !blocking;
- rv = PR_SetSocketOption(fd, &opt);
-
- return rv == PR_SUCCESS ? OK : UNKNOWN_ERROR;
-}
-
-void ARTSPConnection::onConnect(const sp<AMessage> &msg) {
- ++mConnectionID;
-
- if (mState != DISCONNECTED) {
- closeSocket();
-
- flushPendingRequests();
- }
-
- mState = CONNECTING;
-
- AString url;
- CHECK(msg->findString("url", &url));
-
- sp<AMessage> reply;
- CHECK(msg->findMessage("reply", &reply));
-
- AString host, path;
- uint16_t port;
- if (!ParseURL(url.c_str(), &host, &port, &path, &mUser, &mPass)
- || (mUser.size() > 0 && mPass.size() == 0)) {
- // If we have a user name but no password we have to give up
- // right here, since we currently have no way of asking the user
- // for this information.
-
- LOGE("Malformed rtsp url %s", url.c_str());
-
- reply->setInt32("result", ERROR_MALFORMED);
- reply->post();
-
- mState = DISCONNECTED;
- return;
- }
-
- if (mUser.size() > 0) {
- LOGV("user = '%s', pass = '%s'", mUser.c_str(), mPass.c_str());
- }
-
- PRStatus status = PR_FAILURE;
- PRHostEnt hostentry;
- char buffer[PR_NETDB_BUF_SIZE];
-
- status = PR_GetHostByName(
- host.c_str(), buffer, PR_NETDB_BUF_SIZE, &hostentry);
- if (status == PR_FAILURE) {
- LOGE("Unknown host %s", host.c_str());
-
- PRErrorCode code = PR_GetError();
- reply->setInt32("result", -code);
- reply->post();
-
- mState = DISCONNECTED;
- return;
- }
-
- mSocket = PR_OpenTCPSocket(PR_AF_INET);
- if (!mSocket) {
- TRESPASS();
- }
-
- NetworkActivityMonitor::AttachIOLayer(mSocket);
-
- MakeSocketBlocking(mSocket, false);
-
- PRNetAddr remote;
- remote.inet.family = PR_AF_INET;
- remote.inet.ip = *((uint32_t *) hostentry.h_addr_list[0]);
- remote.inet.port = PR_htons(port);
-
- status = PR_Connect(mSocket, &remote, PR_INTERVAL_NO_TIMEOUT);
-
- reply->setInt32("server-ip", PR_ntohl(remote.inet.ip));
-
- if (status != PR_SUCCESS) {
- PRErrorCode code = PR_GetError();
- if (code == PR_IN_PROGRESS_ERROR) {
- mNumSocketPollTimeoutRetries = 0;
- sp<AMessage> msg = new AMessage(kWhatCompleteConnection, id());
- msg->setMessage("reply", reply);
- msg->setInt32("connection-id", mConnectionID);
- msg->post();
- return;
- }
-
- reply->setInt32("result", -code);
- mState = DISCONNECTED;
-
- closeSocket();
- } else {
- reply->setInt32("result", OK);
- mState = CONNECTED;
- mNextCSeq = 1;
-
- postReceiveResponseEvent();
- }
-
- reply->post();
-}
-
-void ARTSPConnection::performDisconnect() {
- closeSocket();
-
- flushPendingRequests();
-
- mUser.clear();
- mPass.clear();
- mAuthType = NONE;
- mNonce.clear();
- mNumSocketPollTimeoutRetries = 0;
-
- mState = DISCONNECTED;
-}
-
-void ARTSPConnection::onDisconnect(const sp<AMessage> &msg) {
- int32_t result;
- if (mState == CONNECTED || mState == CONNECTING) {
- performDisconnect();
- }
-
- sp<AMessage> reply;
- CHECK(msg->findMessage("reply", &reply));
- CHECK(msg->findInt32("result", &result));
-
- reply->setInt32("result", result);
- reply->post();
-}
-
-void ARTSPConnection::onCompleteConnection(const sp<AMessage> &msg) {
- sp<AMessage> reply;
- CHECK(msg->findMessage("reply", &reply));
-
- int32_t connectionID;
- CHECK(msg->findInt32("connection-id", &connectionID));
-
- if ((connectionID != mConnectionID) || mState != CONNECTING) {
- // While we were attempting to connect, the attempt was
- // cancelled.
- reply->setInt32("result", -ECONNABORTED);
- reply->post();
- return;
- }
-
- PRPollDesc writePollDesc;
-
- writePollDesc.fd = mSocket;
- writePollDesc.in_flags = PR_POLL_WRITE;
-
- int32_t numSocketsReadyToRead = PR_Poll(&writePollDesc, 1,
- PR_MicrosecondsToInterval(kSocketPollTimeoutUs));
-
- CHECK_GE(numSocketsReadyToRead, 0);
-
- if (numSocketsReadyToRead == 0) {
- // PR_Poll() timed out. Not yet connected.
- if (mNumSocketPollTimeoutRetries < kSocketPollTimeoutRetries) {
- mNumSocketPollTimeoutRetries++;
- msg->post();
- } else {
- // Connection timeout here.
- // We cannot establish TCP connection, abort the connect
- // and reply an error to RTSPConnectionHandler.
- LOGE("Connection timeout. Failed to connect to the server.");
- mNumSocketPollTimeoutRetries = 0;
- reply->setInt32("result", -ETIMEDOUT);
- reply->post();
- }
- return;
- }
-
- if (numSocketsReadyToRead < 0) {
- reply->setInt32("result", -PR_GetError());
-
- mState = DISCONNECTED;
- closeSocket();
- } else {
- reply->setInt32("result", OK);
- mState = CONNECTED;
- mNextCSeq = 1;
-
- postReceiveResponseEvent();
- }
-
- reply->post();
-}
-
-void ARTSPConnection::onSendRequest(const sp<AMessage> &msg) {
- sp<AMessage> reply;
- CHECK(msg->findMessage("reply", &reply));
-
- if (mState != CONNECTED) {
- reply->setInt32("result", -ENOTCONN);
- reply->post();
- return;
- }
-
- AString request;
- CHECK(msg->findString("request", &request));
-
- // Just in case we need to re-issue the request with proper authentication
- // later, stash it away.
- reply->setString("original-request", request.c_str(), request.size());
-
- addAuthentication(&request);
- addUserAgent(&request);
-
- // Find the boundary between headers and the body.
- ssize_t i = request.find("\r\n\r\n");
- CHECK_GE(i, 0);
-
- int32_t cseq = mNextCSeq++;
-
- AString cseqHeader = "CSeq: ";
- cseqHeader.append(cseq);
- cseqHeader.append("\r\n");
-
- request.insert(cseqHeader, i + 2);
-
- LOGV("request: '%s'", request.c_str());
-
- size_t numBytesSent = 0;
- while (numBytesSent < request.size()) {
- ssize_t n =
- PR_Send(mSocket, request.c_str() + numBytesSent,
- request.size() - numBytesSent, 0, PR_INTERVAL_NO_WAIT);
-
- PRErrorCode errCode = PR_GetError();
- if (n < 0 && errCode == PR_PENDING_INTERRUPT_ERROR) {
- continue;
- }
-
- if (n <= 0) {
- performDisconnect();
-
- if (n == 0) {
- // Server closed the connection.
- LOGE("Server unexpectedly closed the connection.");
-
- reply->setInt32("result", ERROR_IO);
- reply->post();
- } else {
- LOGE("Error sending rtsp request. (%d)", errCode);
- reply->setInt32("result", -errCode);
- reply->post();
- }
-
- return;
- }
-
- numBytesSent += (size_t)n;
- }
-
- mPendingRequests.add(cseq, reply);
-}
-
-void ARTSPConnection::onReceiveResponse() {
- mReceiveResponseEventPending = false;
-
- if (mState != CONNECTED) {
- return;
- }
-
- PRPollDesc readPollDesc;
- readPollDesc.fd = mSocket;
- readPollDesc.in_flags = PR_POLL_READ;
-
- int32_t numSocketsReadyToRead = PR_Poll(&readPollDesc, 1,
- PR_MicrosecondsToInterval(kSocketPollTimeoutUs));
-
- CHECK_GE(numSocketsReadyToRead, 0);
-
- // Number of ready-to-read sockets is not expected to be greater than 1.
- if (numSocketsReadyToRead > 1) {
- return;
- }
-
- if (numSocketsReadyToRead == 1) {
- MakeSocketBlocking(mSocket, true);
-
- bool success = receiveRTSPResponse();
-
- MakeSocketBlocking(mSocket, false);
-
- if (!success) {
- // Something horrible, irreparable has happened.
- flushPendingRequests();
- return;
- }
- }
-
- postReceiveResponseEvent();
-}
-
-void ARTSPConnection::flushPendingRequests() {
- for (size_t i = 0; i < mPendingRequests.size(); ++i) {
- sp<AMessage> reply = mPendingRequests.valueAt(i);
-
- reply->setInt32("result", -ECONNABORTED);
- reply->post();
- }
-
- mPendingRequests.clear();
-}
-
-void ARTSPConnection::postReceiveResponseEvent() {
- if (mReceiveResponseEventPending) {
- return;
- }
-
- sp<AMessage> msg = new AMessage(kWhatReceiveResponse, id());
- msg->post();
-
- mReceiveResponseEventPending = true;
-}
-
-status_t ARTSPConnection::receive(void *data, size_t size) {
- size_t offset = 0;
- while (offset < size) {
- ssize_t n = PR_Recv(mSocket, (uint8_t *)data + offset, size - offset,
- 0, PR_SecondsToInterval(kSocketBlokingRecvTimeout));
-
- PRErrorCode errCode = PR_GetError();
- if (n < 0 && errCode == PR_PENDING_INTERRUPT_ERROR) {
- continue;
- }
-
- if (n <= 0) {
- performDisconnect();
-
- if (n == 0) {
- // Server closed the connection.
- LOGE("Server unexpectedly closed the connection.");
- return ERROR_IO;
- } else {
- LOGE("Error reading rtsp response. (%d)", errCode);
- return -errCode;
- }
- }
-
- offset += (size_t)n;
- }
-
- return OK;
-}
-
-bool ARTSPConnection::receiveLine(AString *line) {
- line->clear();
-
- bool sawCR = false;
- for (;;) {
- char c;
- if (receive(&c, 1) != OK) {
- return false;
- }
-
- if (sawCR && c == '\n') {
- line->erase(line->size() - 1, 1);
- return true;
- }
-
- line->append(&c, 1);
-
- if (c == '$' && line->size() == 1) {
- // Special-case for interleaved binary data.
- return true;
- }
-
- sawCR = (c == '\r');
- }
-}
-
-sp<ABuffer> ARTSPConnection::receiveBinaryData() {
- uint8_t x[3];
- if (receive(x, 3) != OK) {
- return NULL;
- }
-
- sp<ABuffer> buffer = new ABuffer((x[1] << 8) | x[2]);
- if (receive(buffer->data(), buffer->size()) != OK) {
- return NULL;
- }
-
- buffer->meta()->setInt32("index", (int32_t)x[0]);
-
- return buffer;
-}
-
-static bool IsRTSPVersion(const AString &s) {
- return s == "RTSP/1.0";
-}
-
-bool ARTSPConnection::receiveRTSPResponse() {
- AString statusLine;
-
- if (!receiveLine(&statusLine)) {
- return false;
- }
-
- if (statusLine == "$") {
- sp<ABuffer> buffer = receiveBinaryData();
-
- if (buffer == NULL) {
- return false;
- }
-
- if (mObserveBinaryMessage != NULL) {
- sp<AMessage> notify = mObserveBinaryMessage->dup();
- notify->setObject("buffer", buffer);
- notify->post();
- } else {
- LOGW("received binary data, but no one cares.");
- }
-
- return true;
- }
-
- /*
- * Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
- */
- sp<ARTSPResponse> response = new ARTSPResponse;
- response->mStatusLine = statusLine;
-
- LOGI("status: %s", response->mStatusLine.c_str());
-
- ssize_t space1 = response->mStatusLine.find(" ");
- if (space1 < 0) {
- return false;
- }
- ssize_t space2 = response->mStatusLine.find(" ", space1 + 1);
- if (space2 < 0) {
- return false;
- }
-
- bool isRequest = false;
-
- if (!IsRTSPVersion(AString(response->mStatusLine, 0, space1))) {
- /*
- * Request-Line = Method SP Request-URI SP RTSP-Version CRLF
- */
- if (!IsRTSPVersion(AString(response->mStatusLine, space2 + 1,
- response->mStatusLine.size() - space2 - 1))) {
- /* Neither an RTSP response or request */
- return false;
- }
-
- isRequest = true;
- response->mStatusCode = 0;
- } else {
- AString statusCodeStr(
- response->mStatusLine, space1 + 1, space2 - space1 - 1);
-
- if (!ParseSingleUnsignedLong(
- statusCodeStr.c_str(), &response->mStatusCode)
- || response->mStatusCode < 100 || response->mStatusCode > 999) {
- return false;
- }
- }
-
- AString line;
- ssize_t lastDictIndex = -1;
- for (;;) {
- if (!receiveLine(&line)) {
- break;
- }
-
- if (line.empty()) {
- break;
- }
-
- LOGV("line: '%s'", line.c_str());
-
- if (line.c_str()[0] == ' ' || line.c_str()[0] == '\t') {
- // Support for folded header values.
-
- if (lastDictIndex < 0) {
- // First line cannot be a continuation of the previous one.
- return false;
- }
-
- AString &value = response->mHeaders.editValueAt(lastDictIndex);
- value.append(line);
-
- continue;
- }
-
- ssize_t colonPos = line.find(":");
- if (colonPos < 0) {
- // Malformed header line.
- return false;
- }
-
- AString key(line, 0, colonPos);
- key.trim();
- key.tolower();
-
- line.erase(0, colonPos + 1);
-
- lastDictIndex = response->mHeaders.add(key, line);
- }
-
- for (size_t i = 0; i < response->mHeaders.size(); ++i) {
- response->mHeaders.editValueAt(i).trim();
- }
-
- unsigned long contentLength = 0;
-
- ssize_t i = response->mHeaders.indexOfKey("content-length");
-
- if (i >= 0) {
- AString value = response->mHeaders.valueAt(i);
- if (!ParseSingleUnsignedLong(value.c_str(), &contentLength)) {
- return false;
- }
- }
-
- if (contentLength > 0) {
- response->mContent = new ABuffer(contentLength);
-
- if (receive(response->mContent->data(), contentLength) != OK) {
- return false;
- }
- }
-
- if (response->mStatusCode == 401) {
- if (mAuthType == NONE && mUser.size() > 0
- && parseAuthMethod(response)) {
- ssize_t i;
- if ((status_t)OK != findPendingRequest(response, &i) || i < 0) {
- return false;
- }
-
- sp<AMessage> reply = mPendingRequests.valueAt(i);
- mPendingRequests.removeItemsAt(i);
-
- AString request;
- CHECK(reply->findString("original-request", &request));
-
- sp<AMessage> msg = new AMessage(kWhatSendRequest, id());
- msg->setMessage("reply", reply);
- msg->setString("request", request.c_str(), request.size());
-
- LOGI("re-sending request with authentication headers...");
- onSendRequest(msg);
-
- return true;
- }
- }
-
- return isRequest
- ? handleServerRequest(response)
- : notifyResponseListener(response);
-}
-
-bool ARTSPConnection::handleServerRequest(const sp<ARTSPResponse> &request) {
- // Implementation of server->client requests is optional for all methods
- // but we do need to respond, even if it's just to say that we don't
- // support the method.
-
- ssize_t space1 = request->mStatusLine.find(" ");
- if (space1 < 0) {
- return false;
- }
-
- AString response;
- response.append("RTSP/1.0 501 Not Implemented\r\n");
-
- ssize_t i = request->mHeaders.indexOfKey("cseq");
-
- if (i >= 0) {
- AString value = request->mHeaders.valueAt(i);
-
- unsigned long cseq;
- if (!ParseSingleUnsignedLong(value.c_str(), &cseq)) {
- return false;
- }
-
- response.append("CSeq: ");
- response.append(cseq);
- response.append("\r\n");
- }
-
- response.append("\r\n");
-
- size_t numBytesSent = 0;
- while (numBytesSent < response.size()) {
- ssize_t n =
- PR_Send(mSocket, response.c_str() + numBytesSent,
- response.size() - numBytesSent, 0, PR_INTERVAL_NO_WAIT);
-
- PRErrorCode errCode = PR_GetError();
- if (n < 0 && errCode == PR_PENDING_INTERRUPT_ERROR) {
- continue;
- }
-
- if (n <= 0) {
- if (n == 0) {
- // Server closed the connection.
- LOGE("Server unexpectedly closed the connection.");
- } else {
- LOGE("Error sending rtsp response. (%d)", errCode);
- }
-
- performDisconnect();
-
- return false;
- }
-
- numBytesSent += (size_t)n;
- }
-
- return true;
-}
-
-// static
-bool ARTSPConnection::ParseSingleUnsignedLong(
- const char *from, unsigned long *x) {
- char *end;
- *x = strtoul(from, &end, 10);
-
- if (end == from || *end != '\0') {
- return false;
- }
-
- return true;
-}
-
-status_t ARTSPConnection::findPendingRequest(
- const sp<ARTSPResponse> &response, ssize_t *index) const {
- *index = 0;
-
- ssize_t i = response->mHeaders.indexOfKey("cseq");
-
- if (i < 0) {
- // This is an unsolicited server->client message.
- return OK;
- }
-
- AString value = response->mHeaders.valueAt(i);
-
- unsigned long cseq;
- if (!ParseSingleUnsignedLong(value.c_str(), &cseq)) {
- return ERROR_MALFORMED;
- }
-
- i = mPendingRequests.indexOfKey(cseq);
-
- if (i < 0) {
- return -ENOENT;
- }
-
- *index = i;
-
- return OK;
-}
-
-bool ARTSPConnection::notifyResponseListener(
- const sp<ARTSPResponse> &response) {
- ssize_t i;
- status_t err = findPendingRequest(response, &i);
-
- if (err == OK && i < 0) {
- // An unsolicited server response is not a problem.
- return true;
- }
-
- if (err != OK) {
- return false;
- }
-
- sp<AMessage> reply = mPendingRequests.valueAt(i);
- mPendingRequests.removeItemsAt(i);
-
- reply->setInt32("result", OK);
- reply->setObject("response", response);
- reply->post();
-
- return true;
-}
-
-bool ARTSPConnection::parseAuthMethod(const sp<ARTSPResponse> &response) {
- ssize_t i = response->mHeaders.indexOfKey("www-authenticate");
-
- if (i < 0) {
- return false;
- }
-
- AString value = response->mHeaders.valueAt(i);
-
- if (!strncmp(value.c_str(), "Basic", 5)) {
- mAuthType = BASIC;
- } else {
- if (strncmp(value.c_str(), "Digest", 6)) {
- return false;
- }
- mAuthType = DIGEST;
-
- i = value.find("nonce=");
- if (i < 0 || value.c_str()[i + 6] != '\"') {
- return false;
- }
- ssize_t j = value.find("\"", i + 7);
- if (j < 0) {
- return false;
- }
-
- mNonce.setTo(value, i + 7, j - i - 7);
- }
-
- return true;
-}
-
-static void H(const AString &s, AString *out) {
- nsresult rv;
- nsCOMPtr<nsICryptoHash> cryptoHash;
-
- out->clear();
-
- cryptoHash = do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv);
- if (NS_FAILED(rv)) {
- LOGE(("Failed to create crypto hash."));
- return;
- }
- rv = cryptoHash->Init(nsICryptoHash::MD5);
- if (NS_FAILED(rv)) {
- LOGE(("Failed to init md5 hash."));
- return;
- }
-
- rv = cryptoHash->Update((unsigned char*)s.c_str(), s.size());
- if (NS_FAILED(rv)) {
- LOGE(("Failed to update md5 hash."));
- return;
- }
-
- nsAutoCString hashString;
- rv = cryptoHash->Finish(false, hashString);
- if (NS_FAILED(rv)) {
- LOGE(("Failed to finish md5 hash."));
- return;
- }
-
- const uint8_t kHashKeyLength = 16;
- if (hashString.Length() != kHashKeyLength) {
- LOGE(("Invalid hash key length."));
- return;
- }
-
- const char *key;
- hashString.GetData(&key);
-
- for (size_t i = 0; i < 16; ++i) {
- char nibble = key[i] >> 4;
- if (nibble <= 9) {
- nibble += '0';
- } else {
- nibble += 'a' - 10;
- }
- out->append(&nibble, 1);
-
- nibble = key[i] & 0x0f;
- if (nibble <= 9) {
- nibble += '0';
- } else {
- nibble += 'a' - 10;
- }
- out->append(&nibble, 1);
- }
-}
-
-static bool GetMethodAndURL(
- const AString &request, AString *method, AString *url) {
- ssize_t space1 = request.find(" ");
- if (space1 < 0) {
- return false;
- }
-
- ssize_t space2 = request.find(" ", space1 + 1);
- if (space2 < 0) {
- return false;
- }
-
- method->setTo(request, 0, space1);
- url->setTo(request, space1 + 1, space2 - space1);
- return true;
-}
-
-void ARTSPConnection::addAuthentication(AString *request) {
- if (mAuthType == NONE) {
- return;
- }
-
- // Find the boundary between headers and the body.
- ssize_t i = request->find("\r\n\r\n");
- if (i < 0) {
- LOGE("Failed to find the boundary between headers and the body");
- return;
- }
-
- if (mAuthType == BASIC) {
- AString tmp;
- tmp.append(mUser);
- tmp.append(":");
- tmp.append(mPass);
-
- AString out;
- encodeBase64(tmp.c_str(), tmp.size(), &out);
-
- AString fragment;
- fragment.append("Authorization: Basic ");
- fragment.append(out);
- fragment.append("\r\n");
-
- request->insert(fragment, i + 2);
-
- return;
- }
-
- CHECK_EQ((int)mAuthType, (int)DIGEST);
-
- AString method, url;
- if (!GetMethodAndURL(*request, &method, &url)) {
- LOGE("Fail to get method and url");
- return;
- }
-
- AString A1;
- A1.append(mUser);
- A1.append(":");
- A1.append("Streaming Server");
- A1.append(":");
- A1.append(mPass);
-
- AString A2;
- A2.append(method);
- A2.append(":");
- A2.append(url);
-
- AString HA1, HA2;
- H(A1, &HA1);
- H(A2, &HA2);
-
- AString tmp;
- tmp.append(HA1);
- tmp.append(":");
- tmp.append(mNonce);
- tmp.append(":");
- tmp.append(HA2);
-
- AString digest;
- H(tmp, &digest);
-
- AString fragment;
- fragment.append("Authorization: Digest ");
- fragment.append("nonce=\"");
- fragment.append(mNonce);
- fragment.append("\", ");
- fragment.append("username=\"");
- fragment.append(mUser);
- fragment.append("\", ");
- fragment.append("uri=\"");
- fragment.append(url);
- fragment.append("\", ");
- fragment.append("response=\"");
- fragment.append(digest);
- fragment.append("\"");
- fragment.append("\r\n");
-
- request->insert(fragment, i + 2);
-}
-
-void ARTSPConnection::addUserAgent(AString *request) const {
- // Find the boundary between headers and the body.
- ssize_t i = request->find("\r\n\r\n");
- if (i < 0) {
- LOGE("Failed to find the boundary between headers and the body");
- }
-
- request->insert(mUserAgent, i + 2);
-}
-
-void ARTSPConnection::closeSocket() {
- PR_Close(mSocket);
- mSocket = nullptr;
-}
-
-} // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTSPConnection.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_RTSP_CONNECTION_H_
-
-#define A_RTSP_CONNECTION_H_
-
-#include "mozilla/Types.h"
-#include <media/stagefright/foundation/AHandler.h>
-#include <media/stagefright/foundation/AString.h>
-
-#include "prio.h"
-
-namespace android {
-
-struct MOZ_EXPORT ABuffer;
-
-struct ARTSPResponse : public RefBase {
- unsigned long mStatusCode;
- AString mStatusLine;
- KeyedVector<AString,AString> mHeaders;
- sp<ABuffer> mContent;
-};
-
-struct ARTSPConnection : public AHandler {
- ARTSPConnection(bool uidValid = false, uid_t uid = 0);
-
- void connect(const char *url, const sp<AMessage> &reply);
- void disconnect(const sp<AMessage> &reply);
-
- void sendRequest(const char *request, const sp<AMessage> &reply);
-
- void observeBinaryData(const sp<AMessage> &reply);
-
- static bool ParseURL(
- const char *url, AString *host, uint16_t *port, AString *path,
- AString *user, AString *pass);
- void MakeUserAgent(const char *userAgent);
-
-protected:
- virtual ~ARTSPConnection();
- virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
- enum State {
- DISCONNECTED,
- CONNECTING,
- CONNECTED,
- };
-
- enum {
- kWhatConnect = 1,
- kWhatDisconnect,
- kWhatCompleteConnection,
- kWhatSendRequest,
- kWhatReceiveResponse,
- kWhatObserveBinaryData,
- };
-
- enum AuthType {
- NONE,
- BASIC,
- DIGEST
- };
-
- static const uint32_t kSocketPollTimeoutUs;
- static const uint32_t kSocketPollTimeoutRetries;
- static const uint32_t kSocketBlokingRecvTimeout;
-
- bool mUIDValid;
- uid_t mUID;
- State mState;
- AString mUser, mPass;
- AuthType mAuthType;
- AString mNonce;
- int32_t mConnectionID;
- int32_t mNextCSeq;
- bool mReceiveResponseEventPending;
- PRFileDesc *mSocket;
- uint32_t mNumSocketPollTimeoutRetries;
-
- KeyedVector<int32_t, sp<AMessage> > mPendingRequests;
-
- sp<AMessage> mObserveBinaryMessage;
-
- AString mUserAgent;
-
- void performDisconnect();
-
- void onConnect(const sp<AMessage> &msg);
- void onDisconnect(const sp<AMessage> &msg);
- void onCompleteConnection(const sp<AMessage> &msg);
- void onSendRequest(const sp<AMessage> &msg);
- void onReceiveResponse();
-
- void flushPendingRequests();
- void postReceiveResponseEvent();
-
- // Return false iff something went unrecoverably wrong.
- bool receiveRTSPResponse();
- status_t receive(void *data, size_t size);
- bool receiveLine(AString *line);
- sp<ABuffer> receiveBinaryData();
- bool notifyResponseListener(const sp<ARTSPResponse> &response);
-
- bool parseAuthMethod(const sp<ARTSPResponse> &response);
- void addAuthentication(AString *request);
-
- void addUserAgent(AString *request) const;
-
- status_t findPendingRequest(
- const sp<ARTSPResponse> &response, ssize_t *index) const;
-
- bool handleServerRequest(const sp<ARTSPResponse> &request);
-
- static bool ParseSingleUnsignedLong(
- const char *from, unsigned long *x);
-
- void closeSocket();
-
- DISALLOW_EVIL_CONSTRUCTORS(ARTSPConnection);
-};
-
-} // namespace android
-
-#endif // A_RTSP_CONNECTION_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARawAudioAssembler.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ARawAudioAssembler"
-#include "RtspPrlog.h"
-
-#include "ARawAudioAssembler.h"
-
-#include "ARTPSource.h"
-#include "ASessionDescription.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/Utils.h>
-
-namespace android {
-
-ARawAudioAssembler::ARawAudioAssembler(
- const sp<AMessage> ¬ify, const char *desc, const AString ¶ms)
- : mNotifyMsg(notify),
- mNextExpectedSeqNoValid(false),
- mNextExpectedSeqNo(0) {
-}
-
-ARawAudioAssembler::~ARawAudioAssembler() {
-}
-
-ARTPAssembler::AssemblyStatus ARawAudioAssembler::assembleMore(
- const sp<ARTPSource> &source) {
- return addPacket(source);
-}
-
-ARTPAssembler::AssemblyStatus ARawAudioAssembler::addPacket(
- const sp<ARTPSource> &source) {
- List<sp<ABuffer> > *queue = source->queue();
-
- if (queue->empty()) {
- return NOT_ENOUGH_DATA;
- }
-
- if (mNextExpectedSeqNoValid) {
- List<sp<ABuffer> >::iterator it = queue->begin();
- while (it != queue->end()) {
- if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
- break;
- }
-
- it = queue->erase(it);
- }
-
- if (queue->empty()) {
- return NOT_ENOUGH_DATA;
- }
- }
-
- sp<ABuffer> buffer = *queue->begin();
-
- if (!mNextExpectedSeqNoValid) {
- mNextExpectedSeqNoValid = true;
- mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
- } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
- LOGV("Not the sequence number I expected");
-
- return WRONG_SEQUENCE_NUMBER;
- }
-
- // hexdump(buffer->data(), buffer->size());
-
- if (buffer->size() < 1) {
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- LOGW("raw audio packet too short.");
-
- return MALFORMED_PACKET;
- }
-
- sp<AMessage> msg = mNotifyMsg->dup();
- msg->setObject("access-unit", buffer);
- msg->post();
-
- queue->erase(queue->begin());
- ++mNextExpectedSeqNo;
-
- return OK;
-}
-
-void ARawAudioAssembler::packetLost() {
- CHECK(mNextExpectedSeqNoValid);
- ++mNextExpectedSeqNo;
-}
-
-void ARawAudioAssembler::onByeReceived() {
- sp<AMessage> msg = mNotifyMsg->dup();
- msg->setInt32("eos", true);
- msg->post();
-}
-
-// static
-bool ARawAudioAssembler::Supports(const char *desc) {
- return !strncmp(desc, "PCMU/", 5)
- || !strncmp(desc, "PCMA/", 5);
-}
-
-// static
-bool ARawAudioAssembler::MakeFormat(
- const char *desc, const sp<MetaData> &format) {
- if (!strncmp(desc, "PCMU/", 5)) {
- format->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_MLAW);
- } else if (!strncmp(desc, "PCMA/", 5)) {
- format->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW);
- } else {
- return false;
- }
-
- int32_t sampleRate, numChannels;
- if (!ASessionDescription::ParseFormatDesc(
- desc, &sampleRate, &numChannels)) {
- return false;
- }
-
- format->setInt32(kKeySampleRate, sampleRate);
- format->setInt32(kKeyChannelCount, numChannels);
- return true;
-}
-
-} // namespace android
-
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARawAudioAssembler.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_RAW_AUDIO_ASSEMBLER_H_
-
-#define A_RAW_AUDIO_ASSEMBLER_H_
-
-#include "mozilla/Types.h"
-#include "ARTPAssembler.h"
-
-namespace android {
-
-struct AMessage;
-struct MOZ_EXPORT AString;
-struct MOZ_EXPORT MetaData;
-
-struct ARawAudioAssembler : public ARTPAssembler {
- ARawAudioAssembler(
- const sp<AMessage> ¬ify,
- const char *desc, const AString ¶ms);
-
- static bool Supports(const char *desc);
-
- static bool MakeFormat(
- const char *desc, const sp<MetaData> &format);
-
-protected:
- virtual ~ARawAudioAssembler();
-
- virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source);
- virtual void onByeReceived();
- virtual void packetLost();
-
-private:
- bool mIsWide;
-
- sp<AMessage> mNotifyMsg;
- bool mNextExpectedSeqNoValid;
- uint32_t mNextExpectedSeqNo;
-
- AssemblyStatus addPacket(const sp<ARTPSource> &source);
-
- DISALLOW_EVIL_CONSTRUCTORS(ARawAudioAssembler);
-};
-
-} // namespace android
-
-#endif // A_RAW_AUDIO_ASSEMBLER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ASessionDescription.cpp
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ASessionDescription"
-#include "RtspPrlog.h"
-
-#include "ASessionDescription.h"
-
-#include "mozilla/Sprintf.h"
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AString.h>
-
-#include <stdlib.h>
-
-namespace android {
-
-ASessionDescription::ASessionDescription()
- : mIsValid(false) {
-}
-
-ASessionDescription::~ASessionDescription() {
-}
-
-bool ASessionDescription::setTo(const void *data, size_t size) {
- mIsValid = parse(data, size);
-
- if (!mIsValid) {
- mTracks.clear();
- mFormats.clear();
- }
-
- return mIsValid;
-}
-
-bool ASessionDescription::parse(const void *data, size_t size) {
- mTracks.clear();
- mFormats.clear();
-
- mTracks.push(Attribs());
- mFormats.push(AString("[root]"));
-
- AString desc((const char *)data, size);
-
- size_t i = 0;
- for (;;) {
- ssize_t eolPos = desc.find("\n", i);
-
- if (eolPos < 0) {
- break;
- }
-
- AString line;
- if ((size_t)eolPos > i && desc.c_str()[eolPos - 1] == '\r') {
- // We accept both '\n' and '\r\n' line endings, if it's
- // the latter, strip the '\r' as well.
- line.setTo(desc, i, eolPos - i - 1);
- } else {
- line.setTo(desc, i, eolPos - i);
- }
-
- if (line.empty()) {
- i = eolPos + 1;
- continue;
- }
-
- if (line.size() < 2 || line.c_str()[1] != '=') {
- return false;
- }
-
- LOGI("%s", line.c_str());
-
- switch (line.c_str()[0]) {
- case 'v':
- {
- if (strcmp(line.c_str(), "v=0")) {
- return false;
- }
- break;
- }
-
- case 'a':
- case 'b':
- {
- AString key, value;
-
- ssize_t colonPos = line.find(":", 2);
- if (colonPos < 0) {
- key = line;
- } else {
- key.setTo(line, 0, colonPos);
-
- if (key == "a=fmtp" || key == "a=rtpmap"
- || key == "a=framesize") {
- ssize_t spacePos = line.find(" ", colonPos + 1);
- if (spacePos < 0) {
- return false;
- }
-
- key.setTo(line, 0, spacePos);
-
- colonPos = spacePos;
- }
-
- value.setTo(line, colonPos + 1, line.size() - colonPos - 1);
- }
-
- key.trim();
- value.trim();
-
- LOGV("adding '%s' => '%s'", key.c_str(), value.c_str());
-
- mTracks.editItemAt(mTracks.size() - 1).add(key, value);
- break;
- }
-
- case 'm':
- {
- LOGV("new section '%s'",
- AString(line, 2, line.size() - 2).c_str());
-
- mTracks.push(Attribs());
- mFormats.push(AString(line, 2, line.size() - 2));
- break;
- }
-
- default:
- {
- AString key, value;
-
- ssize_t equalPos = line.find("=");
-
- key = AString(line, 0, equalPos + 1);
- value = AString(line, equalPos + 1, line.size() - equalPos - 1);
-
- key.trim();
- value.trim();
-
- LOGV("adding '%s' => '%s'", key.c_str(), value.c_str());
-
- mTracks.editItemAt(mTracks.size() - 1).add(key, value);
- break;
- }
- }
-
- i = eolPos + 1;
- }
-
- return true;
-}
-
-bool ASessionDescription::isValid() const {
- return mIsValid;
-}
-
-size_t ASessionDescription::countTracks() const {
- return mTracks.size();
-}
-
-void ASessionDescription::getFormat(size_t index, AString *value) const {
- CHECK_GE(index, 0u);
- CHECK_LT(index, mTracks.size());
-
- *value = mFormats.itemAt(index);
-}
-
-bool ASessionDescription::findAttribute(
- size_t index, const char *key, AString *value) const {
- CHECK_GE(index, 0u);
- CHECK_LT(index, mTracks.size());
-
- value->clear();
-
- const Attribs &track = mTracks.itemAt(index);
- ssize_t i = track.indexOfKey(AString(key));
-
- if (i < 0) {
- return false;
- }
-
- *value = track.valueAt(i);
-
- return true;
-}
-
-bool ASessionDescription::getFormatType(
- size_t index, unsigned long *PT,
- AString *desc, AString *params) const {
- AString format;
- getFormat(index, &format);
-
- const char *lastSpacePos = strrchr(format.c_str(), ' ');
- if (!lastSpacePos) {
- return false;
- }
-
- char *end;
- unsigned long x = strtoul(lastSpacePos + 1, &end, 10);
- if (end <= lastSpacePos + 1 || *end != '\0') {
- return false;
- }
-
- *PT = x;
-
- char key[20];
- SprintfLiteral(key, "a=rtpmap:%lu", x);
-
- if (!findAttribute(index, key, desc)) {
- // We only support dynamic payload type assignment for now.
- // If SDP description doesn't have the "a=rtpmap:" line, it is static
- // payload type assignment and we refuse to handle it.
- return false;
- }
-
- SprintfLiteral(key, "a=fmtp:%lu", x);
- if (!findAttribute(index, key, params)) {
- params->clear();
- }
-
- return true;
-}
-
-bool ASessionDescription::getDimensions(
- size_t index, unsigned long PT,
- int32_t *width, int32_t *height) const {
- *width = 0;
- *height = 0;
-
- char key[20];
- SprintfLiteral(key, "a=framesize:%lu", PT);
- AString value;
- if (!findAttribute(index, key, &value)) {
- return false;
- }
-
- const char *s = value.c_str();
- char *end;
- *width = strtoul(s, &end, 10);
- if (end <= s || *end != '-') {
- return false;
- }
-
- s = end + 1;
- *height = strtoul(s, &end, 10);
- if (end <= s || *end != '\0') {
- return false;
- }
-
- return true;
-}
-
-bool ASessionDescription::getDurationUs(int64_t *durationUs) const {
- *durationUs = 0;
-
- if (!mIsValid) {
- return false;
- }
-
- AString value;
- if (!findAttribute(0, "a=range", &value)) {
- return false;
- }
-
- if (strncmp(value.c_str(), "npt=", 4)) {
- return false;
- }
-
- float from, to;
- if (!parseNTPRange(value.c_str() + 4, &from, &to)) {
- return false;
- }
-
- *durationUs = (int64_t)((to - from) * 1E6);
-
- return true;
-}
-
-// static
-bool ASessionDescription::ParseFormatDesc(
- const char *desc, int32_t *timescale, int32_t *numChannels) {
- const char *slash1 = strchr(desc, '/');
- if (!slash1) {
- return false;
- }
-
- const char *s = slash1 + 1;
- char *end;
- unsigned long x = strtoul(s, &end, 10);
- if (end <= s) {
- return false;
- }
- if (*end != '\0' && *end != '/') {
- return false;
- }
-
- *timescale = x;
- *numChannels = 1;
-
- if (*end == '/') {
- s = end + 1;
- unsigned long x = strtoul(s, &end, 10);
- if (end <= s || *end != '\0') {
- return false;
- }
-
- *numChannels = x;
- }
- return true;
-}
-
-// static
-bool ASessionDescription::parseNTPRange(
- const char *s, float *npt1, float *npt2) {
- if (s[0] == '-') {
- return false; // no start time available.
- }
-
- if (!strncmp("now", s, 3)) {
- return false; // no absolute start time available
- }
-
- char *end;
- *npt1 = strtof(s, &end);
-
- if (end == s || *end != '-') {
- // Failed to parse float or trailing "dash".
- return false;
- }
-
- s = end + 1; // skip the dash.
-
- if (!strncmp("now", s, 3)) {
- return false; // no absolute end time available
- }
-
- *npt2 = strtof(s, &end);
-
- if (end == s) {
- // No end time available. It means to play until the end of the clip.
- return true;
- }
-
- if (*end != '\0') {
- // Malformed format in NTP description.
- return false;
- }
-
- return *npt2 > *npt1;
-}
-
-} // namespace android
-
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ASessionDescription.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_SESSION_DESCRIPTION_H_
-
-#define A_SESSION_DESCRIPTION_H_
-
-#include "mozilla/Types.h"
-#include <sys/types.h>
-
-#include <media/stagefright/foundation/ABase.h>
-#include <utils/KeyedVector.h>
-#include <utils/RefBase.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-struct MOZ_EXPORT AString;
-
-struct ASessionDescription : public RefBase {
- ASessionDescription();
-
- bool setTo(const void *data, size_t size);
- bool isValid() const;
-
- // Actually, 1 + number of tracks, as index 0 is reserved for the
- // session description root-level attributes.
- size_t countTracks() const;
- void getFormat(size_t index, AString *value) const;
-
- bool getFormatType(
- size_t index, unsigned long *PT,
- AString *desc, AString *params) const;
-
- bool getDimensions(
- size_t index, unsigned long PT,
- int32_t *width, int32_t *height) const;
-
- bool getDurationUs(int64_t *durationUs) const;
-
- static bool ParseFormatDesc(
- const char *desc, int32_t *timescale, int32_t *numChannels);
-
- bool findAttribute(size_t index, const char *key, AString *value) const;
-
- // parses strings of the form
- // npt := npt-time "-" npt-time? | "-" npt-time
- // npt-time := "now" | [0-9]+("." [0-9]*)?
- //
- // Returns true iff both "npt1" and "npt2" times were available,
- // i.e. we have a fixed duration, otherwise this is live streaming.
- static bool parseNTPRange(const char *s, float *npt1, float *npt2);
-
-protected:
- virtual ~ASessionDescription();
-
-private:
- typedef KeyedVector<AString,AString> Attribs;
-
- bool mIsValid;
- Vector<Attribs> mTracks;
- Vector<AString> mFormats;
-
- bool parse(const void *data, size_t size);
-
- DISALLOW_EVIL_CONSTRUCTORS(ASessionDescription);
-};
-
-} // namespace android
-
-#endif // A_SESSION_DESCRIPTION_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/RTSPConnectionHandler.h
+++ /dev/null
@@ -1,1815 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef RTSP_CONNECTION_HANDLER_H_
-#define RTSP_CONNECTION_HANDLER_H_
-
-#include "APacketSource.h"
-#include "ARTPConnection.h"
-#include "ARTSPConnection.h"
-#include "ASessionDescription.h"
-
-#include "RtspPrlog.h"
-
-#include "nsIOService.h"
-
-#include <ctype.h>
-#include <cutils/properties.h>
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/MediaErrors.h>
-
-#include <arpa/inet.h>
-#include <netdb.h>
-#include "nsPrintfCString.h"
-
-#include "mozilla/Logging.h"
-
-#include "prio.h"
-#include "prnetdb.h"
-
-namespace mozilla {
-namespace net {
-extern LazyLogModule gRtspLog;
-}
-}
-
-// If no access units are received within 10 secs, assume that the rtp
-// stream has ended and abort.
-static int64_t kAccessUnitTimeoutUs = 10000000ll;
-
-// The end-of-stream timer will be running in the last 2 seconds of duration.
-static int64_t kActivateEndOfStreamTimerUs = 2000000ll;
-
-// The end-of-stream timer will timeout in 2 seconds.
-static int64_t kEndOfStreamTimeoutUs = 2000000ll;
-
-// If no access units arrive for the first 10 secs after starting the
-// stream, assume none ever will and signal EOS or switch transports.
-static int64_t kPlayTimeoutUs = 10000000ll;
-
-static int64_t kDefaultKeepAliveTimeoutUs = 60000000ll;
-
-namespace android {
-
-static bool GetAttribute(const char *s, const char *key, AString *value) {
- value->clear();
-
- size_t keyLen = strlen(key);
-
- for (;;) {
- while (isspace(*s)) {
- ++s;
- }
-
- const char *colonPos = strchr(s, ';');
-
- size_t len =
- (colonPos == NULL) ? strlen(s) : colonPos - s;
-
- if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
- value->setTo(&s[keyLen + 1], len - keyLen - 1);
- return true;
- }
-
- if (colonPos == NULL) {
- return false;
- }
-
- s = colonPos + 1;
- }
-}
-
-struct RtspConnectionHandler : public AHandler {
- enum {
- kWhatConnected = 1000,
- kWhatDisconnected,
- kWhatDescribe,
- kWhatSetup,
- kWhatPause,
- kWhatSeek,
- kWhatPlay,
- kWhatResume,
- kWhatKeepAlive,
- kWhatOptions,
- kWhatEndOfStream,
- kWhatAbort,
- kWhatTeardown,
- kWhatQuit,
- kWhatAccessUnitTimeoutCheck,
- kWhatEndOfStreamCheck,
- kWhatSeekDone,
- kWhatPausedDone,
- kWhatAccessUnitComplete,
- kWhatAccessUnit,
- kWhatSeek1,
- kWhatSeek2,
- kWhatBinary,
- kWhatTimeout,
- kWhatEOS,
- kWhatSeekDiscontinuity,
- kWhatNormalPlayTimeMapping,
- kWhatTryTCPInterleaving,
- };
-
- RtspConnectionHandler(
- const char *url,
- const char *userAgent,
- const sp<AMessage> ¬ify,
- bool uidValid = false, uid_t uid = 0)
- : mUserAgent(userAgent),
- mNotify(notify),
- mUIDValid(uidValid),
- mUID(uid),
- mNetLooper(new ALooper),
- mConn(new ARTSPConnection(mUIDValid, mUID)),
- mRTPConn(new ARTPConnection),
- mOriginalSessionURL(url),
- mSessionURL(url),
- mSetupTracksSuccessful(false),
- mSeekPending(false),
- mPausePending(false),
- mAborted(false),
- mFirstAccessUnit(true),
- mNTPAnchorUs(-1),
- mMediaAnchorUs(-1),
- mLastMediaTimeUs(0),
- mNumAccessUnitsReceived(0),
- mCheckPending(false),
- mCheckGeneration(0),
- mTryTCPInterleaving(false),
- mTryFakeRTCP(false),
- mReceivedFirstRTCPPacket(false),
- mReceivedFirstRTPPacket(false),
- mSeekable(false),
- mKeepAliveTimeoutUs(kDefaultKeepAliveTimeoutUs),
- mKeepAliveGeneration(0),
- mNumPlayTimeoutsPending(0) {
- mNetLooper->setName("rtsp net");
- mNetLooper->start(false /* runOnCallingThread */,
- false /* canCallJava */,
- PRIORITY_HIGHEST);
-
- // Strip any authentication info from the session url, we don't
- // want to transmit user/pass in cleartext.
- AString host, path, user, pass;
- uint16_t port;
- CHECK(ARTSPConnection::ParseURL(
- mSessionURL.c_str(), &host, &port, &path, &user, &pass));
-
- if (user.size() > 0) {
- mSessionURL.clear();
- mSessionURL.append("rtsp://");
- mSessionURL.append(host);
- mSessionURL.append(":");
- mSessionURL.append(StringPrintf("%u", port));
- mSessionURL.append(path);
-
- LOGI("rewritten session url: '%s'", mSessionURL.c_str());
- }
-
- mSessionHost = host;
- mConn->MakeUserAgent(mUserAgent.c_str());
- }
-
- void connect() {
- looper()->registerHandler(mConn);
- (1 ? mNetLooper : looper())->registerHandler(mRTPConn);
-
- sp<AMessage> notify = new AMessage(kWhatBinary, id());
- mConn->observeBinaryData(notify);
-
- sp<AMessage> reply = new AMessage(kWhatConnected, id());
- mConn->connect(mOriginalSessionURL.c_str(), reply);
- }
-
- void disconnect() {
- (new AMessage(kWhatAbort, id()))->post();
- }
-
- void seek(int64_t timeUs) {
- sp<AMessage> msg = new AMessage(kWhatSeek, id());
- msg->setInt64("time", timeUs);
- msg->post();
- }
-
- void setCheckPending(bool flag) {
- mCheckPending = flag;
- for (size_t i = 0; i < mTracks.size(); ++i) {
- setEndOfStreamCheckPending(i, flag);
- }
- }
-
- void setEndOfStreamCheckPending(size_t trackIndex, bool flag) {
- TrackInfo *info = &mTracks.editItemAt(trackIndex);
- if (info) {
- info->mCheckPendings = flag;
- }
- }
-
- bool getEndOfStreamCheckPending(size_t trackIndex) {
- TrackInfo *info = &mTracks.editItemAt(trackIndex);
- return info->mCheckPendings;
- }
-
- void play(uint64_t timeUs) {
- AString request = "PLAY ";
- request.append(mSessionURL);
- request.append(" RTSP/1.0\r\n");
-
- request.append("Session: ");
- request.append(mSessionID);
- request.append("\r\n");
-
- request.append(nsPrintfCString("Range: npt=%lld-\r\n", timeUs / 1000000ll).get());
- request.append("\r\n");
-
- setCheckPending(false);
-
- sp<AMessage> reply = new AMessage(kWhatPlay, id());
- mConn->sendRequest(request.c_str(), reply);
- }
-
- void pause() {
- if (!mSeekable) {
- return;
- }
- AString request = "PAUSE ";
- request.append(mSessionURL);
- request.append(" RTSP/1.0\r\n");
-
- request.append("Session: ");
- request.append(mSessionID);
- request.append("\r\n");
-
- request.append("\r\n");
- // Disable the access unit timeout until we resume
- // playback again.
- setCheckPending(true);
- ++mCheckGeneration;
-
- sp<AMessage> reply = new AMessage(kWhatPause, id());
- mConn->sendRequest(request.c_str(), reply);
- }
-
- void resume(uint64_t timeUs) {
- AString request = "PLAY ";
- request.append(mSessionURL);
- request.append(" RTSP/1.0\r\n");
-
- request.append("Session: ");
- request.append(mSessionID);
- request.append("\r\n");
-
- request.append(nsPrintfCString("Range: npt=%lld-\r\n", timeUs / 1000000ll).get());
- request.append("\r\n");
-
- setCheckPending(false);
-
- sp<AMessage> reply = new AMessage(kWhatResume, id());
- mConn->sendRequest(request.c_str(), reply);
-
- }
-
- static void addRR(const sp<ABuffer> &buf) {
- uint8_t *ptr = buf->data() + buf->size();
- ptr[0] = 0x80 | 0;
- ptr[1] = 201; // RR
- ptr[2] = 0;
- ptr[3] = 1;
- ptr[4] = 0xde; // SSRC
- ptr[5] = 0xad;
- ptr[6] = 0xbe;
- ptr[7] = 0xef;
-
- buf->setRange(0, buf->size() + 8);
- }
-
- static void addSDES(PRFileDesc *s, const sp<ABuffer> &buffer,
- const char *userAgent) {
- PRNetAddr addr;
- CHECK_EQ(PR_GetSockName(s, &addr), PR_SUCCESS);
-
- uint8_t *data = buffer->data() + buffer->size();
- data[0] = 0x80 | 1;
- data[1] = 202; // SDES
- data[4] = 0xde; // SSRC
- data[5] = 0xad;
- data[6] = 0xbe;
- data[7] = 0xef;
-
- size_t offset = 8;
-
- data[offset++] = 1; // CNAME
-
- AString cname = "stagefright@";
- char buf[64];
- PR_NetAddrToString(&addr, buf, sizeof(buf));
- cname.append(buf);
- data[offset++] = cname.size();
-
- memcpy(&data[offset], cname.c_str(), cname.size());
- offset += cname.size();
-
- data[offset++] = 6; // TOOL
-
- AString tool;
- tool.setTo(userAgent);
-
- data[offset++] = tool.size();
-
- memcpy(&data[offset], tool.c_str(), tool.size());
- offset += tool.size();
-
- data[offset++] = 0;
-
- if ((offset % 4) > 0) {
- size_t count = 4 - (offset % 4);
- switch (count) {
- case 3:
- data[offset++] = 0;
- case 2:
- data[offset++] = 0;
- case 1:
- data[offset++] = 0;
- }
- }
-
- size_t numWords = (offset / 4) - 1;
- data[2] = numWords >> 8;
- data[3] = numWords & 0xff;
-
- buffer->setRange(buffer->offset(), buffer->size() + offset);
- }
-
- // In case we're behind NAT, fire off two UDP packets to the remote
- // rtp/rtcp ports to poke a hole into the firewall for future incoming
- // packets. We're going to send an RR/SDES RTCP packet to both of them.
- bool pokeAHole(PRFileDesc *rtpSocket, PRFileDesc *rtcpSocket, const AString &transport) {
- PRNetAddr addr;
- addr.inet.family = PR_AF_INET;
-
- AString source;
- AString server_port;
- PRStatus status = PR_FAILURE;
- if (!GetAttribute(transport.c_str(),
- "source",
- &source)) {
- LOGW("Missing 'source' field in Transport response. Using "
- "RTSP endpoint address.");
-
- char buffer[PR_NETDB_BUF_SIZE];
- PRHostEnt hostentry;
- status = PR_GetHostByName(mSessionHost.c_str(),
- buffer, PR_NETDB_BUF_SIZE, &hostentry);
-
- if (status == PR_FAILURE) {
- LOGE("Failed to look up address of session host '%s'",
- mSessionHost.c_str());
-
- return false;
- }
-
- addr.inet.ip = *((uint32_t *) hostentry.h_addr_list[0]);
- } else {
- status = PR_StringToNetAddr(source.c_str(), &addr);
- }
-
- if (!GetAttribute(transport.c_str(),
- "server_port",
- &server_port)) {
- LOGI("Missing 'server_port' field in Transport response.");
- return false;
- }
-
- int rtpPort, rtcpPort;
- if (sscanf(server_port.c_str(), "%d-%d", &rtpPort, &rtcpPort) != 2
- || rtpPort <= 0 || rtpPort > 65535
- || rtcpPort <=0 || rtcpPort > 65535
- || rtcpPort != rtpPort + 1) {
- LOGE("Server picked invalid RTP/RTCP port pair %s,"
- " RTP port must be even, RTCP port must be one higher.",
- server_port.c_str());
-
- return false;
- }
-
- if (rtpPort & 1) {
- LOGW("Server picked an odd RTP port, it should've picked an "
- "even one, we'll let it pass for now, but this may break "
- "in the future.");
- }
-
- // Check if ip is vaild.
- if (status == PR_FAILURE) {
- return true;
- }
-
- if (addr.inet.ip == PR_htonl(PR_INADDR_LOOPBACK)) {
- // No firewalls to traverse on the loopback interface.
- return true;
- }
-
- // Make up an RR/SDES RTCP packet.
- sp<ABuffer> buf = new ABuffer(65536);
- buf->setRange(0, 0);
- addRR(buf);
- addSDES(rtpSocket, buf, mUserAgent.c_str());
-
- addr.inet.port = PR_htons(rtpPort);
-
- if (!rtpSocket) {
- return false;
- }
- ssize_t n = PR_SendTo(rtpSocket, buf->data(), buf->size(), 0, &addr,
- PR_INTERVAL_NO_WAIT);
-
- if (n < (ssize_t)buf->size()) {
- LOGE("failed to poke a hole for RTP packets");
- return false;
- }
-
- addr.inet.port = PR_htons(rtcpPort);
-
- if (!rtcpSocket) {
- return false;
- }
- n = PR_SendTo(rtcpSocket, buf->data(), buf->size(), 0,
- &addr, PR_INTERVAL_NO_WAIT);
-
- if (n < (ssize_t)buf->size()) {
- LOGE("failed to poke a hole for RTCP packets");
- return false;
- }
-
- LOGV("successfully poked holes.");
-
- return true;
- }
-
- virtual void onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatConnected:
- {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
- mAborted = false;
-
- LOGI("connection request completed with result %d (%s)",
- result, strerror(-result));
-
- if (result == OK) {
- AString request;
- request = "DESCRIBE ";
- request.append(mSessionURL);
- request.append(" RTSP/1.0\r\n");
- request.append("Accept: application/sdp\r\n");
- request.append("\r\n");
-
- sp<AMessage> reply = new AMessage(kWhatDescribe, id());
- mConn->sendRequest(request.c_str(), reply);
- } else {
- sp<AMessage> reply = new AMessage(kWhatDisconnected, id());
- reply->setInt32("result", result);
- mConn->disconnect(reply);
- }
- break;
- }
-
- case kWhatDisconnected:
- {
- ++mKeepAliveGeneration;
-
- int32_t reconnect;
- if (msg->findInt32("reconnect", &reconnect) && reconnect) {
- sp<AMessage> reply = new AMessage(kWhatConnected, id());
- mConn->connect(mOriginalSessionURL.c_str(), reply);
- } else {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
- sp<AMessage> reply = new AMessage(kWhatQuit, id());
- reply->setInt32("result", result);
- reply->post();
- }
- break;
- }
-
- case kWhatDescribe:
- {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
-
- LOGI("DESCRIBE completed with result %d (%s)",
- result, strerror(-result));
- if (mAborted) {
- LOGV("we're aborted, dropping stale packet.");
- break;
- }
-
- if (result == OK) {
- sp<RefBase> obj;
- CHECK(msg->findObject("response", &obj));
- sp<ARTSPResponse> response =
- static_cast<ARTSPResponse *>(obj.get());
-
- if (response->mStatusCode == 302) {
- ssize_t i = response->mHeaders.indexOfKey("location");
- CHECK_GE(i, 0);
-
- mSessionURL = response->mHeaders.valueAt(i);
-
- AString request;
- request = "DESCRIBE ";
- request.append(mSessionURL);
- request.append(" RTSP/1.0\r\n");
- request.append("Accept: application/sdp\r\n");
- request.append("\r\n");
-
- sp<AMessage> reply = new AMessage(kWhatDescribe, id());
- mConn->sendRequest(request.c_str(), reply);
- break;
- }
-
- if (response->mStatusCode != 200) {
- result = UNKNOWN_ERROR;
- } else {
- mSessionDesc = new ASessionDescription;
-
- mSessionDesc->setTo(
- response->mContent->data(),
- response->mContent->size());
-
- if (!mSessionDesc->isValid()) {
- LOGE("Failed to parse session description.");
- result = ERROR_MALFORMED;
- } else {
- ssize_t i = response->mHeaders.indexOfKey("content-base");
- if (i >= 0) {
- mBaseURL = response->mHeaders.valueAt(i);
- } else {
- i = response->mHeaders.indexOfKey("content-location");
- if (i >= 0) {
- mBaseURL = response->mHeaders.valueAt(i);
- } else {
- mBaseURL = mSessionURL;
- }
- }
-
- if (!mBaseURL.startsWith("rtsp://")) {
- // Some misbehaving servers specify a relative
- // URL in one of the locations above, combine
- // it with the absolute session URL to get
- // something usable...
-
- LOGW("Server specified a non-absolute base URL"
- ", combining it with the session URL to "
- "get something usable...");
-
- AString tmp;
- if (!MakeURL(
- mSessionURL.c_str(),
- mBaseURL.c_str(),
- &tmp)) {
- LOGE("Fail to make url");
- result = ERROR_UNSUPPORTED;
- }
-
- mBaseURL = tmp;
- }
-
- int64_t duration = 0;
- if (mSessionDesc->getDurationUs(&duration) > 0) {
- // This is not a live stream and therefore seekable.
- LOGI("This is not a live stream");
- mSeekable = true;
- } else {
- // This is a live stream.
- LOGI("This is a live stream");
- mSeekable = false;
- }
-
- if (mSessionDesc->countTracks() < 2) {
- // There's no actual tracks in this session.
- // The first "track" is merely session meta
- // data.
-
- LOGW("Session doesn't contain any playable "
- "tracks. Aborting.");
- result = ERROR_UNSUPPORTED;
- } else {
- setupTrack(1);
- }
- }
- }
- }
-
- if (result != OK) {
- sp<AMessage> reply = new AMessage(kWhatDisconnected, id());
- reply->setInt32("result", result);
- mConn->disconnect(reply);
- }
- break;
- }
-
- case kWhatSetup:
- {
- size_t index;
- CHECK(msg->findSize("index", &index));
-
- TrackInfo *track = NULL;
- size_t trackIndex;
- if (msg->findSize("track-index", &trackIndex)) {
- track = &mTracks.editItemAt(trackIndex);
- }
-
- int32_t result;
- CHECK(msg->findInt32("result", &result));
-
- LOGI("SETUP(%d) completed with result %d (%s)",
- index, result, strerror(-result));
- if (mAborted) {
- LOGV("we're aborted, dropping stale packet.");
- break;
- }
-
- if (result == OK) {
- CHECK(track != NULL);
-
- sp<RefBase> obj;
- CHECK(msg->findObject("response", &obj));
- sp<ARTSPResponse> response =
- static_cast<ARTSPResponse *>(obj.get());
-
- if (response->mStatusCode != 200) {
- result = UNKNOWN_ERROR;
- } else {
- ssize_t i = response->mHeaders.indexOfKey("session");
- CHECK_GE(i, 0);
-
- mSessionID = response->mHeaders.valueAt(i);
-
- mKeepAliveTimeoutUs = kDefaultKeepAliveTimeoutUs;
- AString timeoutStr;
- if (GetAttribute(
- mSessionID.c_str(), "timeout", &timeoutStr)) {
- char *end;
- unsigned long timeoutSecs =
- strtoul(timeoutStr.c_str(), &end, 10);
-
- if (end == timeoutStr.c_str() || *end != '\0') {
- LOGW("server specified malformed timeout '%s'",
- timeoutStr.c_str());
-
- mKeepAliveTimeoutUs = kDefaultKeepAliveTimeoutUs;
- } else if (timeoutSecs < 15) {
- LOGW("server specified too short a timeout "
- "(%lu secs), using default.",
- timeoutSecs);
-
- mKeepAliveTimeoutUs = kDefaultKeepAliveTimeoutUs;
- } else {
- mKeepAliveTimeoutUs = timeoutSecs * 1000000ll;
-
- LOGI("server specified timeout of %lu secs.",
- timeoutSecs);
- }
- }
-
- i = mSessionID.find(";");
- if (i >= 0) {
- // Remove options, i.e. ";timeout=90"
- mSessionID.erase(i, mSessionID.size() - i);
- }
-
- sp<AMessage> notify = new AMessage(kWhatAccessUnit, id());
- notify->setSize("track-index", trackIndex);
-
- i = response->mHeaders.indexOfKey("transport");
- CHECK_GE(i, 0);
-
- if (!track->mUsingInterleavedTCP) {
- AString transport = response->mHeaders.valueAt(i);
-
- // We are going to continue even if we were
- // unable to poke a hole into the firewall...
- pokeAHole(
- track->mRTPSocket,
- track->mRTCPSocket,
- transport);
- }
-
- mRTPConn->addStream(
- track->mRTPSocket, track->mRTCPSocket,
- track->mInterleavedRTPIdx, track->mInterleavedRTCPIdx,
- mSessionDesc, index,
- notify, track->mUsingInterleavedTCP);
-
- mSetupTracksSuccessful = true;
- }
- }
-
- if (result != OK) {
- if (track) {
- if (!track->mUsingInterleavedTCP) {
- if (track->mRTPSocket) {
- PR_Close(track->mRTPSocket);
- }
-
- if (track->mRTCPSocket) {
- PR_Close(track->mRTCPSocket);
- }
- }
-
- mTracks.removeItemsAt(trackIndex);
- }
- }
-
- ++index;
- if (index < mSessionDesc->countTracks()) {
- setupTrack(index);
- } else if (mSetupTracksSuccessful) {
- ++mKeepAliveGeneration;
- postKeepAlive();
- sp<AMessage> msg = mNotify->dup();
- if (mSeekable) {
- msg->setInt32("isSeekable", 1);
- } else {
- msg->setInt32("isSeekable", 0);
- }
- // Notify RTSPSource that we are ready to play.
- msg->setInt32("what", kWhatConnected);
- msg->post();
-
- // Notify RTSPSource that we are trying TCP interleaving and
- // ready to play again.
- if (mTryTCPInterleaving) {
- sp<AMessage> msgTryTcp = mNotify->dup();
- msgTryTcp->setInt32("what", kWhatTryTCPInterleaving);
- msgTryTcp->post();
- }
- } else {
- sp<AMessage> reply = new AMessage(kWhatDisconnected, id());
- reply->setInt32("result", result);
- mConn->disconnect(reply);
- }
- break;
- }
- case kWhatPause:
- {
- mPausePending = true;
- LOGI("pause completed");
- sp<AMessage> msg = mNotify->dup();
- msg->setInt32("what", kWhatPausedDone);
- msg->post();
- break;
- }
- case kWhatResume:
- break;
- case kWhatPlay:
- {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
-
- LOGI("PLAY completed with result %d (%s)",
- result, strerror(-result));
- if (mAborted) {
- LOGV("we're aborted, dropping stale packet.");
- break;
- }
-
- if (result == OK) {
- sp<RefBase> obj;
- CHECK(msg->findObject("response", &obj));
- sp<ARTSPResponse> response =
- static_cast<ARTSPResponse *>(obj.get());
- if (response->mStatusCode != 200) {
- result = UNKNOWN_ERROR;
- } else if (!parsePlayResponse(response)) {
- result = UNKNOWN_ERROR;
- } else {
- sp<AMessage> timeout = new AMessage(kWhatTimeout, id());
- timeout->post(kPlayTimeoutUs);
- mPausePending = false;
- mNumPlayTimeoutsPending++;
- }
- }
-
- if (result != OK) {
- sp<AMessage> reply = new AMessage(kWhatDisconnected, id());
- reply->setInt32("result", result);
- mConn->disconnect(reply);
- }
-
- break;
- }
-
- case kWhatKeepAlive:
- {
- int32_t generation;
- CHECK(msg->findInt32("generation", &generation));
-
- if (generation != mKeepAliveGeneration) {
- // obsolete event.
- break;
- }
-
- AString request;
- request.append("OPTIONS ");
- request.append(mSessionURL);
- request.append(" RTSP/1.0\r\n");
- request.append("Session: ");
- request.append(mSessionID);
- request.append("\r\n");
- request.append("\r\n");
-
- sp<AMessage> reply = new AMessage(kWhatOptions, id());
- reply->setInt32("generation", mKeepAliveGeneration);
- mConn->sendRequest(request.c_str(), reply);
- break;
- }
-
- case kWhatOptions:
- {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
-
- LOGI("OPTIONS completed with result %d (%s)",
- result, strerror(-result));
-
- int32_t generation;
- CHECK(msg->findInt32("generation", &generation));
-
- if (generation != mKeepAliveGeneration) {
- // obsolete event.
- break;
- }
-
- postKeepAlive();
- break;
- }
-
- case kWhatEndOfStream:
- {
- size_t trackIndex = 0;
- msg->findSize("trackIndex", &trackIndex);
- postQueueEOS(trackIndex, ERROR_END_OF_STREAM);
- break;
- }
-
- case kWhatAbort:
- {
- for (size_t i = 0; i < mTracks.size(); ++i) {
- TrackInfo *info = &mTracks.editItemAt(i);
- if (!info) {
- continue;
- }
-
- if (!mFirstAccessUnit) {
- postQueueEOS(i, ERROR_END_OF_STREAM);
- }
-
- if (!info->mUsingInterleavedTCP) {
- mRTPConn->removeStream(info->mRTPSocket, info->mRTCPSocket);
-
- if (info->mRTPSocket) {
- PR_Close(info->mRTPSocket);
- }
-
- if (info->mRTCPSocket) {
- PR_Close(info->mRTCPSocket);
- }
- }
- }
- mTracks.clear();
- mSetupTracksSuccessful = false;
- mSeekPending = false;
- mPausePending = false;
- mFirstAccessUnit = true;
- mNTPAnchorUs = -1;
- mMediaAnchorUs = -1;
- mReceivedFirstRTCPPacket = false;
- mReceivedFirstRTPPacket = false;
- mSeekable = false;
- mAborted = true;
-
- sp<AMessage> reply = new AMessage(kWhatTeardown, id());
-
- int32_t reconnect;
- if (msg->findInt32("reconnect", &reconnect) && reconnect) {
- reply->setInt32("reconnect", true);
- }
-
- AString request;
- request = "TEARDOWN ";
-
- // XXX should use aggregate url from SDP here...
- request.append(mSessionURL);
- request.append(" RTSP/1.0\r\n");
-
- request.append("Session: ");
- request.append(mSessionID);
- request.append("\r\n");
-
- request.append("\r\n");
-
- mConn->sendRequest(request.c_str(), reply);
- break;
- }
-
- case kWhatTeardown:
- {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
-
- LOGI("TEARDOWN completed with result %d (%s)",
- result, strerror(-result));
-
- sp<AMessage> reply = new AMessage(kWhatDisconnected, id());
- reply->setInt32("result", result);
-
- int32_t reconnect;
- if (msg->findInt32("reconnect", &reconnect) && reconnect) {
- reply->setInt32("reconnect", true);
- }
-
- mConn->disconnect(reply);
- break;
- }
-
- case kWhatQuit:
- {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
- sp<AMessage> msg = mNotify->dup();
- msg->setInt32("what", kWhatDisconnected);
- msg->setInt32("result", result);
- msg->post();
- break;
- }
-
- case kWhatAccessUnitTimeoutCheck:
- {
- int32_t generation;
- CHECK(msg->findInt32("generation", &generation));
- if (generation != mCheckGeneration) {
- // This is an outdated message. Ignore.
- break;
- }
-
- if (mNumAccessUnitsReceived == 0) {
- LOGI("stream ended? aborting.");
- disconnect();
- break;
- }
- mNumAccessUnitsReceived = 0;
- msg->post(kAccessUnitTimeoutUs);
- break;
- }
-
- case kWhatEndOfStreamCheck:
- {
- int32_t generation;
- CHECK(msg->findInt32("generation", &generation));
- if (generation != mCheckGeneration) {
- // This is an outdated message. Ignore.
- break;
- }
- size_t trackIndex;
- msg->findSize("trackIndex", &trackIndex);
- TrackInfo *track = &mTracks.editItemAt(trackIndex);
- if (!track) {
- break;
- }
-
- if (track->mNumAccessUnitsReceiveds == 0) {
- if (mozilla::net::gIOService->IsOffline()) {
- LOGI("stream ended? aborting.");
- disconnect();
- break;
- }
- sp<AMessage> endStreamMsg = new AMessage(kWhatEndOfStream, id());
- endStreamMsg->setSize("trackIndex", trackIndex);
- endStreamMsg->post();
- break;
- }
- track->mNumAccessUnitsReceiveds = 0;
- msg->post(kEndOfStreamTimeoutUs);
- break;
- }
-
- case kWhatAccessUnit:
- {
- int32_t timeUpdate;
- if (msg->findInt32("time-update", &timeUpdate) && timeUpdate) {
- size_t trackIndex;
- CHECK(msg->findSize("track-index", &trackIndex));
-
- uint32_t rtpTime;
- uint64_t ntpTime;
- CHECK(msg->findInt32("rtp-time", (int32_t *)&rtpTime));
- CHECK(msg->findInt64("ntp-time", (int64_t *)&ntpTime));
-
- onTimeUpdate(trackIndex, rtpTime, ntpTime);
- break;
- }
-
- int32_t first;
- if (msg->findInt32("first-rtcp", &first)) {
- mReceivedFirstRTCPPacket = true;
- break;
- }
-
- if (msg->findInt32("first-rtp", &first)) {
- mReceivedFirstRTPPacket = true;
- break;
- }
-
- mNumAccessUnitsReceived++;
- postAccessUnitTimeoutCheck();
-
- size_t trackIndex;
- CHECK(msg->findSize("track-index", &trackIndex));
-
- if (trackIndex >= mTracks.size()) {
- LOGV("late packets ignored.");
- break;
- }
-
- TrackInfo *track = &mTracks.editItemAt(trackIndex);
-
- int32_t eos;
- if (msg->findInt32("eos", &eos)) {
- LOGI("received BYE on track index %d", trackIndex);
- return;
- }
-
- sp<RefBase> obj;
- CHECK(msg->findObject("access-unit", &obj));
-
- sp<ABuffer> accessUnit = static_cast<ABuffer *>(obj.get());
-
- uint32_t seqNum = (uint32_t)accessUnit->int32Data();
-
- if (mSeekPending) {
- LOGV("we're seeking, dropping stale packet.");
- break;
- }
-
- if (mPausePending) {
- LOGV("we're pausing, dropping stale packet.");
- break;
- }
-
- if (mAborted) {
- LOGV("we're aborted, dropping stale packet.");
- break;
- }
-
- if (seqNum < track->mFirstSeqNumInSegment) {
- LOGV("dropping stale access-unit (%d < %d)",
- seqNum, track->mFirstSeqNumInSegment);
- break;
- }
-
- if (track->mNewSegment) {
- track->mNewSegment = false;
- }
-
- onAccessUnitComplete(trackIndex, accessUnit);
-
- // This code is put here because now accessUnit has timestamp.
- track->mNumAccessUnitsReceiveds++;
- int64_t duration, timeUs;
- mSessionDesc->getDurationUs(&duration);
- accessUnit->meta()->findInt64("timeUs", &timeUs);
-
- // Start a timer to detect end-of-stream if close to the end.
- if (timeUs >= duration - kActivateEndOfStreamTimerUs) {
- postEndOfStreamCheck(trackIndex);
- }
- break;
- }
-
- case kWhatSeek:
- {
- if (!mSeekable) {
- LOGW("This is a live stream, ignoring seek request.");
-
- sp<AMessage> msg = mNotify->dup();
- msg->setInt32("what", kWhatSeekDone);
- msg->post();
- break;
- }
-
- int64_t timeUs;
- CHECK(msg->findInt64("time", &timeUs));
-
- mSeekPending = true;
-
- // Disable the access unit timeout until we resumed
- // playback again.
- setCheckPending(true);
-
- ++mCheckGeneration;
-
- AString request = "PAUSE ";
- request.append(mSessionURL);
- request.append(" RTSP/1.0\r\n");
-
- request.append("Session: ");
- request.append(mSessionID);
- request.append("\r\n");
-
- request.append("\r\n");
-
- sp<AMessage> reply = new AMessage(kWhatSeek1, id());
- reply->setInt64("time", timeUs);
- mConn->sendRequest(request.c_str(), reply);
- break;
- }
-
- case kWhatSeek1:
- {
- if (mAborted || !mSeekPending) {
- LOGV("We're aborted, dropping stale packet.");
- break;
- }
-
- // Session is paused now.
- for (size_t i = 0; i < mTracks.size(); ++i) {
- TrackInfo *info = &mTracks.editItemAt(i);
-
- postQueueSeekDiscontinuity(i);
-
- info->mRTPAnchor = 0;
- info->mNTPAnchorUs = -1;
- }
-
- mNTPAnchorUs = -1;
-
- int64_t timeUs;
- CHECK(msg->findInt64("time", &timeUs));
-
- AString request = "PLAY ";
- request.append(mSessionURL);
- request.append(" RTSP/1.0\r\n");
-
- request.append("Session: ");
- request.append(mSessionID);
- request.append("\r\n");
- request.append(nsPrintfCString("Range: npt=%lld-\r\n", timeUs / 1000000ll).get());
- request.append("\r\n");
-
- sp<AMessage> reply = new AMessage(kWhatSeek2, id());
- mConn->sendRequest(request.c_str(), reply);
- break;
- }
-
- case kWhatSeek2:
- {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
-
- LOGI("PLAY completed with result %d (%s)",
- result, strerror(-result));
- if (mAborted || !mSeekPending) {
- LOGV("We're aborted, dropping stale packet.");
- break;
- }
-
- mCheckPending = false;
- postAccessUnitTimeoutCheck();
-
- for (size_t i = 0; i < mTracks.size(); i++) {
- setEndOfStreamCheckPending(i, false);
- postEndOfStreamCheck(i);
- }
-
- if (result == OK) {
- sp<RefBase> obj;
- CHECK(msg->findObject("response", &obj));
- sp<ARTSPResponse> response =
- static_cast<ARTSPResponse *>(obj.get());
-
- if (response->mStatusCode != 200) {
- result = UNKNOWN_ERROR;
- } else if (!parsePlayResponse(response)) {
- result = UNKNOWN_ERROR;
- } else {
- ssize_t i = response->mHeaders.indexOfKey("rtp-info");
- if (i < 0) {
- LOGE("No RTP info in response");
- (new AMessage(kWhatAbort, id()))->post();
- }
-
- LOGV("rtp-info: %s", response->mHeaders.valueAt(i).c_str());
-
- LOGI("seek completed.");
- }
- }
-
- if (result != OK) {
- LOGE("seek failed, aborting.");
- (new AMessage(kWhatAbort, id()))->post();
- }
-
- mSeekPending = false;
- mPausePending = false;
-
- sp<AMessage> msg = mNotify->dup();
- msg->setInt32("what", kWhatSeekDone);
- msg->post();
- break;
- }
-
- case kWhatBinary:
- {
- sp<RefBase> obj;
- CHECK(msg->findObject("buffer", &obj));
- sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
-
- int32_t index;
- if (!buffer->meta()->findInt32("index", &index)) {
- LOGW("Cannot find index");
- break;
- }
-
- mRTPConn->injectPacket(index, buffer);
- break;
- }
-
- case kWhatTimeout:
- {
- CHECK(mNumPlayTimeoutsPending >= 1);
- mNumPlayTimeoutsPending--;
- // If there are more than one pending kWhatTimeout messages in the
- // queue, we ignore the preceding ones and only handle the last
- // one.
- // This check is necessary when we fail back to using RTP
- // interleaved in the existing RTSP connection. It prevents from
- // aboring a connection that is trying to transport RTP over
- // TCP.
- if (mNumPlayTimeoutsPending > 0) {
- // Do nothing. We only handle the last kWhatTimeout message.
- return;
- }
-
- if (!mReceivedFirstRTCPPacket) {
- if (mReceivedFirstRTPPacket && !mTryFakeRTCP) {
- LOGW("We received RTP packets but no RTCP packets, "
- "using fake timestamps.");
-
- mTryFakeRTCP = true;
-
- mReceivedFirstRTCPPacket = true;
-
- fakeTimestamps();
- } else if (!mReceivedFirstRTPPacket && !mTryTCPInterleaving) {
- LOGW("Never received any data, switching transports.");
-
- mTryTCPInterleaving = true;
-
- sp<AMessage> msg = new AMessage(kWhatAbort, id());
- msg->setInt32("reconnect", true);
- msg->post();
- } else {
- LOGW("Never received any data, disconnecting.");
- (new AMessage(kWhatAbort, id()))->post();
- }
- }
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
- }
-
- void postKeepAlive() {
- sp<AMessage> msg = new AMessage(kWhatKeepAlive, id());
- msg->setInt32("generation", mKeepAliveGeneration);
- msg->post((mKeepAliveTimeoutUs * 9) / 10);
- }
-
- void postEndOfStreamCheck(size_t trackIndex) {
- if (getEndOfStreamCheckPending(trackIndex)) {
- return;
- }
- setEndOfStreamCheckPending(trackIndex, true);
- sp<AMessage> check = new AMessage(kWhatEndOfStreamCheck, id());
- check->setInt32("generation", mCheckGeneration);
- check->setSize("trackIndex", trackIndex);
- check->post(kEndOfStreamTimeoutUs);
- }
-
- void postAccessUnitTimeoutCheck() {
- if (mCheckPending) {
- return;
- }
- mCheckPending = true;
- sp<AMessage> check = new AMessage(kWhatAccessUnitTimeoutCheck, id());
- check->setInt32("generation", mCheckGeneration);
- check->post(kAccessUnitTimeoutUs);
- }
-
- static void SplitString(
- const AString &s, const char *separator, List<AString> *items) {
- items->clear();
- size_t start = 0;
- while (start < s.size()) {
- ssize_t offset = s.find(separator, start);
-
- if (offset < 0) {
- items->push_back(AString(s, start, s.size() - start));
- break;
- }
-
- items->push_back(AString(s, start, offset - start));
- start = offset + strlen(separator);
- }
- }
-
- bool parsePlayResponse(const sp<ARTSPResponse> &response) {
- mSeekable = false;
-
- for (size_t i = 0; i < mTracks.size(); ++i) {
- TrackInfo *info = &mTracks.editItemAt(i);
- info->mIsPlayAcked = true;
- }
-
- ssize_t i = response->mHeaders.indexOfKey("range");
- if (i < 0) {
- // Server doesn't even tell use what range it is going to
- // play, therefore we won't support seeking.
- return false;
- }
-
- AString range = response->mHeaders.valueAt(i);
- LOGV("Range: %s", range.c_str());
-
- AString val;
- if (!GetAttribute(range.c_str(), "npt", &val)) {
- LOGE("No npt attribute in range");
- return false;
- }
-
- float npt1, npt2;
- if (!ASessionDescription::parseNTPRange(val.c_str(), &npt1, &npt2)) {
- // This is a live stream and therefore not seekable.
-
- LOGI("This is a live stream");
- return false;
- }
-
- i = response->mHeaders.indexOfKey("rtp-info");
- if (i < 0) {
- LOGE("No RTP info");
- return false;
- }
-
- AString rtpInfo = response->mHeaders.valueAt(i);
- List<AString> streamInfos;
- SplitString(rtpInfo, ",", &streamInfos);
-
- int n = 1;
- for (List<AString>::iterator it = streamInfos.begin();
- it != streamInfos.end(); ++it) {
- (*it).trim();
- LOGV("streamInfo[%d] = %s", n, (*it).c_str());
-
- if (!GetAttribute((*it).c_str(), "url", &val)) {
- LOGE("No url attribute");
- return false;
- }
-
- size_t trackIndex = 0;
- while (trackIndex < mTracks.size()
- && !(val == mTracks.editItemAt(trackIndex).mURL)) {
- ++trackIndex;
- }
- if (trackIndex >= mTracks.size()) {
- LOGE("No matching url");
- return false;
- }
-
- if (!GetAttribute((*it).c_str(), "seq", &val)) {
- LOGE("No seq attribute");
- return false;
- }
-
- char *end;
- unsigned long seq = strtoul(val.c_str(), &end, 10);
-
- TrackInfo *info = &mTracks.editItemAt(trackIndex);
- info->mFirstSeqNumInSegment = seq;
- info->mNewSegment = true;
-
- if (!GetAttribute((*it).c_str(), "rtptime", &val)) {
- LOGE("No rtptime attribute");
- return false;
- }
-
- uint32_t rtpTime = strtoul(val.c_str(), &end, 10);
-
- LOGV("track #%d: rtpTime=%u <=> npt=%.2f", n, rtpTime, npt1);
-
- info->mNormalPlayTimeRTP = rtpTime;
- info->mNormalPlayTimeUs = (int64_t)(npt1 * 1E6);
-
- if (!mFirstAccessUnit) {
- postNormalPlayTimeMapping(
- trackIndex,
- info->mNormalPlayTimeRTP, info->mNormalPlayTimeUs);
- }
-
- ++n;
- }
-
- mSeekable = true;
- return true;
- }
-
- sp<MetaData> getTrackFormat(size_t index, int32_t *timeScale) {
- CHECK_GE(index, 0u);
- CHECK_LT(index, mTracks.size());
-
- const TrackInfo &info = mTracks.itemAt(index);
-
- *timeScale = info.mTimeScale;
-
- return info.mPacketSource->getFormat();
- }
-
- size_t countTracks() const {
- return mTracks.size();
- }
-
-private:
- struct TrackInfo {
- AString mURL;
- PRFileDesc *mRTPSocket;
- PRFileDesc *mRTCPSocket;
- int mInterleavedRTPIdx;
- int mInterleavedRTCPIdx;
- bool mUsingInterleavedTCP;
- uint32_t mFirstSeqNumInSegment;
- bool mNewSegment;
-
- uint32_t mRTPAnchor;
- int64_t mNTPAnchorUs;
- int32_t mTimeScale;
-
- uint32_t mNormalPlayTimeRTP;
- int64_t mNormalPlayTimeUs;
-
- sp<APacketSource> mPacketSource;
-
- // Stores packets temporarily while no notion of time
- // has been established yet.
- List<sp<ABuffer> > mPackets;
- bool mIsPlayAcked;
- int64_t mNumAccessUnitsReceiveds;
- bool mCheckPendings;
- };
-
- AString mUserAgent;
- sp<AMessage> mNotify;
- bool mUIDValid;
- uid_t mUID;
- sp<ALooper> mNetLooper;
- sp<ARTSPConnection> mConn;
- sp<ARTPConnection> mRTPConn;
- sp<ASessionDescription> mSessionDesc;
- AString mOriginalSessionURL; // This one still has user:pass@
- AString mSessionURL;
- AString mSessionHost;
- AString mBaseURL;
- AString mSessionID;
- bool mSetupTracksSuccessful;
- bool mSeekPending;
- bool mPausePending;
- bool mAborted;
- bool mFirstAccessUnit;
-
- int64_t mNTPAnchorUs;
- int64_t mMediaAnchorUs;
- int64_t mLastMediaTimeUs;
-
- int64_t mNumAccessUnitsReceived;
- bool mCheckPending;
- int32_t mCheckGeneration;
- bool mTryTCPInterleaving;
- bool mTryFakeRTCP;
- bool mReceivedFirstRTCPPacket;
- bool mReceivedFirstRTPPacket;
- bool mSeekable;
- int64_t mKeepAliveTimeoutUs;
- int32_t mKeepAliveGeneration;
- int32_t mNumPlayTimeoutsPending;
-
- Vector<TrackInfo> mTracks;
-
- void setupTrack(size_t index) {
- sp<APacketSource> source =
- new APacketSource(mSessionDesc, index);
-
- if (source->initCheck() != OK) {
- LOGW("Unsupported format. Ignoring track #%d.", index);
-
- sp<AMessage> reply = new AMessage(kWhatSetup, id());
- reply->setSize("index", index);
- reply->setInt32("result", ERROR_UNSUPPORTED);
- reply->post();
- return;
- }
-
- AString url;
- if (!mSessionDesc->findAttribute(index, "a=control", &url)) {
- LOGW("Unsupported format. Ignoring track #%d.", index);
-
- sp<AMessage> reply = new AMessage(kWhatSetup, id());
- reply->setSize("index", index);
- reply->setInt32("result", ERROR_UNSUPPORTED);
- reply->post();
- return;
- }
-
- AString trackURL;
- if (!MakeURL(mBaseURL.c_str(), url.c_str(), &trackURL)) {
- LOGW("Unsupported format. Ignoring track #%d.", index);
-
- sp<AMessage> reply = new AMessage(kWhatSetup, id());
- reply->setSize("index", index);
- reply->setInt32("result", ERROR_UNSUPPORTED);
- reply->post();
- return;
- }
-
- mTracks.push(TrackInfo());
- TrackInfo *info = &mTracks.editItemAt(mTracks.size() - 1);
- info->mURL = trackURL;
- info->mPacketSource = source;
- info->mUsingInterleavedTCP = false;
- info->mFirstSeqNumInSegment = 0;
- info->mNewSegment = true;
- info->mRTPAnchor = 0;
- info->mNTPAnchorUs = -1;
- info->mNormalPlayTimeRTP = 0;
- info->mNormalPlayTimeUs = 0ll;
- info->mIsPlayAcked = false;
- info->mNumAccessUnitsReceiveds = 0;
- info->mCheckPendings = false;
-
- unsigned long PT;
- AString formatDesc;
- AString formatParams;
- mSessionDesc->getFormatType(index, &PT, &formatDesc, &formatParams);
-
- int32_t timescale;
- int32_t numChannels;
- if (!ASessionDescription::ParseFormatDesc(
- formatDesc.c_str(), ×cale, &numChannels)) {
- LOGW("Unsupported format. Ignoring track #%d.", index);
-
- sp<AMessage> reply = new AMessage(kWhatSetup, id());
- reply->setSize("index", index);
- reply->setInt32("result", ERROR_UNSUPPORTED);
- reply->post();
- return;
- }
-
- info->mTimeScale = timescale;
-
- LOGV("track #%d URL=%s", mTracks.size(), trackURL.c_str());
-
- AString request = "SETUP ";
- request.append(trackURL);
- request.append(" RTSP/1.0\r\n");
-
- if (mTryTCPInterleaving) {
- size_t interleaveIndex = 2 * (mTracks.size() - 1);
- info->mUsingInterleavedTCP = true;
- info->mInterleavedRTPIdx = interleaveIndex;
- info->mInterleavedRTCPIdx = interleaveIndex + 1;
-
- request.append("Transport: RTP/AVP/TCP;interleaved=");
- request.append(info->mInterleavedRTPIdx);
- request.append("-");
- request.append(info->mInterleavedRTCPIdx);
- } else {
- uint16_t rtpPort;
- ARTPConnection::MakePortPair(
- &info->mRTPSocket, &info->mRTCPSocket, &rtpPort);
-
- request.append("Transport: RTP/AVP/UDP;unicast;client_port=");
- request.append(rtpPort);
- request.append("-");
- request.append(rtpPort + 1);
- }
-
- request.append("\r\n");
-
- if (index > 1) {
- request.append("Session: ");
- request.append(mSessionID);
- request.append("\r\n");
- }
-
- request.append("\r\n");
-
- sp<AMessage> reply = new AMessage(kWhatSetup, id());
- reply->setSize("index", index);
- reply->setSize("track-index", mTracks.size() - 1);
- mConn->sendRequest(request.c_str(), reply);
- }
-
- static bool MakeURL(const char *baseURL, const char *url, AString *out) {
- out->clear();
-
- if (strncasecmp("rtsp://", baseURL, 7)) {
- // Base URL must be absolute
- return false;
- }
-
- if (!strncasecmp("rtsp://", url, 7)) {
- // "url" is already an absolute URL, ignore base URL.
- out->setTo(url);
- return true;
- }
-
- size_t n = strlen(baseURL);
- if (baseURL[n - 1] == '/') {
- out->setTo(baseURL);
- out->append(url);
- } else {
- const char *slashPos = strrchr(baseURL, '/');
-
- if (slashPos > &baseURL[6]) {
- out->setTo(baseURL, slashPos - baseURL);
- } else {
- out->setTo(baseURL);
- }
-
- out->append("/");
- out->append(url);
- }
-
- return true;
- }
-
- void fakeTimestamps() {
- for (size_t i = 0; i < mTracks.size(); ++i) {
- onTimeUpdate(i, 0, 0ll);
- }
- }
-
- void onTimeUpdate(int32_t trackIndex, uint32_t rtpTime, uint64_t ntpTime) {
- LOGV("onTimeUpdate track %d, rtpTime = 0x%08x, ntpTime = 0x%016llx",
- trackIndex, rtpTime, ntpTime);
-
- int64_t ntpTimeUs = (int64_t)(ntpTime * 1E6 / (1ll << 32));
-
- TrackInfo *track = &mTracks.editItemAt(trackIndex);
-
- track->mRTPAnchor = rtpTime;
- track->mNTPAnchorUs = ntpTimeUs;
-
- if (mNTPAnchorUs < 0) {
- mNTPAnchorUs = ntpTimeUs;
- mMediaAnchorUs = mLastMediaTimeUs;
- }
- }
-
- void onAccessUnitComplete(
- int32_t trackIndex, const sp<ABuffer> &accessUnit) {
- LOGV("onAccessUnitComplete track %d", trackIndex);
-
- if (mFirstAccessUnit) {
- if (mSeekable) {
- for (size_t i = 0; i < mTracks.size(); ++i) {
- TrackInfo *info = &mTracks.editItemAt(i);
-
- postNormalPlayTimeMapping(
- i,
- info->mNormalPlayTimeRTP, info->mNormalPlayTimeUs);
- }
- }
-
- mFirstAccessUnit = false;
- }
-
- TrackInfo *track = &mTracks.editItemAt(trackIndex);
-
- if (mNTPAnchorUs < 0 || mMediaAnchorUs < 0 ||
- track->mNTPAnchorUs < 0 || !track->mIsPlayAcked) {
- LOGE("storing accessUnit, no time established yet");
- track->mPackets.push_back(accessUnit);
- return;
- }
-
- while (!track->mPackets.empty()) {
- sp<ABuffer> accessUnit = *track->mPackets.begin();
- track->mPackets.erase(track->mPackets.begin());
-
- if (addMediaTimestamp(trackIndex, track, accessUnit)) {
- postQueueAccessUnit(trackIndex, accessUnit);
- }
- }
-
- if (addMediaTimestamp(trackIndex, track, accessUnit)) {
- postQueueAccessUnit(trackIndex, accessUnit);
- }
- }
-
- bool addMediaTimestamp(
- int32_t trackIndex, const TrackInfo *track,
- const sp<ABuffer> &accessUnit) {
- uint32_t rtpTime;
- if (!accessUnit->meta()->findInt32(
- "rtp-time", (int32_t *)&rtpTime)) {
- LOGE("No RTP time in access unit meta");
- return false;
- }
-
- int64_t relRtpTimeUs =
- (((int64_t)rtpTime - (int64_t)track->mNormalPlayTimeRTP) * 1000000ll)
- / track->mTimeScale;
-
- int64_t ntpTimeUs = track->mNTPAnchorUs + relRtpTimeUs;
-
- int64_t mediaTimeUs = mMediaAnchorUs + ntpTimeUs - mNTPAnchorUs;
-
- if (mediaTimeUs > mLastMediaTimeUs) {
- mLastMediaTimeUs = mediaTimeUs;
- }
-
- if (mediaTimeUs < 0) {
- LOGV("dropping early accessUnit.");
- return false;
- }
-
- LOGV("track %d rtpTime=%d mediaTimeUs = %lld us (%.2f secs)",
- trackIndex, rtpTime, mediaTimeUs, mediaTimeUs / 1E6);
-
- accessUnit->meta()->setInt64("timeUs", mediaTimeUs);
-
- return true;
- }
-
- void postQueueAccessUnit(
- size_t trackIndex, const sp<ABuffer> &accessUnit) {
- sp<AMessage> msg = mNotify->dup();
- msg->setInt32("what", kWhatAccessUnitComplete);
- msg->setSize("trackIndex", trackIndex);
- msg->setObject("accessUnit", accessUnit);
- msg->post();
- }
-
- void postQueueEOS(size_t trackIndex, status_t finalResult) {
- sp<AMessage> msg = mNotify->dup();
- msg->setInt32("what", kWhatEOS);
- msg->setSize("trackIndex", trackIndex);
- msg->setInt32("finalResult", finalResult);
- msg->post();
- }
-
- void postQueueSeekDiscontinuity(size_t trackIndex) {
- sp<AMessage> msg = mNotify->dup();
- msg->setInt32("what", kWhatSeekDiscontinuity);
- msg->setSize("trackIndex", trackIndex);
- msg->post();
- }
-
- void postNormalPlayTimeMapping(
- size_t trackIndex, uint32_t rtpTime, int64_t nptUs) {
- sp<AMessage> msg = mNotify->dup();
- msg->setInt32("what", kWhatNormalPlayTimeMapping);
- msg->setSize("trackIndex", trackIndex);
- msg->setInt32("rtpTime", rtpTime);
- msg->setInt64("nptUs", nptUs);
- msg->post();
- }
-
- DISALLOW_EVIL_CONSTRUCTORS(RtspConnectionHandler);
-};
-
-} // namespace android
-
-#endif // RTSP_CONNECTION_HANDLER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/RTSPSource.cpp
+++ /dev/null
@@ -1,811 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "RtspPrlog.h"
-#include "RTSPSource.h"
-#include "ARTPConnection.h"
-#include "RTSPConnectionHandler.h"
-#include "RtspMetaData.h"
-#include <AnotherPacketSource.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/foundation/AMessage.h>
-
-#include "nsDebug.h"
-#include "nsString.h"
-#include "nsStringStream.h"
-#include "nsAutoPtr.h"
-#include "mozilla/DebugOnly.h"
-
-using namespace mozilla;
-using namespace mozilla::net;
-
-namespace android {
-
-RTSPSource::RTSPSource(
- nsIStreamingProtocolListener *aListener,
- const char *url,
- const char *userAgent,
- bool uidValid,
- uid_t uid)
- : mURL(url),
- mUserAgent(userAgent),
- mUIDValid(uidValid),
- mUID(uid),
- mState(DISCONNECTED),
- mFinalResult(OK),
- mDisconnectReplyID(0),
- mLatestPausedUnit(0),
- mPlayPending(false),
- mSeekGeneration(0),
- mDisconnectedToPauseLiveStream(false),
- mPlayOnConnected(false)
-{
- CHECK(aListener != NULL);
-
- // Use main thread pointer, but allow access off main thread.
- mListener =
- new nsMainThreadPtrHolder<nsIStreamingProtocolListener>(aListener, false);
- mPrintCount = 0;
-}
-
-RTSPSource::~RTSPSource()
-{
- if (mLooper != NULL) {
- mLooper->stop();
- }
-}
-
-void RTSPSource::start()
-{
- mDisconnectedToPauseLiveStream = false;
-
- if (mLooper == NULL) {
- mLooper = new ALooper;
- mLooper->setName("rtsp");
- mLooper->start();
-
- mReflector = new AHandlerReflector<RTSPSource>(this);
- mLooper->registerHandler(mReflector);
- }
-
- CHECK(mHandler == NULL);
-
- sp<AMessage> notify = new AMessage(kWhatNotify, mReflector->id());
-
- mHandler = new RtspConnectionHandler(mURL.c_str(), mUserAgent.c_str(),
- notify, mUIDValid, mUID);
- mLooper->registerHandler(mHandler);
-
- CHECK_EQ(mState, (int)DISCONNECTED);
- mState = CONNECTING;
- mHandler->connect();
-}
-
-void RTSPSource::stop()
-{
- if (mState == DISCONNECTED) {
- return;
- }
- sp<AMessage> msg = new AMessage(kWhatDisconnect, mReflector->id());
-
- sp<AMessage> dummy;
- msg->postAndAwaitResponse(&dummy);
-}
-
-void RTSPSource::play()
-{
- LOGI("RTSPSource::play()");
- uint64_t playTimeUs = 0;
- sp<AMessage> msg = new AMessage(kWhatPerformPlay, mReflector->id());
- msg->setInt64("timeUs", playTimeUs);
- msg->post();
-}
-
-void RTSPSource::pause()
-{
- LOGI("RTSPSource::pause()");
-
- // Live streams can't be paused, so we have to disconnect now.
- if (isLiveStream()) {
- mDisconnectedToPauseLiveStream = true;
- stop();
- return;
- }
-
- sp<AMessage> msg = new AMessage(kWhatPerformPause, mReflector->id());
- msg->post();
-}
-
-void RTSPSource::resume()
-{
- LOGI("RTSPSource::resume()");
- sp<AMessage> msg = new AMessage(kWhatPerformResume, mReflector->id());
- msg->post();
-}
-
-void RTSPSource::suspend()
-{
- LOGI("RTSPSource::suspend()");
- sp<AMessage> msg = new AMessage(kWhatPerformSuspend, mReflector->id());
- msg->post();
-}
-
-void RTSPSource::seek(uint64_t timeUs)
-{
- LOGI("RTSPSource::seek() %llu", timeUs);
- seekTo(timeUs);
-}
-
-void RTSPSource::playbackEnded()
-{
- LOGI("RTSPSource::playbackEnded()");
- sp<AMessage> msg = new AMessage(kWhatPerformPlaybackEnded, mReflector->id());
- msg->post();
-}
-
-status_t RTSPSource::feedMoreTSData() {
- return mFinalResult;
-}
-
-sp<MetaData> RTSPSource::getFormat(bool audio) {
- sp<AnotherPacketSource> source = getSource(audio);
-
- if (source == NULL) {
- return NULL;
- }
-
- return source->getFormat();
-}
-
-status_t RTSPSource::dequeueAccessUnit(
- bool audio, sp<ABuffer> *accessUnit) {
- sp<AnotherPacketSource> source = getSource(audio);
-
- if (source == NULL) {
- return -EWOULDBLOCK;
- }
-
- status_t finalResult;
- if (!source->hasBufferAvailable(&finalResult)) {
- return finalResult == OK ? -EWOULDBLOCK : finalResult;
- }
-
- return source->dequeueAccessUnit(accessUnit);
-}
-
-sp<AnotherPacketSource> RTSPSource::getSource(bool audio) {
- return audio ? mAudioTrack : mVideoTrack;
-}
-
-status_t RTSPSource::getDuration(int64_t *durationUs) {
- *durationUs = 0ll;
-
- int64_t audioDurationUs;
- if (mAudioTrack != NULL
- && mAudioTrack->getFormat()->findInt64(
- kKeyDuration, &audioDurationUs)
- && audioDurationUs > *durationUs) {
- *durationUs = audioDurationUs;
- }
-
- int64_t videoDurationUs;
- if (mVideoTrack != NULL
- && mVideoTrack->getFormat()->findInt64(
- kKeyDuration, &videoDurationUs)
- && videoDurationUs > *durationUs) {
- *durationUs = videoDurationUs;
- }
-
- return OK;
-}
-
-status_t RTSPSource::seekTo(int64_t seekTimeUs) {
- sp<AMessage> msg = new AMessage(kWhatPerformSeek, mReflector->id());
- msg->setInt32("generation", ++mSeekGeneration);
- msg->setInt64("timeUs", seekTimeUs);
- // The original code in Android posts this message for 200ms delay in order
- // to avoid performing multiple seeks in a short period of time. This is not
- // necessary for us because MediaDecoderStateMachine already circumvents
- // that situation.
- msg->post();
-
- return OK;
-}
-
-void RTSPSource::performPlay(int64_t playTimeUs) {
- if (mState == DISCONNECTED) {
- LOGI("We are in a idle state, restart play");
- mPlayOnConnected = true;
- start();
- return;
- }
- // If state is PAUSING, which means a previous PAUSE request is still being
- // processed, put off the PLAY request until PausedDone.
- if (mState == PAUSING) {
- mPlayPending = true;
- return;
- }
- // Reject invalid state transition.
- if (mState != CONNECTED && mState != PAUSED) {
- return;
- }
- // Use the latest received frame time if we were paused.
- if (mState == PAUSED) {
- playTimeUs = mLatestPausedUnit;
- }
-
- int64_t duration = 0;
- getDuration(&duration);
- MOZ_ASSERT(duration == 0 || playTimeUs < duration,
- "Should never receive an out of bounds play time!");
- if (duration > 0 && playTimeUs >= duration) {
- // if not a live stream and play time out of bounds
- return;
- }
-
- LOGI("performPlay : duration=%lld playTimeUs=%lld", duration, playTimeUs);
- mState = PLAYING;
- mHandler->play(playTimeUs);
-}
-
-void RTSPSource::performPause() {
- // Reject invalid state transition.
- if (mState != PLAYING) {
- return;
- }
- LOGI("performPause :");
- for (size_t i = 0; i < mTracks.size(); ++i) {
- TrackInfo *info = &mTracks.editItemAt(i);
- info->mLatestPausedUnit = 0;
- }
- mLatestPausedUnit = 0;
-
- mState = PAUSING;
- mHandler->pause();
-}
-
-void RTSPSource::performResume() {
-// TODO, Bug 895753.
-}
-
-void RTSPSource::performSuspend() {
-// TODO, Bug 895753.
-}
-
-void RTSPSource::performPlaybackEnded() {
- // Reject invalid state transition.
- if (mState != PLAYING) {
- return;
- }
- // Transition from PLAYING to CONNECTED state so that we are ready to
- // perform an another play operation.
- mState = CONNECTED;
-}
-
-void RTSPSource::performSeek(int64_t seekTimeUs) {
- if (mState != CONNECTED && mState != PLAYING && mState != PAUSED) {
- return;
- }
-
- int64_t duration = 0;
- getDuration(&duration);
- MOZ_ASSERT(seekTimeUs < duration,
- "Should never receive an out of bounds seek time!");
- if (seekTimeUs >= duration) {
- return;
- }
-
- for (size_t i = 0; i < mTracks.size(); ++i) {
- TrackInfo *info = &mTracks.editItemAt(i);
- info->mLatestPausedUnit = 0;
- }
- mLatestPausedUnit = 0;
-
- LOGI("performSeek: %llu", seekTimeUs);
- mState = SEEKING;
- mHandler->seek(seekTimeUs);
-}
-
-bool RTSPSource::isSeekable() {
- return true;
-}
-
-void RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
- if (msg->what() == kWhatDisconnect) {
- uint32_t replyID;
- CHECK(msg->senderAwaitsResponse(&replyID));
-
- mDisconnectReplyID = replyID;
- finishDisconnectIfPossible();
- return;
- } else if (msg->what() == kWhatPerformSeek) {
- int32_t generation;
- CHECK(msg->findInt32("generation", &generation));
-
- if (generation != mSeekGeneration) {
- // obsolete.
- return;
- }
-
- int64_t seekTimeUs;
- CHECK(msg->findInt64("timeUs", &seekTimeUs));
-
- performSeek(seekTimeUs);
- return;
- } else if (msg->what() == kWhatPerformPlay) {
- int64_t playTimeUs;
- CHECK(msg->findInt64("timeUs", &playTimeUs));
- performPlay(playTimeUs);
- return;
- } else if (msg->what() == kWhatPerformPause) {
- performPause();
- return;
- } else if (msg->what() == kWhatPerformResume) {
- performResume();
- return;
- } else if (msg->what() == kWhatPerformSuspend) {
- performSuspend();
- return;
- } else if (msg->what() == kWhatPerformPlaybackEnded) {
- performPlaybackEnded();
- return;
- }
-
- CHECK_EQ(msg->what(), (uint32_t)kWhatNotify);
-
- int32_t what;
- int32_t isSeekable = 0;
- CHECK(msg->findInt32("what", &what));
-
- switch (what) {
- case RtspConnectionHandler::kWhatConnected:
- CHECK(msg->findInt32("isSeekable", &isSeekable));
- onConnected((isSeekable ? true:false));
- break;
-
- case RtspConnectionHandler::kWhatDisconnected:
- onDisconnected(msg);
- break;
-
- case RtspConnectionHandler::kWhatSeekDone:
- {
- mState = PLAYING;
- // Even if we have reset mLatestPausedUnit in performSeek(),
- // it's still possible that kWhatPausedDone event may arrive
- // because of previous performPause() command.
- for (size_t i = 0; i < mTracks.size(); ++i) {
- TrackInfo *info = &mTracks.editItemAt(i);
- info->mLatestPausedUnit = 0;
- }
- mLatestPausedUnit = 0;
- break;
- }
-
- case RtspConnectionHandler::kWhatPausedDone:
- {
- // Reject invalid state transition.
- if (mState != PAUSING) {
- return;
- }
- mState = PAUSED;
-
- for (size_t i = 0; i < mTracks.size(); ++i) {
- TrackInfo *info = &mTracks.editItemAt(i);
- info->mLatestPausedUnit = info->mLatestReceivedUnit;
- }
-
- // The timestamp after a 'Pause' is done is the earliest
- // timestamp among all of the latest received units.
- TrackInfo *info = &mTracks.editItemAt(0);
- mLatestPausedUnit = info->mLatestReceivedUnit;
- for (size_t i = 1; i < mTracks.size(); ++i) {
- TrackInfo *info = &mTracks.editItemAt(i);
- if (mLatestPausedUnit > info->mLatestReceivedUnit) {
- mLatestPausedUnit = info->mLatestReceivedUnit;
- }
- }
-
- if (mPlayPending) {
- mPlayPending = false;
- performPlay(mLatestPausedUnit);
- }
- break;
- }
-
- case RtspConnectionHandler::kWhatAccessUnitComplete:
- {
- if (!isValidState()) {
- LOGI("We're disconnected, dropping access unit.");
- break;
- }
- size_t trackIndex;
- CHECK(msg->findSize("trackIndex", &trackIndex));
- CHECK_LT(trackIndex, mTracks.size());
-
- sp<RefBase> obj;
- CHECK(msg->findObject("accessUnit", &obj));
-
- sp<ABuffer> accessUnit = static_cast<ABuffer *>(obj.get());
-
- int32_t damaged;
- if (accessUnit->meta()->findInt32("damaged", &damaged)
- && damaged) {
- LOGI("dropping damaged access unit.");
- break;
- }
-
- TrackInfo *info = &mTracks.editItemAt(trackIndex);
-
- sp<AnotherPacketSource> source = info->mSource;
- if (source != NULL) {
- uint32_t rtpTime;
- CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
-
- if (!info->mNPTMappingValid) {
- // This is a live stream, we didn't receive any normal
- // playtime mapping. Assume the first packets correspond
- // to time 0.
-
- LOGV("This is a live stream, assuming time = 0");
-
- info->mRTPTime = rtpTime;
- info->mNormalPlaytimeUs = 0ll;
- info->mNPTMappingValid = true;
- }
-
- int64_t nptUs =
- ((double)rtpTime - (double)info->mRTPTime)
- / info->mTimeScale
- * 1000000ll
- + info->mNormalPlaytimeUs;
-
- accessUnit->meta()->setInt64("timeUs", nptUs);
- info->mLatestReceivedUnit = nptUs;
- // Drop the frames that are older than the frames in the queue.
- if (info->mLatestPausedUnit && (int64_t)info->mLatestPausedUnit > nptUs) {
- break;
- }
- source->queueAccessUnit(accessUnit);
- }
-
- onTrackDataAvailable(trackIndex);
- break;
- }
-
- case RtspConnectionHandler::kWhatEOS:
- {
- if (!isValidState()) {
- LOGI("We're disconnected, dropping end-of-stream message.");
- break;
- }
- size_t trackIndex;
- CHECK(msg->findSize("trackIndex", &trackIndex));
- CHECK_LT(trackIndex, mTracks.size());
-
- int32_t finalResult;
- CHECK(msg->findInt32("finalResult", &finalResult));
- CHECK_NE(finalResult, (status_t)OK);
-
- TrackInfo *info = &mTracks.editItemAt(trackIndex);
- sp<AnotherPacketSource> source = info->mSource;
- if (source != NULL) {
- source->signalEOS(finalResult);
- }
-
- onTrackEndOfStream(trackIndex);
- break;
- }
-
- case RtspConnectionHandler::kWhatSeekDiscontinuity:
- {
- if (!isValidState()) {
- LOGI("We're disconnected, dropping seek discontinuity message.");
- break;
- }
- size_t trackIndex;
- CHECK(msg->findSize("trackIndex", &trackIndex));
- CHECK_LT(trackIndex, mTracks.size());
-
- TrackInfo *info = &mTracks.editItemAt(trackIndex);
- sp<AnotherPacketSource> source = info->mSource;
- if (source != NULL) {
-#if ANDROID_VERSION >= 21
- source->queueDiscontinuity(ATSParser::DISCONTINUITY_TIME, NULL,
- true /* discard */);
-#else
- source->queueDiscontinuity(ATSParser::DISCONTINUITY_SEEK, NULL);
-#endif
- }
-
- break;
- }
-
- case RtspConnectionHandler::kWhatNormalPlayTimeMapping:
- {
- if (!isValidState()) {
- LOGI("We're disconnected, dropping normal play time mapping "
- "message.");
- break;
- }
- size_t trackIndex;
- CHECK(msg->findSize("trackIndex", &trackIndex));
- CHECK_LT(trackIndex, mTracks.size());
-
- uint32_t rtpTime;
- CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
-
- int64_t nptUs;
- CHECK(msg->findInt64("nptUs", &nptUs));
-
- TrackInfo *info = &mTracks.editItemAt(trackIndex);
- info->mRTPTime = rtpTime;
- info->mNormalPlaytimeUs = nptUs;
- info->mNPTMappingValid = true;
- break;
- }
-
- case RtspConnectionHandler::kWhatTryTCPInterleaving:
- {
- // By default, we will request to deliver RTP over UDP. If the play
- // request timed out and we didn't receive any RTP packet, we will
- // fail back to use RTP interleaved in the existing RTSP/TCP
- // connection. And in this case, we have to explicitly perform
- // another play event to request the server to start streaming
- // again.
- int64_t playTimeUs;
- if (!msg->findInt64("timeUs", &playTimeUs)) {
- playTimeUs = 0;
- }
- performPlay(playTimeUs);
- break;
- }
-
- default:
- TRESPASS();
- }
-}
-
-void RTSPSource::onConnected(bool isSeekable)
-{
- CHECK(mHandler != NULL);
- CHECK(mListener != NULL);
-
- // Clean up audio and video tracks.
- // In the case of RTSP reconnect, audio/video tracks might be created by
- // previous onConnected event.
- mAudioTrack = NULL;
- mVideoTrack = NULL;
- mTracks.clear();
-
- size_t numTracks = mHandler->countTracks();
- for (size_t i = 0; i < numTracks; ++i) {
- int32_t timeScale;
- sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale);
- CHECK(format != NULL);
-
- const char *mime;
- CHECK(format->findCString(kKeyMIMEType, &mime));
- nsAutoCString mimeType(mime, strlen(mime));
-
- bool isAudio = !strncasecmp(mime, "audio/", 6);
- bool isVideo = !strncasecmp(mime, "video/", 6);
-
- TrackInfo info;
- info.mTimeScale = timeScale;
- info.mRTPTime = 0;
- info.mNormalPlaytimeUs = 0ll;
- info.mNPTMappingValid = false;
- info.mIsAudio = false;
- info.mLatestReceivedUnit = 0;
- info.mLatestPausedUnit = 0;
-
- if ((isAudio && mAudioTrack == NULL)
- || (isVideo && mVideoTrack == NULL)) {
- sp<AnotherPacketSource> source = new AnotherPacketSource(format);
-
- if (isAudio) {
- info.mIsAudio = true;
- mAudioTrack = source;
- } else {
- info.mIsAudio = false;
- mVideoTrack = source;
- }
-
- info.mSource = source;
- }
-
- RefPtr<nsIStreamingProtocolMetaData> meta;
- int32_t int32Value;
- int64_t int64Value;
-
- meta = new mozilla::net::RtspMetaData();
- meta->SetTotalTracks(numTracks);
- meta->SetMimeType(mimeType);
-
- DebugOnly<bool> success;
- success = format->findInt64(kKeyDuration, &int64Value);
- MOZ_ASSERT(success);
- meta->SetDuration(int64Value);
-
- if (isAudio) {
- success = format->findInt32(kKeyChannelCount, &int32Value);
- MOZ_ASSERT(success);
- meta->SetChannelCount(int32Value);
-
- success = format->findInt32(kKeySampleRate, &int32Value);
- MOZ_ASSERT(success);
- meta->SetSampleRate(int32Value);
- } else {
- success = format->findInt32(kKeyWidth, &int32Value);
- MOZ_ASSERT(success);
- meta->SetWidth(int32Value);
-
- success = format->findInt32(kKeyHeight, &int32Value);
- MOZ_ASSERT(success);
- meta->SetHeight(int32Value);
- }
-
- // Optional meta data.
- const void *data;
- uint32_t type;
- size_t length = 0;
-
- if (format->findData(kKeyESDS, &type, &data, &length)) {
- nsCString esds;
- esds.Assign((const char *)data, length);
- meta->SetEsdsData(esds);
- }
-
- if (format->findData(kKeyAVCC, &type, &data, &length)) {
- nsCString avcc;
- avcc.Assign((const char *)data, length);
- meta->SetAvccData(avcc);
- }
-
- mListener->OnConnected(i, meta.get());
- mTracks.push(info);
- }
-
- mState = CONNECTED;
-
- if (mPlayOnConnected) {
- mPlayOnConnected = false;
- play();
- }
-}
-
-void RTSPSource::onDisconnected(const sp<AMessage> &msg) {
- status_t err;
- CHECK(msg != NULL);
- CHECK(msg->findInt32("result", &err));
-
- if ((mLooper != NULL) && (mHandler != NULL)) {
- mLooper->unregisterHandler(mHandler->id());
- mHandler.clear();
- }
-
- mState = DISCONNECTED;
- mFinalResult = err;
-
- if (mDisconnectReplyID != 0) {
- finishDisconnectIfPossible();
- }
- // If the disconnection is caused by pausing live stream,
- // do not report back to the controller.
- if (mListener && !mDisconnectedToPauseLiveStream) {
- nsresult reason = (err == OK) ? NS_OK : NS_ERROR_NET_TIMEOUT;
- mListener->OnDisconnected(0, reason);
- // Break the cycle reference between RtspController and us.
- mListener = nullptr;
- }
- mAudioTrack = NULL;
- mVideoTrack = NULL;
- mTracks.clear();
-}
-
-void RTSPSource::finishDisconnectIfPossible() {
- if (mState != DISCONNECTED) {
- CHECK(mHandler != NULL);
- mHandler->disconnect();
- }
-
- (new AMessage)->postReply(mDisconnectReplyID);
- mDisconnectReplyID = 0;
-}
-
-void RTSPSource::onTrackDataAvailable(size_t trackIndex)
-{
- nsCString data;
- sp<ABuffer> accessUnit;
- TrackInfo *info = &mTracks.editItemAt(trackIndex);
-
- if (mState != PLAYING) {
- return;
- }
-
- status_t err = dequeueAccessUnit(info->mIsAudio, &accessUnit);
-
- if (err == -EWOULDBLOCK || err == ERROR_END_OF_STREAM) {
- return;
- } else if (err == INFO_DISCONTINUITY) {
- RefPtr<nsIStreamingProtocolMetaData> meta;
-
- meta = new mozilla::net::RtspMetaData();
- meta->SetFrameType(MEDIASTREAM_FRAMETYPE_DISCONTINUITY);
-
- data.AssignLiteral("DISCONTINUITY");
- if (mListener) {
- mListener->OnMediaDataAvailable(trackIndex, data, data.Length(), 0, meta.get());
- }
- LOGV("err trackIndex[%d]:INFO_DISCONTINUITY", trackIndex);
- return;
- }
-
- RefPtr<nsIStreamingProtocolMetaData> meta;
- int64_t int64Value;
-
- meta = new mozilla::net::RtspMetaData();
-
- MOZ_ASSERT(accessUnit != NULL);
- DebugOnly<bool> success = accessUnit->meta()->findInt64("timeUs", &int64Value);
- MOZ_ASSERT(success);
- meta->SetTimeStamp(int64Value);
-
- meta->SetFrameType(MEDIASTREAM_FRAMETYPE_NORMAL);
- data.Assign((const char *) accessUnit->data(), accessUnit->size());
-
- if (mListener) {
- mListener->OnMediaDataAvailable(trackIndex, data, data.Length(), 0, meta.get());
- }
-}
-
-void RTSPSource::onTrackEndOfStream(size_t trackIndex)
-{
- // If we are disconnecting to pretend pausing a live stream,
- // do not report the end of stream.
- if (!mListener || mDisconnectedToPauseLiveStream) {
- return;
- }
-
- RefPtr<nsIStreamingProtocolMetaData> meta;
- meta = new mozilla::net::RtspMetaData();
- meta->SetFrameType(MEDIASTREAM_FRAMETYPE_END_OF_STREAM);
-
- nsCString data;
- data.AssignLiteral("END_OF_STREAM");
-
- mListener->OnMediaDataAvailable(trackIndex, data, data.Length(), 0, meta.get());
-}
-
-inline bool RTSPSource::isValidState()
-{
- if (mState == DISCONNECTED || mTracks.size() == 0) {
- return false;
- }
- return true;
-}
-
-
-
-bool RTSPSource::isLiveStream() {
- int64_t duration = 0;
- getDuration(&duration);
- return duration == 0;
-}
-
-} // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/RTSPSource.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef RTSP_SOURCE_H_
-
-#define RTSP_SOURCE_H_
-
-#include "mozilla/Types.h"
-#include <utils/RefBase.h>
-#include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/foundation/AHandlerReflector.h>
-
-#include "nsCOMPtr.h"
-#include "nsString.h"
-#include "nsIStreamingProtocolController.h"
-#include "nsProxyRelease.h"
-
-namespace android {
-
-struct MOZ_EXPORT MetaData;
-struct ABuffer;
-struct ALooper;
-struct MOZ_EXPORT AnotherPacketSource;
-struct RtspConnectionHandler;
-
-class RTSPSource : public RefBase
-{
-public:
-
- RTSPSource(
- nsIStreamingProtocolListener *aListener,
- const char *url,
- const char *userAgent,
- bool uidValid = false,
- uid_t uid = 0);
-
- void start();
- void stop();
-
- void play();
- void pause();
- void seek(uint64_t timeUs);
- void resume();
- void suspend();
- void playbackEnded();
-
- status_t feedMoreTSData();
-
- sp<MetaData> getFormat(bool audio);
- status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
-
- status_t getDuration(int64_t *durationUs);
- status_t seekTo(int64_t seekTimeUs);
- bool isSeekable();
-
- void onMessageReceived(const sp<AMessage> &msg);
-
-protected:
- ~RTSPSource();
-
-private:
- enum {
- kWhatNotify = 1,
- kWhatDisconnect,
- kWhatPerformSeek,
- kWhatPerformPlay,
- kWhatPerformPause,
- kWhatPerformResume,
- kWhatPerformSuspend,
- kWhatPerformPlaybackEnded,
- };
-
- enum State {
- DISCONNECTED,
- CONNECTING,
- CONNECTED,
- SEEKING,
- PAUSING,
- PAUSED,
- PLAYING,
- };
-
- enum Flags {
- // Don't log any URLs.
- kFlagIncognito = 1,
- };
-
- struct TrackInfo {
- sp<AnotherPacketSource> mSource;
-
- int32_t mTimeScale;
- uint32_t mRTPTime;
- int64_t mNormalPlaytimeUs;
- bool mNPTMappingValid;
- bool mIsAudio;
- uint64_t mLatestReceivedUnit;
- uint64_t mLatestPausedUnit;
- };
-
- AString mURL;
- AString mUserAgent;
- bool mUIDValid;
- uid_t mUID;
- State mState;
- status_t mFinalResult;
- uint32_t mDisconnectReplyID;
- uint64_t mLatestPausedUnit;
- bool mPlayPending;
-
- sp<ALooper> mLooper;
- sp<AHandlerReflector<RTSPSource> > mReflector;
- sp<RtspConnectionHandler> mHandler;
-
- Vector<TrackInfo> mTracks;
- sp<AnotherPacketSource> mAudioTrack;
- sp<AnotherPacketSource> mVideoTrack;
-
- int32_t mSeekGeneration;
-
- sp<AnotherPacketSource> getSource(bool audio);
-
- void onConnected(bool isSeekable);
- void onDisconnected(const sp<AMessage> &msg);
- void finishDisconnectIfPossible();
-
- void performSeek(int64_t seekTimeUs);
-
- void performPlay(int64_t playTimeUs);
-
- void performPause();
-
- void performResume();
-
- void performSuspend();
-
- void performPlaybackEnded();
-
- void onTrackDataAvailable(size_t trackIndex);
-
- void onTrackEndOfStream(size_t trackIndex);
-
- inline bool isValidState();
-
- bool isLiveStream();
-
- // This flag is set if we have just disconnected
- // in order to pretend pausing a live stream.
- bool mDisconnectedToPauseLiveStream;
-
- // While performing a play operation, if the current state of RTSP connection
- // is disconnected, we will start over establishing connection to the server.
- // In this case (mPlayOnConnected = true), we have to perform play again when
- // onConnected, to ensure we complete the play operation.
- bool mPlayOnConnected;
-
- nsMainThreadPtrHandle<nsIStreamingProtocolListener> mListener;
- int mPrintCount;
-
- DISALLOW_EVIL_CONSTRUCTORS(RTSPSource);
-};
-
-} // namespace android
-
-#endif // RTSP_SOURCE_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/RTSPTransmitter.h
+++ /dev/null
@@ -1,998 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef RTSP_TRANSMITTER_H_
-
-#define RTSP_TRANSMITTER_H_
-
-#include "ARTPConnection.h"
-
-#include <arpa/inet.h>
-#include <sys/socket.h>
-
-#include <openssl/md5.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/base64.h>
-#include <media/stagefright/foundation/hexdump.h>
-
-#ifdef ANDROID
-#include "VideoSource.h"
-
-#include <media/stagefright/OMXClient.h>
-#include <media/stagefright/OMXCodec.h>
-#endif
-
-#include "prnetdb.h"
-#include "prerr.h"
-
-namespace android {
-
-#define TRACK_SUFFIX "trackid=1"
-#define PT 96
-#define PT_STR "96"
-
-#define USERNAME "bcast"
-#define PASSWORD "test"
-
-static int uniformRand(int limit) {
- return ((double)rand() * limit) / RAND_MAX;
-}
-
-static bool GetAttribute(const char *s, const char *key, AString *value) {
- value->clear();
-
- size_t keyLen = strlen(key);
-
- for (;;) {
- const char *colonPos = strchr(s, ';');
-
- size_t len =
- (colonPos == NULL) ? strlen(s) : colonPos - s;
-
- if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
- value->setTo(&s[keyLen + 1], len - keyLen - 1);
- return true;
- }
-
- if (colonPos == NULL) {
- return false;
- }
-
- s = colonPos + 1;
- }
-}
-
-struct MyTransmitter : public AHandler {
- MyTransmitter(const char *url, const sp<ALooper> &looper)
- : mServerURL(url),
- mLooper(looper),
- mConn(new ARTSPConnection),
- mConnected(false),
- mAuthType(NONE),
- mRTPSocket(nullptr),
- mRTCPSocket(nullptr),
- mSourceID(rand()),
- mSeqNo(uniformRand(65536)),
- mRTPTimeBase(rand()),
- mNumSamplesSent(0),
- mNumRTPSent(0),
- mNumRTPOctetsSent(0),
- mLastRTPTime(0),
- mLastNTPTime(0) {
- mStreamURL = mServerURL;
- mStreamURL.append("/bazong.sdp");
-
- mTrackURL = mStreamURL;
- mTrackURL.append("/");
- mTrackURL.append(TRACK_SUFFIX);
-
- mLooper->registerHandler(this);
- mLooper->registerHandler(mConn);
-
- sp<AMessage> reply = new AMessage(kWhatConnect, id());
- mConn->connect(mServerURL.c_str(), reply);
-
-#ifdef ANDROID
- int width = 640;
- int height = 480;
-
- sp<MediaSource> source = new VideoSource(width, height);
-
- sp<MetaData> encMeta = new MetaData;
- encMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
- encMeta->setInt32(kKeyWidth, width);
- encMeta->setInt32(kKeyHeight, height);
-
- OMXClient client;
- client.connect();
-
- mEncoder = OMXCodec::Create(
- client.interface(), encMeta,
- true /* createEncoder */, source);
-
- mEncoder->start();
-
- MediaBuffer *buffer;
- CHECK_EQ(mEncoder->read(&buffer), (status_t)OK);
- CHECK(buffer != NULL);
-
- makeH264SPropParamSets(buffer);
-
- buffer->release();
- buffer = NULL;
-#endif
- }
-
- uint64_t ntpTime() {
- struct timeval tv;
- gettimeofday(&tv, NULL);
-
- uint64_t nowUs = tv.tv_sec * 1000000ll + tv.tv_usec;
-
- nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
-
- uint64_t hi = nowUs / 1000000ll;
- uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
-
- return (hi << 32) | lo;
- }
-
- void issueAnnounce() {
- AString sdp;
- sdp = "v=0\r\n";
-
- sdp.append("o=- ");
-
- uint64_t ntp = ntpTime();
- sdp.append(ntp);
- sdp.append(" ");
- sdp.append(ntp);
- sdp.append(" IN IP4 127.0.0.0\r\n");
-
- sdp.append(
- "s=Sample\r\n"
- "i=Playing around with ANNOUNCE\r\n"
- "c=IN IP4 ");
-
- struct in_addr addr;
- addr.s_addr = htonl(mServerIP);
-
- sdp.append(inet_ntoa(addr));
-
- sdp.append(
- "\r\n"
- "t=0 0\r\n"
- "a=range:npt=now-\r\n");
-
-#ifdef ANDROID
- sp<MetaData> meta = mEncoder->getFormat();
- int32_t width, height;
- CHECK(meta->findInt32(kKeyWidth, &width));
- CHECK(meta->findInt32(kKeyHeight, &height));
-
- sdp.append(
- "m=video 0 RTP/AVP " PT_STR "\r\n"
- "b=AS 320000\r\n"
- "a=rtpmap:" PT_STR " H264/90000\r\n");
-
- sdp.append("a=cliprect 0,0,");
- sdp.append(height);
- sdp.append(",");
- sdp.append(width);
- sdp.append("\r\n");
-
- sdp.append(
- "a=framesize:" PT_STR " ");
- sdp.append(width);
- sdp.append("-");
- sdp.append(height);
- sdp.append("\r\n");
-
- sdp.append(
- "a=fmtp:" PT_STR " profile-level-id=42C015;sprop-parameter-sets=");
-
- sdp.append(mSeqParamSet);
- sdp.append(",");
- sdp.append(mPicParamSet);
- sdp.append(";packetization-mode=1\r\n");
-#else
- sdp.append(
- "m=audio 0 RTP/AVP " PT_STR "\r\n"
- "a=rtpmap:" PT_STR " L8/8000/1\r\n");
-#endif
-
- sdp.append("a=control:" TRACK_SUFFIX "\r\n");
-
- AString request;
- request.append("ANNOUNCE ");
- request.append(mStreamURL);
- request.append(" RTSP/1.0\r\n");
-
- addAuthentication(&request, "ANNOUNCE", mStreamURL.c_str());
-
- request.append("Content-Type: application/sdp\r\n");
- request.append("Content-Length: ");
- request.append(sdp.size());
- request.append("\r\n");
-
- request.append("\r\n");
- request.append(sdp);
-
- sp<AMessage> reply = new AMessage(kWhatAnnounce, id());
- mConn->sendRequest(request.c_str(), reply);
- }
-
- void H(const AString &s, AString *out) {
- out->clear();
-
- MD5_CTX m;
- MD5_Init(&m);
- MD5_Update(&m, s.c_str(), s.size());
-
- uint8_t key[16];
- MD5_Final(key, &m);
-
- for (size_t i = 0; i < 16; ++i) {
- char nibble = key[i] >> 4;
- if (nibble <= 9) {
- nibble += '0';
- } else {
- nibble += 'a' - 10;
- }
- out->append(&nibble, 1);
-
- nibble = key[i] & 0x0f;
- if (nibble <= 9) {
- nibble += '0';
- } else {
- nibble += 'a' - 10;
- }
- out->append(&nibble, 1);
- }
- }
-
- bool authenticate(const sp<ARTSPResponse> &response) {
- ssize_t i = response->mHeaders.indexOfKey("www-authenticate");
- if (i < 0) {
- return false;
- }
-
- AString value = response->mHeaders.valueAt(i);
-
- if (!strncmp(value.c_str(), "Basic", 5)) {
- mAuthType = BASIC;
- } else {
- if (strncmp(value.c_str(), "Digest", 6)) {
- return false;
- }
-
- mAuthType = DIGEST;
-
- i = value.find("nonce=");
- if (i < 0 || value.c_str()[i + 6] != '\"') {
- return false;
- }
- ssize_t j = value.find("\"", i + 7);
- if (j < 0) {
- return false;
- }
-
- mNonce.setTo(value, i + 7, j - i - 7);
- }
-
- issueAnnounce();
- return true;
- }
-
- void addAuthentication(
- AString *request, const char *method, const char *url) {
- if (mAuthType == NONE) {
- return;
- }
-
- if (mAuthType == BASIC) {
- request->append("Authorization: Basic YmNhc3Q6dGVzdAo=\r\n");
- return;
- }
-
- CHECK_EQ((int)mAuthType, (int)DIGEST);
-
- AString A1;
- A1.append(USERNAME);
- A1.append(":");
- A1.append("Streaming Server");
- A1.append(":");
- A1.append(PASSWORD);
-
- AString A2;
- A2.append(method);
- A2.append(":");
- A2.append(url);
-
- AString HA1, HA2;
- H(A1, &HA1);
- H(A2, &HA2);
-
- AString tmp;
- tmp.append(HA1);
- tmp.append(":");
- tmp.append(mNonce);
- tmp.append(":");
- tmp.append(HA2);
-
- AString digest;
- H(tmp, &digest);
-
- request->append("Authorization: Digest ");
- request->append("nonce=\"");
- request->append(mNonce);
- request->append("\", ");
- request->append("username=\"" USERNAME "\", ");
- request->append("uri=\"");
- request->append(url);
- request->append("\", ");
- request->append("response=\"");
- request->append(digest);
- request->append("\"");
- request->append("\r\n");
- }
-
- virtual void onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatConnect:
- {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
-
- LOG(INFO) << "connection request completed with result "
- << result << " (" << strerror(-result) << ")";
-
- if (result != OK) {
- (new AMessage(kWhatQuit, id()))->post();
- break;
- }
-
- mConnected = true;
-
- CHECK(msg->findInt32("server-ip", (int32_t *)&mServerIP));
-
- issueAnnounce();
- break;
- }
-
- case kWhatAnnounce:
- {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
-
- LOG(INFO) << "ANNOUNCE completed with result "
- << result << " (" << strerror(-result) << ")";
-
- sp<RefBase> obj;
- CHECK(msg->findObject("response", &obj));
- sp<ARTSPResponse> response;
-
- if (result == OK) {
- response = static_cast<ARTSPResponse *>(obj.get());
- CHECK(response != NULL);
-
- if (response->mStatusCode == 401) {
- if (mAuthType != NONE || !authenticate(response)) {
- LOG(INFO) << "FAILED to authenticate";
- (new AMessage(kWhatQuit, id()))->post();
- break;
- }
- break;
- }
- }
-
- if (result != OK || response->mStatusCode != 200) {
- (new AMessage(kWhatQuit, id()))->post();
- break;
- }
-
- unsigned rtpPort;
- ARTPConnection::MakePortPair(&mRTPSocket, &mRTCPSocket, &rtpPort);
-
- // (new AMessage(kWhatPoll, id()))->post();
-
- AString request;
- request.append("SETUP ");
- request.append(mTrackURL);
- request.append(" RTSP/1.0\r\n");
-
- addAuthentication(&request, "SETUP", mTrackURL.c_str());
-
- request.append("Transport: RTP/AVP;unicast;client_port=");
- request.append(rtpPort);
- request.append("-");
- request.append(rtpPort + 1);
- request.append(";mode=record\r\n");
- request.append("\r\n");
-
- sp<AMessage> reply = new AMessage(kWhatSetup, id());
- mConn->sendRequest(request.c_str(), reply);
- break;
- }
-
-#if 0
- case kWhatPoll:
- {
- PRPollDesc readPollDesc;
- readPollDesc.fd = mRTCPSocket;
- readPollDesc.in_flags = PR_POLL_READ;
-
- int numSocketsReadyToRead = PR_Poll(&readPollDesc, 1,
- PR_INTERVAL_NO_WAIT);
-
- if (numSocketsReadyToRead == 1) {
- sp<ABuffer> buffer = new ABuffer(65536);
- ssize_t n = PR_Recv(mRTCPSocket, buffer->data(), buffer->size(),
- 0, PR_INTERVAL_NO_WAIT);
-
- if (n <= 0) {
- LOG(ERROR) << "recv returned " << n;
- } else {
- LOG(INFO) << "recv returned " << n << " bytes of data.";
-
- hexdump(buffer->data(), n);
- }
- }
-
- msg->post(50000);
- break;
- }
-#endif
-
- case kWhatSetup:
- {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
-
- LOG(INFO) << "SETUP completed with result "
- << result << " (" << strerror(-result) << ")";
-
- sp<RefBase> obj;
- CHECK(msg->findObject("response", &obj));
- if (!obj.get()) {
- LOGE("No response to SETUP");
- (new AMessage(kWhatQuit, id()))->post();
- break;
- }
- sp<ARTSPResponse> response;
-
- if (result == OK) {
- response = static_cast<ARTSPResponse *>(obj.get());
- if (!response.get()) {
- LOGE("No response to SETUP");
- (new AMessage(kWhatQuit, id()))->post();
- break;
- }
- }
-
- if (result != OK || response->mStatusCode != 200) {
- LOGE("SETUP error")
- (new AMessage(kWhatQuit, id()))->post();
- break;
- }
-
- ssize_t i = response->mHeaders.indexOfKey("session");
- CHECK_GE(i, 0);
- mSessionID = response->mHeaders.valueAt(i);
- i = mSessionID.find(";");
- if (i >= 0) {
- // Remove options, i.e. ";timeout=90"
- mSessionID.erase(i, mSessionID.size() - i);
- }
-
- i = response->mHeaders.indexOfKey("transport");
- CHECK_GE(i, 0);
- AString transport = response->mHeaders.valueAt(i);
-
- LOG(INFO) << "transport = '" << transport << "'";
-
- AString value;
- CHECK(GetAttribute(transport.c_str(), "server_port", &value));
-
- unsigned rtpPort, rtcpPort;
- CHECK_EQ(sscanf(value.c_str(), "%u-%u", &rtpPort, &rtcpPort), 2);
-
- CHECK(GetAttribute(transport.c_str(), "source", &value));
-
- mRemoteAddr.inet.family = PR_AF_INET;
- mRemoteAddr.inet.port = PR_htons(rtpPort);
- PR_StringToNetAddr(value.c_str(), &mRemoteAddr);
-
- mRemoteRTCPAddr = mRemoteAddr;
- mRemoteRTCPAddr.inet.port = PR_htons(rtpPort + 1);
-
- CHECK_EQ(PR_SUCCESS, PR_Connect(mRTPSocket,
- &mRemoteAddr,
- PR_INTERVAL_NO_TIMEOUT));
-
- CHECK_EQ(PR_SUCCESS, PR_Connect(mRTCPSocket,
- &mRemoteRTCPAddr,
- PR_INTERVAL_NO_TIMEOUT));
-
- uint32_t x = PR_ntohl(mRemoteAddr.inet.ip);
- LOG(INFO) << "sending data to "
- << (x >> 24)
- << "."
- << ((x >> 16) & 0xff)
- << "."
- << ((x >> 8) & 0xff)
- << "."
- << (x & 0xff)
- << ":"
- << rtpPort;
-
- AString request;
- request.append("RECORD ");
- request.append(mStreamURL);
- request.append(" RTSP/1.0\r\n");
-
- addAuthentication(&request, "RECORD", mStreamURL.c_str());
-
- request.append("Session: ");
- request.append(mSessionID);
- request.append("\r\n");
- request.append("\r\n");
-
- sp<AMessage> reply = new AMessage(kWhatRecord, id());
- mConn->sendRequest(request.c_str(), reply);
- break;
- }
-
- case kWhatRecord:
- {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
-
- LOG(INFO) << "RECORD completed with result "
- << result << " (" << strerror(-result) << ")";
-
- sp<RefBase> obj;
- CHECK(msg->findObject("response", &obj));
- sp<ARTSPResponse> response;
-
- if (result == OK) {
- response = static_cast<ARTSPResponse *>(obj.get());
- CHECK(response != NULL);
- }
-
- if (result != OK) {
- (new AMessage(kWhatQuit, id()))->post();
- break;
- }
-
- (new AMessage(kWhatMore, id()))->post();
- (new AMessage(kWhatSendSR, id()))->post();
- (new AMessage(kWhatKeepAlive, id()))->post(30000000ll);
- break;
- }
-
- case kWhatKeepAlive:
- {
- if (!mConnected) {
- break;
- }
-
- AString request;
- request.append("OPTIONS ");
- request.append(mStreamURL);
- request.append(" RTSP/1.0\r\n");
-
- addAuthentication(&request, "RECORD", mStreamURL.c_str());
-
- request.append("Session: ");
- request.append(mSessionID);
- request.append("\r\n");
- request.append("\r\n");
-
- sp<AMessage> reply = new AMessage(kWhatOptions, id());
- mConn->sendRequest(request.c_str(), reply);
- break;
- }
-
- case kWhatOptions:
- {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
-
- LOG(INFO) << "OPTIONS completed with result "
- << result << " (" << strerror(-result) << ")";
-
- if (!mConnected) {
- break;
- }
-
- (new AMessage(kWhatKeepAlive, id()))->post(30000000ll);
- break;
- }
-
- case kWhatMore:
- {
- if (!mConnected) {
- break;
- }
-
- sp<ABuffer> buffer = new ABuffer(65536);
- uint8_t *data = buffer->data();
- data[0] = 0x80;
- data[1] = (1 << 7) | PT; // M-bit
- data[2] = (mSeqNo >> 8) & 0xff;
- data[3] = mSeqNo & 0xff;
- data[8] = mSourceID >> 24;
- data[9] = (mSourceID >> 16) & 0xff;
- data[10] = (mSourceID >> 8) & 0xff;
- data[11] = mSourceID & 0xff;
-
-#ifdef ANDROID
- MediaBuffer *mediaBuf = NULL;
- for (;;) {
- CHECK_EQ(mEncoder->read(&mediaBuf), (status_t)OK);
- if (mediaBuf->range_length() > 0) {
- break;
- }
- mediaBuf->release();
- mediaBuf = NULL;
- }
-
- int64_t timeUs;
- CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs));
-
- uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll);
-
- const uint8_t *mediaData =
- (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset();
-
- CHECK(!memcmp("\x00\x00\x00\x01", mediaData, 4));
-
- CHECK_LE(mediaBuf->range_length() - 4 + 12, buffer->size());
-
- memcpy(&data[12],
- mediaData + 4, mediaBuf->range_length() - 4);
-
- buffer->setRange(0, mediaBuf->range_length() - 4 + 12);
-
- mediaBuf->release();
- mediaBuf = NULL;
-#else
- uint32_t rtpTime = mRTPTimeBase + mNumRTPSent * 128;
- memset(&data[12], 0, 128);
- buffer->setRange(0, 12 + 128);
-#endif
-
- data[4] = rtpTime >> 24;
- data[5] = (rtpTime >> 16) & 0xff;
- data[6] = (rtpTime >> 8) & 0xff;
- data[7] = rtpTime & 0xff;
-
- ssize_t n = PR_Send(
- mRTPSocket, data, buffer->size(), 0, PR_INTERVAL_NO_WAIT);
- if (n < 0) {
- LOG(ERROR) << "send failed (" << strerror(errno) << ")";
- }
- CHECK_EQ(n, (ssize_t)buffer->size());
-
- ++mSeqNo;
-
- ++mNumRTPSent;
- mNumRTPOctetsSent += buffer->size() - 12;
-
- mLastRTPTime = rtpTime;
- mLastNTPTime = ntpTime();
-
-#ifdef ANDROID
- if (mNumRTPSent < 60 * 25) { // 60 secs worth
- msg->post(40000);
-#else
- if (mNumRTPOctetsSent < 8000 * 60) {
- msg->post(1000000ll * 128 / 8000);
-#endif
- } else {
- LOG(INFO) << "That's enough, pausing.";
-
- AString request;
- request.append("PAUSE ");
- request.append(mStreamURL);
- request.append(" RTSP/1.0\r\n");
-
- addAuthentication(&request, "PAUSE", mStreamURL.c_str());
-
- request.append("Session: ");
- request.append(mSessionID);
- request.append("\r\n");
- request.append("\r\n");
-
- sp<AMessage> reply = new AMessage(kWhatPerformPause, id());
- mConn->sendRequest(request.c_str(), reply);
- }
- break;
- }
-
- case kWhatSendSR:
- {
- if (!mConnected) {
- break;
- }
-
- sp<ABuffer> buffer = new ABuffer(65536);
- buffer->setRange(0, 0);
-
- addSR(buffer);
- addSDES(buffer);
-
- uint8_t *data = buffer->data();
- ssize_t n = send(
- mRTCPSocket, data, buffer->size(), 0);
- CHECK_EQ(n, (ssize_t)buffer->size());
-
- msg->post(3000000);
- break;
- }
-
- case kWhatPerformPause:
- {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
-
- LOG(INFO) << "PAUSE completed with result "
- << result << " (" << strerror(-result) << ")";
-
- sp<RefBase> obj;
- CHECK(msg->findObject("response", &obj));
- sp<ARTSPResponse> response;
-
- AString request;
- request.append("TEARDOWN ");
- request.append(mStreamURL);
- request.append(" RTSP/1.0\r\n");
-
- addAuthentication(&request, "TEARDOWN", mStreamURL.c_str());
-
- request.append("Session: ");
- request.append(mSessionID);
- request.append("\r\n");
- request.append("\r\n");
-
- sp<AMessage> reply = new AMessage(kWhatTeardown, id());
- mConn->sendRequest(request.c_str(), reply);
- break;
- }
-
- case kWhatTeardown:
- {
- int32_t result;
- CHECK(msg->findInt32("result", &result));
-
- LOG(INFO) << "TEARDOWN completed with result "
- << result << " (" << strerror(-result) << ")";
-
- sp<RefBase> obj;
- CHECK(msg->findObject("response", &obj));
- sp<ARTSPResponse> response;
-
- if (result == OK) {
- response = static_cast<ARTSPResponse *>(obj.get());
- CHECK(response != NULL);
- }
-
- (new AMessage(kWhatQuit, id()))->post();
- break;
- }
-
- case kWhatDisconnect:
- {
- LOG(INFO) << "disconnect completed";
-
- mConnected = false;
- (new AMessage(kWhatQuit, id()))->post();
- break;
- }
-
- case kWhatQuit:
- {
- if (mConnected) {
- mConn->disconnect(new AMessage(kWhatDisconnect, id()));
- break;
- }
-
- if (mRTPSocket >= 0) {
- close(mRTPSocket);
- mRTPSocket = -1;
- }
-
- if (mRTCPSocket >= 0) {
- close(mRTCPSocket);
- mRTCPSocket = -1;
- }
-
-#ifdef ANDROID
- mEncoder->stop();
- mEncoder.clear();
-#endif
-
- mLooper->stop();
- break;
- }
-
- default:
- TRESPASS();
- }
- }
-
-protected:
- virtual ~MyTransmitter() {
- }
-
-private:
- enum AuthType {
- NONE,
- BASIC,
- DIGEST
- };
-
- AString mServerURL;
- AString mTrackURL;
- AString mStreamURL;
-
- sp<ALooper> mLooper;
- sp<ARTSPConnection> mConn;
- bool mConnected;
- uint32_t mServerIP;
- AuthType mAuthType;
- AString mNonce;
- AString mSessionID;
- PRFileDesc *mRTPSocket, *mRTCPSocket;
- uint32_t mSourceID;
- uint32_t mSeqNo;
- uint32_t mRTPTimeBase;
- PRNetAddr mRemoteAddr;
- PRNetAddr mRemoteRTCPAddr;
- size_t mNumSamplesSent;
- uint32_t mNumRTPSent;
- uint32_t mNumRTPOctetsSent;
- uint32_t mLastRTPTime;
- uint64_t mLastNTPTime;
-
-#ifdef ANDROID
- sp<MediaSource> mEncoder;
- AString mSeqParamSet;
- AString mPicParamSet;
-
- void makeH264SPropParamSets(MediaBuffer *buffer) {
- static const char kStartCode[] = "\x00\x00\x00\x01";
-
- const uint8_t *data =
- (const uint8_t *)buffer->data() + buffer->range_offset();
- size_t size = buffer->range_length();
-
- CHECK_GE(size, 0u);
- CHECK(!memcmp(kStartCode, data, 4));
-
- data += 4;
- size -= 4;
-
- size_t startCodePos = 0;
- while (startCodePos + 3 < size
- && memcmp(kStartCode, &data[startCodePos], 4)) {
- ++startCodePos;
- }
-
- CHECK_LT(startCodePos + 3, size);
-
- encodeBase64(data, startCodePos, &mSeqParamSet);
-
- encodeBase64(&data[startCodePos + 4], size - startCodePos - 4,
- &mPicParamSet);
- }
-#endif
-
- void addSR(const sp<ABuffer> &buffer) {
- uint8_t *data = buffer->data() + buffer->size();
-
- data[0] = 0x80 | 0;
- data[1] = 200; // SR
- data[2] = 0;
- data[3] = 6;
- data[4] = mSourceID >> 24;
- data[5] = (mSourceID >> 16) & 0xff;
- data[6] = (mSourceID >> 8) & 0xff;
- data[7] = mSourceID & 0xff;
-
- data[8] = mLastNTPTime >> (64 - 8);
- data[9] = (mLastNTPTime >> (64 - 16)) & 0xff;
- data[10] = (mLastNTPTime >> (64 - 24)) & 0xff;
- data[11] = (mLastNTPTime >> 32) & 0xff;
- data[12] = (mLastNTPTime >> 24) & 0xff;
- data[13] = (mLastNTPTime >> 16) & 0xff;
- data[14] = (mLastNTPTime >> 8) & 0xff;
- data[15] = mLastNTPTime & 0xff;
-
- data[16] = (mLastRTPTime >> 24) & 0xff;
- data[17] = (mLastRTPTime >> 16) & 0xff;
- data[18] = (mLastRTPTime >> 8) & 0xff;
- data[19] = mLastRTPTime & 0xff;
-
- data[20] = mNumRTPSent >> 24;
- data[21] = (mNumRTPSent >> 16) & 0xff;
- data[22] = (mNumRTPSent >> 8) & 0xff;
- data[23] = mNumRTPSent & 0xff;
-
- data[24] = mNumRTPOctetsSent >> 24;
- data[25] = (mNumRTPOctetsSent >> 16) & 0xff;
- data[26] = (mNumRTPOctetsSent >> 8) & 0xff;
- data[27] = mNumRTPOctetsSent & 0xff;
-
- buffer->setRange(buffer->offset(), buffer->size() + 28);
- }
-
- void addSDES(const sp<ABuffer> &buffer) {
- uint8_t *data = buffer->data() + buffer->size();
- data[0] = 0x80 | 1;
- data[1] = 202; // SDES
- data[4] = mSourceID >> 24;
- data[5] = (mSourceID >> 16) & 0xff;
- data[6] = (mSourceID >> 8) & 0xff;
- data[7] = mSourceID & 0xff;
-
- size_t offset = 8;
-
- data[offset++] = 1; // CNAME
-
- static const char *kCNAME = "andih@laptop";
- data[offset++] = strlen(kCNAME);
-
- memcpy(&data[offset], kCNAME, strlen(kCNAME));
- offset += strlen(kCNAME);
-
- data[offset++] = 7; // NOTE
-
- static const char *kNOTE = "Hell's frozen over.";
- data[offset++] = strlen(kNOTE);
-
- memcpy(&data[offset], kNOTE, strlen(kNOTE));
- offset += strlen(kNOTE);
-
- data[offset++] = 0;
-
- if ((offset % 4) > 0) {
- size_t count = 4 - (offset % 4);
- switch (count) {
- case 3:
- data[offset++] = 0;
- case 2:
- data[offset++] = 0;
- case 1:
- data[offset++] = 0;
- }
- }
-
- size_t numWords = (offset / 4) - 1;
- data[2] = numWords >> 8;
- data[3] = numWords & 0xff;
-
- buffer->setRange(buffer->offset(), buffer->size() + offset);
- }
-
- DISALLOW_EVIL_CONSTRUCTORS(MyTransmitter);
-};
-
-} // namespace android
-
-#endif // RTSP_TRANSMITTER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/RtspPrlog.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* -*- 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 RTSPPRLOG_H
-#define RTSPPRLOG_H
-
-#include "mozilla/Logging.h"
-namespace mozilla {
-namespace net {
-extern LazyLogModule gRtspLog;
-}
-}
-
-#define LOGI(msg, ...) MOZ_LOG(mozilla::net::gRtspLog, mozilla::LogLevel::Info, (msg, ##__VA_ARGS__))
-#define LOGV(msg, ...) MOZ_LOG(mozilla::net::gRtspLog, mozilla::LogLevel::Debug, (msg, ##__VA_ARGS__))
-#define LOGE(msg, ...) MOZ_LOG(mozilla::net::gRtspLog, mozilla::LogLevel::Error, (msg, ##__VA_ARGS__))
-#define LOGW(msg, ...) MOZ_LOG(mozilla::net::gRtspLog, mozilla::LogLevel::Warning, (msg, ##__VA_ARGS__))
-
-#endif // RTSPPRLOG_H
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/UDPPusher.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "UDPPusher"
-#include <utils/Log.h>
-
-#include "UDPPusher.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <utils/ByteOrder.h>
-
-#include "prnetdb.h"
-#include "prerr.h"
-#include "NetworkActivityMonitor.h"
-
-using namespace mozilla::net;
-
-namespace android {
-
-UDPPusher::UDPPusher(const char *filename, unsigned port)
- : mFile(fopen(filename, "rb")),
- mFirstTimeMs(0),
- mFirstTimeUs(0) {
- CHECK(mFile != NULL);
-
- mSocket = PR_OpenUDPSocket(PR_AF_INET);
- if (!mSocket) {
- TRESPASS();
- }
-
- NetworkActivityMonitor::AttachIOLayer(mSocket);
-
- PRNetAddr addr;
- addr.inet.family = PR_AF_INET;
- addr.inet.ip = PR_htonl(PR_INADDR_ANY);
- addr.inet.port = PR_htons(0);
-
- CHECK_EQ(PR_SUCCESS, PR_Bind(mSocket, &addr));
-
- mRemoteAddr.inet.family = PR_AF_INET;
- mRemoteAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
- mRemoteAddr.inet.port = PR_htons(port);
-}
-
-UDPPusher::~UDPPusher() {
- if (mSocket) {
- PR_Close(mSocket);
- mSocket = nullptr;
- }
-
- fclose(mFile);
- mFile = NULL;
-}
-
-void UDPPusher::start() {
- uint32_t timeMs;
- CHECK_EQ(fread(&timeMs, 1, sizeof(timeMs), mFile), sizeof(timeMs));
- mFirstTimeMs = fromlel(timeMs);
- mFirstTimeUs = ALooper::GetNowUs();
-
- (new AMessage(kWhatPush, id()))->post();
-}
-
-bool UDPPusher::onPush() {
- uint32_t length;
- if (fread(&length, 1, sizeof(length), mFile) < sizeof(length)) {
- LOGI("No more data to push.");
- return false;
- }
-
- length = fromlel(length);
-
- if (length <= 0u) {
- LOGE("Zero length");
- return false;
- }
-
- sp<ABuffer> buffer = new ABuffer(length);
- if (fread(buffer->data(), 1, length, mFile) < length) {
- LOGE("File truncated?.");
- return false;
- }
-
- ssize_t n = PR_SendTo(
- mSocket, buffer->data(), buffer->size(), 0,
- &mRemoteAddr, PR_INTERVAL_NO_WAIT);
-
- CHECK_EQ(n, (ssize_t)buffer->size());
- if (n != (ssize_t)buffer->size()) {
- LOGE("Sizes don't match");
- return false;
- }
-
- uint32_t timeMs;
- if (fread(&timeMs, 1, sizeof(timeMs), mFile) < sizeof(timeMs)) {
- LOGI("No more data to push.");
- return false;
- }
-
- timeMs = fromlel(timeMs);
- if (timeMs < mFirstTimeMs) {
- LOGE("Time is wrong");
- return false;
- }
-
- timeMs -= mFirstTimeMs;
- int64_t whenUs = mFirstTimeUs + timeMs * 1000ll;
- int64_t nowUs = ALooper::GetNowUs();
- (new AMessage(kWhatPush, id()))->post(whenUs - nowUs);
-
- return true;
-}
-
-void UDPPusher::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatPush:
- {
- if (!onPush() && !(ntohs(mRemoteAddr.sin_port) & 1)) {
- LOGI("emulating BYE packet");
-
- sp<ABuffer> buffer = new ABuffer(8);
- uint8_t *data = buffer->data();
- *data++ = (2 << 6) | 1;
- *data++ = 203;
- *data++ = 0;
- *data++ = 1;
- *data++ = 0x8f;
- *data++ = 0x49;
- *data++ = 0xc0;
- *data++ = 0xd0;
- buffer->setRange(0, 8);
-
- struct sockaddr_in tmp = mRemoteAddr;
- tmp.sin_port = htons(ntohs(mRemoteAddr.sin_port) | 1);
-
- ssize_t n = PR_SendTo(
- mSocket, buffer->data(), buffer->size(), 0,
- &tmp, PR_INTERVAL_NO_WAIT);
-
- MOZ_ASSERT(n, (ssize_t)buffer->size());
- }
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
-}
-
-} // namespace android
-
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/UDPPusher.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef UDP_PUSHER_H_
-
-#define UDP_PUSHER_H_
-
-#include <media/stagefright/foundation/AHandler.h>
-
-#include <stdio.h>
-#include <arpa/inet.h>
-
-#include "prio.h"
-
-namespace android {
-
-struct UDPPusher : public AHandler {
- UDPPusher(const char *filename, unsigned port);
-
- void start();
-
-protected:
- virtual ~UDPPusher();
- virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
- enum {
- kWhatPush = 1
- };
-
- FILE *mFile;
- PRFileDesc *mSocket;
- PRNetAddr mRemoteAddr;
-
- uint32_t mFirstTimeMs;
- int64_t mFirstTimeUs;
-
- bool onPush();
-
- DISALLOW_EVIL_CONSTRUCTORS(UDPPusher);
-};
-
-} // namespace android
-
-#endif // UDP_PUSHER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/VideoSource.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef VIDEO_SOURCE_H_
-
-#define VIDEO_SOURCE_H_
-
-#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/MetaData.h>
-
-namespace android {
-
-class VideoSource : public MediaSource {
- static const int32_t kFramerate = 24; // fps
-
-public:
- VideoSource(int width, int height)
- : mWidth(width),
- mHeight(height),
- mSize((width * height * 3) / 2) {
- mGroup.add_buffer(new MediaBuffer(mSize));
- }
-
- virtual sp<MetaData> getFormat() {
- sp<MetaData> meta = new MetaData;
- meta->setInt32(kKeyWidth, mWidth);
- meta->setInt32(kKeyHeight, mHeight);
- meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
-
- return meta;
- }
-
- virtual status_t start(MetaData *params) {
- mNumFramesOutput = 0;
- return OK;
- }
-
- virtual status_t stop() {
- return OK;
- }
-
- virtual status_t read(
- MediaBuffer **buffer, const MediaSource::ReadOptions *options) {
- if (mNumFramesOutput == kFramerate * 100) {
- // Stop returning data after 10 secs.
- return ERROR_END_OF_STREAM;
- }
-
- // printf("VideoSource::read\n");
- status_t err = mGroup.acquire_buffer(buffer);
- if (err != OK) {
- return err;
- }
-
- char x = (char)((double)rand() / RAND_MAX * 255);
- memset((*buffer)->data(), x, mSize);
- (*buffer)->set_range(0, mSize);
- (*buffer)->meta_data()->clear();
- (*buffer)->meta_data()->setInt64(
- kKeyTime, (mNumFramesOutput * 1000000) / kFramerate);
- ++mNumFramesOutput;
-
- // printf("VideoSource::read - returning buffer\n");
- // LOG(INFO)("VideoSource::read - returning buffer");
- return OK;
- }
-
-protected:
- virtual ~VideoSource() {}
-
-private:
- MediaBufferGroup mGroup;
- int mWidth, mHeight;
- size_t mSize;
- int64_t mNumFramesOutput;;
-
- VideoSource(const VideoSource &);
- VideoSource &operator=(const VideoSource &);
-};
-
-} // namespace android
-
-#endif // VIDEO_SOURCE_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/rtp_test.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "rtp_test"
-#include <utils/Log.h>
-
-#include <binder/ProcessState.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/DataSource.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/OMXClient.h>
-#include <media/stagefright/OMXCodec.h>
-#include <media/stagefright/foundation/base64.h>
-
-#include "ARTPSession.h"
-#include "ASessionDescription.h"
-#include "UDPPusher.h"
-
-using namespace android;
-
-int main(int argc, char **argv) {
- android::ProcessState::self()->startThreadPool();
-
- DataSource::RegisterDefaultSniffers();
-
- const char *rtpFilename = NULL;
- const char *rtcpFilename = NULL;
-
- if (argc == 3) {
- rtpFilename = argv[1];
- rtcpFilename = argv[2];
- } else if (argc != 1) {
- fprintf(stderr, "usage: %s [ rtpFilename rtcpFilename ]\n", argv[0]);
- return 1;
- }
-
-#if 0
- static const uint8_t kSPS[] = {
- 0x67, 0x42, 0x80, 0x0a, 0xe9, 0x02, 0x83, 0xe4, 0x20, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x0e, 0xa6, 0x00, 0x80
- };
- static const uint8_t kPPS[] = {
- 0x68, 0xce, 0x3c, 0x80
- };
- AString out1, out2;
- encodeBase64(kSPS, sizeof(kSPS), &out1);
- encodeBase64(kPPS, sizeof(kPPS), &out2);
- printf("params=%s,%s\n", out1.c_str(), out2.c_str());
-#endif
-
- sp<ALooper> looper = new ALooper;
-
- sp<UDPPusher> rtp_pusher;
- sp<UDPPusher> rtcp_pusher;
-
- if (rtpFilename != NULL) {
- rtp_pusher = new UDPPusher(rtpFilename, 5434);
- looper->registerHandler(rtp_pusher);
-
- rtcp_pusher = new UDPPusher(rtcpFilename, 5435);
- looper->registerHandler(rtcp_pusher);
- }
-
- sp<ARTPSession> session = new ARTPSession;
- looper->registerHandler(session);
-
-#if 0
- // My H264 SDP
- static const char *raw =
- "v=0\r\n"
- "o=- 64 233572944 IN IP4 127.0.0.0\r\n"
- "s=QuickTime\r\n"
- "t=0 0\r\n"
- "a=range:npt=0-315\r\n"
- "a=isma-compliance:2,2.0,2\r\n"
- "m=video 5434 RTP/AVP 97\r\n"
- "c=IN IP4 127.0.0.1\r\n"
- "b=AS:30\r\n"
- "a=rtpmap:97 H264/90000\r\n"
- "a=fmtp:97 packetization-mode=1;profile-level-id=42000C;"
- "sprop-parameter-sets=Z0IADJZUCg+I,aM44gA==\r\n"
- "a=mpeg4-esid:201\r\n"
- "a=cliprect:0,0,240,320\r\n"
- "a=framesize:97 320-240\r\n";
-#elif 0
- // My H263 SDP
- static const char *raw =
- "v=0\r\n"
- "o=- 64 233572944 IN IP4 127.0.0.0\r\n"
- "s=QuickTime\r\n"
- "t=0 0\r\n"
- "a=range:npt=0-315\r\n"
- "a=isma-compliance:2,2.0,2\r\n"
- "m=video 5434 RTP/AVP 97\r\n"
- "c=IN IP4 127.0.0.1\r\n"
- "b=AS:30\r\n"
- "a=rtpmap:97 H263-1998/90000\r\n"
- "a=cliprect:0,0,240,320\r\n"
- "a=framesize:97 320-240\r\n";
-#elif 0
- // My AMR SDP
- static const char *raw =
- "v=0\r\n"
- "o=- 64 233572944 IN IP4 127.0.0.0\r\n"
- "s=QuickTime\r\n"
- "t=0 0\r\n"
- "a=range:npt=0-315\r\n"
- "a=isma-compliance:2,2.0,2\r\n"
- "m=audio 5434 RTP/AVP 97\r\n"
- "c=IN IP4 127.0.0.1\r\n"
- "b=AS:30\r\n"
- "a=rtpmap:97 AMR/8000/1\r\n"
- "a=fmtp:97 octet-align\r\n";
-#elif 1
- // GTalk's H264 SDP
- static const char *raw =
- "v=0\r\n"
- "o=- 64 233572944 IN IP4 127.0.0.0\r\n"
- "s=QuickTime\r\n"
- "t=0 0\r\n"
- "a=range:npt=now-\r\n"
- "m=video 5434 RTP/AVP 96\r\n"
- "c=IN IP4 127.0.0.1\r\n"
- "b=AS:320000\r\n"
- "a=rtpmap:96 H264/90000\r\n"
- "a=fmtp:96 packetization-mode=1;profile-level-id=42001E;"
- "sprop-parameter-sets=Z0IAHpZUBaHogA==,aM44gA==\r\n"
- "a=cliprect:0,0,480,270\r\n"
- "a=framesize:96 720-480\r\n";
-#else
- // sholes H264 SDP
- static const char *raw =
- "v=0\r\n"
- "o=- 64 233572944 IN IP4 127.0.0.0\r\n"
- "s=QuickTime\r\n"
- "t=0 0\r\n"
- "a=range:npt=now-\r\n"
- "m=video 5434 RTP/AVP 96\r\n"
- "c=IN IP4 127.0.0.1\r\n"
- "b=AS:320000\r\n"
- "a=rtpmap:96 H264/90000\r\n"
- "a=fmtp:96 packetization-mode=1;profile-level-id=42001E;"
- "sprop-parameter-sets=Z0KACukCg+QgAAB9AAAOpgCA,aM48gA==\r\n"
- "a=cliprect:0,0,240,320\r\n"
- "a=framesize:96 320-240\r\n";
-#endif
-
- sp<ASessionDescription> desc = new ASessionDescription;
- CHECK(desc->setTo(raw, strlen(raw)));
-
- CHECK_EQ(session->setup(desc), (status_t)OK);
-
- if (rtp_pusher != NULL) {
- rtp_pusher->start();
- }
-
- if (rtcp_pusher != NULL) {
- rtcp_pusher->start();
- }
-
- looper->start(false /* runOnCallingThread */);
-
- CHECK_EQ(session->countTracks(), 1u);
- sp<MediaSource> source = session->trackAt(0);
-
- OMXClient client;
- CHECK_EQ(client.connect(), (status_t)OK);
-
- sp<MediaSource> decoder = OMXCodec::Create(
- client.interface(),
- source->getFormat(), false /* createEncoder */,
- source,
- NULL,
- 0); // OMXCodec::kPreferSoftwareCodecs);
- CHECK(decoder != NULL);
-
- CHECK_EQ(decoder->start(), (status_t)OK);
-
- for (;;) {
- MediaBuffer *buffer;
- status_t err = decoder->read(&buffer);
-
- if (err != OK) {
- if (err == INFO_FORMAT_CHANGED) {
- int32_t width, height;
- CHECK(decoder->getFormat()->findInt32(kKeyWidth, &width));
- CHECK(decoder->getFormat()->findInt32(kKeyHeight, &height));
- printf("INFO_FORMAT_CHANGED %d x %d\n", width, height);
- continue;
- }
-
- LOGE("decoder returned error 0x%08x", err);
- break;
- }
-
-#if 1
- if (buffer->range_length() != 0) {
- int64_t timeUs;
- CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
-
- printf("decoder returned frame of size %d at time %.2f secs\n",
- buffer->range_length(), timeUs / 1E6);
- }
-#endif
-
- buffer->release();
- buffer = NULL;
- }
-
- CHECK_EQ(decoder->stop(), (status_t)OK);
-
- looper->stop();
-
- return 0;
-}