Merge "Add template class StateQueue"
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index 8ba0203..746f506 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -34,21 +34,7 @@
static Vector<uid_t> trustedUids;
static bool isProtectedCallAllowed() {
- // TODO
- // Following implementation is just for reference.
- // Each OEM manufacturer should implement/replace with their own solutions.
- bool result = false;
-
- IPCThreadState* ipcState = IPCThreadState::self();
- uid_t uid = ipcState->getCallingUid();
-
- for (unsigned int i = 0; i < trustedUids.size(); ++i) {
- if (trustedUids[i] == uid) {
- result = true;
- break;
- }
- }
- return result;
+ return true;
}
void DrmManagerService::instantiate() {
diff --git a/include/media/stagefright/timedtext/TimedTextDriver.h b/include/media/stagefright/timedtext/TimedTextDriver.h
index e3ca536..1c5fd36 100644
--- a/include/media/stagefright/timedtext/TimedTextDriver.h
+++ b/include/media/stagefright/timedtext/TimedTextDriver.h
@@ -40,18 +40,24 @@
status_t start();
status_t pause();
- status_t selectTrack(int32_t index);
- status_t unselectTrack(int32_t index);
+ status_t selectTrack(size_t index);
+ status_t unselectTrack(size_t index);
status_t seekToAsync(int64_t timeUs);
- status_t addInBandTextSource(const sp<MediaSource>& source);
- status_t addOutOfBandTextSource(const char *uri, const char *mimeType);
+ status_t addInBandTextSource(
+ size_t trackIndex, const sp<MediaSource>& source);
+
+ status_t addOutOfBandTextSource(
+ size_t trackIndex, const char *uri, const char *mimeType);
+
// Caller owns the file desriptor and caller is responsible for closing it.
status_t addOutOfBandTextSource(
- int fd, off64_t offset, off64_t length, const char *mimeType);
+ size_t trackIndex, int fd, off64_t offset,
+ off64_t length, const char *mimeType);
- void getTrackInfo(Parcel *parcel);
+ void getExternalTrackInfo(Parcel *parcel);
+ size_t countExternalTracks() const;
private:
Mutex mLock;
@@ -68,13 +74,17 @@
// Variables to be guarded by mLock.
State mState;
- int32_t mCurrentTrackIndex;
- Vector<sp<TimedTextSource> > mTextSourceVector;
+ size_t mCurrentTrackIndex;
+ KeyedVector<size_t, sp<TimedTextSource> > mTextSourceVector;
+ Vector<bool> mTextSourceTypeVector;
+
// -- End of variables to be guarded by mLock
- status_t selectTrack_l(int32_t index);
+ status_t selectTrack_l(size_t index);
+
status_t createOutOfBandTextSource(
- const char *mimeType, const sp<DataSource>& dataSource);
+ size_t trackIndex, const char* mimeType,
+ const sp<DataSource>& dataSource);
DISALLOW_EVIL_CONSTRUCTORS(TimedTextDriver);
};
diff --git a/media/libmediaplayerservice/Crypto.cpp b/media/libmediaplayerservice/Crypto.cpp
index 4491f2b..574ae71 100644
--- a/media/libmediaplayerservice/Crypto.cpp
+++ b/media/libmediaplayerservice/Crypto.cpp
@@ -32,6 +32,7 @@
Crypto::Crypto()
: mInitCheck(NO_INIT),
mLibHandle(NULL),
+ mFactory(NULL),
mPlugin(NULL) {
mInitCheck = init();
}
@@ -57,6 +58,8 @@
mLibHandle = dlopen("libdrmdecrypt.so", RTLD_NOW);
if (mLibHandle == NULL) {
+ ALOGE("Unable to locate libdrmdecrypt.so");
+
return ERROR_UNSUPPORTED;
}
@@ -66,6 +69,12 @@
if (createCryptoFactory == NULL
|| ((mFactory = createCryptoFactory()) == NULL)) {
+ if (createCryptoFactory == NULL) {
+ ALOGE("Unable to find symbol 'createCryptoFactory'.");
+ } else {
+ ALOGE("createCryptoFactory() failed.");
+ }
+
dlclose(mLibHandle);
mLibHandle = NULL;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 120a410..b67476b 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -356,6 +356,7 @@
int64_t totalBitRate = 0;
+ mExtractor = extractor;
for (size_t i = 0; i < extractor->countTracks(); ++i) {
sp<MetaData> meta = extractor->getTrackMetaData(i);
@@ -443,7 +444,7 @@
}
}
} else if (!strcasecmp(mime.string(), MEDIA_MIMETYPE_TEXT_3GPP)) {
- addTextSource(extractor->getTrack(i));
+ addTextSource(i, extractor->getTrack(i));
}
}
@@ -507,6 +508,7 @@
mCachedSource.clear();
mAudioTrack.clear();
mVideoTrack.clear();
+ mExtractor.clear();
// Shutdown audio first, so that the respone to the reset request
// appears to happen instantaneously as far as the user is concerned
@@ -1331,7 +1333,7 @@
mAudioTrack = source;
}
-void AwesomePlayer::addTextSource(const sp<MediaSource>& source) {
+void AwesomePlayer::addTextSource(size_t trackIndex, const sp<MediaSource>& source) {
Mutex::Autolock autoLock(mTimedTextLock);
CHECK(source != NULL);
@@ -1339,7 +1341,7 @@
mTextDriver = new TimedTextDriver(mListener);
}
- mTextDriver->addInBandTextSource(source);
+ mTextDriver->addInBandTextSource(trackIndex, source);
}
status_t AwesomePlayer::initAudioDecoder() {
@@ -2254,6 +2256,94 @@
}
}
+status_t AwesomePlayer::getTrackInfo(Parcel *reply) const {
+ Mutex::Autolock autoLock(mTimedTextLock);
+ if (mTextDriver == NULL) {
+ return INVALID_OPERATION;
+ }
+
+ reply->writeInt32(mTextDriver->countExternalTracks() +
+ mExtractor->countTracks());
+ for (size_t i = 0; i < mExtractor->countTracks(); ++i) {
+ sp<MetaData> meta = mExtractor->getTrackMetaData(i);
+
+ const char *_mime;
+ CHECK(meta->findCString(kKeyMIMEType, &_mime));
+
+ String8 mime = String8(_mime);
+
+ reply->writeInt32(2); // 2 fields
+
+ if (!strncasecmp(mime.string(), "video/", 6)) {
+ reply->writeInt32(MEDIA_TRACK_TYPE_VIDEO);
+ } else if (!strncasecmp(mime.string(), "audio/", 6)) {
+ reply->writeInt32(MEDIA_TRACK_TYPE_AUDIO);
+ } else if (!strcasecmp(mime.string(), MEDIA_MIMETYPE_TEXT_3GPP)) {
+ reply->writeInt32(MEDIA_TRACK_TYPE_TIMEDTEXT);
+ } else {
+ reply->writeInt32(MEDIA_TRACK_TYPE_UNKNOWN);
+ }
+
+ const char *lang;
+ if (meta->findCString(kKeyMediaLanguage, &lang)) {
+ reply->writeString16(String16(lang));
+ } else {
+ reply->writeString16(String16(""));
+ }
+ }
+
+ mTextDriver->getExternalTrackInfo(reply);
+ return OK;
+}
+
+// FIXME:
+// At present, only timed text track is able to be selected or unselected.
+status_t AwesomePlayer::selectTrack(size_t trackIndex, bool select) {
+ Mutex::Autolock autoLock(mTimedTextLock);
+ if (mTextDriver == NULL) {
+ return INVALID_OPERATION;
+ }
+
+ if (trackIndex >= mExtractor->countTracks()
+ + mTextDriver->countExternalTracks()) {
+ return BAD_VALUE;
+ }
+
+ if (trackIndex < mExtractor->countTracks()) {
+ sp<MetaData> meta = mExtractor->getTrackMetaData(trackIndex);
+ const char *_mime;
+ CHECK(meta->findCString(kKeyMIMEType, &_mime));
+ String8 mime = String8(_mime);
+
+ if (strcasecmp(mime.string(), MEDIA_MIMETYPE_TEXT_3GPP)) {
+ return ERROR_UNSUPPORTED;
+ }
+ }
+
+ status_t err = OK;
+ if (select) {
+ err = mTextDriver->selectTrack(trackIndex);
+ if (err == OK) {
+ modifyFlags(TEXTPLAYER_INITIALIZED, SET);
+ if (mFlags & PLAYING && !(mFlags & TEXT_RUNNING)) {
+ mTextDriver->start();
+ modifyFlags(TEXT_RUNNING, SET);
+ }
+ }
+ } else {
+ err = mTextDriver->unselectTrack(trackIndex);
+ if (err == OK) {
+ modifyFlags(TEXTPLAYER_INITIALIZED, CLEAR);
+ modifyFlags(TEXT_RUNNING, CLEAR);
+ }
+ }
+ return err;
+}
+
+size_t AwesomePlayer::countTracks() const {
+ return mExtractor->countTracks() + mTextDriver->countExternalTracks();
+}
+
status_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) {
if (NULL == reply) {
return android::BAD_VALUE;
@@ -2266,12 +2356,7 @@
switch(methodId) {
case INVOKE_ID_GET_TRACK_INFO:
{
- Mutex::Autolock autoLock(mTimedTextLock);
- if (mTextDriver == NULL) {
- return INVALID_OPERATION;
- }
- mTextDriver->getTrackInfo(reply);
- return OK;
+ return getTrackInfo(reply);
}
case INVOKE_ID_ADD_EXTERNAL_SOURCE:
{
@@ -2282,7 +2367,8 @@
// String values written in Parcel are UTF-16 values.
String8 uri(request.readString16());
String8 mimeType(request.readString16());
- return mTextDriver->addOutOfBandTextSource(uri, mimeType);
+ size_t nTracks = countTracks();
+ return mTextDriver->addOutOfBandTextSource(nTracks, uri, mimeType);
}
case INVOKE_ID_ADD_EXTERNAL_SOURCE_FD:
{
@@ -2294,40 +2380,19 @@
off64_t offset = request.readInt64();
off64_t length = request.readInt64();
String8 mimeType(request.readString16());
+ size_t nTracks = countTracks();
return mTextDriver->addOutOfBandTextSource(
- fd, offset, length, mimeType);
+ nTracks, fd, offset, length, mimeType);
}
case INVOKE_ID_SELECT_TRACK:
{
- Mutex::Autolock autoLock(mTimedTextLock);
- if (mTextDriver == NULL) {
- return INVALID_OPERATION;
- }
-
- status_t err = mTextDriver->selectTrack(
- request.readInt32());
- if (err == OK) {
- modifyFlags(TEXTPLAYER_INITIALIZED, SET);
- if (mFlags & PLAYING && !(mFlags & TEXT_RUNNING)) {
- mTextDriver->start();
- modifyFlags(TEXT_RUNNING, SET);
- }
- }
- return err;
+ int trackIndex = request.readInt32();
+ return selectTrack(trackIndex, true);
}
case INVOKE_ID_UNSELECT_TRACK:
{
- Mutex::Autolock autoLock(mTimedTextLock);
- if (mTextDriver == NULL) {
- return INVALID_OPERATION;
- }
- status_t err = mTextDriver->unselectTrack(
- request.readInt32());
- if (err == OK) {
- modifyFlags(TEXTPLAYER_INITIALIZED, CLEAR);
- modifyFlags(TEXT_RUNNING, CLEAR);
- }
- return err;
+ int trackIndex = request.readInt32();
+ return selectTrack(trackIndex, false);
}
default:
{
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index aba95bc..3400724 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -133,27 +133,45 @@
// static
sp<DataSource> DataSource::CreateFromURI(
const char *uri, const KeyedVector<String8, String8> *headers) {
+ bool isWidevine = !strncasecmp("widevine://", uri, 11);
+
sp<DataSource> source;
if (!strncasecmp("file://", uri, 7)) {
source = new FileSource(uri + 7);
} else if (!strncasecmp("http://", uri, 7)
- || !strncasecmp("https://", uri, 8)) {
+ || !strncasecmp("https://", uri, 8)
+ || isWidevine) {
sp<HTTPBase> httpSource = HTTPBase::Create();
+
+ String8 tmp;
+ if (isWidevine) {
+ tmp = String8("http://");
+ tmp.append(uri + 11);
+
+ uri = tmp.string();
+ }
+
if (httpSource->connect(uri, headers) != OK) {
return NULL;
}
- String8 cacheConfig;
- bool disconnectAtHighwatermark;
- if (headers != NULL) {
- KeyedVector<String8, String8> copy = *headers;
- NuCachedSource2::RemoveCacheSpecificHeaders(
- ©, &cacheConfig, &disconnectAtHighwatermark);
- }
+ if (!isWidevine) {
+ String8 cacheConfig;
+ bool disconnectAtHighwatermark;
+ if (headers != NULL) {
+ KeyedVector<String8, String8> copy = *headers;
+ NuCachedSource2::RemoveCacheSpecificHeaders(
+ ©, &cacheConfig, &disconnectAtHighwatermark);
+ }
- source = new NuCachedSource2(
- httpSource,
- cacheConfig.isEmpty() ? NULL : cacheConfig.string());
+ source = new NuCachedSource2(
+ httpSource,
+ cacheConfig.isEmpty() ? NULL : cacheConfig.string());
+ } else {
+ // We do not want that prefetching, caching, datasource wrapper
+ // in the widevine:// case.
+ source = httpSource;
+ }
# if CHROMIUM_AVAILABLE
} else if (!strncasecmp("data:", uri, 5)) {
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 8758c93..166a99f 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -21,6 +21,7 @@
#include <media/stagefright/NuMediaExtractor.h>
#include "include/ESDS.h"
+#include "include/WVMExtractor.h"
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -58,13 +59,32 @@
return -EINVAL;
}
- sp<DataSource> dataSource = DataSource::CreateFromURI(path, headers);
+ sp<DataSource> dataSource =
+ DataSource::CreateFromURI(path, headers);
if (dataSource == NULL) {
return -ENOENT;
}
- mImpl = MediaExtractor::Create(dataSource);
+ if (!strncasecmp("widevine://", path, 11)) {
+ String8 mimeType;
+ float confidence;
+ sp<AMessage> dummy;
+ bool success = SniffWVM(dataSource, &mimeType, &confidence, &dummy);
+
+ if (!success
+ || strcasecmp(
+ mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ sp<WVMExtractor> extractor = new WVMExtractor(dataSource);
+ extractor->setAdaptiveStreamingMode(true);
+
+ mImpl = extractor;
+ } else {
+ mImpl = MediaExtractor::Create(dataSource);
+ }
if (mImpl == NULL) {
return ERROR_UNSUPPORTED;
@@ -409,7 +429,13 @@
}
status_t NuMediaExtractor::seekTo(int64_t timeUs) {
- return fetchTrackSamples(timeUs);
+ ssize_t minIndex = fetchTrackSamples(timeUs);
+
+ if (minIndex < 0) {
+ return ERROR_END_OF_STREAM;
+ }
+
+ return OK;
}
status_t NuMediaExtractor::advance() {
diff --git a/media/libstagefright/WVMExtractor.cpp b/media/libstagefright/WVMExtractor.cpp
index dac8106..effe336 100644
--- a/media/libstagefright/WVMExtractor.cpp
+++ b/media/libstagefright/WVMExtractor.cpp
@@ -59,10 +59,14 @@
"_ZN7android11GetInstanceENS_2spINS_10DataSourceEEE");
if (getInstanceFunc) {
- CHECK(source->DrmInitialization(MEDIA_MIMETYPE_CONTAINER_WVM) != NULL);
- mImpl = (*getInstanceFunc)(source);
- CHECK(mImpl != NULL);
- setDrmFlag(true);
+ if (source->DrmInitialization(
+ MEDIA_MIMETYPE_CONTAINER_WVM) != NULL) {
+ mImpl = (*getInstanceFunc)(source);
+ CHECK(mImpl != NULL);
+ setDrmFlag(true);
+ } else {
+ ALOGE("Drm manager failed to initialize.");
+ }
} else {
ALOGE("Failed to locate GetInstance in libwvm.so");
}
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 06e9468..9115f91 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -235,6 +235,7 @@
mutable Mutex mTimedTextLock;
sp<WVMExtractor> mWVMExtractor;
+ sp<MediaExtractor> mExtractor;
status_t setDataSource_l(
const char *uri,
@@ -257,7 +258,7 @@
void setVideoSource(sp<MediaSource> source);
status_t initVideoDecoder(uint32_t flags = 0);
- void addTextSource(const sp<MediaSource>& source);
+ void addTextSource(size_t trackIndex, const sp<MediaSource>& source);
void onStreamDone();
@@ -318,6 +319,14 @@
Vector<TrackStat> mTracks;
} mStats;
+ status_t getTrackInfo(Parcel* reply) const;
+
+ // when select is true, the given track is selected.
+ // otherwise, the given track is unselected.
+ status_t selectTrack(size_t trackIndex, bool select);
+
+ size_t countTracks() const;
+
AwesomePlayer(const AwesomePlayer &);
AwesomePlayer &operator=(const AwesomePlayer &);
};
diff --git a/media/libstagefright/timedtext/TimedTextDriver.cpp b/media/libstagefright/timedtext/TimedTextDriver.cpp
index a99d882..e26f517 100644
--- a/media/libstagefright/timedtext/TimedTextDriver.cpp
+++ b/media/libstagefright/timedtext/TimedTextDriver.cpp
@@ -52,16 +52,13 @@
TimedTextDriver::~TimedTextDriver() {
mTextSourceVector.clear();
+ mTextSourceTypeVector.clear();
mLooper->stop();
}
-status_t TimedTextDriver::selectTrack_l(int32_t index) {
- if (index >= (int)(mTextSourceVector.size())) {
- return BAD_VALUE;
- }
-
+status_t TimedTextDriver::selectTrack_l(size_t index) {
sp<TimedTextSource> source;
- source = mTextSourceVector.itemAt(index);
+ source = mTextSourceVector.valueFor(index);
mPlayer->setDataSource(source);
if (mState == UNINITIALIZED) {
mState = PAUSED;
@@ -108,7 +105,7 @@
return OK;
}
-status_t TimedTextDriver::selectTrack(int32_t index) {
+status_t TimedTextDriver::selectTrack(size_t index) {
status_t ret = OK;
Mutex::Autolock autoLock(mLock);
switch (mState) {
@@ -130,7 +127,7 @@
return ret;
}
-status_t TimedTextDriver::unselectTrack(int32_t index) {
+status_t TimedTextDriver::unselectTrack(size_t index) {
if (mCurrentTrackIndex != index) {
return INVALID_OPERATION;
}
@@ -149,19 +146,21 @@
}
status_t TimedTextDriver::addInBandTextSource(
- const sp<MediaSource>& mediaSource) {
+ size_t trackIndex, const sp<MediaSource>& mediaSource) {
sp<TimedTextSource> source =
TimedTextSource::CreateTimedTextSource(mediaSource);
if (source == NULL) {
return ERROR_UNSUPPORTED;
}
Mutex::Autolock autoLock(mLock);
- mTextSourceVector.add(source);
+ mTextSourceVector.add(trackIndex, source);
+ mTextSourceTypeVector.add(true);
return OK;
}
status_t TimedTextDriver::addOutOfBandTextSource(
- const char *uri, const char *mimeType) {
+ size_t trackIndex, const char *uri, const char *mimeType) {
+
// To support local subtitle file only for now
if (strncasecmp("file://", uri, 7)) {
ALOGE("uri('%s') is not a file", uri);
@@ -170,11 +169,11 @@
sp<DataSource> dataSource =
DataSource::CreateFromURI(uri);
- return createOutOfBandTextSource(mimeType, dataSource);
+ return createOutOfBandTextSource(trackIndex, mimeType, dataSource);
}
status_t TimedTextDriver::addOutOfBandTextSource(
- int fd, off64_t offset, off64_t length, const char *mimeType) {
+ size_t trackIndex, int fd, off64_t offset, off64_t length, const char *mimeType) {
if (fd < 0) {
ALOGE("Invalid file descriptor: %d", fd);
@@ -182,11 +181,13 @@
}
sp<DataSource> dataSource = new FileSource(dup(fd), offset, length);
- return createOutOfBandTextSource(mimeType, dataSource);
+ return createOutOfBandTextSource(trackIndex, mimeType, dataSource);
}
status_t TimedTextDriver::createOutOfBandTextSource(
- const char *mimeType, const sp<DataSource>& dataSource) {
+ size_t trackIndex,
+ const char *mimeType,
+ const sp<DataSource>& dataSource) {
if (dataSource == NULL) {
return ERROR_UNSUPPORTED;
@@ -199,28 +200,40 @@
}
if (source == NULL) {
+ ALOGE("Failed to create timed text source");
return ERROR_UNSUPPORTED;
}
Mutex::Autolock autoLock(mLock);
- mTextSourceVector.add(source);
+ mTextSourceVector.add(trackIndex, source);
+ mTextSourceTypeVector.add(false);
return OK;
}
-void TimedTextDriver::getTrackInfo(Parcel *parcel) {
+size_t TimedTextDriver::countExternalTracks() const {
+ size_t nTracks = 0;
+ for (size_t i = 0, n = mTextSourceTypeVector.size(); i < n; ++i) {
+ if (!mTextSourceTypeVector[i]) {
+ ++nTracks;
+ }
+ }
+ return nTracks;
+}
+
+void TimedTextDriver::getExternalTrackInfo(Parcel *parcel) {
Mutex::Autolock autoLock(mLock);
- Vector<sp<TimedTextSource> >::const_iterator iter;
- parcel->writeInt32(mTextSourceVector.size());
- for (iter = mTextSourceVector.begin();
- iter != mTextSourceVector.end(); ++iter) {
- sp<MetaData> meta = (*iter)->getFormat();
+ for (size_t i = 0, n = mTextSourceTypeVector.size(); i < n; ++i) {
+ if (mTextSourceTypeVector[i]) {
+ continue;
+ }
+
+ sp<MetaData> meta = mTextSourceVector.valueAt(i)->getFormat();
// There are two fields.
parcel->writeInt32(2);
// track type.
parcel->writeInt32(MEDIA_TRACK_TYPE_TIMEDTEXT);
-
const char *lang = "und";
if (meta != NULL) {
meta->findCString(kKeyMediaLanguage, &lang);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index d0611b0..d42ac8c 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -138,25 +138,31 @@
}
#endif
-static int load_audio_interface(const char *if_name, const hw_module_t **mod,
- audio_hw_device_t **dev)
+static int load_audio_interface(const char *if_name, audio_hw_device_t **dev)
{
+ const hw_module_t *mod;
int rc;
- rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, mod);
- if (rc)
+ rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
+ ALOGE_IF(rc, "%s couldn't load audio hw module %s.%s (%s)", __func__,
+ AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
+ if (rc) {
goto out;
-
- rc = audio_hw_device_open(*mod, dev);
- ALOGE_IF(rc, "couldn't open audio hw device in %s.%s (%s)",
- AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
- if (rc)
+ }
+ rc = audio_hw_device_open(mod, dev);
+ ALOGE_IF(rc, "%s couldn't open audio hw device in %s.%s (%s)", __func__,
+ AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
+ if (rc) {
goto out;
-
+ }
+ if ((*dev)->common.version != AUDIO_DEVICE_API_VERSION_CURRENT) {
+ ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
+ rc = BAD_VALUE;
+ goto out;
+ }
return 0;
out:
- *mod = NULL;
*dev = NULL;
return rc;
}
@@ -914,7 +920,12 @@
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
- size_t size = mPrimaryHardwareDev->get_input_buffer_size(mPrimaryHardwareDev, sampleRate, format, channelCount);
+ struct audio_config config = {
+ sample_rate: sampleRate,
+ channel_mask: audio_channel_in_mask_from_count(channelCount),
+ format: format,
+ };
+ size_t size = mPrimaryHardwareDev->get_input_buffer_size(mPrimaryHardwareDev, &config);
mHardwareStatus = AUDIO_HW_IDLE;
return size;
}
@@ -5743,10 +5754,9 @@
}
}
- const hw_module_t *mod;
audio_hw_device_t *dev;
- int rc = load_audio_interface(name, &mod, &dev);
+ int rc = load_audio_interface(name, &dev);
if (rc) {
ALOGI("loadHwModule() error %d loading module %s ", rc, name);
return 0;
@@ -5772,7 +5782,7 @@
mAudioHwDevs.add(handle, new AudioHwDevice(name, dev));
ALOGI("loadHwModule() Loaded %s audio interface from %s (%s) handle %d",
- name, mod->name, mod->id, handle);
+ name, dev->common.module->name, dev->common.module->id, handle);
return handle;
@@ -5788,19 +5798,20 @@
{
status_t status;
PlaybackThread *thread = NULL;
- uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
- audio_format_t format = pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT;
- audio_channel_mask_t channelMask = pChannelMask ? *pChannelMask : 0;
- uint32_t latency = pLatencyMs ? *pLatencyMs : 0;
- audio_stream_out_t *outStream;
+ struct audio_config config = {
+ sample_rate: pSamplingRate ? *pSamplingRate : 0,
+ channel_mask: pChannelMask ? *pChannelMask : 0,
+ format: pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT,
+ };
+ audio_stream_out_t *outStream = NULL;
audio_hw_device_t *outHwDev;
ALOGV("openOutput(), module %d Device %x, SamplingRate %d, Format %d, Channels %x, flags %x",
module,
(pDevices != NULL) ? (int)*pDevices : 0,
- samplingRate,
- format,
- channelMask,
+ config.sample_rate,
+ config.format,
+ config.channel_mask,
flags);
if (pDevices == NULL || *pDevices == 0) {
@@ -5813,24 +5824,31 @@
if (outHwDev == NULL)
return 0;
+ audio_io_handle_t id = nextUniqueId();
+
mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
- status = outHwDev->open_output_stream(outHwDev, *pDevices, &format,
- &channelMask, &samplingRate, &outStream);
+
+ status = outHwDev->open_output_stream(outHwDev,
+ id,
+ *pDevices,
+ (audio_output_flags_t)flags,
+ &config,
+ &outStream);
+
mHardwareStatus = AUDIO_HW_IDLE;
ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, Channels %x, status %d",
outStream,
- samplingRate,
- format,
- channelMask,
+ config.sample_rate,
+ config.format,
+ config.channel_mask,
status);
- if (outStream != NULL) {
+ if (status == NO_ERROR && outStream != NULL) {
AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream);
- audio_io_handle_t id = nextUniqueId();
if ((flags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT) ||
- (format != AUDIO_FORMAT_PCM_16_BIT) ||
- (channelMask != AUDIO_CHANNEL_OUT_STEREO)) {
+ (config.format != AUDIO_FORMAT_PCM_16_BIT) ||
+ (config.channel_mask != AUDIO_CHANNEL_OUT_STEREO)) {
thread = new DirectOutputThread(this, output, id, *pDevices);
ALOGV("openOutput() created direct output: ID %d thread %p", id, thread);
} else {
@@ -5839,9 +5857,9 @@
}
mPlaybackThreads.add(id, thread);
- if (pSamplingRate != NULL) *pSamplingRate = samplingRate;
- if (pFormat != NULL) *pFormat = format;
- if (pChannelMask != NULL) *pChannelMask = channelMask;
+ if (pSamplingRate != NULL) *pSamplingRate = config.sample_rate;
+ if (pFormat != NULL) *pFormat = config.format;
+ if (pChannelMask != NULL) *pChannelMask = config.channel_mask;
if (pLatencyMs != NULL) *pLatencyMs = thread->latency();
// notify client processes of the new output creation
@@ -5995,13 +6013,15 @@
{
status_t status;
RecordThread *thread = NULL;
- uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
- audio_format_t format = pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT;
- audio_channel_mask_t channelMask = pChannelMask ? *pChannelMask : 0;
- uint32_t reqSamplingRate = samplingRate;
- audio_format_t reqFormat = format;
- audio_channel_mask_t reqChannels = channelMask;
- audio_stream_in_t *inStream;
+ struct audio_config config = {
+ sample_rate: pSamplingRate ? *pSamplingRate : 0,
+ channel_mask: pChannelMask ? *pChannelMask : 0,
+ format: pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT,
+ };
+ uint32_t reqSamplingRate = config.sample_rate;
+ audio_format_t reqFormat = config.format;
+ audio_channel_mask_t reqChannels = config.channel_mask;
+ audio_stream_in_t *inStream = NULL;
audio_hw_device_t *inHwDev;
if (pDevices == NULL || *pDevices == 0) {
@@ -6014,35 +6034,32 @@
if (inHwDev == NULL)
return 0;
- status = inHwDev->open_input_stream(inHwDev, *pDevices, &format,
- &channelMask, &samplingRate,
- (audio_in_acoustics_t)0,
+ audio_io_handle_t id = nextUniqueId();
+
+ status = inHwDev->open_input_stream(inHwDev, id, *pDevices, &config,
&inStream);
ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, status %d",
inStream,
- samplingRate,
- format,
- channelMask,
+ config.sample_rate,
+ config.format,
+ config.channel_mask,
status);
// If the input could not be opened with the requested parameters and we can handle the conversion internally,
// try to open again with the proposed parameters. The AudioFlinger can resample the input and do mono to stereo
// or stereo to mono conversions on 16 bit PCM inputs.
- if (inStream == NULL && status == BAD_VALUE &&
- reqFormat == format && format == AUDIO_FORMAT_PCM_16_BIT &&
- (samplingRate <= 2 * reqSamplingRate) &&
- (popcount(channelMask) <= FCC_2) && (popcount(reqChannels) <= FCC_2)) {
+ if (status == BAD_VALUE &&
+ reqFormat == config.format && config.format == AUDIO_FORMAT_PCM_16_BIT &&
+ (config.sample_rate <= 2 * reqSamplingRate) &&
+ (popcount(config.channel_mask) <= FCC_2) && (popcount(reqChannels) <= FCC_2)) {
ALOGV("openInput() reopening with proposed sampling rate and channels");
- status = inHwDev->open_input_stream(inHwDev, *pDevices, &format,
- &channelMask, &samplingRate,
- (audio_in_acoustics_t)0,
- &inStream);
+ inStream = NULL;
+ status = inHwDev->open_input_stream(inHwDev, id, *pDevices, &config, &inStream);
}
- if (inStream != NULL) {
+ if (status == NO_ERROR && inStream != NULL) {
AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);
- audio_io_handle_t id = nextUniqueId();
// Start record thread
// RecorThread require both input and output device indication to forward to audio
// pre processing modules
@@ -6056,7 +6073,7 @@
mRecordThreads.add(id, thread);
ALOGV("openInput() created record thread: ID %d thread %p", id, thread);
if (pSamplingRate != NULL) *pSamplingRate = reqSamplingRate;
- if (pFormat != NULL) *pFormat = format;
+ if (pFormat != NULL) *pFormat = config.format;
if (pChannelMask != NULL) *pChannelMask = reqChannels;
input->stream->common.standby(&input->stream->common);