diff options
18 files changed, 100 insertions, 34 deletions
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index 42883b5..42fa3be 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -942,6 +942,7 @@ protected: // For Device Selection API // a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing. audio_port_handle_t mSelectedDeviceId; + bool mPlaybackRateSet; private: class DeathNotifier : public IBinder::DeathRecipient { diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h index d68227c..2f2057f 100644 --- a/include/media/stagefright/MediaExtractor.h +++ b/include/media/stagefright/MediaExtractor.h @@ -41,7 +41,8 @@ public: } static sp<MediaExtractor> Create( - const sp<DataSource> &source, const char *mime = NULL); + const sp<DataSource> &source, const char *mime = NULL, + const uint32_t flags = 0); virtual size_t countTracks() = 0; virtual sp<MediaSource> getTrack(size_t index) = 0; @@ -79,6 +80,7 @@ public: } virtual void setUID(uid_t uid) { } + virtual void setExtraFlags(uint32_t flag) {} protected: MediaExtractor() : mIsDrm(false) {} diff --git a/media/libavextensions/media/AVMediaExtensions.h b/media/libavextensions/media/AVMediaExtensions.h index 6cf39f2..ae26143 100644 --- a/media/libavextensions/media/AVMediaExtensions.h +++ b/media/libavextensions/media/AVMediaExtensions.h @@ -47,12 +47,12 @@ struct AVMediaUtils { return false; } virtual status_t AudioTrackGetPosition(AudioTrack* /*track*/, - uint32_t* /*position*/) { + uint32_t* /*position*/) { return NO_INIT; } virtual status_t AudioTrackGetTimestamp(AudioTrack* /*track*/, - AudioTimestamp /*timestamp*/) { + AudioTimestamp* /*timestamp*/) { return NO_INIT; } diff --git a/media/libavextensions/mediaplayerservice/AVNuExtensions.h b/media/libavextensions/mediaplayerservice/AVNuExtensions.h index 9aa4cde..5a7a0cb 100644 --- a/media/libavextensions/mediaplayerservice/AVNuExtensions.h +++ b/media/libavextensions/mediaplayerservice/AVNuExtensions.h @@ -80,6 +80,8 @@ struct AVNuUtils { virtual void setDecodedPCMFormat(const sp<AMessage> &); virtual status_t convertToSinkFormatIfNeeded(const sp<ABuffer> &, sp<ABuffer> &, audio_format_t sinkFormat, bool isOffload); + virtual uint32_t getUseSetBuffersFlag(); + virtual bool canUseSetBuffers(const sp<MetaData> &Meta); virtual void printFileName(int fd); virtual void checkFormatChange(bool *formatChange, const sp<ABuffer> &accessUnit); diff --git a/media/libavextensions/mediaplayerservice/AVNuUtils.cpp b/media/libavextensions/mediaplayerservice/AVNuUtils.cpp index 08a96a3..ba837e4 100644 --- a/media/libavextensions/mediaplayerservice/AVNuUtils.cpp +++ b/media/libavextensions/mediaplayerservice/AVNuUtils.cpp @@ -146,6 +146,14 @@ void AVNuUtils::addFlagsInMeta(const sp<ABuffer> & /*buffer*/, int32_t /*flags*/, bool /*isAudio*/) { } +uint32_t AVNuUtils::getUseSetBuffersFlag() { + return 0; +} + +bool AVNuUtils::canUseSetBuffers(const sp<MetaData> &/*Meta*/) { + return false; +} + // ----- NO TRESSPASSING BEYOND THIS LINE ------ AVNuUtils::AVNuUtils() {} diff --git a/media/libavextensions/stagefright/AVExtensions.h b/media/libavextensions/stagefright/AVExtensions.h index 17ea475..937180f 100644 --- a/media/libavextensions/stagefright/AVExtensions.h +++ b/media/libavextensions/stagefright/AVExtensions.h @@ -68,10 +68,10 @@ struct AVFactory { virtual sp<ACodec> createACodec(); virtual MediaExtractor* createExtendedExtractor( const sp<DataSource> &source, const char *mime, - const sp<AMessage> &meta); + const sp<AMessage> &meta, const uint32_t flags); virtual sp<MediaExtractor> updateExtractor( sp<MediaExtractor> ext, const sp<DataSource> &source, - const char *mime, const sp<AMessage> &meta); + const char *mime, const sp<AMessage> &meta, const uint32_t flags); virtual sp<NuCachedSource2> createCachedSource( const sp<DataSource> &source, const char *cacheConfig = NULL, diff --git a/media/libavextensions/stagefright/AVFactory.cpp b/media/libavextensions/stagefright/AVFactory.cpp index 90ac7b2..2a3810d 100644 --- a/media/libavextensions/stagefright/AVFactory.cpp +++ b/media/libavextensions/stagefright/AVFactory.cpp @@ -57,13 +57,14 @@ sp<ACodec> AVFactory::createACodec() { } MediaExtractor* AVFactory::createExtendedExtractor( - const sp<DataSource> &, const char *, const sp<AMessage> &) { + const sp<DataSource> &, const char *, const sp<AMessage> &, + const uint32_t) { return NULL; } sp<MediaExtractor> AVFactory::updateExtractor( sp<MediaExtractor> ext, const sp<DataSource> &, - const char *, const sp<AMessage> &) { + const char *, const sp<AMessage> &, const uint32_t) { return ext; } diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 4a4df54..5af70d3 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -31,6 +31,7 @@ #include <media/AudioPolicyHelper.h> #include <media/AudioResamplerPublic.h> #include "media/AVMediaExtensions.h" +#include <cutils/properties.h> #define WAIT_PERIOD_MS 10 #define WAIT_STREAM_END_TIMEOUT_SEC 120 @@ -168,7 +169,8 @@ AudioTrack::AudioTrack() mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT), mPausedPosition(0), - mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE) + mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), + mPlaybackRateSet(false) { mAttributes.content_type = AUDIO_CONTENT_TYPE_UNKNOWN; mAttributes.usage = AUDIO_USAGE_UNKNOWN; @@ -198,7 +200,8 @@ AudioTrack::AudioTrack( mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT), mPausedPosition(0), - mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE) + mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), + mPlaybackRateSet(false) { mStatus = set(streamType, sampleRate, format, channelMask, frameCount, flags, cbf, user, notificationFrames, @@ -228,7 +231,8 @@ AudioTrack::AudioTrack( mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT), mPausedPosition(0), - mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE) + mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), + mPlaybackRateSet(false) { mStatus = set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags, cbf, user, notificationFrames, @@ -844,6 +848,15 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) //set effective rates mProxy->setPlaybackRate(playbackRateTemp); mProxy->setSampleRate(effectiveRate); // FIXME: not quite "atomic" with setPlaybackRate + + // fallback out of Direct PCM if setPlaybackRate is called on PCM track + if (property_get_bool("audio.offload.track.enable", false) && + (mFormat == AUDIO_FORMAT_PCM_16_BIT) && (mOffloadInfo == NULL) && + (mFlags == AUDIO_OUTPUT_FLAG_NONE)) { + mPlaybackRateSet = true; + android_atomic_or(CBLK_INVALID, &mCblk->mFlags); + } + return NO_ERROR; } @@ -1135,11 +1148,16 @@ status_t AudioTrack::createTrack_l() audio_stream_type_t streamType = mStreamType; audio_attributes_t *attr = (mStreamType == AUDIO_STREAM_DEFAULT) ? &mAttributes : NULL; - status_t status; - status = AudioSystem::getOutputForAttr(attr, &output, + audio_offload_info_t tOffloadInfo = AUDIO_INFO_INITIALIZER; + if (mPlaybackRateSet == true && mOffloadInfo == NULL && mFormat == AUDIO_FORMAT_PCM_16_BIT) { + mOffloadInfo = &tOffloadInfo; + } + status_t status = AudioSystem::getOutputForAttr(attr, &output, (audio_session_t)mSessionId, &streamType, mClientUid, mSampleRate, mFormat, mChannelMask, mFlags, mSelectedDeviceId, mOffloadInfo); + //reset offload info if forced + mOffloadInfo = (mOffloadInfo == &tOffloadInfo) ? NULL : mOffloadInfo; if (status != NO_ERROR || output == AUDIO_IO_HANDLE_NONE) { ALOGE("Could not get audio output for session %d, stream type %d, usage %d, sample rate %u, format %#x," @@ -2318,7 +2336,7 @@ status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp) } else { // Update the mapping between local consumed (mPosition) and server consumed (mServer) - if (AVMediaUtils::get()->AudioTrackGetTimestamp(this, timestamp) == NO_ERROR) { + if (AVMediaUtils::get()->AudioTrackGetTimestamp(this, ×tamp) == NO_ERROR) { return NO_ERROR; } diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index 21befd3..7be4d23 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -37,6 +37,7 @@ #include "../../libstagefright/include/NuCachedSource2.h" #include "../../libstagefright/include/WVMExtractor.h" #include "../../libstagefright/include/HTTPBase.h" +#include "mediaplayerservice/AVNuExtensions.h" namespace android { @@ -60,6 +61,7 @@ NuPlayer::GenericSource::GenericSource( mAudioIsVorbis(false), mIsWidevine(false), mIsSecure(false), + mUseSetBuffers(false), mIsStreaming(false), mUIDValid(uidValid), mUID(uid), @@ -172,7 +174,8 @@ status_t NuPlayer::GenericSource::initFromDataSource() { extractor = mWVMExtractor; } else { extractor = MediaExtractor::Create(mDataSource, - mimeType.isEmpty() ? NULL : mimeType.string()); + mimeType.isEmpty() ? NULL : mimeType.string(), + mIsStreaming ? 0 : AVNuUtils::get()->getUseSetBuffersFlag()); } if (extractor == NULL) { @@ -202,6 +205,11 @@ status_t NuPlayer::GenericSource::initFromDataSource() { } } + if (AVNuUtils::get()->canUseSetBuffers(mFileMeta)) { + mUseSetBuffers = true; + ALOGI("setBuffers mode enabled"); + } + int32_t totalBitrate = 0; size_t numtracks = extractor->countTracks(); @@ -318,7 +326,7 @@ int64_t NuPlayer::GenericSource::getLastReadPosition() { status_t NuPlayer::GenericSource::setBuffers( bool audio, Vector<MediaBuffer *> &buffers) { - if (mIsSecure && !audio) { + if ((mIsSecure || mUseSetBuffers) && !audio) { return mVideoTrack.mSource->setBuffers(buffers); } return INVALID_OPERATION; @@ -428,7 +436,8 @@ void NuPlayer::GenericSource::onPrepareAsync() { | FLAG_CAN_PAUSE | FLAG_CAN_SEEK_BACKWARD | FLAG_CAN_SEEK_FORWARD - | FLAG_CAN_SEEK); + | FLAG_CAN_SEEK + | (mUseSetBuffers ? FLAG_USE_SET_BUFFERS : 0)); if (mIsSecure) { // secure decoders must be instantiated before starting widevine source @@ -1023,7 +1032,8 @@ status_t NuPlayer::GenericSource::dequeueAccessUnit( // start pulling in more buffers if we only have one (or no) buffer left // so that decoder has less chance of being starved - if (track->mPackets->getAvailableBufferCount(&finalResult) < 2) { + if ((track->mPackets->getAvailableBufferCount(&finalResult) < 2) + && !mUseSetBuffers) { postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO); } @@ -1367,7 +1377,7 @@ sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer( } sp<ABuffer> ab; - if (mIsSecure && !audio) { + if ((mIsSecure || mUseSetBuffers) && !audio) { // data is already provided in the buffer ab = new ABuffer(NULL, mb->range_length()); mb->add_ref(); @@ -1518,7 +1528,7 @@ void NuPlayer::GenericSource::readBuffer( track->mPackets->clear(); } - if (mIsWidevine) { + if (mIsWidevine || mUseSetBuffers) { options.setNonBlocking(); } diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index d7467c2..bdcf706 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -126,6 +126,7 @@ protected: bool mAudioIsVorbis; bool mIsWidevine; bool mIsSecure; + bool mUseSetBuffers; bool mIsStreaming; bool mUIDValid; uid_t mUID; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 6305a02..ec1ab79 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -243,7 +243,7 @@ bool NuPlayer::IsHTTPLiveURL(const char *url) { return true; } - if (strstr(url,".m3u8")) { + if (strstr(url,"m3u8")) { return true; } } @@ -1169,6 +1169,9 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { FLUSH_CMD_SHUTDOWN /* video */)); mDeferredActions.push_back( + new SimpleAction(&NuPlayer::closeAudioSink)); + + mDeferredActions.push_back( new SimpleAction(&NuPlayer::performReset)); processDeferredActions(); @@ -1602,7 +1605,8 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<DecoderBase> *decoder) { (*decoder)->configure(format); // allocate buffers to decrypt widevine source buffers - if (!audio && (mSourceFlags & Source::FLAG_SECURE)) { + if (!audio && ((mSourceFlags & Source::FLAG_SECURE) || + (mSourceFlags & Source::FLAG_USE_SET_BUFFERS))) { Vector<sp<ABuffer> > inputBufs; CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index b84453b..9ca8c9f 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -372,7 +372,14 @@ void NuPlayer::Decoder::onResume(bool notifyComplete) { if (notifyComplete) { mResumePending = true; } - mCodec->start(); + + if (mCodec != NULL) { + mCodec->start(); + } else { + ALOGW("Decoder %s onResume without a valid codec object", + mComponentName.c_str()); + handleError(NO_INIT); + } } void NuPlayer::Decoder::doFlush(bool notifyComplete) { diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h index 9ee6c7b..b248316 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h @@ -39,6 +39,7 @@ struct NuPlayer::Source : public AHandler { FLAG_DYNAMIC_DURATION = 16, FLAG_SECURE = 32, FLAG_PROTECTED = 64, + FLAG_USE_SET_BUFFERS = 128, }; enum { diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index a01c63a..83954f9 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -626,8 +626,8 @@ void ACodec::initiateShutdown(bool keepComponentAllocated) { msg->setInt32("keepComponentAllocated", keepComponentAllocated); msg->post(); if (!keepComponentAllocated) { - // ensure shutdown completes in 10 seconds - (new AMessage(kWhatReleaseCodecInstance, this))->post(10000000); + // ensure shutdown completes in 30 seconds + (new AMessage(kWhatReleaseCodecInstance, this))->post(30000000); } } diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp index fc43d43..fc96e2f 100644 --- a/media/libstagefright/MediaExtractor.cpp +++ b/media/libstagefright/MediaExtractor.cpp @@ -56,7 +56,8 @@ uint32_t MediaExtractor::flags() const { // static sp<MediaExtractor> MediaExtractor::Create( - const sp<DataSource> &source, const char *mime) { + const sp<DataSource> &source, const char *mime, + const uint32_t flags) { sp<AMessage> meta; bool secondPass = false; @@ -103,7 +104,7 @@ retry: sp<MediaExtractor> ret = NULL; AString extractorName; - if ((ret = AVFactory::get()->createExtendedExtractor(source, mime, meta)) != NULL) { + if ((ret = AVFactory::get()->createExtendedExtractor(source, mime, meta, flags)) != NULL) { } else if (meta.get() && meta->findString("extended-extractor-use", &extractorName) && sPlugin.create) { ALOGI("Use extended extractor for the special mime(%s) or codec", mime); @@ -139,7 +140,7 @@ retry: ret = sPlugin.create(source, mime, meta); } - ret = AVFactory::get()->updateExtractor(ret, source, mime, meta); + ret = AVFactory::get()->updateExtractor(ret, source, mime, meta, flags); if (ret != NULL) { if (isDrm) { ret->setDrmFlag(true); diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp index 8c371ba..98b5c0e 100644 --- a/media/libstagefright/avc_utils.cpp +++ b/media/libstagefright/avc_utils.cpp @@ -25,6 +25,7 @@ #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> +#include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MetaData.h> #include <utils/misc.h> @@ -443,25 +444,34 @@ bool IsIDR(const sp<ABuffer> &buffer) { } bool IsAVCReferenceFrame(const sp<ABuffer> &accessUnit) { - const uint8_t *data = accessUnit->data(); + MediaBuffer *mediaBuffer = + (MediaBuffer *)(accessUnit->getMediaBufferBase()); + const uint8_t *data = + (mediaBuffer != NULL) ? (uint8_t *) mediaBuffer->data() : accessUnit->data(); size_t size = accessUnit->size(); const uint8_t *nalStart; size_t nalSize; + bool bIsReferenceFrame = true; while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { CHECK_GT(nalSize, 0u); unsigned nalType = nalStart[0] & 0x1f; if (nalType == 5) { - return true; + bIsReferenceFrame = true; + break; } else if (nalType == 1) { unsigned nal_ref_idc = (nalStart[0] >> 5) & 3; - return nal_ref_idc != 0; + bIsReferenceFrame = (nal_ref_idc != 0); + break; } } - return true; + if (mediaBuffer != NULL) { + mediaBuffer->release(); + } + return bIsReferenceFrame; } sp<MetaData> MakeAACCodecSpecificData( diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h index 50f622d..e1c2999 100644 --- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h +++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h @@ -72,6 +72,7 @@ public: sp<AudioPort> mPort; audio_devices_t mDevice; // current device this output is routed to audio_patch_handle_t mPatchHandle; + audio_io_handle_t mIoHandle; // output handle uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output nsecs_t mStopTime[AUDIO_STREAM_CNT]; float mCurVolume[AUDIO_STREAM_CNT]; // current stream volume in dB @@ -116,7 +117,6 @@ public: virtual void toAudioPort(struct audio_port *port) const; const sp<IOProfile> mProfile; // I/O profile this output derives from - audio_io_handle_t mIoHandle; // output handle uint32_t mLatency; // audio_output_flags_t mFlags; // AudioMix *mPolicyMix; // non NULL when used by a dynamic policy diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp index a278375..5ddeaed 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp @@ -33,7 +33,7 @@ namespace android { AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port, AudioPolicyClientInterface *clientInterface) - : mPort(port), mDevice(AUDIO_DEVICE_NONE), + : mPort(port), mDevice(AUDIO_DEVICE_NONE), mIoHandle(0), mPatchHandle(0), mClientInterface(clientInterface), mId(0) { // clear usage count for all stream types @@ -223,7 +223,7 @@ void AudioOutputDescriptor::log(const char* indent) SwAudioOutputDescriptor::SwAudioOutputDescriptor( const sp<IOProfile>& profile, AudioPolicyClientInterface *clientInterface) : AudioOutputDescriptor(profile, clientInterface), - mProfile(profile), mIoHandle(0), mLatency(0), + mProfile(profile), mLatency(0), mFlags((audio_output_flags_t)0), mPolicyMix(NULL), mOutput1(0), mOutput2(0), mDirectOpenCount(0), mGlobalRefCount(0) { |