From 1b86fe063badb5f28c467ade39be0f4008688947 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Wed, 29 Jan 2014 11:13:26 -0800 Subject: FINAL ATTEMPT: HTTP services are now provided from JAVA and made available to media code Change-Id: I9f74a86e70422187c9cf0ca1318a29019700192d --- cmds/stagefright/SimplePlayer.cpp | 4 +- cmds/stagefright/codec.cpp | 3 +- cmds/stagefright/muxer.cpp | 3 +- cmds/stagefright/sf2.cpp | 5 +- cmds/stagefright/stagefright.cpp | 4 +- cmds/stagefright/stream.cpp | 5 +- include/media/IMediaHTTPConnection.h | 48 +++++ include/media/IMediaHTTPService.h | 41 +++++ include/media/IMediaMetadataRetriever.h | 3 + include/media/IMediaPlayer.h | 8 +- include/media/IMediaPlayerService.h | 12 +- include/media/MediaMetadataRetrieverInterface.h | 3 + include/media/MediaPlayerInterface.h | 1 + include/media/mediametadataretriever.h | 2 + include/media/mediaplayer.h | 14 +- include/media/stagefright/DataSource.h | 2 + include/media/stagefright/MediaHTTP.h | 77 ++++++++ include/media/stagefright/NuMediaExtractor.h | 2 + .../media/stagefright/timedtext/TimedTextDriver.h | 6 +- libvideoeditor/lvpp/PreviewPlayer.cpp | 4 +- libvideoeditor/lvpp/VideoEditorPlayer.cpp | 1 + libvideoeditor/lvpp/VideoEditorPlayer.h | 1 + .../lvpp/VideoEditorPreviewController.cpp | 4 +- media/libmedia/Android.mk | 2 + media/libmedia/IMediaHTTPConnection.cpp | 158 ++++++++++++++++ media/libmedia/IMediaHTTPService.cpp | 58 ++++++ media/libmedia/IMediaMetadataRetriever.cpp | 19 +- media/libmedia/IMediaPlayer.cpp | 19 +- media/libmedia/IMediaPlayerService.cpp | 30 ++- media/libmedia/SoundPool.cpp | 10 +- media/libmedia/mediametadataretriever.cpp | 7 +- media/libmedia/mediaplayer.cpp | 16 +- media/libmediaplayerservice/MediaPlayerService.cpp | 20 +- media/libmediaplayerservice/MediaPlayerService.h | 13 +- .../MetadataRetrieverClient.cpp | 7 +- .../MetadataRetrieverClient.h | 5 +- media/libmediaplayerservice/MidiFile.cpp | 4 +- media/libmediaplayerservice/MidiFile.h | 4 +- .../MidiMetadataRetriever.cpp | 8 +- .../libmediaplayerservice/MidiMetadataRetriever.h | 4 +- media/libmediaplayerservice/StagefrightPlayer.cpp | 6 +- media/libmediaplayerservice/StagefrightPlayer.h | 4 +- media/libmediaplayerservice/TestPlayerStub.cpp | 6 +- media/libmediaplayerservice/TestPlayerStub.h | 4 +- .../nuplayer/GenericSource.cpp | 3 +- .../libmediaplayerservice/nuplayer/GenericSource.h | 1 + .../nuplayer/HTTPLiveSource.cpp | 4 + .../nuplayer/HTTPLiveSource.h | 2 + media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 16 +- media/libmediaplayerservice/nuplayer/NuPlayer.h | 4 +- .../nuplayer/NuPlayerDriver.cpp | 6 +- .../nuplayer/NuPlayerDriver.h | 4 +- .../libmediaplayerservice/nuplayer/RTSPSource.cpp | 4 + media/libmediaplayerservice/nuplayer/RTSPSource.h | 2 + media/libstagefright/Android.mk | 1 + media/libstagefright/AwesomePlayer.cpp | 41 +++-- media/libstagefright/DataSource.cpp | 9 +- media/libstagefright/HTTPBase.cpp | 15 -- media/libstagefright/NuCachedSource2.cpp | 9 +- media/libstagefright/NuMediaExtractor.cpp | 6 +- media/libstagefright/StagefrightMediaScanner.cpp | 3 +- .../StagefrightMetadataRetriever.cpp | 7 +- media/libstagefright/http/Android.mk | 22 +++ media/libstagefright/http/HTTPHelper.cpp | 70 +++++++ media/libstagefright/http/HTTPHelper.h | 31 ++++ media/libstagefright/http/MediaHTTP.cpp | 201 +++++++++++++++++++++ media/libstagefright/httplive/LiveSession.cpp | 14 +- media/libstagefright/httplive/LiveSession.h | 7 +- media/libstagefright/include/AwesomePlayer.h | 3 + media/libstagefright/include/HTTPBase.h | 2 - media/libstagefright/include/SDPLoader.h | 8 +- .../include/StagefrightMetadataRetriever.h | 1 + media/libstagefright/omx/tests/OMXHarness.cpp | 4 +- media/libstagefright/rtsp/APacketSource.cpp | 2 +- media/libstagefright/rtsp/ARTSPConnection.cpp | 2 +- media/libstagefright/rtsp/Android.mk | 2 +- media/libstagefright/rtsp/SDPLoader.cpp | 19 +- media/libstagefright/timedtext/TimedTextDriver.cpp | 6 +- .../wifi-display/source/PlaybackSession.cpp | 4 +- services/camera/libcameraservice/CameraService.cpp | 3 +- 80 files changed, 1065 insertions(+), 130 deletions(-) create mode 100644 include/media/IMediaHTTPConnection.h create mode 100644 include/media/IMediaHTTPService.h create mode 100644 include/media/stagefright/MediaHTTP.h create mode 100644 media/libmedia/IMediaHTTPConnection.cpp create mode 100644 media/libmedia/IMediaHTTPService.cpp create mode 100644 media/libstagefright/http/Android.mk create mode 100644 media/libstagefright/http/HTTPHelper.cpp create mode 100644 media/libstagefright/http/HTTPHelper.h create mode 100644 media/libstagefright/http/MediaHTTP.cpp diff --git a/cmds/stagefright/SimplePlayer.cpp b/cmds/stagefright/SimplePlayer.cpp index 5d2d721..1b2f792 100644 --- a/cmds/stagefright/SimplePlayer.cpp +++ b/cmds/stagefright/SimplePlayer.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -275,7 +276,8 @@ status_t SimplePlayer::onPrepare() { mExtractor = new NuMediaExtractor; - status_t err = mExtractor->setDataSource(mPath.c_str()); + status_t err = mExtractor->setDataSource( + NULL /* httpService */, mPath.c_str()); if (err != OK) { mExtractor.clear(); diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp index fdfefdf..098c899 100644 --- a/cmds/stagefright/codec.cpp +++ b/cmds/stagefright/codec.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -75,7 +76,7 @@ static int decode( static int64_t kTimeout = 500ll; sp extractor = new NuMediaExtractor; - if (extractor->setDataSource(path) != OK) { + if (extractor->setDataSource(NULL /* httpService */, path) != OK) { fprintf(stderr, "unable to instantiate extractor.\n"); return 1; } diff --git a/cmds/stagefright/muxer.cpp b/cmds/stagefright/muxer.cpp index cca33e0..c0747f8 100644 --- a/cmds/stagefright/muxer.cpp +++ b/cmds/stagefright/muxer.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -58,7 +59,7 @@ static int muxing( int trimEndTimeMs, int rotationDegrees) { sp extractor = new NuMediaExtractor; - if (extractor->setDataSource(path) != OK) { + if (extractor->setDataSource(NULL /* httpService */, path) != OK) { fprintf(stderr, "unable to instantiate extractor. %s\n", path); return 1; } diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp index 439b6e4..627610f 100644 --- a/cmds/stagefright/sf2.cpp +++ b/cmds/stagefright/sf2.cpp @@ -22,6 +22,8 @@ #include +#include + #include #include #include @@ -111,7 +113,8 @@ protected: #endif sp dataSource = - DataSource::CreateFromURI(mURI.c_str()); + DataSource::CreateFromURI( + NULL /* httpService */, mURI.c_str()); sp extractor = MediaExtractor::Create(dataSource); diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp index 030bf1b..eb1db4b 100644 --- a/cmds/stagefright/stagefright.cpp +++ b/cmds/stagefright/stagefright.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include "include/NuCachedSource2.h" @@ -958,7 +959,8 @@ int main(int argc, char **argv) { const char *filename = argv[k]; - sp dataSource = DataSource::CreateFromURI(filename); + sp dataSource = + DataSource::CreateFromURI(NULL /* httpService */, filename); if (strncasecmp(filename, "sine:", 5) && dataSource == NULL) { fprintf(stderr, "Unable to create data source.\n"); diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp index dba67a9..b2abc0f 100644 --- a/cmds/stagefright/stream.cpp +++ b/cmds/stagefright/stream.cpp @@ -21,6 +21,7 @@ #include #include // for property_get +#include #include #include #include @@ -159,7 +160,9 @@ private: MyConvertingStreamSource::MyConvertingStreamSource(const char *filename) : mCurrentBufferIndex(-1), mCurrentBufferOffset(0) { - sp dataSource = DataSource::CreateFromURI(filename); + sp dataSource = + DataSource::CreateFromURI(NULL /* httpService */, filename); + CHECK(dataSource != NULL); sp extractor = MediaExtractor::Create(dataSource); diff --git a/include/media/IMediaHTTPConnection.h b/include/media/IMediaHTTPConnection.h new file mode 100644 index 0000000..e048b64 --- /dev/null +++ b/include/media/IMediaHTTPConnection.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2013 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 I_MEDIA_HTTP_CONNECTION_H_ + +#define I_MEDIA_HTTP_CONNECTION_H_ + +#include +#include +#include + +namespace android { + +struct IMediaHTTPConnection; + +/** MUST stay in sync with IMediaHTTPConnection.aidl */ + +struct IMediaHTTPConnection : public IInterface { + DECLARE_META_INTERFACE(MediaHTTPConnection); + + virtual bool connect( + const char *uri, const KeyedVector *headers) = 0; + + virtual void disconnect() = 0; + virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0; + virtual off64_t getSize() = 0; + virtual status_t getMIMEType(String8 *mimeType) = 0; + +private: + DISALLOW_EVIL_CONSTRUCTORS(IMediaHTTPConnection); +}; + +} // namespace android + +#endif // I_MEDIA_HTTP_CONNECTION_H_ diff --git a/include/media/IMediaHTTPService.h b/include/media/IMediaHTTPService.h new file mode 100644 index 0000000..f66d6c8 --- /dev/null +++ b/include/media/IMediaHTTPService.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2013 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 I_MEDIA_HTTP_SERVICE_H_ + +#define I_MEDIA_HTTP_SERVICE_H_ + +#include +#include + +namespace android { + +struct IMediaHTTPConnection; + +/** MUST stay in sync with IMediaHTTPService.aidl */ + +struct IMediaHTTPService : public IInterface { + DECLARE_META_INTERFACE(MediaHTTPService); + + virtual sp makeHTTPConnection() = 0; + +private: + DISALLOW_EVIL_CONSTRUCTORS(IMediaHTTPService); +}; + +} // namespace android + +#endif // I_MEDIA_HTTP_SERVICE_H_ diff --git a/include/media/IMediaMetadataRetriever.h b/include/media/IMediaMetadataRetriever.h index 6dbb2d7..2529800 100644 --- a/include/media/IMediaMetadataRetriever.h +++ b/include/media/IMediaMetadataRetriever.h @@ -26,6 +26,8 @@ namespace android { +struct IMediaHTTPService; + class IMediaMetadataRetriever: public IInterface { public: @@ -33,6 +35,7 @@ public: virtual void disconnect() = 0; virtual status_t setDataSource( + const sp &httpService, const char *srcUrl, const KeyedVector *headers = NULL) = 0; diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h index 0cbd269..db62cd5 100644 --- a/include/media/IMediaPlayer.h +++ b/include/media/IMediaPlayer.h @@ -33,6 +33,7 @@ class Parcel; class Surface; class IStreamSource; class IGraphicBufferProducer; +struct IMediaHTTPService; class IMediaPlayer: public IInterface { @@ -41,8 +42,11 @@ public: virtual void disconnect() = 0; - virtual status_t setDataSource(const char *url, - const KeyedVector* headers) = 0; + virtual status_t setDataSource( + const sp &httpService, + const char *url, + const KeyedVector* headers) = 0; + virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0; virtual status_t setDataSource(const sp& source) = 0; virtual status_t setVideoSurfaceTexture( diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h index 2998b37..e7ad75b 100644 --- a/include/media/IMediaPlayerService.h +++ b/include/media/IMediaPlayerService.h @@ -34,6 +34,7 @@ namespace android { struct ICrypto; struct IDrm; struct IHDCP; +struct IMediaHTTPService; class IMediaRecorder; class IOMX; class IRemoteDisplay; @@ -49,9 +50,14 @@ public: virtual sp createMetadataRetriever() = 0; virtual sp create(const sp& client, int audioSessionId = 0) = 0; - virtual status_t decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, - audio_format_t* pFormat, - const sp& heap, size_t *pSize) = 0; + virtual status_t decode( + const sp &httpService, + const char* url, + uint32_t *pSampleRate, + int* pNumChannels, + audio_format_t* pFormat, + const sp& heap, size_t *pSize) = 0; + virtual status_t decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat, const sp& heap, size_t *pSize) = 0; diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h index ecc3b65..bb6b97b 100644 --- a/include/media/MediaMetadataRetrieverInterface.h +++ b/include/media/MediaMetadataRetrieverInterface.h @@ -24,6 +24,8 @@ namespace android { +struct IMediaHTTPService; + // Abstract base class class MediaMetadataRetrieverBase : public RefBase { @@ -32,6 +34,7 @@ public: virtual ~MediaMetadataRetrieverBase() {} virtual status_t setDataSource( + const sp &httpService, const char *url, const KeyedVector *headers = NULL) = 0; diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index 26d8729..cd85f88 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -137,6 +137,7 @@ public: } virtual status_t setDataSource( + const sp &httpService, const char *url, const KeyedVector *headers = NULL) = 0; diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h index 0df77c1..b35cf32 100644 --- a/include/media/mediametadataretriever.h +++ b/include/media/mediametadataretriever.h @@ -25,6 +25,7 @@ namespace android { +struct IMediaHTTPService; class IMediaPlayerService; class IMediaMetadataRetriever; @@ -68,6 +69,7 @@ public: void disconnect(); status_t setDataSource( + const sp &httpService, const char *dataSourceUrl, const KeyedVector *headers = NULL); diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h index 4c05fc3..00f681d 100644 --- a/include/media/mediaplayer.h +++ b/include/media/mediaplayer.h @@ -189,6 +189,8 @@ public: virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) = 0; }; +struct IMediaHTTPService; + class MediaPlayer : public BnMediaPlayerClient, public virtual IMediaDeathNotifier { @@ -199,6 +201,7 @@ public: void disconnect(); status_t setDataSource( + const sp &httpService, const char *url, const KeyedVector *headers); @@ -224,9 +227,14 @@ public: bool isLooping(); status_t setVolume(float leftVolume, float rightVolume); void notify(int msg, int ext1, int ext2, const Parcel *obj = NULL); - static status_t decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, - audio_format_t* pFormat, - const sp& heap, size_t *pSize); + static status_t decode( + const sp &httpService, + const char* url, + uint32_t *pSampleRate, + int* pNumChannels, + audio_format_t* pFormat, + const sp& heap, + size_t *pSize); static status_t decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat, const sp& heap, size_t *pSize); diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h index 157b1aa..f8787dd 100644 --- a/include/media/stagefright/DataSource.h +++ b/include/media/stagefright/DataSource.h @@ -31,6 +31,7 @@ namespace android { struct AMessage; +struct IMediaHTTPService; class String8; class DataSource : public RefBase { @@ -43,6 +44,7 @@ public: }; static sp CreateFromURI( + const sp &httpService, const char *uri, const KeyedVector *headers = NULL); diff --git a/include/media/stagefright/MediaHTTP.h b/include/media/stagefright/MediaHTTP.h new file mode 100644 index 0000000..006d8d8 --- /dev/null +++ b/include/media/stagefright/MediaHTTP.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2013 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 MEDIA_HTTP_H_ + +#define MEDIA_HTTP_H_ + +#include + +#include "include/HTTPBase.h" + +namespace android { + +struct IMediaHTTPConnection; + +struct MediaHTTP : public HTTPBase { + MediaHTTP(const sp &conn); + + virtual status_t connect( + const char *uri, + const KeyedVector *headers, + off64_t offset); + + virtual void disconnect(); + + virtual status_t initCheck() const; + + virtual ssize_t readAt(off64_t offset, void *data, size_t size); + + virtual status_t getSize(off64_t *size); + + virtual uint32_t flags(); + + virtual status_t reconnectAtOffset(off64_t offset); + +protected: + virtual ~MediaHTTP(); + + virtual sp DrmInitialization(const char* mime); + virtual void getDrmInfo(sp &handle, DrmManagerClient **client); + virtual String8 getUri(); + virtual String8 getMIMEType() const; + +private: + status_t mInitCheck; + sp mHTTPConnection; + + KeyedVector mLastHeaders; + AString mLastURI; + + bool mCachedSizeValid; + off64_t mCachedSize; + + sp mDecryptHandle; + DrmManagerClient *mDrmManagerClient; + + void clearDRMState_l(); + + DISALLOW_EVIL_CONSTRUCTORS(MediaHTTP); +}; + +} // namespace android + +#endif // MEDIA_HTTP_H_ diff --git a/include/media/stagefright/NuMediaExtractor.h b/include/media/stagefright/NuMediaExtractor.h index 5ae6f6b..402e7f8 100644 --- a/include/media/stagefright/NuMediaExtractor.h +++ b/include/media/stagefright/NuMediaExtractor.h @@ -31,6 +31,7 @@ namespace android { struct ABuffer; struct AMessage; struct DataSource; +struct IMediaHTTPService; struct MediaBuffer; struct MediaExtractor; struct MediaSource; @@ -45,6 +46,7 @@ struct NuMediaExtractor : public RefBase { NuMediaExtractor(); status_t setDataSource( + const sp &httpService, const char *path, const KeyedVector *headers = NULL); diff --git a/include/media/stagefright/timedtext/TimedTextDriver.h b/include/media/stagefright/timedtext/TimedTextDriver.h index f23c337..37ef674 100644 --- a/include/media/stagefright/timedtext/TimedTextDriver.h +++ b/include/media/stagefright/timedtext/TimedTextDriver.h @@ -25,6 +25,7 @@ namespace android { class ALooper; +struct IMediaHTTPService; class MediaPlayerBase; class MediaSource; class Parcel; @@ -34,7 +35,9 @@ class DataSource; class TimedTextDriver { public: - TimedTextDriver(const wp &listener); + TimedTextDriver( + const wp &listener, + const sp &httpService); ~TimedTextDriver(); @@ -77,6 +80,7 @@ private: sp mLooper; sp mPlayer; wp mListener; + sp mHTTPService; // Variables to be guarded by mLock. State mState; diff --git a/libvideoeditor/lvpp/PreviewPlayer.cpp b/libvideoeditor/lvpp/PreviewPlayer.cpp index 2bd9f84..b36fe0a 100755 --- a/libvideoeditor/lvpp/PreviewPlayer.cpp +++ b/libvideoeditor/lvpp/PreviewPlayer.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -1160,7 +1161,8 @@ status_t PreviewPlayer::finishSetDataSource_l() { sp dataSource; sp extractor; - dataSource = DataSource::CreateFromURI(mUri.string(), NULL); + dataSource = DataSource::CreateFromURI( + NULL /* httpService */, mUri.string(), NULL); if (dataSource == NULL) { return UNKNOWN_ERROR; diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.cpp b/libvideoeditor/lvpp/VideoEditorPlayer.cpp index 8d656c4..f9c3879 100755 --- a/libvideoeditor/lvpp/VideoEditorPlayer.cpp +++ b/libvideoeditor/lvpp/VideoEditorPlayer.cpp @@ -57,6 +57,7 @@ status_t VideoEditorPlayer::setAudioPlayer(VideoEditorAudioPlayer *audioPlayer) status_t VideoEditorPlayer::setDataSource( + const sp &httpService, const char *url, const KeyedVector *headers) { ALOGI("setDataSource('%s')", url); if (headers != NULL) { diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.h b/libvideoeditor/lvpp/VideoEditorPlayer.h index b8c1254..781e4bc 100755 --- a/libvideoeditor/lvpp/VideoEditorPlayer.h +++ b/libvideoeditor/lvpp/VideoEditorPlayer.h @@ -98,6 +98,7 @@ public: virtual status_t initCheck(); virtual status_t setDataSource( + const sp &httpService, const char *url, const KeyedVector *headers); virtual status_t setDataSource(int fd, int64_t offset, int64_t length); diff --git a/libvideoeditor/lvpp/VideoEditorPreviewController.cpp b/libvideoeditor/lvpp/VideoEditorPreviewController.cpp index c3cd3d0..953f35a 100755 --- a/libvideoeditor/lvpp/VideoEditorPreviewController.cpp +++ b/libvideoeditor/lvpp/VideoEditorPreviewController.cpp @@ -19,6 +19,7 @@ #include #include +#include #include "VideoEditorAudioPlayer.h" #include "PreviewRenderer.h" @@ -967,7 +968,8 @@ M4OSA_ERR VideoEditorPreviewController::preparePlayer( ALOGV("preparePlayer: instance %d file %d", playerInstance, index); const char* fileName = (const char*) pController->mClipList[index]->pFile; - pController->mVePlayer[playerInstance]->setDataSource(fileName, NULL); + pController->mVePlayer[playerInstance]->setDataSource( + NULL /* httpService */, fileName, NULL); ALOGV("preparePlayer: setDataSource instance %s", (const char *)pController->mClipList[index]->pFile); diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index 8aa54dc..fc4b2a5 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -25,6 +25,8 @@ LOCAL_SRC_FILES:= \ AudioRecord.cpp \ AudioSystem.cpp \ mediaplayer.cpp \ + IMediaHTTPConnection.cpp \ + IMediaHTTPService.cpp \ IMediaLogService.cpp \ IMediaPlayerService.cpp \ IMediaPlayerClient.cpp \ diff --git a/media/libmedia/IMediaHTTPConnection.cpp b/media/libmedia/IMediaHTTPConnection.cpp new file mode 100644 index 0000000..622d9cf --- /dev/null +++ b/media/libmedia/IMediaHTTPConnection.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2013 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_NDEBUG 0 +#define LOG_TAG "IMediaHTTPConnection" +#include + +#include + +#include +#include +#include +#include + +namespace android { + +enum { + CONNECT = IBinder::FIRST_CALL_TRANSACTION, + DISCONNECT, + READ_AT, + GET_SIZE, + GET_MIME_TYPE, +}; + +struct BpMediaHTTPConnection : public BpInterface { + BpMediaHTTPConnection(const sp &impl) + : BpInterface(impl) { + } + + virtual bool connect( + const char *uri, const KeyedVector *headers) { + Parcel data, reply; + data.writeInterfaceToken( + IMediaHTTPConnection::getInterfaceDescriptor()); + + String16 tmp(uri); + data.writeString16(tmp); + + tmp = String16(""); + if (headers != NULL) { + for (size_t i = 0; i < headers->size(); ++i) { + String16 key(headers->keyAt(i).string()); + String16 val(headers->valueAt(i).string()); + + tmp.append(key); + tmp.append(String16(": ")); + tmp.append(val); + tmp.append(String16("\r\n")); + } + } + data.writeString16(tmp); + + remote()->transact(CONNECT, data, &reply); + + int32_t exceptionCode = reply.readExceptionCode(); + + if (exceptionCode) { + return UNKNOWN_ERROR; + } + + sp binder = reply.readStrongBinder(); + mMemory = interface_cast(binder); + + return mMemory != NULL; + } + + virtual void disconnect() { + Parcel data, reply; + data.writeInterfaceToken( + IMediaHTTPConnection::getInterfaceDescriptor()); + + remote()->transact(DISCONNECT, data, &reply); + } + + virtual ssize_t readAt(off64_t offset, void *buffer, size_t size) { + Parcel data, reply; + data.writeInterfaceToken( + IMediaHTTPConnection::getInterfaceDescriptor()); + + data.writeInt64(offset); + data.writeInt32(size); + + status_t err = remote()->transact(READ_AT, data, &reply); + CHECK_EQ(err, (status_t)OK); + + int32_t exceptionCode = reply.readExceptionCode(); + + if (exceptionCode) { + return UNKNOWN_ERROR; + } + + int32_t len = reply.readInt32(); + + if (len > 0) { + memcpy(buffer, mMemory->pointer(), len); + } + + return len; + } + + virtual off64_t getSize() { + Parcel data, reply; + data.writeInterfaceToken( + IMediaHTTPConnection::getInterfaceDescriptor()); + + remote()->transact(GET_SIZE, data, &reply); + + int32_t exceptionCode = reply.readExceptionCode(); + + if (exceptionCode) { + return UNKNOWN_ERROR; + } + + return reply.readInt64(); + } + + virtual status_t getMIMEType(String8 *mimeType) { + *mimeType = String8(""); + + Parcel data, reply; + data.writeInterfaceToken( + IMediaHTTPConnection::getInterfaceDescriptor()); + + remote()->transact(GET_MIME_TYPE, data, &reply); + + int32_t exceptionCode = reply.readExceptionCode(); + + if (exceptionCode) { + return UNKNOWN_ERROR; + } + + *mimeType = String8(reply.readString16()); + + return OK; + } + +private: + sp mMemory; +}; + +IMPLEMENT_META_INTERFACE( + MediaHTTPConnection, "android.media.IMediaHTTPConnection"); + +} // namespace android + diff --git a/media/libmedia/IMediaHTTPService.cpp b/media/libmedia/IMediaHTTPService.cpp new file mode 100644 index 0000000..1260582 --- /dev/null +++ b/media/libmedia/IMediaHTTPService.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2013 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_NDEBUG 0 +#define LOG_TAG "IMediaHTTPService" +#include + +#include + +#include +#include + +namespace android { + +enum { + MAKE_HTTP = IBinder::FIRST_CALL_TRANSACTION, +}; + +struct BpMediaHTTPService : public BpInterface { + BpMediaHTTPService(const sp &impl) + : BpInterface(impl) { + } + + virtual sp makeHTTPConnection() { + Parcel data, reply; + data.writeInterfaceToken( + IMediaHTTPService::getInterfaceDescriptor()); + + remote()->transact(MAKE_HTTP, data, &reply); + + status_t err = reply.readInt32(); + + if (err != OK) { + return NULL; + } + + return interface_cast(reply.readStrongBinder()); + } +}; + +IMPLEMENT_META_INTERFACE( + MediaHTTPService, "android.media.IMediaHTTPService"); + +} // namespace android + diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp index bb066a0..c7d9d51 100644 --- a/media/libmedia/IMediaMetadataRetriever.cpp +++ b/media/libmedia/IMediaMetadataRetriever.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -84,10 +85,16 @@ public: } status_t setDataSource( - const char *srcUrl, const KeyedVector *headers) + const sp &httpService, + const char *srcUrl, + const KeyedVector *headers) { Parcel data, reply; data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); + data.writeInt32(httpService != NULL); + if (httpService != NULL) { + data.writeStrongBinder(httpService->asBinder()); + } data.writeCString(srcUrl); if (headers == NULL) { @@ -195,6 +202,13 @@ status_t BnMediaMetadataRetriever::onTransact( } break; case SET_DATA_SOURCE_URL: { CHECK_INTERFACE(IMediaMetadataRetriever, data, reply); + + sp httpService; + if (data.readInt32()) { + httpService = + interface_cast(data.readStrongBinder()); + } + const char* srcUrl = data.readCString(); KeyedVector headers; @@ -206,7 +220,8 @@ status_t BnMediaMetadataRetriever::onTransact( } reply->writeInt32( - setDataSource(srcUrl, numHeaders > 0 ? &headers : NULL)); + setDataSource( + httpService, srcUrl, numHeaders > 0 ? &headers : NULL)); return NO_ERROR; } break; diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp index e79bcd2..d778d05 100644 --- a/media/libmedia/IMediaPlayer.cpp +++ b/media/libmedia/IMediaPlayer.cpp @@ -21,6 +21,7 @@ #include +#include #include #include @@ -75,11 +76,17 @@ public: remote()->transact(DISCONNECT, data, &reply); } - status_t setDataSource(const char* url, + status_t setDataSource( + const sp &httpService, + const char* url, const KeyedVector* headers) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); + data.writeInt32(httpService != NULL); + if (httpService != NULL) { + data.writeStrongBinder(httpService->asBinder()); + } data.writeCString(url); if (headers == NULL) { data.writeInt32(0); @@ -355,6 +362,13 @@ status_t BnMediaPlayer::onTransact( } break; case SET_DATA_SOURCE_URL: { CHECK_INTERFACE(IMediaPlayer, data, reply); + + sp httpService; + if (data.readInt32()) { + httpService = + interface_cast(data.readStrongBinder()); + } + const char* url = data.readCString(); KeyedVector headers; int32_t numHeaders = data.readInt32(); @@ -363,7 +377,8 @@ status_t BnMediaPlayer::onTransact( String8 value = data.readString8(); headers.add(key, value); } - reply->writeInt32(setDataSource(url, numHeaders > 0 ? &headers : NULL)); + reply->writeInt32(setDataSource( + httpService, url, numHeaders > 0 ? &headers : NULL)); return NO_ERROR; } break; case SET_DATA_SOURCE_FD: { diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp index 3c22b4c..190adf2 100644 --- a/media/libmedia/IMediaPlayerService.cpp +++ b/media/libmedia/IMediaPlayerService.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -86,12 +87,21 @@ public: return interface_cast(reply.readStrongBinder()); } - virtual status_t decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, - audio_format_t* pFormat, - const sp& heap, size_t *pSize) + virtual status_t decode( + const sp &httpService, + const char* url, + uint32_t *pSampleRate, + int* pNumChannels, + audio_format_t* pFormat, + const sp& heap, + size_t *pSize) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); + data.writeInt32(httpService != NULL); + if (httpService != NULL) { + data.writeStrongBinder(httpService->asBinder()); + } data.writeCString(url); data.writeStrongBinder(heap->asBinder()); status_t status = remote()->transact(DECODE_URL, data, &reply); @@ -222,13 +232,25 @@ status_t BnMediaPlayerService::onTransact( } break; case DECODE_URL: { CHECK_INTERFACE(IMediaPlayerService, data, reply); + sp httpService; + if (data.readInt32()) { + httpService = + interface_cast(data.readStrongBinder()); + } const char* url = data.readCString(); sp heap = interface_cast(data.readStrongBinder()); uint32_t sampleRate; int numChannels; audio_format_t format; size_t size; - status_t status = decode(url, &sampleRate, &numChannels, &format, heap, &size); + status_t status = + decode(httpService, + url, + &sampleRate, + &numChannels, + &format, + heap, + &size); reply->writeInt32(status); if (status == NO_ERROR) { reply->writeInt32(sampleRate); diff --git a/media/libmedia/SoundPool.cpp b/media/libmedia/SoundPool.cpp index 98acd1f..9ed010d 100644 --- a/media/libmedia/SoundPool.cpp +++ b/media/libmedia/SoundPool.cpp @@ -21,6 +21,7 @@ #define USE_SHARED_MEM_BUFFER #include +#include #include #include #include "SoundPoolThread.h" @@ -496,7 +497,14 @@ status_t Sample::doLoad() ALOGV("Start decode"); if (mUrl) { - status = MediaPlayer::decode(mUrl, &sampleRate, &numChannels, &format, mHeap, &mSize); + status = MediaPlayer::decode( + NULL /* httpService */, + mUrl, + &sampleRate, + &numChannels, + &format, + mHeap, + &mSize); } else { status = MediaPlayer::decode(mFd, mOffset, mLength, &sampleRate, &numChannels, &format, mHeap, &mSize); diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp index bad2494..1d6bb6f 100644 --- a/media/libmedia/mediametadataretriever.cpp +++ b/media/libmedia/mediametadataretriever.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -93,7 +94,9 @@ void MediaMetadataRetriever::disconnect() } status_t MediaMetadataRetriever::setDataSource( - const char *srcUrl, const KeyedVector *headers) + const sp &httpService, + const char *srcUrl, + const KeyedVector *headers) { ALOGV("setDataSource"); Mutex::Autolock _l(mLock); @@ -106,7 +109,7 @@ status_t MediaMetadataRetriever::setDataSource( return UNKNOWN_ERROR; } ALOGV("data source (%s)", srcUrl); - return mRetriever->setDataSource(srcUrl, headers); + return mRetriever->setDataSource(httpService, srcUrl, headers); } status_t MediaMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length) diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 7a6f31d..a4d4b1a 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -136,6 +136,7 @@ status_t MediaPlayer::attachNewPlayer(const sp& player) } status_t MediaPlayer::setDataSource( + const sp &httpService, const char *url, const KeyedVector *headers) { ALOGV("setDataSource(%s)", url); @@ -145,7 +146,7 @@ status_t MediaPlayer::setDataSource( if (service != 0) { sp player(service->create(this, mAudioSessionId)); if ((NO_ERROR != doSetRetransmitEndpoint(player)) || - (NO_ERROR != player->setDataSource(url, headers))) { + (NO_ERROR != player->setDataSource(httpService, url, headers))) { player.clear(); } err = attachNewPlayer(player); @@ -776,15 +777,20 @@ void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj) } } -/*static*/ status_t MediaPlayer::decode(const char* url, uint32_t *pSampleRate, - int* pNumChannels, audio_format_t* pFormat, - const sp& heap, size_t *pSize) +/*static*/ status_t MediaPlayer::decode( + const sp &httpService, + const char* url, + uint32_t *pSampleRate, + int* pNumChannels, + audio_format_t* pFormat, + const sp& heap, + size_t *pSize) { ALOGV("decode(%s)", url); status_t status; const sp& service = getMediaPlayerService(); if (service != 0) { - status = service->decode(url, pSampleRate, pNumChannels, pFormat, heap, pSize); + status = service->decode(httpService, url, pSampleRate, pNumChannels, pFormat, heap, pSize); } else { ALOGE("Unable to locate media service"); status = DEAD_OBJECT; diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 9ac9105..1c6018c 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -622,7 +623,9 @@ void MediaPlayerService::Client::setDataSource_post( } status_t MediaPlayerService::Client::setDataSource( - const char *url, const KeyedVector *headers) + const sp &httpService, + const char *url, + const KeyedVector *headers) { ALOGV("setDataSource(%s)", url); if (url == NULL) @@ -657,7 +660,7 @@ status_t MediaPlayerService::Client::setDataSource( return NO_INIT; } - setDataSource_post(p, p->setDataSource(url, headers)); + setDataSource_post(p, p->setDataSource(httpService, url, headers)); return mStatus; } } @@ -1176,9 +1179,14 @@ int Antagonizer::callbackThread(void* user) } #endif -status_t MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, - audio_format_t* pFormat, - const sp& heap, size_t *pSize) +status_t MediaPlayerService::decode( + const sp &httpService, + const char* url, + uint32_t *pSampleRate, + int* pNumChannels, + audio_format_t* pFormat, + const sp& heap, + size_t *pSize) { ALOGV("decode(%s)", url); sp player; @@ -1206,7 +1214,7 @@ status_t MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* static_cast(player.get())->setAudioSink(cache); // set data source - if (player->setDataSource(url) != NO_ERROR) goto Exit; + if (player->setDataSource(httpService, url) != NO_ERROR) goto Exit; ALOGV("prepare"); player->prepareAsync(); diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index 9c084e1..6749f4a 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -256,9 +256,15 @@ public: virtual sp create(const sp& client, int audioSessionId); - virtual status_t decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, - audio_format_t* pFormat, - const sp& heap, size_t *pSize); + virtual status_t decode( + const sp &httpService, + const char* url, + uint32_t *pSampleRate, + int* pNumChannels, + audio_format_t* pFormat, + const sp& heap, + size_t *pSize); + virtual status_t decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat, @@ -356,6 +362,7 @@ private: sp createPlayer(player_type playerType); virtual status_t setDataSource( + const sp &httpService, const char *url, const KeyedVector *headers); diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp index 348957f..c61cf89 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp +++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -106,7 +107,9 @@ static sp createRetriever(player_type playerType) } status_t MetadataRetrieverClient::setDataSource( - const char *url, const KeyedVector *headers) + const sp &httpService, + const char *url, + const KeyedVector *headers) { ALOGV("setDataSource(%s)", url); Mutex::Autolock lock(mLock); @@ -127,7 +130,7 @@ status_t MetadataRetrieverClient::setDataSource( ALOGV("player type = %d", playerType); sp p = createRetriever(playerType); if (p == NULL) return NO_INIT; - status_t ret = p->setDataSource(url, headers); + status_t ret = p->setDataSource(httpService, url, headers); if (ret == NO_ERROR) mRetriever = p; return ret; } diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h index f08f933..9d3fbe9 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.h +++ b/media/libmediaplayerservice/MetadataRetrieverClient.h @@ -30,6 +30,7 @@ namespace android { +struct IMediaHTTPService; class IMediaPlayerService; class MemoryDealer; @@ -43,7 +44,9 @@ public: virtual void disconnect(); virtual status_t setDataSource( - const char *url, const KeyedVector *headers); + const sp &httpService, + const char *url, + const KeyedVector *headers); virtual status_t setDataSource(int fd, int64_t offset, int64_t length); virtual sp getFrameAtTime(int64_t timeUs, int option); diff --git a/media/libmediaplayerservice/MidiFile.cpp b/media/libmediaplayerservice/MidiFile.cpp index 0a6aa90..deeddd1 100644 --- a/media/libmediaplayerservice/MidiFile.cpp +++ b/media/libmediaplayerservice/MidiFile.cpp @@ -114,7 +114,9 @@ MidiFile::~MidiFile() { } status_t MidiFile::setDataSource( - const char* path, const KeyedVector *) { + const sp &httpService, + const char* path, + const KeyedVector *) { ALOGV("MidiFile::setDataSource url=%s", path); Mutex::Autolock lock(mMutex); diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h index 24d59b4..12802ba 100644 --- a/media/libmediaplayerservice/MidiFile.h +++ b/media/libmediaplayerservice/MidiFile.h @@ -32,7 +32,9 @@ public: virtual status_t initCheck(); virtual status_t setDataSource( - const char* path, const KeyedVector *headers); + const sp &httpService, + const char* path, + const KeyedVector *headers); virtual status_t setDataSource(int fd, int64_t offset, int64_t length); virtual status_t setVideoSurfaceTexture( diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.cpp b/media/libmediaplayerservice/MidiMetadataRetriever.cpp index 465209f..f3cf6ef 100644 --- a/media/libmediaplayerservice/MidiMetadataRetriever.cpp +++ b/media/libmediaplayerservice/MidiMetadataRetriever.cpp @@ -22,6 +22,8 @@ #include "MidiMetadataRetriever.h" #include +#include + namespace android { static status_t ERROR_NOT_OPEN = -1; @@ -36,7 +38,9 @@ void MidiMetadataRetriever::clearMetadataValues() } status_t MidiMetadataRetriever::setDataSource( - const char *url, const KeyedVector *headers) + const sp &httpService, + const char *url, + const KeyedVector *headers) { ALOGV("setDataSource: %s", url? url: "NULL pointer"); Mutex::Autolock lock(mLock); @@ -44,7 +48,7 @@ status_t MidiMetadataRetriever::setDataSource( if (mMidiPlayer == 0) { mMidiPlayer = new MidiFile(); } - return mMidiPlayer->setDataSource(url, headers); + return mMidiPlayer->setDataSource(httpService, url, headers); } status_t MidiMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length) diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.h b/media/libmediaplayerservice/MidiMetadataRetriever.h index 4cee42d..b8214ee 100644 --- a/media/libmediaplayerservice/MidiMetadataRetriever.h +++ b/media/libmediaplayerservice/MidiMetadataRetriever.h @@ -32,7 +32,9 @@ public: ~MidiMetadataRetriever() {} virtual status_t setDataSource( - const char *url, const KeyedVector *headers); + const sp &httpService, + const char *url, + const KeyedVector *headers); virtual status_t setDataSource(int fd, int64_t offset, int64_t length); virtual const char* extractMetadata(int keyCode); diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp index de61d9b..b19e8bf 100644 --- a/media/libmediaplayerservice/StagefrightPlayer.cpp +++ b/media/libmediaplayerservice/StagefrightPlayer.cpp @@ -54,8 +54,10 @@ status_t StagefrightPlayer::setUID(uid_t uid) { } status_t StagefrightPlayer::setDataSource( - const char *url, const KeyedVector *headers) { - return mPlayer->setDataSource(url, headers); + const sp &httpService, + const char *url, + const KeyedVector *headers) { + return mPlayer->setDataSource(httpService, url, headers); } // Warning: The filedescriptor passed into this method will only be valid until diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h index 600945e..e6c30ff 100644 --- a/media/libmediaplayerservice/StagefrightPlayer.h +++ b/media/libmediaplayerservice/StagefrightPlayer.h @@ -34,7 +34,9 @@ public: virtual status_t setUID(uid_t uid); virtual status_t setDataSource( - const char *url, const KeyedVector *headers); + const sp &httpService, + const char *url, + const KeyedVector *headers); virtual status_t setDataSource(int fd, int64_t offset, int64_t length); diff --git a/media/libmediaplayerservice/TestPlayerStub.cpp b/media/libmediaplayerservice/TestPlayerStub.cpp index 5d9728a..5795773 100644 --- a/media/libmediaplayerservice/TestPlayerStub.cpp +++ b/media/libmediaplayerservice/TestPlayerStub.cpp @@ -113,7 +113,9 @@ status_t TestPlayerStub::parseUrl() // Create the test player. // Call setDataSource on the test player with the url in param. status_t TestPlayerStub::setDataSource( - const char *url, const KeyedVector *headers) { + const sp &httpService, + const char *url, + const KeyedVector *headers) { if (!isTestUrl(url) || NULL != mHandle) { return INVALID_OPERATION; } @@ -162,7 +164,7 @@ status_t TestPlayerStub::setDataSource( } mPlayer = (*mNewPlayer)(); - return mPlayer->setDataSource(mContentUrl, headers); + return mPlayer->setDataSource(httpService, mContentUrl, headers); } // Internal cleanup. diff --git a/media/libmediaplayerservice/TestPlayerStub.h b/media/libmediaplayerservice/TestPlayerStub.h index a3802eb..55bf2c8 100644 --- a/media/libmediaplayerservice/TestPlayerStub.h +++ b/media/libmediaplayerservice/TestPlayerStub.h @@ -66,7 +66,9 @@ class TestPlayerStub : public MediaPlayerInterface { // @param url Should be a test url. See class comment. virtual status_t setDataSource( - const char* url, const KeyedVector *headers); + const sp &httpService, + const char* url, + const KeyedVector *headers); // Test player for a file descriptor source is not supported. virtual status_t setDataSource(int, int64_t, int64_t) { diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index b04e7a6..837e5b6 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -33,6 +33,7 @@ namespace android { NuPlayer::GenericSource::GenericSource( const sp ¬ify, + const sp &httpService, const char *url, const KeyedVector *headers, bool uidValid, @@ -43,7 +44,7 @@ NuPlayer::GenericSource::GenericSource( DataSource::RegisterDefaultSniffers(); sp dataSource = - DataSource::CreateFromURI(url, headers); + DataSource::CreateFromURI(httpService, url, headers); CHECK(dataSource != NULL); initFromDataSource(dataSource); diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index 2da680c..6d7e1d6 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -33,6 +33,7 @@ struct MediaSource; struct NuPlayer::GenericSource : public NuPlayer::Source { GenericSource( const sp ¬ify, + const sp &httpService, const char *url, const KeyedVector *headers, bool uidValid = false, diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp index f1782cc..e4145e6 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp @@ -24,6 +24,7 @@ #include "LiveDataSource.h" #include "LiveSession.h" +#include #include #include #include @@ -34,10 +35,12 @@ namespace android { NuPlayer::HTTPLiveSource::HTTPLiveSource( const sp ¬ify, + const sp &httpService, const char *url, const KeyedVector *headers, bool uidValid, uid_t uid) : Source(notify), + mHTTPService(httpService), mURL(url), mUIDValid(uidValid), mUID(uid), @@ -79,6 +82,7 @@ void NuPlayer::HTTPLiveSource::prepareAsync() { mLiveSession = new LiveSession( notify, (mFlags & kFlagIncognito) ? LiveSession::kFlagIncognito : 0, + mHTTPService, mUIDValid, mUID); diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h index bcc3f8b..a60d38e 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h @@ -28,6 +28,7 @@ struct LiveSession; struct NuPlayer::HTTPLiveSource : public NuPlayer::Source { HTTPLiveSource( const sp ¬ify, + const sp &httpService, const char *url, const KeyedVector *headers, bool uidValid = false, @@ -61,6 +62,7 @@ private: kWhatFetchSubtitleData, }; + sp mHTTPService; AString mURL; KeyedVector mExtraHeaders; bool mUIDValid; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 3669a5b..93fe594 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -212,7 +212,9 @@ static bool IsHTTPLiveURL(const char *url) { } void NuPlayer::setDataSourceAsync( - const char *url, const KeyedVector *headers) { + const sp &httpService, + const char *url, + const KeyedVector *headers) { sp msg = new AMessage(kWhatSetDataSource, id()); size_t len = strlen(url); @@ -220,16 +222,20 @@ void NuPlayer::setDataSourceAsync( sp source; if (IsHTTPLiveURL(url)) { - source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID); + source = new HTTPLiveSource( + notify, httpService, url, headers, mUIDValid, mUID); } else if (!strncasecmp(url, "rtsp://", 7)) { - source = new RTSPSource(notify, url, headers, mUIDValid, mUID); + source = new RTSPSource( + notify, httpService, url, headers, mUIDValid, mUID); } else if ((!strncasecmp(url, "http://", 7) || !strncasecmp(url, "https://", 8)) && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) || strstr(url, ".sdp?"))) { - source = new RTSPSource(notify, url, headers, mUIDValid, mUID, true); + source = new RTSPSource( + notify, httpService, url, headers, mUIDValid, mUID, true); } else { - source = new GenericSource(notify, url, headers, mUIDValid, mUID); + source = new GenericSource( + notify, httpService, url, headers, mUIDValid, mUID); } msg->setObject("source", source); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index 590e1f2..9dfe4a0 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -38,7 +38,9 @@ struct NuPlayer : public AHandler { void setDataSourceAsync(const sp &source); void setDataSourceAsync( - const char *url, const KeyedVector *headers); + const sp &httpService, + const char *url, + const KeyedVector *headers); void setDataSourceAsync(int fd, int64_t offset, int64_t length); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp index 47834fd..d35d1df 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp @@ -70,7 +70,9 @@ status_t NuPlayerDriver::setUID(uid_t uid) { } status_t NuPlayerDriver::setDataSource( - const char *url, const KeyedVector *headers) { + const sp &httpService, + const char *url, + const KeyedVector *headers) { Mutex::Autolock autoLock(mLock); if (mState != STATE_IDLE) { @@ -79,7 +81,7 @@ status_t NuPlayerDriver::setDataSource( mState = STATE_SET_DATASOURCE_PENDING; - mPlayer->setDataSourceAsync(url, headers); + mPlayer->setDataSourceAsync(httpService, url, headers); while (mState == STATE_SET_DATASOURCE_PENDING) { mCondition.wait(mLock); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h index 99f72a6..0148fb1 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h @@ -31,7 +31,9 @@ struct NuPlayerDriver : public MediaPlayerInterface { virtual status_t setUID(uid_t uid); virtual status_t setDataSource( - const char *url, const KeyedVector *headers); + const sp &httpService, + const char *url, + const KeyedVector *headers); virtual status_t setDataSource(int fd, int64_t offset, int64_t length); diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp index 18cf6d1..6cdf0c9 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp @@ -24,6 +24,7 @@ #include "MyHandler.h" #include "SDPLoader.h" +#include #include #include @@ -33,12 +34,14 @@ const int64_t kNearEOSTimeoutUs = 2000000ll; // 2 secs NuPlayer::RTSPSource::RTSPSource( const sp ¬ify, + const sp &httpService, const char *url, const KeyedVector *headers, bool uidValid, uid_t uid, bool isSDP) : Source(notify), + mHTTPService(httpService), mURL(url), mUIDValid(uidValid), mUID(uid), @@ -92,6 +95,7 @@ void NuPlayer::RTSPSource::prepareAsync() { if (mIsSDP) { mSDPLoader = new SDPLoader(notify, (mFlags & kFlagIncognito) ? SDPLoader::kFlagIncognito : 0, + mHTTPService, mUIDValid, mUID); mSDPLoader->load( diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h index 8cf34a0..3718bf9 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.h +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h @@ -34,6 +34,7 @@ struct SDPLoader; struct NuPlayer::RTSPSource : public NuPlayer::Source { RTSPSource( const sp ¬ify, + const sp &httpService, const char *url, const KeyedVector *headers, bool uidValid = false, @@ -88,6 +89,7 @@ private: bool mNPTMappingValid; }; + sp mHTTPService; AString mURL; KeyedVector mExtraHeaders; bool mUIDValid; diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk index 6a2a696..c6cee5d 100644 --- a/media/libstagefright/Android.mk +++ b/media/libstagefright/Android.mk @@ -32,6 +32,7 @@ LOCAL_SRC_FILES:= \ MediaCodecList.cpp \ MediaDefs.cpp \ MediaExtractor.cpp \ + http/MediaHTTP.cpp \ MediaMuxer.cpp \ MediaSource.cpp \ MetaData.cpp \ diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index aae6800..67ea052 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -34,6 +34,8 @@ #include #include +#include +#include #include #include #include @@ -44,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -276,15 +279,20 @@ void AwesomePlayer::setUID(uid_t uid) { } status_t AwesomePlayer::setDataSource( - const char *uri, const KeyedVector *headers) { + const sp &httpService, + const char *uri, + const KeyedVector *headers) { Mutex::Autolock autoLock(mLock); - return setDataSource_l(uri, headers); + return setDataSource_l(httpService, uri, headers); } status_t AwesomePlayer::setDataSource_l( - const char *uri, const KeyedVector *headers) { + const sp &httpService, + const char *uri, + const KeyedVector *headers) { reset_l(); + mHTTPService = httpService; mUri = uri; if (headers) { @@ -581,6 +589,7 @@ void AwesomePlayer::reset_l() { mSeekNotificationSent = true; mSeekTimeUs = 0; + mHTTPService.clear(); mUri.setTo(""); mUriHeaders.clear(); @@ -1482,7 +1491,7 @@ void AwesomePlayer::addTextSource_l(size_t trackIndex, const sp& so CHECK(source != NULL); if (mTextDriver == NULL) { - mTextDriver = new TimedTextDriver(mListener); + mTextDriver = new TimedTextDriver(mListener, mHTTPService); } mTextDriver->addInBandTextSource(trackIndex, source); @@ -2192,15 +2201,14 @@ status_t AwesomePlayer::finishSetDataSource_l() { if (!strncasecmp("http://", mUri.string(), 7) || !strncasecmp("https://", mUri.string(), 8) || isWidevineStreaming) { - mConnectingDataSource = HTTPBase::Create( - (mFlags & INCOGNITO) - ? HTTPBase::kFlagIncognito - : 0); - - if (mUIDValid) { - mConnectingDataSource->setUID(mUID); + if (mHTTPService == NULL) { + ALOGE("Attempt to play media from http URI without HTTP service."); + return UNKNOWN_ERROR; } + sp conn = mHTTPService->makeHTTPConnection(); + mConnectingDataSource = new MediaHTTP(conn); + String8 cacheConfig; bool disconnectAtHighwatermark; NuCachedSource2::RemoveCacheSpecificHeaders( @@ -2316,7 +2324,8 @@ status_t AwesomePlayer::finishSetDataSource_l() { } } } else { - dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders); + dataSource = DataSource::CreateFromURI( + mHTTPService, mUri.string(), &mUriHeaders); } if (dataSource == NULL) { @@ -2758,7 +2767,7 @@ status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) { { Mutex::Autolock autoLock(mLock); if (mTextDriver == NULL) { - mTextDriver = new TimedTextDriver(mListener); + mTextDriver = new TimedTextDriver(mListener, mHTTPService); } // String values written in Parcel are UTF-16 values. String8 uri(request.readString16()); @@ -2770,7 +2779,7 @@ status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) { { Mutex::Autolock autoLock(mLock); if (mTextDriver == NULL) { - mTextDriver = new TimedTextDriver(mListener); + mTextDriver = new TimedTextDriver(mListener, mHTTPService); } int fd = request.readFileDescriptor(); off64_t offset = request.readInt64(); @@ -2899,6 +2908,8 @@ void AwesomePlayer::onAudioTearDownEvent() { // get current position so we can start recreated stream from here getPosition(&mAudioTearDownPosition); + sp savedHTTPService = mHTTPService; + // Reset and recreate reset_l(); @@ -2908,7 +2919,7 @@ void AwesomePlayer::onAudioTearDownEvent() { mFileSource = fileSource; err = setDataSource_l(fileSource); } else { - err = setDataSource_l(uri, &uriHeaders); + err = setDataSource_l(savedHTTPService, uri, &uriHeaders); } mFlags |= PREPARING; diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp index 97987e2..9ff9ca2 100644 --- a/media/libstagefright/DataSource.cpp +++ b/media/libstagefright/DataSource.cpp @@ -35,10 +35,13 @@ #include "matroska/MatroskaExtractor.h" +#include +#include #include #include #include #include +#include #include #include @@ -180,7 +183,9 @@ void DataSource::RegisterDefaultSniffers() { // static sp DataSource::CreateFromURI( - const char *uri, const KeyedVector *headers) { + const sp &httpService, + const char *uri, + const KeyedVector *headers) { bool isWidevine = !strncasecmp("widevine://", uri, 11); sp source; @@ -189,7 +194,7 @@ sp DataSource::CreateFromURI( } else if (!strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8) || isWidevine) { - sp httpSource = HTTPBase::Create(); + sp httpSource = new MediaHTTP(httpService->makeHTTPConnection()); String8 tmp; if (isWidevine) { diff --git a/media/libstagefright/HTTPBase.cpp b/media/libstagefright/HTTPBase.cpp index 5fa4b6f..f3b1ef9 100644 --- a/media/libstagefright/HTTPBase.cpp +++ b/media/libstagefright/HTTPBase.cpp @@ -46,21 +46,6 @@ HTTPBase::HTTPBase() } // static -sp HTTPBase::Create(uint32_t flags) { -#if CHROMIUM_AVAILABLE - HTTPBase *dataSource = createChromiumHTTPDataSource(flags); - if (dataSource) { - return dataSource; - } -#endif - { - TRESPASS(); - - return NULL; - } -} - -// static status_t HTTPBase::UpdateProxyConfig( const char *host, int32_t port, const char *exclusionList) { #if CHROMIUM_AVAILABLE diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp index 05e599b..1287fb1 100644 --- a/media/libstagefright/NuCachedSource2.cpp +++ b/media/libstagefright/NuCachedSource2.cpp @@ -213,7 +213,14 @@ NuCachedSource2::NuCachedSource2( mLooper->setName("NuCachedSource2"); mLooper->registerHandler(mReflector); - mLooper->start(); + + // Since it may not be obvious why our looper thread needs to be + // able to call into java since it doesn't appear to do so at all... + // IMediaHTTPConnection may be (and most likely is) implemented in JAVA + // and a local JAVA IBinder will call directly into JNI methods. + // So whenever we call DataSource::readAt it may end up in a call to + // IMediaHTTPConnection::readAt and therefore call back into JAVA. + mLooper->start(false /* runOnCallingThread */, true /* canCallJava */); Mutex::Autolock autoLock(mLock); (new AMessage(kWhatFetchMore, mReflector->id()))->post(); diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp index 7bc7da2..64f56e9 100644 --- a/media/libstagefright/NuMediaExtractor.cpp +++ b/media/libstagefright/NuMediaExtractor.cpp @@ -58,7 +58,9 @@ NuMediaExtractor::~NuMediaExtractor() { } status_t NuMediaExtractor::setDataSource( - const char *path, const KeyedVector *headers) { + const sp &httpService, + const char *path, + const KeyedVector *headers) { Mutex::Autolock autoLock(mLock); if (mImpl != NULL) { @@ -66,7 +68,7 @@ status_t NuMediaExtractor::setDataSource( } sp dataSource = - DataSource::CreateFromURI(path, headers); + DataSource::CreateFromURI(httpService, path, headers); if (dataSource == NULL) { return -ENOENT; diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp index af8186c..edd12fc 100644 --- a/media/libstagefright/StagefrightMediaScanner.cpp +++ b/media/libstagefright/StagefrightMediaScanner.cpp @@ -24,6 +24,7 @@ #include +#include #include #include @@ -147,7 +148,7 @@ MediaScanResult StagefrightMediaScanner::processFileInternal( status_t status; if (fd < 0) { // couldn't open it locally, maybe the media server can? - status = mRetriever->setDataSource(path); + status = mRetriever->setDataSource(NULL /* httpService */, path); } else { status = mRetriever->setDataSource(fd, 0, 0x7ffffffffffffffL); close(fd); diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp index 19af4fb..b4f906e 100644 --- a/media/libstagefright/StagefrightMetadataRetriever.cpp +++ b/media/libstagefright/StagefrightMetadataRetriever.cpp @@ -20,6 +20,7 @@ #include "include/StagefrightMetadataRetriever.h" +#include #include #include #include @@ -50,7 +51,9 @@ StagefrightMetadataRetriever::~StagefrightMetadataRetriever() { } status_t StagefrightMetadataRetriever::setDataSource( - const char *uri, const KeyedVector *headers) { + const sp &httpService, + const char *uri, + const KeyedVector *headers) { ALOGV("setDataSource(%s)", uri); mParsedMetaData = false; @@ -58,7 +61,7 @@ status_t StagefrightMetadataRetriever::setDataSource( delete mAlbumArt; mAlbumArt = NULL; - mSource = DataSource::CreateFromURI(uri, headers); + mSource = DataSource::CreateFromURI(httpService, uri, headers); if (mSource == NULL) { ALOGE("Unable to create data source for '%s'.", uri); diff --git a/media/libstagefright/http/Android.mk b/media/libstagefright/http/Android.mk new file mode 100644 index 0000000..baef9ab --- /dev/null +++ b/media/libstagefright/http/Android.mk @@ -0,0 +1,22 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + HTTPHelper.cpp \ + +LOCAL_C_INCLUDES:= \ + $(TOP)/frameworks/av/media/libstagefright \ + $(TOP)/frameworks/native/include/media/openmax \ + $(TOP)/frameworks/base/core/jni \ + +LOCAL_SHARED_LIBRARIES := \ + libstagefright liblog libutils libbinder libstagefright_foundation \ + libandroid_runtime \ + libmedia + +LOCAL_MODULE:= libstagefright_http_support + +LOCAL_CFLAGS += -Wno-multichar + +include $(BUILD_SHARED_LIBRARY) diff --git a/media/libstagefright/http/HTTPHelper.cpp b/media/libstagefright/http/HTTPHelper.cpp new file mode 100644 index 0000000..77845e2 --- /dev/null +++ b/media/libstagefright/http/HTTPHelper.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2014 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_NDEBUG 0 +#define LOG_TAG "HTTPHelper" +#include + +#include "HTTPHelper.h" + +#include "android_runtime/AndroidRuntime.h" +#include "android_util_Binder.h" +#include +#include +#include +#include "jni.h" + +namespace android { + +sp CreateHTTPServiceInCurrentJavaContext() { + if (AndroidRuntime::getJavaVM() == NULL) { + ALOGE("CreateHTTPServiceInCurrentJavaContext called outside " + "JAVA environment."); + return NULL; + } + + JNIEnv *env = AndroidRuntime::getJNIEnv(); + + ScopedLocalRef clazz( + env, env->FindClass("android/media/MediaHTTPService")); + CHECK(clazz.get() != NULL); + + jmethodID constructID = env->GetMethodID(clazz.get(), "", "()V"); + CHECK(constructID != NULL); + + ScopedLocalRef httpServiceObj( + env, env->NewObject(clazz.get(), constructID)); + + sp httpService; + if (httpServiceObj.get() != NULL) { + jmethodID asBinderID = + env->GetMethodID(clazz.get(), "asBinder", "()Landroid/os/IBinder;"); + CHECK(asBinderID != NULL); + + ScopedLocalRef httpServiceBinderObj( + env, env->CallObjectMethod(httpServiceObj.get(), asBinderID)); + CHECK(httpServiceBinderObj.get() != NULL); + + sp binder = + ibinderForJavaObject(env, httpServiceBinderObj.get()); + + httpService = interface_cast(binder); + } + + return httpService; +} + +} // namespace android diff --git a/media/libstagefright/http/HTTPHelper.h b/media/libstagefright/http/HTTPHelper.h new file mode 100644 index 0000000..8aef115 --- /dev/null +++ b/media/libstagefright/http/HTTPHelper.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2014 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 HTTP_HELPER_H_ + +#define HTTP_HELPER_H_ + +#include + +namespace android { + +struct IMediaHTTPService; + +sp CreateHTTPServiceInCurrentJavaContext(); + +} // namespace android + +#endif // HTTP_HELPER_H_ diff --git a/media/libstagefright/http/MediaHTTP.cpp b/media/libstagefright/http/MediaHTTP.cpp new file mode 100644 index 0000000..157d967 --- /dev/null +++ b/media/libstagefright/http/MediaHTTP.cpp @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2013 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_NDEBUG 0 +#define LOG_TAG "MediaHTTP" +#include + +#include + +#include +#include +#include +#include + +#include + +namespace android { + +MediaHTTP::MediaHTTP(const sp &conn) + : mInitCheck(NO_INIT), + mHTTPConnection(conn), + mCachedSizeValid(false), + mCachedSize(0ll), + mDrmManagerClient(NULL) { + mInitCheck = OK; +} + +MediaHTTP::~MediaHTTP() { + clearDRMState_l(); +} + +status_t MediaHTTP::connect( + const char *uri, + const KeyedVector *headers, + off64_t /* offset */) { + if (mInitCheck != OK) { + return mInitCheck; + } + + KeyedVector extHeaders; + if (headers != NULL) { + extHeaders = *headers; + } + extHeaders.add(String8("User-Agent"), String8(MakeUserAgent().c_str())); + + bool success = mHTTPConnection->connect(uri, &extHeaders); + + mLastHeaders = extHeaders; + mLastURI = uri; + + mCachedSizeValid = false; + + return success ? OK : UNKNOWN_ERROR; +} + +void MediaHTTP::disconnect() { + if (mInitCheck != OK) { + return; + } + + mHTTPConnection->disconnect(); +} + +status_t MediaHTTP::initCheck() const { + return mInitCheck; +} + +ssize_t MediaHTTP::readAt(off64_t offset, void *data, size_t size) { + if (mInitCheck != OK) { + return mInitCheck; + } + + int64_t startTimeUs = ALooper::GetNowUs(); + + size_t numBytesRead = 0; + while (numBytesRead < size) { + size_t copy = size - numBytesRead; + + if (copy > 64 * 1024) { + // limit the buffer sizes transferred across binder boundaries + // to avoid spurious transaction failures. + copy = 64 * 1024; + } + + ssize_t n = mHTTPConnection->readAt( + offset + numBytesRead, (uint8_t *)data + numBytesRead, copy); + + if (n < 0) { + return n; + } else if (n == 0) { + break; + } + + numBytesRead += n; + } + + int64_t delayUs = ALooper::GetNowUs() - startTimeUs; + + addBandwidthMeasurement(numBytesRead, delayUs); + + return numBytesRead; +} + +status_t MediaHTTP::getSize(off64_t *size) { + if (mInitCheck != OK) { + return mInitCheck; + } + + // Caching the returned size so that it stays valid even after a + // disconnect. NuCachedSource2 relies on this. + + if (!mCachedSizeValid) { + mCachedSize = mHTTPConnection->getSize(); + mCachedSizeValid = true; + } + + *size = mCachedSize; + + return *size < 0 ? *size : OK; +} + +uint32_t MediaHTTP::flags() { + return kWantsPrefetching | kIsHTTPBasedSource; +} + +status_t MediaHTTP::reconnectAtOffset(off64_t offset) { + return connect(mLastURI.c_str(), &mLastHeaders, offset); +} + +// DRM... + +sp MediaHTTP::DrmInitialization(const char* mime) { + if (mDrmManagerClient == NULL) { + mDrmManagerClient = new DrmManagerClient(); + } + + if (mDrmManagerClient == NULL) { + return NULL; + } + + if (mDecryptHandle == NULL) { + mDecryptHandle = mDrmManagerClient->openDecryptSession( + String8(mLastURI.c_str()), mime); + } + + if (mDecryptHandle == NULL) { + delete mDrmManagerClient; + mDrmManagerClient = NULL; + } + + return mDecryptHandle; +} + +void MediaHTTP::getDrmInfo( + sp &handle, DrmManagerClient **client) { + handle = mDecryptHandle; + *client = mDrmManagerClient; +} + +String8 MediaHTTP::getUri() { + return String8(mLastURI.c_str()); +} + +String8 MediaHTTP::getMIMEType() const { + if (mInitCheck != OK) { + return String8("application/octet-stream"); + } + + String8 mimeType; + status_t err = mHTTPConnection->getMIMEType(&mimeType); + + if (err != OK) { + return String8("application/octet-stream"); + } + + return mimeType; +} + +void MediaHTTP::clearDRMState_l() { + if (mDecryptHandle != NULL) { + // To release mDecryptHandle + CHECK(mDrmManagerClient); + mDrmManagerClient->closeDecryptSession(mDecryptHandle); + mDecryptHandle = NULL; + } +} + +} // namespace android diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp index 233db44..dbdca5c 100644 --- a/media/libstagefright/httplive/LiveSession.cpp +++ b/media/libstagefright/httplive/LiveSession.cpp @@ -27,6 +27,8 @@ #include "mpeg2ts/AnotherPacketSource.h" #include +#include +#include #include #include #include @@ -34,6 +36,7 @@ #include #include #include +#include #include #include @@ -44,17 +47,16 @@ namespace android { LiveSession::LiveSession( - const sp ¬ify, uint32_t flags, bool uidValid, uid_t uid) + const sp ¬ify, uint32_t flags, + const sp &httpService, + bool uidValid, uid_t uid) : mNotify(notify), mFlags(flags), + mHTTPService(httpService), mUIDValid(uidValid), mUID(uid), mInPreparationPhase(true), - mHTTPDataSource( - HTTPBase::Create( - (mFlags & kFlagIncognito) - ? HTTPBase::kFlagIncognito - : 0)), + mHTTPDataSource(new MediaHTTP(mHTTPService->makeHTTPConnection())), mPrevBandwidthIndex(-1), mStreamMask(0), mCheckBandwidthGeneration(0), diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h index 99b480a8..16fc65a 100644 --- a/media/libstagefright/httplive/LiveSession.h +++ b/media/libstagefright/httplive/LiveSession.h @@ -28,6 +28,7 @@ struct ABuffer; struct AnotherPacketSource; struct DataSource; struct HTTPBase; +struct IMediaHTTPService; struct LiveDataSource; struct M3UParser; struct PlaylistFetcher; @@ -40,7 +41,10 @@ struct LiveSession : public AHandler { }; LiveSession( const sp ¬ify, - uint32_t flags = 0, bool uidValid = false, uid_t uid = 0); + uint32_t flags, + const sp &httpService, + bool uidValid = false, + uid_t uid = 0); enum StreamType { STREAMTYPE_AUDIO = 1, @@ -107,6 +111,7 @@ private: sp mNotify; uint32_t mFlags; + sp mHTTPService; bool mUIDValid; uid_t mUID; diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h index 271df8e..a81bbba 100644 --- a/media/libstagefright/include/AwesomePlayer.h +++ b/media/libstagefright/include/AwesomePlayer.h @@ -63,6 +63,7 @@ struct AwesomePlayer { void setUID(uid_t uid); status_t setDataSource( + const sp &httpService, const char *uri, const KeyedVector *headers = NULL); @@ -159,6 +160,7 @@ private: SystemTimeSource mSystemTimeSource; TimeSource *mTimeSource; + sp mHTTPService; String8 mUri; KeyedVector mUriHeaders; @@ -247,6 +249,7 @@ private: sp mExtractor; status_t setDataSource_l( + const sp &httpService, const char *uri, const KeyedVector *headers = NULL); diff --git a/media/libstagefright/include/HTTPBase.h b/media/libstagefright/include/HTTPBase.h index d4b7f9f..f891b56 100644 --- a/media/libstagefright/include/HTTPBase.h +++ b/media/libstagefright/include/HTTPBase.h @@ -54,8 +54,6 @@ struct HTTPBase : public DataSource { void setUID(uid_t uid); bool getUID(uid_t *uid) const; - static sp Create(uint32_t flags = 0); - static void RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag); static void UnRegisterSocketUserTag(int sockfd); diff --git a/media/libstagefright/include/SDPLoader.h b/media/libstagefright/include/SDPLoader.h index ca59dc0..223bd92 100644 --- a/media/libstagefright/include/SDPLoader.h +++ b/media/libstagefright/include/SDPLoader.h @@ -25,6 +25,7 @@ namespace android { struct HTTPBase; +struct IMediaHTTPService; struct SDPLoader : public AHandler { enum Flags { @@ -34,7 +35,12 @@ struct SDPLoader : public AHandler { enum { kWhatSDPLoaded = 'sdpl' }; - SDPLoader(const sp ¬ify, uint32_t flags = 0, bool uidValid = false, uid_t uid = 0); + SDPLoader( + const sp ¬ify, + uint32_t flags, + const sp &httpService, + bool uidValid = false, + uid_t uid = 0); void load(const char* url, const KeyedVector *headers); diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libstagefright/include/StagefrightMetadataRetriever.h index b02ed0e..6632c27 100644 --- a/media/libstagefright/include/StagefrightMetadataRetriever.h +++ b/media/libstagefright/include/StagefrightMetadataRetriever.h @@ -33,6 +33,7 @@ struct StagefrightMetadataRetriever : public MediaMetadataRetrieverInterface { virtual ~StagefrightMetadataRetriever(); virtual status_t setDataSource( + const sp &httpService, const char *url, const KeyedVector *headers); diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp index 4bee808..499545e 100644 --- a/media/libstagefright/omx/tests/OMXHarness.cpp +++ b/media/libstagefright/omx/tests/OMXHarness.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -241,7 +242,8 @@ private: }; static sp CreateExtractorFromURI(const char *uri) { - sp source = DataSource::CreateFromURI(uri); + sp source = + DataSource::CreateFromURI(NULL /* httpService */, uri); if (source == NULL) { return NULL; diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp index 462c384..09f52bc 100644 --- a/media/libstagefright/rtsp/APacketSource.cpp +++ b/media/libstagefright/rtsp/APacketSource.cpp @@ -23,7 +23,7 @@ #include "ARawAudioAssembler.h" #include "ASessionDescription.h" -#include "avc_utils.h" +#include "include/avc_utils.h" #include diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp index efde7a9..4054da6 100644 --- a/media/libstagefright/rtsp/ARTSPConnection.cpp +++ b/media/libstagefright/rtsp/ARTSPConnection.cpp @@ -33,7 +33,7 @@ #include #include -#include "HTTPBase.h" +#include "include/HTTPBase.h" namespace android { diff --git a/media/libstagefright/rtsp/Android.mk b/media/libstagefright/rtsp/Android.mk index e77c69c..02e44f4 100644 --- a/media/libstagefright/rtsp/Android.mk +++ b/media/libstagefright/rtsp/Android.mk @@ -20,7 +20,7 @@ LOCAL_SRC_FILES:= \ SDPLoader.cpp \ LOCAL_C_INCLUDES:= \ - $(TOP)/frameworks/av/media/libstagefright/include \ + $(TOP)/frameworks/av/media/libstagefright \ $(TOP)/frameworks/native/include/media/openmax \ $(TOP)/external/openssl/include diff --git a/media/libstagefright/rtsp/SDPLoader.cpp b/media/libstagefright/rtsp/SDPLoader.cpp index ed3fa7e..6710923 100644 --- a/media/libstagefright/rtsp/SDPLoader.cpp +++ b/media/libstagefright/rtsp/SDPLoader.cpp @@ -18,11 +18,13 @@ #define LOG_TAG "SDPLoader" #include -#include "SDPLoader.h" +#include "include/SDPLoader.h" #include "ASessionDescription.h" -#include "HTTPBase.h" +#include +#include +#include #include #include @@ -30,18 +32,19 @@ namespace android { -SDPLoader::SDPLoader(const sp ¬ify, uint32_t flags, bool uidValid, uid_t uid) +SDPLoader::SDPLoader( + const sp ¬ify, + uint32_t flags, + const sp &httpService, + bool uidValid, + uid_t uid) : mNotify(notify), mFlags(flags), mUIDValid(uidValid), mUID(uid), mNetLooper(new ALooper), mCancelled(false), - mHTTPDataSource( - HTTPBase::Create( - (mFlags & kFlagIncognito) - ? HTTPBase::kFlagIncognito - : 0)) { + mHTTPDataSource(new MediaHTTP(httpService->makeHTTPConnection())) { if (mUIDValid) { mHTTPDataSource->setUID(mUID); } diff --git a/media/libstagefright/timedtext/TimedTextDriver.cpp b/media/libstagefright/timedtext/TimedTextDriver.cpp index 12fd7f4..05d6d02 100644 --- a/media/libstagefright/timedtext/TimedTextDriver.cpp +++ b/media/libstagefright/timedtext/TimedTextDriver.cpp @@ -20,6 +20,7 @@ #include +#include #include #include #include @@ -40,7 +41,8 @@ namespace android { TimedTextDriver::TimedTextDriver( - const wp &listener) + const wp &listener, + const sp &httpService) : mLooper(new ALooper), mListener(listener), mState(UNINITIALIZED), @@ -207,7 +209,7 @@ status_t TimedTextDriver::addOutOfBandTextSource( } sp dataSource = - DataSource::CreateFromURI(uri); + DataSource::CreateFromURI(mHTTPService, uri); return createOutOfBandTextSource(trackIndex, mimeType, dataSource); } diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp index 286ea13..1a5acba 100644 --- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp +++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -749,7 +750,8 @@ status_t WifiDisplaySource::PlaybackSession::setupMediaPacketizer( mExtractor = new NuMediaExtractor; - status_t err = mExtractor->setDataSource(mMediaPath.c_str()); + status_t err = mExtractor->setDataSource( + NULL /* httpService */, mMediaPath.c_str()); if (err != OK) { return err; diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index eeedfc9..dcea760 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -866,7 +867,7 @@ void CameraService::setCameraFree(int cameraId) { MediaPlayer* CameraService::newMediaPlayer(const char *file) { MediaPlayer* mp = new MediaPlayer(); - if (mp->setDataSource(file, NULL) == NO_ERROR) { + if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) { mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE); mp->prepare(); } else { -- cgit v1.1