Skip to content

Commit 4ed260f

Browse files
committed
Add channel mask in AudioSink
Add support for specifying a channel mask when opening an AudioSink. This parameter does not replace the channel count parameter in order to not have to duplicate the logic to derive a mask from the channel count everywhere an AudioSink is used without a known mask. A mask of 0 (CHANNEL_MASK_USE_CHANNEL_ORDER) means a mask will be automatically derived from the number of channels. Update existing AudioSink implementations to use the channel mask, and users of AudioSink to specify the mask if available, and CHANNEL_MASK_USE_CHANNEL_ORDER otherwise. Change-Id: Ifa9bd259874816dbc25ead2b03ea52e873cff474
1 parent e6e47f0 commit 4ed260f

File tree

7 files changed

+42
-17
lines changed

7 files changed

+42
-17
lines changed

include/media/MediaPlayerInterface.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ enum player_type {
6060
#define DEFAULT_AUDIOSINK_BUFFERSIZE 1200
6161
#define DEFAULT_AUDIOSINK_SAMPLERATE 44100
6262

63+
// when the channel mask isn't known, use the channel count to derive a mask in AudioSink::open()
64+
#define CHANNEL_MASK_USE_CHANNEL_ORDER 0
6365

6466
// callback mechanism for passing messages to MediaPlayer object
6567
typedef void (*notify_callback_f)(void* cookie,
@@ -91,7 +93,7 @@ class MediaPlayerBase : public RefBase
9193
// If no callback is specified, use the "write" API below to submit
9294
// audio data.
9395
virtual status_t open(
94-
uint32_t sampleRate, int channelCount,
96+
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
9597
audio_format_t format=AUDIO_FORMAT_PCM_16_BIT,
9698
int bufferCount=DEFAULT_AUDIOSINK_BUFFERCOUNT,
9799
AudioCallback cb = NULL,

include/media/stagefright/MetaData.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ enum {
4343
kKeyStride = 'strd', // int32_t
4444
kKeySliceHeight = 'slht', // int32_t
4545
kKeyChannelCount = '#chn', // int32_t
46+
kKeyChannelMask = 'chnm', // int32_t
4647
kKeySampleRate = 'srte', // int32_t (audio sampling rate Hz)
4748
kKeyFrameRate = 'frmR', // int32_t (video frame rate fps)
4849
kKeyBitRate = 'brte', // int32_t (bps)

media/libmediaplayerservice/MediaPlayerService.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,7 +1458,8 @@ status_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position)
14581458
}
14591459

14601460
status_t MediaPlayerService::AudioOutput::open(
1461-
uint32_t sampleRate, int channelCount, audio_format_t format, int bufferCount,
1461+
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
1462+
audio_format_t format, int bufferCount,
14621463
AudioCallback cb, void *cookie)
14631464
{
14641465
mCallback = cb;
@@ -1470,7 +1471,8 @@ status_t MediaPlayerService::AudioOutput::open(
14701471
bufferCount = mMinBufferCount;
14711472

14721473
}
1473-
ALOGV("open(%u, %d, %d, %d, %d)", sampleRate, channelCount, format, bufferCount,mSessionId);
1474+
ALOGV("open(%u, %d, 0x%x, %d, %d, %d)", sampleRate, channelCount, channelMask,
1475+
format, bufferCount, mSessionId);
14741476
if (mTrack) close();
14751477
int afSampleRate;
14761478
int afFrameCount;
@@ -1485,13 +1487,21 @@ status_t MediaPlayerService::AudioOutput::open(
14851487

14861488
frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate;
14871489

1490+
if (channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER) {
1491+
channelMask = audio_channel_mask_from_count(channelCount);
1492+
if (0 == channelMask) {
1493+
ALOGE("open() error, can\'t derive mask for %d audio channels", channelCount);
1494+
return NO_INIT;
1495+
}
1496+
}
1497+
14881498
AudioTrack *t;
14891499
if (mCallback != NULL) {
14901500
t = new AudioTrack(
14911501
mStreamType,
14921502
sampleRate,
14931503
format,
1494-
(channelCount == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO,
1504+
channelMask,
14951505
frameCount,
14961506
0 /* flags */,
14971507
CallbackWrapper,
@@ -1503,7 +1513,7 @@ status_t MediaPlayerService::AudioOutput::open(
15031513
mStreamType,
15041514
sampleRate,
15051515
format,
1506-
(channelCount == 2) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO,
1516+
channelMask,
15071517
frameCount,
15081518
0,
15091519
NULL,
@@ -1751,10 +1761,11 @@ bool CallbackThread::threadLoop() {
17511761
////////////////////////////////////////////////////////////////////////////////
17521762

17531763
status_t MediaPlayerService::AudioCache::open(
1754-
uint32_t sampleRate, int channelCount, audio_format_t format, int bufferCount,
1764+
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
1765+
audio_format_t format, int bufferCount,
17551766
AudioCallback cb, void *cookie)
17561767
{
1757-
ALOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount);
1768+
ALOGV("open(%u, %d, 0x%x, %d, %d)", sampleRate, channelCount, channelMask, format, bufferCount);
17581769
if (mHeap->getHeapID() < 0) {
17591770
return NO_INIT;
17601771
}

media/libmediaplayerservice/MediaPlayerService.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class MediaPlayerService : public BnMediaPlayerService
8585
virtual int getSessionId();
8686

8787
virtual status_t open(
88-
uint32_t sampleRate, int channelCount,
88+
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
8989
audio_format_t format, int bufferCount,
9090
AudioCallback cb, void *cookie);
9191

@@ -145,8 +145,8 @@ class MediaPlayerService : public BnMediaPlayerService
145145
virtual int getSessionId();
146146

147147
virtual status_t open(
148-
uint32_t sampleRate, int channelCount, audio_format_t format,
149-
int bufferCount = 1,
148+
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
149+
audio_format_t format, int bufferCount = 1,
150150
AudioCallback cb = NULL, void *cookie = NULL);
151151

152152
virtual void start();

media/libmediaplayerservice/MidiFile.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,8 @@ status_t MidiFile::setLooping(int loop)
421421
}
422422

423423
status_t MidiFile::createOutputTrack() {
424-
if (mAudioSink->open(pLibConfig->sampleRate, pLibConfig->numChannels, AUDIO_FORMAT_PCM_16_BIT, 2) != NO_ERROR) {
424+
if (mAudioSink->open(pLibConfig->sampleRate, pLibConfig->numChannels,
425+
CHANNEL_MASK_USE_CHANNEL_ORDER, AUDIO_FORMAT_PCM_16_BIT, 2) != NO_ERROR) {
425426
ALOGE("mAudioSink open failed");
426427
return ERROR_OPEN_FAILED;
427428
}

media/libmediaplayerservice/nuplayer/NuPlayer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
336336
CHECK_EQ(mAudioSink->open(
337337
sampleRate,
338338
numChannels,
339+
CHANNEL_MASK_USE_CHANNEL_ORDER,
339340
AUDIO_FORMAT_PCM_16_BIT,
340341
8 /* bufferCount */),
341342
(status_t)OK);

media/libstagefright/AudioPlayer.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,18 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
110110
success = format->findInt32(kKeySampleRate, &mSampleRate);
111111
CHECK(success);
112112

113-
int32_t numChannels;
113+
int32_t numChannels, channelMask;
114114
success = format->findInt32(kKeyChannelCount, &numChannels);
115115
CHECK(success);
116116

117+
if(!format->findInt32(kKeyChannelMask, &channelMask)) {
118+
ALOGW("source format didn't specify channel mask, using channel order");
119+
channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
120+
}
121+
117122
if (mAudioSink.get() != NULL) {
118123
status_t err = mAudioSink->open(
119-
mSampleRate, numChannels, AUDIO_FORMAT_PCM_16_BIT,
124+
mSampleRate, numChannels, channelMask, AUDIO_FORMAT_PCM_16_BIT,
120125
DEFAULT_AUDIOSINK_BUFFERCOUNT,
121126
&AudioPlayer::AudioSinkCallback, this);
122127
if (err != OK) {
@@ -137,11 +142,15 @@ status_t AudioPlayer::start(bool sourceAlreadyStarted) {
137142

138143
mAudioSink->start();
139144
} else {
145+
// playing to an AudioTrack, set up mask if necessary
146+
audio_channel_mask_t audioMask = channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER ?
147+
audio_channel_mask_from_count(numChannels) : channelMask;
148+
if (0 == audioMask) {
149+
return BAD_VALUE;
150+
}
151+
140152
mAudioTrack = new AudioTrack(
141-
AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT,
142-
(numChannels == 2)
143-
? AUDIO_CHANNEL_OUT_STEREO
144-
: AUDIO_CHANNEL_OUT_MONO,
153+
AUDIO_STREAM_MUSIC, mSampleRate, AUDIO_FORMAT_PCM_16_BIT, audioMask,
145154
0, 0, &AudioCallback, this, 0);
146155

147156
if ((err = mAudioTrack->initCheck()) != OK) {

0 commit comments

Comments
 (0)