diff options
| author | Ronghua Wu <ronghuawu@google.com> | 2015-05-21 12:20:21 -0700 | 
|---|---|---|
| committer | Ronghua Wu <ronghuawu@google.com> | 2015-05-22 10:36:31 -0700 | 
| commit | faeb0f291330134dc4468359a36e099aae508449 (patch) | |
| tree | 028333c0801e03826c4162cb35880236eaae3b3b | |
| parent | 8eddd88568fe4da0ca0ceab5072bc488827f01b5 (diff) | |
| download | frameworks_av-faeb0f291330134dc4468359a36e099aae508449.zip frameworks_av-faeb0f291330134dc4468359a36e099aae508449.tar.gz frameworks_av-faeb0f291330134dc4468359a36e099aae508449.tar.bz2  | |
libmediaplayerservice: try to open audio sink in offload mode in error.
Bug: 19061432
Bug: 21370108
Change-Id: Iaa757555ef37fd1ac87b6e2d5a9969bb58cc5ebc
| -rw-r--r-- | include/media/AudioTrack.h | 15 | ||||
| -rw-r--r-- | include/media/MediaPlayerInterface.h | 3 | ||||
| -rw-r--r-- | media/libmedia/AudioTrack.cpp | 16 | ||||
| -rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.cpp | 9 | ||||
| -rw-r--r-- | media/libmediaplayerservice/MediaPlayerService.h | 3 | ||||
| -rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 21 | ||||
| -rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp | 1 | ||||
| -rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 31 | ||||
| -rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h | 20 | 
9 files changed, 76 insertions, 43 deletions
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index 458f4b4..e9f0131 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -183,6 +183,10 @@ public:       * pid:                Process ID of the app which initially requested this AudioTrack       *                     for power management tracking, or -1 for current process ID.       * pAttributes:        If not NULL, supersedes streamType for use case selection. +     * doNotReconnect:     If set to true, AudioTrack won't automatically recreate the IAudioTrack +                           binder to AudioFlinger. +                           It will return an error instead.  The application will recreate +                           the track based on offloading or different channel configuration, etc.       * threadCanCallJava:  Not present in parameter list, and so is fixed at false.       */ @@ -200,7 +204,8 @@ public:                                      const audio_offload_info_t *offloadInfo = NULL,                                      int uid = -1,                                      pid_t pid = -1, -                                    const audio_attributes_t* pAttributes = NULL); +                                    const audio_attributes_t* pAttributes = NULL, +                                    bool doNotReconnect = false);      /* Creates an audio track and registers it with AudioFlinger.       * With this constructor, the track is configured for static buffer mode. @@ -228,7 +233,8 @@ public:                                      const audio_offload_info_t *offloadInfo = NULL,                                      int uid = -1,                                      pid_t pid = -1, -                                    const audio_attributes_t* pAttributes = NULL); +                                    const audio_attributes_t* pAttributes = NULL, +                                    bool doNotReconnect = false);      /* Terminates the AudioTrack and unregisters it from AudioFlinger.       * Also destroys all resources associated with the AudioTrack. @@ -272,7 +278,8 @@ public:                              const audio_offload_info_t *offloadInfo = NULL,                              int uid = -1,                              pid_t pid = -1, -                            const audio_attributes_t* pAttributes = NULL); +                            const audio_attributes_t* pAttributes = NULL, +                            bool doNotReconnect = false);      /* Result of constructing the AudioTrack. This must be checked for successful initialization       * before using any AudioTrack API (except for set()), because using @@ -877,6 +884,8 @@ protected:          // const after set(), except for bits AUDIO_OUTPUT_FLAG_FAST and AUDIO_OUTPUT_FLAG_OFFLOAD.          // mLock must be held to read or write those bits reliably. +    bool                    mDoNotReconnect; +      int                     mSessionId;      int                     mAuxEffectId; diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index fa917f9..8c36f0e 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -113,7 +113,8 @@ public:                  AudioCallback cb = NULL,                  void *cookie = NULL,                  audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, -                const audio_offload_info_t *offloadInfo = NULL) = 0; +                const audio_offload_info_t *offloadInfo = NULL, +                bool doNotResuscitate = false) = 0;          virtual status_t    start() = 0; diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index db316b0..faf5935 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -178,7 +178,8 @@ AudioTrack::AudioTrack(          const audio_offload_info_t *offloadInfo,          int uid,          pid_t pid, -        const audio_attributes_t* pAttributes) +        const audio_attributes_t* pAttributes, +        bool doNotReconnect)      : mStatus(NO_INIT),        mIsTimed(false),        mPreviousPriority(ANDROID_PRIORITY_NORMAL), @@ -189,7 +190,7 @@ AudioTrack::AudioTrack(      mStatus = set(streamType, sampleRate, format, channelMask,              frameCount, flags, cbf, user, notificationFrames,              0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, -            offloadInfo, uid, pid, pAttributes); +            offloadInfo, uid, pid, pAttributes, doNotReconnect);  }  AudioTrack::AudioTrack( @@ -207,7 +208,8 @@ AudioTrack::AudioTrack(          const audio_offload_info_t *offloadInfo,          int uid,          pid_t pid, -        const audio_attributes_t* pAttributes) +        const audio_attributes_t* pAttributes, +        bool doNotReconnect)      : mStatus(NO_INIT),        mIsTimed(false),        mPreviousPriority(ANDROID_PRIORITY_NORMAL), @@ -218,7 +220,7 @@ AudioTrack::AudioTrack(      mStatus = set(streamType, sampleRate, format, channelMask,              0 /*frameCount*/, flags, cbf, user, notificationFrames,              sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, -            uid, pid, pAttributes); +            uid, pid, pAttributes, doNotReconnect);  }  AudioTrack::~AudioTrack() @@ -266,7 +268,8 @@ status_t AudioTrack::set(          const audio_offload_info_t *offloadInfo,          int uid,          pid_t pid, -        const audio_attributes_t* pAttributes) +        const audio_attributes_t* pAttributes, +        bool doNotReconnect)  {      ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "            "flags #%x, notificationFrames %u, sessionId %d, transferType %d, uid %d, pid %d", @@ -308,6 +311,7 @@ status_t AudioTrack::set(      }      mSharedBuffer = sharedBuffer;      mTransfer = transferType; +    mDoNotReconnect = doNotReconnect;      ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(),              sharedBuffer->size()); @@ -2006,7 +2010,7 @@ status_t AudioTrack::restoreTrack_l(const char *from)      // output parameters and new IAudioFlinger in createTrack_l()      AudioSystem::clearAudioConfigCache(); -    if (isOffloadedOrDirect_l()) { +    if (isOffloadedOrDirect_l() || mDoNotReconnect) {          // FIXME re-creation of offloaded tracks is not yet implemented          return DEAD_OBJECT;      } diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index efbc0d6..9c0af4a 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -1489,7 +1489,8 @@ status_t MediaPlayerService::AudioOutput::open(          audio_format_t format, int bufferCount,          AudioCallback cb, void *cookie,          audio_output_flags_t flags, -        const audio_offload_info_t *offloadInfo) +        const audio_offload_info_t *offloadInfo, +        bool doNotReconnect)  {      mCallback = cb;      mCallbackCookie = cookie; @@ -1605,7 +1606,8 @@ status_t MediaPlayerService::AudioOutput::open(                      offloadInfo,                      mUid,                      mPid, -                    mAttributes); +                    mAttributes, +                    doNotReconnect);          } else {              t = new AudioTrack(                      mStreamType, @@ -1622,7 +1624,8 @@ status_t MediaPlayerService::AudioOutput::open(                      NULL, // offload info                      mUid,                      mPid, -                    mAttributes); +                    mAttributes, +                    doNotReconnect);          }          if ((t == 0) || (t->initCheck() != NO_ERROR)) { diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index 5103841..e9f72b8 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -97,7 +97,8 @@ class MediaPlayerService : public BnMediaPlayerService                  audio_format_t format, int bufferCount,                  AudioCallback cb, void *cookie,                  audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, -                const audio_offload_info_t *offloadInfo = NULL); +                const audio_offload_info_t *offloadInfo = NULL, +                bool doNotReconnect = false);          virtual status_t        start();          virtual ssize_t         write(const void* buffer, size_t size, bool blocking = true); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 96a7adb..87074f0 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -1083,12 +1083,12 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {              } else if (what == Renderer::kWhatMediaRenderingStart) {                  ALOGV("media rendering started");                  notifyListener(MEDIA_STARTED, 0, 0); -            } else if (what == Renderer::kWhatAudioOffloadTearDown) { -                ALOGV("Tear down audio offload, fall back to s/w path if due to error."); +            } else if (what == Renderer::kWhatAudioTearDown) {                  int64_t positionUs;                  CHECK(msg->findInt64("positionUs", &positionUs));                  int32_t reason;                  CHECK(msg->findInt32("reason", &reason)); +                ALOGV("Tear down audio with reason %d.", reason);                  closeAudioSink();                  mAudioDecoder.clear();                  ++mAudioDecoderGeneration; @@ -1100,9 +1100,22 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {                  }                  performSeek(positionUs); +                  if (reason == Renderer::kDueToError) { -                    mRenderer->signalDisableOffloadAudio(); -                    mOffloadAudio = false; +                    sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */); +                    sp<AMessage> videoFormat = mSource->getFormat(false /* audio */); +                    audio_stream_type_t streamType = mAudioSink->getAudioStreamType(); +                    const bool hasVideo = (videoFormat != NULL); +                    const bool canOffload = canOffloadStream( +                            audioMeta, hasVideo, true /* is_streaming */, streamType); +                    if (canOffload) { +                        mRenderer->signalEnableOffloadAudio(); +                        sp<AMessage> format = mSource->getFormat(true /*audio*/); +                        tryOpenAudioSinkForOffload(format, hasVideo); +                    } else { +                        mRenderer->signalDisableOffloadAudio(); +                        mOffloadAudio = false; +                    }                      instantiateDecoder(true /* audio */, &mAudioDecoder);                  }              } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index 376c93a..73f8ba8 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -68,6 +68,7 @@ NuPlayer::Decoder::Decoder(  }  NuPlayer::Decoder::~Decoder() { +    mCodec->release();      releaseAndResetMediaBuffers();  } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 007a335..409dedf 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -82,7 +82,7 @@ NuPlayer::Renderer::Renderer(        mVideoRenderingStartGeneration(0),        mAudioRenderingStartGeneration(0),        mAudioOffloadPauseTimeoutGeneration(0), -      mAudioOffloadTornDown(false), +      mAudioTornDown(false),        mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),        mCurrentPcmInfo(AUDIO_PCMINFO_INITIALIZER),        mTotalBuffersQueued(0), @@ -566,9 +566,9 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {              break;          } -        case kWhatAudioOffloadTearDown: +        case kWhatAudioTearDown:          { -            onAudioOffloadTearDown(kDueToError); +            onAudioTearDown(kDueToError);              break;          } @@ -580,7 +580,7 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {                  break;              }              ALOGV("Audio Offload tear down due to pause timeout."); -            onAudioOffloadTearDown(kDueToTimeout); +            onAudioTearDown(kDueToTimeout);              mWakeLock->release();              break;          } @@ -648,7 +648,7 @@ size_t NuPlayer::Renderer::AudioSinkCallback(          case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN:          { -            me->notifyAudioOffloadTearDown(); +            me->notifyAudioTearDown();              break;          }      } @@ -792,6 +792,7 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {                  ALOGW("AudioSink write would block when writing %zu bytes", copy);              } else {                  ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy); +                notifyAudioTearDown();              }              break;          } @@ -1060,8 +1061,8 @@ void NuPlayer::Renderer::notifyEOS(bool audio, status_t finalResult, int64_t del      notify->post(delayUs);  } -void NuPlayer::Renderer::notifyAudioOffloadTearDown() { -    (new AMessage(kWhatAudioOffloadTearDown, this))->post(); +void NuPlayer::Renderer::notifyAudioTearDown() { +    (new AMessage(kWhatAudioTearDown, this))->post();  }  void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) { @@ -1480,11 +1481,11 @@ int64_t NuPlayer::Renderer::getPlayedOutAudioDurationUs(int64_t nowUs) {      return durationUs;  } -void NuPlayer::Renderer::onAudioOffloadTearDown(AudioOffloadTearDownReason reason) { -    if (mAudioOffloadTornDown) { +void NuPlayer::Renderer::onAudioTearDown(AudioTearDownReason reason) { +    if (mAudioTornDown) {          return;      } -    mAudioOffloadTornDown = true; +    mAudioTornDown = true;      int64_t currentPositionUs;      if (getCurrentPosition(¤tPositionUs) != OK) { @@ -1495,7 +1496,7 @@ void NuPlayer::Renderer::onAudioOffloadTearDown(AudioOffloadTearDownReason reaso      mAudioSink->flush();      sp<AMessage> notify = mNotify->dup(); -    notify->setInt32("what", kWhatAudioOffloadTearDown); +    notify->setInt32("what", kWhatAudioTearDown);      notify->setInt64("positionUs", currentPositionUs);      notify->setInt32("reason", reason);      notify->post(); @@ -1653,7 +1654,9 @@ status_t NuPlayer::Renderer::onOpenAudioSink(                      8 /* bufferCount */,                      NULL,                      NULL, -                    (audio_output_flags_t)pcmFlags); +                    (audio_output_flags_t)pcmFlags, +                    NULL, +                    true /* doNotReconnect */);          if (err == OK) {              err = mAudioSink->setPlaybackRate(mPlaybackSettings);          } @@ -1668,9 +1671,7 @@ status_t NuPlayer::Renderer::onOpenAudioSink(      if (audioSinkChanged) {          onAudioSinkChanged();      } -    if (offloadingAudio()) { -        mAudioOffloadTornDown = false; -    } +    mAudioTornDown = false;      return OK;  } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h index 928b71b..fbdf5bf 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h @@ -82,16 +82,16 @@ struct NuPlayer::Renderer : public AHandler {      void closeAudioSink();      enum { -        kWhatEOS                 = 'eos ', -        kWhatFlushComplete       = 'fluC', -        kWhatPosition            = 'posi', -        kWhatVideoRenderingStart = 'vdrd', -        kWhatMediaRenderingStart = 'mdrd', -        kWhatAudioOffloadTearDown = 'aOTD', +        kWhatEOS                      = 'eos ', +        kWhatFlushComplete            = 'fluC', +        kWhatPosition                 = 'posi', +        kWhatVideoRenderingStart      = 'vdrd', +        kWhatMediaRenderingStart      = 'mdrd', +        kWhatAudioTearDown            = 'adTD',          kWhatAudioOffloadPauseTimeout = 'aOPT',      }; -    enum AudioOffloadTearDownReason { +    enum AudioTearDownReason {          kDueToError = 0,          kDueToTimeout,      }; @@ -179,7 +179,7 @@ private:      int64_t mLastPositionUpdateUs;      int32_t mAudioOffloadPauseTimeoutGeneration; -    bool mAudioOffloadTornDown; +    bool mAudioTornDown;      audio_offload_info_t mCurrentOffloadInfo;      struct PcmInfo { @@ -242,7 +242,7 @@ private:      int32_t getQueueGeneration(bool audio);      int32_t getDrainGeneration(bool audio);      bool getSyncQueues(); -    void onAudioOffloadTearDown(AudioOffloadTearDownReason reason); +    void onAudioTearDown(AudioTearDownReason reason);      status_t onOpenAudioSink(              const sp<AMessage> &format,              bool offloadOnly, @@ -255,7 +255,7 @@ private:      void notifyPosition();      void notifyVideoLateBy(int64_t lateByUs);      void notifyVideoRenderingStart(); -    void notifyAudioOffloadTearDown(); +    void notifyAudioTearDown();      void flushQueue(List<QueueEntry> *queue);      bool dropBufferIfStale(bool audio, const sp<AMessage> &msg);  | 
