diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 51 | ||||
-rw-r--r-- | media/libmedia/IAudioFlinger.cpp | 62 | ||||
-rw-r--r-- | media/libmedia/IOMX.cpp | 33 | ||||
-rw-r--r-- | media/libmedia/mediaplayer.cpp | 7 | ||||
-rw-r--r-- | media/libstagefright/ACodec.cpp | 17 | ||||
-rw-r--r-- | media/libstagefright/OMXClient.cpp | 11 | ||||
-rw-r--r-- | media/libstagefright/SurfaceMediaSource.cpp | 4 | ||||
-rw-r--r-- | media/libstagefright/include/OMX.h | 4 | ||||
-rw-r--r-- | media/libstagefright/include/OMXNodeInstance.h | 4 | ||||
-rw-r--r-- | media/libstagefright/omx/OMX.cpp | 7 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXNodeInstance.cpp | 20 |
11 files changed, 186 insertions, 34 deletions
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index f039ec2..2718420 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -250,7 +250,7 @@ status_t AudioRecord::set( } // create the IAudioRecord - status = openRecord_l(sampleRate, format, frameCount, input, 0 /*epoch*/); + status = openRecord_l(sampleRate, format, frameCount, mFlags, input, 0 /*epoch*/); if (status != NO_ERROR) { return status; } @@ -267,7 +267,8 @@ status_t AudioRecord::set( mActive = false; mCbf = cbf; - mNotificationFrames = notificationFrames; + mNotificationFramesReq = notificationFrames; + mNotificationFramesAct = 0; mRefreshRemaining = true; mUserData = user; // TODO: add audio hardware input latency here @@ -435,6 +436,7 @@ status_t AudioRecord::openRecord_l( uint32_t sampleRate, audio_format_t format, size_t frameCount, + audio_input_flags_t flags, audio_io_handle_t input, size_t epoch) { @@ -445,15 +447,29 @@ status_t AudioRecord::openRecord_l( return NO_INIT; } + IAudioFlinger::track_flags_t trackFlags = IAudioFlinger::TRACK_DEFAULT; pid_t tid = -1; - // FIXME see similar logic at AudioTrack for tid + + // Client can only express a preference for FAST. Server will perform additional tests. + // The only supported use case for FAST is callback transfer mode. + if (flags & AUDIO_INPUT_FLAG_FAST) { + if ((mTransfer != TRANSFER_CALLBACK) || (mAudioRecordThread == 0)) { + ALOGW("AUDIO_INPUT_FLAG_FAST denied by client"); + // once denied, do not request again if IAudioRecord is re-created + flags = (audio_input_flags_t) (flags & ~AUDIO_INPUT_FLAG_FAST); + mFlags = flags; + } else { + trackFlags |= IAudioFlinger::TRACK_FAST; + tid = mAudioRecordThread->getTid(); + } + } int originalSessionId = mSessionId; sp<IAudioRecord> record = audioFlinger->openRecord(input, sampleRate, format, mChannelMask, frameCount, - IAudioFlinger::TRACK_DEFAULT, + &trackFlags, tid, &mSessionId, &status); @@ -477,6 +493,27 @@ status_t AudioRecord::openRecord_l( mCblkMemory = iMem; audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMem->pointer()); mCblk = cblk; + // FIXME missing fast track frameCount logic + mAwaitBoost = false; + mNotificationFramesAct = mNotificationFramesReq; + if (flags & AUDIO_INPUT_FLAG_FAST) { + if (trackFlags & IAudioFlinger::TRACK_FAST) { + ALOGV("AUDIO_INPUT_FLAG_FAST successful; frameCount %u", frameCount); + mAwaitBoost = true; + // double-buffering is not required for fast tracks, due to tighter scheduling + if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount) { + mNotificationFramesAct = frameCount; + } + } else { + ALOGV("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %u", frameCount); + // once denied, do not request again if IAudioRecord is re-created + flags = (audio_input_flags_t) (flags & ~AUDIO_INPUT_FLAG_FAST); + mFlags = flags; + if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/2) { + mNotificationFramesAct = frameCount/2; + } + } + } // starting address of buffers in shared memory void *buffers = (char*)cblk + sizeof(audio_track_cblk_t); @@ -484,7 +521,7 @@ status_t AudioRecord::openRecord_l( // update proxy mProxy = new AudioRecordClientProxy(cblk, buffers, frameCount, mFrameSize); mProxy->setEpoch(epoch); - mProxy->setMinimum(mNotificationFrames); + mProxy->setMinimum(mNotificationFramesAct); mDeathNotifier = new DeathNotifier(this); mAudioRecord->asBinder()->linkToDeath(mDeathNotifier, this); @@ -731,7 +768,7 @@ nsecs_t AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread) } // Cache other fields that will be needed soon - size_t notificationFrames = mNotificationFrames; + size_t notificationFrames = mNotificationFramesAct; if (mRefreshRemaining) { mRefreshRemaining = false; mRemainingFrames = notificationFrames; @@ -907,7 +944,7 @@ status_t AudioRecord::restoreRecord_l(const char *from) // It will also delete the strong references on previous IAudioRecord and IMemory size_t position = mProxy->getPosition(); mNewPosition = position + mUpdatePeriod; - result = openRecord_l(mSampleRate, mFormat, mFrameCount, getInput_l(), position); + result = openRecord_l(mSampleRate, mFormat, mFrameCount, mFlags, getInput_l(), position); if (result == NO_ERROR) { if (mActive) { // callback thread or sync event hasn't changed diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index c6e43e7..22ad453 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -132,7 +132,7 @@ public: lStatus = reply.readInt32(); track = interface_cast<IAudioTrack>(reply.readStrongBinder()); } - if (status) { + if (status != NULL) { *status = lStatus; } return track; @@ -144,7 +144,7 @@ public: audio_format_t format, audio_channel_mask_t channelMask, size_t frameCount, - track_flags_t flags, + track_flags_t *flags, pid_t tid, int *sessionId, status_t *status) @@ -157,7 +157,8 @@ public: data.writeInt32(format); data.writeInt32(channelMask); data.writeInt32(frameCount); - data.writeInt32(flags); + track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT; + data.writeInt32(lFlags); data.writeInt32((int32_t) tid); int lSessionId = 0; if (sessionId != NULL) { @@ -168,6 +169,10 @@ public: if (lStatus != NO_ERROR) { ALOGE("openRecord error: %s", strerror(-lStatus)); } else { + lFlags = reply.readInt32(); + if (flags != NULL) { + *flags = lFlags; + } lSessionId = reply.readInt32(); if (sessionId != NULL) { *sessionId = lSessionId; @@ -175,7 +180,7 @@ public: lStatus = reply.readInt32(); record = interface_cast<IAudioRecord>(reply.readStrongBinder()); } - if (status) { + if (status != NULL) { *status = lStatus; } return record; @@ -392,15 +397,25 @@ public: audio_io_handle_t output = (audio_io_handle_t) reply.readInt32(); ALOGV("openOutput() returned output, %d", output); devices = (audio_devices_t)reply.readInt32(); - if (pDevices != NULL) *pDevices = devices; + if (pDevices != NULL) { + *pDevices = devices; + } samplingRate = reply.readInt32(); - if (pSamplingRate != NULL) *pSamplingRate = samplingRate; + if (pSamplingRate != NULL) { + *pSamplingRate = samplingRate; + } format = (audio_format_t) reply.readInt32(); - if (pFormat != NULL) *pFormat = format; + if (pFormat != NULL) { + *pFormat = format; + } channelMask = (audio_channel_mask_t)reply.readInt32(); - if (pChannelMask != NULL) *pChannelMask = channelMask; + if (pChannelMask != NULL) { + *pChannelMask = channelMask; + } latency = reply.readInt32(); - if (pLatencyMs != NULL) *pLatencyMs = latency; + if (pLatencyMs != NULL) { + *pLatencyMs = latency; + } return output; } @@ -464,13 +479,21 @@ public: remote()->transact(OPEN_INPUT, data, &reply); audio_io_handle_t input = (audio_io_handle_t) reply.readInt32(); devices = (audio_devices_t)reply.readInt32(); - if (pDevices != NULL) *pDevices = devices; + if (pDevices != NULL) { + *pDevices = devices; + } samplingRate = reply.readInt32(); - if (pSamplingRate != NULL) *pSamplingRate = samplingRate; + if (pSamplingRate != NULL) { + *pSamplingRate = samplingRate; + } format = (audio_format_t) reply.readInt32(); - if (pFormat != NULL) *pFormat = format; + if (pFormat != NULL) { + *pFormat = format; + } channelMask = (audio_channel_mask_t)reply.readInt32(); - if (pChannelMask != NULL) *pChannelMask = channelMask; + if (pChannelMask != NULL) { + *pChannelMask = channelMask; + } return input; } @@ -512,11 +535,11 @@ public: status_t status = reply.readInt32(); if (status == NO_ERROR) { uint32_t tmp = reply.readInt32(); - if (halFrames) { + if (halFrames != NULL) { *halFrames = tmp; } tmp = reply.readInt32(); - if (dspFrames) { + if (dspFrames != NULL) { *dspFrames = tmp; } } @@ -634,7 +657,7 @@ public: if (pDesc == NULL) { return effect; - if (status) { + if (status != NULL) { *status = BAD_VALUE; } } @@ -652,7 +675,7 @@ public: } else { lStatus = reply.readInt32(); int tmp = reply.readInt32(); - if (id) { + if (id != NULL) { *id = tmp; } tmp = reply.readInt32(); @@ -662,7 +685,7 @@ public: effect = interface_cast<IEffect>(reply.readStrongBinder()); reply.read(pDesc, sizeof(effect_descriptor_t)); } - if (status) { + if (status != NULL) { *status = lStatus; } @@ -761,7 +784,8 @@ status_t BnAudioFlinger::onTransact( int sessionId = data.readInt32(); status_t status; sp<IAudioRecord> record = openRecord(input, - sampleRate, format, channelMask, frameCount, flags, tid, &sessionId, &status); + sampleRate, format, channelMask, frameCount, &flags, tid, &sessionId, &status); + reply->writeInt32(flags); reply->writeInt32(sessionId); reply->writeInt32(status); reply->writeStrongBinder(record->asBinder()); diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index 5bbb2f0..ef99f4f 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -52,6 +52,7 @@ enum { OBSERVER_ON_MSG, GET_GRAPHIC_BUFFER_USAGE, SET_INTERNAL_OPTION, + UPDATE_GRAPHIC_BUFFER_IN_META, }; class BpOMX : public BpInterface<IOMX> { @@ -283,6 +284,21 @@ public: return err; } + virtual status_t updateGraphicBufferInMeta( + node_id node, OMX_U32 port_index, + const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) { + Parcel data, reply; + data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); + data.writeIntPtr((intptr_t)node); + data.writeInt32(port_index); + data.write(*graphicBuffer); + data.writeIntPtr((intptr_t)buffer); + remote()->transact(UPDATE_GRAPHIC_BUFFER_IN_META, data, &reply); + + status_t err = reply.readInt32(); + return err; + } + virtual status_t createInputSurface( node_id node, OMX_U32 port_index, sp<IGraphicBufferProducer> *bufferProducer) { @@ -691,6 +707,23 @@ status_t BnOMX::onTransact( return NO_ERROR; } + case UPDATE_GRAPHIC_BUFFER_IN_META: + { + CHECK_OMX_INTERFACE(IOMX, data, reply); + + node_id node = (void*)data.readIntPtr(); + OMX_U32 port_index = data.readInt32(); + sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); + data.read(*graphicBuffer); + buffer_id buffer = (void*)data.readIntPtr(); + + status_t err = updateGraphicBufferInMeta( + node, port_index, graphicBuffer, buffer); + reply->writeInt32(err); + + return NO_ERROR; + } + case CREATE_INPUT_SURFACE: { CHECK_OMX_INTERFACE(IOMX, data, reply); diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 963b04f..056cc0a 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -811,6 +811,13 @@ status_t MediaPlayer::setNextMediaPlayer(const sp<MediaPlayer>& next) { if (mPlayer == NULL) { return NO_INIT; } + + if (next != NULL && !(next->mCurrentState & + (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE))) { + ALOGE("next player is not prepared"); + return INVALID_OPERATION; + } + return mPlayer->setNextPlayer(next == NULL ? NULL : next->mPlayer); } diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 00804c5..5aefa58 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -833,15 +833,20 @@ ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() { oldest->mGraphicBuffer = new GraphicBuffer(buf, false); oldest->mStatus = BufferInfo::OWNED_BY_US; - struct VideoDecoderOutputMetaData metaData; - metaData.eType = kMetadataBufferTypeGrallocSource; - metaData.pHandle = oldest->mGraphicBuffer->handle; - memcpy(oldest->mData->base(), &metaData, sizeof(metaData)); + mOMX->updateGraphicBufferInMeta( + mNode, kPortIndexOutput, oldest->mGraphicBuffer, + oldest->mBufferID); - ALOGV("replaced oldest buffer #%u with age %u (%p stored in %p)", + VideoDecoderOutputMetaData *metaData = + reinterpret_cast<VideoDecoderOutputMetaData *>( + oldest->mData->base()); + CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource); + + ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)", oldest - &mBuffers[kPortIndexOutput][0], mDequeueCounter - oldest->mDequeuedAt, - metaData.pHandle, oldest->mData->base()); + metaData->pHandle, + oldest->mGraphicBuffer->handle, oldest->mData->base()); return oldest; } diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp index 810d88f..9820ef5 100644 --- a/media/libstagefright/OMXClient.cpp +++ b/media/libstagefright/OMXClient.cpp @@ -83,6 +83,10 @@ struct MuxOMX : public IOMX { node_id node, OMX_U32 port_index, const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer); + virtual status_t updateGraphicBufferInMeta( + node_id node, OMX_U32 port_index, + const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer); + virtual status_t createInputSurface( node_id node, OMX_U32 port_index, sp<IGraphicBufferProducer> *bufferProducer); @@ -287,6 +291,13 @@ status_t MuxOMX::useGraphicBuffer( node, port_index, graphicBuffer, buffer); } +status_t MuxOMX::updateGraphicBufferInMeta( + node_id node, OMX_U32 port_index, + const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) { + return getOMX(node)->updateGraphicBufferInMeta( + node, port_index, graphicBuffer, buffer); +} + status_t MuxOMX::createInputSurface( node_id node, OMX_U32 port_index, sp<IGraphicBufferProducer> *bufferProducer) { diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp index b082c3a..6b934d4 100644 --- a/media/libstagefright/SurfaceMediaSource.cpp +++ b/media/libstagefright/SurfaceMediaSource.cpp @@ -65,7 +65,7 @@ SurfaceMediaSource::SurfaceMediaSource(uint32_t bufferWidth, uint32_t bufferHeig // reference once the ctor ends, as that would cause the refcount of 'this' // dropping to 0 at the end of the ctor. Since all we need is a wp<...> // that's what we create. - wp<BufferQueue::ConsumerListener> listener = static_cast<BufferQueue::ConsumerListener*>(this); + wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this); sp<BufferQueue::ProxyConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener); status_t err = mBufferQueue->consumerConnect(proxy, false); @@ -105,7 +105,7 @@ void SurfaceMediaSource::dump(String8& result, const char* prefix, Mutex::Autolock lock(mMutex); result.append(buffer); - mBufferQueue->dump(result); + mBufferQueue->dump(result, ""); } status_t SurfaceMediaSource::setFrameRate(int32_t fps) diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h index 7fed7d4..7e53af3 100644 --- a/media/libstagefright/include/OMX.h +++ b/media/libstagefright/include/OMX.h @@ -79,6 +79,10 @@ public: node_id node, OMX_U32 port_index, const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer); + virtual status_t updateGraphicBufferInMeta( + node_id node, OMX_U32 port_index, + const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer); + virtual status_t createInputSurface( node_id node, OMX_U32 port_index, sp<IGraphicBufferProducer> *bufferProducer); diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h index f6ae376..ae498b4 100644 --- a/media/libstagefright/include/OMXNodeInstance.h +++ b/media/libstagefright/include/OMXNodeInstance.h @@ -66,6 +66,10 @@ struct OMXNodeInstance { OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer, OMX::buffer_id *buffer); + status_t updateGraphicBufferInMeta( + OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer, + OMX::buffer_id buffer); + status_t createInputSurface( OMX_U32 portIndex, sp<IGraphicBufferProducer> *bufferProducer); diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index 4b1dbe6..aaa9f89 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -345,6 +345,13 @@ status_t OMX::useGraphicBuffer( port_index, graphicBuffer, buffer); } +status_t OMX::updateGraphicBufferInMeta( + node_id node, OMX_U32 port_index, + const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) { + return findInstance(node)->updateGraphicBufferInMeta( + port_index, graphicBuffer, buffer); +} + status_t OMX::createInputSurface( node_id node, OMX_U32 port_index, sp<IGraphicBufferProducer> *bufferProducer) { diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index 525e18d..8d100f1 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -70,6 +70,10 @@ struct BufferMeta { header->nFilledLen); } + void setGraphicBuffer(const sp<GraphicBuffer> &graphicBuffer) { + mGraphicBuffer = graphicBuffer; + } + private: sp<GraphicBuffer> mGraphicBuffer; sp<IMemory> mMem; @@ -566,6 +570,22 @@ status_t OMXNodeInstance::useGraphicBuffer( return OK; } +status_t OMXNodeInstance::updateGraphicBufferInMeta( + OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer, + OMX::buffer_id buffer) { + Mutex::Autolock autoLock(mLock); + + OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)(buffer); + VideoDecoderOutputMetaData *metadata = + (VideoDecoderOutputMetaData *)(header->pBuffer); + BufferMeta *bufferMeta = (BufferMeta *)(header->pAppPrivate); + bufferMeta->setGraphicBuffer(graphicBuffer); + metadata->eType = kMetadataBufferTypeGrallocSource; + metadata->pHandle = graphicBuffer->handle; + + return OK; +} + status_t OMXNodeInstance::createInputSurface( OMX_U32 portIndex, sp<IGraphicBufferProducer> *bufferProducer) { Mutex::Autolock autolock(mLock); |