From a0129612ed5a335de8838f88ddddfaf948a5993c Mon Sep 17 00:00:00 2001 From: jiabin Date: Sun, 9 Dec 2018 13:07:40 -0800 Subject: Add channel mask in SoundPool sample. There may be channel mask information after extracting from files. For instance, haptic-audio coupled ogg file. In that case, it is preferred using that channel mask directly to create AudioTrack instead of using channel count to calculate a channel mask. Test: manully test with playing with SoundPool. Bug: 111454766 Change-Id: I0483365cbc1b93587d1c4738b0ed25b2d800718d --- media/jni/soundpool/SoundPool.cpp | 17 ++++++++++++++--- media/jni/soundpool/SoundPool.h | 26 ++++++++++++++------------ 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp index ed2afdd84a7c..5f513207bd5f 100644 --- a/media/jni/soundpool/SoundPool.cpp +++ b/media/jni/soundpool/SoundPool.cpp @@ -513,7 +513,8 @@ Sample::~Sample() static status_t decode(int fd, int64_t offset, int64_t length, uint32_t *rate, int *numChannels, audio_format_t *audioFormat, - sp heap, size_t *memsize) { + audio_channel_mask_t *channelMask, sp heap, + size_t *memsize) { ALOGV("fd %d, offset %" PRId64 ", size %" PRId64, fd, offset, length); AMediaExtractor *ex = AMediaExtractor_new(); @@ -650,6 +651,10 @@ static status_t decode(int fd, int64_t offset, int64_t length, (void)AMediaFormat_delete(format); return UNKNOWN_ERROR; } + if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_MASK, + (int32_t*) channelMask)) { + *channelMask = AUDIO_CHANNEL_NONE; + } (void)AMediaFormat_delete(format); *memsize = written; return OK; @@ -665,12 +670,13 @@ status_t Sample::doLoad() uint32_t sampleRate; int numChannels; audio_format_t format; + audio_channel_mask_t channelMask; status_t status; mHeap = new MemoryHeapBase(kDefaultHeapSize); ALOGV("Start decode"); status = decode(mFd, mOffset, mLength, &sampleRate, &numChannels, &format, - mHeap, &mSize); + &channelMask, mHeap, &mSize); ALOGV("close(%d)", mFd); ::close(mFd); mFd = -1; @@ -697,6 +703,7 @@ status_t Sample::doLoad() mSampleRate = sampleRate; mNumChannels = numChannels; mFormat = format; + mChannelMask = channelMask; mState = READY; return NO_ERROR; @@ -781,7 +788,11 @@ void SoundChannel::play(const sp& sample, int nextChannelID, float leftV // wrong audio audio buffer size (mAudioBufferSize) unsigned long toggle = mToggle ^ 1; void *userData = (void *)((unsigned long)this | toggle); - audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(numChannels); + audio_channel_mask_t sampleChannelMask = sample->channelMask(); + // When sample contains a not none channel mask, use it as is. + // Otherwise, use channel count to calculate channel mask. + audio_channel_mask_t channelMask = sampleChannelMask != AUDIO_CHANNEL_NONE + ? sampleChannelMask : audio_channel_out_mask_from_count(numChannels); // do not create a new audio track if current track is compatible with sample parameters #ifdef USE_SHARED_MEM_BUFFER diff --git a/media/jni/soundpool/SoundPool.h b/media/jni/soundpool/SoundPool.h index 5c48a907c832..9d7410305c2c 100644 --- a/media/jni/soundpool/SoundPool.h +++ b/media/jni/soundpool/SoundPool.h @@ -58,6 +58,7 @@ public: int numChannels() { return mNumChannels; } int sampleRate() { return mSampleRate; } audio_format_t format() { return mFormat; } + audio_channel_mask_t channelMask() { return mChannelMask; } size_t size() { return mSize; } int state() { return mState; } uint8_t* data() { return static_cast(mData->pointer()); } @@ -68,18 +69,19 @@ public: private: void init(); - size_t mSize; - volatile int32_t mRefCount; - uint16_t mSampleID; - uint16_t mSampleRate; - uint8_t mState; - uint8_t mNumChannels; - audio_format_t mFormat; - int mFd; - int64_t mOffset; - int64_t mLength; - sp mData; - sp mHeap; + size_t mSize; + volatile int32_t mRefCount; + uint16_t mSampleID; + uint16_t mSampleRate; + uint8_t mState; + uint8_t mNumChannels; + audio_format_t mFormat; + audio_channel_mask_t mChannelMask; + int mFd; + int64_t mOffset; + int64_t mLength; + sp mData; + sp mHeap; }; // stores pending events for stolen channels -- cgit v1.2.3-59-g8ed1b