This commit is contained in:
Ryan VanderMeulen 2014-04-22 12:50:29 -07:00
Родитель 92378320da 6f65169861
Коммит e4daf0a0d5
43 изменённых файлов: 985 добавлений и 301 удалений

Просмотреть файл

@ -49,7 +49,7 @@ pref("network.protocol-handler.warn-external.vnd.youtube", false);
// By default, all protocol handlers are exposed. This means that the browser
// will response to openURL commands for all URL types. It will also try to open
// link clicks inside the browser before failing over to the system handlers.
pref("network.protocol-handler.expose.rtsp", false);
pref("network.protocol-handler.expose.rtsp", true);
/* http prefs */
pref("network.http.pipelining", true);

Просмотреть файл

@ -19,11 +19,11 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="55bcc2d7e44dc805c24b57d1e783fc26e8a2ee86"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="52720b94a4f709d5f96c23b2d63c398e7002ecb9"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="0292e64ef8451df104dcf9ac3b2c6749b81684dd"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="85f9690323b235f4dcf2901ea2240d3c60fc22a0"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
<!-- Stock Android things -->

Просмотреть файл

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
@ -128,7 +128,7 @@
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="09485b73629856b21b2ed6073e327ab0e69a1189"/>
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="8afce6d5d48b71b6e7cb917179fb6147fb747521"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9a00b3db898a83ef0766baa93e935e525572899e"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="72e3a520e3c700839f07ba0113fd527b923c3330"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="baaf899afb158b9530690002f3656e958e3eb047"/>

Просмотреть файл

@ -12,10 +12,10 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="52c909ccead537f8f9dbf634f3e6639078a8b0bd">
<project name="platform_build" path="build" remote="b2g" revision="65fba428f8d76336b33ddd9e15900357953600ba">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
@ -119,15 +119,15 @@
<project name="platform/system/netd" path="system/netd" revision="36704b0da24debcab8090156568ac236315036bb"/>
<project name="platform/system/security" path="system/security" revision="583374f69f531ba68fc3dcbff1f74893d2a96406"/>
<project name="platform/system/vold" path="system/vold" revision="d4455b8cf361f8353e8aebac15ffd64b4aedd2b9"/>
<project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="ee814270f52127febfcf29bacf9f1b327d7c4c29"/>
<project name="platform_system_core" path="system/core" remote="b2g" revision="9395eb5aa885cf6d305a202de6e9694a58a89717"/>
<default remote="caf" revision="refs/tags/android-4.4.2_r1" sync-j="4"/>
<!-- Emulator specific things -->
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="72ffdf71c68a96309212eb13d63560d66db14c9e"/>
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="a706bf388e30ec1f5273cf72cd0156e429f23fac"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="0909f27aaa6bf55314edddb48bb1cd6296a2d55c"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="3ef6c54fd5bba6fbd4c11f3870ab3aa32693f0da"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="694cecf256122d0cb3b6a1a4efb4b5c7401db223"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="e5dba2723b3e417b107cf9546fb8e10b98e977ae"/>
<project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="ee814270f52127febfcf29bacf9f1b327d7c4c29"/>
<project name="platform_system_core" path="system/core" remote="b2g" revision="9395eb5aa885cf6d305a202de6e9694a58a89717"/>
<project name="platform/development" path="development" revision="5968ff4e13e0d696ad8d972281fc27ae5a12829b"/>
<project name="android-sdk" path="sdk" remote="b2g" revision="0951179277915335251c5e11d242e4e1a8c2236f"/>
</manifest>

Просмотреть файл

@ -19,11 +19,11 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="55bcc2d7e44dc805c24b57d1e783fc26e8a2ee86"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="52720b94a4f709d5f96c23b2d63c398e7002ecb9"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="0292e64ef8451df104dcf9ac3b2c6749b81684dd"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="85f9690323b235f4dcf2901ea2240d3c60fc22a0"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
<!-- Stock Android things -->

Просмотреть файл

@ -18,7 +18,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>

Просмотреть файл

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "3f54f719dc145f1544db67881a48819559ecb71b",
"revision": "b209dbf62facaae103d9a577ef885d429a431d6c",
"repo_path": "/integration/gaia-central"
}

Просмотреть файл

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

Просмотреть файл

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

Просмотреть файл

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>

Просмотреть файл

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

Просмотреть файл

@ -430,6 +430,11 @@ DecoderTraits::CanHandleMediaType(const char* aMIMEType,
if (MediaDecoder::IsMediaPluginsEnabled() &&
GetMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), &codecList))
result = CANPLAY_MAYBE;
#endif
#ifdef NECKO_PROTOCOL_rtsp
if (IsRtspSupportedType(nsDependentCString(aMIMEType))) {
result = CANPLAY_MAYBE;
}
#endif
if (result == CANPLAY_NO || !aHaveRequestedCodecs || !codecList) {
return result;
@ -664,6 +669,9 @@ bool DecoderTraits::IsSupportedInVideoDocument(const nsACString& aType)
#endif
#ifdef MOZ_APPLEMEDIA
IsAppleMediaSupportedType(aType) ||
#endif
#ifdef NECKO_PROTOCOL_rtsp
IsRtspSupportedType(aType) ||
#endif
false;
}

Просмотреть файл

@ -1552,6 +1552,11 @@ MediaCache::ReleaseStream(MediaCacheStream* aStream)
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
CACHE_LOG(PR_LOG_DEBUG, ("Stream %p closed", aStream));
mStreams.RemoveElement(aStream);
// Update MediaCache again for |mStreams| is changed.
// We need to re-run Update() to ensure streams reading from the same resource
// as the removed stream get a chance to continue reading.
gMediaCache->QueueUpdate();
}
void

Просмотреть файл

@ -15,6 +15,10 @@
#include "nsIScriptSecurityManager.h"
#include "nsIStreamingProtocolService.h"
#include "nsServiceManagerUtils.h"
#ifdef NECKO_PROTOCOL_rtsp
#include "mozilla/net/RtspChannelChild.h"
#endif
using namespace mozilla::net;
#ifdef PR_LOGGING
PRLogModuleInfo* gRtspMediaResourceLog;
@ -37,9 +41,9 @@ namespace mozilla {
* Even though the ring buffer is divided into fixed size slots, it still can
* store the data which size is larger than one slot size.
* */
#define BUFFER_SLOT_NUM 512
#define BUFFER_SLOT_NUM 8192
#define BUFFER_SLOT_DEFAULT_SIZE 256
#define BUFFER_SLOT_MAX_SIZE 8192
#define BUFFER_SLOT_MAX_SIZE 512
#define BUFFER_SLOT_INVALID -1
#define BUFFER_SLOT_EMPTY 0
@ -354,21 +358,21 @@ RtspMediaResource::RtspMediaResource(MediaDecoder* aDecoder,
, mIsConnected(false)
, mRealTime(false)
{
nsCOMPtr<nsIStreamingProtocolControllerService> mediaControllerService =
do_GetService(MEDIASTREAMCONTROLLERSERVICE_CONTRACTID);
MOZ_ASSERT(mediaControllerService);
if (mediaControllerService) {
mediaControllerService->Create(mChannel,
getter_AddRefs(mMediaStreamController));
#ifndef NECKO_PROTOCOL_rtsp
MOZ_CRASH("Should not be called except for B2G platform");
#else
MOZ_ASSERT(aChannel);
mMediaStreamController =
static_cast<RtspChannelChild*>(aChannel)->GetController();
MOZ_ASSERT(mMediaStreamController);
mListener = new Listener(this);
mMediaStreamController->AsyncOpen(mListener);
}
#ifdef PR_LOGGING
if (!gRtspMediaResourceLog) {
gRtspMediaResourceLog = PR_NewLogModule("RtspMediaResource");
}
#endif
#endif
}
RtspMediaResource::~RtspMediaResource()
@ -634,6 +638,9 @@ RtspMediaResource::OnDisconnected(uint8_t aTrackIdx, nsresult aReason)
void RtspMediaResource::Suspend(bool aCloseImmediately)
{
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
if (NS_WARN_IF(!mDecoder)) {
return;
}
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
NS_ENSURE_TRUE_VOID(owner);
@ -647,6 +654,9 @@ void RtspMediaResource::Suspend(bool aCloseImmediately)
void RtspMediaResource::Resume()
{
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
if (NS_WARN_IF(!mDecoder)) {
return;
}
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
NS_ENSURE_TRUE_VOID(owner);

Просмотреть файл

@ -175,6 +175,7 @@ LOCAL_INCLUDES += [
'/content/base/src',
'/layout/generic',
'/layout/xul',
'/netwerk/base/src',
]
if CONFIG['MOZ_DIRECTSHOW']:

Просмотреть файл

@ -47,6 +47,10 @@ PRLogModuleInfo* gAudioOffloadPlayerLog;
#define AUDIO_OFFLOAD_LOG(type, msg)
#endif
// maximum time in paused state when offloading audio decompression.
// When elapsed, the AudioSink is destroyed to allow the audio DSP to power down.
static const uint64_t OFFLOAD_PAUSE_MAX_MSECS = 60000ll;
AudioOffloadPlayer::AudioOffloadPlayer(MediaOmxDecoder* aObserver) :
mObserver(aObserver),
mInputBuffer(nullptr),
@ -78,9 +82,7 @@ AudioOffloadPlayer::AudioOffloadPlayer(MediaOmxDecoder* aObserver) :
AudioOffloadPlayer::~AudioOffloadPlayer()
{
if (mStarted) {
Reset();
}
AudioSystem::releaseAudioSessionId(mSessionId);
}
@ -109,12 +111,6 @@ status_t AudioOffloadPlayer::Start(bool aSourceAlreadyStarted)
}
}
MediaSource::ReadOptions options;
if (mSeeking) {
options.setSeekTo(mSeekTimeUs);
mSeeking = false;
}
sp<MetaData> format = mSource->getFormat();
const char* mime;
int avgBitRate = -1;
@ -177,21 +173,24 @@ status_t AudioOffloadPlayer::Start(bool aSourceAlreadyStarted)
return err;
}
void AudioOffloadPlayer::ChangeState(MediaDecoder::PlayState aState)
status_t AudioOffloadPlayer::ChangeState(MediaDecoder::PlayState aState)
{
MOZ_ASSERT(NS_IsMainThread());
mPlayState = aState;
switch (mPlayState) {
case MediaDecoder::PLAY_STATE_PLAYING:
Play();
case MediaDecoder::PLAY_STATE_PLAYING: {
status_t err = Play();
if (err != OK) {
return err;
}
StartTimeUpdate();
break;
} break;
case MediaDecoder::PLAY_STATE_SEEKING: {
int64_t seekTimeUs
= mObserver->GetSeekTime();
SeekTo(seekTimeUs);
SeekTo(seekTimeUs, true);
mObserver->ResetSeekTime();
} break;
@ -209,41 +208,81 @@ void AudioOffloadPlayer::ChangeState(MediaDecoder::PlayState aState)
default:
break;
}
return OK;
}
static void ResetCallback(nsITimer* aTimer, void* aClosure)
{
AudioOffloadPlayer* player = static_cast<AudioOffloadPlayer*>(aClosure);
if (player) {
player->Reset();
}
}
void AudioOffloadPlayer::Pause(bool aPlayPendingSamples)
{
MOZ_ASSERT(NS_IsMainThread());
CHECK(mStarted);
CHECK(mAudioSink.get());
if (mStarted) {
CHECK(mAudioSink.get());
if (aPlayPendingSamples) {
mAudioSink->Stop();
} else {
mAudioSink->Pause();
}
mPlaying = false;
}
if (mResetTimer) {
return;
}
mResetTimer = do_CreateInstance("@mozilla.org/timer;1");
mResetTimer->InitWithFuncCallback(ResetCallback,
this,
OFFLOAD_PAUSE_MAX_MSECS,
nsITimer::TYPE_ONE_SHOT);
}
status_t AudioOffloadPlayer::Play()
{
MOZ_ASSERT(NS_IsMainThread());
CHECK(mStarted);
CHECK(mAudioSink.get());
if (mResetTimer) {
mResetTimer->Cancel();
mResetTimer = nullptr;
}
status_t err = OK;
err = mAudioSink->Start();
if (!mStarted) {
// Last pause timed out and offloaded audio sink was reset. Start it again
err = Start(false);
if (err != OK) {
return err;
}
// Seek to last play position only when there was no seek during last pause
if (!mSeeking) {
SeekTo(mPositionTimeMediaUs);
}
}
if (!mPlaying) {
CHECK(mAudioSink.get());
err = mAudioSink->Start();
if (err == OK) {
mPlaying = true;
}
}
return err;
}
void AudioOffloadPlayer::Reset()
{
CHECK(mStarted);
if (!mStarted) {
return;
}
CHECK(mAudioSink.get());
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("reset: mPlaying=%d mReachedEOS=%d",
@ -273,19 +312,18 @@ void AudioOffloadPlayer::Reset()
mInputBuffer->release();
mInputBuffer = nullptr;
}
mSource->stop();
IPCThreadState::self()->flushCommands();
StopTimeUpdate();
mSeeking = false;
mSeekTimeUs = 0;
mReachedEOS = false;
mStarted = false;
mPlaying = false;
mStartPosUs = 0;
}
status_t AudioOffloadPlayer::SeekTo(int64_t aTimeUs)
status_t AudioOffloadPlayer::SeekTo(int64_t aTimeUs, bool aDispatchSeekEvents)
{
MOZ_ASSERT(NS_IsMainThread());
CHECK(mAudioSink.get());
@ -299,27 +337,34 @@ status_t AudioOffloadPlayer::SeekTo(int64_t aTimeUs)
mPositionTimeMediaUs = -1;
mSeekTimeUs = aTimeUs;
mStartPosUs = aTimeUs;
mDispatchSeekEvents = aDispatchSeekEvents;
if (mDispatchSeekEvents) {
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
&MediaDecoder::SeekingStarted);
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
}
if (mPlaying) {
mAudioSink->Pause();
}
mAudioSink->Flush();
if (mPlaying) {
mAudioSink->Start();
} else {
mSeekDuringPause = true;
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Fake seek complete during pause"));
if (mStarted) {
mAudioSink->Flush();
}
if (mDispatchSeekEvents) {
mDispatchSeekEvents = false;
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Fake seek complete during pause"));
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
&MediaDecoder::SeekingStopped);
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
}
}
return OK;
}
@ -339,6 +384,9 @@ int64_t AudioOffloadPlayer::GetMediaTimeUs()
if (mSeeking) {
return mSeekTimeUs;
}
if (!mStarted) {
return mPositionTimeMediaUs;
}
playPosition = GetOutputPlayPositionUs_l();
if (!mReachedEOS) {
@ -427,8 +475,6 @@ size_t AudioOffloadPlayer::FillBuffer(void* aData, size_t aSize)
return 0;
}
bool postSeekComplete = false;
size_t sizeDone = 0;
size_t sizeRemaining = aSize;
while (sizeRemaining > 0) {
@ -446,9 +492,7 @@ size_t AudioOffloadPlayer::FillBuffer(void* aData, size_t aSize)
mInputBuffer->release();
mInputBuffer = nullptr;
}
mSeeking = false;
postSeekComplete = true;
}
}
@ -491,17 +535,16 @@ size_t AudioOffloadPlayer::FillBuffer(void* aData, size_t aSize)
kKeyTime, &mPositionTimeMediaUs));
}
// need to adjust the mStartPosUs for offload decoding since parser
// might not be able to get the exact seek time requested.
if (refreshSeekTime) {
if (postSeekComplete) {
if (!mSeekDuringPause) {
if (mDispatchSeekEvents && !mSeekDuringPause) {
mDispatchSeekEvents = false;
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("FillBuffer posting SEEK_COMPLETE"));
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
&MediaDecoder::SeekingStopped);
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
} else {
} else if (mSeekDuringPause) {
// Callback is already called for seek during pause. Just reset the
// flag
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Not posting seek complete as its"
@ -510,12 +553,13 @@ size_t AudioOffloadPlayer::FillBuffer(void* aData, size_t aSize)
}
NotifyPositionChanged();
postSeekComplete = false;
}
// need to adjust the mStartPosUs for offload decoding since parser
// might not be able to get the exact seek time requested.
mStartPosUs = mPositionTimeMediaUs;
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Adjust seek time to: %.2f",
mStartPosUs / 1E6));
// clear seek time with mLock locked and once we have valid
// mPositionTimeMediaUs
// before clearing mSeekTimeUs check if a new seek request has been

Просмотреть файл

@ -86,7 +86,7 @@ public:
// To update progress bar when the element is visible
void SetElementVisibility(bool aIsVisible);
void ChangeState(MediaDecoder::PlayState aState);
status_t ChangeState(MediaDecoder::PlayState aState);
void SetVolume(double aVolume);
@ -97,6 +97,9 @@ public:
void TimeUpdate();
// Close the audio sink, stop time updates, frees the input buffers
void Reset();
private:
// Set when audio source is started and audioSink is initialized
// Used only in main thread
@ -122,6 +125,12 @@ private:
// mLock
bool mSeekDuringPause;
// Seek can be triggered internally or by MediaDecoder. This bool is to
// to track seek triggered by MediaDecoder so that we can send back
// SeekingStarted and SeekingStopped events.
// Used in main thread and offload callback thread, protected by Mutex mLock
bool mDispatchSeekEvents;
// Set when the HTML Audio Element is visible to the user.
// Used only in main thread
bool mIsElementVisible;
@ -164,7 +173,7 @@ private:
android::sp<MediaSource> mSource;
// Audio sink wrapper to access offloaded audio tracks
// Used in main thread and offload callback thread, access is protected by
// Used in main thread and offload callback thread
// Race conditions are protected in underlying Android::AudioTrack class
android::sp<AudioSink> mAudioSink;
@ -175,10 +184,17 @@ private:
MediaOmxDecoder* mObserver;
TimeStamp mLastFireUpdateTime;
// Timer to trigger position changed events
nsCOMPtr<nsITimer> mTimeUpdateTimer;
// Timer to reset AudioSink when audio is paused for OFFLOAD_PAUSE_MAX_USECS.
// It is triggered in Pause() and canceled when there is a Play() within
// OFFLOAD_PAUSE_MAX_USECS. Used only from main thread so no lock is needed.
nsCOMPtr<nsITimer> mResetTimer;
int64_t GetMediaTimeUs();
// Provide the playback position in microseconds from total number of
// frames played by audio track
int64_t GetOutputPlayPositionUs_l() const;
@ -198,16 +214,14 @@ private:
bool IsSeeking();
// Set mSeekTime to the given position and restart the sink. Actual seek
// happens in FillBuffer(). To MediaDecoder, send SeekingStarted event always
// and SeekingStopped event when the play state is paused.
// happens in FillBuffer(). If aDispatchSeekEvents is true, send
// SeekingStarted event always and SeekingStopped event when the play state is
// paused to MediaDecoder.
// When decoding and playing happens separately, if there is a seek during
// pause, we can decode and keep data ready.
// In case of offload player, no way to seek during pause. So just fake that
// seek is done.
status_t SeekTo(int64_t aTimeUs);
// Close the audio sink, stop time updates, frees the input buffers
void Reset();
status_t SeekTo(int64_t aTimeUs, bool aDispatchSeekEvents = false);
// Start/Resume the audio sink so that callback will start being called to get
// compressed data

Просмотреть файл

@ -49,7 +49,10 @@ public:
return android::NO_INIT;
}
virtual void ChangeState(MediaDecoder::PlayState aState) {}
virtual status_t ChangeState(MediaDecoder::PlayState aState)
{
return android::NO_INIT;
}
virtual void SetVolume(double aVolume) {}

Просмотреть файл

@ -65,7 +65,6 @@ void MediaOmxDecoder::MetadataLoaded(int aChannels,
MediaDecoder::MetadataLoaded(aChannels, aRate, aHasAudio, aHasVideo, aTags);
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
if (!mCanOffloadAudio || mFallbackToStateMachine || mOutputStreams.Length() ||
mInitialPlaybackRate != 1.0) {
DECODER_LOG(PR_LOG_DEBUG, ("In %s Offload Audio check failed",
@ -95,7 +94,6 @@ void MediaOmxDecoder::PauseStateMachine()
MOZ_ASSERT(NS_IsMainThread());
GetReentrantMonitor().AssertCurrentThreadIn();
DECODER_LOG(PR_LOG_DEBUG, ("%s", __PRETTY_FUNCTION__));
if (!mDecoderStateMachine) {
return;
}
@ -106,7 +104,7 @@ void MediaOmxDecoder::PauseStateMachine()
void MediaOmxDecoder::ResumeStateMachine()
{
MOZ_ASSERT(NS_IsMainThread());
GetReentrantMonitor().AssertCurrentThreadIn();
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
DECODER_LOG(PR_LOG_DEBUG, ("%s current time %f", __PRETTY_FUNCTION__,
mCurrentTime));
@ -130,7 +128,6 @@ void MediaOmxDecoder::AudioOffloadTearDown()
DECODER_LOG(PR_LOG_DEBUG, ("%s", __PRETTY_FUNCTION__));
{
// Audio offload player sent tear down event. Fallback to state machine
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
ResumeStateMachine();
}
}
@ -143,7 +140,6 @@ void MediaOmxDecoder::AddOutputStream(ProcessedMediaStream* aStream,
if (mAudioOffloadPlayer) {
// Offload player cannot handle MediaStream. Fallback
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
ResumeStateMachine();
}
@ -158,7 +154,6 @@ void MediaOmxDecoder::SetPlaybackRate(double aPlaybackRate)
if (mAudioOffloadPlayer &&
((aPlaybackRate != 0.0) || (aPlaybackRate != 1.0))) {
// Offload player cannot handle playback rate other than 1/0. Fallback
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
ResumeStateMachine();
}
@ -168,21 +163,22 @@ void MediaOmxDecoder::SetPlaybackRate(double aPlaybackRate)
void MediaOmxDecoder::ChangeState(PlayState aState)
{
MOZ_ASSERT(NS_IsMainThread());
// Keep MediaDecoder state in sync with MediaElement irrespective of offload
// playback so it will continue to work in normal mode when offloading fails
// in between
MediaDecoder::ChangeState(aState);
if (mAudioOffloadPlayer) {
mAudioOffloadPlayer->ChangeState(aState);
status_t err = mAudioOffloadPlayer->ChangeState(aState);
if (err != OK) {
ResumeStateMachine();
}
}
}
void MediaOmxDecoder::ApplyStateToStateMachine(PlayState aState)
{
MOZ_ASSERT(NS_IsMainThread());
// During offload playback, state machine should be in dormant state.
// ApplyStateToStateMachine() can change state machine state to
// something else or reset the seek time. So don't call this when audio is

Просмотреть файл

@ -999,15 +999,6 @@ BluetoothHfpManager::SendResponse(bthf_at_response_t aResponseCode)
void
BluetoothHfpManager::UpdatePhoneCIND(uint32_t aCallIndex, bool aSend)
{
// Update callsetup state
uint16_t callState = mCurrentCallArray[aCallIndex].mState;
if (callState == nsITelephonyProvider::CALL_STATE_CONNECTED ||
callState == nsITelephonyProvider::CALL_STATE_HELD) {
mCallSetupState = nsITelephonyProvider::CALL_STATE_DISCONNECTED;
} else {
mCallSetupState = callState;
}
NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
int numActive = GetNumberOfCalls(nsITelephonyProvider::CALL_STATE_CONNECTED);
@ -1016,8 +1007,8 @@ BluetoothHfpManager::UpdatePhoneCIND(uint32_t aCallIndex, bool aSend)
nsAutoCString number = NS_ConvertUTF16toUTF8(mCurrentCallArray[aCallIndex].mNumber);
bthf_call_addrtype_t type = mCurrentCallArray[aCallIndex].mType;
BT_LOGR("[%d] state %d => BTHF: active[%d] held[%d] state[%d]",
aCallIndex, callState, numActive, numHeld, bthfCallState);
BT_LOGR("[%d] state %d => BTHF: active[%d] held[%d] state[%d]", aCallIndex,
mCurrentCallArray[aCallIndex].mState, numActive, numHeld, bthfCallState);
NS_ENSURE_TRUE_VOID(BT_STATUS_SUCCESS ==
sBluetoothHfpInterface->phone_state_change(
@ -1124,6 +1115,22 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
mCurrentCallArray[aCallIndex].mType = BTHF_CALL_ADDRTYPE_INTERNATIONAL;
}
bool isSetupCall = (aCallState == nsITelephonyProvider::CALL_STATE_INCOMING ||
aCallState == nsITelephonyProvider::CALL_STATE_ALERTING ||
aCallState == nsITelephonyProvider::CALL_STATE_DIALING);
bool hasSetupCall = (FindFirstCall(nsITelephonyProvider::CALL_STATE_INCOMING) ||
FindFirstCall(nsITelephonyProvider::CALL_STATE_ALERTING) ||
FindFirstCall(nsITelephonyProvider::CALL_STATE_DIALING));
// Update callsetup state when
// 1) this call is in call setup
// 2) all calls in the call array including this call are not in call setup
if (isSetupCall) {
mCallSetupState = aCallState;
} else if (!hasSetupCall) {
mCallSetupState = nsITelephonyProvider::CALL_STATE_DISCONNECTED;
}
UpdatePhoneCIND(aCallIndex, aSend);
switch (aCallState) {

Просмотреть файл

@ -1162,6 +1162,74 @@ AppendDeviceName(BluetoothSignal& aSignal)
unused << handler.forget(); // picked up by callback handler
}
class SetPairingConfirmationTask : public Task
{
public:
SetPairingConfirmationTask(const nsAString& aDeviceAddress,
bool aConfirm,
BluetoothReplyRunnable* aRunnable)
: mDeviceAddress(aDeviceAddress)
, mConfirm(aConfirm)
, mRunnable(aRunnable)
{
MOZ_ASSERT(!mDeviceAddress.IsEmpty());
}
void Run() MOZ_OVERRIDE
{
MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
MOZ_ASSERT(sDBusConnection);
nsAutoString errorStr;
BluetoothValue v = true;
DBusMessage *msg;
if (!sPairingReqTable->Get(mDeviceAddress, &msg) && mRunnable) {
BT_WARNING("%s: Couldn't get original request message.", __FUNCTION__);
errorStr.AssignLiteral("Couldn't get original request message.");
DispatchBluetoothReply(mRunnable, v, errorStr);
return;
}
DBusMessage *reply;
if (mConfirm) {
reply = dbus_message_new_method_return(msg);
} else {
reply = dbus_message_new_error(msg, "org.bluez.Error.Rejected",
"User rejected confirmation");
}
if (!reply) {
BT_WARNING("%s: Memory can't be allocated for the message.", __FUNCTION__);
dbus_message_unref(msg);
errorStr.AssignLiteral("Memory can't be allocated for the message.");
if (mRunnable) {
DispatchBluetoothReply(mRunnable, v, errorStr);
}
return;
}
bool result = sDBusConnection->Send(reply);
if (!result) {
errorStr.AssignLiteral("Can't send message!");
}
dbus_message_unref(msg);
dbus_message_unref(reply);
sPairingReqTable->Remove(mDeviceAddress);
if (mRunnable) {
DispatchBluetoothReply(mRunnable, v, errorStr);
}
}
private:
nsString mDeviceAddress;
bool mConfirm;
nsRefPtr<BluetoothReplyRunnable> mRunnable;
};
static DBusHandlerResult
AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data)
{
@ -1331,7 +1399,25 @@ AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data)
dbus_connection_send(conn, reply, nullptr);
dbus_message_unref(reply);
// Do not send an notification to upper layer, too annoying.
// Do not send a notification to upper layer, too annoying.
return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_method_call(msg, DBUS_AGENT_IFACE, "RequestPairingConsent")) {
// Directly SetPairingconfirmation for RequestPairingConsent here
if (!dbus_message_get_args(msg, nullptr,
DBUS_TYPE_OBJECT_PATH, &objectPath,
DBUS_TYPE_INVALID)) {
errorStr.AssignLiteral("Invalid arguments: RequestPairingConsent()");
goto handle_error;
}
nsString address = GetAddressFromObjectPath(NS_ConvertUTF8toUTF16(objectPath));
sPairingReqTable->Put(address, msg);
Task* task = new SetPairingConfirmationTask(address, true, nullptr);
DispatchToDBusThread(task);
// Increase dbus message reference counts, it will be decreased in
// SetPairingConfirmationTask
dbus_message_ref(msg);
// Do not send a notification to upper layer
return DBUS_HANDLER_RESULT_HANDLED;
} else {
#ifdef DEBUG
@ -3182,68 +3268,6 @@ BluetoothDBusService::SetPasskeyInternal(const nsAString& aDeviceAddress,
return true;
}
class SetPairingConfirmationTask : public Task
{
public:
SetPairingConfirmationTask(const nsAString& aDeviceAddress,
bool aConfirm,
BluetoothReplyRunnable* aRunnable)
: mDeviceAddress(aDeviceAddress)
, mConfirm(aConfirm)
, mRunnable(aRunnable)
{
MOZ_ASSERT(!mDeviceAddress.IsEmpty());
MOZ_ASSERT(mRunnable);
}
void Run() MOZ_OVERRIDE
{
MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
MOZ_ASSERT(sDBusConnection);
nsAutoString errorStr;
BluetoothValue v = true;
DBusMessage *msg;
if (!sPairingReqTable->Get(mDeviceAddress, &msg)) {
BT_WARNING("%s: Couldn't get original request message.", __FUNCTION__);
errorStr.AssignLiteral("Couldn't get original request message.");
DispatchBluetoothReply(mRunnable, v, errorStr);
return;
}
DBusMessage *reply;
if (mConfirm) {
reply = dbus_message_new_method_return(msg);
} else {
reply = dbus_message_new_error(msg, "org.bluez.Error.Rejected",
"User rejected confirmation");
}
if (!reply) {
BT_WARNING("%s: Memory can't be allocated for the message.", __FUNCTION__);
dbus_message_unref(msg);
errorStr.AssignLiteral("Memory can't be allocated for the message.");
DispatchBluetoothReply(mRunnable, v, errorStr);
return;
}
bool result = sDBusConnection->Send(reply);
if (!result) {
errorStr.AssignLiteral("Can't send message!");
}
dbus_message_unref(msg);
dbus_message_unref(reply);
sPairingReqTable->Remove(mDeviceAddress);
DispatchBluetoothReply(mRunnable, v, errorStr);
}
private:
nsString mDeviceAddress;
bool mConfirm;
nsRefPtr<BluetoothReplyRunnable> mRunnable;
};
bool
BluetoothDBusService::SetPairingConfirmationInternal(

Просмотреть файл

@ -51,6 +51,7 @@
#include <cutils/properties.h>
#include <system/audio.h>
#define RES_720P (720 * 1280)
namespace android {
GonkRecorder::GonkRecorder()
@ -370,6 +371,11 @@ status_t GonkRecorder::setParamMaxFileSizeBytes(int64_t bytes) {
RE_LOGW("Target file size (%lld bytes) is too small to be respected", bytes);
}
if (bytes >= 0xffffffffLL) {
RE_LOGW("Target file size (%lld bytes) too large to be respected, clipping to 4GB", bytes);
bytes = 0xffffffffLL;
}
mMaxFileSizeBytes = bytes;
return OK;
}
@ -656,6 +662,13 @@ status_t GonkRecorder::setClientName(const String16& clientName) {
}
status_t GonkRecorder::prepare() {
if (mVideoSource != VIDEO_SOURCE_LIST_END && mVideoEncoder != VIDEO_ENCODER_LIST_END &&
mVideoHeight && mVideoWidth && // Video recording
(mVideoHeight * mVideoWidth >= RES_720P)) {
// TODO: Above check needs to be updated when mMaxFileDurationUs is set from camera app
RE_LOGV("Video is high resolution so setting 64-bit file offsets");
setParam64BitFileOffset(true);
}
return OK;
}

Просмотреть файл

@ -30,14 +30,6 @@ using namespace mozilla::dom;
using mozilla::ErrorResult;
using mozilla::dom::telephony::kOutgoingPlaceholderCallIndex;
namespace {
typedef nsAutoTArray<Telephony*, 2> TelephonyList;
TelephonyList* gTelephonyList;
} // anonymous namespace
class Telephony::Listener : public nsITelephonyListener
{
Telephony* mTelephony;
@ -121,26 +113,11 @@ public:
Telephony::Telephony(nsPIDOMWindow* aOwner)
: DOMEventTargetHelper(aOwner), mActiveCall(nullptr), mEnumerated(false)
{
if (!gTelephonyList) {
gTelephonyList = new TelephonyList();
}
gTelephonyList->AppendElement(this);
}
Telephony::~Telephony()
{
Shutdown();
NS_ASSERTION(gTelephonyList, "This should never be null!");
NS_ASSERTION(gTelephonyList->Contains(this), "Should be in the list!");
if (gTelephonyList->Length() == 1) {
delete gTelephonyList;
gTelephonyList = nullptr;
} else {
gTelephonyList->RemoveElement(this);
}
}
void

Просмотреть файл

@ -787,7 +787,8 @@ TelephonyProvider.prototype = {
aCall.isSwitchable,
aCall.isMergeable]);
} else {
this.notifyCallError(aClientId, aCall.callIndex, aCall.failCause);
this._notifyAllListeners("notifyError",
[aClientId, aCall.callIndex, aCall.failCause]);
}
delete this._currentCalls[aClientId][aCall.callIndex];
@ -796,13 +797,6 @@ TelephonyProvider.prototype = {
}
},
/**
* Handle call error.
*/
notifyCallError: function(aClientId, aCallIndex, aErrorMsg) {
this._notifyAllListeners("notifyError", [aClientId, aCallIndex, aErrorMsg]);
},
/**
* Handle an incoming call.
*

Просмотреть файл

@ -10,14 +10,11 @@
"@mozilla.org/telephony/gonktelephonyprovider;1"
%}
[scriptable, uuid(5fdd720f-fbe8-46f5-b671-3bf3360013dd)]
[scriptable, uuid(9d884482-90fc-4050-a4b1-1a370afe7a35)]
interface nsIGonkTelephonyProvider : nsITelephonyProvider
{
void notifyCallDisconnected(in unsigned long clientId, in jsval call);
void notifyCallError(in unsigned long clientId, in long callIndex,
in AString error);
void notifyCallRing();
void notifyCallStateChanged(in unsigned long clientId, in jsval call,

Просмотреть файл

@ -7,6 +7,7 @@
include protocol PHttpChannel;
include protocol PFTPChannel;
include protocol PRtspChannel;
include URIParams;
include InputStreamParams;
@ -89,5 +90,15 @@ union ChannelDiverterArgs
PFTPChannel;
};
//-----------------------------------------------------------------------------
// RTSP IPDL structs
//-----------------------------------------------------------------------------
struct RtspChannelConnectArgs
{
URIParams uri;
uint32_t channelId;
};
} // namespace ipc
} // namespace mozilla

Просмотреть файл

@ -22,6 +22,7 @@
#include "mozilla/dom/network/UDPSocketChild.h"
#ifdef NECKO_PROTOCOL_rtsp
#include "mozilla/net/RtspControllerChild.h"
#include "mozilla/net/RtspChannelChild.h"
#endif
#include "SerializedLoadContext.h"
@ -181,6 +182,23 @@ NeckoChild::DeallocPRtspControllerChild(PRtspControllerChild* child)
return true;
}
PRtspChannelChild*
NeckoChild::AllocPRtspChannelChild(const RtspChannelConnectArgs& aArgs)
{
NS_NOTREACHED("AllocPRtspController should not be called");
return nullptr;
}
bool
NeckoChild::DeallocPRtspChannelChild(PRtspChannelChild* child)
{
#ifdef NECKO_PROTOCOL_rtsp
RtspChannelChild* p = static_cast<RtspChannelChild*>(child);
p->ReleaseIPDLReference();
#endif
return true;
}
PTCPSocketChild*
NeckoChild::AllocPTCPSocketChild()
{

Просмотреть файл

@ -62,6 +62,10 @@ protected:
virtual bool DeallocPRemoteOpenFileChild(PRemoteOpenFileChild*) MOZ_OVERRIDE;
virtual PRtspControllerChild* AllocPRtspControllerChild() MOZ_OVERRIDE;
virtual bool DeallocPRtspControllerChild(PRtspControllerChild*) MOZ_OVERRIDE;
virtual PRtspChannelChild*
AllocPRtspChannelChild(const RtspChannelConnectArgs& aArgs)
MOZ_OVERRIDE;
virtual bool DeallocPRtspChannelChild(PRtspChannelChild*) MOZ_OVERRIDE;
virtual PChannelDiverterChild*
AllocPChannelDiverterChild(const ChannelDiverterArgs& channel) MOZ_OVERRIDE;
virtual bool

Просмотреть файл

@ -15,6 +15,7 @@
#include "mozilla/net/WebSocketChannelParent.h"
#ifdef NECKO_PROTOCOL_rtsp
#include "mozilla/net/RtspControllerParent.h"
#include "mozilla/net/RtspChannelParent.h"
#endif
#include "mozilla/net/DNSRequestParent.h"
#include "mozilla/net/RemoteOpenFileParent.h"
@ -336,6 +337,42 @@ NeckoParent::DeallocPRtspControllerParent(PRtspControllerParent* actor)
return true;
}
PRtspChannelParent*
NeckoParent::AllocPRtspChannelParent(const RtspChannelConnectArgs& aArgs)
{
#ifdef NECKO_PROTOCOL_rtsp
nsCOMPtr<nsIURI> uri = DeserializeURI(aArgs.uri());
RtspChannelParent *p = new RtspChannelParent(uri);
p->AddRef();
return p;
#else
return nullptr;
#endif
}
bool
NeckoParent::RecvPRtspChannelConstructor(
PRtspChannelParent* aActor,
const RtspChannelConnectArgs& aConnectArgs)
{
#ifdef NECKO_PROTOCOL_rtsp
RtspChannelParent* p = static_cast<RtspChannelParent*>(aActor);
return p->Init(aConnectArgs);
#else
return nullptr;
#endif
}
bool
NeckoParent::DeallocPRtspChannelParent(PRtspChannelParent* actor)
{
#ifdef NECKO_PROTOCOL_rtsp
RtspChannelParent* p = static_cast<RtspChannelParent*>(actor);
p->Release();
#endif
return true;
}
PTCPSocketParent*
NeckoParent::AllocPTCPSocketParent()
{

Просмотреть файл

@ -144,6 +144,15 @@ protected:
virtual PRtspControllerParent* AllocPRtspControllerParent() MOZ_OVERRIDE;
virtual bool DeallocPRtspControllerParent(PRtspControllerParent*) MOZ_OVERRIDE;
virtual PRtspChannelParent*
AllocPRtspChannelParent(const RtspChannelConnectArgs& aArgs)
MOZ_OVERRIDE;
virtual bool
RecvPRtspChannelConstructor(PRtspChannelParent* aActor,
const RtspChannelConnectArgs& aArgs)
MOZ_OVERRIDE;
virtual bool DeallocPRtspChannelParent(PRtspChannelParent*) MOZ_OVERRIDE;
virtual PChannelDiverterParent*
AllocPChannelDiverterParent(const ChannelDiverterArgs& channel) MOZ_OVERRIDE;
virtual bool

Просмотреть файл

@ -22,6 +22,7 @@ include protocol PBlob; //FIXME: bug #792908
include protocol PFileDescriptorSet;
include protocol PRtspController;
include protocol PRtspChannel;
include URIParams;
include InputStreamParams;
include NeckoChannelParams;
@ -47,6 +48,7 @@ sync protocol PNecko
manages PDNSRequest;
manages PRemoteOpenFile;
manages PRtspController;
manages PRtspChannel;
manages PChannelDiverter;
parent:
@ -71,6 +73,7 @@ parent:
HTMLDNSPrefetch(nsString hostname, uint16_t flags);
CancelHTMLDNSPrefetch(nsString hostname, uint16_t flags, nsresult reason);
PRtspController();
PRtspChannel(RtspChannelConnectArgs args);
PChannelDiverter(ChannelDiverterArgs channel);
both:

Просмотреть файл

@ -0,0 +1,25 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PNecko;
include URIParams;
namespace mozilla {
namespace net {
async protocol PRtspChannel
{
manager PNecko;
parent:
// Note: channels are opened during construction, so no open method here:
// see PNecko.ipdl
__delete__();
};
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -34,6 +34,7 @@ IPDL_SOURCES = [
'PChannelDiverter.ipdl',
'PNecko.ipdl',
'PRemoteOpenFile.ipdl',
'PRtspChannel.ipdl',
'PRtspController.ipdl',
]

Просмотреть файл

@ -5,42 +5,72 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RtspChannelChild.h"
#include "nsIURI.h"
#include "nsAutoPtr.h"
#include "nsStandardURL.h"
#include "mozilla/ipc/URIUtils.h"
using namespace mozilla::ipc;
namespace mozilla {
namespace net {
NS_IMPL_ISUPPORTS_INHERITED1(RtspChannelChild,
nsBaseChannel,
nsIChannel)
//-----------------------------------------------------------------------------
// RtspChannelChild::nsIChannel
// RtspChannelChild
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelChild::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
RtspChannelChild::RtspChannelChild(nsIURI *aUri)
: mIPCOpen(false)
, mCanceled(false)
{
MOZ_ASSERT(aListener);
nsCOMPtr<nsIURI> uri = nsBaseChannel::URI();
NS_ENSURE_TRUE(uri, NS_ERROR_ILLEGAL_VALUE);
nsAutoCString uriSpec;
uri->GetSpec(uriSpec);
mListener = aListener;
mListenerContext = aContext;
// Call OnStartRequest directly. mListener is expected to create/load an
// RtspMediaResource which will create an RtspMediaController. This controller
// manages the control and data streams to and from the network.
mListener->OnStartRequest(this, aContext);
return NS_OK;
nsBaseChannel::SetURI(aUri);
}
RtspChannelChild::~RtspChannelChild()
{
}
nsIStreamingProtocolController*
RtspChannelChild::GetController()
{
return mMediaStreamController;
}
void
RtspChannelChild::ReleaseController()
{
if (mMediaStreamController) {
mMediaStreamController = nullptr;
}
}
//-----------------------------------------------------------------------------
// IPDL
//-----------------------------------------------------------------------------
void
RtspChannelChild::AddIPDLReference()
{
NS_ABORT_IF_FALSE(!mIPCOpen,
"Attempt to retain more than one IPDL reference");
mIPCOpen = true;
AddRef();
}
void
RtspChannelChild::ReleaseIPDLReference()
{
NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference");
mIPCOpen = false;
Release();
}
//-----------------------------------------------------------------------------
// nsISupports
//-----------------------------------------------------------------------------
NS_IMPL_ISUPPORTS_INHERITED2(RtspChannelChild,
nsBaseChannel,
nsIChannel,
nsIChildChannel)
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelChild::GetContentType(nsACString& aContentType)
{
@ -48,15 +78,194 @@ RtspChannelChild::GetContentType(nsACString& aContentType)
return NS_OK;
}
NS_IMETHODIMP
RtspChannelChild::Init(nsIURI* aUri)
class CallListenerOnStartRequestEvent : public nsRunnable
{
MOZ_ASSERT(aUri);
public:
CallListenerOnStartRequestEvent(nsIStreamListener *aListener,
nsIRequest *aRequest, nsISupports *aContext)
: mListener(aListener)
, mRequest(aRequest)
, mContext(aContext)
{
MOZ_RELEASE_ASSERT(aListener);
}
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
mListener->OnStartRequest(mRequest, mContext);
return NS_OK;
}
private:
nsRefPtr<nsIStreamListener> mListener;
nsRefPtr<nsIRequest> mRequest;
nsRefPtr<nsISupports> mContext;
};
NS_IMETHODIMP
RtspChannelChild::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
{
// Precondition checks.
MOZ_ASSERT(aListener);
nsCOMPtr<nsIURI> uri = nsBaseChannel::URI();
NS_ENSURE_TRUE(uri, NS_ERROR_ILLEGAL_VALUE);
// Create RtspController.
nsCOMPtr<nsIStreamingProtocolControllerService> mediaControllerService =
do_GetService(MEDIASTREAMCONTROLLERSERVICE_CONTRACTID);
MOZ_RELEASE_ASSERT(mediaControllerService,
"Cannot proceed if media controller service is unavailable!");
mediaControllerService->Create(this, getter_AddRefs(mMediaStreamController));
MOZ_ASSERT(mMediaStreamController);
// Add ourselves to the load group.
if (mLoadGroup) {
mLoadGroup->AddRequest(this, nullptr);
}
// Dispatch mListener's OnStartRequest directly. mListener is expected to
// create an RtspMediaResource and use the RtspController we just created to
// manage the control and data streams to and from the network.
mListener = aListener;
mListenerContext = aContext;
NS_DispatchToMainThread(
new CallListenerOnStartRequestEvent(mListener, this, mListenerContext));
nsBaseChannel::Init();
nsBaseChannel::SetURI(aUri);
return NS_OK;
}
} // namespace mozilla::net
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelChild::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
{
MOZ_CRASH("Should never be called");
}
NS_IMETHODIMP
RtspChannelChild::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
nsresult aStatusCode)
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIStreamListener
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelChild::OnDataAvailable(nsIRequest *aRequest,
nsISupports *aContext,
nsIInputStream *aInputStream,
uint64_t aOffset,
uint32_t aCount)
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIChannel::nsIRequest
//-----------------------------------------------------------------------------
class CallListenerOnStopRequestEvent : public nsRunnable
{
public:
CallListenerOnStopRequestEvent(nsIStreamListener *aListener,
nsIRequest *aRequest,
nsISupports *aContext, nsresult aStatus)
: mListener(aListener)
, mRequest(aRequest)
, mContext(aContext)
, mStatus(aStatus)
{
MOZ_RELEASE_ASSERT(aListener);
}
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
mListener->OnStopRequest(mRequest, mContext, mStatus);
return NS_OK;
}
private:
nsRefPtr<nsIStreamListener> mListener;
nsRefPtr<nsIRequest> mRequest;
nsRefPtr<nsISupports> mContext;
nsresult mStatus;
};
NS_IMETHODIMP
RtspChannelChild::Cancel(nsresult status)
{
if (mCanceled) {
return NS_OK;
}
mCanceled = true;
// Stop RtspController.
if (mMediaStreamController) {
mMediaStreamController->Stop();
}
// Call mListener's OnStopRequest to do clean up.
NS_DispatchToMainThread(
new CallListenerOnStopRequestEvent(mListener, this,
mListenerContext, status));
mListener = nullptr;
mListenerContext = nullptr;
// Remove ourselves from the load group.
if (mLoadGroup) {
mLoadGroup->RemoveRequest(this, nullptr, status);
}
return NS_OK;
}
NS_IMETHODIMP
RtspChannelChild::Suspend()
{
MOZ_CRASH("Should never be called");
}
NS_IMETHODIMP
RtspChannelChild::Resume()
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsBaseChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelChild::OpenContentStream(bool aAsync,
nsIInputStream **aStream,
nsIChannel **aChannel)
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsIChildChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelChild::ConnectParent(uint32_t id)
{
// Create RtspChannelParent for redirection.
AddIPDLReference();
RtspChannelConnectArgs connectArgs;
SerializeURI(nsBaseChannel::URI(), connectArgs.uri());
connectArgs.channelId() = id;
if (!gNeckoChild->SendPRtspChannelConstructor(this, connectArgs)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
RtspChannelChild::CompleteRedirectSetup(nsIStreamListener *aListener,
nsISupports *aContext)
{
return AsyncOpen(aListener, aContext);
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -7,69 +7,82 @@
#ifndef RtspChannelChild_h
#define RtspChannelChild_h
#include "mozilla/net/PRtspChannelChild.h"
#include "mozilla/net/NeckoChild.h"
#include "nsBaseChannel.h"
#include "nsIChildChannel.h"
#include "nsIStreamingProtocolController.h"
#include "nsIStreamingProtocolService.h"
namespace mozilla {
namespace net {
//-----------------------------------------------------------------------------
// RtspChannelChild is a dummy channel used to aid MediaResource creation in
// HTMLMediaElement. Actual network control and data flows are managed by an
// RtspController object created and owned by RtspMediaResource.
// Therefore, when RtspChannelChild::AsyncOpen is called, mListener->OnStartRequest
// will be called immediately. It is expected that an RtspMediaResource object
// will be created in that calling context or after; the RtspController object
// will be created internally by RtspMediaResource."
// HTMLMediaElement. Network control and data flows are managed by an
// RtspController object, which is created by us and manipulated by
// RtspMediaResource. This object is also responsible for inter-process
// communication with the parent process.
// When RtspChannelChild::AsyncOpen is called, it should create an
// RtspController object, dispatch an OnStartRequest and immediately return.
// We expect an RtspMediaResource object will be created in the calling context
// and it will use the RtpController we create.
class RtspChannelChild : public nsBaseChannel
class RtspChannelChild : public PRtspChannelChild
, public nsBaseChannel
, public nsIChildChannel
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICHILDCHANNEL
RtspChannelChild() { }
RtspChannelChild(nsIURI *aUri);
~RtspChannelChild();
~RtspChannelChild() { }
// Overrides nsBaseChannel::AsyncOpen and call listener's OnStartRequest immediately.
NS_IMETHOD AsyncOpen(nsIStreamListener *listener,
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL;
// Set Rtsp URL.
NS_IMETHOD Init(nsIURI* uri);
// Overrides nsBaseChannel::GetContentType, return streaming protocol type "RTSP".
// nsBaseChannel::nsIChannel
NS_IMETHOD GetContentType(nsACString & aContentType) MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD OpenContentStream(bool aAsync,
nsIInputStream **aStream,
nsIChannel **aChannel) MOZ_OVERRIDE MOZ_FINAL
{
return NS_ERROR_NOT_IMPLEMENTED;
}
// nsIRequestObserver
NS_IMETHOD OnStartRequest(nsIRequest *aRequest,
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL
{
return NS_ERROR_NOT_IMPLEMENTED;
}
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
NS_IMETHOD OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD OnStopRequest(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aStatusCode) MOZ_OVERRIDE MOZ_FINAL
{
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult aStatusCode) MOZ_OVERRIDE MOZ_FINAL;
// nsIStreamListener
// nsBaseChannel::nsIStreamListener
NS_IMETHOD OnDataAvailable(nsIRequest *aRequest,
nsISupports *aContext,
nsIInputStream *aInputStream,
uint64_t aOffset,
uint32_t aCount) MOZ_OVERRIDE MOZ_FINAL
{
return NS_ERROR_NOT_IMPLEMENTED;
}
uint32_t aCount) MOZ_OVERRIDE MOZ_FINAL;
// nsBaseChannel::nsIChannel::nsIRequest
NS_IMETHOD Cancel(nsresult status) MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD Suspend() MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD Resume() MOZ_OVERRIDE MOZ_FINAL;
// nsBaseChannel
NS_IMETHOD OpenContentStream(bool aAsync,
nsIInputStream **aStream,
nsIChannel **aChannel) MOZ_OVERRIDE MOZ_FINAL;
// IPDL
void AddIPDLReference();
void ReleaseIPDLReference();
// RtspChannelChild
nsIStreamingProtocolController* GetController();
void ReleaseController();
private:
bool mIPCOpen;
bool mCanceled;
nsCOMPtr<nsIStreamingProtocolController> mMediaStreamController;
};
}
} // namespace mozilla::net
} // namespace net
} // namespace mozilla
#endif // RtspChannelChild_h

Просмотреть файл

@ -0,0 +1,159 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RtspChannelParent.h"
using namespace mozilla::ipc;
namespace mozilla {
namespace net {
//-----------------------------------------------------------------------------
// RtspChannelParent
//-----------------------------------------------------------------------------
RtspChannelParent::RtspChannelParent(nsIURI *aUri)
: mIPCClosed(false)
{
nsBaseChannel::SetURI(aUri);
}
RtspChannelParent::~RtspChannelParent()
{
}
void
RtspChannelParent::ActorDestroy(ActorDestroyReason why)
{
mIPCClosed = true;
}
//-----------------------------------------------------------------------------
// nsISupports
//-----------------------------------------------------------------------------
NS_IMPL_ISUPPORTS_INHERITED1(RtspChannelParent,
nsBaseChannel,
nsIParentChannel)
//-----------------------------------------------------------------------------
// RtspChannelParent methods
//-----------------------------------------------------------------------------
bool
RtspChannelParent::Init(const RtspChannelConnectArgs& aArgs)
{
return ConnectChannel(aArgs.channelId());
}
bool
RtspChannelParent::ConnectChannel(const uint32_t& channelId)
{
nsresult rv;
nsCOMPtr<nsIChannel> channel;
rv = NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel));
return true;
}
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelParent::GetContentType(nsACString& aContentType)
{
aContentType.AssignLiteral("RTSP");
return NS_OK;
}
NS_IMETHODIMP
RtspChannelParent::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
{
return NS_OK;
}
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelParent::OnStartRequest(nsIRequest *aRequest,
nsISupports *aContext)
{
MOZ_CRASH("Should never be called");
}
NS_IMETHODIMP
RtspChannelParent::OnStopRequest(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aStatusCode)
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIStreamListener
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelParent::OnDataAvailable(nsIRequest *aRequest,
nsISupports *aContext,
nsIInputStream *aInputStream,
uint64_t aOffset,
uint32_t aCount)
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsBaseChannel::nsIChannel::nsIRequeset
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelParent::Cancel(nsresult status)
{
// FIXME: This method will be called by
// nsXMLHttpRequest::CloseRequestWithError while closing the browser app.
// However, the root cause is RtspChannelParent will be created by
// nsXMLHttpRequest::Open when we navigate away from an RTSP web page.
// We should find out why it happens and decide how to fix it.
return NS_OK;
}
NS_IMETHODIMP
RtspChannelParent::Suspend()
{
MOZ_CRASH("Should never be called");
}
NS_IMETHODIMP
RtspChannelParent::Resume()
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsBaseChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelParent::OpenContentStream(bool aAsync,
nsIInputStream **aStream,
nsIChannel **aChannel)
{
MOZ_CRASH("Should never be called");
}
//-----------------------------------------------------------------------------
// nsIParentChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
RtspChannelParent::SetParentListener(HttpChannelParentListener *aListener)
{
return NS_OK;
}
NS_IMETHODIMP
RtspChannelParent::Delete()
{
return NS_OK;
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,84 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef RtspChannelParent_h
#define RtspChannelParent_h
#include "mozilla/net/PRtspChannelParent.h"
#include "mozilla/net/NeckoParent.h"
#include "nsBaseChannel.h"
#include "nsIParentChannel.h"
namespace mozilla {
namespace net {
//-----------------------------------------------------------------------------
// Note: RtspChannel doesn't transport streams as normal channel does.
// (See RtspChannelChild.h for detail).
// The reason for the existence of RtspChannelParent is to support HTTP->RTSP
// redirection.
// When redirection happens, two instances of RtspChannelParent will be created:
// - One will be created when HTTP creates the new channel for redirects, and
// will be registered as an nsIChannel.
// - The other will be created via IPDL by RtspChannelChild, and will be
// registered as an nsIParentChannel.
class RtspChannelParent : public PRtspChannelParent
, public nsBaseChannel
, public nsIParentChannel
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPARENTCHANNEL
RtspChannelParent(nsIURI *aUri);
~RtspChannelParent();
// nsBaseChannel::nsIChannel
NS_IMETHOD GetContentType(nsACString & aContentType) MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD AsyncOpen(nsIStreamListener *listener,
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL;
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
NS_IMETHOD OnStartRequest(nsIRequest *aRequest,
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD OnStopRequest(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aStatusCode) MOZ_OVERRIDE MOZ_FINAL;
// nsBaseChannel::nsIStreamListener
NS_IMETHOD OnDataAvailable(nsIRequest *aRequest,
nsISupports *aContext,
nsIInputStream *aInputStream,
uint64_t aOffset,
uint32_t aCount) MOZ_OVERRIDE MOZ_FINAL;
// nsBaseChannel::nsIChannel::nsIRequest
NS_IMETHOD Cancel(nsresult status) MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD Suspend() MOZ_OVERRIDE MOZ_FINAL;
NS_IMETHOD Resume() MOZ_OVERRIDE MOZ_FINAL;
// nsBaseChannel
NS_IMETHOD OpenContentStream(bool aAsync,
nsIInputStream **aStream,
nsIChannel **aChannel) MOZ_OVERRIDE MOZ_FINAL;
// RtspChannelParent
bool Init(const RtspChannelConnectArgs& aArgs);
protected:
// Used to connect redirected-to channel in parent with just created
// ChildChannel. Used during HTTP->RTSP redirection.
bool ConnectChannel(const uint32_t& channelId);
private:
bool mIPCClosed;
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
};
} // namespace net
} // namespace mozilla
#endif // RtspChannelParent_h

Просмотреть файл

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RtspChannelChild.h"
#include "RtspChannelParent.h"
#include "RtspHandler.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
@ -68,15 +69,19 @@ NS_IMETHODIMP
RtspHandler::NewChannel(nsIURI *aURI, nsIChannel **aResult)
{
bool isRtsp = false;
nsRefPtr<RtspChannelChild> rtspChannel;
nsRefPtr<nsBaseChannel> rtspChannel;
nsresult rv = aURI->SchemeIs("rtsp", &isRtsp);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(isRtsp, NS_ERROR_UNEXPECTED);
rtspChannel = new RtspChannelChild();
if (IsNeckoChild()) {
rtspChannel = new RtspChannelChild(aURI);
} else {
rtspChannel = new RtspChannelParent(aURI);
}
rv = rtspChannel->Init(aURI);
rv = rtspChannel->Init();
NS_ENSURE_SUCCESS(rv, rv);
rtspChannel.forget(aResult);

Просмотреть файл

@ -78,6 +78,12 @@ RtspControllerChild::~RtspControllerChild()
LOG(("RtspControllerChild::~RtspControllerChild()"));
}
void
RtspControllerChild::ReleaseChannel()
{
static_cast<RtspChannelChild*>(mChannel.get())->ReleaseController();
}
bool
RtspControllerChild::OKToSendIPC()
{
@ -174,6 +180,7 @@ RtspControllerChild::RecvOnDisconnected(
if (mListener) {
mListener->OnDisconnected(index, reason);
}
ReleaseChannel();
return true;
}
@ -185,6 +192,7 @@ RtspControllerChild::RecvAsyncOpenFailed(const nsresult& reason)
if (mListener) {
mListener->OnDisconnected(0, NS_ERROR_CONNECTION_REFUSED);
}
ReleaseChannel();
return true;
}

Просмотреть файл

@ -13,6 +13,7 @@
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsTArray.h"
#include "mozilla/net/RtspChannelChild.h"
namespace mozilla {
namespace net {
@ -70,6 +71,8 @@ class RtspControllerChild : public nsIStreamingProtocolController
uint32_t mTotalTracks;
// Current suspension depth for this channel object
uint32_t mSuspendCount;
// Detach channel-controller relationship.
void ReleaseChannel();
};
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -10,6 +10,7 @@ EXPORTS.mozilla.net += [
'controller/RtspMetaData.h',
'rtsp/RTSPSource.h',
'RtspChannelChild.h',
'RtspChannelParent.h',
'RtspHandler.h',
]
@ -20,6 +21,7 @@ SOURCES += [
'controller/RtspControllerParent.cpp',
'controller/RtspMetaData.cpp',
'RtspChannelChild.cpp',
'RtspChannelParent.cpp',
'RtspHandler.cpp',
]