Loading media/libmedia/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -254,6 +254,7 @@ cc_library { srcs: [ "BufferingSettings.cpp", "DataSourceDesc.cpp", "IDataSource.cpp", "IMediaExtractor.cpp", "IMediaExtractorService.cpp", Loading media/libmedia/DataSourceDesc.cpp 0 → 100644 +37 −0 Original line number Diff line number Diff line /* * Copyright 2018 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 "DataSourceDesc" #include <media/DataSource.h> #include <media/DataSourceDesc.h> #include <media/MediaHTTPService.h> namespace android { static const int64_t kLongMax = 0x7ffffffffffffffL; DataSourceDesc::DataSourceDesc() : mType(TYPE_NONE), mFDOffset(0), mFDLength(kLongMax), mId(0), mStartPositionMs(0), mEndPositionMs(0) { } } // namespace android media/libmedia/MediaPlayer2Manager.cpp +34 −145 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #include <utils/Vector.h> #include <media/AudioPolicyHelper.h> #include <media/DataSourceDesc.h> #include <media/MediaHTTPService.h> #include <media/MediaPlayer2EngineClient.h> #include <media/MediaPlayer2Interface.h> Loading Loading @@ -247,13 +248,6 @@ extern ALooperRoster gLooperRoster; MediaPlayer2Manager gMediaPlayer2Manager; static bool checkPermission(const char* permissionString) { if (getpid() == IPCThreadState::self()->getCallingPid()) return true; bool ok = checkCallingPermission(String16(permissionString)); if (!ok) ALOGE("Request requires %s", permissionString); return ok; } // TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround /* static */ int MediaPlayer2Manager::AudioOutput::mMinBufferCount = 4; /* static */ bool MediaPlayer2Manager::AudioOutput::mIsOnEmulator = false; Loading Loading @@ -284,6 +278,10 @@ sp<MediaPlayer2Engine> MediaPlayer2Manager::create( sp<Client> c = new Client( mPid, connId, client, audioSessionId, mUid); if (!c->init()) { return NULL; } ALOGV("Create new client(%d) from pid %d, uid %d, ", connId, mPid, mUid); wp<Client> w = c; Loading Loading @@ -514,6 +512,25 @@ MediaPlayer2Manager::Client::Client( #endif } bool MediaPlayer2Manager::Client::init() { sp<MediaPlayer2Interface> p = new NuPlayer2Driver(mPid); status_t init_result = p->initCheck(); if (init_result != NO_ERROR) { ALOGE("Failed to create player object, initCheck failed(%d)", init_result); return false; } p->setNotifyCallback(this, notify); p->setUID(mUid); mAudioDeviceUpdatedListener = new AudioDeviceUpdatedNotifier(p); mAudioOutput = new AudioOutput(mAudioSessionId, mUid, mPid, mAudioAttributes, mAudioDeviceUpdatedListener); p->setAudioSink(mAudioOutput); mPlayer = p; return true; } MediaPlayer2Manager::Client::~Client() { ALOGV("Client(%d) destructor pid = %d", mConnId, mPid); Loading Loading @@ -560,26 +577,6 @@ void MediaPlayer2Manager::Client::disconnect() IPCThreadState::self()->flushCommands(); } sp<MediaPlayer2Interface> MediaPlayer2Manager::Client::createPlayer() { sp<MediaPlayer2Interface> p = getPlayer(); if (p == NULL) { p = new NuPlayer2Driver(mPid); status_t init_result = p->initCheck(); if (init_result == NO_ERROR) { p->setNotifyCallback(this, notify); } else { ALOGE("Failed to create player, initCheck failed(res = %d)", init_result); p.clear(); } } if (p != NULL) { p->setUID(mUid); } return p; } void MediaPlayer2Manager::Client::AudioDeviceUpdatedNotifier::onAudioDeviceUpdate( audio_io_handle_t audioIo, audio_port_handle_t deviceId) { Loading @@ -591,30 +588,20 @@ void MediaPlayer2Manager::Client::AudioDeviceUpdatedNotifier::onAudioDeviceUpdat } } sp<MediaPlayer2Interface> MediaPlayer2Manager::Client::setDataSource_pre() { sp<MediaPlayer2Interface> p = createPlayer(); status_t MediaPlayer2Manager::Client::setDataSource( const sp<DataSourceDesc> &dsd) { sp<MediaPlayer2Interface> p = getPlayer(); if (p == NULL) { return p; return NO_INIT; } Mutex::Autolock lock(mLock); mAudioDeviceUpdatedListener = new AudioDeviceUpdatedNotifier(p); mAudioOutput = new AudioOutput(mAudioSessionId, mUid, mPid, mAudioAttributes, mAudioDeviceUpdatedListener); p->setAudioSink(mAudioOutput); return p; if (dsd == NULL) { return BAD_VALUE; } status_t MediaPlayer2Manager::Client::setDataSource_post( const sp<MediaPlayer2Interface>& p, status_t status) { ALOGV(" setDataSource"); status_t status = p->setDataSource(dsd); if (status != OK) { ALOGE(" error: %d", status); ALOGE("setDataSource error: %d", status); return status; } Loading @@ -626,102 +613,9 @@ status_t MediaPlayer2Manager::Client::setDataSource_post( } } if (status == OK) { Mutex::Autolock lock(mLock); mPlayer = p; } return status; } status_t MediaPlayer2Manager::Client::setDataSource( const sp<MediaHTTPService> &httpService, const char *url, const KeyedVector<String8, String8> *headers) { ALOGV("setDataSource(%s)", url); if (url == NULL) return UNKNOWN_ERROR; if ((strncmp(url, "http://", 7) == 0) || (strncmp(url, "https://", 8) == 0) || (strncmp(url, "rtsp://", 7) == 0)) { if (!checkPermission("android.permission.INTERNET")) { return PERMISSION_DENIED; } } if (strncmp(url, "content://", 10) == 0) { ALOGE("setDataSource: content scheme is not supported here"); mStatus = UNKNOWN_ERROR; return mStatus; } else { sp<MediaPlayer2Interface> p = setDataSource_pre(); if (p == NULL) { return NO_INIT; } return mStatus = setDataSource_post( p, p->setDataSource(httpService, url, headers)); } } status_t MediaPlayer2Manager::Client::setDataSource(int fd, int64_t offset, int64_t length) { ALOGV("setDataSource fd=%d (%s), offset=%lld, length=%lld", fd, nameForFd(fd).c_str(), (long long) offset, (long long) length); struct stat sb; int ret = fstat(fd, &sb); if (ret != 0) { ALOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno)); return UNKNOWN_ERROR; } ALOGV("st_dev = %llu", static_cast<unsigned long long>(sb.st_dev)); ALOGV("st_mode = %u", sb.st_mode); ALOGV("st_uid = %lu", static_cast<unsigned long>(sb.st_uid)); ALOGV("st_gid = %lu", static_cast<unsigned long>(sb.st_gid)); ALOGV("st_size = %llu", static_cast<unsigned long long>(sb.st_size)); if (offset >= sb.st_size) { ALOGE("offset error"); return UNKNOWN_ERROR; } if (offset + length > sb.st_size) { length = sb.st_size - offset; ALOGV("calculated length = %lld", (long long)length); } sp<MediaPlayer2Interface> p = setDataSource_pre(); if (p == NULL) { return NO_INIT; } // now set data source return mStatus = setDataSource_post(p, p->setDataSource(fd, offset, length)); } status_t MediaPlayer2Manager::Client::setDataSource( const sp<IStreamSource> &source) { sp<MediaPlayer2Interface> p = setDataSource_pre(); if (p == NULL) { return NO_INIT; } // now set data source return mStatus = setDataSource_post(p, p->setDataSource(source)); } status_t MediaPlayer2Manager::Client::setDataSource( const sp<DataSource> &source) { sp<MediaPlayer2Interface> p = setDataSource_pre(); if (p == NULL) { return NO_INIT; } // now set data source return mStatus = setDataSource_post(p, p->setDataSource(source)); } void MediaPlayer2Manager::Client::disconnectNativeWindow_l() { if (mConnectedWindow != NULL && mConnectedWindow->getANativeWindow() != NULL) { status_t err = native_window_api_disconnect( Loading Loading @@ -1187,13 +1081,8 @@ status_t MediaPlayer2Manager::Client::setRetransmitEndpoint( ALOGV("[%d] setRetransmitEndpoint = <none>", mConnId); } sp<MediaPlayer2Interface> p = getPlayer(); // Right now, the only valid time to set a retransmit endpoint is before // player selection has been made (since the presence or absence of a // retransmit endpoint is going to determine which player is selected during // setDataSource). if (p != 0) return INVALID_OPERATION; // setDataSource. if (NULL != endpoint) { Mutex::Autolock lock(mLock); Loading media/libmedia/MediaPlayer2Manager.h +2 −16 Original line number Diff line number Diff line Loading @@ -287,22 +287,7 @@ private: const sp<media::VolumeShaper::Operation>& operation) override; virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) override; sp<MediaPlayer2Interface> createPlayer(); virtual status_t setDataSource( const sp<MediaHTTPService> &httpService, const char *url, const KeyedVector<String8, String8> *headers); virtual status_t setDataSource(int fd, int64_t offset, int64_t length); virtual status_t setDataSource(const sp<IStreamSource> &source); virtual status_t setDataSource(const sp<DataSource> &source); sp<MediaPlayer2Interface> setDataSource_pre(); status_t setDataSource_post(const sp<MediaPlayer2Interface>& p, status_t status); virtual status_t setDataSource(const sp<DataSourceDesc> &dsd); static void notify(const wp<MediaPlayer2Engine> &listener, int msg, int ext1, int ext2, const Parcel *obj); Loading Loading @@ -343,6 +328,7 @@ private: uid_t uid); Client(); virtual ~Client(); bool init(); void deletePlayer(); Loading media/libmedia/include/media/DataSourceDesc.h 0 → 100644 +68 −0 Original line number Diff line number Diff line /* * Copyright 2018 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 ANDROID_DATASOURCEDESC_H #define ANDROID_DATASOURCEDESC_H #include <media/stagefright/foundation/ABase.h> #include <utils/RefBase.h> #include <utils/KeyedVector.h> #include <utils/String8.h> namespace android { class DataSource; struct MediaHTTPService; // A binder interface for implementing a stagefright DataSource remotely. struct DataSourceDesc : public RefBase { public: enum { /* No data source has been set yet */ TYPE_NONE = 0, /* data source is type of MediaDataSource */ TYPE_CALLBACK = 1, /* data source is type of FileDescriptor */ TYPE_FD = 2, /* data source is type of Url */ TYPE_URL = 3, }; DataSourceDesc(); int mType; sp<MediaHTTPService> mHttpService; String8 mUrl; KeyedVector<String8, String8> mHeaders; int mFD; int64_t mFDOffset; int64_t mFDLength; sp<DataSource> mCallbackSource; int64_t mId; int64_t mStartPositionMs; int64_t mEndPositionMs; private: DISALLOW_EVIL_CONSTRUCTORS(DataSourceDesc); }; }; // namespace android #endif // ANDROID_DATASOURCEDESC_H Loading
media/libmedia/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -254,6 +254,7 @@ cc_library { srcs: [ "BufferingSettings.cpp", "DataSourceDesc.cpp", "IDataSource.cpp", "IMediaExtractor.cpp", "IMediaExtractorService.cpp", Loading
media/libmedia/DataSourceDesc.cpp 0 → 100644 +37 −0 Original line number Diff line number Diff line /* * Copyright 2018 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 "DataSourceDesc" #include <media/DataSource.h> #include <media/DataSourceDesc.h> #include <media/MediaHTTPService.h> namespace android { static const int64_t kLongMax = 0x7ffffffffffffffL; DataSourceDesc::DataSourceDesc() : mType(TYPE_NONE), mFDOffset(0), mFDLength(kLongMax), mId(0), mStartPositionMs(0), mEndPositionMs(0) { } } // namespace android
media/libmedia/MediaPlayer2Manager.cpp +34 −145 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #include <utils/Vector.h> #include <media/AudioPolicyHelper.h> #include <media/DataSourceDesc.h> #include <media/MediaHTTPService.h> #include <media/MediaPlayer2EngineClient.h> #include <media/MediaPlayer2Interface.h> Loading Loading @@ -247,13 +248,6 @@ extern ALooperRoster gLooperRoster; MediaPlayer2Manager gMediaPlayer2Manager; static bool checkPermission(const char* permissionString) { if (getpid() == IPCThreadState::self()->getCallingPid()) return true; bool ok = checkCallingPermission(String16(permissionString)); if (!ok) ALOGE("Request requires %s", permissionString); return ok; } // TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround /* static */ int MediaPlayer2Manager::AudioOutput::mMinBufferCount = 4; /* static */ bool MediaPlayer2Manager::AudioOutput::mIsOnEmulator = false; Loading Loading @@ -284,6 +278,10 @@ sp<MediaPlayer2Engine> MediaPlayer2Manager::create( sp<Client> c = new Client( mPid, connId, client, audioSessionId, mUid); if (!c->init()) { return NULL; } ALOGV("Create new client(%d) from pid %d, uid %d, ", connId, mPid, mUid); wp<Client> w = c; Loading Loading @@ -514,6 +512,25 @@ MediaPlayer2Manager::Client::Client( #endif } bool MediaPlayer2Manager::Client::init() { sp<MediaPlayer2Interface> p = new NuPlayer2Driver(mPid); status_t init_result = p->initCheck(); if (init_result != NO_ERROR) { ALOGE("Failed to create player object, initCheck failed(%d)", init_result); return false; } p->setNotifyCallback(this, notify); p->setUID(mUid); mAudioDeviceUpdatedListener = new AudioDeviceUpdatedNotifier(p); mAudioOutput = new AudioOutput(mAudioSessionId, mUid, mPid, mAudioAttributes, mAudioDeviceUpdatedListener); p->setAudioSink(mAudioOutput); mPlayer = p; return true; } MediaPlayer2Manager::Client::~Client() { ALOGV("Client(%d) destructor pid = %d", mConnId, mPid); Loading Loading @@ -560,26 +577,6 @@ void MediaPlayer2Manager::Client::disconnect() IPCThreadState::self()->flushCommands(); } sp<MediaPlayer2Interface> MediaPlayer2Manager::Client::createPlayer() { sp<MediaPlayer2Interface> p = getPlayer(); if (p == NULL) { p = new NuPlayer2Driver(mPid); status_t init_result = p->initCheck(); if (init_result == NO_ERROR) { p->setNotifyCallback(this, notify); } else { ALOGE("Failed to create player, initCheck failed(res = %d)", init_result); p.clear(); } } if (p != NULL) { p->setUID(mUid); } return p; } void MediaPlayer2Manager::Client::AudioDeviceUpdatedNotifier::onAudioDeviceUpdate( audio_io_handle_t audioIo, audio_port_handle_t deviceId) { Loading @@ -591,30 +588,20 @@ void MediaPlayer2Manager::Client::AudioDeviceUpdatedNotifier::onAudioDeviceUpdat } } sp<MediaPlayer2Interface> MediaPlayer2Manager::Client::setDataSource_pre() { sp<MediaPlayer2Interface> p = createPlayer(); status_t MediaPlayer2Manager::Client::setDataSource( const sp<DataSourceDesc> &dsd) { sp<MediaPlayer2Interface> p = getPlayer(); if (p == NULL) { return p; return NO_INIT; } Mutex::Autolock lock(mLock); mAudioDeviceUpdatedListener = new AudioDeviceUpdatedNotifier(p); mAudioOutput = new AudioOutput(mAudioSessionId, mUid, mPid, mAudioAttributes, mAudioDeviceUpdatedListener); p->setAudioSink(mAudioOutput); return p; if (dsd == NULL) { return BAD_VALUE; } status_t MediaPlayer2Manager::Client::setDataSource_post( const sp<MediaPlayer2Interface>& p, status_t status) { ALOGV(" setDataSource"); status_t status = p->setDataSource(dsd); if (status != OK) { ALOGE(" error: %d", status); ALOGE("setDataSource error: %d", status); return status; } Loading @@ -626,102 +613,9 @@ status_t MediaPlayer2Manager::Client::setDataSource_post( } } if (status == OK) { Mutex::Autolock lock(mLock); mPlayer = p; } return status; } status_t MediaPlayer2Manager::Client::setDataSource( const sp<MediaHTTPService> &httpService, const char *url, const KeyedVector<String8, String8> *headers) { ALOGV("setDataSource(%s)", url); if (url == NULL) return UNKNOWN_ERROR; if ((strncmp(url, "http://", 7) == 0) || (strncmp(url, "https://", 8) == 0) || (strncmp(url, "rtsp://", 7) == 0)) { if (!checkPermission("android.permission.INTERNET")) { return PERMISSION_DENIED; } } if (strncmp(url, "content://", 10) == 0) { ALOGE("setDataSource: content scheme is not supported here"); mStatus = UNKNOWN_ERROR; return mStatus; } else { sp<MediaPlayer2Interface> p = setDataSource_pre(); if (p == NULL) { return NO_INIT; } return mStatus = setDataSource_post( p, p->setDataSource(httpService, url, headers)); } } status_t MediaPlayer2Manager::Client::setDataSource(int fd, int64_t offset, int64_t length) { ALOGV("setDataSource fd=%d (%s), offset=%lld, length=%lld", fd, nameForFd(fd).c_str(), (long long) offset, (long long) length); struct stat sb; int ret = fstat(fd, &sb); if (ret != 0) { ALOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno)); return UNKNOWN_ERROR; } ALOGV("st_dev = %llu", static_cast<unsigned long long>(sb.st_dev)); ALOGV("st_mode = %u", sb.st_mode); ALOGV("st_uid = %lu", static_cast<unsigned long>(sb.st_uid)); ALOGV("st_gid = %lu", static_cast<unsigned long>(sb.st_gid)); ALOGV("st_size = %llu", static_cast<unsigned long long>(sb.st_size)); if (offset >= sb.st_size) { ALOGE("offset error"); return UNKNOWN_ERROR; } if (offset + length > sb.st_size) { length = sb.st_size - offset; ALOGV("calculated length = %lld", (long long)length); } sp<MediaPlayer2Interface> p = setDataSource_pre(); if (p == NULL) { return NO_INIT; } // now set data source return mStatus = setDataSource_post(p, p->setDataSource(fd, offset, length)); } status_t MediaPlayer2Manager::Client::setDataSource( const sp<IStreamSource> &source) { sp<MediaPlayer2Interface> p = setDataSource_pre(); if (p == NULL) { return NO_INIT; } // now set data source return mStatus = setDataSource_post(p, p->setDataSource(source)); } status_t MediaPlayer2Manager::Client::setDataSource( const sp<DataSource> &source) { sp<MediaPlayer2Interface> p = setDataSource_pre(); if (p == NULL) { return NO_INIT; } // now set data source return mStatus = setDataSource_post(p, p->setDataSource(source)); } void MediaPlayer2Manager::Client::disconnectNativeWindow_l() { if (mConnectedWindow != NULL && mConnectedWindow->getANativeWindow() != NULL) { status_t err = native_window_api_disconnect( Loading Loading @@ -1187,13 +1081,8 @@ status_t MediaPlayer2Manager::Client::setRetransmitEndpoint( ALOGV("[%d] setRetransmitEndpoint = <none>", mConnId); } sp<MediaPlayer2Interface> p = getPlayer(); // Right now, the only valid time to set a retransmit endpoint is before // player selection has been made (since the presence or absence of a // retransmit endpoint is going to determine which player is selected during // setDataSource). if (p != 0) return INVALID_OPERATION; // setDataSource. if (NULL != endpoint) { Mutex::Autolock lock(mLock); Loading
media/libmedia/MediaPlayer2Manager.h +2 −16 Original line number Diff line number Diff line Loading @@ -287,22 +287,7 @@ private: const sp<media::VolumeShaper::Operation>& operation) override; virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) override; sp<MediaPlayer2Interface> createPlayer(); virtual status_t setDataSource( const sp<MediaHTTPService> &httpService, const char *url, const KeyedVector<String8, String8> *headers); virtual status_t setDataSource(int fd, int64_t offset, int64_t length); virtual status_t setDataSource(const sp<IStreamSource> &source); virtual status_t setDataSource(const sp<DataSource> &source); sp<MediaPlayer2Interface> setDataSource_pre(); status_t setDataSource_post(const sp<MediaPlayer2Interface>& p, status_t status); virtual status_t setDataSource(const sp<DataSourceDesc> &dsd); static void notify(const wp<MediaPlayer2Engine> &listener, int msg, int ext1, int ext2, const Parcel *obj); Loading Loading @@ -343,6 +328,7 @@ private: uid_t uid); Client(); virtual ~Client(); bool init(); void deletePlayer(); Loading
media/libmedia/include/media/DataSourceDesc.h 0 → 100644 +68 −0 Original line number Diff line number Diff line /* * Copyright 2018 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 ANDROID_DATASOURCEDESC_H #define ANDROID_DATASOURCEDESC_H #include <media/stagefright/foundation/ABase.h> #include <utils/RefBase.h> #include <utils/KeyedVector.h> #include <utils/String8.h> namespace android { class DataSource; struct MediaHTTPService; // A binder interface for implementing a stagefright DataSource remotely. struct DataSourceDesc : public RefBase { public: enum { /* No data source has been set yet */ TYPE_NONE = 0, /* data source is type of MediaDataSource */ TYPE_CALLBACK = 1, /* data source is type of FileDescriptor */ TYPE_FD = 2, /* data source is type of Url */ TYPE_URL = 3, }; DataSourceDesc(); int mType; sp<MediaHTTPService> mHttpService; String8 mUrl; KeyedVector<String8, String8> mHeaders; int mFD; int64_t mFDOffset; int64_t mFDLength; sp<DataSource> mCallbackSource; int64_t mId; int64_t mStartPositionMs; int64_t mEndPositionMs; private: DISALLOW_EVIL_CONSTRUCTORS(DataSourceDesc); }; }; // namespace android #endif // ANDROID_DATASOURCEDESC_H