1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/protocol/rtsp/controller/RtspControllerParent.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,303 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set sw=2 ts=8 et tw=80 : */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "RtspControllerParent.h" 1.11 +#include "RtspController.h" 1.12 +#include "nsIAuthPromptProvider.h" 1.13 +#include "nsThreadUtils.h" 1.14 +#include "nsProxyRelease.h" 1.15 +#include "mozilla/ipc/InputStreamUtils.h" 1.16 +#include "mozilla/ipc/URIUtils.h" 1.17 +#include "mozilla/unused.h" 1.18 +#include "nsNetUtil.h" 1.19 +#include "prlog.h" 1.20 + 1.21 +#include <sys/types.h> 1.22 +#include <sys/socket.h> 1.23 + 1.24 +PRLogModuleInfo* gRtspLog; 1.25 +#undef LOG 1.26 +#define LOG(args) PR_LOG(gRtspLog, PR_LOG_DEBUG, args) 1.27 + 1.28 +#define SEND_DISCONNECT_IF_ERROR(rv) \ 1.29 + if (NS_FAILED(rv) && mIPCOpen && mTotalTracks > 0ul) { \ 1.30 + for (uint32_t i = 0; i < mTotalTracks; i++) { \ 1.31 + unused << SendOnDisconnected(i, rv); \ 1.32 + } \ 1.33 + } 1.34 + 1.35 +using namespace mozilla::ipc; 1.36 + 1.37 +namespace mozilla { 1.38 +namespace net { 1.39 + 1.40 +void 1.41 +RtspControllerParent::Destroy() 1.42 +{ 1.43 + // If we're being destroyed on a non-main thread, we AddRef again and use a 1.44 + // proxy to release the RtspControllerParent on the main thread, where the 1.45 + // RtspControllerParent is deleted. This ensures we only delete the 1.46 + // RtspControllerParent on the main thread. 1.47 + if (!NS_IsMainThread()) { 1.48 + nsCOMPtr<nsIThread> mainThread = do_GetMainThread(); 1.49 + NS_ENSURE_TRUE_VOID(mainThread); 1.50 + nsRefPtr<RtspControllerParent> doomed(this); 1.51 + if (NS_FAILED(NS_ProxyRelease(mainThread, 1.52 + static_cast<nsIStreamingProtocolListener*>(doomed), true))) { 1.53 + NS_WARNING("Failed to proxy release to main thread!"); 1.54 + } 1.55 + } else { 1.56 + delete this; 1.57 + } 1.58 +} 1.59 + 1.60 +NS_IMPL_ADDREF(RtspControllerParent) 1.61 +NS_IMPL_RELEASE_WITH_DESTROY(RtspControllerParent, Destroy()) 1.62 +NS_IMPL_QUERY_INTERFACE(RtspControllerParent, 1.63 + nsIInterfaceRequestor, 1.64 + nsIStreamingProtocolListener) 1.65 + 1.66 +RtspControllerParent::RtspControllerParent() 1.67 + : mIPCOpen(true) 1.68 + , mTotalTracks(0) 1.69 +{ 1.70 +#if defined(PR_LOGGING) 1.71 + if (!gRtspLog) 1.72 + gRtspLog = PR_NewLogModule("nsRtsp"); 1.73 +#endif 1.74 +} 1.75 + 1.76 +RtspControllerParent::~RtspControllerParent() 1.77 +{ 1.78 +} 1.79 + 1.80 +void 1.81 +RtspControllerParent::ActorDestroy(ActorDestroyReason why) 1.82 +{ 1.83 + LOG(("RtspControllerParent::ActorDestroy()")); 1.84 + mIPCOpen = false; 1.85 + 1.86 + NS_ENSURE_TRUE_VOID(mController); 1.87 + if (mController) { 1.88 + mController->Stop(); 1.89 + mController = nullptr; 1.90 + } 1.91 +} 1.92 + 1.93 +bool 1.94 +RtspControllerParent::RecvAsyncOpen(const URIParams& aURI) 1.95 +{ 1.96 + LOG(("RtspControllerParent::RecvAsyncOpen()")); 1.97 + 1.98 + mURI = DeserializeURI(aURI); 1.99 + 1.100 + mController = new RtspController(nullptr); 1.101 + mController->Init(mURI); 1.102 + nsresult rv = mController->AsyncOpen(this); 1.103 + if (NS_SUCCEEDED(rv)) return true; 1.104 + 1.105 + mController = nullptr; 1.106 + return SendAsyncOpenFailed(rv); 1.107 +} 1.108 + 1.109 +bool 1.110 +RtspControllerParent::RecvPlay() 1.111 +{ 1.112 + LOG(("RtspControllerParent::RecvPlay()")); 1.113 + NS_ENSURE_TRUE(mController, true); 1.114 + 1.115 + nsresult rv = mController->Play(); 1.116 + SEND_DISCONNECT_IF_ERROR(rv) 1.117 + return true; 1.118 +} 1.119 + 1.120 +bool 1.121 +RtspControllerParent::RecvPause() 1.122 +{ 1.123 + LOG(("RtspControllerParent::RecvPause()")); 1.124 + NS_ENSURE_TRUE(mController, true); 1.125 + 1.126 + nsresult rv = mController->Pause(); 1.127 + SEND_DISCONNECT_IF_ERROR(rv) 1.128 + return true; 1.129 +} 1.130 + 1.131 +bool 1.132 +RtspControllerParent::RecvResume() 1.133 +{ 1.134 + LOG(("RtspControllerParent::RecvResume()")); 1.135 + NS_ENSURE_TRUE(mController, true); 1.136 + 1.137 + nsresult rv = mController->Resume(); 1.138 + SEND_DISCONNECT_IF_ERROR(rv) 1.139 + return true; 1.140 +} 1.141 + 1.142 +bool 1.143 +RtspControllerParent::RecvSuspend() 1.144 +{ 1.145 + LOG(("RtspControllerParent::RecvSuspend()")); 1.146 + NS_ENSURE_TRUE(mController, true); 1.147 + 1.148 + nsresult rv = mController->Suspend(); 1.149 + SEND_DISCONNECT_IF_ERROR(rv) 1.150 + return true; 1.151 +} 1.152 + 1.153 +bool 1.154 +RtspControllerParent::RecvSeek(const uint64_t& offset) 1.155 +{ 1.156 + LOG(("RtspControllerParent::RecvSeek()")); 1.157 + NS_ENSURE_TRUE(mController, true); 1.158 + 1.159 + nsresult rv = mController->Seek(offset); 1.160 + SEND_DISCONNECT_IF_ERROR(rv) 1.161 + return true; 1.162 +} 1.163 + 1.164 +bool 1.165 +RtspControllerParent::RecvStop() 1.166 +{ 1.167 + LOG(("RtspControllerParent::RecvStop()")); 1.168 + NS_ENSURE_TRUE(mController, true); 1.169 + 1.170 + nsresult rv = mController->Stop(); 1.171 + NS_ENSURE_SUCCESS(rv, true); 1.172 + return true; 1.173 +} 1.174 + 1.175 +NS_IMETHODIMP 1.176 +RtspControllerParent::OnMediaDataAvailable(uint8_t index, 1.177 + const nsACString & data, 1.178 + uint32_t length, 1.179 + uint32_t offset, 1.180 + nsIStreamingProtocolMetaData *meta) 1.181 +{ 1.182 + NS_ENSURE_ARG_POINTER(meta); 1.183 + uint32_t int32Value; 1.184 + uint64_t int64Value; 1.185 + 1.186 + nsresult rv = meta->GetTimeStamp(&int64Value); 1.187 + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); 1.188 + 1.189 + LOG(("RtspControllerParent:: OnMediaDataAvailable %d:%d time %lld", 1.190 + index, length, int64Value)); 1.191 + 1.192 + // Serialize meta data. 1.193 + nsCString name; 1.194 + name.AssignLiteral("TIMESTAMP"); 1.195 + InfallibleTArray<RtspMetadataParam> metaData; 1.196 + metaData.AppendElement(RtspMetadataParam(name, int64Value)); 1.197 + 1.198 + name.AssignLiteral("FRAMETYPE"); 1.199 + rv = meta->GetFrameType(&int32Value); 1.200 + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); 1.201 + metaData.AppendElement(RtspMetadataParam(name, int32Value)); 1.202 + 1.203 + nsCString stream; 1.204 + stream.Assign(data); 1.205 + if (!mIPCOpen || 1.206 + !SendOnMediaDataAvailable(index, stream, length, offset, metaData)) { 1.207 + return NS_ERROR_FAILURE; 1.208 + } 1.209 + return NS_OK; 1.210 +} 1.211 + 1.212 +NS_IMETHODIMP 1.213 +RtspControllerParent::OnConnected(uint8_t index, 1.214 + nsIStreamingProtocolMetaData *meta) 1.215 +{ 1.216 + NS_ENSURE_ARG_POINTER(meta); 1.217 + uint32_t int32Value; 1.218 + uint64_t int64Value; 1.219 + 1.220 + LOG(("RtspControllerParent:: OnConnected")); 1.221 + // Serialize meta data. 1.222 + InfallibleTArray<RtspMetadataParam> metaData; 1.223 + nsCString name; 1.224 + name.AssignLiteral("TRACKS"); 1.225 + nsresult rv = meta->GetTotalTracks(&mTotalTracks); 1.226 + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); 1.227 + metaData.AppendElement(RtspMetadataParam(name, mTotalTracks)); 1.228 + 1.229 + name.AssignLiteral("MIMETYPE"); 1.230 + nsCString mimeType; 1.231 + rv = meta->GetMimeType(mimeType); 1.232 + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); 1.233 + metaData.AppendElement(RtspMetadataParam(name, mimeType)); 1.234 + 1.235 + name.AssignLiteral("WIDTH"); 1.236 + rv = meta->GetWidth(&int32Value); 1.237 + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); 1.238 + metaData.AppendElement(RtspMetadataParam(name, int32Value)); 1.239 + 1.240 + name.AssignLiteral("HEIGHT"); 1.241 + rv = meta->GetHeight(&int32Value); 1.242 + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); 1.243 + metaData.AppendElement(RtspMetadataParam(name, int32Value)); 1.244 + 1.245 + name.AssignLiteral("DURATION"); 1.246 + rv = meta->GetDuration(&int64Value); 1.247 + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); 1.248 + metaData.AppendElement(RtspMetadataParam(name, int64Value)); 1.249 + 1.250 + name.AssignLiteral("SAMPLERATE"); 1.251 + rv = meta->GetSampleRate(&int32Value); 1.252 + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); 1.253 + metaData.AppendElement(RtspMetadataParam(name, int32Value)); 1.254 + 1.255 + name.AssignLiteral("TIMESTAMP"); 1.256 + rv = meta->GetTimeStamp(&int64Value); 1.257 + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); 1.258 + metaData.AppendElement(RtspMetadataParam(name, int64Value)); 1.259 + 1.260 + name.AssignLiteral("CHANNELCOUNT"); 1.261 + rv = meta->GetChannelCount(&int32Value); 1.262 + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); 1.263 + metaData.AppendElement(RtspMetadataParam(name, int32Value)); 1.264 + 1.265 + nsCString esds; 1.266 + rv = meta->GetEsdsData(esds); 1.267 + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); 1.268 + name.AssignLiteral("ESDS"); 1.269 + metaData.AppendElement(RtspMetadataParam(name, esds)); 1.270 + 1.271 + nsCString avcc; 1.272 + rv = meta->GetAvccData(avcc); 1.273 + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); 1.274 + name.AssignLiteral("AVCC"); 1.275 + metaData.AppendElement(RtspMetadataParam(name, avcc)); 1.276 + 1.277 + if (!mIPCOpen || !SendOnConnected(index, metaData)) { 1.278 + return NS_ERROR_FAILURE; 1.279 + } 1.280 + 1.281 + return NS_OK; 1.282 +} 1.283 + 1.284 +NS_IMETHODIMP 1.285 +RtspControllerParent::OnDisconnected(uint8_t index, 1.286 + nsresult reason) 1.287 +{ 1.288 + LOG(("RtspControllerParent::OnDisconnected() for track %d reason = 0x%x", index, reason)); 1.289 + if (!mIPCOpen || !SendOnDisconnected(index, reason)) { 1.290 + return NS_ERROR_FAILURE; 1.291 + } 1.292 + if (mController) { 1.293 + mController = nullptr; 1.294 + } 1.295 + return NS_OK; 1.296 +} 1.297 + 1.298 +NS_IMETHODIMP 1.299 +RtspControllerParent::GetInterface(const nsIID & iid, void **result) 1.300 +{ 1.301 + LOG(("RtspControllerParent::GetInterface()")); 1.302 + return QueryInterface(iid, result); 1.303 +} 1.304 + 1.305 +} // namespace net 1.306 +} // namespace mozilla