diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/libmedia/AudioSystem.cpp | 14 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 10 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp | 6 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 66 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.h | 3 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp | 5 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 18 | ||||
-rw-r--r-- | media/libstagefright/ACodec.cpp | 1 | ||||
-rw-r--r-- | media/libstagefright/CameraSource.cpp | 5 |
9 files changed, 119 insertions, 9 deletions
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 3bfb09a..9d645f0 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -476,7 +476,7 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(audio_io_config_event even switch (event) { case AUDIO_OUTPUT_OPENED: case AUDIO_INPUT_OPENED: { - sp<AudioIoDescriptor> oldDesc = getIoDescriptor(ioDesc->mIoHandle); + sp<AudioIoDescriptor> oldDesc = getIoDescriptor_l(ioDesc->mIoHandle); if (oldDesc == 0) { mIoDescriptors.add(ioDesc->mIoHandle, ioDesc); } else { @@ -498,7 +498,7 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(audio_io_config_event even } break; case AUDIO_OUTPUT_CLOSED: case AUDIO_INPUT_CLOSED: { - if (getIoDescriptor(ioDesc->mIoHandle) == 0) { + if (getIoDescriptor_l(ioDesc->mIoHandle) == 0) { ALOGW("ioConfigChanged() closing unknown %s %d", event == AUDIO_OUTPUT_CLOSED ? "output" : "input", ioDesc->mIoHandle); break; @@ -512,7 +512,7 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(audio_io_config_event even case AUDIO_OUTPUT_CONFIG_CHANGED: case AUDIO_INPUT_CONFIG_CHANGED: { - sp<AudioIoDescriptor> oldDesc = getIoDescriptor(ioDesc->mIoHandle); + sp<AudioIoDescriptor> oldDesc = getIoDescriptor_l(ioDesc->mIoHandle); if (oldDesc == 0) { ALOGW("ioConfigChanged() modifying unknown output! %d", ioDesc->mIoHandle); break; @@ -575,7 +575,7 @@ status_t AudioSystem::AudioFlingerClient::getInputBufferSize( return NO_ERROR; } -sp<AudioIoDescriptor> AudioSystem::AudioFlingerClient::getIoDescriptor(audio_io_handle_t ioHandle) +sp<AudioIoDescriptor> AudioSystem::AudioFlingerClient::getIoDescriptor_l(audio_io_handle_t ioHandle) { sp<AudioIoDescriptor> desc; ssize_t index = mIoDescriptors.indexOfKey(ioHandle); @@ -585,6 +585,12 @@ sp<AudioIoDescriptor> AudioSystem::AudioFlingerClient::getIoDescriptor(audio_io_ return desc; } +sp<AudioIoDescriptor> AudioSystem::AudioFlingerClient::getIoDescriptor(audio_io_handle_t ioHandle) +{ + Mutex::Autolock _l(mLock); + return getIoDescriptor_l(ioHandle); +} + status_t AudioSystem::AudioFlingerClient::addAudioDeviceCallback( const sp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo) { diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index f46b66e..2d9fcf7 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -999,14 +999,18 @@ status_t AudioTrack::getPosition(uint32_t *position) return NO_ERROR; } - if (AVMediaUtils::get()->AudioTrackGetPosition(this, position) == NO_ERROR) { + if (AVMediaUtils::get()->AudioTrackIsPcmOffloaded(mFormat) && + AVMediaUtils::get()->AudioTrackGetPosition(this, position) == NO_ERROR) { return NO_ERROR; } if (mOutput != AUDIO_IO_HANDLE_NONE) { uint32_t halFrames; // actually unused - (void) AudioSystem::getRenderPosition(mOutput, &halFrames, &dspFrames); - // FIXME: on getRenderPosition() error, we return OK with frame position 0. + status_t status = AudioSystem::getRenderPosition(mOutput, &halFrames, &dspFrames); + if (status != NO_ERROR) { + ALOGW("failed to getRenderPosition for offload session status %d", status); + return INVALID_OPERATION; + } } // FIXME: dspFrames may not be zero in (mState == STATE_STOPPED || mState == STATE_FLUSHED) // due to hardware latency. We leave this behavior for now. diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp index 6683481..a57fdc1 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp @@ -212,7 +212,11 @@ status_t NuPlayer::HTTPLiveSource::selectTrack(size_t trackIndex, bool select, i } status_t NuPlayer::HTTPLiveSource::seekTo(int64_t seekTimeUs) { - return mLiveSession->seekTo(seekTimeUs); + if (mLiveSession->isSeekable()) { + return mLiveSession->seekTo(seekTimeUs); + } else { + return INVALID_OPERATION; + } } void NuPlayer::HTTPLiveSource::pollForRawData( diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 86c35e2..356c519 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -131,6 +131,23 @@ private: DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction); }; +struct NuPlayer::InstantiateDecoderAction : public Action { + InstantiateDecoderAction(bool audio, sp<DecoderBase> *decoder) + : mAudio(audio), + mdecoder(decoder) { + } + + virtual void execute(NuPlayer *player) { + player->instantiateDecoder(mAudio, mdecoder); + } + +private: + bool mAudio; + sp<DecoderBase> *mdecoder; + + DISALLOW_EVIL_CONSTRUCTORS(InstantiateDecoderAction); +}; + struct NuPlayer::PostMessageAction : public Action { PostMessageAction(const sp<AMessage> &msg) : mMessage(msg) { @@ -226,7 +243,7 @@ bool NuPlayer::IsHTTPLiveURL(const char *url) { return true; } - if (strstr(url,"m3u8")) { + if (strstr(url,".m3u8")) { return true; } } @@ -1093,6 +1110,12 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { int32_t reason; CHECK(msg->findInt32("reason", &reason)); ALOGV("Tear down audio with reason %d.", reason); + + if (ifDecodedPCMOffload()) { + tearDownPCMOffload(msg); + break; + } + mAudioDecoder.clear(); ++mAudioDecoderGeneration; bool needsToCreateAudioDecoder = true; @@ -2384,4 +2407,45 @@ void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) { TRESPASS(); } +void NuPlayer::tearDownPCMOffload(const sp<AMessage> &msg) { + int32_t reason; + CHECK(msg->findInt32("reason", &reason)); + + if (mAudioDecoder != NULL) { + switch (mFlushingAudio) { + case NONE: + case FLUSHING_DECODER: + mDeferredActions.push_back( + new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */, + FLUSH_CMD_NONE /* video */)); + + if (reason == Renderer::kDueToError) { + mDeferredActions.push_back( + new InstantiateDecoderAction(true /* audio */, &mAudioDecoder)); + } + + int64_t positionUs; + if (!msg->findInt64("positionUs", &positionUs)) { + positionUs = mPreviousSeekTimeUs; + } + mDeferredActions.push_back(new SeekAction(positionUs)); + break; + default: + ALOGW("tearDownPCMOffload while flushing audio in %d", mFlushingAudio); + break; + } + } + + if (mRenderer != NULL) { + closeAudioSink(); + mRenderer->flush( + true /* audio */, false /* notifyComplete */); + if (mVideoDecoder != NULL) { + mRenderer->flush( + false /* audio */, false /* notifyComplete */); + } + } + processDeferredActions(); +} + } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index 4ed3079..c0aa782 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -109,6 +109,7 @@ public: struct SetSurfaceAction; struct ResumeDecoderAction; struct FlushDecoderAction; + struct InstantiateDecoderAction; struct PostMessageAction; struct SimpleAction; @@ -279,6 +280,8 @@ protected: void writeTrackInfo(Parcel* reply, const sp<AMessage> format) const; + void tearDownPCMOffload(const sp<AMessage> &msg); + DISALLOW_EVIL_CONSTRUCTORS(NuPlayer); }; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index 27650d7..f83eaf6 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -565,6 +565,11 @@ bool NuPlayer::Decoder::handleAnOutputBuffer( sp<ABuffer> buffer; mCodec->getOutputBuffer(index, &buffer); + if (buffer == NULL) { + handleError(UNKNOWN_ERROR); + return false; + } + if (index >= mOutputBuffers.size()) { for (size_t i = mOutputBuffers.size(); i <= index; ++i) { mOutputBuffers.add(); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index aa993a9..9d2f134 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -83,6 +83,16 @@ const NuPlayer::Renderer::PcmInfo NuPlayer::Renderer::AUDIO_PCMINFO_INITIALIZER // static const int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll; +static bool sFrameAccurateAVsync = false; + +static void readProperties() { + char value[PROPERTY_VALUE_MAX]; + if (property_get("persist.sys.media.avsync", value, NULL)) { + sFrameAccurateAVsync = + !strcmp("1", value) || !strcasecmp("true", value); + } +} + NuPlayer::Renderer::Renderer( const sp<MediaPlayerBase::AudioSink> &sink, const sp<AMessage> ¬ify, @@ -124,6 +134,7 @@ NuPlayer::Renderer::Renderer( mMediaClock = new MediaClock; mPlaybackRate = mPlaybackSettings.mSpeed; mMediaClock->setPlaybackRate(mPlaybackRate); + readProperties(); } NuPlayer::Renderer::~Renderer() { @@ -1065,6 +1076,11 @@ void NuPlayer::Renderer::postDrainVideoQueue() { ALOGW_IF(delayUs > 500000, "unusually high delayUs: %" PRId64, delayUs); // post 2 display refreshes before rendering is due + // FIXME currently this increases power consumption, so unless frame-accurate + // AV sync is requested, post closer to required render time (at 0.63 vsyncs) + if (!sFrameAccurateAVsync) { + twoVsyncsUs >>= 4; + } msg->post(delayUs > twoVsyncsUs ? delayUs - twoVsyncsUs : 0); mDrainVideoQueuePending = true; @@ -1477,6 +1493,8 @@ void NuPlayer::Renderer::onPause() { } void NuPlayer::Renderer::onResume() { + readProperties(); + if (!mPaused) { return; } diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 78ab3db..a132637 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -4615,6 +4615,7 @@ bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { ALOGI("[%s] forcing the release of codec", mCodec->mComponentName.c_str()); status_t err = mCodec->mOMX->freeNode(mCodec->mNode); + mCodec->changeState(mCodec->mUninitializedState); ALOGE_IF("[%s] failed to release codec instance: err=%d", mCodec->mComponentName.c_str(), err); sp<AMessage> notify = mCodec->mNotify->dup(); diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index 41513fb..27a6086 100644 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -100,6 +100,11 @@ void CameraSourceListener::postDataTimestamp( } static int32_t getColorFormat(const char* colorFormat) { + if (!colorFormat) { + ALOGE("Invalid color format"); + return -1; + } + if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420P)) { return OMX_COLOR_FormatYUV420Planar; } |