summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/libmedia/AudioRecord.cpp51
-rw-r--r--media/libmedia/IAudioFlinger.cpp62
-rw-r--r--media/libmedia/IOMX.cpp33
-rw-r--r--media/libmedia/mediaplayer.cpp7
-rw-r--r--media/libstagefright/ACodec.cpp17
-rw-r--r--media/libstagefright/OMXClient.cpp11
-rw-r--r--media/libstagefright/SurfaceMediaSource.cpp4
-rw-r--r--media/libstagefright/include/OMX.h4
-rw-r--r--media/libstagefright/include/OMXNodeInstance.h4
-rw-r--r--media/libstagefright/omx/OMX.cpp7
-rw-r--r--media/libstagefright/omx/OMXNodeInstance.cpp20
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);