Merge "Check input HAL channel mask instead of channel count"
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 529b96c..797e0b6 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -939,7 +939,7 @@
sp<BufferQueue> bq = new BufferQueue();
sp<GLConsumer> texture = new GLConsumer(bq, 0 /* tex */);
- gSurface = new Surface(texture->getBufferQueue());
+ gSurface = new Surface(bq);
}
CHECK_EQ((status_t)OK,
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index eef108b..b426798 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -60,7 +60,7 @@
size_t frameCount; // number of sample frames corresponding to size;
// on input it is the number of frames available,
// on output is the number of frames actually drained
- // (currently ignored, but will make the primary field in future)
+ // (currently ignored but will make the primary field in future)
size_t size; // input/output in bytes == frameCount * frameSize
// FIXME this is redundant with respect to frameCount,
@@ -346,8 +346,7 @@
__attribute__((__deprecated__));
private:
- /* New internal API.
- * If nonContig is non-NULL, it is an output parameter that will be set to the number of
+ /* If nonContig is non-NULL, it is an output parameter that will be set to the number of
* additional non-contiguous frames that are available immediately.
* FIXME We could pass an array of Buffers instead of only one Buffer to obtainBuffer(),
* in case the requested amount of frames is in two or more non-contiguous regions.
@@ -424,14 +423,7 @@
nsecs_t processAudioBuffer(const sp<AudioRecordThread>& thread);
// caller must hold lock on mLock for all _l methods
- status_t 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);
-
- audio_io_handle_t getInput_l();
+ status_t openRecord_l(size_t epoch);
// FIXME enum is faster than strcmp() for parameter 'from'
status_t restoreRecord_l(const char *from);
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 006af08..77f7d9a 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -155,7 +155,8 @@
class OutputDescriptor {
public:
OutputDescriptor()
- : samplingRate(0), format(AUDIO_FORMAT_DEFAULT), channelMask(0), frameCount(0), latency(0) {}
+ : samplingRate(0), format(AUDIO_FORMAT_DEFAULT), channelMask(0), frameCount(0), latency(0)
+ {}
uint32_t samplingRate;
audio_format_t format;
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index ddb5842..ae92cdd 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -332,11 +332,6 @@
/* Enables looping and sets the start and end points of looping.
* Only supported for static buffer mode.
*
- * FIXME The comments below are for the new planned interpretation which is not yet implemented.
- * Currently the legacy behavior is still implemented, where loopStart and loopEnd
- * are in wrapping (overflow) frame units like the return value of getPosition().
- * The plan is to fix all callers to use the new version at same time implementation changes.
- *
* Parameters:
*
* loopStart: loop start in frames relative to start of buffer.
@@ -394,11 +389,6 @@
/* Sets playback head position.
* Only supported for static buffer mode.
*
- * FIXME The comments below are for the new planned interpretation which is not yet implemented.
- * Currently the legacy behavior is still implemented, where the new position
- * is in wrapping (overflow) frame units like the return value of getPosition().
- * The plan is to fix all callers to use the new version at same time implementation changes.
- *
* Parameters:
*
* position: New playback head position in frames relative to start of buffer.
@@ -428,7 +418,7 @@
status_t getPosition(uint32_t *position) const;
/* For static buffer mode only, this returns the current playback position in frames
- * relative to start of buffer. It is analogous to the new API for
+ * relative to start of buffer. It is analogous to the position units used by
* setLoop() and setPosition(). After underrun, the position will be at end of buffer.
*/
status_t getBufferPosition(uint32_t *position);
@@ -518,8 +508,7 @@
__attribute__((__deprecated__));
private:
- /* New internal API
- * If nonContig is non-NULL, it is an output parameter that will be set to the number of
+ /* If nonContig is non-NULL, it is an output parameter that will be set to the number of
* additional non-contiguous frames that are available immediately.
* FIXME We could pass an array of Buffers instead of only one Buffer to obtainBuffer(),
* in case the requested amount of frames is in two or more non-contiguous regions.
@@ -547,12 +536,11 @@
* This is implemented on top of obtainBuffer/releaseBuffer. For best
* performance use callbacks. Returns actual number of bytes written >= 0,
* or one of the following negative status codes:
- * INVALID_OPERATION AudioTrack is configured for shared buffer mode
+ * INVALID_OPERATION AudioTrack is configured for static buffer or streaming mode
* BAD_VALUE size is invalid
* WOULD_BLOCK when obtainBuffer() returns same, or
* AudioTrack was stopped during the write
* or any other error code returned by IAudioTrack::start() or restoreTrack_l().
- * Not supported for static buffer mode.
*/
ssize_t write(const void* buffer, size_t size);
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 38f9d11..6d116f0 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -97,6 +97,10 @@
node_id node, OMX_U32 port_index,
const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) = 0;
+ virtual status_t updateGraphicBufferInMeta(
+ node_id node, OMX_U32 port_index,
+ const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) = 0;
+
virtual status_t createInputSurface(
node_id node, OMX_U32 port_index,
sp<IGraphicBufferProducer> *bufferProducer) = 0;
diff --git a/include/media/stagefright/MediaErrors.h b/include/media/stagefright/MediaErrors.h
index ee5e4e2..686f286 100644
--- a/include/media/stagefright/MediaErrors.h
+++ b/include/media/stagefright/MediaErrors.h
@@ -56,14 +56,11 @@
ERROR_DRM_TAMPER_DETECTED = DRM_ERROR_BASE - 7,
ERROR_DRM_NOT_PROVISIONED = DRM_ERROR_BASE - 8,
ERROR_DRM_DEVICE_REVOKED = DRM_ERROR_BASE - 9,
+ ERROR_DRM_RESOURCE_BUSY = DRM_ERROR_BASE - 10,
ERROR_DRM_VENDOR_MAX = DRM_ERROR_BASE - 500,
ERROR_DRM_VENDOR_MIN = DRM_ERROR_BASE - 999,
- // Deprecated
- ERROR_DRM_WV_VENDOR_MAX = ERROR_DRM_VENDOR_MAX,
- ERROR_DRM_WV_VENDOR_MIN = ERROR_DRM_VENDOR_MIN,
-
// Heartbeat Error Codes
HEARTBEAT_ERROR_BASE = -3000,
ERROR_HEARTBEAT_TERMINATE_REQUESTED = HEARTBEAT_ERROR_BASE,
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 2718420..e934a3e 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -175,6 +175,7 @@
if (inputSource == AUDIO_SOURCE_DEFAULT) {
inputSource = AUDIO_SOURCE_MIC;
}
+ mInputSource = inputSource;
if (sampleRate == 0) {
ALOGE("Invalid sample rate %u", sampleRate);
@@ -210,28 +211,10 @@
// Assumes audio_is_linear_pcm(format), else sizeof(uint8_t)
mFrameSize = channelCount * audio_bytes_per_sample(format);
- if (sessionId == 0 ) {
- mSessionId = AudioSystem::newAudioSessionId();
- } else {
- mSessionId = sessionId;
- }
- ALOGV("set(): mSessionId %d", mSessionId);
-
- mFlags = flags;
-
- audio_io_handle_t input = AudioSystem::getInput(inputSource,
- sampleRate,
- format,
- channelMask,
- mSessionId);
- if (input == 0) {
- ALOGE("Could not get audio input for record source %d", inputSource);
- return BAD_VALUE;
- }
-
// validate framecount
size_t minFrameCount = 0;
- status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelMask);
+ status_t status = AudioRecord::getMinFrameCount(&minFrameCount,
+ sampleRate, format, channelMask);
if (status != NO_ERROR) {
ALOGE("getMinFrameCount() failed; status %d", status);
return status;
@@ -244,14 +227,23 @@
ALOGE("frameCount %u < minFrameCount %u", frameCount, minFrameCount);
return BAD_VALUE;
}
+ mFrameCount = frameCount;
- if (notificationFrames == 0) {
- notificationFrames = frameCount/2;
+ mNotificationFramesReq = notificationFrames;
+ mNotificationFramesAct = 0;
+
+ if (sessionId == 0 ) {
+ mSessionId = AudioSystem::newAudioSessionId();
+ } else {
+ mSessionId = sessionId;
}
+ ALOGV("set(): mSessionId %d", mSessionId);
+
+ mFlags = flags;
// create the IAudioRecord
- status = openRecord_l(sampleRate, format, frameCount, mFlags, input, 0 /*epoch*/);
- if (status != NO_ERROR) {
+ status = openRecord_l(0 /*epoch*/);
+ if (status) {
return status;
}
@@ -267,8 +259,6 @@
mActive = false;
mCbf = cbf;
- mNotificationFramesReq = notificationFrames;
- mNotificationFramesAct = 0;
mRefreshRemaining = true;
mUserData = user;
// TODO: add audio hardware input latency here
@@ -277,8 +267,6 @@
mMarkerReached = false;
mNewPosition = 0;
mUpdatePeriod = 0;
- mInputSource = inputSource;
- mInput = input;
AudioSystem::acquireAudioSessionId(mSessionId);
mSequence = 1;
mObservedSequence = mSequence;
@@ -432,13 +420,7 @@
// -------------------------------------------------------------------------
// must be called with mLock held
-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)
+status_t AudioRecord::openRecord_l(size_t epoch)
{
status_t status;
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
@@ -452,23 +434,38 @@
// 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 (mFlags & 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;
+ mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST);
} else {
trackFlags |= IAudioFlinger::TRACK_FAST;
tid = mAudioRecordThread->getTid();
}
}
+ mNotificationFramesAct = mNotificationFramesReq;
+
+ if (!(mFlags & AUDIO_INPUT_FLAG_FAST)) {
+ // Make sure that application is notified with sufficient margin before overrun
+ if (mNotificationFramesAct == 0 || mNotificationFramesAct > mFrameCount/2) {
+ mNotificationFramesAct = mFrameCount/2;
+ }
+ }
+
+ audio_io_handle_t input = AudioSystem::getInput(mInputSource, mSampleRate, mFormat,
+ mChannelMask, mSessionId);
+ if (input == 0) {
+ ALOGE("Could not get audio input for record source %d", mInputSource);
+ return BAD_VALUE;
+ }
+
int originalSessionId = mSessionId;
sp<IAudioRecord> record = audioFlinger->openRecord(input,
- sampleRate, format,
+ mSampleRate, mFormat,
mChannelMask,
- frameCount,
+ mFrameCount,
&trackFlags,
tid,
&mSessionId,
@@ -478,6 +475,7 @@
if (record == 0) {
ALOGE("AudioFlinger could not create record track, status: %d", status);
+ AudioSystem::releaseInput(input);
return status;
}
sp<IMemory> iMem = record->getCblk();
@@ -489,28 +487,27 @@
mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this);
mDeathNotifier.clear();
}
+ mInput = input;
mAudioRecord = record;
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 (mFlags & AUDIO_INPUT_FLAG_FAST) {
if (trackFlags & IAudioFlinger::TRACK_FAST) {
- ALOGV("AUDIO_INPUT_FLAG_FAST successful; frameCount %u", frameCount);
+ ALOGV("AUDIO_INPUT_FLAG_FAST successful; frameCount %u", mFrameCount);
mAwaitBoost = true;
// double-buffering is not required for fast tracks, due to tighter scheduling
- if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount) {
- mNotificationFramesAct = frameCount;
+ if (mNotificationFramesAct == 0 || mNotificationFramesAct > mFrameCount) {
+ mNotificationFramesAct = mFrameCount;
}
} else {
- ALOGV("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %u", frameCount);
+ ALOGV("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %u", mFrameCount);
// 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;
+ mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST);
+ if (mNotificationFramesAct == 0 || mNotificationFramesAct > mFrameCount/2) {
+ mNotificationFramesAct = mFrameCount/2;
}
}
}
@@ -519,7 +516,7 @@
void *buffers = (char*)cblk + sizeof(audio_track_cblk_t);
// update proxy
- mProxy = new AudioRecordClientProxy(cblk, buffers, frameCount, mFrameSize);
+ mProxy = new AudioRecordClientProxy(cblk, buffers, mFrameCount, mFrameSize);
mProxy->setEpoch(epoch);
mProxy->setMinimum(mNotificationFramesAct);
@@ -646,17 +643,6 @@
return mInput;
}
-// must be called with mLock held
-audio_io_handle_t AudioRecord::getInput_l()
-{
- mInput = AudioSystem::getInput(mInputSource,
- mSampleRate,
- mFormat,
- mChannelMask,
- mSessionId);
- return mInput;
-}
-
// -------------------------------------------------------------------------
ssize_t AudioRecord::read(void* buffer, size_t userSize)
@@ -944,7 +930,7 @@
// 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, mFlags, getInput_l(), position);
+ result = openRecord_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 be818c6..22ad453 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -132,7 +132,7 @@
lStatus = reply.readInt32();
track = interface_cast<IAudioTrack>(reply.readStrongBinder());
}
- if (status) {
+ if (status != NULL) {
*status = lStatus;
}
return track;
@@ -180,7 +180,7 @@
lStatus = reply.readInt32();
record = interface_cast<IAudioRecord>(reply.readStrongBinder());
}
- if (status) {
+ if (status != NULL) {
*status = lStatus;
}
return record;
@@ -397,15 +397,25 @@
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;
}
@@ -469,13 +479,21 @@
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;
}
@@ -517,11 +535,11 @@
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;
}
}
@@ -639,7 +657,7 @@
if (pDesc == NULL) {
return effect;
- if (status) {
+ if (status != NULL) {
*status = BAD_VALUE;
}
}
@@ -657,7 +675,7 @@
} else {
lStatus = reply.readInt32();
int tmp = reply.readInt32();
- if (id) {
+ if (id != NULL) {
*id = tmp;
}
tmp = reply.readInt32();
@@ -667,7 +685,7 @@
effect = interface_cast<IEffect>(reply.readStrongBinder());
reply.read(pDesc, sizeof(effect_descriptor_t));
}
- if (status) {
+ if (status != NULL) {
*status = lStatus;
}
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 @@
OBSERVER_ON_MSG,
GET_GRAPHIC_BUFFER_USAGE,
SET_INTERNAL_OPTION,
+ UPDATE_GRAPHIC_BUFFER_IN_META,
};
class BpOMX : public BpInterface<IOMX> {
@@ -283,6 +284,21 @@
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 @@
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/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 00804c5..36549d1 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -833,15 +833,20 @@
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;
}
@@ -4118,13 +4123,28 @@
if (params->findInt32("drop-input-frames", &dropInputFrames)) {
bool suspend = dropInputFrames != 0;
- CHECK_EQ((status_t)OK,
- mOMX->setInternalOption(
+ status_t err =
+ mOMX->setInternalOption(
mNode,
kPortIndexInput,
IOMX::INTERNAL_OPTION_SUSPEND,
&suspend,
- sizeof(suspend)));
+ sizeof(suspend));
+
+ if (err != OK) {
+ ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
+ return err;
+ }
+ }
+
+ int32_t dummy;
+ if (params->findInt32("request-sync", &dummy)) {
+ status_t err = requestIDRFrame();
+
+ if (err != OK) {
+ ALOGE("Requesting a sync frame failed w/ err %d", err);
+ return err;
+ }
}
return OK;
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 @@
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 @@
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/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 @@
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 @@
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 @@
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 @@
header->nFilledLen);
}
+ void setGraphicBuffer(const sp<GraphicBuffer> &graphicBuffer) {
+ mGraphicBuffer = graphicBuffer;
+ }
+
private:
sp<GraphicBuffer> mGraphicBuffer;
sp<IMemory> mMem;
@@ -566,6 +570,22 @@
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);
diff --git a/media/libstagefright/rtsp/AAVCAssembler.cpp b/media/libstagefright/rtsp/AAVCAssembler.cpp
index 7ea132e..a6825eb 100644
--- a/media/libstagefright/rtsp/AAVCAssembler.cpp
+++ b/media/libstagefright/rtsp/AAVCAssembler.cpp
@@ -106,6 +106,13 @@
++mNextExpectedSeqNo;
return success ? OK : MALFORMED_PACKET;
+ } else if (nalType == 0) {
+ ALOGV("Ignoring undefined nal type.");
+
+ queue->erase(queue->begin());
+ ++mNextExpectedSeqNo;
+
+ return OK;
} else {
ALOGV("Ignoring unsupported buffer (nalType=%d)", nalType);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 3d65c44..1bac09e 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -537,9 +537,7 @@
}
Exit:
- if (status != NULL) {
- *status = lStatus;
- }
+ *status = lStatus;
return trackHandle;
}
@@ -1273,12 +1271,9 @@
// return to handle to client
recordHandle = new RecordHandle(recordTrack);
- lStatus = NO_ERROR;
Exit:
- if (status) {
- *status = lStatus;
- }
+ *status = lStatus;
return recordHandle;
}
@@ -1421,10 +1416,11 @@
{
PlaybackThread *thread = NULL;
struct audio_config config;
+ memset(&config, 0, sizeof(config));
config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;
config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;
config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;
- if (offloadInfo) {
+ if (offloadInfo != NULL) {
config.offload_info = *offloadInfo;
}
@@ -1645,13 +1641,14 @@
status_t status;
RecordThread *thread = NULL;
struct audio_config config;
+ memset(&config, 0, sizeof(config));
config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;
config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;
config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;
uint32_t reqSamplingRate = config.sample_rate;
audio_format_t reqFormat = config.format;
- audio_channel_mask_t reqChannels = config.channel_mask;
+ audio_channel_mask_t reqChannelMask = config.channel_mask;
audio_stream_in_t *inStream = NULL;
AudioHwDevice *inHwDev;
@@ -1684,7 +1681,7 @@
if (status == BAD_VALUE &&
reqFormat == config.format && config.format == AUDIO_FORMAT_PCM_16_BIT &&
(config.sample_rate <= 2 * reqSamplingRate) &&
- (popcount(config.channel_mask) <= FCC_2) && (popcount(reqChannels) <= FCC_2)) {
+ (popcount(config.channel_mask) <= FCC_2) && (popcount(reqChannelMask) <= FCC_2)) {
ALOGV("openInput() reopening with proposed sampling rate and channel mask");
inStream = NULL;
status = inHwHal->open_input_stream(inHwHal, id, *pDevices, &config, &inStream);
@@ -1749,7 +1746,7 @@
thread = new RecordThread(this,
input,
reqSamplingRate,
- reqChannels,
+ reqChannelMask,
id,
primaryOutputDevice_l(),
*pDevices
@@ -1766,7 +1763,7 @@
*pFormat = config.format;
}
if (pChannelMask != NULL) {
- *pChannelMask = reqChannels;
+ *pChannelMask = reqChannelMask;
}
// notify client processes of the new input creation
@@ -2209,9 +2206,7 @@
}
Exit:
- if (status != NULL) {
- *status = lStatus;
- }
+ *status = lStatus;
return handle;
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index e5e4113..50c20b8 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -109,7 +109,7 @@
pid_t tid,
int *sessionId,
String8& name,
- status_t *status);
+ status_t *status /*non-NULL*/);
virtual sp<IAudioRecord> openRecord(
audio_io_handle_t input,
@@ -120,7 +120,7 @@
IAudioFlinger::track_flags_t *flags,
pid_t tid,
int *sessionId,
- status_t *status);
+ status_t *status /*non-NULL*/);
virtual uint32_t sampleRate(audio_io_handle_t output) const;
virtual int channelCount(audio_io_handle_t output) const;
@@ -209,7 +209,7 @@
int32_t priority,
audio_io_handle_t io,
int sessionId,
- status_t *status,
+ status_t *status /*non-NULL*/,
int *id,
int *enabled);
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 5600411c..43fb946 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -33,6 +33,7 @@
int sessionId,
IAudioFlinger::track_flags_t flags);
virtual ~Track();
+ virtual status_t initCheck() const;
static void appendDumpHeader(String8& result);
void dump(char* buffer, size_t size);
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index ffe3e9f..6c0d1d3 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -57,5 +57,4 @@
// releaseBuffer() not overridden
bool mOverflow; // overflow on most recent attempt to fill client buffer
- AudioRecordServerProxy* mAudioRecordServerProxy;
};
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index a8753d2..db3b82b 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -266,8 +266,8 @@
: Thread(false /*canCallJava*/),
mType(type),
mAudioFlinger(audioFlinger),
- // mSampleRate, mFrameCount, mChannelMask, mChannelCount, mFrameSize, and mFormat are
- // set by PlaybackThread::readOutputParameters() or RecordThread::readInputParameters()
+ // mSampleRate, mFrameCount, mChannelMask, mChannelCount, mFrameSize, mFormat, mBufferSize
+ // are set by PlaybackThread::readOutputParameters() or RecordThread::readInputParameters()
mParamStatus(NO_ERROR),
mStandby(false), mOutDevice(outDevice), mInDevice(inDevice),
mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id),
@@ -293,6 +293,17 @@
}
}
+status_t AudioFlinger::ThreadBase::readyToRun()
+{
+ status_t status = initCheck();
+ if (status == NO_ERROR) {
+ ALOGI("AudioFlinger's thread %p ready to run", this);
+ } else {
+ ALOGE("No working audio driver found.");
+ }
+ return status;
+}
+
void AudioFlinger::ThreadBase::exit()
{
ALOGV("ThreadBase::exit");
@@ -423,6 +434,8 @@
result.append(buffer);
snprintf(buffer, SIZE, "HAL frame count: %d\n", mFrameCount);
result.append(buffer);
+ snprintf(buffer, SIZE, "HAL buffer size: %u bytes\n", mBufferSize);
+ result.append(buffer);
snprintf(buffer, SIZE, "Channel Count: %u\n", mChannelCount);
result.append(buffer);
snprintf(buffer, SIZE, "Channel Mask: 0x%08x\n", mChannelMask);
@@ -682,8 +695,7 @@
int sessionId,
effect_descriptor_t *desc,
int *enabled,
- status_t *status
- )
+ status_t *status)
{
sp<EffectModule> effect;
sp<EffectHandle> handle;
@@ -783,9 +795,7 @@
handle.clear();
}
- if (status != NULL) {
- *status = lStatus;
- }
+ *status = lStatus;
return handle;
}
@@ -929,7 +939,7 @@
type_t type)
: ThreadBase(audioFlinger, id, device, AUDIO_DEVICE_NONE, type),
mNormalFrameCount(0), mMixBuffer(NULL),
- mAllocMixBuffer(NULL), mSuspended(0), mBytesWritten(0),
+ mSuspended(0), mBytesWritten(0),
// mStreamTypes[] initialized in constructor body
mOutput(output),
mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
@@ -983,7 +993,7 @@
AudioFlinger::PlaybackThread::~PlaybackThread()
{
mAudioFlinger->unregisterWriter(mNBLogWriter);
- delete [] mAllocMixBuffer;
+ delete[] mMixBuffer;
}
void AudioFlinger::PlaybackThread::dump(int fd, const Vector<String16>& args)
@@ -1073,16 +1083,6 @@
}
// Thread virtuals
-status_t AudioFlinger::PlaybackThread::readyToRun()
-{
- status_t status = initCheck();
- if (status == NO_ERROR) {
- ALOGI("AudioFlinger's thread %p ready to run", this);
- } else {
- ALOGE("No working audio driver found.");
- }
- return status;
-}
void AudioFlinger::PlaybackThread::onFirstRef()
{
@@ -1248,8 +1248,12 @@
track = TimedTrack::create(this, client, streamType, sampleRate, format,
channelMask, frameCount, sharedBuffer, sessionId);
}
- if (track == 0 || track->getCblk() == NULL || track->name() < 0) {
- lStatus = NO_MEMORY;
+
+ // new Track always returns non-NULL,
+ // but TimedTrack::create() is a factory that could fail by returning NULL
+ lStatus = track != 0 ? track->initCheck() : (status_t) NO_MEMORY;
+ if (lStatus != NO_ERROR) {
+ track.clear();
goto Exit;
}
@@ -1274,9 +1278,7 @@
lStatus = NO_ERROR;
Exit:
- if (status) {
- *status = lStatus;
- }
+ *status = lStatus;
return track;
}
@@ -1559,7 +1561,8 @@
mFormat);
}
mFrameSize = audio_stream_frame_size(&mOutput->stream->common);
- mFrameCount = mOutput->stream->common.get_buffer_size(&mOutput->stream->common) / mFrameSize;
+ mBufferSize = mOutput->stream->common.get_buffer_size(&mOutput->stream->common);
+ mFrameCount = mBufferSize / mFrameSize;
if (mFrameCount & 15) {
ALOGW("HAL output buffer size is %u frames but AudioMixer requires multiples of 16 frames",
mFrameCount);
@@ -1615,11 +1618,11 @@
ALOGI("HAL output buffer size %u frames, normal mix buffer size %u frames", mFrameCount,
mNormalFrameCount);
- delete[] mAllocMixBuffer;
- size_t align = (mFrameSize < sizeof(int16_t)) ? sizeof(int16_t) : mFrameSize;
- mAllocMixBuffer = new int8_t[mNormalFrameCount * mFrameSize + align - 1];
- mMixBuffer = (int16_t *) ((((size_t)mAllocMixBuffer + align - 1) / align) * align);
- memset(mMixBuffer, 0, mNormalFrameCount * mFrameSize);
+ delete[] mMixBuffer;
+ size_t normalBufferSize = mNormalFrameCount * mFrameSize;
+ // For historical reasons mMixBuffer is int16_t[], but mFrameSize can be odd (such as 1)
+ mMixBuffer = new int16_t[(normalBufferSize + 1) >> 1];
+ memset(mMixBuffer, 0, normalBufferSize);
// force reconfiguration of effect chains and engines to take new buffer size and audio
// parameters into account
@@ -4159,7 +4162,7 @@
) :
ThreadBase(audioFlinger, id, outDevice, inDevice, RECORD),
mInput(input), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL),
- // mRsmpInIndex and mBufferSize set by readInputParameters()
+ // mRsmpInIndex set by readInputParameters()
mReqChannelCount(popcount(channelMask)),
mReqSampleRate(sampleRate)
// mBytesRead is only meaningful while active, and so is cleared in start()
@@ -4187,13 +4190,6 @@
run(mName, PRIORITY_URGENT_AUDIO);
}
-status_t AudioFlinger::RecordThread::readyToRun()
-{
- status_t status = initCheck();
- ALOGW_IF(status != NO_ERROR,"RecordThread %p could not initialize", this);
- return status;
-}
-
bool AudioFlinger::RecordThread::threadLoop()
{
AudioBufferProvider::Buffer buffer;
@@ -4505,8 +4501,9 @@
track = new RecordTrack(this, client, sampleRate,
format, channelMask, frameCount, sessionId);
- if (track->getCblk() == 0) {
- lStatus = NO_MEMORY;
+ lStatus = track->initCheck();
+ if (lStatus != NO_ERROR) {
+ track.clear();
goto Exit;
}
mTracks.add(track);
@@ -4527,9 +4524,7 @@
lStatus = NO_ERROR;
Exit:
- if (status) {
- *status = lStatus;
- }
+ *status = lStatus;
return track;
}
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 31d5323..fce3245 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -36,6 +36,8 @@
audio_devices_t outDevice, audio_devices_t inDevice, type_t type);
virtual ~ThreadBase();
+ virtual status_t readyToRun();
+
void dumpBase(int fd, const Vector<String16>& args);
void dumpEffectChains(int fd, const Vector<String16>& args);
@@ -156,7 +158,7 @@
int sessionId,
effect_descriptor_t *desc,
int *enabled,
- status_t *status);
+ status_t *status /*non-NULL*/);
void disconnectEffect(const sp< EffectModule>& effect,
EffectHandle *handle,
bool unpinIfLast);
@@ -270,6 +272,7 @@
uint32_t mChannelCount;
size_t mFrameSize;
audio_format_t mFormat;
+ size_t mBufferSize; // HAL buffer size for read() or write()
// Parameter sequence by client: binder thread calling setParameters():
// 1. Lock mLock
@@ -353,7 +356,6 @@
void dump(int fd, const Vector<String16>& args);
// Thread virtuals
- virtual status_t readyToRun();
virtual bool threadLoop();
// RefBase
@@ -419,7 +421,7 @@
int sessionId,
IAudioFlinger::track_flags_t *flags,
pid_t tid,
- status_t *status);
+ status_t *status /*non-NULL*/);
AudioStreamOut* getOutput() const;
AudioStreamOut* clearOutput();
@@ -471,7 +473,6 @@
size_t mNormalFrameCount; // normal mixer and effects
int16_t* mMixBuffer; // frame size aligned mix buffer
- int8_t* mAllocMixBuffer; // mixer buffer allocation address
// suspend count, > 0 means suspended. While suspended, the thread continues to pull from
// tracks and mix, but doesn't write to HAL. A2DP and SCO HAL implementations can't handle
@@ -824,7 +825,6 @@
// Thread virtuals
virtual bool threadLoop();
- virtual status_t readyToRun();
// RefBase
virtual void onFirstRef();
@@ -839,7 +839,7 @@
int sessionId,
IAudioFlinger::track_flags_t *flags,
pid_t tid,
- status_t *status);
+ status_t *status /*non-NULL*/);
status_t start(RecordTrack* recordTrack,
AudioSystem::sync_event_t event,
@@ -903,7 +903,6 @@
int32_t *mRsmpOutBuffer;
int16_t *mRsmpInBuffer; // [mFrameCount * mChannelCount]
size_t mRsmpInIndex;
- size_t mBufferSize; // stream buffer size for read()
const uint32_t mReqChannelCount;
const uint32_t mReqSampleRate;
ssize_t mBytesRead;
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 523e4b2..00a91b7 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -47,6 +47,7 @@
int sessionId,
bool isOut);
virtual ~TrackBase();
+ virtual status_t initCheck() const { return getCblk() != 0 ? NO_ERROR : NO_MEMORY; }
virtual status_t start(AudioSystem::sync_event_t event,
int triggerSession) = 0;
@@ -76,15 +77,6 @@
virtual uint32_t sampleRate() const { return mSampleRate; }
- // Return a pointer to the start of a contiguous slice of the track buffer.
- // Parameter 'offset' is the requested start position, expressed in
- // monotonically increasing frame units relative to the track epoch.
- // Parameter 'frames' is the requested length, also in frame units.
- // Always returns non-NULL. It is the caller's responsibility to
- // verify that this will be successful; the result of calling this
- // function with invalid 'offset' or 'frames' is undefined.
- void* getBuffer(uint32_t offset, uint32_t frames) const;
-
bool isStopped() const {
return (mState == STOPPED || mState == FLUSHED);
}
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index e676365..6039078 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -361,6 +361,15 @@
ALOGV("PlaybackThread::Track destructor");
}
+status_t AudioFlinger::PlaybackThread::Track::initCheck() const
+{
+ status_t status = TrackBase::initCheck();
+ if (status == NO_ERROR && mName < 0) {
+ status = NO_MEMORY;
+ }
+ return status;
+}
+
void AudioFlinger::PlaybackThread::Track::destroy()
{
// NOTE: destroyTrack_l() can remove a strong reference to this Track
@@ -1651,9 +1660,7 @@
{
ALOGV("RecordTrack constructor");
if (mCblk != NULL) {
- mAudioRecordServerProxy = new AudioRecordServerProxy(mCblk, mBuffer, frameCount,
- mFrameSize);
- mServerProxy = mAudioRecordServerProxy;
+ mServerProxy = new AudioRecordServerProxy(mCblk, mBuffer, frameCount, mFrameSize);
}
}