summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/libmedia/AudioTrack.cpp14
-rw-r--r--media/libmediaplayerservice/Android.mk1
-rw-r--r--media/libmediaplayerservice/Drm.cpp74
-rw-r--r--media/libmediaplayerservice/Drm.h3
-rw-r--r--media/libmediaplayerservice/DrmSessionClientInterface.h34
-rw-r--r--media/libmediaplayerservice/DrmSessionManager.cpp271
-rw-r--r--media/libmediaplayerservice/DrmSessionManager.h77
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp7
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h2
-rw-r--r--media/libmediaplayerservice/ProcessInfoInterface.h33
-rw-r--r--media/libmediaplayerservice/nuplayer/Android.mk1
-rw-r--r--media/libmediaplayerservice/nuplayer/GenericSource.cpp44
-rw-r--r--media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp4
-rw-r--r--media/libmediaplayerservice/nuplayer/MediaClock.h77
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp59
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp4
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp16
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp72
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp12
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.h4
-rw-r--r--media/libmediaplayerservice/nuplayer/RTSPSource.cpp10
-rw-r--r--media/libmediaplayerservice/nuplayer/RTSPSource.h3
-rw-r--r--media/libmediaplayerservice/nuplayer/StreamingSource.cpp4
-rw-r--r--media/libmediaplayerservice/tests/Android.mk24
-rw-r--r--media/libmediaplayerservice/tests/DrmSessionManager_test.cpp249
-rw-r--r--media/libstagefright/ACodec.cpp36
-rw-r--r--media/libstagefright/Android.mk1
-rw-r--r--media/libstagefright/HTTPBase.cpp6
-rw-r--r--media/libstagefright/MPEG2TSWriter.cpp6
-rw-r--r--media/libstagefright/MediaClock.cpp (renamed from media/libmediaplayerservice/nuplayer/MediaClock.cpp)2
-rw-r--r--media/libstagefright/MediaCodec.cpp94
-rw-r--r--media/libstagefright/MediaCodecSource.cpp30
-rw-r--r--media/libstagefright/NuCachedSource2.cpp6
-rw-r--r--media/libstagefright/codecs/aacdec/SoftAAC2.cpp6
-rw-r--r--media/libstagefright/filters/MediaFilter.cpp26
-rw-r--r--media/libstagefright/foundation/AHandler.cpp18
-rw-r--r--media/libstagefright/foundation/ALooper.cpp30
-rw-r--r--media/libstagefright/foundation/ALooperRoster.cpp128
-rw-r--r--media/libstagefright/foundation/AMessage.cpp106
-rw-r--r--media/libstagefright/httplive/LiveSession.cpp365
-rw-r--r--media/libstagefright/httplive/LiveSession.h39
-rw-r--r--media/libstagefright/httplive/PlaylistFetcher.cpp74
-rw-r--r--media/libstagefright/httplive/PlaylistFetcher.h6
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.cpp147
-rw-r--r--media/libstagefright/mpeg2ts/AnotherPacketSource.cpp12
-rw-r--r--media/libstagefright/omx/Android.mk4
-rw-r--r--media/libstagefright/omx/GraphicBufferSource.cpp6
-rw-r--r--media/libstagefright/omx/SimpleSoftOMXComponent.cpp6
-rw-r--r--media/libstagefright/rtsp/ARTPConnection.cpp8
-rw-r--r--media/libstagefright/rtsp/ARTPSession.cpp2
-rw-r--r--media/libstagefright/rtsp/ARTPWriter.cpp8
-rw-r--r--media/libstagefright/rtsp/ARTSPConnection.cpp14
-rw-r--r--media/libstagefright/rtsp/MyHandler.h78
-rw-r--r--media/libstagefright/rtsp/MyTransmitter.h40
-rw-r--r--media/libstagefright/rtsp/SDPLoader.cpp2
-rw-r--r--media/libstagefright/rtsp/UDPPusher.cpp4
-rw-r--r--media/libstagefright/timedtext/TimedTextPlayer.cpp14
-rw-r--r--media/libstagefright/wifi-display/MediaSender.cpp4
-rw-r--r--media/libstagefright/wifi-display/rtp/RTPSender.cpp4
-rw-r--r--media/libstagefright/wifi-display/source/Converter.cpp15
-rw-r--r--media/libstagefright/wifi-display/source/MediaPuller.cpp12
-rw-r--r--media/libstagefright/wifi-display/source/PlaybackSession.cpp20
-rw-r--r--media/libstagefright/wifi-display/source/RepeaterSource.cpp2
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.cpp34
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.h3
-rw-r--r--media/libstagefright/yuv/YUVImage.cpp12
-rw-r--r--media/ndk/NdkMediaCodec.cpp8
68 files changed, 1604 insertions, 935 deletions
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 1d5fc95..c775e7b 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -299,6 +299,9 @@ status_t AudioTrack::set(
ALOGV("Building AudioTrack with attributes: usage=%d content=%d flags=0x%x tags=[%s]",
mAttributes.usage, mAttributes.content_type, mAttributes.flags, mAttributes.tags);
mStreamType = AUDIO_STREAM_DEFAULT;
+ if ((mAttributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
+ flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
+ }
}
// these below should probably come from the audioFlinger too...
@@ -1002,7 +1005,9 @@ status_t AudioTrack::createTrack_l()
// use case 1: shared buffer
(mSharedBuffer != 0) ||
// use case 2: callback transfer mode
- (mTransfer == TRANSFER_CALLBACK)) &&
+ (mTransfer == TRANSFER_CALLBACK) ||
+ // use case 3: obtain/release mode
+ (mTransfer == TRANSFER_OBTAIN)) &&
// matching sample rate
(mSampleRate == afSampleRate))) {
ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by client");
@@ -1236,7 +1241,7 @@ release:
return status;
}
-status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
+status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount, size_t *nonContig)
{
if (audioBuffer == NULL) {
return BAD_VALUE;
@@ -1263,7 +1268,7 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
ALOGE("%s invalid waitCount %d", __func__, waitCount);
requested = NULL;
}
- return obtainBuffer(audioBuffer, requested);
+ return obtainBuffer(audioBuffer, requested, NULL /*elapsed*/, nonContig);
}
status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, const struct timespec *requested,
@@ -1338,8 +1343,9 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, const struct timespec *re
return status;
}
-void AudioTrack::releaseBuffer(Buffer* audioBuffer)
+void AudioTrack::releaseBuffer(const Buffer* audioBuffer)
{
+ // FIXME add error checking on mode, by adding an internal version
if (mTransfer == TRANSFER_SHARED) {
return;
}
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 9d8fe62..4b31715 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -10,6 +10,7 @@ LOCAL_SRC_FILES:= \
ActivityManager.cpp \
Crypto.cpp \
Drm.cpp \
+ DrmSessionManager.cpp \
HDCP.cpp \
MediaPlayerFactory.cpp \
MediaPlayerService.cpp \
diff --git a/media/libmediaplayerservice/Drm.cpp b/media/libmediaplayerservice/Drm.cpp
index 73f1a2a..d4f6fab 100644
--- a/media/libmediaplayerservice/Drm.cpp
+++ b/media/libmediaplayerservice/Drm.cpp
@@ -23,6 +23,8 @@
#include "Drm.h"
+#include "DrmSessionClientInterface.h"
+#include "DrmSessionManager.h"
#include <media/drm/DrmAPI.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AString.h>
@@ -33,6 +35,10 @@
namespace android {
+static inline int getCallingPid() {
+ return IPCThreadState::self()->getCallingPid();
+}
+
static bool checkPermission(const char* permissionString) {
#ifndef HAVE_ANDROID_OS
return true;
@@ -57,14 +63,41 @@ static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {
return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0;
}
+struct DrmSessionClient : public DrmSessionClientInterface {
+ DrmSessionClient(Drm* drm) : mDrm(drm) {}
+
+ virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
+ sp<Drm> drm = mDrm.promote();
+ if (drm == NULL) {
+ return true;
+ }
+ status_t err = drm->closeSession(sessionId);
+ if (err != OK) {
+ return false;
+ }
+ drm->sendEvent(DrmPlugin::kDrmPluginEventSessionReclaimed, 0, &sessionId, NULL);
+ return true;
+ }
+
+protected:
+ virtual ~DrmSessionClient() {}
+
+private:
+ wp<Drm> mDrm;
+
+ DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
+};
+
Drm::Drm()
: mInitCheck(NO_INIT),
+ mDrmSessionClient(new DrmSessionClient(this)),
mListener(NULL),
mFactory(NULL),
mPlugin(NULL) {
}
Drm::~Drm() {
+ DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
delete mPlugin;
mPlugin = NULL;
closeFactory();
@@ -289,7 +322,18 @@ status_t Drm::openSession(Vector<uint8_t> &sessionId) {
return -EINVAL;
}
- return mPlugin->openSession(sessionId);
+ status_t err = mPlugin->openSession(sessionId);
+ if (err == ERROR_DRM_RESOURCE_BUSY) {
+ bool retry = false;
+ retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
+ if (retry) {
+ err = mPlugin->openSession(sessionId);
+ }
+ }
+ if (err == OK) {
+ DrmSessionManager::Instance()->addSession(getCallingPid(), mDrmSessionClient, sessionId);
+ }
+ return err;
}
status_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
@@ -303,7 +347,11 @@ status_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
return -EINVAL;
}
- return mPlugin->closeSession(sessionId);
+ status_t err = mPlugin->closeSession(sessionId);
+ if (err == OK) {
+ DrmSessionManager::Instance()->removeSession(sessionId);
+ }
+ return err;
}
status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
@@ -321,6 +369,8 @@ status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
return -EINVAL;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType,
optionalParameters, request, defaultUrl);
}
@@ -338,6 +388,8 @@ status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId,
return -EINVAL;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->provideKeyResponse(sessionId, response, keySetId);
}
@@ -367,6 +419,8 @@ status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
return -EINVAL;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->restoreKeys(sessionId, keySetId);
}
@@ -382,6 +436,8 @@ status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
return -EINVAL;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->queryKeyStatus(sessionId, infoMap);
}
@@ -561,6 +617,8 @@ status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
return -EINVAL;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->setCipherAlgorithm(sessionId, algorithm);
}
@@ -576,6 +634,8 @@ status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
return -EINVAL;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->setMacAlgorithm(sessionId, algorithm);
}
@@ -594,6 +654,8 @@ status_t Drm::encrypt(Vector<uint8_t> const &sessionId,
return -EINVAL;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->encrypt(sessionId, keyId, input, iv, output);
}
@@ -612,6 +674,8 @@ status_t Drm::decrypt(Vector<uint8_t> const &sessionId,
return -EINVAL;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->decrypt(sessionId, keyId, input, iv, output);
}
@@ -629,6 +693,8 @@ status_t Drm::sign(Vector<uint8_t> const &sessionId,
return -EINVAL;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->sign(sessionId, keyId, message, signature);
}
@@ -647,6 +713,8 @@ status_t Drm::verify(Vector<uint8_t> const &sessionId,
return -EINVAL;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->verify(sessionId, keyId, message, signature, match);
}
@@ -669,6 +737,8 @@ status_t Drm::signRSA(Vector<uint8_t> const &sessionId,
return -EPERM;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
}
diff --git a/media/libmediaplayerservice/Drm.h b/media/libmediaplayerservice/Drm.h
index 0e1eb2c..0cea639 100644
--- a/media/libmediaplayerservice/Drm.h
+++ b/media/libmediaplayerservice/Drm.h
@@ -28,6 +28,7 @@ namespace android {
struct DrmFactory;
struct DrmPlugin;
+struct DrmSessionClientInterface;
struct Drm : public BnDrm,
public IBinder::DeathRecipient,
@@ -138,6 +139,8 @@ private:
status_t mInitCheck;
+ sp<DrmSessionClientInterface> mDrmSessionClient;
+
sp<IDrmClient> mListener;
mutable Mutex mEventLock;
mutable Mutex mNotifyLock;
diff --git a/media/libmediaplayerservice/DrmSessionClientInterface.h b/media/libmediaplayerservice/DrmSessionClientInterface.h
new file mode 100644
index 0000000..17faf08
--- /dev/null
+++ b/media/libmediaplayerservice/DrmSessionClientInterface.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 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 DRM_PROXY_INTERFACE_H_
+#define DRM_PROXY_INTERFACE_H_
+
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct DrmSessionClientInterface : public RefBase {
+ virtual bool reclaimSession(const Vector<uint8_t>& sessionId) = 0;
+
+protected:
+ virtual ~DrmSessionClientInterface() {}
+};
+
+} // namespace android
+
+#endif // DRM_PROXY_INTERFACE_H_
diff --git a/media/libmediaplayerservice/DrmSessionManager.cpp b/media/libmediaplayerservice/DrmSessionManager.cpp
new file mode 100644
index 0000000..6e17eb1
--- /dev/null
+++ b/media/libmediaplayerservice/DrmSessionManager.cpp
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2015 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 "DrmSessionManager"
+#include <utils/Log.h>
+
+#include "DrmSessionManager.h"
+
+#include "DrmSessionClientInterface.h"
+#include "ProcessInfoInterface.h"
+#include <binder/IPCThreadState.h>
+#include <binder/IProcessInfoService.h>
+#include <binder/IServiceManager.h>
+#include <unistd.h>
+#include <utils/String8.h>
+
+namespace android {
+
+static String8 GetSessionIdString(const Vector<uint8_t> &sessionId) {
+ String8 sessionIdStr;
+ for (size_t i = 0; i < sessionId.size(); ++i) {
+ sessionIdStr.appendFormat("%u ", sessionId[i]);
+ }
+ return sessionIdStr;
+}
+
+struct ProcessInfo : public ProcessInfoInterface {
+ ProcessInfo() {}
+
+ virtual bool getPriority(int pid, int* priority) {
+ sp<IBinder> binder = defaultServiceManager()->getService(String16("processinfo"));
+ sp<IProcessInfoService> service = interface_cast<IProcessInfoService>(binder);
+
+ size_t length = 1;
+ int32_t states;
+ status_t err = service->getProcessStatesFromPids(length, &pid, &states);
+ if (err != OK) {
+ ALOGE("getProcessStatesFromPids failed");
+ return false;
+ }
+ ALOGV("pid %d states %d", pid, states);
+ if (states < 0) {
+ return false;
+ }
+
+ // Use process state as the priority. Lower the value, higher the priority.
+ *priority = states;
+ return true;
+ }
+
+protected:
+ virtual ~ProcessInfo() {}
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(ProcessInfo);
+};
+
+bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2) {
+ if (sessionId1.size() != sessionId2.size()) {
+ return false;
+ }
+ for (size_t i = 0; i < sessionId1.size(); ++i) {
+ if (sessionId1[i] != sessionId2[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+sp<DrmSessionManager> DrmSessionManager::Instance() {
+ static sp<DrmSessionManager> drmSessionManager = new DrmSessionManager();
+ return drmSessionManager;
+}
+
+DrmSessionManager::DrmSessionManager()
+ : mProcessInfo(new ProcessInfo()),
+ mTime(0) {}
+
+DrmSessionManager::DrmSessionManager(sp<ProcessInfoInterface> processInfo)
+ : mProcessInfo(processInfo),
+ mTime(0) {}
+
+DrmSessionManager::~DrmSessionManager() {}
+
+void DrmSessionManager::addSession(
+ int pid, sp<DrmSessionClientInterface> drm, const Vector<uint8_t> &sessionId) {
+ ALOGV("addSession(pid %d, drm %p, sessionId %s)", pid, drm.get(),
+ GetSessionIdString(sessionId).string());
+
+ Mutex::Autolock lock(mLock);
+ SessionInfo info;
+ info.drm = drm;
+ info.sessionId = sessionId;
+ info.timeStamp = getTime_l();
+ ssize_t index = mSessionMap.indexOfKey(pid);
+ if (index < 0) {
+ // new pid
+ SessionInfos infosForPid;
+ infosForPid.push_back(info);
+ mSessionMap.add(pid, infosForPid);
+ } else {
+ mSessionMap.editValueAt(index).push_back(info);
+ }
+}
+
+void DrmSessionManager::useSession(const Vector<uint8_t> &sessionId) {
+ ALOGV("useSession(%s)", GetSessionIdString(sessionId).string());
+
+ Mutex::Autolock lock(mLock);
+ for (size_t i = 0; i < mSessionMap.size(); ++i) {
+ SessionInfos& infos = mSessionMap.editValueAt(i);
+ for (size_t j = 0; j < infos.size(); ++j) {
+ SessionInfo& info = infos.editItemAt(j);
+ if (isEqualSessionId(sessionId, info.sessionId)) {
+ info.timeStamp = getTime_l();
+ return;
+ }
+ }
+ }
+}
+
+void DrmSessionManager::removeSession(const Vector<uint8_t> &sessionId) {
+ ALOGV("removeSession(%s)", GetSessionIdString(sessionId).string());
+
+ Mutex::Autolock lock(mLock);
+ for (size_t i = 0; i < mSessionMap.size(); ++i) {
+ SessionInfos& infos = mSessionMap.editValueAt(i);
+ for (size_t j = 0; j < infos.size(); ++j) {
+ if (isEqualSessionId(sessionId, infos[j].sessionId)) {
+ infos.removeAt(j);
+ return;
+ }
+ }
+ }
+}
+
+void DrmSessionManager::removeDrm(sp<DrmSessionClientInterface> drm) {
+ ALOGV("removeDrm(%p)", drm.get());
+
+ Mutex::Autolock lock(mLock);
+ bool found = false;
+ for (size_t i = 0; i < mSessionMap.size(); ++i) {
+ SessionInfos& infos = mSessionMap.editValueAt(i);
+ for (size_t j = 0; j < infos.size();) {
+ if (infos[j].drm == drm) {
+ ALOGV("removed session (%s)", GetSessionIdString(infos[j].sessionId).string());
+ j = infos.removeAt(j);
+ found = true;
+ } else {
+ ++j;
+ }
+ }
+ if (found) {
+ break;
+ }
+ }
+}
+
+bool DrmSessionManager::reclaimSession(int callingPid) {
+ ALOGV("reclaimSession(%d)", callingPid);
+
+ sp<DrmSessionClientInterface> drm;
+ Vector<uint8_t> sessionId;
+ int lowestPriorityPid;
+ int lowestPriority;
+ {
+ Mutex::Autolock lock(mLock);
+ int callingPriority;
+ if (!mProcessInfo->getPriority(callingPid, &callingPriority)) {
+ return false;
+ }
+ if (!getLowestPriority_l(&lowestPriorityPid, &lowestPriority)) {
+ return false;
+ }
+ if (lowestPriority <= callingPriority) {
+ return false;
+ }
+
+ if (!getLeastUsedSession_l(lowestPriorityPid, &drm, &sessionId)) {
+ return false;
+ }
+ }
+
+ if (drm == NULL) {
+ return false;
+ }
+
+ ALOGV("reclaim session(%s) opened by pid %d",
+ GetSessionIdString(sessionId).string(), lowestPriorityPid);
+
+ return drm->reclaimSession(sessionId);
+}
+
+int64_t DrmSessionManager::getTime_l() {
+ return mTime++;
+}
+
+bool DrmSessionManager::getLowestPriority_l(int* lowestPriorityPid, int* lowestPriority) {
+ int pid = -1;
+ int priority = -1;
+ for (size_t i = 0; i < mSessionMap.size(); ++i) {
+ if (mSessionMap.valueAt(i).size() == 0) {
+ // no opened session by this process.
+ continue;
+ }
+ int tempPid = mSessionMap.keyAt(i);
+ int tempPriority;
+ if (!mProcessInfo->getPriority(tempPid, &tempPriority)) {
+ // shouldn't happen.
+ return false;
+ }
+ if (pid == -1) {
+ pid = tempPid;
+ priority = tempPriority;
+ } else {
+ if (tempPriority > priority) {
+ pid = tempPid;
+ priority = tempPriority;
+ }
+ }
+ }
+ if (pid != -1) {
+ *lowestPriorityPid = pid;
+ *lowestPriority = priority;
+ }
+ return (pid != -1);
+}
+
+bool DrmSessionManager::getLeastUsedSession_l(
+ int pid, sp<DrmSessionClientInterface>* drm, Vector<uint8_t>* sessionId) {
+ ssize_t index = mSessionMap.indexOfKey(pid);
+ if (index < 0) {
+ return false;
+ }
+
+ int leastUsedIndex = -1;
+ int64_t minTs = LLONG_MAX;
+ const SessionInfos& infos = mSessionMap.valueAt(index);
+ for (size_t j = 0; j < infos.size(); ++j) {
+ if (leastUsedIndex == -1) {
+ leastUsedIndex = j;
+ minTs = infos[j].timeStamp;
+ } else {
+ if (infos[j].timeStamp < minTs) {
+ leastUsedIndex = j;
+ minTs = infos[j].timeStamp;
+ }
+ }
+ }
+ if (leastUsedIndex != -1) {
+ *drm = infos[leastUsedIndex].drm;
+ *sessionId = infos[leastUsedIndex].sessionId;
+ }
+ return (leastUsedIndex != -1);
+}
+
+} // namespace android
diff --git a/media/libmediaplayerservice/DrmSessionManager.h b/media/libmediaplayerservice/DrmSessionManager.h
new file mode 100644
index 0000000..ba5c268
--- /dev/null
+++ b/media/libmediaplayerservice/DrmSessionManager.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015 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 DRM_SESSION_MANAGER_H_
+
+#define DRM_SESSION_MANAGER_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/RefBase.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class DrmSessionManagerTest;
+struct DrmSessionClientInterface;
+struct ProcessInfoInterface;
+
+bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2);
+
+struct SessionInfo {
+ sp<DrmSessionClientInterface> drm;
+ Vector<uint8_t> sessionId;
+ int64_t timeStamp;
+};
+
+typedef Vector<SessionInfo > SessionInfos;
+typedef KeyedVector<int, SessionInfos > PidSessionInfosMap;
+
+struct DrmSessionManager : public RefBase {
+ static sp<DrmSessionManager> Instance();
+
+ DrmSessionManager();
+ DrmSessionManager(sp<ProcessInfoInterface> processInfo);
+
+ void addSession(int pid, sp<DrmSessionClientInterface> drm, const Vector<uint8_t>& sessionId);
+ void useSession(const Vector<uint8_t>& sessionId);
+ void removeSession(const Vector<uint8_t>& sessionId);
+ void removeDrm(sp<DrmSessionClientInterface> drm);
+ bool reclaimSession(int callingPid);
+
+protected:
+ virtual ~DrmSessionManager();
+
+private:
+ friend class DrmSessionManagerTest;
+
+ int64_t getTime_l();
+ bool getLowestPriority_l(int* lowestPriorityPid, int* lowestPriority);
+ bool getLeastUsedSession_l(
+ int pid, sp<DrmSessionClientInterface>* drm, Vector<uint8_t>* sessionId);
+
+ sp<ProcessInfoInterface> mProcessInfo;
+ mutable Mutex mLock;
+ PidSessionInfosMap mSessionMap;
+ int64_t mTime;
+
+ DISALLOW_EVIL_CONSTRUCTORS(DrmSessionManager);
+};
+
+} // namespace android
+
+#endif // DRM_SESSION_MANAGER_H_
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index b595b1d..f113e21 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -290,8 +290,9 @@ MediaPlayerService::MediaPlayerService()
const sp<IServiceManager> sm(defaultServiceManager());
if (sm != NULL) {
const String16 name("batterystats");
+ // use checkService() to avoid blocking if service is not up yet
sp<IBatteryStats> batteryStats =
- interface_cast<IBatteryStats>(sm->getService(name));
+ interface_cast<IBatteryStats>(sm->checkService(name));
if (batteryStats != NULL) {
batteryStats->noteResetVideo();
batteryStats->noteResetAudio();
@@ -1677,13 +1678,13 @@ void MediaPlayerService::AudioOutput::switchToNextOutput() {
}
}
-ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size)
+ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size, bool blocking)
{
LOG_ALWAYS_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");
//ALOGV("write(%p, %u)", buffer, size);
if (mTrack != 0) {
- ssize_t ret = mTrack->write(buffer, size);
+ ssize_t ret = mTrack->write(buffer, size, blocking);
if (ret >= 0) {
mBytesWritten += ret;
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 7320311..4ce4b81 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -97,7 +97,7 @@ class MediaPlayerService : public BnMediaPlayerService
const audio_offload_info_t *offloadInfo = NULL);
virtual status_t start();
- virtual ssize_t write(const void* buffer, size_t size);
+ virtual ssize_t write(const void* buffer, size_t size, bool blocking = true);
virtual void stop();
virtual void flush();
virtual void pause();
diff --git a/media/libmediaplayerservice/ProcessInfoInterface.h b/media/libmediaplayerservice/ProcessInfoInterface.h
new file mode 100644
index 0000000..222f92d
--- /dev/null
+++ b/media/libmediaplayerservice/ProcessInfoInterface.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 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 PROCESS_INFO_INTERFACE_H_
+#define PROCESS_INFO_INTERFACE_H_
+
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct ProcessInfoInterface : public RefBase {
+ virtual bool getPriority(int pid, int* priority) = 0;
+
+protected:
+ virtual ~ProcessInfoInterface() {}
+};
+
+} // namespace android
+
+#endif // PROCESS_INFO_INTERFACE_H_
diff --git a/media/libmediaplayerservice/nuplayer/Android.mk b/media/libmediaplayerservice/nuplayer/Android.mk
index e2c72ed..6609874 100644
--- a/media/libmediaplayerservice/nuplayer/Android.mk
+++ b/media/libmediaplayerservice/nuplayer/Android.mk
@@ -4,7 +4,6 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
GenericSource.cpp \
HTTPLiveSource.cpp \
- MediaClock.cpp \
NuPlayer.cpp \
NuPlayerCCDecoder.cpp \
NuPlayerDecoder.cpp \
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index cbc5e0d..70ae85e 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -334,7 +334,7 @@ void NuPlayer::GenericSource::prepareAsync() {
mLooper->registerHandler(this);
}
- sp<AMessage> msg = new AMessage(kWhatPrepareAsync, id());
+ sp<AMessage> msg = new AMessage(kWhatPrepareAsync, this);
msg->post();
}
@@ -393,7 +393,7 @@ void NuPlayer::GenericSource::onPrepareAsync() {
status_t err = prefillCacheIfNecessary();
if (err != OK) {
if (err == -EAGAIN) {
- (new AMessage(kWhatPrepareAsync, id()))->post(200000);
+ (new AMessage(kWhatPrepareAsync, this))->post(200000);
} else {
ALOGE("Failed to prefill data cache!");
notifyPreparedAndCleanup(UNKNOWN_ERROR);
@@ -538,7 +538,7 @@ void NuPlayer::GenericSource::start() {
setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
mStarted = true;
- (new AMessage(kWhatStart, id()))->post();
+ (new AMessage(kWhatStart, this))->post();
}
void NuPlayer::GenericSource::stop() {
@@ -547,7 +547,7 @@ void NuPlayer::GenericSource::stop() {
mStarted = false;
if (mIsWidevine || mIsSecure) {
// For widevine or secure sources we need to prevent any further reads.
- sp<AMessage> msg = new AMessage(kWhatStopWidevine, id());
+ sp<AMessage> msg = new AMessage(kWhatStopWidevine, this);
sp<AMessage> response;
(void) msg->postAndAwaitResponse(&response);
}
@@ -564,7 +564,7 @@ void NuPlayer::GenericSource::resume() {
setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
mStarted = true;
- (new AMessage(kWhatResume, id()))->post();
+ (new AMessage(kWhatResume, this))->post();
}
void NuPlayer::GenericSource::disconnect() {
@@ -591,7 +591,7 @@ status_t NuPlayer::GenericSource::feedMoreTSData() {
}
void NuPlayer::GenericSource::schedulePollBuffering() {
- sp<AMessage> msg = new AMessage(kWhatPollBuffering, id());
+ sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
msg->setInt32("generation", mPollBufferingGeneration);
msg->post(1000000ll);
}
@@ -888,7 +888,7 @@ void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) {
mVideoTrack.mPackets->clear();
}
sp<AMessage> response = new AMessage;
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
response->postReply(replyID);
break;
@@ -928,7 +928,7 @@ void NuPlayer::GenericSource::fetchTextData(
const int64_t oneSecUs = 1000000ll;
delayUs -= oneSecUs;
}
- sp<AMessage> msg2 = new AMessage(sendWhat, id());
+ sp<AMessage> msg2 = new AMessage(sendWhat, this);
msg2->setInt32("generation", msgGeneration);
msg2->post(delayUs < 0 ? 0 : delayUs);
}
@@ -968,7 +968,7 @@ void NuPlayer::GenericSource::sendTextData(
}
sp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) {
- sp<AMessage> msg = new AMessage(kWhatGetFormat, id());
+ sp<AMessage> msg = new AMessage(kWhatGetFormat, this);
msg->setInt32("audio", audio);
sp<AMessage> response;
@@ -990,7 +990,7 @@ void NuPlayer::GenericSource::onGetFormatMeta(sp<AMessage> msg) const {
sp<MetaData> format = doGetFormatMeta(audio);
response->setPointer("format", format.get());
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
response->postReply(replyID);
}
@@ -1057,7 +1057,7 @@ status_t NuPlayer::GenericSource::dequeueAccessUnit(
if (mSubtitleTrack.mSource != NULL
&& !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
- sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id());
+ sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this);
msg->setInt64("timeUs", timeUs);
msg->setInt32("generation", mFetchSubtitleDataGeneration);
msg->post();
@@ -1065,7 +1065,7 @@ status_t NuPlayer::GenericSource::dequeueAccessUnit(
if (mTimedTextTrack.mSource != NULL
&& !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
- sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, id());
+ sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, this);
msg->setInt64("timeUs", timeUs);
msg->setInt32("generation", mFetchTimedTextDataGeneration);
msg->post();
@@ -1130,7 +1130,7 @@ sp<AMessage> NuPlayer::GenericSource::getTrackInfo(size_t trackIndex) const {
}
ssize_t NuPlayer::GenericSource::getSelectedTrack(media_track_type type) const {
- sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, id());
+ sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
msg->setInt32("type", type);
sp<AMessage> response;
@@ -1153,7 +1153,7 @@ void NuPlayer::GenericSource::onGetSelectedTrack(sp<AMessage> msg) const {
ssize_t index = doGetSelectedTrack(type);
response->setInt32("index", index);
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
response->postReply(replyID);
}
@@ -1186,7 +1186,7 @@ ssize_t NuPlayer::GenericSource::doGetSelectedTrack(media_track_type type) const
status_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex);
- sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
+ sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
msg->setInt32("trackIndex", trackIndex);
msg->setInt32("select", select);
msg->setInt64("timeUs", timeUs);
@@ -1211,7 +1211,7 @@ void NuPlayer::GenericSource::onSelectTrack(sp<AMessage> msg) {
status_t err = doSelectTrack(trackIndex, select, timeUs);
response->setInt32("err", err);
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
response->postReply(replyID);
}
@@ -1272,7 +1272,7 @@ status_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select,
status_t eosResult; // ignored
if (mSubtitleTrack.mSource != NULL
&& !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
- sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id());
+ sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this);
msg->setInt64("timeUs", timeUs);
msg->setInt32("generation", mFetchSubtitleDataGeneration);
msg->post();
@@ -1280,7 +1280,7 @@ status_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select,
if (mTimedTextTrack.mSource != NULL
&& !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
- sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, id());
+ sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, this);
msg->setInt64("timeUs", timeUs);
msg->setInt32("generation", mFetchTimedTextDataGeneration);
msg->post();
@@ -1294,7 +1294,7 @@ status_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select,
return OK;
}
- sp<AMessage> msg = new AMessage(kWhatChangeAVSource, id());
+ sp<AMessage> msg = new AMessage(kWhatChangeAVSource, this);
msg->setInt32("trackIndex", trackIndex);
msg->post();
return OK;
@@ -1304,7 +1304,7 @@ status_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select,
}
status_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs) {
- sp<AMessage> msg = new AMessage(kWhatSeek, id());
+ sp<AMessage> msg = new AMessage(kWhatSeek, this);
msg->setInt64("seekTimeUs", seekTimeUs);
sp<AMessage> response;
@@ -1324,7 +1324,7 @@ void NuPlayer::GenericSource::onSeek(sp<AMessage> msg) {
status_t err = doSeek(seekTimeUs);
response->setInt32("err", err);
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
response->postReply(replyID);
}
@@ -1444,7 +1444,7 @@ void NuPlayer::GenericSource::postReadBuffer(media_track_type trackType) {
if ((mPendingReadBufferTypes & (1 << trackType)) == 0) {
mPendingReadBufferTypes |= (1 << trackType);
- sp<AMessage> msg = new AMessage(kWhatReadBuffer, id());
+ sp<AMessage> msg = new AMessage(kWhatReadBuffer, this);
msg->setInt32("trackType", trackType);
msg->post();
}
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index a26ef9e..d01e83a 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -81,7 +81,7 @@ void NuPlayer::HTTPLiveSource::prepareAsync() {
mLiveLooper->registerHandler(this);
}
- sp<AMessage> notify = new AMessage(kWhatSessionNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatSessionNotify, this);
mLiveSession = new LiveSession(
notify,
@@ -153,7 +153,7 @@ status_t NuPlayer::HTTPLiveSource::selectTrack(size_t trackIndex, bool select, i
if (err == OK) {
mFetchSubtitleDataGeneration++;
if (select) {
- sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id());
+ sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this);
msg->setInt32("generation", mFetchSubtitleDataGeneration);
msg->post();
}
diff --git a/media/libmediaplayerservice/nuplayer/MediaClock.h b/media/libmediaplayerservice/nuplayer/MediaClock.h
deleted file mode 100644
index 660764f..0000000
--- a/media/libmediaplayerservice/nuplayer/MediaClock.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2015 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_CLOCK_H_
-
-#define MEDIA_CLOCK_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <utils/Mutex.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-struct AMessage;
-
-struct MediaClock : public RefBase {
- MediaClock();
-
- void setStartingTimeMedia(int64_t startingTimeMediaUs);
-
- void clearAnchor();
- // It's required to use timestamp of just rendered frame as
- // anchor time in paused state.
- void updateAnchor(
- int64_t anchorTimeMediaUs,
- int64_t anchorTimeRealUs,
- int64_t maxTimeMediaUs = INT64_MAX);
-
- void updateMaxTimeMedia(int64_t maxTimeMediaUs);
-
- void setPlaybackRate(float rate);
-
- // query media time corresponding to real time |realUs|, and save the
- // result in |outMediaUs|.
- status_t getMediaTime(int64_t realUs,
- int64_t *outMediaUs,
- bool allowPastMaxTime = false);
- // query real time corresponding to media time |targetMediaUs|.
- // The result is saved in |outRealUs|.
- status_t getRealTimeFor(int64_t targetMediaUs, int64_t *outRealUs);
-
-protected:
- virtual ~MediaClock();
-
-private:
- status_t getMediaTime_l(int64_t realUs,
- int64_t *outMediaUs,
- bool allowPastMaxTime);
-
- Mutex mLock;
-
- int64_t mAnchorTimeMediaUs;
- int64_t mAnchorTimeRealUs;
- int64_t mMaxTimeMediaUs;
- int64_t mStartingTimeMediaUs;
-
- float mPlaybackRate;
-
- DISALLOW_EVIL_CONSTRUCTORS(MediaClock);
-};
-
-} // namespace android
-
-#endif // MEDIA_CLOCK_H_
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 0d19fe9..f4d3794 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -200,9 +200,9 @@ void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
}
void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
- sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
+ sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
- sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
msg->setObject("source", new StreamingSource(notify, source));
msg->post();
@@ -230,10 +230,10 @@ void NuPlayer::setDataSourceAsync(
const char *url,
const KeyedVector<String8, String8> *headers) {
- sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
+ sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
size_t len = strlen(url);
- sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
sp<Source> source;
if (IsHTTPLiveURL(url)) {
@@ -267,9 +267,9 @@ void NuPlayer::setDataSourceAsync(
}
void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
- sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
+ sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
- sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
sp<GenericSource> source =
new GenericSource(notify, mUIDValid, mUID);
@@ -286,12 +286,12 @@ void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
}
void NuPlayer::prepareAsync() {
- (new AMessage(kWhatPrepare, id()))->post();
+ (new AMessage(kWhatPrepare, this))->post();
}
void NuPlayer::setVideoSurfaceTextureAsync(
const sp<IGraphicBufferProducer> &bufferProducer) {
- sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
+ sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, this);
if (bufferProducer == NULL) {
msg->setObject("native-window", NULL);
@@ -306,23 +306,23 @@ void NuPlayer::setVideoSurfaceTextureAsync(
}
void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
- sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
+ sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
msg->setObject("sink", sink);
msg->post();
}
void NuPlayer::start() {
- (new AMessage(kWhatStart, id()))->post();
+ (new AMessage(kWhatStart, this))->post();
}
void NuPlayer::setPlaybackRate(float rate) {
- sp<AMessage> msg = new AMessage(kWhatSetRate, id());
+ sp<AMessage> msg = new AMessage(kWhatSetRate, this);
msg->setFloat("rate", rate);
msg->post();
}
void NuPlayer::pause() {
- (new AMessage(kWhatPause, id()))->post();
+ (new AMessage(kWhatPause, this))->post();
}
void NuPlayer::resetAsync() {
@@ -336,11 +336,11 @@ void NuPlayer::resetAsync() {
mSource->disconnect();
}
- (new AMessage(kWhatReset, id()))->post();
+ (new AMessage(kWhatReset, this))->post();
}
void NuPlayer::seekToAsync(int64_t seekTimeUs, bool needNotify) {
- sp<AMessage> msg = new AMessage(kWhatSeek, id());
+ sp<AMessage> msg = new AMessage(kWhatSeek, this);
msg->setInt64("seekTimeUs", seekTimeUs);
msg->setInt32("needNotify", needNotify);
msg->post();
@@ -408,7 +408,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
case kWhatGetTrackInfo:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
Parcel* reply;
@@ -461,7 +461,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
sp<AMessage> response = new AMessage;
response->setInt32("err", err);
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
response->postReply(replyID);
break;
@@ -469,7 +469,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
case kWhatSelectTrack:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
size_t trackIndex;
@@ -1061,18 +1061,17 @@ void NuPlayer::onStart() {
flags |= Renderer::FLAG_OFFLOAD_AUDIO;
}
- sp<AMessage> notify = new AMessage(kWhatRendererNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
++mRendererGeneration;
notify->setInt32("generation", mRendererGeneration);
mRenderer = new Renderer(mAudioSink, notify, flags);
- if (mPlaybackRate != 1.0) {
- mRenderer->setPlaybackRate(mPlaybackRate);
- }
-
mRendererLooper = new ALooper;
mRendererLooper->setName("NuPlayerRenderer");
mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
mRendererLooper->registerHandler(mRenderer);
+ if (mPlaybackRate != 1.0) {
+ mRenderer->setPlaybackRate(mPlaybackRate);
+ }
sp<MetaData> meta = getFileMeta();
int32_t rate;
@@ -1178,7 +1177,7 @@ void NuPlayer::postScanSources() {
return;
}
- sp<AMessage> msg = new AMessage(kWhatScanSources, id());
+ sp<AMessage> msg = new AMessage(kWhatScanSources, this);
msg->setInt32("generation", mScanSourcesGeneration);
msg->post();
@@ -1220,7 +1219,7 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<DecoderBase> *decoder) {
AString mime;
CHECK(format->findString("mime", &mime));
- sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, id());
+ sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
if (mCCDecoder == NULL) {
mCCDecoder = new CCDecoder(ccNotify);
}
@@ -1235,7 +1234,7 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<DecoderBase> *decoder) {
}
if (audio) {
- sp<AMessage> notify = new AMessage(kWhatAudioNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
++mAudioDecoderGeneration;
notify->setInt32("generation", mAudioDecoderGeneration);
@@ -1245,7 +1244,7 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<DecoderBase> *decoder) {
*decoder = new Decoder(notify, mSource, mRenderer);
}
} else {
- sp<AMessage> notify = new AMessage(kWhatVideoNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
++mVideoDecoderGeneration;
notify->setInt32("generation", mVideoDecoderGeneration);
@@ -1436,7 +1435,7 @@ status_t NuPlayer::setVideoScalingMode(int32_t mode) {
}
status_t NuPlayer::getTrackInfo(Parcel* reply) const {
- sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, id());
+ sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
msg->setPointer("reply", reply);
sp<AMessage> response;
@@ -1445,7 +1444,7 @@ status_t NuPlayer::getTrackInfo(Parcel* reply) const {
}
status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
- sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, id());
+ sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
msg->setPointer("reply", reply);
msg->setInt32("type", type);
@@ -1458,7 +1457,7 @@ status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
}
status_t NuPlayer::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
- sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
+ sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
msg->setSize("trackIndex", trackIndex);
msg->setInt32("select", select);
msg->setInt64("timeUs", timeUs);
@@ -1501,7 +1500,7 @@ sp<MetaData> NuPlayer::getFileMeta() {
}
void NuPlayer::schedulePollDuration() {
- sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
+ sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
msg->setInt32("generation", mPollDurationGeneration);
msg->post();
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 5d98d98..8e59b75 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -480,7 +480,7 @@ bool NuPlayer::Decoder::handleAnOutputBuffer() {
}
// we do not expect CODECCONFIG or SYNCFRAME for decoder
- sp<AMessage> reply = new AMessage(kWhatRenderBuffer, id());
+ sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this);
reply->setSize("buffer-ix", bufferIx);
reply->setInt32("generation", mBufferGeneration);
@@ -537,7 +537,7 @@ void NuPlayer::Decoder::requestCodecNotification() {
return;
}
if (mCodec != NULL) {
- sp<AMessage> reply = new AMessage(kWhatCodecNotify, id());
+ sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
reply->setInt32("generation", mBufferGeneration);
mCodec->requestActivityNotification(reply);
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
index d56fc4d..a726239 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
@@ -61,7 +61,7 @@ status_t PostAndAwaitResponse(
}
void NuPlayer::DecoderBase::configure(const sp<AMessage> &format) {
- sp<AMessage> msg = new AMessage(kWhatConfigure, id());
+ sp<AMessage> msg = new AMessage(kWhatConfigure, this);
msg->setMessage("format", format);
msg->post();
}
@@ -71,13 +71,13 @@ void NuPlayer::DecoderBase::init() {
}
void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
- sp<AMessage> msg = new AMessage(kWhatSetRenderer, id());
+ sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
msg->setObject("renderer", renderer);
msg->post();
}
status_t NuPlayer::DecoderBase::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
- sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, id());
+ sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, this);
msg->setPointer("buffers", buffers);
sp<AMessage> response;
@@ -85,17 +85,17 @@ status_t NuPlayer::DecoderBase::getInputBuffers(Vector<sp<ABuffer> > *buffers) c
}
void NuPlayer::DecoderBase::signalFlush() {
- (new AMessage(kWhatFlush, id()))->post();
+ (new AMessage(kWhatFlush, this))->post();
}
void NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
- sp<AMessage> msg = new AMessage(kWhatResume, id());
+ sp<AMessage> msg = new AMessage(kWhatResume, this);
msg->setInt32("notifyComplete", notifyComplete);
msg->post();
}
void NuPlayer::DecoderBase::initiateShutdown() {
- (new AMessage(kWhatShutdown, id()))->post();
+ (new AMessage(kWhatShutdown, this))->post();
}
void NuPlayer::DecoderBase::onRequestInputBuffers() {
@@ -111,7 +111,7 @@ void NuPlayer::DecoderBase::scheduleRequestBuffers() {
return;
}
mRequestInputBuffersPending = true;
- sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, id());
+ sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
msg->post(10 * 1000ll);
}
@@ -136,7 +136,7 @@ void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
case kWhatGetInputBuffers:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
Vector<sp<ABuffer> > *dstBuffers;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
index 9f7f09a..479eba1 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
@@ -333,7 +333,7 @@ void NuPlayer::DecoderPassThrough::onInputBufferFetched(
return;
}
- sp<AMessage> reply = new AMessage(kWhatBufferConsumed, id());
+ sp<AMessage> reply = new AMessage(kWhatBufferConsumed, this);
reply->setInt32("generation", mBufferGeneration);
reply->setInt32("size", bufferSize);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index d21884b..4bccfa8 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -20,13 +20,12 @@
#include "NuPlayerRenderer.h"
-#include "MediaClock.h"
-
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/foundation/AWakeLock.h>
+#include <media/stagefright/MediaClock.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/Utils.h>
@@ -104,7 +103,7 @@ void NuPlayer::Renderer::queueBuffer(
bool audio,
const sp<ABuffer> &buffer,
const sp<AMessage> &notifyConsumed) {
- sp<AMessage> msg = new AMessage(kWhatQueueBuffer, id());
+ sp<AMessage> msg = new AMessage(kWhatQueueBuffer, this);
msg->setInt32("queueGeneration", getQueueGeneration(audio));
msg->setInt32("audio", static_cast<int32_t>(audio));
msg->setBuffer("buffer", buffer);
@@ -115,7 +114,7 @@ void NuPlayer::Renderer::queueBuffer(
void NuPlayer::Renderer::queueEOS(bool audio, status_t finalResult) {
CHECK_NE(finalResult, (status_t)OK);
- sp<AMessage> msg = new AMessage(kWhatQueueEOS, id());
+ sp<AMessage> msg = new AMessage(kWhatQueueEOS, this);
msg->setInt32("queueGeneration", getQueueGeneration(audio));
msg->setInt32("audio", static_cast<int32_t>(audio));
msg->setInt32("finalResult", finalResult);
@@ -123,7 +122,7 @@ void NuPlayer::Renderer::queueEOS(bool audio, status_t finalResult) {
}
void NuPlayer::Renderer::setPlaybackRate(float rate) {
- sp<AMessage> msg = new AMessage(kWhatSetRate, id());
+ sp<AMessage> msg = new AMessage(kWhatSetRate, this);
msg->setFloat("rate", rate);
msg->post();
}
@@ -147,7 +146,7 @@ void NuPlayer::Renderer::flush(bool audio, bool notifyComplete) {
mSyncQueues = false;
}
- sp<AMessage> msg = new AMessage(kWhatFlush, id());
+ sp<AMessage> msg = new AMessage(kWhatFlush, this);
msg->setInt32("audio", static_cast<int32_t>(audio));
msg->post();
}
@@ -156,23 +155,23 @@ void NuPlayer::Renderer::signalTimeDiscontinuity() {
}
void NuPlayer::Renderer::signalDisableOffloadAudio() {
- (new AMessage(kWhatDisableOffloadAudio, id()))->post();
+ (new AMessage(kWhatDisableOffloadAudio, this))->post();
}
void NuPlayer::Renderer::signalEnableOffloadAudio() {
- (new AMessage(kWhatEnableOffloadAudio, id()))->post();
+ (new AMessage(kWhatEnableOffloadAudio, this))->post();
}
void NuPlayer::Renderer::pause() {
- (new AMessage(kWhatPause, id()))->post();
+ (new AMessage(kWhatPause, this))->post();
}
void NuPlayer::Renderer::resume() {
- (new AMessage(kWhatResume, id()))->post();
+ (new AMessage(kWhatResume, this))->post();
}
void NuPlayer::Renderer::setVideoFrameRate(float fps) {
- sp<AMessage> msg = new AMessage(kWhatSetVideoFrameRate, id());
+ sp<AMessage> msg = new AMessage(kWhatSetVideoFrameRate, this);
msg->setFloat("frame-rate", fps);
msg->post();
}
@@ -216,7 +215,7 @@ status_t NuPlayer::Renderer::openAudioSink(
bool hasVideo,
uint32_t flags,
bool *isOffloaded) {
- sp<AMessage> msg = new AMessage(kWhatOpenAudioSink, id());
+ sp<AMessage> msg = new AMessage(kWhatOpenAudioSink, this);
msg->setMessage("format", format);
msg->setInt32("offload-only", offloadOnly);
msg->setInt32("has-video", hasVideo);
@@ -237,7 +236,7 @@ status_t NuPlayer::Renderer::openAudioSink(
}
void NuPlayer::Renderer::closeAudioSink() {
- sp<AMessage> msg = new AMessage(kWhatCloseAudioSink, id());
+ sp<AMessage> msg = new AMessage(kWhatCloseAudioSink, this);
sp<AMessage> response;
msg->postAndAwaitResponse(&response);
@@ -265,7 +264,7 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
response->setInt32("err", err);
response->setInt32("offload", offloadingAudio());
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
response->postReply(replyID);
@@ -274,7 +273,7 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
case kWhatCloseAudioSink:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
onCloseAudioSink();
@@ -447,7 +446,7 @@ void NuPlayer::Renderer::postDrainAudioQueue_l(int64_t delayUs) {
}
mDrainAudioQueuePending = true;
- sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, id());
+ sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, this);
msg->setInt32("drainGeneration", mAudioDrainGeneration);
msg->post(delayUs);
}
@@ -560,13 +559,14 @@ size_t NuPlayer::Renderer::fillAudioBuffer(void *buffer, size_t size) {
}
if (hasEOS) {
- (new AMessage(kWhatStopAudioSink, id()))->post();
+ (new AMessage(kWhatStopAudioSink, this))->post();
}
return sizeCopied;
}
bool NuPlayer::Renderer::onDrainAudioQueue() {
+#if 0
uint32_t numFramesPlayed;
if (mAudioSink->getPosition(&numFramesPlayed) != OK) {
return false;
@@ -575,7 +575,6 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {
ssize_t numFramesAvailableToWrite =
mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
-#if 0
if (numFramesAvailableToWrite == mAudioSink->frameCount()) {
ALOGI("audio sink underrun");
} else {
@@ -584,10 +583,7 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {
}
#endif
- size_t numBytesAvailableToWrite =
- numFramesAvailableToWrite * mAudioSink->frameSize();
-
- while (numBytesAvailableToWrite > 0 && !mAudioQueue.empty()) {
+ while (!mAudioQueue.empty()) {
QueueEntry *entry = &*mAudioQueue.begin();
mLastAudioBufferDrained = entry->mBufferOrdinal;
@@ -620,14 +616,16 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {
}
size_t copy = entry->mBuffer->size() - entry->mOffset;
- if (copy > numBytesAvailableToWrite) {
- copy = numBytesAvailableToWrite;
- }
- ssize_t written = mAudioSink->write(entry->mBuffer->data() + entry->mOffset, copy);
+ ssize_t written = mAudioSink->write(entry->mBuffer->data() + entry->mOffset,
+ copy, false /* blocking */);
if (written < 0) {
// An error in AudioSink write. Perhaps the AudioSink was not properly opened.
- ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy);
+ if (written == WOULD_BLOCK) {
+ ALOGW("AudioSink write would block when writing %zu bytes", copy);
+ } else {
+ ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy);
+ }
break;
}
@@ -639,7 +637,6 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {
entry = NULL;
}
- numBytesAvailableToWrite -= written;
size_t copiedFrames = written / mAudioSink->frameSize();
mNumFramesWritten += copiedFrames;
@@ -651,21 +648,23 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {
if (written != (ssize_t)copy) {
// A short count was received from AudioSink::write()
//
- // AudioSink write should block until exactly the number of bytes are delivered.
- // But it may return with a short count (without an error) when:
+ // AudioSink write is called in non-blocking mode.
+ // It may return with a short count when:
//
// 1) Size to be copied is not a multiple of the frame size. We consider this fatal.
- // 2) AudioSink is an AudioCache for data retrieval, and the AudioCache is exceeded.
+ // 2) The data to be copied exceeds the available buffer in AudioSink.
+ // 3) An error occurs and data has been partially copied to the buffer in AudioSink.
+ // 4) AudioSink is an AudioCache for data retrieval, and the AudioCache is exceeded.
// (Case 1)
// Must be a multiple of the frame size. If it is not a multiple of a frame size, it
// needs to fail, as we should not carry over fractional frames between calls.
CHECK_EQ(copy % mAudioSink->frameSize(), 0);
- // (Case 2)
+ // (Case 2, 3, 4)
// Return early to the caller.
// Beware of calling immediately again as this may busy-loop if you are not careful.
- ALOGW("AudioSink write short frame count %zd < %zu", written, copy);
+ ALOGV("AudioSink write short frame count %zd < %zu", written, copy);
break;
}
}
@@ -716,6 +715,7 @@ void NuPlayer::Renderer::onNewAudioMediaTime(int64_t mediaTimeUs) {
int64_t nowUs = ALooper::GetNowUs();
int64_t nowMediaUs = mediaTimeUs - getPendingAudioPlayoutDurationUs(nowUs);
mMediaClock->updateAnchor(nowMediaUs, nowUs, mediaTimeUs);
+ mAnchorNumFramesWritten = mNumFramesWritten;
mAnchorTimeMediaUs = mediaTimeUs;
}
@@ -733,7 +733,7 @@ void NuPlayer::Renderer::postDrainVideoQueue() {
QueueEntry &entry = *mVideoQueue.begin();
- sp<AMessage> msg = new AMessage(kWhatDrainVideoQueue, id());
+ sp<AMessage> msg = new AMessage(kWhatDrainVideoQueue, this);
msg->setInt32("drainGeneration", getDrainGeneration(false /* audio */));
if (entry.mBuffer == NULL) {
@@ -894,7 +894,7 @@ void NuPlayer::Renderer::notifyEOS(bool audio, status_t finalResult, int64_t del
}
void NuPlayer::Renderer::notifyAudioOffloadTearDown() {
- (new AMessage(kWhatAudioOffloadTearDown, id()))->post();
+ (new AMessage(kWhatAudioOffloadTearDown, this))->post();
}
void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
@@ -1322,7 +1322,7 @@ void NuPlayer::Renderer::onAudioOffloadTearDown(AudioOffloadTearDownReason reaso
void NuPlayer::Renderer::startAudioOffloadPauseTimeout() {
if (offloadingAudio()) {
mWakeLock->acquire();
- sp<AMessage> msg = new AMessage(kWhatAudioOffloadPauseTimeout, id());
+ sp<AMessage> msg = new AMessage(kWhatAudioOffloadPauseTimeout, this);
msg->setInt32("drainGeneration", mAudioOffloadPauseTimeoutGeneration);
msg->post(kOffloadPauseMaxUs);
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp
index 885ebe4..f53afbd 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp
@@ -29,9 +29,9 @@ namespace android {
NuPlayer::NuPlayerStreamListener::NuPlayerStreamListener(
const sp<IStreamSource> &source,
- ALooper::handler_id id)
+ const sp<AHandler> &targetHandler)
: mSource(source),
- mTargetID(id),
+ mTargetHandler(targetHandler),
mEOS(false),
mSendDataNotification(true) {
mSource->setListener(this);
@@ -65,8 +65,8 @@ void NuPlayer::NuPlayerStreamListener::queueBuffer(size_t index, size_t size) {
if (mSendDataNotification) {
mSendDataNotification = false;
- if (mTargetID != 0) {
- (new AMessage(kWhatMoreDataQueued, mTargetID))->post();
+ if (mTargetHandler != NULL) {
+ (new AMessage(kWhatMoreDataQueued, mTargetHandler))->post();
}
}
}
@@ -86,8 +86,8 @@ void NuPlayer::NuPlayerStreamListener::issueCommand(
if (mSendDataNotification) {
mSendDataNotification = false;
- if (mTargetID != 0) {
- (new AMessage(kWhatMoreDataQueued, mTargetID))->post();
+ if (mTargetHandler != NULL) {
+ (new AMessage(kWhatMoreDataQueued, mTargetHandler))->post();
}
}
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.h b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.h
index 1874d80..2de829b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.h
@@ -29,7 +29,7 @@ struct MemoryDealer;
struct NuPlayer::NuPlayerStreamListener : public BnStreamListener {
NuPlayerStreamListener(
const sp<IStreamSource> &source,
- ALooper::handler_id targetID);
+ const sp<AHandler> &targetHandler);
virtual void queueBuffer(size_t index, size_t size);
@@ -59,7 +59,7 @@ private:
Mutex mLock;
sp<IStreamSource> mSource;
- ALooper::handler_id mTargetID;
+ sp<AHandler> mTargetHandler;
sp<MemoryDealer> mMemoryDealer;
Vector<sp<IMemory> > mBuffers;
List<QueueEntry> mQueue;
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index 0282a9f..5210fc8 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -87,7 +87,7 @@ void NuPlayer::RTSPSource::prepareAsync() {
CHECK(mHandler == NULL);
CHECK(mSDPLoader == NULL);
- sp<AMessage> notify = new AMessage(kWhatNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatNotify, this);
CHECK_EQ(mState, (int)DISCONNECTED);
mState = CONNECTING;
@@ -116,7 +116,7 @@ void NuPlayer::RTSPSource::stop() {
if (mLooper == NULL) {
return;
}
- sp<AMessage> msg = new AMessage(kWhatDisconnect, id());
+ sp<AMessage> msg = new AMessage(kWhatDisconnect, this);
sp<AMessage> dummy;
msg->postAndAwaitResponse(&dummy);
@@ -292,7 +292,7 @@ status_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) {
}
status_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) {
- sp<AMessage> msg = new AMessage(kWhatPerformSeek, id());
+ sp<AMessage> msg = new AMessage(kWhatPerformSeek, this);
msg->setInt32("generation", ++mSeekGeneration);
msg->setInt64("timeUs", seekTimeUs);
msg->post(200000ll);
@@ -311,7 +311,7 @@ void NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) {
void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
if (msg->what() == kWhatDisconnect) {
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
mDisconnectReplyID = replyID;
@@ -600,7 +600,7 @@ void NuPlayer::RTSPSource::onSDPLoaded(const sp<AMessage> &msg) {
ALOGE("Unable to find url in SDP");
err = UNKNOWN_ERROR;
} else {
- sp<AMessage> notify = new AMessage(kWhatNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatNotify, this);
mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID);
mLooper->registerHandler(mHandler);
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h
index ac3299a..5f2cf33 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.h
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h
@@ -25,6 +25,7 @@
namespace android {
struct ALooper;
+struct AReplyToken;
struct AnotherPacketSource;
struct MyHandler;
struct SDPLoader;
@@ -96,7 +97,7 @@ private:
bool mIsSDP;
State mState;
status_t mFinalResult;
- uint32_t mDisconnectReplyID;
+ sp<AReplyToken> mDisconnectReplyID;
Mutex mBufferingLock;
bool mBuffering;
diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
index b3f224d..0246b59 100644
--- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
@@ -63,7 +63,7 @@ void NuPlayer::StreamingSource::prepareAsync() {
}
void NuPlayer::StreamingSource::start() {
- mStreamListener = new NuPlayerStreamListener(mSource, 0);
+ mStreamListener = new NuPlayerStreamListener(mSource, NULL);
uint32_t sourceFlags = mSource->flags();
@@ -163,7 +163,7 @@ status_t NuPlayer::StreamingSource::postReadBuffer() {
mBuffering = true;
}
- (new AMessage(kWhatReadBuffer, id()))->post();
+ (new AMessage(kWhatReadBuffer, this))->post();
return OK;
}
diff --git a/media/libmediaplayerservice/tests/Android.mk b/media/libmediaplayerservice/tests/Android.mk
new file mode 100644
index 0000000..7bc78ff
--- /dev/null
+++ b/media/libmediaplayerservice/tests/Android.mk
@@ -0,0 +1,24 @@
+# Build the unit tests.
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := DrmSessionManager_test
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := \
+ DrmSessionManager_test.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libmediaplayerservice \
+ libutils \
+
+LOCAL_C_INCLUDES := \
+ frameworks/av/include \
+ frameworks/av/media/libmediaplayerservice \
+
+LOCAL_32_BIT_ONLY := true
+
+include $(BUILD_NATIVE_TEST)
+
diff --git a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
new file mode 100644
index 0000000..27b482b
--- /dev/null
+++ b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2015 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 "DrmSessionManager_test"
+#include <utils/Log.h>
+
+#include <gtest/gtest.h>
+
+#include "Drm.h"
+#include "DrmSessionClientInterface.h"
+#include "DrmSessionManager.h"
+#include "ProcessInfoInterface.h"
+#include <media/stagefright/foundation/ADebug.h>
+
+namespace android {
+
+struct FakeProcessInfo : public ProcessInfoInterface {
+ FakeProcessInfo() {}
+ virtual ~FakeProcessInfo() {}
+
+ virtual bool getPriority(int pid, int* priority) {
+ // For testing, use pid as priority.
+ // Lower the value higher the priority.
+ *priority = pid;
+ return true;
+ }
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(FakeProcessInfo);
+};
+
+struct FakeDrm : public DrmSessionClientInterface {
+ FakeDrm() {}
+ virtual ~FakeDrm() {}
+
+ virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
+ mReclaimedSessions.push_back(sessionId);
+ return true;
+ }
+
+ const Vector<Vector<uint8_t> >& reclaimedSessions() const {
+ return mReclaimedSessions;
+ }
+
+private:
+ Vector<Vector<uint8_t> > mReclaimedSessions;
+
+ DISALLOW_EVIL_CONSTRUCTORS(FakeDrm);
+};
+
+static const int kTestPid1 = 30;
+static const int kTestPid2 = 20;
+static const uint8_t kTestSessionId1[] = {1, 2, 3};
+static const uint8_t kTestSessionId2[] = {4, 5, 6, 7, 8};
+static const uint8_t kTestSessionId3[] = {9, 0};
+
+class DrmSessionManagerTest : public ::testing::Test {
+public:
+ DrmSessionManagerTest()
+ : mDrmSessionManager(new DrmSessionManager(new FakeProcessInfo())),
+ mTestDrm1(new FakeDrm()),
+ mTestDrm2(new FakeDrm()) {
+ GetSessionId(kTestSessionId1, ARRAY_SIZE(kTestSessionId1), &mSessionId1);
+ GetSessionId(kTestSessionId2, ARRAY_SIZE(kTestSessionId2), &mSessionId2);
+ GetSessionId(kTestSessionId3, ARRAY_SIZE(kTestSessionId3), &mSessionId3);
+ }
+
+protected:
+ static void GetSessionId(const uint8_t* ids, size_t num, Vector<uint8_t>* sessionId) {
+ for (size_t i = 0; i < num; ++i) {
+ sessionId->push_back(ids[i]);
+ }
+ }
+
+ static void ExpectEqSessionInfo(const SessionInfo& info, sp<DrmSessionClientInterface> drm,
+ const Vector<uint8_t>& sessionId, int64_t timeStamp) {
+ EXPECT_EQ(drm, info.drm);
+ EXPECT_TRUE(isEqualSessionId(sessionId, info.sessionId));
+ EXPECT_EQ(timeStamp, info.timeStamp);
+ }
+
+ void addSession() {
+ mDrmSessionManager->addSession(kTestPid1, mTestDrm1, mSessionId1);
+ mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mSessionId2);
+ mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mSessionId3);
+ const PidSessionInfosMap& map = sessionMap();
+ EXPECT_EQ(2, map.size());
+ ssize_t index1 = map.indexOfKey(kTestPid1);
+ ASSERT_GE(index1, 0);
+ const SessionInfos& infos1 = map[index1];
+ EXPECT_EQ(1, infos1.size());
+ ExpectEqSessionInfo(infos1[0], mTestDrm1, mSessionId1, 0);
+
+ ssize_t index2 = map.indexOfKey(kTestPid2);
+ ASSERT_GE(index2, 0);
+ const SessionInfos& infos2 = map[index2];
+ EXPECT_EQ(2, infos2.size());
+ ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId2, 1);
+ ExpectEqSessionInfo(infos2[1], mTestDrm2, mSessionId3, 2);
+ }
+
+ const PidSessionInfosMap& sessionMap() {
+ return mDrmSessionManager->mSessionMap;
+ }
+
+ void testGetLowestPriority() {
+ int pid;
+ int priority;
+ EXPECT_FALSE(mDrmSessionManager->getLowestPriority_l(&pid, &priority));
+
+ addSession();
+ EXPECT_TRUE(mDrmSessionManager->getLowestPriority_l(&pid, &priority));
+
+ EXPECT_EQ(kTestPid1, pid);
+ FakeProcessInfo processInfo;
+ int priority1;
+ processInfo.getPriority(kTestPid1, &priority1);
+ EXPECT_EQ(priority1, priority);
+ }
+
+ void testGetLeastUsedSession() {
+ sp<DrmSessionClientInterface> drm;
+ Vector<uint8_t> sessionId;
+ EXPECT_FALSE(mDrmSessionManager->getLeastUsedSession_l(kTestPid1, &drm, &sessionId));
+
+ addSession();
+
+ EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid1, &drm, &sessionId));
+ EXPECT_EQ(mTestDrm1, drm);
+ EXPECT_TRUE(isEqualSessionId(mSessionId1, sessionId));
+
+ EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid2, &drm, &sessionId));
+ EXPECT_EQ(mTestDrm2, drm);
+ EXPECT_TRUE(isEqualSessionId(mSessionId2, sessionId));
+
+ // mSessionId2 is no longer the least used session.
+ mDrmSessionManager->useSession(mSessionId2);
+ EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid2, &drm, &sessionId));
+ EXPECT_EQ(mTestDrm2, drm);
+ EXPECT_TRUE(isEqualSessionId(mSessionId3, sessionId));
+ }
+
+ sp<DrmSessionManager> mDrmSessionManager;
+ sp<FakeDrm> mTestDrm1;
+ sp<FakeDrm> mTestDrm2;
+ Vector<uint8_t> mSessionId1;
+ Vector<uint8_t> mSessionId2;
+ Vector<uint8_t> mSessionId3;
+};
+
+TEST_F(DrmSessionManagerTest, addSession) {
+ addSession();
+}
+
+TEST_F(DrmSessionManagerTest, useSession) {
+ addSession();
+
+ mDrmSessionManager->useSession(mSessionId1);
+ mDrmSessionManager->useSession(mSessionId3);
+
+ const PidSessionInfosMap& map = sessionMap();
+ const SessionInfos& infos1 = map.valueFor(kTestPid1);
+ const SessionInfos& infos2 = map.valueFor(kTestPid2);
+ ExpectEqSessionInfo(infos1[0], mTestDrm1, mSessionId1, 3);
+ ExpectEqSessionInfo(infos2[1], mTestDrm2, mSessionId3, 4);
+}
+
+TEST_F(DrmSessionManagerTest, removeSession) {
+ addSession();
+
+ mDrmSessionManager->removeSession(mSessionId2);
+
+ const PidSessionInfosMap& map = sessionMap();
+ EXPECT_EQ(2, map.size());
+ const SessionInfos& infos1 = map.valueFor(kTestPid1);
+ const SessionInfos& infos2 = map.valueFor(kTestPid2);
+ EXPECT_EQ(1, infos1.size());
+ EXPECT_EQ(1, infos2.size());
+ // mSessionId2 has been removed.
+ ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId3, 2);
+}
+
+TEST_F(DrmSessionManagerTest, removeDrm) {
+ addSession();
+
+ sp<FakeDrm> drm = new FakeDrm;
+ const uint8_t ids[] = {123};
+ Vector<uint8_t> sessionId;
+ GetSessionId(ids, ARRAY_SIZE(ids), &sessionId);
+ mDrmSessionManager->addSession(kTestPid2, drm, sessionId);
+
+ mDrmSessionManager->removeDrm(mTestDrm2);
+
+ const PidSessionInfosMap& map = sessionMap();
+ const SessionInfos& infos2 = map.valueFor(kTestPid2);
+ EXPECT_EQ(1, infos2.size());
+ // mTestDrm2 has been removed.
+ ExpectEqSessionInfo(infos2[0], drm, sessionId, 3);
+}
+
+TEST_F(DrmSessionManagerTest, reclaimSession) {
+ EXPECT_FALSE(mDrmSessionManager->reclaimSession(kTestPid1));
+ addSession();
+
+ // calling pid priority is too low
+ EXPECT_FALSE(mDrmSessionManager->reclaimSession(50));
+
+ EXPECT_TRUE(mDrmSessionManager->reclaimSession(10));
+ EXPECT_EQ(1, mTestDrm1->reclaimedSessions().size());
+ EXPECT_TRUE(isEqualSessionId(mSessionId1, mTestDrm1->reclaimedSessions()[0]));
+
+ mDrmSessionManager->removeSession(mSessionId1);
+
+ // add a session from a higher priority process.
+ sp<FakeDrm> drm = new FakeDrm;
+ const uint8_t ids[] = {1, 3, 5};
+ Vector<uint8_t> sessionId;
+ GetSessionId(ids, ARRAY_SIZE(ids), &sessionId);
+ mDrmSessionManager->addSession(15, drm, sessionId);
+
+ EXPECT_TRUE(mDrmSessionManager->reclaimSession(18));
+ EXPECT_EQ(1, mTestDrm2->reclaimedSessions().size());
+ // mSessionId2 is reclaimed.
+ EXPECT_TRUE(isEqualSessionId(mSessionId2, mTestDrm2->reclaimedSessions()[0]));
+}
+
+TEST_F(DrmSessionManagerTest, getLowestPriority) {
+ testGetLowestPriority();
+}
+
+TEST_F(DrmSessionManagerTest, getLeastUsedSession_l) {
+ testGetLeastUsedSession();
+}
+
+} // namespace android
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 7d313e0..c75d4df 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -452,61 +452,61 @@ void ACodec::setNotificationMessage(const sp<AMessage> &msg) {
void ACodec::initiateSetup(const sp<AMessage> &msg) {
msg->setWhat(kWhatSetup);
- msg->setTarget(id());
+ msg->setTarget(this);
msg->post();
}
void ACodec::signalSetParameters(const sp<AMessage> &params) {
- sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
+ sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
msg->setMessage("params", params);
msg->post();
}
void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
msg->setWhat(kWhatAllocateComponent);
- msg->setTarget(id());
+ msg->setTarget(this);
msg->post();
}
void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
msg->setWhat(kWhatConfigureComponent);
- msg->setTarget(id());
+ msg->setTarget(this);
msg->post();
}
void ACodec::initiateCreateInputSurface() {
- (new AMessage(kWhatCreateInputSurface, id()))->post();
+ (new AMessage(kWhatCreateInputSurface, this))->post();
}
void ACodec::signalEndOfInputStream() {
- (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
+ (new AMessage(kWhatSignalEndOfInputStream, this))->post();
}
void ACodec::initiateStart() {
- (new AMessage(kWhatStart, id()))->post();
+ (new AMessage(kWhatStart, this))->post();
}
void ACodec::signalFlush() {
ALOGV("[%s] signalFlush", mComponentName.c_str());
- (new AMessage(kWhatFlush, id()))->post();
+ (new AMessage(kWhatFlush, this))->post();
}
void ACodec::signalResume() {
- (new AMessage(kWhatResume, id()))->post();
+ (new AMessage(kWhatResume, this))->post();
}
void ACodec::initiateShutdown(bool keepComponentAllocated) {
- sp<AMessage> msg = new AMessage(kWhatShutdown, id());
+ sp<AMessage> msg = new AMessage(kWhatShutdown, this);
msg->setInt32("keepComponentAllocated", keepComponentAllocated);
msg->post();
if (!keepComponentAllocated) {
// ensure shutdown completes in 3 seconds
- (new AMessage(kWhatReleaseCodecInstance, id()))->post(3000000);
+ (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
}
}
void ACodec::signalRequestIDRFrame() {
- (new AMessage(kWhatRequestIDRFrame, id()))->post();
+ (new AMessage(kWhatRequestIDRFrame, this))->post();
}
// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
@@ -517,7 +517,7 @@ void ACodec::signalRequestIDRFrame() {
void ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
mMetaDataBuffersToSubmit > 0) {
- (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
+ (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, this))->post();
}
}
@@ -4298,7 +4298,7 @@ void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
info->mData->meta()->clear();
notify->setBuffer("buffer", info->mData);
- sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
+ sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
reply->setInt32("buffer-id", info->mBufferID);
notify->setMessage("reply", reply);
@@ -4558,7 +4558,7 @@ bool ACodec::BaseState::onOMXFillBufferDone(
}
sp<AMessage> reply =
- new AMessage(kWhatOutputBufferDrained, mCodec->id());
+ new AMessage(kWhatOutputBufferDrained, mCodec);
if (!mCodec->mSentFormat && rangeLength > 0) {
mCodec->sendFormatChange(reply);
@@ -4834,7 +4834,7 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
sp<IOMX> omx = client.interface();
- sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
+ sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
mDeathNotifier = new DeathNotifier(notify);
if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
@@ -4909,7 +4909,7 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
return false;
}
- notify = new AMessage(kWhatOMXMessage, mCodec->id());
+ notify = new AMessage(kWhatOMXMessage, mCodec);
observer->setNotificationMessage(notify);
mCodec->mComponentName = componentName;
@@ -6000,7 +6000,7 @@ bool ACodec::FlushingState::onOMXEvent(
case OMX_EventPortSettingsChanged:
{
- sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
+ sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
msg->setInt32("type", omx_message::EVENT);
msg->setInt32("node", mCodec->mNode);
msg->setInt32("event", event);
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 6d9bbae..38f2e34 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -31,6 +31,7 @@ LOCAL_SRC_FILES:= \
MediaAdapter.cpp \
MediaBuffer.cpp \
MediaBufferGroup.cpp \
+ MediaClock.cpp \
MediaCodec.cpp \
MediaCodecList.cpp \
MediaCodecSource.cpp \
diff --git a/media/libstagefright/HTTPBase.cpp b/media/libstagefright/HTTPBase.cpp
index 0c2ff15..77a652a 100644
--- a/media/libstagefright/HTTPBase.cpp
+++ b/media/libstagefright/HTTPBase.cpp
@@ -75,7 +75,11 @@ void HTTPBase::addBandwidthMeasurement(
bool HTTPBase::estimateBandwidth(int32_t *bandwidth_bps) {
Mutex::Autolock autoLock(mLock);
- if (mNumBandwidthHistoryItems < 2) {
+ // Do not do bandwidth estimation if we don't have enough samples, or
+ // total bytes download are too small (<64K).
+ // Bandwidth estimation from these samples can often shoot up and cause
+ // unwanted bw adaption behaviors.
+ if (mNumBandwidthHistoryItems < 2 || mTotalTransferBytes < 65536) {
return false;
}
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index 4359fb9..ef07aa0 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -135,7 +135,7 @@ void MPEG2TSWriter::SourceInfo::start(const sp<AMessage> &notify) {
mNotify = notify;
- (new AMessage(kWhatStart, id()))->post();
+ (new AMessage(kWhatStart, this))->post();
}
void MPEG2TSWriter::SourceInfo::stop() {
@@ -361,7 +361,7 @@ bool MPEG2TSWriter::SourceInfo::flushAACFrames() {
}
void MPEG2TSWriter::SourceInfo::readMore() {
- (new AMessage(kWhatRead, id()))->post();
+ (new AMessage(kWhatRead, this))->post();
}
void MPEG2TSWriter::SourceInfo::onMessageReceived(const sp<AMessage> &msg) {
@@ -552,7 +552,7 @@ status_t MPEG2TSWriter::start(MetaData * /* param */) {
for (size_t i = 0; i < mSources.size(); ++i) {
sp<AMessage> notify =
- new AMessage(kWhatSourceNotify, mReflector->id());
+ new AMessage(kWhatSourceNotify, mReflector);
notify->setInt32("source-index", i);
diff --git a/media/libmediaplayerservice/nuplayer/MediaClock.cpp b/media/libstagefright/MediaClock.cpp
index 9152da1..38db5e4 100644
--- a/media/libmediaplayerservice/nuplayer/MediaClock.cpp
+++ b/media/libstagefright/MediaClock.cpp
@@ -18,7 +18,7 @@
#define LOG_TAG "MediaClock"
#include <utils/Log.h>
-#include "MediaClock.h"
+#include <media/stagefright/MediaClock.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 50e6bd0..0597f1d 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -174,7 +174,7 @@ status_t MediaCodec::PostAndAwaitResponse(
}
// static
-void MediaCodec::PostReplyWithError(int32_t replyID, int32_t err) {
+void MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
sp<AMessage> response = new AMessage;
response->setInt32("err", err);
response->postReply(replyID);
@@ -237,9 +237,9 @@ status_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
mLooper->registerHandler(this);
- mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id()));
+ mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this));
- sp<AMessage> msg = new AMessage(kWhatInit, id());
+ sp<AMessage> msg = new AMessage(kWhatInit, this);
msg->setString("name", name);
msg->setInt32("nameIsType", nameIsType);
@@ -252,7 +252,7 @@ status_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
}
status_t MediaCodec::setCallback(const sp<AMessage> &callback) {
- sp<AMessage> msg = new AMessage(kWhatSetCallback, id());
+ sp<AMessage> msg = new AMessage(kWhatSetCallback, this);
msg->setMessage("callback", callback);
sp<AMessage> response;
@@ -264,7 +264,7 @@ status_t MediaCodec::configure(
const sp<Surface> &nativeWindow,
const sp<ICrypto> &crypto,
uint32_t flags) {
- sp<AMessage> msg = new AMessage(kWhatConfigure, id());
+ sp<AMessage> msg = new AMessage(kWhatConfigure, this);
msg->setMessage("format", format);
msg->setInt32("flags", flags);
@@ -298,7 +298,7 @@ status_t MediaCodec::configure(
status_t MediaCodec::createInputSurface(
sp<IGraphicBufferProducer>* bufferProducer) {
- sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, id());
+ sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this);
sp<AMessage> response;
status_t err = PostAndAwaitResponse(msg, &response);
@@ -317,21 +317,21 @@ status_t MediaCodec::createInputSurface(
}
status_t MediaCodec::start() {
- sp<AMessage> msg = new AMessage(kWhatStart, id());
+ sp<AMessage> msg = new AMessage(kWhatStart, this);
sp<AMessage> response;
return PostAndAwaitResponse(msg, &response);
}
status_t MediaCodec::stop() {
- sp<AMessage> msg = new AMessage(kWhatStop, id());
+ sp<AMessage> msg = new AMessage(kWhatStop, this);
sp<AMessage> response;
return PostAndAwaitResponse(msg, &response);
}
status_t MediaCodec::release() {
- sp<AMessage> msg = new AMessage(kWhatRelease, id());
+ sp<AMessage> msg = new AMessage(kWhatRelease, this);
sp<AMessage> response;
return PostAndAwaitResponse(msg, &response);
@@ -383,7 +383,7 @@ status_t MediaCodec::queueInputBuffer(
errorDetailMsg->clear();
}
- sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
+ sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
msg->setSize("index", index);
msg->setSize("offset", offset);
msg->setSize("size", size);
@@ -410,7 +410,7 @@ status_t MediaCodec::queueSecureInputBuffer(
errorDetailMsg->clear();
}
- sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
+ sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
msg->setSize("index", index);
msg->setSize("offset", offset);
msg->setPointer("subSamples", (void *)subSamples);
@@ -429,7 +429,7 @@ status_t MediaCodec::queueSecureInputBuffer(
}
status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
- sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id());
+ sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this);
msg->setInt64("timeoutUs", timeoutUs);
sp<AMessage> response;
@@ -450,7 +450,7 @@ status_t MediaCodec::dequeueOutputBuffer(
int64_t *presentationTimeUs,
uint32_t *flags,
int64_t timeoutUs) {
- sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id());
+ sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this);
msg->setInt64("timeoutUs", timeoutUs);
sp<AMessage> response;
@@ -469,7 +469,7 @@ status_t MediaCodec::dequeueOutputBuffer(
}
status_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
- sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
+ sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
msg->setSize("index", index);
msg->setInt32("render", true);
@@ -478,7 +478,7 @@ status_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
}
status_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
- sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
+ sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
msg->setSize("index", index);
msg->setInt32("render", true);
msg->setInt64("timestampNs", timestampNs);
@@ -488,7 +488,7 @@ status_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestam
}
status_t MediaCodec::releaseOutputBuffer(size_t index) {
- sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
+ sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
msg->setSize("index", index);
sp<AMessage> response;
@@ -496,14 +496,14 @@ status_t MediaCodec::releaseOutputBuffer(size_t index) {
}
status_t MediaCodec::signalEndOfInputStream() {
- sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, id());
+ sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this);
sp<AMessage> response;
return PostAndAwaitResponse(msg, &response);
}
status_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
- sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id());
+ sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this);
sp<AMessage> response;
status_t err;
@@ -517,7 +517,7 @@ status_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
}
status_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
- sp<AMessage> msg = new AMessage(kWhatGetInputFormat, id());
+ sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this);
sp<AMessage> response;
status_t err;
@@ -531,7 +531,7 @@ status_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
}
status_t MediaCodec::getName(AString *name) const {
- sp<AMessage> msg = new AMessage(kWhatGetName, id());
+ sp<AMessage> msg = new AMessage(kWhatGetName, this);
sp<AMessage> response;
status_t err;
@@ -545,7 +545,7 @@ status_t MediaCodec::getName(AString *name) const {
}
status_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
- sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
+ sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
msg->setInt32("portIndex", kPortIndexInput);
msg->setPointer("buffers", buffers);
@@ -554,7 +554,7 @@ status_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
}
status_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
- sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
+ sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
msg->setInt32("portIndex", kPortIndexOutput);
msg->setPointer("buffers", buffers);
@@ -612,20 +612,20 @@ status_t MediaCodec::getBufferAndFormat(
}
status_t MediaCodec::flush() {
- sp<AMessage> msg = new AMessage(kWhatFlush, id());
+ sp<AMessage> msg = new AMessage(kWhatFlush, this);
sp<AMessage> response;
return PostAndAwaitResponse(msg, &response);
}
status_t MediaCodec::requestIDRFrame() {
- (new AMessage(kWhatRequestIDRFrame, id()))->post();
+ (new AMessage(kWhatRequestIDRFrame, this))->post();
return OK;
}
void MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
- sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, id());
+ sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this);
msg->setMessage("notify", notify);
msg->post();
}
@@ -650,7 +650,7 @@ void MediaCodec::cancelPendingDequeueOperations() {
}
}
-bool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) {
+bool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
if (!isExecuting() || (mFlags & kFlagIsAsync)
|| (newRequest && (mFlags & kFlagDequeueInputPending))) {
PostReplyWithError(replyID, INVALID_OPERATION);
@@ -674,7 +674,7 @@ bool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) {
return true;
}
-bool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) {
+bool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
sp<AMessage> response = new AMessage;
if (!isExecuting() || (mFlags & kFlagIsAsync)
@@ -1198,7 +1198,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatInit:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if (mState != UNINITIALIZED) {
@@ -1234,7 +1234,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatSetCallback:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if (mState == UNINITIALIZED
@@ -1266,7 +1266,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatConfigure:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if (mState != INITIALIZED) {
@@ -1323,7 +1323,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatCreateInputSurface:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
// Must be configured, but can't have been started yet.
@@ -1339,7 +1339,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatStart:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if (mState == FLUSHED) {
@@ -1365,7 +1365,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
State targetState =
(msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
@@ -1413,7 +1413,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatDequeueInputBuffer:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if (mFlags & kFlagIsAsync) {
@@ -1445,7 +1445,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
if (timeoutUs > 0ll) {
sp<AMessage> timeoutMsg =
- new AMessage(kWhatDequeueInputTimedOut, id());
+ new AMessage(kWhatDequeueInputTimedOut, this);
timeoutMsg->setInt32(
"generation", ++mDequeueInputTimeoutGeneration);
timeoutMsg->post(timeoutUs);
@@ -1474,7 +1474,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatQueueInputBuffer:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if (!isExecuting()) {
@@ -1493,7 +1493,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatDequeueOutputBuffer:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if (mFlags & kFlagIsAsync) {
@@ -1519,7 +1519,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
if (timeoutUs > 0ll) {
sp<AMessage> timeoutMsg =
- new AMessage(kWhatDequeueOutputTimedOut, id());
+ new AMessage(kWhatDequeueOutputTimedOut, this);
timeoutMsg->setInt32(
"generation", ++mDequeueOutputTimeoutGeneration);
timeoutMsg->post(timeoutUs);
@@ -1548,7 +1548,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatReleaseOutputBuffer:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if (!isExecuting()) {
@@ -1567,7 +1567,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatSignalEndOfInputStream:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if (!isExecuting()) {
@@ -1585,7 +1585,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatGetBuffers:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if (!isExecuting() || (mFlags & kFlagIsAsync)) {
@@ -1619,7 +1619,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatFlush:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if (!isExecuting()) {
@@ -1645,7 +1645,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
sp<AMessage> format =
(msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if ((mState != CONFIGURED && mState != STARTING &&
@@ -1682,7 +1682,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatGetName:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if (mComponentName.empty()) {
@@ -1698,7 +1698,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
case kWhatSetParameters:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
sp<AMessage> params;
@@ -1752,7 +1752,7 @@ status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
AString errorDetailMsg;
- sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
+ sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
msg->setSize("index", bufferIndex);
msg->setSize("offset", 0);
msg->setSize("size", csd->size());
@@ -2207,7 +2207,7 @@ void MediaCodec::postActivityNotificationIfPossible() {
}
status_t MediaCodec::setParameters(const sp<AMessage> &params) {
- sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
+ sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
msg->setMessage("params", params);
sp<AMessage> response;
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index c26e909..b6fa810 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -121,7 +121,7 @@ status_t MediaCodecSource::Puller::start(const sp<MetaData> &meta,
mLooper->registerHandler(this);
mNotify = notify;
- sp<AMessage> msg = new AMessage(kWhatStart, id());
+ sp<AMessage> msg = new AMessage(kWhatStart, this);
msg->setObject("meta", meta);
return postSynchronouslyAndReturnError(msg);
}
@@ -137,19 +137,19 @@ void MediaCodecSource::Puller::stop() {
mSource->stop();
ALOGV("source (%s) stopped", mIsAudio ? "audio" : "video");
- (new AMessage(kWhatStop, id()))->post();
+ (new AMessage(kWhatStop, this))->post();
}
void MediaCodecSource::Puller::pause() {
- (new AMessage(kWhatPause, id()))->post();
+ (new AMessage(kWhatPause, this))->post();
}
void MediaCodecSource::Puller::resume() {
- (new AMessage(kWhatResume, id()))->post();
+ (new AMessage(kWhatResume, this))->post();
}
void MediaCodecSource::Puller::schedulePull() {
- sp<AMessage> msg = new AMessage(kWhatPull, id());
+ sp<AMessage> msg = new AMessage(kWhatPull, this);
msg->setInt32("generation", mPullGeneration);
msg->post();
}
@@ -182,7 +182,7 @@ void MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) {
sp<AMessage> response = new AMessage;
response->setInt32("err", err);
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
response->postReply(replyID);
break;
@@ -269,13 +269,13 @@ sp<MediaCodecSource> MediaCodecSource::Create(
}
status_t MediaCodecSource::start(MetaData* params) {
- sp<AMessage> msg = new AMessage(kWhatStart, mReflector->id());
+ sp<AMessage> msg = new AMessage(kWhatStart, mReflector);
msg->setObject("meta", params);
return postSynchronouslyAndReturnError(msg);
}
status_t MediaCodecSource::stop() {
- sp<AMessage> msg = new AMessage(kWhatStop, mReflector->id());
+ sp<AMessage> msg = new AMessage(kWhatStop, mReflector);
status_t err = postSynchronouslyAndReturnError(msg);
// mPuller->stop() needs to be done outside MediaCodecSource's looper,
@@ -294,7 +294,7 @@ status_t MediaCodecSource::stop() {
}
status_t MediaCodecSource::pause() {
- (new AMessage(kWhatPause, mReflector->id()))->post();
+ (new AMessage(kWhatPause, mReflector))->post();
return OK;
}
@@ -422,8 +422,7 @@ status_t MediaCodecSource::initEncoder() {
}
}
- mEncoderActivityNotify = new AMessage(
- kWhatEncoderActivity, mReflector->id());
+ mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, mReflector);
mEncoder->setCallback(mEncoderActivityNotify);
err = mEncoder->start();
@@ -492,7 +491,7 @@ void MediaCodecSource::signalEOS(status_t err) {
if (mStopping && mEncoderReachedEOS) {
ALOGI("encoder (%s) stopped", mIsVideo ? "video" : "audio");
// posting reply to everyone that's waiting
- List<uint32_t>::iterator it;
+ List<sp<AReplyToken>>::iterator it;
for (it = mStopReplyIDQueue.begin();
it != mStopReplyIDQueue.end(); it++) {
(new AMessage)->postReply(*it);
@@ -620,8 +619,7 @@ status_t MediaCodecSource::onStart(MetaData *params) {
resume(startTimeUs);
} else {
CHECK(mPuller != NULL);
- sp<AMessage> notify = new AMessage(
- kWhatPullerNotify, mReflector->id());
+ sp<AMessage> notify = new AMessage(kWhatPullerNotify, mReflector);
err = mPuller->start(params, notify);
if (err != OK) {
return err;
@@ -768,7 +766,7 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {
}
case kWhatStart:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
sp<RefBase> obj;
@@ -784,7 +782,7 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {
{
ALOGI("encoder (%s) stopping", mIsVideo ? "video" : "audio");
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
if (mEncoderReachedEOS) {
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 7d7d631..8d70e50 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -226,7 +226,7 @@ NuCachedSource2::NuCachedSource2(
mLooper->start(false /* runOnCallingThread */, true /* canCallJava */);
Mutex::Autolock autoLock(mLock);
- (new AMessage(kWhatFetchMore, mReflector->id()))->post();
+ (new AMessage(kWhatFetchMore, mReflector))->post();
}
NuCachedSource2::~NuCachedSource2() {
@@ -433,7 +433,7 @@ void NuCachedSource2::onFetch() {
delayUs = 100000ll;
}
- (new AMessage(kWhatFetchMore, mReflector->id()))->post(delayUs);
+ (new AMessage(kWhatFetchMore, mReflector))->post(delayUs);
}
void NuCachedSource2::onRead(const sp<AMessage> &msg) {
@@ -522,7 +522,7 @@ ssize_t NuCachedSource2::readAt(off64_t offset, void *data, size_t size) {
return size;
}
- sp<AMessage> msg = new AMessage(kWhatRead, mReflector->id());
+ sp<AMessage> msg = new AMessage(kWhatRead, mReflector);
msg->setInt64("offset", offset);
msg->setPointer("data", data);
msg->setSize("size", size);
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 495bad0..10937ec 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -623,7 +623,7 @@ void SoftAAC2::onQueueFilled(OMX_U32 /* portIndex */) {
} else {
int64_t currentTime = mBufferTimestamps.top();
currentTime += mStreamInfo->aacSamplesPerFrame *
- 1000000ll / mStreamInfo->sampleRate;
+ 1000000ll / mStreamInfo->aacSampleRate;
mBufferTimestamps.add(currentTime);
}
} else {
@@ -874,7 +874,7 @@ void SoftAAC2::onQueueFilled(OMX_U32 /* portIndex */) {
// adjust/interpolate next time stamp
*currentBufLeft -= decodedSize;
*nextTimeStamp += mStreamInfo->aacSamplesPerFrame *
- 1000000ll / mStreamInfo->sampleRate;
+ 1000000ll / mStreamInfo->aacSampleRate;
ALOGV("adjusted nextTimeStamp/size to %lld/%d",
(long long) *nextTimeStamp, *currentBufLeft);
} else {
@@ -975,6 +975,7 @@ void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) {
mBufferSizes.clear();
mDecodedSizes.clear();
mLastInHeader = NULL;
+ mEndOfInput = false;
} else {
int avail;
while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) {
@@ -989,6 +990,7 @@ void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) {
mOutputBufferCount++;
}
mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos;
+ mEndOfOutput = false;
}
}
diff --git a/media/libstagefright/filters/MediaFilter.cpp b/media/libstagefright/filters/MediaFilter.cpp
index c5289b6..d2f662d 100644
--- a/media/libstagefright/filters/MediaFilter.cpp
+++ b/media/libstagefright/filters/MediaFilter.cpp
@@ -60,36 +60,36 @@ void MediaFilter::setNotificationMessage(const sp<AMessage> &msg) {
void MediaFilter::initiateAllocateComponent(const sp<AMessage> &msg) {
msg->setWhat(kWhatAllocateComponent);
- msg->setTarget(id());
+ msg->setTarget(this);
msg->post();
}
void MediaFilter::initiateConfigureComponent(const sp<AMessage> &msg) {
msg->setWhat(kWhatConfigureComponent);
- msg->setTarget(id());
+ msg->setTarget(this);
msg->post();
}
void MediaFilter::initiateCreateInputSurface() {
- (new AMessage(kWhatCreateInputSurface, id()))->post();
+ (new AMessage(kWhatCreateInputSurface, this))->post();
}
void MediaFilter::initiateStart() {
- (new AMessage(kWhatStart, id()))->post();
+ (new AMessage(kWhatStart, this))->post();
}
void MediaFilter::initiateShutdown(bool keepComponentAllocated) {
- sp<AMessage> msg = new AMessage(kWhatShutdown, id());
+ sp<AMessage> msg = new AMessage(kWhatShutdown, this);
msg->setInt32("keepComponentAllocated", keepComponentAllocated);
msg->post();
}
void MediaFilter::signalFlush() {
- (new AMessage(kWhatFlush, id()))->post();
+ (new AMessage(kWhatFlush, this))->post();
}
void MediaFilter::signalResume() {
- (new AMessage(kWhatResume, id()))->post();
+ (new AMessage(kWhatResume, this))->post();
}
// nothing to do
@@ -98,13 +98,13 @@ void MediaFilter::signalRequestIDRFrame() {
}
void MediaFilter::signalSetParameters(const sp<AMessage> &params) {
- sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
+ sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
msg->setMessage("params", params);
msg->post();
}
void MediaFilter::signalEndOfInputStream() {
- (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
+ (new AMessage(kWhatSignalEndOfInputStream, this))->post();
}
void MediaFilter::onMessageReceived(const sp<AMessage> &msg) {
@@ -208,7 +208,7 @@ sp<ABuffer> MediaFilter::PortDescription::bufferAt(size_t index) const {
//////////////////// HELPER FUNCTIONS //////////////////////////////////////////
void MediaFilter::signalProcessBuffers() {
- (new AMessage(kWhatProcessBuffers, id()))->post();
+ (new AMessage(kWhatProcessBuffers, this))->post();
}
void MediaFilter::signalError(status_t error) {
@@ -309,7 +309,7 @@ void MediaFilter::postFillThisBuffer(BufferInfo *info) {
info->mData->meta()->clear();
notify->setBuffer("buffer", info->mData);
- sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id());
+ sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, this);
reply->setInt32("buffer-id", info->mBufferID);
notify->setMessage("reply", reply);
@@ -329,7 +329,7 @@ void MediaFilter::postDrainThisBuffer(BufferInfo *info) {
notify->setInt32("flags", info->mOutputFlags);
notify->setBuffer("buffer", info->mData);
- sp<AMessage> reply = new AMessage(kWhatOutputBufferDrained, id());
+ sp<AMessage> reply = new AMessage(kWhatOutputBufferDrained, this);
reply->setInt32("buffer-id", info->mBufferID);
notify->setMessage("reply", reply);
@@ -729,7 +729,7 @@ void MediaFilter::onCreateInputSurface() {
mGraphicBufferListener = new GraphicBufferListener;
sp<AMessage> notify = new AMessage();
- notify->setTarget(id());
+ notify->setTarget(this);
status_t err = mGraphicBufferListener->init(
notify, mStride, mSliceHeight, kBufferCountActual);
diff --git a/media/libstagefright/foundation/AHandler.cpp b/media/libstagefright/foundation/AHandler.cpp
index bd5f7e9..7dbbe54 100644
--- a/media/libstagefright/foundation/AHandler.cpp
+++ b/media/libstagefright/foundation/AHandler.cpp
@@ -19,15 +19,23 @@
#include <utils/Log.h>
#include <media/stagefright/foundation/AHandler.h>
-
-#include <media/stagefright/foundation/ALooperRoster.h>
+#include <media/stagefright/foundation/AMessage.h>
namespace android {
-sp<ALooper> AHandler::looper() {
- extern ALooperRoster gLooperRoster;
+void AHandler::deliverMessage(const sp<AMessage> &msg) {
+ onMessageReceived(msg);
+ mMessageCounter++;
- return gLooperRoster.findLooper(id());
+ if (mVerboseStats) {
+ uint32_t what = msg->what();
+ ssize_t idx = mMessages.indexOfKey(what);
+ if (idx < 0) {
+ mMessages.add(what, 1);
+ } else {
+ mMessages.editValueAt(idx)++;
+ }
+ }
}
} // namespace android
diff --git a/media/libstagefright/foundation/ALooper.cpp b/media/libstagefright/foundation/ALooper.cpp
index 88b1c92..90b5f68 100644
--- a/media/libstagefright/foundation/ALooper.cpp
+++ b/media/libstagefright/foundation/ALooper.cpp
@@ -16,6 +16,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "ALooper"
+
+#include <media/stagefright/foundation/ADebug.h>
+
#include <utils/Log.h>
#include <sys/time.h>
@@ -210,7 +213,7 @@ bool ALooper::loop() {
mEventQueue.erase(mEventQueue.begin());
}
- gLooperRoster.deliverMessage(event.mMessage);
+ event.mMessage->deliver();
// NOTE: It's important to note that at this point our "ALooper" object
// may no longer exist (its final reference may have gone away while
@@ -220,4 +223,29 @@ bool ALooper::loop() {
return true;
}
+// to be called by AMessage::postAndAwaitResponse only
+sp<AReplyToken> ALooper::createReplyToken() {
+ return new AReplyToken(this);
+}
+
+// to be called by AMessage::postAndAwaitResponse only
+status_t ALooper::awaitResponse(const sp<AReplyToken> &replyToken, sp<AMessage> *response) {
+ // return status in case we want to handle an interrupted wait
+ Mutex::Autolock autoLock(mRepliesLock);
+ CHECK(replyToken != NULL);
+ while (!replyToken->retrieveReply(response)) {
+ mRepliesCondition.wait(mRepliesLock);
+ }
+ return OK;
+}
+
+status_t ALooper::postReply(const sp<AReplyToken> &replyToken, const sp<AMessage> &reply) {
+ Mutex::Autolock autoLock(mRepliesLock);
+ status_t err = replyToken->setReply(reply);
+ if (err == OK) {
+ mRepliesCondition.broadcast();
+ }
+ return err;
+}
+
} // namespace android
diff --git a/media/libstagefright/foundation/ALooperRoster.cpp b/media/libstagefright/foundation/ALooperRoster.cpp
index 2d57aee..473ce1b 100644
--- a/media/libstagefright/foundation/ALooperRoster.cpp
+++ b/media/libstagefright/foundation/ALooperRoster.cpp
@@ -30,8 +30,7 @@ namespace android {
static bool verboseStats = false;
ALooperRoster::ALooperRoster()
- : mNextHandlerID(1),
- mNextReplyID(1) {
+ : mNextHandlerID(1) {
}
ALooper::handler_id ALooperRoster::registerHandler(
@@ -49,7 +48,7 @@ ALooper::handler_id ALooperRoster::registerHandler(
ALooper::handler_id handlerID = mNextHandlerID++;
mHandlers.add(handlerID, info);
- handler->setID(handlerID);
+ handler->setID(handlerID, looper);
return handlerID;
}
@@ -68,7 +67,7 @@ void ALooperRoster::unregisterHandler(ALooper::handler_id handlerID) {
sp<AHandler> handler = info.mHandler.promote();
if (handler != NULL) {
- handler->setID(0);
+ handler->setID(0, NULL);
}
mHandlers.removeItemsAt(index);
@@ -100,116 +99,6 @@ void ALooperRoster::unregisterStaleHandlers() {
}
}
-status_t ALooperRoster::postMessage(
- const sp<AMessage> &msg, int64_t delayUs) {
-
- sp<ALooper> looper = findLooper(msg->target());
-
- if (looper == NULL) {
- return -ENOENT;
- }
- looper->post(msg, delayUs);
- return OK;
-}
-
-void ALooperRoster::deliverMessage(const sp<AMessage> &msg) {
- sp<AHandler> handler;
-
- {
- Mutex::Autolock autoLock(mLock);
-
- ssize_t index = mHandlers.indexOfKey(msg->target());
-
- if (index < 0) {
- ALOGW("failed to deliver message. Target handler not registered.");
- return;
- }
-
- const HandlerInfo &info = mHandlers.valueAt(index);
- handler = info.mHandler.promote();
-
- if (handler == NULL) {
- ALOGW("failed to deliver message. "
- "Target handler %d registered, but object gone.",
- msg->target());
-
- mHandlers.removeItemsAt(index);
- return;
- }
- }
-
- handler->onMessageReceived(msg);
- handler->mMessageCounter++;
-
- if (verboseStats) {
- uint32_t what = msg->what();
- ssize_t idx = handler->mMessages.indexOfKey(what);
- if (idx < 0) {
- handler->mMessages.add(what, 1);
- } else {
- handler->mMessages.editValueAt(idx)++;
- }
- }
-}
-
-sp<ALooper> ALooperRoster::findLooper(ALooper::handler_id handlerID) {
- Mutex::Autolock autoLock(mLock);
-
- ssize_t index = mHandlers.indexOfKey(handlerID);
-
- if (index < 0) {
- return NULL;
- }
-
- sp<ALooper> looper = mHandlers.valueAt(index).mLooper.promote();
-
- if (looper == NULL) {
- mHandlers.removeItemsAt(index);
- return NULL;
- }
-
- return looper;
-}
-
-status_t ALooperRoster::postAndAwaitResponse(
- const sp<AMessage> &msg, sp<AMessage> *response) {
- sp<ALooper> looper = findLooper(msg->target());
-
- if (looper == NULL) {
- ALOGW("failed to post message. "
- "Target handler %d still registered, but object gone.",
- msg->target());
- response->clear();
- return -ENOENT;
- }
-
- Mutex::Autolock autoLock(mLock);
-
- uint32_t replyID = mNextReplyID++;
-
- msg->setInt32("replyID", replyID);
-
- looper->post(msg, 0 /* delayUs */);
-
- ssize_t index;
- while ((index = mReplies.indexOfKey(replyID)) < 0) {
- mRepliesCondition.wait(mLock);
- }
-
- *response = mReplies.valueAt(index);
- mReplies.removeItemsAt(index);
-
- return OK;
-}
-
-void ALooperRoster::postReply(uint32_t replyID, const sp<AMessage> &reply) {
- Mutex::Autolock autoLock(mLock);
-
- CHECK(mReplies.indexOfKey(replyID) < 0);
- mReplies.add(replyID, reply);
- mRepliesCondition.broadcast();
-}
-
static void makeFourCC(uint32_t fourcc, char *s) {
s[0] = (fourcc >> 24) & 0xff;
if (s[0]) {
@@ -225,7 +114,7 @@ static void makeFourCC(uint32_t fourcc, char *s) {
void ALooperRoster::dump(int fd, const Vector<String16>& args) {
bool clear = false;
bool oldVerbose = verboseStats;
- for (size_t i = 0;i < args.size(); i++) {
+ for (size_t i = 0; i < args.size(); i++) {
if (args[i] == String16("-c")) {
clear = true;
} else if (args[i] == String16("-von")) {
@@ -241,22 +130,23 @@ void ALooperRoster::dump(int fd, const Vector<String16>& args) {
Mutex::Autolock autoLock(mLock);
size_t n = mHandlers.size();
- s.appendFormat(" %zd registered handlers:\n", n);
+ s.appendFormat(" %zu registered handlers:\n", n);
for (size_t i = 0; i < n; i++) {
- s.appendFormat(" %zd: ", i);
+ s.appendFormat(" %d: ", mHandlers.keyAt(i));
HandlerInfo &info = mHandlers.editValueAt(i);
sp<ALooper> looper = info.mLooper.promote();
if (looper != NULL) {
- s.append(looper->mName.c_str());
+ s.append(looper->getName());
sp<AHandler> handler = info.mHandler.promote();
if (handler != NULL) {
+ handler->mVerboseStats = verboseStats;
s.appendFormat(": %u messages processed", handler->mMessageCounter);
if (verboseStats) {
for (size_t j = 0; j < handler->mMessages.size(); j++) {
char fourcc[15];
makeFourCC(handler->mMessages.keyAt(j), fourcc);
- s.appendFormat("\n %s: %d",
+ s.appendFormat("\n %s: %u",
fourcc,
handler->mMessages.valueAt(j));
}
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index 1f46bc9..e549ff6 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -27,6 +27,7 @@
#include "ABuffer.h"
#include "ADebug.h"
#include "ALooperRoster.h"
+#include "AHandler.h"
#include "AString.h"
#include <binder/Parcel.h>
@@ -36,10 +37,27 @@ namespace android {
extern ALooperRoster gLooperRoster;
-AMessage::AMessage(uint32_t what, ALooper::handler_id target)
+status_t AReplyToken::setReply(const sp<AMessage> &reply) {
+ if (mReplied) {
+ ALOGE("trying to post a duplicate reply");
+ return -EBUSY;
+ }
+ CHECK(mReply == NULL);
+ mReply = reply;
+ mReplied = true;
+ return OK;
+}
+
+AMessage::AMessage(void)
+ : mWhat(0),
+ mTarget(0),
+ mNumItems(0) {
+}
+
+AMessage::AMessage(uint32_t what, const sp<const AHandler> &handler)
: mWhat(what),
- mTarget(target),
mNumItems(0) {
+ setTarget(handler);
}
AMessage::~AMessage() {
@@ -54,12 +72,16 @@ uint32_t AMessage::what() const {
return mWhat;
}
-void AMessage::setTarget(ALooper::handler_id handlerID) {
- mTarget = handlerID;
-}
-
-ALooper::handler_id AMessage::target() const {
- return mTarget;
+void AMessage::setTarget(const sp<const AHandler> &handler) {
+ if (handler == NULL) {
+ mTarget = 0;
+ mHandler.clear();
+ mLooper.clear();
+ } else {
+ mTarget = handler->id();
+ mHandler = handler->getHandler();
+ mLooper = handler->getLooper();
+ }
}
void AMessage::clear() {
@@ -322,33 +344,76 @@ bool AMessage::findRect(
return true;
}
-void AMessage::post(int64_t delayUs) {
- gLooperRoster.postMessage(this, delayUs);
+void AMessage::deliver() {
+ sp<AHandler> handler = mHandler.promote();
+ if (handler == NULL) {
+ ALOGW("failed to deliver message as target handler %d is gone.", mTarget);
+ return;
+ }
+
+ handler->deliverMessage(this);
+}
+
+status_t AMessage::post(int64_t delayUs) {
+ sp<ALooper> looper = mLooper.promote();
+ if (looper == NULL) {
+ ALOGW("failed to post message as target looper for handler %d is gone.", mTarget);
+ return -ENOENT;
+ }
+
+ looper->post(this, delayUs);
+ return OK;
}
status_t AMessage::postAndAwaitResponse(sp<AMessage> *response) {
- return gLooperRoster.postAndAwaitResponse(this, response);
+ sp<ALooper> looper = mLooper.promote();
+ if (looper == NULL) {
+ ALOGW("failed to post message as target looper for handler %d is gone.", mTarget);
+ return -ENOENT;
+ }
+
+ sp<AReplyToken> token = looper->createReplyToken();
+ if (token == NULL) {
+ ALOGE("failed to create reply token");
+ return -ENOMEM;
+ }
+ setObject("replyID", token);
+
+ looper->post(this, 0 /* delayUs */);
+ return looper->awaitResponse(token, response);
}
-void AMessage::postReply(uint32_t replyID) {
- gLooperRoster.postReply(replyID, this);
+status_t AMessage::postReply(const sp<AReplyToken> &replyToken) {
+ if (replyToken == NULL) {
+ ALOGW("failed to post reply to a NULL token");
+ return -ENOENT;
+ }
+ sp<ALooper> looper = replyToken->getLooper();
+ if (looper == NULL) {
+ ALOGW("failed to post reply as target looper is gone.");
+ return -ENOENT;
+ }
+ return looper->postReply(replyToken, this);
}
-bool AMessage::senderAwaitsResponse(uint32_t *replyID) const {
- int32_t tmp;
- bool found = findInt32("replyID", &tmp);
+bool AMessage::senderAwaitsResponse(sp<AReplyToken> *replyToken) {
+ sp<RefBase> tmp;
+ bool found = findObject("replyID", &tmp);
if (!found) {
return false;
}
- *replyID = static_cast<uint32_t>(tmp);
+ *replyToken = static_cast<AReplyToken *>(tmp.get());
+ tmp.clear();
+ setObject("replyID", tmp);
+ // TODO: delete Object instead of setting it to NULL
- return true;
+ return *replyToken != NULL;
}
sp<AMessage> AMessage::dup() const {
- sp<AMessage> msg = new AMessage(mWhat, mTarget);
+ sp<AMessage> msg = new AMessage(mWhat, mHandler.promote());
msg->mNumItems = mNumItems;
#ifdef DUMP_STATS
@@ -532,7 +597,8 @@ AString AMessage::debugString(int32_t indent) const {
// static
sp<AMessage> AMessage::FromParcel(const Parcel &parcel) {
int32_t what = parcel.readInt32();
- sp<AMessage> msg = new AMessage(what);
+ sp<AMessage> msg = new AMessage();
+ msg->setWhat(what);
msg->mNumItems = static_cast<size_t>(parcel.readInt32());
for (size_t i = 0; i < msg->mNumItems; ++i) {
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index d0f3bc2..a8f60a8 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -49,8 +49,13 @@
namespace android {
+// static
// Number of recently-read bytes to use for bandwidth estimation
const size_t LiveSession::kBandwidthHistoryBytes = 200 * 1024;
+// High water mark to start up switch or report prepared)
+const int64_t LiveSession::kHighWaterMark = 8000000ll;
+const int64_t LiveSession::kMidWaterMark = 5000000ll;
+const int64_t LiveSession::kLowWaterMark = 3000000ll;
LiveSession::LiveSession(
const sp<AMessage> &notify, uint32_t flags,
@@ -75,14 +80,14 @@ LiveSession::LiveSession(
mSeekReplyID(0),
mFirstTimeUsValid(false),
mFirstTimeUs(0),
- mLastSeekTimeUs(0) {
+ mLastSeekTimeUs(0),
+ mPollBufferingGeneration(0) {
mStreams[kAudioIndex] = StreamItem("audio");
mStreams[kVideoIndex] = StreamItem("video");
mStreams[kSubtitleIndex] = StreamItem("subtitles");
for (size_t i = 0; i < kMaxStreams; ++i) {
- mDiscontinuities.add(indexToType(i), new AnotherPacketSource(NULL /* meta */));
mPacketSources.add(indexToType(i), new AnotherPacketSource(NULL /* meta */));
mPacketSources2.add(indexToType(i), new AnotherPacketSource(NULL /* meta */));
mBuffering[i] = false;
@@ -97,6 +102,9 @@ LiveSession::LiveSession(
}
LiveSession::~LiveSession() {
+ if (mFetcherLooper != NULL) {
+ mFetcherLooper->stop();
+ }
}
sp<ABuffer> LiveSession::createFormatChangeBuffer(bool swap) {
@@ -125,24 +133,7 @@ status_t LiveSession::dequeueAccessUnit(
return -EWOULDBLOCK;
}
- status_t finalResult;
- sp<AnotherPacketSource> discontinuityQueue = mDiscontinuities.valueFor(stream);
- if (discontinuityQueue->hasBufferAvailable(&finalResult)) {
- discontinuityQueue->dequeueAccessUnit(accessUnit);
- // seeking, track switching
- sp<AMessage> extra;
- int64_t timeUs;
- if ((*accessUnit)->meta()->findMessage("extra", &extra)
- && extra != NULL
- && extra->findInt64("timeUs", &timeUs)) {
- // seeking only
- mLastSeekTimeUs = timeUs;
- mDiscontinuityOffsetTimesUs.clear();
- mDiscontinuityAbsStartTimesUs.clear();
- }
- return INFO_DISCONTINUITY;
- }
-
+ status_t finalResult = OK;
sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(stream);
ssize_t idx = typeToIndex(stream);
@@ -172,7 +163,7 @@ status_t LiveSession::dequeueAccessUnit(
if (mBuffering[idx]) {
if (mSwitchInProgress
|| packetSource->isFinished(0)
- || packetSource->getEstimatedDurationUs() > targetDurationUs) {
+ || packetSource->hasBufferAvailable(&finalResult)) {
mBuffering[idx] = false;
}
}
@@ -244,7 +235,7 @@ status_t LiveSession::dequeueAccessUnit(
Mutex::Autolock lock(mSwapMutex);
if (switchGeneration == mSwitchGeneration) {
swapPacketSource(stream);
- sp<AMessage> msg = new AMessage(kWhatSwapped, id());
+ sp<AMessage> msg = new AMessage(kWhatSwapped, this);
msg->setInt32("stream", stream);
msg->setInt32("switchGeneration", switchGeneration);
msg->post();
@@ -349,7 +340,7 @@ status_t LiveSession::getStreamFormat(StreamType stream, sp<AMessage> *format) {
void LiveSession::connectAsync(
const char *url, const KeyedVector<String8, String8> *headers) {
- sp<AMessage> msg = new AMessage(kWhatConnect, id());
+ sp<AMessage> msg = new AMessage(kWhatConnect, this);
msg->setString("url", url);
if (headers != NULL) {
@@ -362,7 +353,7 @@ void LiveSession::connectAsync(
}
status_t LiveSession::disconnect() {
- sp<AMessage> msg = new AMessage(kWhatDisconnect, id());
+ sp<AMessage> msg = new AMessage(kWhatDisconnect, this);
sp<AMessage> response;
status_t err = msg->postAndAwaitResponse(&response);
@@ -371,7 +362,7 @@ status_t LiveSession::disconnect() {
}
status_t LiveSession::seekTo(int64_t timeUs) {
- sp<AMessage> msg = new AMessage(kWhatSeek, id());
+ sp<AMessage> msg = new AMessage(kWhatSeek, this);
msg->setInt64("timeUs", timeUs);
sp<AMessage> response;
@@ -402,7 +393,7 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) {
case kWhatSeek:
{
- uint32_t seekReplyID;
+ sp<AReplyToken> seekReplyID;
CHECK(msg->senderAwaitsResponse(&seekReplyID));
mSeekReplyID = seekReplyID;
mSeekReply = new AMessage;
@@ -429,11 +420,16 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) {
if (what == PlaylistFetcher::kWhatStopped) {
AString uri;
CHECK(msg->findString("uri", &uri));
- if (mFetcherInfos.removeItem(uri) < 0) {
+ ssize_t index = mFetcherInfos.indexOfKey(uri);
+ if (index < 0) {
// ignore duplicated kWhatStopped messages.
break;
}
+ mFetcherLooper->unregisterHandler(
+ mFetcherInfos[index].mFetcher->id());
+ mFetcherInfos.removeItemsAt(index);
+
if (mSwitchInProgress) {
tryToFinishBandwidthSwitch();
}
@@ -443,14 +439,6 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) {
CHECK_GT(mContinuationCounter, 0);
if (--mContinuationCounter == 0) {
mContinuation->post();
-
- if (mSeekReplyID != 0) {
- CHECK(mSeekReply != NULL);
- mSeekReply->setInt32("err", OK);
- mSeekReply->postReply(mSeekReplyID);
- mSeekReplyID = 0;
- mSeekReply.clear();
- }
}
}
break;
@@ -464,8 +452,11 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) {
int64_t durationUs;
CHECK(msg->findInt64("durationUs", &durationUs));
- FetcherInfo *info = &mFetcherInfos.editValueFor(uri);
- info->mDurationUs = durationUs;
+ ssize_t index = mFetcherInfos.indexOfKey(uri);
+ if (index >= 0) {
+ FetcherInfo *info = &mFetcherInfos.editValueFor(uri);
+ info->mDurationUs = durationUs;
+ }
break;
}
@@ -513,34 +504,6 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) {
break;
}
- case PlaylistFetcher::kWhatTemporarilyDoneFetching:
- {
- AString uri;
- CHECK(msg->findString("uri", &uri));
-
- if (mFetcherInfos.indexOfKey(uri) < 0) {
- ALOGE("couldn't find uri");
- break;
- }
- FetcherInfo *info = &mFetcherInfos.editValueFor(uri);
- info->mIsPrepared = true;
-
- if (mInPreparationPhase) {
- bool allFetchersPrepared = true;
- for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
- if (!mFetcherInfos.valueAt(i).mIsPrepared) {
- allFetchersPrepared = false;
- break;
- }
- }
-
- if (allFetchersPrepared) {
- postPrepared(OK);
- }
- }
- break;
- }
-
case PlaylistFetcher::kWhatStartedAt:
{
int32_t switchGeneration;
@@ -569,19 +532,6 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) {
break;
}
- case kWhatCheckBandwidth:
- {
- int32_t generation;
- CHECK(msg->findInt32("generation", &generation));
-
- if (generation != mCheckBandwidthGeneration) {
- break;
- }
-
- onCheckBandwidth(msg);
- break;
- }
-
case kWhatChangeConfiguration:
{
onChangeConfiguration(msg);
@@ -612,15 +562,13 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) {
break;
}
- case kWhatCheckSwitchDown:
+ case kWhatPollBuffering:
{
- onCheckSwitchDown();
- break;
- }
-
- case kWhatSwitchDown:
- {
- onSwitchDown();
+ int32_t generation;
+ CHECK(msg->findInt32("generation", &generation));
+ if (generation == mPollBufferingGeneration) {
+ onPollBuffering();
+ }
break;
}
@@ -691,6 +639,14 @@ void LiveSession::onConnect(const sp<AMessage> &msg) {
return;
}
+ // create looper for fetchers
+ if (mFetcherLooper == NULL) {
+ mFetcherLooper = new ALooper();
+
+ mFetcherLooper->setName("Fetcher");
+ mFetcherLooper->start(false, false);
+ }
+
// We trust the content provider to make a reasonable choice of preferred
// initial bandwidth by listing it first in the variant playlist.
// At startup we really don't have a good estimate on the available
@@ -739,25 +695,26 @@ void LiveSession::onConnect(const sp<AMessage> &msg) {
mPlaylist->pickRandomMediaItems();
changeConfiguration(
0ll /* timeUs */, initialBandwidthIndex, false /* pickTrack */);
+
+ schedulePollBuffering();
}
void LiveSession::finishDisconnect() {
// No reconfiguration is currently pending, make sure none will trigger
// during disconnection either.
- cancelCheckBandwidthEvent();
// Protect mPacketSources from a swapPacketSource race condition through disconnect.
// (finishDisconnect, onFinishDisconnect2)
cancelBandwidthSwitch();
- // cancel switch down monitor
- mSwitchDownMonitor.clear();
+ // cancel buffer polling
+ cancelPollBuffering();
for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
mFetcherInfos.valueAt(i).mFetcher->stopAsync();
}
- sp<AMessage> msg = new AMessage(kWhatFinishDisconnect2, id());
+ sp<AMessage> msg = new AMessage(kWhatFinishDisconnect2, this);
mContinuationCounter = mFetcherInfos.size();
mContinuation = msg;
@@ -790,7 +747,7 @@ sp<PlaylistFetcher> LiveSession::addFetcher(const char *uri) {
return NULL;
}
- sp<AMessage> notify = new AMessage(kWhatFetcherNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatFetcherNotify, this);
notify->setString("uri", uri);
notify->setInt32("switchGeneration", mSwitchGeneration);
@@ -799,7 +756,7 @@ sp<PlaylistFetcher> LiveSession::addFetcher(const char *uri) {
info.mDurationUs = -1ll;
info.mIsPrepared = false;
info.mToBeRemoved = false;
- looper()->registerHandler(info.mFetcher);
+ mFetcherLooper->registerHandler(info.mFetcher);
mFetcherInfos.add(uri, info);
@@ -1185,7 +1142,7 @@ status_t LiveSession::selectTrack(size_t index, bool select) {
++mSubtitleGeneration;
status_t err = mPlaylist->selectTrack(index, select);
if (err == OK) {
- sp<AMessage> msg = new AMessage(kWhatChangeConfiguration, id());
+ sp<AMessage> msg = new AMessage(kWhatChangeConfiguration, this);
msg->setInt32("bandwidthIndex", mCurBandwidthIndex);
msg->setInt32("pickTrack", select);
msg->post();
@@ -1201,19 +1158,6 @@ ssize_t LiveSession::getSelectedTrack(media_track_type type) const {
}
}
-bool LiveSession::canSwitchUp() {
- // Allow upwards bandwidth switch when a stream has buffered at least 10 seconds.
- status_t err = OK;
- for (size_t i = 0; i < mPacketSources.size(); ++i) {
- sp<AnotherPacketSource> source = mPacketSources.valueAt(i);
- int64_t dur = source->getBufferedDurationUs(&err);
- if (err == OK && dur > 10000000) {
- return true;
- }
- }
- return false;
-}
-
void LiveSession::changeConfiguration(
int64_t timeUs, size_t bandwidthIndex, bool pickTrack) {
// Protect mPacketSources from a swapPacketSource race condition through reconfiguration.
@@ -1273,9 +1217,9 @@ void LiveSession::changeConfiguration(
sp<AMessage> msg;
if (timeUs < 0ll) {
// skip onChangeConfiguration2 (decoder destruction) if not seeking.
- msg = new AMessage(kWhatChangeConfiguration3, id());
+ msg = new AMessage(kWhatChangeConfiguration3, this);
} else {
- msg = new AMessage(kWhatChangeConfiguration2, id());
+ msg = new AMessage(kWhatChangeConfiguration2, this);
}
msg->setInt32("streamMask", streamMask);
msg->setInt32("resumeMask", resumeMask);
@@ -1296,14 +1240,6 @@ void LiveSession::changeConfiguration(
if (mContinuationCounter == 0) {
msg->post();
-
- if (mSeekReplyID != 0) {
- CHECK(mSeekReply != NULL);
- mSeekReply->setInt32("err", OK);
- mSeekReply->postReply(mSeekReplyID);
- mSeekReplyID = 0;
- mSeekReply.clear();
- }
}
}
@@ -1323,6 +1259,30 @@ void LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) {
// All fetchers are either suspended or have been removed now.
+ // If we're seeking, clear all packet sources before we report
+ // seek complete, to prevent decoder from pulling stale data.
+ int64_t timeUs;
+ CHECK(msg->findInt64("timeUs", &timeUs));
+
+ if (timeUs >= 0) {
+ mLastSeekTimeUs = timeUs;
+
+ for (size_t i = 0; i < mPacketSources.size(); i++) {
+ mPacketSources.editValueAt(i)->clear();
+ }
+
+ mDiscontinuityOffsetTimesUs.clear();
+ mDiscontinuityAbsStartTimesUs.clear();
+
+ if (mSeekReplyID != 0) {
+ CHECK(mSeekReply != NULL);
+ mSeekReply->setInt32("err", OK);
+ mSeekReply->postReply(mSeekReplyID);
+ mSeekReplyID = 0;
+ mSeekReply.clear();
+ }
+ }
+
uint32_t streamMask, resumeMask;
CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask));
CHECK(msg->findInt32("resumeMask", (int32_t *)&resumeMask));
@@ -1372,7 +1332,7 @@ void LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) {
notify->setInt32("changedMask", changedMask);
msg->setWhat(kWhatChangeConfiguration3);
- msg->setTarget(id());
+ msg->setTarget(this);
notify->setMessage("reply", msg);
notify->post();
@@ -1428,19 +1388,8 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
for (size_t j = 0; j < kMaxStreams; ++j) {
if ((resumeMask & indexToType(j)) && uri == mStreams[j].mUri) {
sources[j] = mPacketSources.valueFor(indexToType(j));
-
- if (j != kSubtitleIndex) {
- ALOGV("queueing dummy discontinuity for stream type %d", indexToType(j));
- sp<AnotherPacketSource> discontinuityQueue;
- discontinuityQueue = mDiscontinuities.valueFor(indexToType(j));
- discontinuityQueue->queueDiscontinuity(
- ATSParser::DISCONTINUITY_NONE,
- NULL,
- true);
- }
}
}
-
FetcherInfo &info = mFetcherInfos.editValueAt(i);
if (sources[kAudioIndex] != NULL || sources[kVideoIndex] != NULL
|| sources[kSubtitleIndex] != NULL) {
@@ -1486,15 +1435,7 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
sources[j] = mPacketSources.valueFor(indexToType(j));
if (timeUs >= 0) {
- sources[j]->clear();
startTimeUs = timeUs;
-
- sp<AnotherPacketSource> discontinuityQueue;
- sp<AMessage> extra = new AMessage;
- extra->setInt64("timeUs", timeUs);
- discontinuityQueue = mDiscontinuities.valueFor(indexToType(j));
- discontinuityQueue->queueDiscontinuity(
- ATSParser::DISCONTINUITY_TIME, extra, true);
} else {
int32_t type;
sp<AMessage> meta;
@@ -1532,9 +1473,10 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
if (j == kSubtitleIndex) {
break;
}
- sp<AnotherPacketSource> discontinuityQueue;
- discontinuityQueue = mDiscontinuities.valueFor(indexToType(j));
- discontinuityQueue->queueDiscontinuity(
+
+ ALOGV("stream[%d]: queue format change", j);
+
+ sources[j]->queueDiscontinuity(
ATSParser::DISCONTINUITY_FORMATCHANGE, NULL, true);
} else {
// adapting, queue discontinuities after resume
@@ -1564,9 +1506,6 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
// All fetchers have now been started, the configuration change
// has completed.
- cancelCheckBandwidthEvent();
- scheduleCheckBandwidthEvent();
-
ALOGV("XXX configuration change completed.");
mReconfigurationInProgress = false;
if (switching) {
@@ -1623,47 +1562,35 @@ void LiveSession::onSwapped(const sp<AMessage> &msg) {
tryToFinishBandwidthSwitch();
}
-void LiveSession::onCheckSwitchDown() {
- if (mSwitchDownMonitor == NULL) {
- return;
- }
-
- if (mSwitchInProgress || mReconfigurationInProgress) {
- ALOGV("Switch/Reconfig in progress, defer switch down");
- mSwitchDownMonitor->post(1000000ll);
- return;
- }
+void LiveSession::schedulePollBuffering() {
+ sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
+ msg->setInt32("generation", mPollBufferingGeneration);
+ msg->post(1000000ll);
+}
- for (size_t i = 0; i < kMaxStreams; ++i) {
- int32_t targetDuration;
- sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(indexToType(i));
- sp<AMessage> meta = packetSource->getLatestDequeuedMeta();
+void LiveSession::cancelPollBuffering() {
+ ++mPollBufferingGeneration;
+}
- if (meta != NULL && meta->findInt32("targetDuration", &targetDuration) ) {
- int64_t bufferedDurationUs = packetSource->getEstimatedDurationUs();
- int64_t targetDurationUs = targetDuration * 1000000ll;
+void LiveSession::onPollBuffering() {
+ ALOGV("onPollBuffering: mSwitchInProgress %d, mReconfigurationInProgress %d, "
+ "mInPreparationPhase %d, mStreamMask 0x%x",
+ mSwitchInProgress, mReconfigurationInProgress,
+ mInPreparationPhase, mStreamMask);
- if (bufferedDurationUs < targetDurationUs / 3) {
- (new AMessage(kWhatSwitchDown, id()))->post();
- break;
- }
+ bool low, mid, high;
+ if (checkBuffering(low, mid, high)) {
+ if (mInPreparationPhase && mid) {
+ postPrepared(OK);
}
- }
-
- mSwitchDownMonitor->post(1000000ll);
-}
-
-void LiveSession::onSwitchDown() {
- if (mReconfigurationInProgress || mSwitchInProgress || mCurBandwidthIndex == 0) {
- return;
- }
- ssize_t bandwidthIndex = getBandwidthIndex();
- if (bandwidthIndex < mCurBandwidthIndex) {
- changeConfiguration(-1, bandwidthIndex, false);
- return;
+ // don't switch before we report prepared
+ if (!mInPreparationPhase && (low || high)) {
+ switchBandwidthIfNeeded(high);
+ }
}
+ schedulePollBuffering();
}
// Mark switch done when:
@@ -1688,16 +1615,6 @@ void LiveSession::tryToFinishBandwidthSwitch() {
}
}
-void LiveSession::scheduleCheckBandwidthEvent() {
- sp<AMessage> msg = new AMessage(kWhatCheckBandwidth, id());
- msg->setInt32("generation", mCheckBandwidthGeneration);
- msg->post(10000000ll);
-}
-
-void LiveSession::cancelCheckBandwidthEvent() {
- ++mCheckBandwidthGeneration;
-}
-
void LiveSession::cancelBandwidthSwitch() {
Mutex::Autolock lock(mSwapMutex);
mSwitchGeneration++;
@@ -1727,33 +1644,69 @@ void LiveSession::cancelBandwidthSwitch() {
}
}
-bool LiveSession::canSwitchBandwidthTo(size_t bandwidthIndex) {
- if (mReconfigurationInProgress || mSwitchInProgress) {
+bool LiveSession::checkBuffering(bool &low, bool &mid, bool &high) {
+ low = mid = high = false;
+
+ if (mSwitchInProgress || mReconfigurationInProgress) {
+ ALOGV("Switch/Reconfig in progress, defer buffer polling");
return false;
}
- if (mCurBandwidthIndex < 0) {
- return true;
+ // TODO: Fine tune low/high mark.
+ // We also need to pause playback if buffering is too low.
+ // Currently during underflow, we depend on decoder to starve
+ // to pause, but A/V could have different buffering left,
+ // they're not paused together.
+ // TODO: Report buffering level to NuPlayer for BUFFERING_UPDATE
+
+ // Switch down if any of the fetchers are below low mark;
+ // Switch up if all of the fetchers are over high mark.
+ size_t activeCount, lowCount, midCount, highCount;
+ activeCount = lowCount = midCount = highCount = 0;
+ for (size_t i = 0; i < mPacketSources.size(); ++i) {
+ // we don't check subtitles for buffering level
+ if (!(mStreamMask & mPacketSources.keyAt(i)
+ & (STREAMTYPE_AUDIO | STREAMTYPE_VIDEO))) {
+ continue;
+ }
+ // ignore streams that never had any packet queued.
+ // (it's possible that the variant only has audio or video)
+ sp<AMessage> meta = mPacketSources[i]->getLatestEnqueuedMeta();
+ if (meta == NULL) {
+ continue;
+ }
+
+ ++activeCount;
+ int64_t bufferedDurationUs =
+ mPacketSources[i]->getEstimatedDurationUs();
+ ALOGV("source[%d]: buffered %lld us", i, bufferedDurationUs);
+ if (bufferedDurationUs < kLowWaterMark) {
+ ++lowCount;
+ break;
+ } else if (bufferedDurationUs > kHighWaterMark) {
+ ++midCount;
+ ++highCount;
+ } else if (bufferedDurationUs > kMidWaterMark) {
+ ++midCount;
+ }
}
- if (bandwidthIndex == (size_t)mCurBandwidthIndex) {
- return false;
- } else if (bandwidthIndex > (size_t)mCurBandwidthIndex) {
- return canSwitchUp();
- } else {
+ if (activeCount > 0) {
+ high = (highCount == activeCount);
+ mid = (midCount == activeCount);
+ low = (lowCount > 0);
return true;
}
+
+ return false;
}
-void LiveSession::onCheckBandwidth(const sp<AMessage> &msg) {
- size_t bandwidthIndex = getBandwidthIndex();
- if (canSwitchBandwidthTo(bandwidthIndex)) {
- changeConfiguration(-1ll /* timeUs */, bandwidthIndex);
- } else {
- // Come back and check again 10 seconds later in case there is nothing to do now.
- // If we DO change configuration, once that completes it'll schedule a new
- // check bandwidth event with an incremented mCheckBandwidthGeneration.
- msg->post(10000000ll);
+void LiveSession::switchBandwidthIfNeeded(bool canSwitchUp) {
+ ssize_t bandwidthIndex = getBandwidthIndex();
+
+ if ((canSwitchUp && bandwidthIndex > mCurBandwidthIndex)
+ || (!canSwitchUp && bandwidthIndex < mCurBandwidthIndex)) {
+ changeConfiguration(-1, bandwidthIndex, false);
}
}
@@ -1771,10 +1724,8 @@ void LiveSession::postPrepared(status_t err) {
notify->post();
mInPreparationPhase = false;
-
- mSwitchDownMonitor = new AMessage(kWhatCheckSwitchDown, id());
- mSwitchDownMonitor->post();
}
+
} // namespace android
diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h
index 2d3a25a..3b0a9a4 100644
--- a/media/libstagefright/httplive/LiveSession.h
+++ b/media/libstagefright/httplive/LiveSession.h
@@ -26,6 +26,7 @@
namespace android {
struct ABuffer;
+struct AReplyToken;
struct AnotherPacketSource;
struct DataSource;
struct HTTPBase;
@@ -39,10 +40,6 @@ struct LiveSession : public AHandler {
// Don't log any URLs.
kFlagIncognito = 1,
};
- LiveSession(
- const sp<AMessage> &notify,
- uint32_t flags,
- const sp<IMediaHTTPService> &httpService);
enum StreamIndex {
kAudioIndex = 0,
@@ -56,6 +53,12 @@ struct LiveSession : public AHandler {
STREAMTYPE_VIDEO = 1 << kVideoIndex,
STREAMTYPE_SUBTITLES = 1 << kSubtitleIndex,
};
+
+ LiveSession(
+ const sp<AMessage> &notify,
+ uint32_t flags,
+ const sp<IMediaHTTPService> &httpService);
+
status_t dequeueAccessUnit(StreamType stream, sp<ABuffer> *accessUnit);
status_t getStreamFormat(StreamType stream, sp<AMessage> *format);
@@ -109,11 +112,13 @@ private:
kWhatChangeConfiguration3 = 'chC3',
kWhatFinishDisconnect2 = 'fin2',
kWhatSwapped = 'swap',
- kWhatCheckSwitchDown = 'ckSD',
- kWhatSwitchDown = 'sDwn',
+ kWhatPollBuffering = 'poll',
};
static const size_t kBandwidthHistoryBytes;
+ static const int64_t kHighWaterMark;
+ static const int64_t kMidWaterMark;
+ static const int64_t kLowWaterMark;
struct BandwidthItem {
size_t mPlaylistIndex;
@@ -168,6 +173,7 @@ private:
sp<M3UParser> mPlaylist;
+ sp<ALooper> mFetcherLooper;
KeyedVector<AString, FetcherInfo> mFetcherInfos;
uint32_t mStreamMask;
@@ -180,7 +186,6 @@ private:
// we use this to track reconfiguration progress.
uint32_t mSwapMask;
- KeyedVector<StreamType, sp<AnotherPacketSource> > mDiscontinuities;
KeyedVector<StreamType, sp<AnotherPacketSource> > mPacketSources;
// A second set of packet sources that buffer content for the variant we're switching to.
KeyedVector<StreamType, sp<AnotherPacketSource> > mPacketSources2;
@@ -203,16 +208,17 @@ private:
bool mReconfigurationInProgress;
bool mSwitchInProgress;
- uint32_t mDisconnectReplyID;
- uint32_t mSeekReplyID;
+ sp<AReplyToken> mDisconnectReplyID;
+ sp<AReplyToken> mSeekReplyID;
bool mFirstTimeUsValid;
int64_t mFirstTimeUs;
int64_t mLastSeekTimeUs;
- sp<AMessage> mSwitchDownMonitor;
KeyedVector<size_t, int64_t> mDiscontinuityAbsStartTimesUs;
KeyedVector<size_t, int64_t> mDiscontinuityOffsetTimesUs;
+ int32_t mPollBufferingGeneration;
+
sp<PlaylistFetcher> addFetcher(const char *uri);
void onConnect(const sp<AMessage> &msg);
@@ -256,27 +262,24 @@ private:
void onChangeConfiguration2(const sp<AMessage> &msg);
void onChangeConfiguration3(const sp<AMessage> &msg);
void onSwapped(const sp<AMessage> &msg);
- void onCheckSwitchDown();
- void onSwitchDown();
void tryToFinishBandwidthSwitch();
- void scheduleCheckBandwidthEvent();
- void cancelCheckBandwidthEvent();
-
// cancelBandwidthSwitch is atomic wrt swapPacketSource; call it to prevent packet sources
// from being swapped out on stale discontinuities while manipulating
// mPacketSources/mPacketSources2.
void cancelBandwidthSwitch();
- bool canSwitchBandwidthTo(size_t bandwidthIndex);
- void onCheckBandwidth(const sp<AMessage> &msg);
+ void schedulePollBuffering();
+ void cancelPollBuffering();
+ void onPollBuffering();
+ bool checkBuffering(bool &low, bool &mid, bool &high);
+ void switchBandwidthIfNeeded(bool canSwitchUp);
void finishDisconnect();
void postPrepared(status_t err);
void swapPacketSource(StreamType stream);
- bool canSwitchUp();
DISALLOW_EVIL_CONSTRUCTORS(LiveSession);
};
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 1227600..3710686 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -49,6 +49,7 @@ namespace android {
// static
const int64_t PlaylistFetcher::kMinBufferedDurationUs = 10000000ll;
const int64_t PlaylistFetcher::kMaxMonitorDelayUs = 3000000ll;
+const int64_t PlaylistFetcher::kFetcherResumeThreshold = 100000ll;
// LCM of 188 (size of a TS packet) & 1k works well
const int32_t PlaylistFetcher::kDownloadBlockSize = 47 * 1024;
const int32_t PlaylistFetcher::kNumSkipFrames = 5;
@@ -325,7 +326,7 @@ void PlaylistFetcher::postMonitorQueue(int64_t delayUs, int64_t minDelayUs) {
ALOGV("Need to refresh playlist in %" PRId64 , maxDelayUs);
delayUs = maxDelayUs;
}
- sp<AMessage> msg = new AMessage(kWhatMonitorQueue, id());
+ sp<AMessage> msg = new AMessage(kWhatMonitorQueue, this);
msg->setInt32("generation", mMonitorQueueGeneration);
msg->post(delayUs);
}
@@ -342,7 +343,7 @@ void PlaylistFetcher::startAsync(
int64_t segmentStartTimeUs,
int32_t startDiscontinuitySeq,
bool adaptive) {
- sp<AMessage> msg = new AMessage(kWhatStart, id());
+ sp<AMessage> msg = new AMessage(kWhatStart, this);
uint32_t streamTypeMask = 0ul;
@@ -370,17 +371,17 @@ void PlaylistFetcher::startAsync(
}
void PlaylistFetcher::pauseAsync() {
- (new AMessage(kWhatPause, id()))->post();
+ (new AMessage(kWhatPause, this))->post();
}
void PlaylistFetcher::stopAsync(bool clear) {
- sp<AMessage> msg = new AMessage(kWhatStop, id());
+ sp<AMessage> msg = new AMessage(kWhatStop, this);
msg->setInt32("clear", clear);
msg->post();
}
void PlaylistFetcher::resumeUntilAsync(const sp<AMessage> &params) {
- AMessage* msg = new AMessage(kWhatResumeUntil, id());
+ AMessage* msg = new AMessage(kWhatResumeUntil, this);
msg->setMessage("params", params);
msg->post();
}
@@ -535,12 +536,19 @@ status_t PlaylistFetcher::onResumeUntil(const sp<AMessage> &msg) {
sp<AMessage> params;
CHECK(msg->findMessage("params", &params));
- bool stop = false;
+ size_t stopCount = 0;
for (size_t i = 0; i < mPacketSources.size(); i++) {
sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i);
const char *stopKey;
int streamType = mPacketSources.keyAt(i);
+
+ if (streamType == LiveSession::STREAMTYPE_SUBTITLES) {
+ // the subtitle track can always be stopped
+ ++stopCount;
+ continue;
+ }
+
switch (streamType) {
case LiveSession::STREAMTYPE_VIDEO:
stopKey = "timeUsVideo";
@@ -550,15 +558,11 @@ status_t PlaylistFetcher::onResumeUntil(const sp<AMessage> &msg) {
stopKey = "timeUsAudio";
break;
- case LiveSession::STREAMTYPE_SUBTITLES:
- stopKey = "timeUsSubtitle";
- break;
-
default:
TRESPASS();
}
- // Don't resume if we would stop within a resume threshold.
+ // check if this stream has too little data left to be resumed
int32_t discontinuitySeq;
int64_t latestTimeUs = 0, stopTimeUs = 0;
sp<AMessage> latestMeta = packetSource->getLatestEnqueuedMeta();
@@ -567,12 +571,13 @@ status_t PlaylistFetcher::onResumeUntil(const sp<AMessage> &msg) {
&& discontinuitySeq == mDiscontinuitySeq
&& latestMeta->findInt64("timeUs", &latestTimeUs)
&& params->findInt64(stopKey, &stopTimeUs)
- && stopTimeUs - latestTimeUs < resumeThreshold(latestMeta)) {
- stop = true;
+ && stopTimeUs - latestTimeUs < kFetcherResumeThreshold) {
+ ++stopCount;
}
}
- if (stop) {
+ // Don't resume if all streams are within a resume threshold
+ if (stopCount == mPacketSources.size()) {
for (size_t i = 0; i < mPacketSources.size(); i++) {
mPacketSources.valueAt(i)->queueAccessUnit(mSession->createFormatChangeBuffer());
}
@@ -581,7 +586,7 @@ status_t PlaylistFetcher::onResumeUntil(const sp<AMessage> &msg) {
}
mStopParams = params;
- postMonitorQueue();
+ onDownloadNext();
return OK;
}
@@ -660,9 +665,6 @@ void PlaylistFetcher::onMonitorQueue() {
ALOGV("prepared, buffered=%" PRId64 " > %" PRId64 "",
bufferedDurationUs, targetDurationUs);
- sp<AMessage> msg = mNotify->dup();
- msg->setInt32("what", kWhatTemporarilyDoneFetching);
- msg->post();
}
if (finalResult == OK && downloadMore) {
@@ -671,16 +673,11 @@ void PlaylistFetcher::onMonitorQueue() {
// delay the next download slightly; hopefully this gives other concurrent fetchers
// a better chance to run.
// onDownloadNext();
- sp<AMessage> msg = new AMessage(kWhatDownloadNext, id());
+ sp<AMessage> msg = new AMessage(kWhatDownloadNext, this);
msg->setInt32("generation", mMonitorQueueGeneration);
msg->post(1000l);
} else {
// Nothing to do yet, try again in a second.
-
- sp<AMessage> msg = mNotify->dup();
- msg->setInt32("what", kWhatTemporarilyDoneFetching);
- msg->post();
-
int64_t delayUs = mPrepared ? kMaxMonitorDelayUs : targetDurationUs / 2;
ALOGV("pausing for %" PRId64 ", buffered=%" PRId64 " > %" PRId64 "",
delayUs, bufferedDurationUs, durationToBufferUs);
@@ -1687,33 +1684,4 @@ void PlaylistFetcher::updateDuration() {
msg->post();
}
-int64_t PlaylistFetcher::resumeThreshold(const sp<AMessage> &msg) {
- int64_t durationUs;
- if (msg->findInt64("durationUs", &durationUs) && durationUs > 0) {
- return kNumSkipFrames * durationUs;
- }
-
- sp<RefBase> obj;
- msg->findObject("format", &obj);
- MetaData *format = static_cast<MetaData *>(obj.get());
-
- const char *mime;
- CHECK(format->findCString(kKeyMIMEType, &mime));
- bool audio = !strncasecmp(mime, "audio/", 6);
- if (audio) {
- // Assumes 1000 samples per frame.
- int32_t sampleRate;
- CHECK(format->findInt32(kKeySampleRate, &sampleRate));
- return kNumSkipFrames /* frames */ * 1000 /* samples */
- * (1000000 / sampleRate) /* sample duration (us) */;
- } else {
- int32_t frameRate;
- if (format->findInt32(kKeyFrameRate, &frameRate) && frameRate > 0) {
- return kNumSkipFrames * (1000000 / frameRate);
- }
- }
-
- return 500000ll;
-}
-
} // namespace android
diff --git a/media/libstagefright/httplive/PlaylistFetcher.h b/media/libstagefright/httplive/PlaylistFetcher.h
index 4e15f85..2f11949 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.h
+++ b/media/libstagefright/httplive/PlaylistFetcher.h
@@ -36,6 +36,7 @@ class String8;
struct PlaylistFetcher : public AHandler {
static const int64_t kMinBufferedDurationUs;
static const int32_t kDownloadBlockSize;
+ static const int64_t kFetcherResumeThreshold;
enum {
kWhatStarted,
@@ -43,7 +44,6 @@ struct PlaylistFetcher : public AHandler {
kWhatStopped,
kWhatError,
kWhatDurationUpdate,
- kWhatTemporarilyDoneFetching,
kWhatPrepared,
kWhatPreparationFailed,
kWhatStartedAt,
@@ -212,10 +212,6 @@ private:
void updateDuration();
- // Before resuming a fetcher in onResume, check the remaining duration is longer than that
- // returned by resumeThreshold.
- int64_t resumeThreshold(const sp<AMessage> &msg);
-
DISALLOW_EVIL_CONSTRUCTORS(PlaylistFetcher);
};
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 482ccff..aebe86c 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -35,6 +35,7 @@
#include <media/stagefright/Utils.h>
#include <media/IStreamSource.h>
#include <utils/KeyedVector.h>
+#include <utils/Vector.h>
#include <inttypes.h>
@@ -86,14 +87,22 @@ struct ATSParser::Program : public RefBase {
}
private:
+ struct StreamInfo {
+ unsigned mType;
+ unsigned mPID;
+ };
+
ATSParser *mParser;
unsigned mProgramNumber;
unsigned mProgramMapPID;
KeyedVector<unsigned, sp<Stream> > mStreams;
bool mFirstPTSValid;
uint64_t mFirstPTS;
+ int64_t mLastRecoveredPTS;
status_t parseProgramMap(ABitReader *br);
+ int64_t recoverPTS(uint64_t PTS_33bit);
+ bool switchPIDs(const Vector<StreamInfo> &infos);
DISALLOW_EVIL_CONSTRUCTORS(Program);
};
@@ -182,7 +191,8 @@ ATSParser::Program::Program(
mProgramNumber(programNumber),
mProgramMapPID(programMapPID),
mFirstPTSValid(false),
- mFirstPTS(0) {
+ mFirstPTS(0),
+ mLastRecoveredPTS(-1ll) {
ALOGV("new program number %u", programNumber);
}
@@ -237,10 +247,71 @@ void ATSParser::Program::signalEOS(status_t finalResult) {
}
}
-struct StreamInfo {
- unsigned mType;
- unsigned mPID;
-};
+bool ATSParser::Program::switchPIDs(const Vector<StreamInfo> &infos) {
+ bool success = false;
+
+ if (mStreams.size() == infos.size()) {
+ // build type->PIDs map for old and new mapping
+ size_t i;
+ KeyedVector<int32_t, Vector<int32_t> > oldType2PIDs, newType2PIDs;
+ for (i = 0; i < mStreams.size(); ++i) {
+ ssize_t index = oldType2PIDs.indexOfKey(mStreams[i]->type());
+ if (index < 0) {
+ oldType2PIDs.add(mStreams[i]->type(), Vector<int32_t>());
+ }
+ oldType2PIDs.editValueFor(mStreams[i]->type()).push_back(mStreams[i]->pid());
+ }
+ for (i = 0; i < infos.size(); ++i) {
+ ssize_t index = newType2PIDs.indexOfKey(infos[i].mType);
+ if (index < 0) {
+ newType2PIDs.add(infos[i].mType, Vector<int32_t>());
+ }
+ newType2PIDs.editValueFor(infos[i].mType).push_back(infos[i].mPID);
+ }
+
+ // we can recover if the number of streams for each type hasn't changed
+ if (oldType2PIDs.size() == newType2PIDs.size()) {
+ success = true;
+ for (i = 0; i < oldType2PIDs.size(); ++i) {
+ // KeyedVector is sorted, we just compare key and size of each index
+ if (oldType2PIDs.keyAt(i) != newType2PIDs.keyAt(i)
+ || oldType2PIDs[i].size() != newType2PIDs[i].size()) {
+ success = false;
+ break;
+ }
+ }
+ }
+
+ if (success) {
+ // save current streams to temp
+ KeyedVector<int32_t, sp<Stream> > temp;
+ for (i = 0; i < mStreams.size(); ++i) {
+ temp.add(mStreams.keyAt(i), mStreams.editValueAt(i));
+ }
+
+ mStreams.clear();
+ for (i = 0; i < temp.size(); ++i) {
+ // The two checks below shouldn't happen,
+ // we already checked above the stream count matches
+ ssize_t index = newType2PIDs.indexOfKey(temp[i]->type());
+ CHECK(index >= 0);
+ Vector<int32_t> &newPIDs = newType2PIDs.editValueAt(index);
+ CHECK(newPIDs.size() > 0);
+
+ // get the next PID for temp[i]->type() in the new PID map
+ Vector<int32_t>::iterator it = newPIDs.begin();
+
+ // change the PID of the stream, and add it back
+ temp.editValueAt(i)->setPID(*it);
+ mStreams.add(temp[i]->pid(), temp.editValueAt(i));
+
+ // removed the used PID
+ newPIDs.erase(it);
+ }
+ }
+ }
+ return success;
+}
status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
unsigned table_id = br->getBits(8);
@@ -369,39 +440,8 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
}
#endif
- // The only case we can recover from is if we have two streams
- // and they switched PIDs.
-
- bool success = false;
-
- if (mStreams.size() == 2 && infos.size() == 2) {
- const StreamInfo &info1 = infos.itemAt(0);
- const StreamInfo &info2 = infos.itemAt(1);
-
- sp<Stream> s1 = mStreams.editValueAt(0);
- sp<Stream> s2 = mStreams.editValueAt(1);
-
- bool caseA =
- info1.mPID == s1->pid() && info1.mType == s2->type()
- && info2.mPID == s2->pid() && info2.mType == s1->type();
-
- bool caseB =
- info1.mPID == s2->pid() && info1.mType == s1->type()
- && info2.mPID == s1->pid() && info2.mType == s2->type();
-
- if (caseA || caseB) {
- unsigned pid1 = s1->pid();
- unsigned pid2 = s2->pid();
- s1->setPID(pid2);
- s2->setPID(pid1);
-
- mStreams.clear();
- mStreams.add(s1->pid(), s1);
- mStreams.add(s2->pid(), s2);
-
- success = true;
- }
- }
+ // we can recover if number of streams for each type remain the same
+ bool success = switchPIDs(infos);
if (!success) {
ALOGI("Stream PIDs changed and we cannot recover.");
@@ -425,6 +465,32 @@ status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
return OK;
}
+int64_t ATSParser::Program::recoverPTS(uint64_t PTS_33bit) {
+ // We only have the lower 33-bit of the PTS. It could overflow within a
+ // reasonable amount of time. To handle the wrap-around, use fancy math
+ // to get an extended PTS that is within [-0xffffffff, 0xffffffff]
+ // of the latest recovered PTS.
+ if (mLastRecoveredPTS < 0ll) {
+ // Use the original 33bit number for 1st frame, the reason is that
+ // if 1st frame wraps to negative that's far away from 0, we could
+ // never start. Only start wrapping around from 2nd frame.
+ mLastRecoveredPTS = static_cast<int64_t>(PTS_33bit);
+ } else {
+ mLastRecoveredPTS = static_cast<int64_t>(
+ ((mLastRecoveredPTS - PTS_33bit + 0x100000000ll)
+ & 0xfffffffe00000000ull) | PTS_33bit);
+ // We start from 0, but recovered PTS could be slightly below 0.
+ // Clamp it to 0 as rest of the pipeline doesn't take negative pts.
+ // (eg. video is read first and starts at 0, but audio starts at 0xfffffff0)
+ if (mLastRecoveredPTS < 0ll) {
+ ALOGI("Clamping negative recovered PTS (%lld) to 0", mLastRecoveredPTS);
+ mLastRecoveredPTS = 0ll;
+ }
+ }
+
+ return mLastRecoveredPTS;
+}
+
sp<MediaSource> ATSParser::Program::getSource(SourceType type) {
size_t index = (type == AUDIO) ? 0 : 0;
@@ -455,6 +521,8 @@ bool ATSParser::Program::hasSource(SourceType type) const {
}
int64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) {
+ PTS = recoverPTS(PTS);
+
if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) {
if (!mFirstPTSValid) {
mFirstPTSValid = true;
@@ -1098,7 +1166,8 @@ status_t ATSParser::parsePID(
if (payload_unit_start_indicator) {
if (!section->isEmpty()) {
- return ERROR_UNSUPPORTED;
+ ALOGW("parsePID encounters payload_unit_start_indicator when section is not empty");
+ section->clear();
}
unsigned skip = br->getBits(8);
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index f266fe7..bb05417 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -91,13 +91,11 @@ sp<MetaData> AnotherPacketSource::getFormat() {
while (it != mBuffers.end()) {
sp<ABuffer> buffer = *it;
int32_t discontinuity;
- if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
- break;
- }
-
- sp<RefBase> object;
- if (buffer->meta()->findObject("format", &object)) {
- return mFormat = static_cast<MetaData*>(object.get());
+ if (!buffer->meta()->findInt32("discontinuity", &discontinuity)) {
+ sp<RefBase> object;
+ if (buffer->meta()->findObject("format", &object)) {
+ return mFormat = static_cast<MetaData*>(object.get());
+ }
}
++it;
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index be8cf46..07ea605 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -1,10 +1,6 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-ifeq ($(TARGET_DEVICE), manta)
- LOCAL_CFLAGS += -DSURFACE_IS_BGR32
-endif
-
LOCAL_SRC_FILES:= \
FrameDropper.cpp \
GraphicBufferSource.cpp \
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index 7afe699..d81da3f 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -155,7 +155,7 @@ void GraphicBufferSource::omxExecuting() {
if (mLatestBufferId >= 0) {
sp<AMessage> msg =
- new AMessage(kWhatRepeatLastFrame, mReflector->id());
+ new AMessage(kWhatRepeatLastFrame, mReflector);
msg->setInt32("generation", ++mRepeatLastFrameGeneration);
msg->post(mRepeatAfterUs);
@@ -524,7 +524,7 @@ bool GraphicBufferSource::repeatLatestBuffer_l() {
mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;
if (mReflector != NULL) {
- sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector->id());
+ sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector);
msg->setInt32("generation", ++mRepeatLastFrameGeneration);
msg->post(mRepeatAfterUs);
}
@@ -557,7 +557,7 @@ void GraphicBufferSource::setLatestBuffer_l(
mRepeatLastFrameCount = kRepeatLastFrameCount;
if (mReflector != NULL) {
- sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector->id());
+ sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector);
msg->setInt32("generation", ++mRepeatLastFrameGeneration);
msg->post(mRepeatAfterUs);
}
diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
index 7f99dcd..801a1bd 100644
--- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
@@ -58,7 +58,7 @@ OMX_ERRORTYPE SimpleSoftOMXComponent::sendCommand(
OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data) {
CHECK(data == NULL);
- sp<AMessage> msg = new AMessage(kWhatSendCommand, mHandler->id());
+ sp<AMessage> msg = new AMessage(kWhatSendCommand, mHandler);
msg->setInt32("cmd", cmd);
msg->setInt32("param", param);
msg->post();
@@ -307,7 +307,7 @@ OMX_ERRORTYPE SimpleSoftOMXComponent::freeBuffer(
OMX_ERRORTYPE SimpleSoftOMXComponent::emptyThisBuffer(
OMX_BUFFERHEADERTYPE *buffer) {
- sp<AMessage> msg = new AMessage(kWhatEmptyThisBuffer, mHandler->id());
+ sp<AMessage> msg = new AMessage(kWhatEmptyThisBuffer, mHandler);
msg->setPointer("header", buffer);
msg->post();
@@ -316,7 +316,7 @@ OMX_ERRORTYPE SimpleSoftOMXComponent::emptyThisBuffer(
OMX_ERRORTYPE SimpleSoftOMXComponent::fillThisBuffer(
OMX_BUFFERHEADERTYPE *buffer) {
- sp<AMessage> msg = new AMessage(kWhatFillThisBuffer, mHandler->id());
+ sp<AMessage> msg = new AMessage(kWhatFillThisBuffer, mHandler);
msg->setPointer("header", buffer);
msg->post();
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index a6bd824..a86ab74 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -82,7 +82,7 @@ void ARTPConnection::addStream(
size_t index,
const sp<AMessage> &notify,
bool injected) {
- sp<AMessage> msg = new AMessage(kWhatAddStream, id());
+ sp<AMessage> msg = new AMessage(kWhatAddStream, this);
msg->setInt32("rtp-socket", rtpSocket);
msg->setInt32("rtcp-socket", rtcpSocket);
msg->setObject("session-desc", sessionDesc);
@@ -93,7 +93,7 @@ void ARTPConnection::addStream(
}
void ARTPConnection::removeStream(int rtpSocket, int rtcpSocket) {
- sp<AMessage> msg = new AMessage(kWhatRemoveStream, id());
+ sp<AMessage> msg = new AMessage(kWhatRemoveStream, this);
msg->setInt32("rtp-socket", rtpSocket);
msg->setInt32("rtcp-socket", rtcpSocket);
msg->post();
@@ -233,7 +233,7 @@ void ARTPConnection::postPollEvent() {
return;
}
- sp<AMessage> msg = new AMessage(kWhatPollStreams, id());
+ sp<AMessage> msg = new AMessage(kWhatPollStreams, this);
msg->post();
mPollEventPending = true;
@@ -639,7 +639,7 @@ sp<ARTPSource> ARTPConnection::findSource(StreamInfo *info, uint32_t srcId) {
}
void ARTPConnection::injectPacket(int index, const sp<ABuffer> &buffer) {
- sp<AMessage> msg = new AMessage(kWhatInjectPacket, id());
+ sp<AMessage> msg = new AMessage(kWhatInjectPacket, this);
msg->setInt32("index", index);
msg->setBuffer("buffer", buffer);
msg->post();
diff --git a/media/libstagefright/rtsp/ARTPSession.cpp b/media/libstagefright/rtsp/ARTPSession.cpp
index ba4e33c..e5acb06 100644
--- a/media/libstagefright/rtsp/ARTPSession.cpp
+++ b/media/libstagefright/rtsp/ARTPSession.cpp
@@ -82,7 +82,7 @@ status_t ARTPSession::setup(const sp<ASessionDescription> &desc) {
info->mRTPSocket = rtpSocket;
info->mRTCPSocket = rtcpSocket;
- sp<AMessage> notify = new AMessage(kWhatAccessUnitComplete, id());
+ sp<AMessage> notify = new AMessage(kWhatAccessUnitComplete, this);
notify->setSize("track-index", mTracks.size() - 1);
mRTPConn->addStream(
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index e1607bf..56c4aa6 100644
--- a/media/libstagefright/rtsp/ARTPWriter.cpp
+++ b/media/libstagefright/rtsp/ARTPWriter.cpp
@@ -146,7 +146,7 @@ status_t ARTPWriter::start(MetaData * /* params */) {
TRESPASS();
}
- (new AMessage(kWhatStart, mReflector->id()))->post();
+ (new AMessage(kWhatStart, mReflector))->post();
while (!(mFlags & kFlagStarted)) {
mCondition.wait(mLock);
@@ -161,7 +161,7 @@ status_t ARTPWriter::stop() {
return OK;
}
- (new AMessage(kWhatStop, mReflector->id()))->post();
+ (new AMessage(kWhatStop, mReflector))->post();
while (mFlags & kFlagStarted) {
mCondition.wait(mLock);
@@ -213,8 +213,8 @@ void ARTPWriter::onMessageReceived(const sp<AMessage> &msg) {
mCondition.signal();
}
- (new AMessage(kWhatRead, mReflector->id()))->post();
- (new AMessage(kWhatSendSR, mReflector->id()))->post();
+ (new AMessage(kWhatRead, mReflector))->post();
+ (new AMessage(kWhatSendSR, mReflector))->post();
break;
}
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index 60b3aaf..855ffdc 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -68,28 +68,28 @@ ARTSPConnection::~ARTSPConnection() {
}
void ARTSPConnection::connect(const char *url, const sp<AMessage> &reply) {
- sp<AMessage> msg = new AMessage(kWhatConnect, id());
+ sp<AMessage> msg = new AMessage(kWhatConnect, this);
msg->setString("url", url);
msg->setMessage("reply", reply);
msg->post();
}
void ARTSPConnection::disconnect(const sp<AMessage> &reply) {
- sp<AMessage> msg = new AMessage(kWhatDisconnect, id());
+ sp<AMessage> msg = new AMessage(kWhatDisconnect, this);
msg->setMessage("reply", reply);
msg->post();
}
void ARTSPConnection::sendRequest(
const char *request, const sp<AMessage> &reply) {
- sp<AMessage> msg = new AMessage(kWhatSendRequest, id());
+ sp<AMessage> msg = new AMessage(kWhatSendRequest, this);
msg->setString("request", request);
msg->setMessage("reply", reply);
msg->post();
}
void ARTSPConnection::observeBinaryData(const sp<AMessage> &reply) {
- sp<AMessage> msg = new AMessage(kWhatObserveBinaryData, id());
+ sp<AMessage> msg = new AMessage(kWhatObserveBinaryData, this);
msg->setMessage("reply", reply);
msg->post();
}
@@ -286,7 +286,7 @@ void ARTSPConnection::onConnect(const sp<AMessage> &msg) {
if (err < 0) {
if (errno == EINPROGRESS) {
- sp<AMessage> msg = new AMessage(kWhatCompleteConnection, id());
+ sp<AMessage> msg = new AMessage(kWhatCompleteConnection, this);
msg->setMessage("reply", reply);
msg->setInt32("connection-id", mConnectionID);
msg->post();
@@ -523,7 +523,7 @@ void ARTSPConnection::postReceiveReponseEvent() {
return;
}
- sp<AMessage> msg = new AMessage(kWhatReceiveResponse, id());
+ sp<AMessage> msg = new AMessage(kWhatReceiveResponse, this);
msg->post();
mReceiveResponseEventPending = true;
@@ -746,7 +746,7 @@ bool ARTSPConnection::receiveRTSPReponse() {
AString request;
CHECK(reply->findString("original-request", &request));
- sp<AMessage> msg = new AMessage(kWhatSendRequest, id());
+ sp<AMessage> msg = new AMessage(kWhatSendRequest, this);
msg->setMessage("reply", reply);
msg->setString("request", request.c_str(), request.size());
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index 3bf489b..0642343 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -169,10 +169,10 @@ struct MyHandler : public AHandler {
looper()->registerHandler(mConn);
(1 ? mNetLooper : looper())->registerHandler(mRTPConn);
- sp<AMessage> notify = new AMessage('biny', id());
+ sp<AMessage> notify = new AMessage('biny', this);
mConn->observeBinaryData(notify);
- sp<AMessage> reply = new AMessage('conn', id());
+ sp<AMessage> reply = new AMessage('conn', this);
mConn->connect(mOriginalSessionURL.c_str(), reply);
}
@@ -180,10 +180,10 @@ struct MyHandler : public AHandler {
looper()->registerHandler(mConn);
(1 ? mNetLooper : looper())->registerHandler(mRTPConn);
- sp<AMessage> notify = new AMessage('biny', id());
+ sp<AMessage> notify = new AMessage('biny', this);
mConn->observeBinaryData(notify);
- sp<AMessage> reply = new AMessage('sdpl', id());
+ sp<AMessage> reply = new AMessage('sdpl', this);
reply->setObject("description", desc);
mConn->connect(mOriginalSessionURL.c_str(), reply);
}
@@ -210,11 +210,11 @@ struct MyHandler : public AHandler {
}
void disconnect() {
- (new AMessage('abor', id()))->post();
+ (new AMessage('abor', this))->post();
}
void seek(int64_t timeUs) {
- sp<AMessage> msg = new AMessage('seek', id());
+ sp<AMessage> msg = new AMessage('seek', this);
msg->setInt64("time", timeUs);
mPauseGeneration++;
msg->post();
@@ -225,14 +225,14 @@ struct MyHandler : public AHandler {
}
void pause() {
- sp<AMessage> msg = new AMessage('paus', id());
+ sp<AMessage> msg = new AMessage('paus', this);
mPauseGeneration++;
msg->setInt32("pausecheck", mPauseGeneration);
msg->post(kPauseDelayUs);
}
void resume() {
- sp<AMessage> msg = new AMessage('resu', id());
+ sp<AMessage> msg = new AMessage('resu', this);
mPauseGeneration++;
msg->post();
}
@@ -454,10 +454,10 @@ struct MyHandler : public AHandler {
request.append("Accept: application/sdp\r\n");
request.append("\r\n");
- sp<AMessage> reply = new AMessage('desc', id());
+ sp<AMessage> reply = new AMessage('desc', this);
mConn->sendRequest(request.c_str(), reply);
} else {
- (new AMessage('disc', id()))->post();
+ (new AMessage('disc', this))->post();
}
break;
}
@@ -468,10 +468,10 @@ struct MyHandler : public AHandler {
int32_t reconnect;
if (msg->findInt32("reconnect", &reconnect) && reconnect) {
- sp<AMessage> reply = new AMessage('conn', id());
+ sp<AMessage> reply = new AMessage('conn', this);
mConn->connect(mOriginalSessionURL.c_str(), reply);
} else {
- (new AMessage('quit', id()))->post();
+ (new AMessage('quit', this))->post();
}
break;
}
@@ -514,7 +514,7 @@ struct MyHandler : public AHandler {
ALOGI("rewritten session url: '%s'", mSessionURL.c_str());
}
- sp<AMessage> reply = new AMessage('conn', id());
+ sp<AMessage> reply = new AMessage('conn', this);
mConn->connect(mOriginalSessionURL.c_str(), reply);
break;
}
@@ -586,7 +586,7 @@ struct MyHandler : public AHandler {
}
if (result != OK) {
- sp<AMessage> reply = new AMessage('disc', id());
+ sp<AMessage> reply = new AMessage('disc', this);
mConn->disconnect(reply);
}
break;
@@ -631,7 +631,7 @@ struct MyHandler : public AHandler {
}
if (result != OK) {
- sp<AMessage> reply = new AMessage('disc', id());
+ sp<AMessage> reply = new AMessage('disc', this);
mConn->disconnect(reply);
}
break;
@@ -703,7 +703,7 @@ struct MyHandler : public AHandler {
mSessionID.erase(i, mSessionID.size() - i);
}
- sp<AMessage> notify = new AMessage('accu', id());
+ sp<AMessage> notify = new AMessage('accu', this);
notify->setSize("track-index", trackIndex);
i = response->mHeaders.indexOfKey("transport");
@@ -769,10 +769,10 @@ struct MyHandler : public AHandler {
request.append("\r\n");
- sp<AMessage> reply = new AMessage('play', id());
+ sp<AMessage> reply = new AMessage('play', this);
mConn->sendRequest(request.c_str(), reply);
} else {
- sp<AMessage> reply = new AMessage('disc', id());
+ sp<AMessage> reply = new AMessage('disc', this);
mConn->disconnect(reply);
}
break;
@@ -797,7 +797,7 @@ struct MyHandler : public AHandler {
} else {
parsePlayResponse(response);
- sp<AMessage> timeout = new AMessage('tiou', id());
+ sp<AMessage> timeout = new AMessage('tiou', this);
mCheckTimeoutGeneration++;
timeout->setInt32("tioucheck", mCheckTimeoutGeneration);
timeout->post(kStartupTimeoutUs);
@@ -805,7 +805,7 @@ struct MyHandler : public AHandler {
}
if (result != OK) {
- sp<AMessage> reply = new AMessage('disc', id());
+ sp<AMessage> reply = new AMessage('disc', this);
mConn->disconnect(reply);
}
@@ -831,7 +831,7 @@ struct MyHandler : public AHandler {
request.append("\r\n");
request.append("\r\n");
- sp<AMessage> reply = new AMessage('opts', id());
+ sp<AMessage> reply = new AMessage('opts', this);
reply->setInt32("generation", mKeepAliveGeneration);
mConn->sendRequest(request.c_str(), reply);
break;
@@ -894,7 +894,7 @@ struct MyHandler : public AHandler {
mPausing = false;
mSeekable = true;
- sp<AMessage> reply = new AMessage('tear', id());
+ sp<AMessage> reply = new AMessage('tear', this);
int32_t reconnect;
if (msg->findInt32("reconnect", &reconnect) && reconnect) {
@@ -926,7 +926,7 @@ struct MyHandler : public AHandler {
ALOGI("TEARDOWN completed with result %d (%s)",
result, strerror(-result));
- sp<AMessage> reply = new AMessage('disc', id());
+ sp<AMessage> reply = new AMessage('disc', this);
int32_t reconnect;
if (msg->findInt32("reconnect", &reconnect) && reconnect) {
@@ -958,7 +958,7 @@ struct MyHandler : public AHandler {
if (mNumAccessUnitsReceived == 0) {
#if 1
ALOGI("stream ended? aborting.");
- (new AMessage('abor', id()))->post();
+ (new AMessage('abor', this))->post();
break;
#else
ALOGI("haven't seen an AU in a looong time.");
@@ -1077,7 +1077,7 @@ struct MyHandler : public AHandler {
request.append("\r\n");
- sp<AMessage> reply = new AMessage('pau2', id());
+ sp<AMessage> reply = new AMessage('pau2', this);
mConn->sendRequest(request.c_str(), reply);
break;
}
@@ -1114,7 +1114,7 @@ struct MyHandler : public AHandler {
request.append("\r\n");
- sp<AMessage> reply = new AMessage('res2', id());
+ sp<AMessage> reply = new AMessage('res2', this);
mConn->sendRequest(request.c_str(), reply);
break;
}
@@ -1143,7 +1143,7 @@ struct MyHandler : public AHandler {
// Post new timeout in order to make sure to use
// fake timestamps if no new Sender Reports arrive
- sp<AMessage> timeout = new AMessage('tiou', id());
+ sp<AMessage> timeout = new AMessage('tiou', this);
mCheckTimeoutGeneration++;
timeout->setInt32("tioucheck", mCheckTimeoutGeneration);
timeout->post(kStartupTimeoutUs);
@@ -1152,7 +1152,7 @@ struct MyHandler : public AHandler {
if (result != OK) {
ALOGE("resume failed, aborting.");
- (new AMessage('abor', id()))->post();
+ (new AMessage('abor', this))->post();
}
mPausing = false;
@@ -1180,7 +1180,7 @@ struct MyHandler : public AHandler {
mCheckPending = true;
++mCheckGeneration;
- sp<AMessage> reply = new AMessage('see1', id());
+ sp<AMessage> reply = new AMessage('see1', this);
reply->setInt64("time", timeUs);
if (mPausing) {
@@ -1221,7 +1221,7 @@ struct MyHandler : public AHandler {
// Start new timeoutgeneration to avoid getting timeout
// before PLAY response arrive
- sp<AMessage> timeout = new AMessage('tiou', id());
+ sp<AMessage> timeout = new AMessage('tiou', this);
mCheckTimeoutGeneration++;
timeout->setInt32("tioucheck", mCheckTimeoutGeneration);
timeout->post(kStartupTimeoutUs);
@@ -1243,7 +1243,7 @@ struct MyHandler : public AHandler {
request.append("\r\n");
- sp<AMessage> reply = new AMessage('see2', id());
+ sp<AMessage> reply = new AMessage('see2', this);
mConn->sendRequest(request.c_str(), reply);
break;
}
@@ -1277,7 +1277,7 @@ struct MyHandler : public AHandler {
// Post new timeout in order to make sure to use
// fake timestamps if no new Sender Reports arrive
- sp<AMessage> timeout = new AMessage('tiou', id());
+ sp<AMessage> timeout = new AMessage('tiou', this);
mCheckTimeoutGeneration++;
timeout->setInt32("tioucheck", mCheckTimeoutGeneration);
timeout->post(kStartupTimeoutUs);
@@ -1293,7 +1293,7 @@ struct MyHandler : public AHandler {
if (result != OK) {
ALOGE("seek failed, aborting.");
- (new AMessage('abor', id()))->post();
+ (new AMessage('abor', this))->post();
}
mPausing = false;
@@ -1343,12 +1343,12 @@ struct MyHandler : public AHandler {
mTryTCPInterleaving = true;
- sp<AMessage> msg = new AMessage('abor', id());
+ sp<AMessage> msg = new AMessage('abor', this);
msg->setInt32("reconnect", true);
msg->post();
} else {
ALOGW("Never received any data, disconnecting.");
- (new AMessage('abor', id()))->post();
+ (new AMessage('abor', this))->post();
}
} else {
if (!mAllTracksHaveTime) {
@@ -1369,7 +1369,7 @@ struct MyHandler : public AHandler {
}
void postKeepAlive() {
- sp<AMessage> msg = new AMessage('aliv', id());
+ sp<AMessage> msg = new AMessage('aliv', this);
msg->setInt32("generation", mKeepAliveGeneration);
msg->post((mKeepAliveTimeoutUs * 9) / 10);
}
@@ -1380,7 +1380,7 @@ struct MyHandler : public AHandler {
}
mCheckPending = true;
- sp<AMessage> check = new AMessage('chek', id());
+ sp<AMessage> check = new AMessage('chek', this);
check->setInt32("generation", mCheckGeneration);
check->post(kAccessUnitTimeoutUs);
}
@@ -1566,7 +1566,7 @@ private:
if (source->initCheck() != OK) {
ALOGW("Unsupported format. Ignoring track #%d.", index);
- sp<AMessage> reply = new AMessage('setu', id());
+ sp<AMessage> reply = new AMessage('setu', this);
reply->setSize("index", index);
reply->setInt32("result", ERROR_UNSUPPORTED);
reply->post();
@@ -1652,7 +1652,7 @@ private:
request.append("\r\n");
- sp<AMessage> reply = new AMessage('setu', id());
+ sp<AMessage> reply = new AMessage('setu', this);
reply->setSize("index", index);
reply->setSize("track-index", mTracks.size() - 1);
mConn->sendRequest(request.c_str(), reply);
diff --git a/media/libstagefright/rtsp/MyTransmitter.h b/media/libstagefright/rtsp/MyTransmitter.h
index 009a3b1..369f276 100644
--- a/media/libstagefright/rtsp/MyTransmitter.h
+++ b/media/libstagefright/rtsp/MyTransmitter.h
@@ -100,7 +100,7 @@ struct MyTransmitter : public AHandler {
mLooper->registerHandler(this);
mLooper->registerHandler(mConn);
- sp<AMessage> reply = new AMessage('conn', id());
+ sp<AMessage> reply = new AMessage('conn', this);
mConn->connect(mServerURL.c_str(), reply);
#ifdef ANDROID
@@ -229,7 +229,7 @@ struct MyTransmitter : public AHandler {
request.append("\r\n");
request.append(sdp);
- sp<AMessage> reply = new AMessage('anno', id());
+ sp<AMessage> reply = new AMessage('anno', this);
mConn->sendRequest(request.c_str(), reply);
}
@@ -350,7 +350,7 @@ struct MyTransmitter : public AHandler {
<< result << " (" << strerror(-result) << ")";
if (result != OK) {
- (new AMessage('quit', id()))->post();
+ (new AMessage('quit', this))->post();
break;
}
@@ -381,7 +381,7 @@ struct MyTransmitter : public AHandler {
if (response->mStatusCode == 401) {
if (mAuthType != NONE) {
LOG(INFO) << "FAILED to authenticate";
- (new AMessage('quit', id()))->post();
+ (new AMessage('quit', this))->post();
break;
}
@@ -391,14 +391,14 @@ struct MyTransmitter : public AHandler {
}
if (result != OK || response->mStatusCode != 200) {
- (new AMessage('quit', id()))->post();
+ (new AMessage('quit', this))->post();
break;
}
unsigned rtpPort;
ARTPConnection::MakePortPair(&mRTPSocket, &mRTCPSocket, &rtpPort);
- // (new AMessage('poll', id()))->post();
+ // (new AMessage('poll', this))->post();
AString request;
request.append("SETUP ");
@@ -414,7 +414,7 @@ struct MyTransmitter : public AHandler {
request.append(";mode=record\r\n");
request.append("\r\n");
- sp<AMessage> reply = new AMessage('setu', id());
+ sp<AMessage> reply = new AMessage('setu', this);
mConn->sendRequest(request.c_str(), reply);
break;
}
@@ -468,7 +468,7 @@ struct MyTransmitter : public AHandler {
}
if (result != OK || response->mStatusCode != 200) {
- (new AMessage('quit', id()))->post();
+ (new AMessage('quit', this))->post();
break;
}
@@ -535,7 +535,7 @@ struct MyTransmitter : public AHandler {
request.append("\r\n");
request.append("\r\n");
- sp<AMessage> reply = new AMessage('reco', id());
+ sp<AMessage> reply = new AMessage('reco', this);
mConn->sendRequest(request.c_str(), reply);
break;
}
@@ -558,13 +558,13 @@ struct MyTransmitter : public AHandler {
}
if (result != OK) {
- (new AMessage('quit', id()))->post();
+ (new AMessage('quit', this))->post();
break;
}
- (new AMessage('more', id()))->post();
- (new AMessage('sr ', id()))->post();
- (new AMessage('aliv', id()))->post(30000000ll);
+ (new AMessage('more', this))->post();
+ (new AMessage('sr ', this))->post();
+ (new AMessage('aliv', this))->post(30000000ll);
break;
}
@@ -586,7 +586,7 @@ struct MyTransmitter : public AHandler {
request.append("\r\n");
request.append("\r\n");
- sp<AMessage> reply = new AMessage('opts', id());
+ sp<AMessage> reply = new AMessage('opts', this);
mConn->sendRequest(request.c_str(), reply);
break;
}
@@ -603,7 +603,7 @@ struct MyTransmitter : public AHandler {
break;
}
- (new AMessage('aliv', id()))->post(30000000ll);
+ (new AMessage('aliv', this))->post(30000000ll);
break;
}
@@ -702,7 +702,7 @@ struct MyTransmitter : public AHandler {
request.append("\r\n");
request.append("\r\n");
- sp<AMessage> reply = new AMessage('paus', id());
+ sp<AMessage> reply = new AMessage('paus', this);
mConn->sendRequest(request.c_str(), reply);
}
break;
@@ -753,7 +753,7 @@ struct MyTransmitter : public AHandler {
request.append("\r\n");
request.append("\r\n");
- sp<AMessage> reply = new AMessage('tear', id());
+ sp<AMessage> reply = new AMessage('tear', this);
mConn->sendRequest(request.c_str(), reply);
break;
}
@@ -775,7 +775,7 @@ struct MyTransmitter : public AHandler {
CHECK(response != NULL);
}
- (new AMessage('quit', id()))->post();
+ (new AMessage('quit', this))->post();
break;
}
@@ -784,14 +784,14 @@ struct MyTransmitter : public AHandler {
LOG(INFO) << "disconnect completed";
mConnected = false;
- (new AMessage('quit', id()))->post();
+ (new AMessage('quit', this))->post();
break;
}
case 'quit':
{
if (mConnected) {
- mConn->disconnect(new AMessage('disc', id()));
+ mConn->disconnect(new AMessage('disc', this));
break;
}
diff --git a/media/libstagefright/rtsp/SDPLoader.cpp b/media/libstagefright/rtsp/SDPLoader.cpp
index a24eb69..0f46c83 100644
--- a/media/libstagefright/rtsp/SDPLoader.cpp
+++ b/media/libstagefright/rtsp/SDPLoader.cpp
@@ -51,7 +51,7 @@ SDPLoader::SDPLoader(
void SDPLoader::load(const char *url, const KeyedVector<String8, String8> *headers) {
mNetLooper->registerHandler(this);
- sp<AMessage> msg = new AMessage(kWhatLoad, id());
+ sp<AMessage> msg = new AMessage(kWhatLoad, this);
msg->setString("url", url);
if (headers != NULL) {
diff --git a/media/libstagefright/rtsp/UDPPusher.cpp b/media/libstagefright/rtsp/UDPPusher.cpp
index 47ea6f1..5c685a1 100644
--- a/media/libstagefright/rtsp/UDPPusher.cpp
+++ b/media/libstagefright/rtsp/UDPPusher.cpp
@@ -65,7 +65,7 @@ void UDPPusher::start() {
mFirstTimeMs = fromlel(timeMs);
mFirstTimeUs = ALooper::GetNowUs();
- (new AMessage(kWhatPush, id()))->post();
+ (new AMessage(kWhatPush, this))->post();
}
bool UDPPusher::onPush() {
@@ -103,7 +103,7 @@ bool UDPPusher::onPush() {
timeMs -= mFirstTimeMs;
int64_t whenUs = mFirstTimeUs + timeMs * 1000ll;
int64_t nowUs = ALooper::GetNowUs();
- (new AMessage(kWhatPush, id()))->post(whenUs - nowUs);
+ (new AMessage(kWhatPush, this))->post(whenUs - nowUs);
return true;
}
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.cpp b/media/libstagefright/timedtext/TimedTextPlayer.cpp
index a070487..aecf666 100644
--- a/media/libstagefright/timedtext/TimedTextPlayer.cpp
+++ b/media/libstagefright/timedtext/TimedTextPlayer.cpp
@@ -56,25 +56,25 @@ TimedTextPlayer::~TimedTextPlayer() {
}
void TimedTextPlayer::start() {
- (new AMessage(kWhatStart, id()))->post();
+ (new AMessage(kWhatStart, this))->post();
}
void TimedTextPlayer::pause() {
- (new AMessage(kWhatPause, id()))->post();
+ (new AMessage(kWhatPause, this))->post();
}
void TimedTextPlayer::resume() {
- (new AMessage(kWhatResume, id()))->post();
+ (new AMessage(kWhatResume, this))->post();
}
void TimedTextPlayer::seekToAsync(int64_t timeUs) {
- sp<AMessage> msg = new AMessage(kWhatSeek, id());
+ sp<AMessage> msg = new AMessage(kWhatSeek, this);
msg->setInt64("seekTimeUs", timeUs);
msg->post();
}
void TimedTextPlayer::setDataSource(sp<TimedTextSource> source) {
- sp<AMessage> msg = new AMessage(kWhatSetSource, id());
+ sp<AMessage> msg = new AMessage(kWhatSetSource, this);
msg->setObject("source", source);
msg->post();
}
@@ -231,7 +231,7 @@ void TimedTextPlayer::doRead(MediaSource::ReadOptions* options) {
status_t err = mSource->read(&startTimeUs, &endTimeUs,
&(parcelEvent->parcel), options);
if (err == WOULD_BLOCK) {
- sp<AMessage> msg = new AMessage(kWhatRetryRead, id());
+ sp<AMessage> msg = new AMessage(kWhatRetryRead, this);
if (options != NULL) {
int64_t seekTimeUs = kInvalidTimeUs;
MediaSource::ReadOptions::SeekMode seekMode =
@@ -259,7 +259,7 @@ void TimedTextPlayer::doRead(MediaSource::ReadOptions* options) {
void TimedTextPlayer::postTextEvent(const sp<ParcelEvent>& parcel, int64_t timeUs) {
int64_t delayUs = delayUsFromCurrentTime(timeUs);
- sp<AMessage> msg = new AMessage(kWhatSendSubtitle, id());
+ sp<AMessage> msg = new AMessage(kWhatSendSubtitle, this);
msg->setInt32("generation", mSendSubtitleGeneration);
if (parcel != NULL) {
msg->setObject("subtitle", parcel);
diff --git a/media/libstagefright/wifi-display/MediaSender.cpp b/media/libstagefright/wifi-display/MediaSender.cpp
index b1cdec0..6f0087f 100644
--- a/media/libstagefright/wifi-display/MediaSender.cpp
+++ b/media/libstagefright/wifi-display/MediaSender.cpp
@@ -121,7 +121,7 @@ status_t MediaSender::initAsync(
}
if (err == OK) {
- sp<AMessage> notify = new AMessage(kWhatSenderNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatSenderNotify, this);
notify->setInt32("generation", mGeneration);
mTSSender = new RTPSender(mNetSession, notify);
looper()->registerHandler(mTSSender);
@@ -170,7 +170,7 @@ status_t MediaSender::initAsync(
return INVALID_OPERATION;
}
- sp<AMessage> notify = new AMessage(kWhatSenderNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatSenderNotify, this);
notify->setInt32("generation", mGeneration);
notify->setSize("trackIndex", trackIndex);
diff --git a/media/libstagefright/wifi-display/rtp/RTPSender.cpp b/media/libstagefright/wifi-display/rtp/RTPSender.cpp
index e88a3bd..4e72533 100644
--- a/media/libstagefright/wifi-display/rtp/RTPSender.cpp
+++ b/media/libstagefright/wifi-display/rtp/RTPSender.cpp
@@ -95,11 +95,11 @@ status_t RTPSender::initAsync(
return INVALID_OPERATION;
}
- sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
+ sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, this);
sp<AMessage> rtcpNotify;
if (remoteRTCPPort >= 0) {
- rtcpNotify = new AMessage(kWhatRTCPNotify, id());
+ rtcpNotify = new AMessage(kWhatRTCPNotify, this);
}
CHECK_EQ(mRTPSessionID, 0);
diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp
index 2834a66..8368945 100644
--- a/media/libstagefright/wifi-display/source/Converter.cpp
+++ b/media/libstagefright/wifi-display/source/Converter.cpp
@@ -93,7 +93,7 @@ Converter::~Converter() {
void Converter::shutdownAsync() {
ALOGV("shutdown");
- (new AMessage(kWhatShutdown, id()))->post();
+ (new AMessage(kWhatShutdown, this))->post();
}
status_t Converter::init() {
@@ -482,11 +482,11 @@ void Converter::scheduleDoMoreWork() {
#if 1
if (mEncoderActivityNotify == NULL) {
- mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, id());
+ mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, this);
}
mEncoder->requestActivityNotification(mEncoderActivityNotify->dup());
#else
- sp<AMessage> notify = new AMessage(kWhatEncoderActivity, id());
+ sp<AMessage> notify = new AMessage(kWhatEncoderActivity, this);
notify->setInt64("whenUs", ALooper::GetNowUs());
mEncoder->requestActivityNotification(notify);
#endif
@@ -731,8 +731,7 @@ status_t Converter::doMoreWork() {
// MediaSender will post the following message when HDCP
// is done, to release the output buffer back to encoder.
- sp<AMessage> notify(new AMessage(
- kWhatReleaseOutputBuffer, id()));
+ sp<AMessage> notify(new AMessage(kWhatReleaseOutputBuffer, this));
notify->setInt32("bufferIndex", bufferIndex);
buffer = new ABuffer(
@@ -787,18 +786,18 @@ status_t Converter::doMoreWork() {
}
void Converter::requestIDRFrame() {
- (new AMessage(kWhatRequestIDRFrame, id()))->post();
+ (new AMessage(kWhatRequestIDRFrame, this))->post();
}
void Converter::dropAFrame() {
// Unsupported in surface input mode.
CHECK(!(mFlags & FLAG_USE_SURFACE_INPUT));
- (new AMessage(kWhatDropAFrame, id()))->post();
+ (new AMessage(kWhatDropAFrame, this))->post();
}
void Converter::suspendEncoding(bool suspend) {
- sp<AMessage> msg = new AMessage(kWhatSuspendEncoding, id());
+ sp<AMessage> msg = new AMessage(kWhatSuspendEncoding, this);
msg->setInt32("suspend", suspend);
msg->post();
}
diff --git a/media/libstagefright/wifi-display/source/MediaPuller.cpp b/media/libstagefright/wifi-display/source/MediaPuller.cpp
index 86b918f..ce07a4e 100644
--- a/media/libstagefright/wifi-display/source/MediaPuller.cpp
+++ b/media/libstagefright/wifi-display/source/MediaPuller.cpp
@@ -63,21 +63,21 @@ status_t MediaPuller::postSynchronouslyAndReturnError(
}
status_t MediaPuller::start() {
- return postSynchronouslyAndReturnError(new AMessage(kWhatStart, id()));
+ return postSynchronouslyAndReturnError(new AMessage(kWhatStart, this));
}
void MediaPuller::stopAsync(const sp<AMessage> &notify) {
- sp<AMessage> msg = new AMessage(kWhatStop, id());
+ sp<AMessage> msg = new AMessage(kWhatStop, this);
msg->setMessage("notify", notify);
msg->post();
}
void MediaPuller::pause() {
- (new AMessage(kWhatPause, id()))->post();
+ (new AMessage(kWhatPause, this))->post();
}
void MediaPuller::resume() {
- (new AMessage(kWhatResume, id()))->post();
+ (new AMessage(kWhatResume, this))->post();
}
void MediaPuller::onMessageReceived(const sp<AMessage> &msg) {
@@ -105,7 +105,7 @@ void MediaPuller::onMessageReceived(const sp<AMessage> &msg) {
sp<AMessage> response = new AMessage;
response->setInt32("err", err);
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
response->postReply(replyID);
break;
@@ -215,7 +215,7 @@ void MediaPuller::onMessageReceived(const sp<AMessage> &msg) {
}
void MediaPuller::schedulePull() {
- sp<AMessage> msg = new AMessage(kWhatPull, id());
+ sp<AMessage> msg = new AMessage(kWhatPull, this);
msg->setInt32("generation", mPullGeneration);
msg->post();
}
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index 2cb4786..6080943 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -214,7 +214,7 @@ void WifiDisplaySource::PlaybackSession::Track::stopAsync() {
mConverter->shutdownAsync();
}
- sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id());
+ sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, this);
if (mStarted && mMediaPuller != NULL) {
if (mRepeaterSource != NULL) {
@@ -382,7 +382,7 @@ status_t WifiDisplaySource::PlaybackSession::init(
size_t videoResolutionIndex,
VideoFormats::ProfileType videoProfileType,
VideoFormats::LevelType videoLevelType) {
- sp<AMessage> notify = new AMessage(kWhatMediaSenderNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatMediaSenderNotify, this);
mMediaSender = new MediaSender(mNetSession, notify);
looper()->registerHandler(mMediaSender);
@@ -440,7 +440,7 @@ void WifiDisplaySource::PlaybackSession::updateLiveness() {
status_t WifiDisplaySource::PlaybackSession::play() {
updateLiveness();
- (new AMessage(kWhatResume, id()))->post();
+ (new AMessage(kWhatResume, this))->post();
return OK;
}
@@ -460,7 +460,7 @@ status_t WifiDisplaySource::PlaybackSession::onMediaSenderInitialized() {
status_t WifiDisplaySource::PlaybackSession::pause() {
updateLiveness();
- (new AMessage(kWhatPause, id()))->post();
+ (new AMessage(kWhatPause, this))->post();
return OK;
}
@@ -786,7 +786,7 @@ status_t WifiDisplaySource::PlaybackSession::setupMediaPacketizer(
size_t trackIndex = mTracks.size();
- sp<AMessage> notify = new AMessage(kWhatTrackNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatTrackNotify, this);
notify->setSize("trackIndex", trackIndex);
sp<Track> track = new Track(notify, format);
@@ -833,7 +833,7 @@ void WifiDisplaySource::PlaybackSession::schedulePullExtractor() {
int64_t whenUs = sampleTimeUs - mFirstSampleTimeUs + mFirstSampleTimeRealUs;
- sp<AMessage> msg = new AMessage(kWhatPullExtractorSample, id());
+ sp<AMessage> msg = new AMessage(kWhatPullExtractorSample, this);
msg->setInt32("generation", mPullExtractorGeneration);
msg->post(whenUs - nowUs);
@@ -857,7 +857,7 @@ void WifiDisplaySource::PlaybackSession::onPullExtractor() {
size_t trackIndex;
CHECK_EQ((status_t)OK, mExtractor->getSampleTrackIndex(&trackIndex));
- sp<AMessage> msg = new AMessage(kWhatConverterNotify, id());
+ sp<AMessage> msg = new AMessage(kWhatConverterNotify, this);
msg->setSize(
"trackIndex", mExtractorTrackToInternalTrack.valueFor(trackIndex));
@@ -955,7 +955,7 @@ status_t WifiDisplaySource::PlaybackSession::addSource(
? MEDIA_MIMETYPE_AUDIO_RAW : MEDIA_MIMETYPE_AUDIO_AAC);
}
- notify = new AMessage(kWhatConverterNotify, id());
+ notify = new AMessage(kWhatConverterNotify, this);
notify->setSize("trackIndex", trackIndex);
sp<Converter> converter = new Converter(notify, codecLooper, format);
@@ -970,7 +970,7 @@ status_t WifiDisplaySource::PlaybackSession::addSource(
return err;
}
- notify = new AMessage(Converter::kWhatMediaPullerNotify, converter->id());
+ notify = new AMessage(Converter::kWhatMediaPullerNotify, converter);
notify->setSize("trackIndex", trackIndex);
sp<MediaPuller> puller = new MediaPuller(source, notify);
@@ -980,7 +980,7 @@ status_t WifiDisplaySource::PlaybackSession::addSource(
*numInputBuffers = converter->getInputBufferCount();
}
- notify = new AMessage(kWhatTrackNotify, id());
+ notify = new AMessage(kWhatTrackNotify, this);
notify->setSize("trackIndex", trackIndex);
sp<Track> track = new Track(
diff --git a/media/libstagefright/wifi-display/source/RepeaterSource.cpp b/media/libstagefright/wifi-display/source/RepeaterSource.cpp
index 59d7e6e..af6b663 100644
--- a/media/libstagefright/wifi-display/source/RepeaterSource.cpp
+++ b/media/libstagefright/wifi-display/source/RepeaterSource.cpp
@@ -173,7 +173,7 @@ status_t RepeaterSource::read(
}
void RepeaterSource::postRead() {
- (new AMessage(kWhatRead, mReflector->id()))->post();
+ (new AMessage(kWhatRead, mReflector))->post();
}
void RepeaterSource::onMessageReceived(const sp<AMessage> &msg) {
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index 7eb8b73..14d0951 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -57,7 +57,7 @@ WifiDisplaySource::WifiDisplaySource(
mNetSession(netSession),
mClient(client),
mSessionID(0),
- mStopReplyID(0),
+ mStopReplyID(NULL),
mChosenRTPPort(-1),
mUsingPCMAudio(false),
mClientSessionID(0),
@@ -106,7 +106,7 @@ static status_t PostAndAwaitResponse(
status_t WifiDisplaySource::start(const char *iface) {
CHECK_EQ(mState, INITIALIZED);
- sp<AMessage> msg = new AMessage(kWhatStart, id());
+ sp<AMessage> msg = new AMessage(kWhatStart, this);
msg->setString("iface", iface);
sp<AMessage> response;
@@ -114,21 +114,21 @@ status_t WifiDisplaySource::start(const char *iface) {
}
status_t WifiDisplaySource::stop() {
- sp<AMessage> msg = new AMessage(kWhatStop, id());
+ sp<AMessage> msg = new AMessage(kWhatStop, this);
sp<AMessage> response;
return PostAndAwaitResponse(msg, &response);
}
status_t WifiDisplaySource::pause() {
- sp<AMessage> msg = new AMessage(kWhatPause, id());
+ sp<AMessage> msg = new AMessage(kWhatPause, this);
sp<AMessage> response;
return PostAndAwaitResponse(msg, &response);
}
status_t WifiDisplaySource::resume() {
- sp<AMessage> msg = new AMessage(kWhatResume, id());
+ sp<AMessage> msg = new AMessage(kWhatResume, this);
sp<AMessage> response;
return PostAndAwaitResponse(msg, &response);
@@ -138,7 +138,7 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
case kWhatStart:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
AString iface;
@@ -167,7 +167,7 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
if (err == OK) {
if (inet_aton(iface.c_str(), &mInterfaceAddr) != 0) {
- sp<AMessage> notify = new AMessage(kWhatRTSPNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatRTSPNotify, this);
err = mNetSession->createRTSPServer(
mInterfaceAddr, port, notify, &mSessionID);
@@ -310,7 +310,7 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
if (err == OK) {
mState = AWAITING_CLIENT_TEARDOWN;
- (new AMessage(kWhatTeardownTriggerTimedOut, id()))->post(
+ (new AMessage(kWhatTeardownTriggerTimedOut, this))->post(
kTeardownTriggerTimeouSecs * 1000000ll);
break;
@@ -325,7 +325,7 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
case kWhatPause:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
status_t err = OK;
@@ -345,7 +345,7 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
case kWhatResume:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
status_t err = OK;
@@ -492,7 +492,7 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
if (mState == AWAITING_CLIENT_TEARDOWN) {
ALOGI("TEARDOWN trigger timed out, forcing disconnection.");
- CHECK_NE(mStopReplyID, 0);
+ CHECK(mStopReplyID != NULL);
finishStop();
break;
}
@@ -529,7 +529,7 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
// HDCPObserver::notify is completely handled before
// we clear the HDCP instance and unload the shared
// library :(
- (new AMessage(kWhatFinishStop2, id()))->post(300000ll);
+ (new AMessage(kWhatFinishStop2, this))->post(300000ll);
break;
}
@@ -1027,7 +1027,7 @@ void WifiDisplaySource::scheduleReaper() {
}
mReaperPending = true;
- (new AMessage(kWhatReapDeadClients, id()))->post(kReaperIntervalUs);
+ (new AMessage(kWhatReapDeadClients, this))->post(kReaperIntervalUs);
}
void WifiDisplaySource::scheduleKeepAlive(int32_t sessionID) {
@@ -1035,7 +1035,7 @@ void WifiDisplaySource::scheduleKeepAlive(int32_t sessionID) {
// expire, make sure the timeout is greater than 5 secs to begin with.
CHECK_GT(kPlaybackSessionTimeoutUs, 5000000ll);
- sp<AMessage> msg = new AMessage(kWhatKeepAlive, id());
+ sp<AMessage> msg = new AMessage(kWhatKeepAlive, this);
msg->setInt32("sessionID", sessionID);
msg->post(kPlaybackSessionTimeoutUs - 5000000ll);
}
@@ -1239,7 +1239,7 @@ status_t WifiDisplaySource::onSetupRequest(
int32_t playbackSessionID = makeUniquePlaybackSessionID();
- sp<AMessage> notify = new AMessage(kWhatPlaybackSessionNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatPlaybackSessionNotify, this);
notify->setInt32("playbackSessionID", playbackSessionID);
notify->setInt32("sessionID", sessionID);
@@ -1470,7 +1470,7 @@ status_t WifiDisplaySource::onTeardownRequest(
mNetSession->sendRequest(sessionID, response.c_str());
if (mState == AWAITING_CLIENT_TEARDOWN) {
- CHECK_NE(mStopReplyID, 0);
+ CHECK(mStopReplyID != NULL);
finishStop();
} else {
mClient->onDisplayError(IRemoteDisplayClient::kDisplayErrorUnknown);
@@ -1707,7 +1707,7 @@ status_t WifiDisplaySource::makeHDCP() {
return ERROR_UNSUPPORTED;
}
- sp<AMessage> notify = new AMessage(kWhatHDCPNotify, id());
+ sp<AMessage> notify = new AMessage(kWhatHDCPNotify, this);
mHDCPObserver = new HDCPObserver(notify);
status_t err = mHDCP->setObserver(mHDCPObserver);
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
index 750265f..0f779e4 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
@@ -27,6 +27,7 @@
namespace android {
+struct AReplyToken;
struct IHDCP;
struct IRemoteDisplayClient;
struct ParsedMessage;
@@ -121,7 +122,7 @@ private:
struct in_addr mInterfaceAddr;
int32_t mSessionID;
- uint32_t mStopReplyID;
+ sp<AReplyToken> mStopReplyID;
AString mWfdClientRtpPorts;
int32_t mChosenRTPPort; // extracted from "wfd_client_rtp_ports"
diff --git a/media/libstagefright/yuv/YUVImage.cpp b/media/libstagefright/yuv/YUVImage.cpp
index bb3e2fd..c098135 100644
--- a/media/libstagefright/yuv/YUVImage.cpp
+++ b/media/libstagefright/yuv/YUVImage.cpp
@@ -374,13 +374,13 @@ uint8_t clamp(uint8_t v, uint8_t minValue, uint8_t maxValue) {
void YUVImage::yuv2rgb(uint8_t yValue, uint8_t uValue, uint8_t vValue,
uint8_t *r, uint8_t *g, uint8_t *b) const {
- *r = yValue + (1.370705 * (vValue-128));
- *g = yValue - (0.698001 * (vValue-128)) - (0.337633 * (uValue-128));
- *b = yValue + (1.732446 * (uValue-128));
+ int rTmp = yValue + (1.370705 * (vValue-128));
+ int gTmp = yValue - (0.698001 * (vValue-128)) - (0.337633 * (uValue-128));
+ int bTmp = yValue + (1.732446 * (uValue-128));
- *r = clamp(*r, 0, 255);
- *g = clamp(*g, 0, 255);
- *b = clamp(*b, 0, 255);
+ *r = clamp(rTmp, 0, 255);
+ *g = clamp(gTmp, 0, 255);
+ *b = clamp(bTmp, 0, 255);
}
bool YUVImage::writeToPPM(const char *filename) const {
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index 3124e4a..80c1c2f 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -116,7 +116,7 @@ void CodecHandler::onMessageReceived(const sp<AMessage> &msg) {
case kWhatStopActivityNotifications:
{
- uint32_t replyID;
+ sp<AReplyToken> replyID;
msg->senderAwaitsResponse(&replyID);
mCodec->mGeneration++;
@@ -136,7 +136,7 @@ void CodecHandler::onMessageReceived(const sp<AMessage> &msg) {
static void requestActivityNotification(AMediaCodec *codec) {
- (new AMessage(kWhatRequestActivityNotifications, codec->mHandler->id()))->post();
+ (new AMessage(kWhatRequestActivityNotifications, codec->mHandler))->post();
}
extern "C" {
@@ -219,7 +219,7 @@ media_status_t AMediaCodec_start(AMediaCodec *mData) {
if (ret != OK) {
return translate_error(ret);
}
- mData->mActivityNotification = new AMessage(kWhatActivityNotify, mData->mHandler->id());
+ mData->mActivityNotification = new AMessage(kWhatActivityNotify, mData->mHandler);
mData->mActivityNotification->setInt32("generation", mData->mGeneration);
requestActivityNotification(mData);
return AMEDIA_OK;
@@ -229,7 +229,7 @@ EXPORT
media_status_t AMediaCodec_stop(AMediaCodec *mData) {
media_status_t ret = translate_error(mData->mCodec->stop());
- sp<AMessage> msg = new AMessage(kWhatStopActivityNotifications, mData->mHandler->id());
+ sp<AMessage> msg = new AMessage(kWhatStopActivityNotifications, mData->mHandler);
sp<AMessage> response;
msg->postAndAwaitResponse(&response);
mData->mActivityNotification.clear();