Merge changes I7835e753,I5fe4d3e7
* changes:
AudioPolicyManager: abort when client is removed while active
AudioOutputDescriptor: improve refcount logging
diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp
index fde09df18..c5df5c7 100644
--- a/media/extractors/midi/Android.bp
+++ b/media/extractors/midi/Android.bp
@@ -9,6 +9,7 @@
shared_libs: [
"liblog",
"libmediaextractor",
+ "libmediandk",
],
static_libs: [
diff --git a/media/extractors/midi/MidiExtractor.cpp b/media/extractors/midi/MidiExtractor.cpp
index ea56734..9b0f4e7 100644
--- a/media/extractors/midi/MidiExtractor.cpp
+++ b/media/extractors/midi/MidiExtractor.cpp
@@ -33,16 +33,16 @@
// how many Sonivox output buffers to aggregate into one MediaBufferBase
static const int NUM_COMBINE_BUFFERS = 4;
-class MidiSource : public MediaTrackHelper {
+class MidiSource : public MediaTrackHelperV2 {
public:
MidiSource(
MidiEngine &engine,
- MetaDataBase &trackMetadata);
+ AMediaFormat *trackMetadata);
- virtual status_t start(MetaDataBase *params);
+ virtual status_t start(AMediaFormat *params);
virtual status_t stop();
- virtual status_t getFormat(MetaDataBase&);
+ virtual status_t getFormat(AMediaFormat *);
virtual status_t read(
MediaBufferBase **buffer, const ReadOptions *options = NULL);
@@ -52,7 +52,7 @@
private:
MidiEngine &mEngine;
- MetaDataBase &mTrackMetadata;
+ AMediaFormat *mTrackMetadata;
bool mInitCheck;
bool mStarted;
@@ -69,7 +69,7 @@
MidiSource::MidiSource(
MidiEngine &engine,
- MetaDataBase &trackMetadata)
+ AMediaFormat *trackMetadata)
: mEngine(engine),
mTrackMetadata(trackMetadata),
mInitCheck(false),
@@ -87,7 +87,7 @@
}
}
-status_t MidiSource::start(MetaDataBase * /* params */)
+status_t MidiSource::start(AMediaFormat * /* params */)
{
ALOGV("MidiSource::start");
@@ -108,9 +108,9 @@
return OK;
}
-status_t MidiSource::getFormat(MetaDataBase &meta)
+status_t MidiSource::getFormat(AMediaFormat *meta)
{
- meta = mTrackMetadata;
+ AMediaFormat_copy(meta, mTrackMetadata);
return OK;
}
@@ -143,8 +143,8 @@
// MidiEngine
MidiEngine::MidiEngine(CDataSource *dataSource,
- MetaDataBase *fileMetadata,
- MetaDataBase *trackMetadata) :
+ AMediaFormat *fileMetadata,
+ AMediaFormat *trackMetadata) :
mGroup(NULL),
mEasData(NULL),
mEasHandle(NULL),
@@ -170,16 +170,20 @@
}
if (fileMetadata != NULL) {
- fileMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MIDI);
+ AMediaFormat_setString(fileMetadata, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MIDI);
}
if (trackMetadata != NULL) {
- trackMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
- trackMetadata->setInt64(kKeyDuration, 1000ll * temp); // milli->micro
+ AMediaFormat_setString(trackMetadata, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_RAW);
+ AMediaFormat_setInt64(
+ trackMetadata, AMEDIAFORMAT_KEY_DURATION, 1000ll * temp); // milli->micro
mEasConfig = EAS_Config();
- trackMetadata->setInt32(kKeySampleRate, mEasConfig->sampleRate);
- trackMetadata->setInt32(kKeyChannelCount, mEasConfig->numChannels);
- trackMetadata->setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit);
+ AMediaFormat_setInt32(
+ trackMetadata, AMEDIAFORMAT_KEY_SAMPLE_RATE, mEasConfig->sampleRate);
+ AMediaFormat_setInt32(
+ trackMetadata, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mEasConfig->numChannels);
+ AMediaFormat_setInt32(
+ trackMetadata, AMEDIAFORMAT_KEY_PCM_ENCODING, kAudioEncodingPcm16bit);
}
mIsInitialized = true;
}
@@ -268,13 +272,17 @@
mInitCheck(false)
{
ALOGV("MidiExtractor ctor");
- mEngine = new MidiEngine(mDataSource, &mFileMetadata, &mTrackMetadata);
+ mFileMetadata = AMediaFormat_new();
+ mTrackMetadata = AMediaFormat_new();
+ mEngine = new MidiEngine(mDataSource, mFileMetadata, mTrackMetadata);
mInitCheck = mEngine->initCheck();
}
MidiExtractor::~MidiExtractor()
{
ALOGV("MidiExtractor dtor");
+ AMediaFormat_delete(mFileMetadata);
+ AMediaFormat_delete(mTrackMetadata);
}
size_t MidiExtractor::countTracks()
@@ -282,7 +290,7 @@
return mInitCheck == OK ? 1 : 0;
}
-MediaTrackHelper *MidiExtractor::getTrack(size_t index)
+MediaTrackHelperV2 *MidiExtractor::getTrack(size_t index)
{
if (mInitCheck != OK || index > 0) {
return NULL;
@@ -291,20 +299,20 @@
}
status_t MidiExtractor::getTrackMetaData(
- MetaDataBase &meta,
+ AMediaFormat *meta,
size_t index, uint32_t /* flags */) {
ALOGV("MidiExtractor::getTrackMetaData");
if (mInitCheck != OK || index > 0) {
return UNKNOWN_ERROR;
}
- meta = mTrackMetadata;
+ AMediaFormat_copy(meta, mTrackMetadata);
return OK;
}
-status_t MidiExtractor::getMetaData(MetaDataBase &meta)
+status_t MidiExtractor::getMetaData(AMediaFormat *meta)
{
ALOGV("MidiExtractor::getMetaData");
- meta = mFileMetadata;
+ AMediaFormat_copy(meta, mFileMetadata);
return OK;
}
@@ -323,26 +331,27 @@
}
+
extern "C" {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
ExtractorDef GETEXTRACTORDEF() {
return {
- EXTRACTORDEF_VERSION,
+ EXTRACTORDEF_VERSION_CURRENT,
UUID("ef6cca0a-f8a2-43e6-ba5f-dfcd7c9a7ef2"),
1,
"MIDI Extractor",
{
- [](
- CDataSource *source,
- float *confidence,
- void **,
- FreeMetaFunc *) -> CreatorFunc {
+ .v2 = [](
+ CDataSource *source,
+ float *confidence,
+ void **,
+ FreeMetaFunc *) -> CreatorFuncV2 {
if (SniffMidi(source, confidence)) {
return [](
CDataSource *source,
- void *) -> CMediaExtractor* {
- return wrap(new MidiExtractor(source));};
+ void *) -> CMediaExtractorV2* {
+ return wrapV2(new MidiExtractor(source));};
}
return NULL;
}
diff --git a/media/extractors/midi/MidiExtractor.h b/media/extractors/midi/MidiExtractor.h
index 2147297..d82c5be 100644
--- a/media/extractors/midi/MidiExtractor.h
+++ b/media/extractors/midi/MidiExtractor.h
@@ -22,8 +22,8 @@
#include <media/MediaExtractorPluginHelper.h>
#include <media/stagefright/MediaBufferBase.h>
#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MetaDataBase.h>
#include <media/MidiIoWrapper.h>
+#include <media/NdkMediaFormat.h>
#include <utils/String8.h>
#include <libsonivox/eas.h>
@@ -32,8 +32,8 @@
class MidiEngine {
public:
explicit MidiEngine(CDataSource *dataSource,
- MetaDataBase *fileMetadata,
- MetaDataBase *trackMetadata);
+ AMediaFormat *fileMetadata,
+ AMediaFormat *trackMetadata);
~MidiEngine();
status_t initCheck();
@@ -51,16 +51,16 @@
bool mIsInitialized;
};
-class MidiExtractor : public MediaExtractorPluginHelper {
+class MidiExtractor : public MediaExtractorPluginHelperV2 {
public:
explicit MidiExtractor(CDataSource *source);
virtual size_t countTracks();
- virtual MediaTrackHelper *getTrack(size_t index);
- virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+ virtual MediaTrackHelperV2 *getTrack(size_t index);
+ virtual status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
- virtual status_t getMetaData(MetaDataBase& meta);
+ virtual status_t getMetaData(AMediaFormat *meta);
virtual const char * name() { return "MidiExtractor"; }
protected:
@@ -69,10 +69,10 @@
private:
CDataSource *mDataSource;
status_t mInitCheck;
- MetaDataBase mFileMetadata;
+ AMediaFormat *mFileMetadata;
// There is only one track
- MetaDataBase mTrackMetadata;
+ AMediaFormat *mTrackMetadata;
MidiEngine *mEngine;
diff --git a/media/libaaudio/examples/utils/AAudioArgsParser.h b/media/libaaudio/examples/utils/AAudioArgsParser.h
index 0e61589..ece9e6a 100644
--- a/media/libaaudio/examples/utils/AAudioArgsParser.h
+++ b/media/libaaudio/examples/utils/AAudioArgsParser.h
@@ -185,18 +185,26 @@
mNumberOfBursts = numBursts;
}
+ int32_t getFramesPerCallback() const {
+ return mFramesPerCallback;
+ }
+ void setFramesPerCallback(int32_t size) {
+ mFramesPerCallback = size;
+ }
+
/**
* Apply these parameters to a stream builder.
* @param builder
*/
void applyParameters(AAudioStreamBuilder *builder) const {
- AAudioStreamBuilder_setChannelCount(builder, mChannelCount);
- AAudioStreamBuilder_setFormat(builder, mFormat);
- AAudioStreamBuilder_setSampleRate(builder, mSampleRate);
AAudioStreamBuilder_setBufferCapacityInFrames(builder, mBufferCapacity);
+ AAudioStreamBuilder_setChannelCount(builder, mChannelCount);
AAudioStreamBuilder_setDeviceId(builder, mDeviceId);
- AAudioStreamBuilder_setSharingMode(builder, mSharingMode);
+ AAudioStreamBuilder_setFormat(builder, mFormat);
+ AAudioStreamBuilder_setFramesPerDataCallback(builder, mFramesPerCallback);
AAudioStreamBuilder_setPerformanceMode(builder, mPerformanceMode);
+ AAudioStreamBuilder_setSampleRate(builder, mSampleRate);
+ AAudioStreamBuilder_setSharingMode(builder, mSharingMode);
// Call P functions if supported.
loadFutureFunctions();
@@ -232,6 +240,7 @@
aaudio_input_preset_t mInputPreset = AAUDIO_UNSPECIFIED;
int32_t mNumberOfBursts = AAUDIO_UNSPECIFIED;
+ int32_t mFramesPerCallback = AAUDIO_UNSPECIFIED;
};
class AAudioArgsParser : public AAudioParameters {
@@ -297,6 +306,9 @@
case 'y':
setContentType(atoi(&arg[2]));
break;
+ case 'z':
+ setFramesPerCallback(atoi(&arg[2]));
+ break;
default:
unrecognized = true;
break;
@@ -350,6 +362,7 @@
printf(" -u{usage} eg. 14 for AAUDIO_USAGE_GAME\n");
printf(" -x to use EXCLUSIVE mode\n");
printf(" -y{contentType} eg. 1 for AAUDIO_CONTENT_TYPE_SPEECH\n");
+ printf(" -z{callbackSize} or block size, in frames, default = 0\n");
}
static aaudio_performance_mode_t parsePerformanceMode(char c) {
@@ -406,6 +419,9 @@
printf(" Capacity: requested = %d, actual = %d\n", getBufferCapacity(),
AAudioStream_getBufferCapacityInFrames(stream));
+ printf(" CallbackSize: requested = %d, actual = %d\n", getFramesPerCallback(),
+ AAudioStream_getFramesPerDataCallback(stream));
+
printf(" SharingMode: requested = %s, actual = %s\n",
getSharingModeText(getSharingMode()),
getSharingModeText(AAudioStream_getSharingMode(stream)));
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index dbf00a9..40e22ac 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -57,6 +57,9 @@
// Try to create an AudioRecord
+ const aaudio_session_id_t requestedSessionId = builder.getSessionId();
+ const audio_session_t sessionId = AAudioConvert_aaudioToAndroidSessionId(requestedSessionId);
+
// TODO Support UNSPECIFIED in AudioRecord. For now, use stereo if unspecified.
int32_t samplesPerFrame = (getSamplesPerFrame() == AAUDIO_UNSPECIFIED)
? 2 : getSamplesPerFrame();
@@ -66,17 +69,21 @@
: builder.getBufferCapacity();
- audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE;
+ audio_input_flags_t flags;
aaudio_performance_mode_t perfMode = getPerformanceMode();
switch (perfMode) {
case AAUDIO_PERFORMANCE_MODE_LOW_LATENCY:
- flags = (audio_input_flags_t) (AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW);
+ // If the app asks for a sessionId then it means they want to use effects.
+ // So don't use RAW flag.
+ flags = (audio_input_flags_t) ((requestedSessionId == AAUDIO_SESSION_ID_NONE)
+ ? (AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW)
+ : (AUDIO_INPUT_FLAG_FAST));
break;
case AAUDIO_PERFORMANCE_MODE_POWER_SAVING:
case AAUDIO_PERFORMANCE_MODE_NONE:
default:
- // No flags.
+ flags = AUDIO_INPUT_FLAG_NONE;
break;
}
@@ -141,9 +148,6 @@
.tags = ""
};
- aaudio_session_id_t requestedSessionId = builder.getSessionId();
- audio_session_t sessionId = AAudioConvert_aaudioToAndroidSessionId(requestedSessionId);
-
// ----------- open the AudioRecord ---------------------
// Might retry, but never more than once.
for (int i = 0; i < 2; i ++) {
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 1572f0d..1ac2558 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -59,18 +59,25 @@
return result;
}
+ const aaudio_session_id_t requestedSessionId = builder.getSessionId();
+ const audio_session_t sessionId = AAudioConvert_aaudioToAndroidSessionId(requestedSessionId);
+
// Try to create an AudioTrack
// Use stereo if unspecified.
int32_t samplesPerFrame = (getSamplesPerFrame() == AAUDIO_UNSPECIFIED)
? 2 : getSamplesPerFrame();
audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(samplesPerFrame);
- audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
+ audio_output_flags_t flags;
aaudio_performance_mode_t perfMode = getPerformanceMode();
switch(perfMode) {
case AAUDIO_PERFORMANCE_MODE_LOW_LATENCY:
// Bypass the normal mixer and go straight to the FAST mixer.
- flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW);
+ // If the app asks for a sessionId then it means they want to use effects.
+ // So don't use RAW flag.
+ flags = (audio_output_flags_t) ((requestedSessionId == AAUDIO_SESSION_ID_NONE)
+ ? (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_RAW)
+ : (AUDIO_OUTPUT_FLAG_FAST));
break;
case AAUDIO_PERFORMANCE_MODE_POWER_SAVING:
@@ -81,6 +88,7 @@
case AAUDIO_PERFORMANCE_MODE_NONE:
default:
// No flags. Use a normal mixer in front of the FAST mixer.
+ flags = AUDIO_OUTPUT_FLAG_NONE;
break;
}
@@ -135,11 +143,6 @@
.tags = ""
};
- static_assert(AAUDIO_UNSPECIFIED == AUDIO_SESSION_ALLOCATE, "Session IDs should match");
-
- aaudio_session_id_t requestedSessionId = builder.getSessionId();
- audio_session_t sessionId = AAudioConvert_aaudioToAndroidSessionId(requestedSessionId);
-
mAudioTrack = new AudioTrack();
mAudioTrack->set(
AUDIO_STREAM_DEFAULT, // ignored because we pass attributes below
diff --git a/media/libmedia/NdkWrapper.cpp b/media/libmedia/NdkWrapper.cpp
index 272bc30..7d67262 100644
--- a/media/libmedia/NdkWrapper.cpp
+++ b/media/libmedia/NdkWrapper.cpp
@@ -31,18 +31,6 @@
#include <media/stagefright/foundation/AMessage.h>
#include <utils/Errors.h>
-// TODO: remove forward declaration when AMediaExtractor_disconnect is offcially added to NDK
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-media_status_t AMediaExtractor_disconnect(AMediaExtractor *);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
namespace android {
static const size_t kAESBlockSize = 16; // AES_BLOCK_SIZE
@@ -1080,14 +1068,6 @@
return OK;
}
-status_t AMediaExtractorWrapper::disconnect() {
- if (mAMediaExtractor != NULL) {
- media_status_t err = AMediaExtractor_disconnect(mAMediaExtractor);
- return translateErrorCode(err);
- }
- return DEAD_OBJECT;
-}
-
AMediaExtractor *AMediaExtractorWrapper::getAMediaExtractor() const {
return mAMediaExtractor;
}
diff --git a/media/libmedia/include/media/NdkWrapper.h b/media/libmedia/include/media/NdkWrapper.h
index c97d171..191665a 100644
--- a/media/libmedia/include/media/NdkWrapper.h
+++ b/media/libmedia/include/media/NdkWrapper.h
@@ -287,8 +287,6 @@
status_t release();
- status_t disconnect();
-
status_t setDataSource(int fd, off64_t offset, off64_t length);
status_t setDataSource(const char *location);
diff --git a/media/libmediaextractor/include/media/DataSourceBase.h b/media/libmediaextractor/include/media/DataSourceBase.h
index fc620fd..af5b83d 100644
--- a/media/libmediaextractor/include/media/DataSourceBase.h
+++ b/media/libmediaextractor/include/media/DataSourceBase.h
@@ -66,9 +66,7 @@
virtual void close() {};
- virtual void disconnect() {}
-
- virtual ssize_t getAvailableSize(status_t * /*err*/) {
+ virtual status_t getAvailableSize(off64_t /*offset*/, off64_t * /*size*/) {
return -1;
}
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.cpp
index 57d1147..f41a431 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.cpp
@@ -147,9 +147,10 @@
}
uint32_t psshSize = pssh.tellp();
- const uint8_t* psshPtr = reinterpret_cast<const uint8_t*>(pssh.str().c_str());
- const char *psshHex = DrmUUID::arrayToHex(psshPtr, psshSize).string();
- ALOGV("retrieveDrmInfo: MEDIA_DRM_INFO PSSH: size: %u %s", psshSize, psshHex);
+ std::string psshBase = pssh.str();
+ const auto* psshPtr = reinterpret_cast<const uint8_t*>(psshBase.c_str());
+ ALOGV("retrieveDrmInfo: MEDIA_DRM_INFO PSSH: size: %u %s", psshSize,
+ DrmUUID::arrayToHex(psshPtr, psshSize).string());
// 1) Write PSSH bytes
playerMsg->add_values()->set_bytes_value(
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 68adf3c..f720667 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -5384,7 +5384,7 @@
AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
(void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
- (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
+ (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
if (mConverter[kPortIndexOutput] != NULL) {
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 18f4b12..7025af7 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -256,6 +256,10 @@
return ERROR_UNSUPPORTED;
}
+void NuCachedSource2::close() {
+ disconnect();
+}
+
void NuCachedSource2::disconnect() {
if (mSource->flags() & kIsHTTPBasedSource) {
ALOGV("disconnecting HTTPBasedSource");
@@ -567,12 +571,19 @@
return mCacheOffset + mCache->totalSize();
}
-size_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) const {
+status_t NuCachedSource2::getAvailableSize(off64_t offset, off64_t *size) {
Mutex::Autolock autoLock(mLock);
- return approxDataRemaining_l(finalStatus);
+ status_t finalStatus = UNKNOWN_ERROR;
+ *size = approxDataRemaining_l(offset, &finalStatus);
+ return finalStatus;
}
-size_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) const {
+size_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) const {
+ Mutex::Autolock autoLock(mLock);
+ return approxDataRemaining_l(mLastAccessPos, finalStatus);
+}
+
+size_t NuCachedSource2::approxDataRemaining_l(off64_t offset, status_t *finalStatus) const {
*finalStatus = mFinalStatus;
if (mFinalStatus != OK && mNumRetriesLeft > 0) {
@@ -580,9 +591,10 @@
*finalStatus = OK;
}
+ offset = offset >= 0 ? offset : mLastAccessPos;
off64_t lastBytePosCached = mCacheOffset + mCache->totalSize();
- if (mLastAccessPos < lastBytePosCached) {
- return lastBytePosCached - mLastAccessPos;
+ if (offset < lastBytePosCached) {
+ return lastBytePosCached - offset;
}
return 0;
}
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index e42d8d0..f94648c 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -204,12 +204,6 @@
return OK;
}
-void NuMediaExtractor::disconnect() {
- if (mDataSource != NULL) {
- mDataSource->disconnect();
- }
-}
-
status_t NuMediaExtractor::updateDurationAndBitrate() {
if (mImpl->countTracks() > kMaxTrackCount) {
return ERROR_UNSUPPORTED;
@@ -786,9 +780,8 @@
int64_t *durationUs, bool *eos) const {
Mutex::Autolock autoLock(mLock);
- status_t finalStatus;
- ssize_t cachedDataRemaining =
- mDataSource->getAvailableSize(&finalStatus);
+ off64_t cachedDataRemaining = -1;
+ status_t finalStatus = mDataSource->getAvailableSize(-1, &cachedDataRemaining);
int64_t bitrate;
if (cachedDataRemaining >= 0
diff --git a/media/libstagefright/http/ClearMediaHTTP.cpp b/media/libstagefright/http/ClearMediaHTTP.cpp
index bfbad1e..9557c8a 100644
--- a/media/libstagefright/http/ClearMediaHTTP.cpp
+++ b/media/libstagefright/http/ClearMediaHTTP.cpp
@@ -74,6 +74,10 @@
return success ? OK : UNKNOWN_ERROR;
}
+void ClearMediaHTTP::close() {
+ disconnect();
+}
+
void ClearMediaHTTP::disconnect() {
mName = String8("ClearMediaHTTP(<disconnected>)");
if (mInitCheck != OK) {
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index f4aab25..596efb8 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -37,6 +37,8 @@
virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+ virtual void close();
+
virtual void disconnect();
virtual status_t getSize(off64_t *size);
@@ -51,9 +53,7 @@
return mName;
}
- ssize_t getAvailableSize(status_t *finalStatus) {
- return approxDataRemaining(finalStatus);
- }
+ status_t getAvailableSize(off64_t offset, off64_t *size);
////////////////////////////////////////////////////////////////////////////
@@ -139,7 +139,7 @@
ssize_t readInternal(off64_t offset, void *data, size_t size);
status_t seekInternal_l(off64_t offset);
- size_t approxDataRemaining_l(status_t *finalStatus) const;
+ size_t approxDataRemaining_l(off64_t offset, status_t *finalStatus) const;
void restartPrefetcherIfNecessary_l(
bool ignoreLowWaterThreshold = false, bool force = false);
diff --git a/media/libstagefright/include/media/stagefright/ClearMediaHTTP.h b/media/libstagefright/include/media/stagefright/ClearMediaHTTP.h
index 7fe9c74..72907a9 100644
--- a/media/libstagefright/include/media/stagefright/ClearMediaHTTP.h
+++ b/media/libstagefright/include/media/stagefright/ClearMediaHTTP.h
@@ -34,6 +34,8 @@
const KeyedVector<String8, String8> *headers,
off64_t offset);
+ virtual void close();
+
virtual void disconnect();
virtual status_t initCheck() const;
diff --git a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
index 54a7095..641ccfa 100644
--- a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
@@ -64,8 +64,6 @@
status_t setMediaCas(const HInterfaceToken &casToken);
- void disconnect();
-
size_t countTracks() const;
status_t getTrackFormat(size_t index, sp<AMessage> *format, uint32_t flags = 0) const;
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 417f1df..05c8582 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -39,6 +39,7 @@
"NdkMediaCrypto.cpp",
"NdkMediaDataSource.cpp",
"NdkMediaExtractor.cpp",
+ "NdkMediaError.cpp",
"NdkMediaFormat.cpp",
"NdkMediaMuxer.cpp",
"NdkMediaDrm.cpp",
@@ -106,6 +107,7 @@
srcs: [
"NdkMediaDataSourceCallbacks.cpp",
+ "NdkMediaError.cpp",
],
include_dirs: [
diff --git a/media/ndk/NdkMediaDataSource.cpp b/media/ndk/NdkMediaDataSource.cpp
index 2c44fa3..75477b4 100644
--- a/media/ndk/NdkMediaDataSource.cpp
+++ b/media/ndk/NdkMediaDataSource.cpp
@@ -246,5 +246,10 @@
mSource->close = close;
}
+EXPORT
+void AMediaDataSource_close(AMediaDataSource *mSource) {
+ return mSource->close(mSource->userdata);
+}
+
} // extern "C"
diff --git a/media/ndk/NdkMediaDataSourceCallbacks.cpp b/media/ndk/NdkMediaDataSourceCallbacks.cpp
index 4338048..1efcaa0 100644
--- a/media/ndk/NdkMediaDataSourceCallbacks.cpp
+++ b/media/ndk/NdkMediaDataSourceCallbacks.cpp
@@ -17,6 +17,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "NdkMediaDataSourceCallbacks"
+#include "NdkMediaErrorPriv.h"
#include "NdkMediaDataSourceCallbacksPriv.h"
#include <media/DataSource.h>
diff --git a/media/ndk/NdkMediaError.cpp b/media/ndk/NdkMediaError.cpp
new file mode 100644
index 0000000..2facd8c
--- /dev/null
+++ b/media/ndk/NdkMediaError.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <media/NdkMediaError.h>
+#include <media/stagefright/MediaErrors.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+using namespace android;
+
+media_status_t translate_error(status_t err) {
+
+ if (err == OK) {
+ return AMEDIA_OK;
+ } else if (err == ERROR_END_OF_STREAM) {
+ return AMEDIA_ERROR_END_OF_STREAM;
+ } else if (err == ERROR_IO) {
+ return AMEDIA_ERROR_IO;
+ }
+
+ ALOGE("sf error code: %d", err);
+ return AMEDIA_ERROR_UNKNOWN;
+}
+
+status_t reverse_translate_error(media_status_t err) {
+
+ if (err == AMEDIA_OK) {
+ return OK;
+ } else if (err == AMEDIA_ERROR_END_OF_STREAM) {
+ return ERROR_END_OF_STREAM;
+ } else if (err == AMEDIA_ERROR_IO) {
+ return ERROR_IO;
+ }
+
+ ALOGE("ndk error code: %d", err);
+ return UNKNOWN_ERROR;
+}
diff --git a/media/ndk/NdkMediaErrorPriv.h b/media/ndk/NdkMediaErrorPriv.h
new file mode 100644
index 0000000..f5e2f02
--- /dev/null
+++ b/media/ndk/NdkMediaErrorPriv.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _NDK_MEDIA_ERROR_PRIV_H
+#define _NDK_MEDIA_ERROR_PRIV_H
+
+#include <media/NdkMediaError.h>
+#include <utils/Errors.h>
+
+using namespace android;
+
+media_status_t translate_error(status_t);
+
+status_t reverse_translate_error(media_status_t);
+
+#endif // _NDK_MEDIA_ERROR_PRIV_H
diff --git a/media/ndk/NdkMediaExtractor.cpp b/media/ndk/NdkMediaExtractor.cpp
index f00a19c..ff1c8a9 100644
--- a/media/ndk/NdkMediaExtractor.cpp
+++ b/media/ndk/NdkMediaExtractor.cpp
@@ -21,6 +21,7 @@
#include <media/NdkMediaError.h>
#include <media/NdkMediaExtractor.h>
#include <media/NdkMediaFormatPriv.h>
+#include "NdkMediaErrorPriv.h"
#include "NdkMediaDataSourcePriv.h"
@@ -40,19 +41,6 @@
using namespace android;
-static media_status_t translate_error(status_t err) {
- if (err == OK) {
- return AMEDIA_OK;
- } else if (err == ERROR_END_OF_STREAM) {
- return AMEDIA_ERROR_END_OF_STREAM;
- } else if (err == ERROR_IO) {
- return AMEDIA_ERROR_IO;
- }
-
- ALOGE("sf error code: %d", err);
- return AMEDIA_ERROR_UNKNOWN;
-}
-
struct AMediaExtractor {
sp<NuMediaExtractor> mImpl;
sp<ABuffer> mPsshBuf;
@@ -464,11 +452,5 @@
return AMEDIA_OK;
}
-EXPORT
-media_status_t AMediaExtractor_disconnect(AMediaExtractor * ex) {
- ex->mImpl->disconnect();
- return AMEDIA_OK;
-}
-
} // extern "C"
diff --git a/media/ndk/NdkMediaMuxer.cpp b/media/ndk/NdkMediaMuxer.cpp
index b213fa9..ab709ac 100644
--- a/media/ndk/NdkMediaMuxer.cpp
+++ b/media/ndk/NdkMediaMuxer.cpp
@@ -21,6 +21,7 @@
#include <media/NdkMediaMuxer.h>
#include <media/NdkMediaCodec.h>
#include <media/NdkMediaFormatPriv.h>
+#include "NdkMediaErrorPriv.h"
#include <utils/Log.h>
@@ -36,14 +37,6 @@
using namespace android;
-static media_status_t translate_error(status_t err) {
- if (err == OK) {
- return AMEDIA_OK;
- }
- ALOGE("sf error code: %d", err);
- return AMEDIA_ERROR_UNKNOWN;
-}
-
struct AMediaMuxer {
sp<MediaMuxer> mImpl;
diff --git a/media/ndk/include/media/NdkMediaDataSource.h b/media/ndk/include/media/NdkMediaDataSource.h
index 021029b..297d4bc 100644
--- a/media/ndk/include/media/NdkMediaDataSource.h
+++ b/media/ndk/include/media/NdkMediaDataSource.h
@@ -43,14 +43,9 @@
/*
* AMediaDataSource's callbacks will be invoked on an implementation-defined thread
* or thread pool. No guarantees are provided about which thread(s) will be used for
- * callbacks. However, it is guaranteed that AMediaDataSource's callbacks will only
- * ever be invoked by a single thread at a time.
- *
- * There will be a thread synchronization point between each call to ensure that
- * modifications to the state of your AMediaDataSource are visible to future
- * calls. This means you don't need to do your own synchronization unless you're
- * modifying the AMediaDataSource from another thread while it's being used by the
- * framework.
+ * callbacks. For example, |close| can be invoked from a different thread than the
+ * thread invoking |readAt|. As such, the Implementations of AMediaDataSource callbacks
+ * must be threadsafe.
*/
/**
@@ -74,9 +69,19 @@
typedef ssize_t (*AMediaDataSourceGetSize)(void *userdata);
/**
- * Called to close the data source and release associated resources.
- * The NDK media framework guarantees that after |close| is called
- * no future callbacks will be invoked on the data source.
+ * Called to close the data source, unblock reads, and release associated
+ * resources.
+ *
+ * The NDK media framework guarantees that after the first |close| is
+ * called, no future callbacks will be invoked on the data source except
+ * for |close| itself.
+ *
+ * Closing a data source allows readAt calls that were blocked waiting
+ * for I/O data to return promptly.
+ *
+ * When using AMediaDataSource as input to AMediaExtractor, closing
+ * has the effect of unblocking slow reads inside of setDataSource
+ * and readSampleData.
*/
typedef void (*AMediaDataSourceClose)(void *userdata);
@@ -161,6 +166,18 @@
#endif /*__ANDROID_API__ >= 28 */
+#if __ANDROID_API__ >= 29
+
+/**
+ * Close the data source, unblock reads, and release associated resources.
+ *
+ * Please refer to the definition of AMediaDataSourceClose for
+ * additional details.
+ */
+void AMediaDataSource_close(AMediaDataSource*) __INTRODUCED_IN(29);
+
+#endif /*__ANDROID_API__ >= 29 */
+
__END_DECLS
#endif // _NDK_MEDIA_DATASOURCE_H
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index a805e87..d13edfc 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -142,6 +142,7 @@
AMediaDataSource_setReadAt; # introduced=28
AMediaDataSource_setUserdata; # introduced=28
AMediaDataSource_newUri; # introduced=29
+ AMediaDataSource_close; # introduced=29
AMediaDrm_closeSession;
AMediaDrm_createByUUID;
AMediaDrm_decrypt;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 6fa0b81..5ea82a7 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1013,6 +1013,23 @@
String8 address = outputDevices.size() > 0 ? outputDevices.itemAt(0)->mAddress
: String8("");
+ // MSD patch may be using the only output stream that can service this request. Release
+ // MSD patch to prioritize this request over any active output on MSD.
+ AudioPatchCollection msdPatches = getMsdPatches();
+ for (size_t i = 0; i < msdPatches.size(); i++) {
+ const auto& patch = msdPatches[i];
+ for (size_t j = 0; j < patch->mPatch.num_sinks; ++j) {
+ const struct audio_port_config *sink = &patch->mPatch.sinks[j];
+ if (sink->type == AUDIO_PORT_TYPE_DEVICE &&
+ (sink->ext.device.type & device) != AUDIO_DEVICE_NONE &&
+ (address.isEmpty() || strncmp(sink->ext.device.address, address.string(),
+ AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
+ releaseAudioPatch(patch->mHandle, mUidCached);
+ break;
+ }
+ }
+ }
+
status = outputDesc->open(config, device, address, stream, *flags, &output);
// only accept an output with the requested parameters
@@ -4565,6 +4582,22 @@
removeOutput(output);
mPreviousOutputs = mOutputs;
+
+ // MSD patches may have been released to support a non-MSD direct output. Reset MSD patch if
+ // no direct outputs are open.
+ if (getMsdAudioOutDeviceTypes() != AUDIO_DEVICE_NONE) {
+ bool directOutputOpen = false;
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ if (mOutputs[i]->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
+ directOutputOpen = true;
+ break;
+ }
+ }
+ if (!directOutputOpen) {
+ ALOGV("no direct outputs open, reset MSD patch");
+ setMsdPatch();
+ }
+ }
}
void AudioPolicyManager::closeInput(audio_io_handle_t input)