diff options
256 files changed, 2342 insertions, 1432 deletions
diff --git a/camera/Camera.cpp b/camera/Camera.cpp index 85f44f0..3a9fb4c 100644 --- a/camera/Camera.cpp +++ b/camera/Camera.cpp @@ -55,7 +55,7 @@ sp<Camera> Camera::create(const sp<ICamera>& camera) if (camera->connect(c) == NO_ERROR) { c->mStatus = NO_ERROR; c->mCamera = camera; - camera->asBinder()->linkToDeath(c); + IInterface::asBinder(camera)->linkToDeath(c); return c; } return 0; @@ -93,7 +93,7 @@ status_t Camera::connectLegacy(int cameraId, int halVersion, clientUid, /*out*/c->mCamera); } if (status == OK && c->mCamera != 0) { - c->mCamera->asBinder()->linkToDeath(c); + IInterface::asBinder(c->mCamera)->linkToDeath(c); c->mStatus = NO_ERROR; camera = c; } else { diff --git a/camera/CameraBase.cpp b/camera/CameraBase.cpp index 04694cd..65a1a47 100644 --- a/camera/CameraBase.cpp +++ b/camera/CameraBase.cpp @@ -107,7 +107,7 @@ sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId, /*out*/ c->mCamera); } if (status == OK && c->mCamera != 0) { - c->mCamera->asBinder()->linkToDeath(c); + IInterface::asBinder(c->mCamera)->linkToDeath(c); c->mStatus = NO_ERROR; } else { ALOGW("An error occurred while connecting to camera: %d", cameraId); @@ -122,7 +122,7 @@ void CameraBase<TCam, TCamTraits>::disconnect() ALOGV("%s: disconnect", __FUNCTION__); if (mCamera != 0) { mCamera->disconnect(); - mCamera->asBinder()->unlinkToDeath(this); + IInterface::asBinder(mCamera)->unlinkToDeath(this); mCamera = 0; } ALOGV("%s: disconnect (done)", __FUNCTION__); diff --git a/camera/ICamera.cpp b/camera/ICamera.cpp index 8c6e1f7..9943be6 100644 --- a/camera/ICamera.cpp +++ b/camera/ICamera.cpp @@ -75,7 +75,7 @@ public: ALOGV("setPreviewTarget"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); - sp<IBinder> b(bufferProducer->asBinder()); + sp<IBinder> b(IInterface::asBinder(bufferProducer)); data.writeStrongBinder(b); remote()->transact(SET_PREVIEW_TARGET, data, &reply); return reply.readInt32(); @@ -98,7 +98,7 @@ public: ALOGV("setPreviewCallbackTarget"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); - sp<IBinder> b(callbackProducer->asBinder()); + sp<IBinder> b(IInterface::asBinder(callbackProducer)); data.writeStrongBinder(b); remote()->transact(SET_PREVIEW_CALLBACK_TARGET, data, &reply); return reply.readInt32(); @@ -147,7 +147,7 @@ public: ALOGV("releaseRecordingFrame"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); - data.writeStrongBinder(mem->asBinder()); + data.writeStrongBinder(IInterface::asBinder(mem)); remote()->transact(RELEASE_RECORDING_FRAME, data, &reply); } @@ -250,7 +250,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); - data.writeStrongBinder(cameraClient->asBinder()); + data.writeStrongBinder(IInterface::asBinder(cameraClient)); remote()->transact(CONNECT, data, &reply); return reply.readInt32(); } diff --git a/camera/ICameraClient.cpp b/camera/ICameraClient.cpp index 205c8ba..179a341 100644 --- a/camera/ICameraClient.cpp +++ b/camera/ICameraClient.cpp @@ -58,7 +58,7 @@ public: Parcel data, reply; data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor()); data.writeInt32(msgType); - data.writeStrongBinder(imageData->asBinder()); + data.writeStrongBinder(IInterface::asBinder(imageData)); if (metadata) { data.writeInt32(metadata->number_of_faces); data.write(metadata->faces, sizeof(camera_face_t) * metadata->number_of_faces); @@ -74,7 +74,7 @@ public: data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor()); data.writeInt64(timestamp); data.writeInt32(msgType); - data.writeStrongBinder(imageData->asBinder()); + data.writeStrongBinder(IInterface::asBinder(imageData)); remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply, IBinder::FLAG_ONEWAY); } }; diff --git a/camera/ICameraRecordingProxy.cpp b/camera/ICameraRecordingProxy.cpp index 7223b6d..3dc0ffb 100644 --- a/camera/ICameraRecordingProxy.cpp +++ b/camera/ICameraRecordingProxy.cpp @@ -45,7 +45,7 @@ public: ALOGV("startRecording"); Parcel data, reply; data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor()); - data.writeStrongBinder(listener->asBinder()); + data.writeStrongBinder(IInterface::asBinder(listener)); remote()->transact(START_RECORDING, data, &reply); return reply.readInt32(); } @@ -63,7 +63,7 @@ public: ALOGV("releaseRecordingFrame"); Parcel data, reply; data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor()); - data.writeStrongBinder(mem->asBinder()); + data.writeStrongBinder(IInterface::asBinder(mem)); remote()->transact(RELEASE_RECORDING_FRAME, data, &reply); } }; diff --git a/camera/ICameraRecordingProxyListener.cpp b/camera/ICameraRecordingProxyListener.cpp index cb17f19..cf848fc 100644 --- a/camera/ICameraRecordingProxyListener.cpp +++ b/camera/ICameraRecordingProxyListener.cpp @@ -42,7 +42,7 @@ public: data.writeInterfaceToken(ICameraRecordingProxyListener::getInterfaceDescriptor()); data.writeInt64(timestamp); data.writeInt32(msgType); - data.writeStrongBinder(imageData->asBinder()); + data.writeStrongBinder(IInterface::asBinder(imageData)); remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply, IBinder::FLAG_ONEWAY); } }; diff --git a/camera/ICameraService.cpp b/camera/ICameraService.cpp index 5485205..fc3e437 100644 --- a/camera/ICameraService.cpp +++ b/camera/ICameraService.cpp @@ -172,7 +172,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); - data.writeStrongBinder(cameraClient->asBinder()); + data.writeStrongBinder(IInterface::asBinder(cameraClient)); data.writeInt32(cameraId); data.writeString16(clientPackageName); data.writeInt32(clientUid); @@ -194,7 +194,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); - data.writeStrongBinder(cameraClient->asBinder()); + data.writeStrongBinder(IInterface::asBinder(cameraClient)); data.writeInt32(cameraId); data.writeInt32(halVersion); data.writeString16(clientPackageName); @@ -217,7 +217,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); - data.writeStrongBinder(cameraCb->asBinder()); + data.writeStrongBinder(IInterface::asBinder(cameraCb)); data.writeInt32(cameraId); data.writeString16(clientPackageName); data.writeInt32(clientUid); @@ -242,7 +242,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); - data.writeStrongBinder(cameraCb->asBinder()); + data.writeStrongBinder(IInterface::asBinder(cameraCb)); data.writeInt32(cameraId); data.writeString16(clientPackageName); data.writeInt32(clientUid); @@ -260,7 +260,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); - data.writeStrongBinder(listener->asBinder()); + data.writeStrongBinder(IInterface::asBinder(listener)); remote()->transact(BnCameraService::ADD_LISTENER, data, &reply); if (readExceptionCode(reply)) return -EPROTO; @@ -271,7 +271,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); - data.writeStrongBinder(listener->asBinder()); + data.writeStrongBinder(IInterface::asBinder(listener)); remote()->transact(BnCameraService::REMOVE_LISTENER, data, &reply); if (readExceptionCode(reply)) return -EPROTO; @@ -384,7 +384,7 @@ status_t BnCameraService::onTransact( reply->writeInt32(status); if (camera != NULL) { reply->writeInt32(1); - reply->writeStrongBinder(camera->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(camera)); } else { reply->writeInt32(0); } @@ -404,7 +404,7 @@ status_t BnCameraService::onTransact( reply->writeInt32(status); if (camera != NULL) { reply->writeInt32(1); - reply->writeStrongBinder(camera->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(camera)); } else { reply->writeInt32(0); } @@ -424,7 +424,7 @@ status_t BnCameraService::onTransact( reply->writeInt32(status); if (camera != NULL) { reply->writeInt32(1); - reply->writeStrongBinder(camera->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(camera)); } else { reply->writeInt32(0); } @@ -484,7 +484,7 @@ status_t BnCameraService::onTransact( reply->writeInt32(status); if (camera != NULL) { reply->writeInt32(1); - reply->writeStrongBinder(camera->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(camera)); } else { reply->writeInt32(0); } diff --git a/camera/IProCameraUser.cpp b/camera/IProCameraUser.cpp index 8f22124..9bd7597 100644 --- a/camera/IProCameraUser.cpp +++ b/camera/IProCameraUser.cpp @@ -65,7 +65,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(IProCameraUser::getInterfaceDescriptor()); - data.writeStrongBinder(cameraClient->asBinder()); + data.writeStrongBinder(IInterface::asBinder(cameraClient)); remote()->transact(CONNECT, data, &reply); return reply.readInt32(); } @@ -150,7 +150,7 @@ public: data.writeInt32(height); data.writeInt32(format); - sp<IBinder> b(bufferProducer->asBinder()); + sp<IBinder> b(IInterface::asBinder(bufferProducer)); data.writeStrongBinder(b); remote()->transact(CREATE_STREAM, data, &reply); diff --git a/camera/camera2/CaptureRequest.cpp b/camera/camera2/CaptureRequest.cpp index 57e5319..d5e1c5b 100644 --- a/camera/camera2/CaptureRequest.cpp +++ b/camera/camera2/CaptureRequest.cpp @@ -106,7 +106,7 @@ status_t CaptureRequest::writeToParcel(Parcel* parcel) const { sp<IBinder> binder; if (surface != 0) { - binder = surface->getIGraphicBufferProducer()->asBinder(); + binder = IInterface::asBinder(surface->getIGraphicBufferProducer()); } // not sure if readParcelableArray does this, hard to tell from source diff --git a/camera/camera2/ICameraDeviceUser.cpp b/camera/camera2/ICameraDeviceUser.cpp index ff4a0c2..35345d2 100644 --- a/camera/camera2/ICameraDeviceUser.cpp +++ b/camera/camera2/ICameraDeviceUser.cpp @@ -219,7 +219,7 @@ public: data.writeInt32(1); // marker that bufferProducer is not null data.writeString16(String16("unknown_name")); // name of surface - sp<IBinder> b(bufferProducer->asBinder()); + sp<IBinder> b(IInterface::asBinder(bufferProducer)); data.writeStrongBinder(b); remote()->transact(CREATE_STREAM, data, &reply); diff --git a/cmds/screenrecord/FrameOutput.cpp b/cmds/screenrecord/FrameOutput.cpp index 03e0062..bef74f5 100644 --- a/cmds/screenrecord/FrameOutput.cpp +++ b/cmds/screenrecord/FrameOutput.cpp @@ -206,7 +206,7 @@ void FrameOutput::reduceRgbaToRgb(uint8_t* buf, unsigned int pixelCount) { } // Callback; executes on arbitrary thread. -void FrameOutput::onFrameAvailable() { +void FrameOutput::onFrameAvailable(const BufferItem& /* item */) { Mutex::Autolock _l(mMutex); mFrameAvailable = true; mEventCond.signal(); diff --git a/cmds/screenrecord/FrameOutput.h b/cmds/screenrecord/FrameOutput.h index c49ec3b..4c0c3be 100644 --- a/cmds/screenrecord/FrameOutput.h +++ b/cmds/screenrecord/FrameOutput.h @@ -62,7 +62,7 @@ private: } // (overrides GLConsumer::FrameAvailableListener method) - virtual void onFrameAvailable(); + virtual void onFrameAvailable(const BufferItem& item); // Reduces RGBA to RGB, in place. static void reduceRgbaToRgb(uint8_t* buf, unsigned int pixelCount); diff --git a/cmds/screenrecord/Overlay.cpp b/cmds/screenrecord/Overlay.cpp index 7fef53d..c659170 100644 --- a/cmds/screenrecord/Overlay.cpp +++ b/cmds/screenrecord/Overlay.cpp @@ -274,7 +274,7 @@ void Overlay::getTimeString_l(nsecs_t monotonicNsec, char* buf, size_t bufLen) { } // Callback; executes on arbitrary thread. -void Overlay::onFrameAvailable() { +void Overlay::onFrameAvailable(const BufferItem& /* item */) { ALOGV("Overlay::onFrameAvailable"); Mutex::Autolock _l(mMutex); mFrameAvailable = true; diff --git a/cmds/screenrecord/Overlay.h b/cmds/screenrecord/Overlay.h index b1b5c29..ee3444d 100644 --- a/cmds/screenrecord/Overlay.h +++ b/cmds/screenrecord/Overlay.h @@ -78,7 +78,7 @@ private: const Program& texRender, TextRenderer& textRenderer); // (overrides GLConsumer::FrameAvailableListener method) - virtual void onFrameAvailable(); + virtual void onFrameAvailable(const BufferItem& item); // (overrides Thread method) virtual bool threadLoop(); diff --git a/cmds/stagefright/SineSource.h b/cmds/stagefright/SineSource.h index 76ab669..d772e0d 100644 --- a/cmds/stagefright/SineSource.h +++ b/cmds/stagefright/SineSource.h @@ -6,7 +6,7 @@ namespace android { -struct MediaBufferGroup; +class MediaBufferGroup; struct SineSource : public MediaSource { SineSource(int32_t sampleRate, int32_t numChannels); diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp index 36cb612..3f62ed7 100644 --- a/drm/common/IDrmManagerService.cpp +++ b/drm/common/IDrmManagerService.cpp @@ -148,8 +148,7 @@ status_t BpDrmManagerService::setDrmServiceListener( data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); - data.writeStrongBinder( - drmServiceListener != NULL ? drmServiceListener->asBinder() : NULL); + data.writeStrongBinder(IInterface::asBinder(drmServiceListener)); remote()->transact(SET_DRM_SERVICE_LISTENER, data, &reply); return reply.readInt32(); } diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp index 2d2c90e..9457bb6 100644 --- a/drm/libdrmframework/DrmManagerClientImpl.cpp +++ b/drm/libdrmframework/DrmManagerClientImpl.cpp @@ -346,7 +346,7 @@ status_t DrmManagerClientImpl::notify(const DrmInfoEvent& event) { DrmManagerClientImpl::DeathNotifier::~DeathNotifier() { Mutex::Autolock lock(sMutex); if (NULL != sDrmManagerService.get()) { - sDrmManagerService->asBinder()->unlinkToDeath(this); + IInterface::asBinder(sDrmManagerService)->unlinkToDeath(this); } } diff --git a/drm/mediadrm/plugins/clearkey/Android.mk b/drm/mediadrm/plugins/clearkey/Android.mk index 22a85b4..b713a7f 100644 --- a/drm/mediadrm/plugins/clearkey/Android.mk +++ b/drm/mediadrm/plugins/clearkey/Android.mk @@ -31,7 +31,6 @@ LOCAL_SRC_FILES := \ Utils.cpp \ LOCAL_C_INCLUDES := \ - bionic \ external/jsmn \ external/openssl/include \ frameworks/av/drm/mediadrm/plugins/clearkey \ diff --git a/drm/mediadrm/plugins/clearkey/tests/Android.mk b/drm/mediadrm/plugins/clearkey/tests/Android.mk index ac5bb21..80f94e0 100644 --- a/drm/mediadrm/plugins/clearkey/tests/Android.mk +++ b/drm/mediadrm/plugins/clearkey/tests/Android.mk @@ -28,25 +28,17 @@ LOCAL_SRC_FILES := \ JsonWebKeyUnittest.cpp \ LOCAL_C_INCLUDES := \ - bionic \ - external/gtest/include \ external/jsmn \ external/openssl/include \ - external/stlport/stlport \ frameworks/av/drm/mediadrm/plugins/clearkey \ frameworks/av/include \ frameworks/native/include \ -LOCAL_STATIC_LIBRARIES := \ - libgtest \ - libgtest_main \ - LOCAL_SHARED_LIBRARIES := \ libcrypto \ libdrmclearkeyplugin \ liblog \ libstagefright_foundation \ - libstlport \ libutils \ include $(BUILD_NATIVE_TEST) diff --git a/include/camera/ProCamera.h b/include/camera/ProCamera.h index 83a3028..e9b687a 100644 --- a/include/camera/ProCamera.h +++ b/include/camera/ProCamera.h @@ -265,7 +265,7 @@ private: } protected: - virtual void onFrameAvailable() { + virtual void onFrameAvailable(const BufferItem& /* item */) { sp<ProCamera> c = mCamera.promote(); if (c.get() != NULL) { c->onFrameAvailable(mStreamId); diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index f8c0198..f3b7fbb 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -99,8 +99,6 @@ public: // to be non-zero if status == NO_ERROR static status_t getOutputSamplingRate(uint32_t* samplingRate, audio_stream_type_t stream); - static status_t getOutputSamplingRateForAttr(uint32_t* samplingRate, - const audio_attributes_t *attr); static status_t getOutputFrameCount(size_t* frameCount, audio_stream_type_t stream); static status_t getOutputLatency(uint32_t* latency, @@ -116,8 +114,6 @@ public: static status_t getLatency(audio_io_handle_t output, uint32_t* latency); - static bool routedToA2dpOutput(audio_stream_type_t streamType); - // return status NO_ERROR implies *buffSize > 0 static status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, size_t* buffSize); @@ -377,7 +373,10 @@ private: friend class AudioFlingerClient; friend class AudioPolicyServiceClient; - static Mutex gLock; + static Mutex gLock; // protects all members except gAudioPolicyService, + // gAudioPolicyServiceClient, and gAudioPortCallback + static Mutex gLockAPS; // protects gAudioPolicyService and gAudioPolicyServiceClient + static Mutex gLockAPC; // protects gAudioPortCallback static sp<IAudioFlinger> gAudioFlinger; static audio_error_callback gAudioErrorCallback; diff --git a/include/media/stagefright/MediaCodecSource.h b/include/media/stagefright/MediaCodecSource.h index 3629c8b..0970b2b 100644 --- a/include/media/stagefright/MediaCodecSource.h +++ b/include/media/stagefright/MediaCodecSource.h @@ -85,8 +85,6 @@ private: status_t initEncoder(); void releaseEncoder(); status_t feedEncoderInputBuffers(); - void scheduleDoMoreWork(); - status_t doMoreWork(int32_t numInput, int32_t numOutput); void suspend(); void resume(int64_t skipFramesBeforeUs = -1ll); void signalEOS(status_t err = ERROR_END_OF_STREAM); @@ -108,8 +106,6 @@ private: bool mDoMoreWorkPending; sp<AMessage> mEncoderActivityNotify; sp<IGraphicBufferProducer> mGraphicBufferProducer; - Vector<sp<ABuffer> > mEncoderInputBuffers; - Vector<sp<ABuffer> > mEncoderOutputBuffers; List<MediaBuffer *> mInputBufferQueue; List<size_t> mAvailEncoderInputIndices; List<int64_t> mDecodingTimeQueue; // decoding time (us) for video diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h index ffe4f4c..2177c00 100644 --- a/include/media/stagefright/SurfaceMediaSource.h +++ b/include/media/stagefright/SurfaceMediaSource.h @@ -126,7 +126,7 @@ protected: // Implementation of the BufferQueue::ConsumerListener interface. These // calls are used to notify the Surface of asynchronous events in the // BufferQueue. - virtual void onFrameAvailable(); + virtual void onFrameAvailable(const BufferItem& item); // Used as a hook to BufferQueue::disconnect() // This is called by the client side when it is done diff --git a/include/media/stagefright/foundation/ADebug.h b/include/media/stagefright/foundation/ADebug.h index 450dcfe..1d0e2cb 100644 --- a/include/media/stagefright/foundation/ADebug.h +++ b/include/media/stagefright/foundation/ADebug.h @@ -80,6 +80,36 @@ MAKE_COMPARATOR(GT,>) __FILE__ ":" LITERAL_TO_STRING(__LINE__) \ " Should not be here."); +struct ADebug { + enum Level { + kDebugNone, // no debug + kDebugLifeCycle, // lifecycle events: creation/deletion + kDebugState, // commands and events + kDebugConfig, // configuration + kDebugInternalState, // internal state changes + kDebugAll, // all + kDebugMax = kDebugAll, + + }; + + // parse the property or string to get the debug level for a component name + // string format is: + // <level>[:<glob>][,<level>[:<glob>]...] + // - <level> is 0-5 corresponding to ADebug::Level + // - <glob> is used to match component name case insensitively, if omitted, it + // matches all components + // - string is read left-to-right, and the last matching level is returned, or + // the def if no terms matched + static Level GetDebugLevelFromProperty( + const char *name, const char *propertyName, Level def = kDebugNone); + static Level GetDebugLevelFromString( + const char *name, const char *value, Level def = kDebugNone); + + // remove redundant segments of a codec name, and return a newly allocated + // string suitable for debugging + static char *GetDebugName(const char *name); +}; + } // namespace android #endif // A_DEBUG_H_ diff --git a/include/media/stagefright/foundation/AString.h b/include/media/stagefright/foundation/AString.h index 7c98699..c3a68e1 100644 --- a/include/media/stagefright/foundation/AString.h +++ b/include/media/stagefright/foundation/AString.h @@ -23,7 +23,7 @@ namespace android { -struct String8; +class String8; struct Parcel; struct AString { diff --git a/include/media/stagefright/foundation/AStringUtils.h b/include/media/stagefright/foundation/AStringUtils.h new file mode 100644 index 0000000..76a7791 --- /dev/null +++ b/include/media/stagefright/foundation/AStringUtils.h @@ -0,0 +1,36 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef A_STRING_UTILS_H_ +#define A_STRING_UTILS_H_ + +#include <stdlib.h> + +namespace android { + +struct AStringUtils { + // similar to strncmp or strcasecmp, but case sensitivity is parametric + static int Compare(const char *a, const char *b, size_t len, bool ignoreCase); + + // matches a string (str) to a glob pattern that supports: + // * - matches any number of characters + static bool MatchesGlob( + const char *glob, size_t globLen, const char *str, size_t strLen, bool ignoreCase); +}; + +} // namespace android + +#endif // A_STRING_UTILS_H_ diff --git a/media/common_time/ICommonClock.cpp b/media/common_time/ICommonClock.cpp index 25ae69e..19b7d6e 100644 --- a/media/common_time/ICommonClock.cpp +++ b/media/common_time/ICommonClock.cpp @@ -206,7 +206,7 @@ class BpCommonClock : public BpInterface<ICommonClock> const sp<ICommonClockListener>& listener) { Parcel data, reply; data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); - data.writeStrongBinder(listener->asBinder()); + data.writeStrongBinder(IInterface::asBinder(listener)); status_t status = remote()->transact(REGISTER_LISTENER, data, &reply); @@ -221,7 +221,7 @@ class BpCommonClock : public BpInterface<ICommonClock> const sp<ICommonClockListener>& listener) { Parcel data, reply; data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); - data.writeStrongBinder(listener->asBinder()); + data.writeStrongBinder(IInterface::asBinder(listener)); status_t status = remote()->transact(UNREGISTER_LISTENER, data, &reply); if (status == OK) { diff --git a/media/libeffects/loudness/Android.mk b/media/libeffects/loudness/Android.mk index 70d7984..55d0611 100644 --- a/media/libeffects/loudness/Android.mk +++ b/media/libeffects/loudness/Android.mk @@ -19,5 +19,4 @@ LOCAL_MODULE:= libldnhncr LOCAL_C_INCLUDES := \ $(call include-path-for, audio-effects) \ -include external/stlport/libstlport.mk include $(BUILD_SHARED_LIBRARY) diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index e012116..50d9a0f 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -74,6 +74,8 @@ LOCAL_WHOLE_STATIC_LIBRARIES := libmedia_helper LOCAL_MODULE:= libmedia +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk + LOCAL_C_INCLUDES := \ $(TOP)/frameworks/native/include/media/openmax \ $(TOP)/frameworks/av/include/media/ \ @@ -87,8 +89,6 @@ include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) -# for <cutils/atomic-inline.h> -LOCAL_CFLAGS += -DANDROID_SMP=$(if $(findstring true,$(TARGET_CPU_SMP)),1,0) LOCAL_SRC_FILES += SingleStateQueue.cpp LOCAL_CFLAGS += -DSINGLE_STATE_QUEUE_INSTANTIATIONS='"SingleStateQueueInstantiations.cpp"' diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp index 0d5d7e4..af103c1 100644 --- a/media/libmedia/AudioEffect.cpp +++ b/media/libmedia/AudioEffect.cpp @@ -150,7 +150,7 @@ status_t AudioEffect::set(const effect_uuid_t *type, int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int); mCblk->buffer = (uint8_t *)mCblk + bufOffset; - iEffect->asBinder()->linkToDeath(mIEffectClient); + IInterface::asBinder(iEffect)->linkToDeath(mIEffectClient); mClientPid = IPCThreadState::self()->getCallingPid(); ALOGV("set() %p OK effect: %s id: %d status %d enabled %d pid %d", this, mDescriptor.name, mId, mStatus, mEnabled, mClientPid); @@ -173,7 +173,7 @@ AudioEffect::~AudioEffect() } if (mIEffect != NULL) { mIEffect->disconnect(); - mIEffect->asBinder()->unlinkToDeath(mIEffectClient); + IInterface::asBinder(mIEffect)->unlinkToDeath(mIEffectClient); } IPCThreadState::self()->flushCommands(); } diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 9e7ba88..9d92cfe 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -105,7 +105,7 @@ AudioRecord::~AudioRecord() mAudioRecordThread->requestExitAndWait(); mAudioRecordThread.clear(); } - mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this); + IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this); mAudioRecord.clear(); mCblkMemory.clear(); mBufferMemory.clear(); @@ -516,7 +516,7 @@ status_t AudioRecord::openRecord_l(size_t epoch) // invariant that mAudioRecord != 0 is true only after set() returns successfully if (mAudioRecord != 0) { - mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this); + IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this); mDeathNotifier.clear(); } mAudioRecord = record; @@ -566,7 +566,7 @@ status_t AudioRecord::openRecord_l(size_t epoch) mProxy->setMinimum(mNotificationFramesAct); mDeathNotifier = new DeathNotifier(this); - mAudioRecord->asBinder()->linkToDeath(mDeathNotifier, this); + IInterface::asBinder(mAudioRecord)->linkToDeath(mDeathNotifier, this); return NO_ERROR; } diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index dda3657..fce4389 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -32,6 +32,8 @@ namespace android { // client singleton for AudioFlinger binder interface Mutex AudioSystem::gLock; +Mutex AudioSystem::gLockAPS; +Mutex AudioSystem::gLockAPC; sp<IAudioFlinger> AudioSystem::gAudioFlinger; sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient; audio_error_callback AudioSystem::gAudioErrorCallback = NULL; @@ -70,9 +72,9 @@ const sp<IAudioFlinger>& AudioSystem::get_audio_flinger() } binder->linkToDeath(gAudioFlingerClient); gAudioFlinger = interface_cast<IAudioFlinger>(binder); + LOG_ALWAYS_FATAL_IF(gAudioFlinger == 0); gAudioFlinger->registerClient(gAudioFlingerClient); } - ALOGE_IF(gAudioFlinger==0, "no AudioFlinger!?"); return gAudioFlinger; } @@ -245,19 +247,6 @@ status_t AudioSystem::getOutputSamplingRate(uint32_t* samplingRate, audio_stream return getSamplingRate(output, samplingRate); } -status_t AudioSystem::getOutputSamplingRateForAttr(uint32_t* samplingRate, - const audio_attributes_t *attr) -{ - if (attr == NULL) { - return BAD_VALUE; - } - audio_io_handle_t output = getOutputForAttr(attr); - if (output == 0) { - return PERMISSION_DENIED; - } - return getSamplingRate(output, samplingRate); -} - status_t AudioSystem::getSamplingRate(audio_io_handle_t output, uint32_t* samplingRate) { @@ -543,22 +532,8 @@ void AudioSystem::setErrorCallback(audio_error_callback cb) gAudioErrorCallback = cb; } - -bool AudioSystem::routedToA2dpOutput(audio_stream_type_t streamType) -{ - switch (streamType) { - case AUDIO_STREAM_MUSIC: - case AUDIO_STREAM_VOICE_CALL: - case AUDIO_STREAM_BLUETOOTH_SCO: - case AUDIO_STREAM_SYSTEM: - return true; - default: - return false; - } -} - - // client singleton for AudioPolicyService binder interface +// protected by gLockAPS sp<IAudioPolicyService> AudioSystem::gAudioPolicyService; sp<AudioSystem::AudioPolicyServiceClient> AudioSystem::gAudioPolicyServiceClient; @@ -566,7 +541,7 @@ sp<AudioSystem::AudioPolicyServiceClient> AudioSystem::gAudioPolicyServiceClient // establish binder interface to AudioPolicy service const sp<IAudioPolicyService>& AudioSystem::get_audio_policy_service() { - gLock.lock(); + Mutex::Autolock _l(gLockAPS); if (gAudioPolicyService == 0) { sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder; @@ -582,15 +557,10 @@ const sp<IAudioPolicyService>& AudioSystem::get_audio_policy_service() } binder->linkToDeath(gAudioPolicyServiceClient); gAudioPolicyService = interface_cast<IAudioPolicyService>(binder); - gLock.unlock(); - // Registering the client takes the AudioPolicyService lock. - // Don't hold the AudioSystem lock at the same time. + LOG_ALWAYS_FATAL_IF(gAudioPolicyService == 0); gAudioPolicyService->registerClient(gAudioPolicyServiceClient); - } else { - // There exists a benign race condition where gAudioPolicyService - // is set, but gAudioPolicyServiceClient is not yet registered. - gLock.unlock(); } + return gAudioPolicyService; } @@ -856,9 +826,18 @@ status_t AudioSystem::setLowRamDevice(bool isLowRamDevice) void AudioSystem::clearAudioConfigCache() { - Mutex::Autolock _l(gLock); + // called by restoreTrack_l(), which needs new IAudioFlinger and IAudioPolicyService instances ALOGV("clearAudioConfigCache()"); - gOutputs.clear(); + { + Mutex::Autolock _l(gLock); + gOutputs.clear(); + gAudioFlinger.clear(); + } + { + Mutex::Autolock _l(gLockAPS); + gAudioPolicyService.clear(); + } + // Do not clear gAudioPortCallback } bool AudioSystem::isOffloadSupported(const audio_offload_info_t& info) @@ -920,7 +899,7 @@ status_t AudioSystem::setAudioPortConfig(const struct audio_port_config *config) void AudioSystem::setAudioPortCallback(sp<AudioPortCallback> callBack) { - Mutex::Autolock _l(gLock); + Mutex::Autolock _l(gLockAPC); gAudioPortCallback = callBack; } @@ -952,18 +931,23 @@ audio_mode_t AudioSystem::getPhoneState() void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused) { - Mutex::Autolock _l(gLock); - if (gAudioPortCallback != 0) { - gAudioPortCallback->onServiceDied(); + { + Mutex::Autolock _l(gLockAPC); + if (gAudioPortCallback != 0) { + gAudioPortCallback->onServiceDied(); + } + } + { + Mutex::Autolock _l(gLockAPS); + AudioSystem::gAudioPolicyService.clear(); } - AudioSystem::gAudioPolicyService.clear(); ALOGW("AudioPolicyService server died!"); } void AudioSystem::AudioPolicyServiceClient::onAudioPortListUpdate() { - Mutex::Autolock _l(gLock); + Mutex::Autolock _l(gLockAPC); if (gAudioPortCallback != 0) { gAudioPortCallback->onAudioPortListUpdate(); } @@ -971,7 +955,7 @@ void AudioSystem::AudioPolicyServiceClient::onAudioPortListUpdate() void AudioSystem::AudioPolicyServiceClient::onAudioPatchListUpdate() { - Mutex::Autolock _l(gLock); + Mutex::Autolock _l(gLockAPC); if (gAudioPortCallback != 0) { gAudioPortCallback->onAudioPatchListUpdate(); } diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 082a5e1..3248adb 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -193,7 +193,7 @@ AudioTrack::~AudioTrack() mAudioTrackThread->requestExitAndWait(); mAudioTrackThread.clear(); } - mAudioTrack->asBinder()->unlinkToDeath(mDeathNotifier, this); + IInterface::asBinder(mAudioTrack)->unlinkToDeath(mDeathNotifier, this); mAudioTrack.clear(); mCblkMemory.clear(); mSharedBuffer.clear(); @@ -304,17 +304,6 @@ status_t AudioTrack::set( mAttributes.usage, mAttributes.content_type, mAttributes.flags, mAttributes.tags); } - status_t status; - if (sampleRate == 0) { - status = AudioSystem::getOutputSamplingRateForAttr(&sampleRate, &mAttributes); - if (status != NO_ERROR) { - ALOGE("Could not get output sample rate for stream type %d; status %d", - mStreamType, status); - return status; - } - } - mSampleRate = sampleRate; - // these below should probably come from the audioFlinger too... if (format == AUDIO_FORMAT_DEFAULT) { format = AUDIO_FORMAT_PCM_16_BIT; @@ -373,6 +362,12 @@ status_t AudioTrack::set( // so no need to check for specific PCM formats here } + // sampling rate must be specified for direct outputs + if (sampleRate == 0 && (flags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) { + return BAD_VALUE; + } + mSampleRate = sampleRate; + // Make copy of input parameter offloadInfo so that in the future: // (a) createTrack_l doesn't need it as an input parameter // (b) we can support re-creation of offloaded tracks @@ -413,7 +408,7 @@ status_t AudioTrack::set( } // create the IAudioTrack - status = createTrack_l(); + status_t status = createTrack_l(); if (status != NO_ERROR) { if (mAudioTrackThread != 0) { @@ -680,15 +675,18 @@ status_t AudioTrack::setSampleRate(uint32_t rate) return INVALID_OPERATION; } + AutoMutex lock(mLock); + if (mOutput == AUDIO_IO_HANDLE_NONE) { + return NO_INIT; + } uint32_t afSamplingRate; - if (AudioSystem::getOutputSamplingRateForAttr(&afSamplingRate, &mAttributes) != NO_ERROR) { + if (AudioSystem::getSamplingRate(mOutput, &afSamplingRate) != NO_ERROR) { return NO_INIT; } if (rate == 0 || rate > afSamplingRate * AUDIO_RESAMPLER_DOWN_RATIO_MAX) { return BAD_VALUE; } - AutoMutex lock(mLock); mSampleRate = rate; mProxy->setSampleRate(rate); @@ -963,7 +961,9 @@ status_t AudioTrack::createTrack_l() ALOGE("getSamplingRate(output=%d) status %d", output, status); goto release; } - + if (mSampleRate == 0) { + mSampleRate = afSampleRate; + } // Client decides whether the track is TIMED (see below), but can only express a preference // for FAST. Server will perform additional tests. if ((mFlags & AUDIO_OUTPUT_FLAG_FAST) && !(( @@ -1123,7 +1123,7 @@ status_t AudioTrack::createTrack_l() } // invariant that mAudioTrack != 0 is true only after set() returns successfully if (mAudioTrack != 0) { - mAudioTrack->asBinder()->unlinkToDeath(mDeathNotifier, this); + IInterface::asBinder(mAudioTrack)->unlinkToDeath(mDeathNotifier, this); mDeathNotifier.clear(); } mAudioTrack = track; @@ -1226,7 +1226,7 @@ status_t AudioTrack::createTrack_l() mProxy->setMinimum(mNotificationFramesAct); mDeathNotifier = new DeathNotifier(this); - mAudioTrack->asBinder()->linkToDeath(mDeathNotifier, this); + IInterface::asBinder(mAudioTrack)->linkToDeath(mDeathNotifier, this); return NO_ERROR; } @@ -1828,7 +1828,7 @@ status_t AudioTrack::restoreTrack_l(const char *from) status_t result; // refresh the audio configuration cache in this process to make sure we get new - // output parameters in createTrack_l() + // output parameters and new IAudioFlinger in createTrack_l() AudioSystem::clearAudioConfigCache(); if (isOffloadedOrDirect_l()) { @@ -2149,6 +2149,11 @@ void AudioTrack::setStreamTypeFromAttributes(audio_attributes_t& aa) { mStreamType = AUDIO_STREAM_ALARM; break; } + audio_mode_t phoneState = AudioSystem::getPhoneState(); + if (phoneState == AUDIO_MODE_IN_CALL || phoneState == AUDIO_MODE_IN_COMMUNICATION) { + mStreamType = AUDIO_STREAM_VOICE_CALL; + break; + } } /// FALL THROUGH case AUDIO_USAGE_MEDIA: case AUDIO_USAGE_GAME: diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index 6099a05..8e3b633 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -119,7 +119,7 @@ public: // haveSharedBuffer if (sharedBuffer != 0) { data.writeInt32(true); - data.writeStrongBinder(sharedBuffer->asBinder()); + data.writeStrongBinder(IInterface::asBinder(sharedBuffer)); } else { data.writeInt32(false); } @@ -419,7 +419,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeStrongBinder(client->asBinder()); + data.writeStrongBinder(IInterface::asBinder(client)); remote()->transact(REGISTER_CLIENT, data, &reply); } @@ -716,7 +716,7 @@ public: data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); data.write(pDesc, sizeof(effect_descriptor_t)); - data.writeStrongBinder(client->asBinder()); + data.writeStrongBinder(IInterface::asBinder(client)); data.writeInt32(priority); data.writeInt32((int32_t) output); data.writeInt32(sessionId); @@ -939,7 +939,7 @@ status_t BnAudioFlinger::onTransact( reply->writeInt32(flags); reply->writeInt32(sessionId); reply->writeInt32(status); - reply->writeStrongBinder(track->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(track)); return NO_ERROR; } break; case OPEN_RECORD: { @@ -966,11 +966,9 @@ status_t BnAudioFlinger::onTransact( reply->writeInt32(sessionId); reply->writeInt64(notificationFrames); reply->writeInt32(status); - reply->writeStrongBinder(record != NULL ? record->asBinder() - : NULL); - reply->writeStrongBinder(cblk != NULL ? cblk->asBinder() : NULL); - reply->writeStrongBinder(buffers != NULL ? buffers->asBinder() - : NULL); + reply->writeStrongBinder(IInterface::asBinder(record)); + reply->writeStrongBinder(IInterface::asBinder(cblk)); + reply->writeStrongBinder(IInterface::asBinder(buffers)); return NO_ERROR; } break; case SAMPLE_RATE: { @@ -1256,7 +1254,7 @@ status_t BnAudioFlinger::onTransact( reply->writeInt32(status); reply->writeInt32(id); reply->writeInt32(enabled); - reply->writeStrongBinder(effect->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(effect)); reply->write(&desc, sizeof(effect_descriptor_t)); return NO_ERROR; } break; diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index 89178f1..9349662 100644 --- a/media/libmedia/IAudioPolicyService.cpp +++ b/media/libmedia/IAudioPolicyService.cpp @@ -572,7 +572,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); - data.writeStrongBinder(client->asBinder()); + data.writeStrongBinder(IInterface::asBinder(client)); remote()->transact(REGISTER_CLIENT, data, &reply); } diff --git a/media/libmedia/IAudioTrack.cpp b/media/libmedia/IAudioTrack.cpp index 265bb1b..df209fd 100644 --- a/media/libmedia/IAudioTrack.cpp +++ b/media/libmedia/IAudioTrack.cpp @@ -137,7 +137,7 @@ public: int64_t pts) { Parcel data, reply; data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); - data.writeStrongBinder(buffer->asBinder()); + data.writeStrongBinder(IInterface::asBinder(buffer)); data.writeInt64(pts); status_t status = remote()->transact(QUEUE_TIMED_BUFFER, data, &reply); @@ -207,7 +207,7 @@ status_t BnAudioTrack::onTransact( switch (code) { case GET_CBLK: { CHECK_INTERFACE(IAudioTrack, data, reply); - reply->writeStrongBinder(getCblk()->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(getCblk())); return NO_ERROR; } break; case START: { @@ -241,7 +241,7 @@ status_t BnAudioTrack::onTransact( status_t status = allocateTimedBuffer(data.readInt64(), &buffer); reply->writeInt32(status); if (status == NO_ERROR) { - reply->writeStrongBinder(buffer->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(buffer)); } return NO_ERROR; } break; diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp index 7e74de9..b08fa82 100644 --- a/media/libmedia/IDrm.cpp +++ b/media/libmedia/IDrm.cpp @@ -450,7 +450,7 @@ struct BpDrm : public BpInterface<IDrm> { virtual status_t setListener(const sp<IDrmClient>& listener) { Parcel data, reply; data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); - data.writeStrongBinder(listener->asBinder()); + data.writeStrongBinder(IInterface::asBinder(listener)); remote()->transact(SET_LISTENER, data, &reply); return reply.readInt32(); } diff --git a/media/libmedia/IEffect.cpp b/media/libmedia/IEffect.cpp index b94012a..c2fff78 100644 --- a/media/libmedia/IEffect.cpp +++ b/media/libmedia/IEffect.cpp @@ -190,7 +190,7 @@ status_t BnEffect::onTransact( case GET_CBLK: { CHECK_INTERFACE(IEffect, data, reply); - reply->writeStrongBinder(getCblk()->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(getCblk())); return NO_ERROR; } break; diff --git a/media/libmedia/IHDCP.cpp b/media/libmedia/IHDCP.cpp index 1cf987a..9122f75 100644 --- a/media/libmedia/IHDCP.cpp +++ b/media/libmedia/IHDCP.cpp @@ -65,7 +65,7 @@ struct BpHDCP : public BpInterface<IHDCP> { virtual status_t setObserver(const sp<IHDCPObserver> &observer) { Parcel data, reply; data.writeInterfaceToken(IHDCP::getInterfaceDescriptor()); - data.writeStrongBinder(observer->asBinder()); + data.writeStrongBinder(IInterface::asBinder(observer)); remote()->transact(HDCP_SET_OBSERVER, data, &reply); return reply.readInt32(); } diff --git a/media/libmedia/IMediaDeathNotifier.cpp b/media/libmedia/IMediaDeathNotifier.cpp index 10b4934..38e9ca0 100644 --- a/media/libmedia/IMediaDeathNotifier.cpp +++ b/media/libmedia/IMediaDeathNotifier.cpp @@ -104,7 +104,7 @@ IMediaDeathNotifier::DeathNotifier::~DeathNotifier() Mutex::Autolock _l(sServiceLock); sObitRecipients.clear(); if (sMediaPlayerService != 0) { - sMediaPlayerService->asBinder()->unlinkToDeath(this); + IInterface::asBinder(sMediaPlayerService)->unlinkToDeath(this); } } diff --git a/media/libmedia/IMediaLogService.cpp b/media/libmedia/IMediaLogService.cpp index 8a66c7c..a4af7b7 100644 --- a/media/libmedia/IMediaLogService.cpp +++ b/media/libmedia/IMediaLogService.cpp @@ -42,7 +42,7 @@ public: virtual void registerWriter(const sp<IMemory>& shared, size_t size, const char *name) { Parcel data, reply; data.writeInterfaceToken(IMediaLogService::getInterfaceDescriptor()); - data.writeStrongBinder(shared->asBinder()); + data.writeStrongBinder(IInterface::asBinder(shared)); data.writeInt64((int64_t) size); data.writeCString(name); status_t status = remote()->transact(REGISTER_WRITER, data, &reply); @@ -52,7 +52,7 @@ public: virtual void unregisterWriter(const sp<IMemory>& shared) { Parcel data, reply; data.writeInterfaceToken(IMediaLogService::getInterfaceDescriptor()); - data.writeStrongBinder(shared->asBinder()); + data.writeStrongBinder(IInterface::asBinder(shared)); status_t status = remote()->transact(UNREGISTER_WRITER, data, &reply); // FIXME ignores status } diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp index 38f717c..aa2665a 100644 --- a/media/libmedia/IMediaMetadataRetriever.cpp +++ b/media/libmedia/IMediaMetadataRetriever.cpp @@ -95,7 +95,7 @@ public: data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor()); data.writeInt32(httpService != NULL); if (httpService != NULL) { - data.writeStrongBinder(httpService->asBinder()); + data.writeStrongBinder(IInterface::asBinder(httpService)); } data.writeCString(srcUrl); @@ -246,7 +246,7 @@ status_t BnMediaMetadataRetriever::onTransact( sp<IMemory> bitmap = getFrameAtTime(timeUs, option); if (bitmap != 0) { // Don't send NULL across the binder interface reply->writeInt32(NO_ERROR); - reply->writeStrongBinder(bitmap->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(bitmap)); } else { reply->writeInt32(UNKNOWN_ERROR); } @@ -263,7 +263,7 @@ status_t BnMediaMetadataRetriever::onTransact( sp<IMemory> albumArt = extractAlbumArt(); if (albumArt != 0) { // Don't send NULL across the binder interface reply->writeInt32(NO_ERROR); - reply->writeStrongBinder(albumArt->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(albumArt)); } else { reply->writeInt32(UNKNOWN_ERROR); } diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp index d778d05..7f3e5cc 100644 --- a/media/libmedia/IMediaPlayer.cpp +++ b/media/libmedia/IMediaPlayer.cpp @@ -85,7 +85,7 @@ public: data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); data.writeInt32(httpService != NULL); if (httpService != NULL) { - data.writeStrongBinder(httpService->asBinder()); + data.writeStrongBinder(IInterface::asBinder(httpService)); } data.writeCString(url); if (headers == NULL) { @@ -115,7 +115,7 @@ public: status_t setDataSource(const sp<IStreamSource> &source) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - data.writeStrongBinder(source->asBinder()); + data.writeStrongBinder(IInterface::asBinder(source)); remote()->transact(SET_DATA_SOURCE_STREAM, data, &reply); return reply.readInt32(); } @@ -125,7 +125,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - sp<IBinder> b(bufferProducer->asBinder()); + sp<IBinder> b(IInterface::asBinder(bufferProducer)); data.writeStrongBinder(b); remote()->transact(SET_VIDEO_SURFACETEXTURE, data, &reply); return reply.readInt32(); @@ -323,7 +323,7 @@ public: status_t setNextPlayer(const sp<IMediaPlayer>& player) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - sp<IBinder> b(player->asBinder()); + sp<IBinder> b(IInterface::asBinder(player)); data.writeStrongBinder(b); remote()->transact(SET_NEXT_PLAYER, data, &reply); return reply.readInt32(); diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp index 2e02d17..a7568b9 100644 --- a/media/libmedia/IMediaPlayerService.cpp +++ b/media/libmedia/IMediaPlayerService.cpp @@ -73,7 +73,7 @@ public: const sp<IMediaPlayerClient>& client, int audioSessionId) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); - data.writeStrongBinder(client->asBinder()); + data.writeStrongBinder(IInterface::asBinder(client)); data.writeInt32(audioSessionId); remote()->transact(CREATE, data, &reply); @@ -101,10 +101,10 @@ public: data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); data.writeInt32(httpService != NULL); if (httpService != NULL) { - data.writeStrongBinder(httpService->asBinder()); + data.writeStrongBinder(IInterface::asBinder(httpService)); } data.writeCString(url); - data.writeStrongBinder(heap->asBinder()); + data.writeStrongBinder(IInterface::asBinder(heap)); status_t status = remote()->transact(DECODE_URL, data, &reply); if (status == NO_ERROR) { status = (status_t)reply.readInt32(); @@ -127,7 +127,7 @@ public: data.writeFileDescriptor(fd); data.writeInt64(offset); data.writeInt64(length); - data.writeStrongBinder(heap->asBinder()); + data.writeStrongBinder(IInterface::asBinder(heap)); status_t status = remote()->transact(DECODE_FD, data, &reply); if (status == NO_ERROR) { status = (status_t)reply.readInt32(); @@ -188,7 +188,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); - data.writeStrongBinder(client->asBinder()); + data.writeStrongBinder(IInterface::asBinder(client)); data.writeString8(iface); remote()->transact(LISTEN_FOR_REMOTE_DISPLAY, data, &reply); return interface_cast<IRemoteDisplay>(reply.readStrongBinder()); @@ -216,7 +216,7 @@ status_t BnMediaPlayerService::onTransact( interface_cast<IMediaPlayerClient>(data.readStrongBinder()); int audioSessionId = data.readInt32(); sp<IMediaPlayer> player = create(client, audioSessionId); - reply->writeStrongBinder(player->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(player)); return NO_ERROR; } break; case DECODE_URL: { @@ -273,38 +273,38 @@ status_t BnMediaPlayerService::onTransact( case CREATE_MEDIA_RECORDER: { CHECK_INTERFACE(IMediaPlayerService, data, reply); sp<IMediaRecorder> recorder = createMediaRecorder(); - reply->writeStrongBinder(recorder->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(recorder)); return NO_ERROR; } break; case CREATE_METADATA_RETRIEVER: { CHECK_INTERFACE(IMediaPlayerService, data, reply); sp<IMediaMetadataRetriever> retriever = createMetadataRetriever(); - reply->writeStrongBinder(retriever->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(retriever)); return NO_ERROR; } break; case GET_OMX: { CHECK_INTERFACE(IMediaPlayerService, data, reply); sp<IOMX> omx = getOMX(); - reply->writeStrongBinder(omx->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(omx)); return NO_ERROR; } break; case MAKE_CRYPTO: { CHECK_INTERFACE(IMediaPlayerService, data, reply); sp<ICrypto> crypto = makeCrypto(); - reply->writeStrongBinder(crypto->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(crypto)); return NO_ERROR; } break; case MAKE_DRM: { CHECK_INTERFACE(IMediaPlayerService, data, reply); sp<IDrm> drm = makeDrm(); - reply->writeStrongBinder(drm->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(drm)); return NO_ERROR; } break; case MAKE_HDCP: { CHECK_INTERFACE(IMediaPlayerService, data, reply); bool createEncryptionModule = data.readInt32(); sp<IHDCP> hdcp = makeHDCP(createEncryptionModule); - reply->writeStrongBinder(hdcp->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(hdcp)); return NO_ERROR; } break; case ADD_BATTERY_DATA: { @@ -324,13 +324,13 @@ status_t BnMediaPlayerService::onTransact( interface_cast<IRemoteDisplayClient>(data.readStrongBinder())); String8 iface(data.readString8()); sp<IRemoteDisplay> display(listenForRemoteDisplay(client, iface)); - reply->writeStrongBinder(display->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(display)); return NO_ERROR; } break; case GET_CODEC_LIST: { CHECK_INTERFACE(IMediaPlayerService, data, reply); sp<IMediaCodecList> mcl = getCodecList(); - reply->writeStrongBinder(mcl->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(mcl)); return NO_ERROR; } break; default: diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp index 95af006..a733b68 100644 --- a/media/libmedia/IMediaRecorder.cpp +++ b/media/libmedia/IMediaRecorder.cpp @@ -70,8 +70,8 @@ public: ALOGV("setCamera(%p,%p)", camera.get(), proxy.get()); Parcel data, reply; data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeStrongBinder(camera->asBinder()); - data.writeStrongBinder(proxy->asBinder()); + data.writeStrongBinder(IInterface::asBinder(camera)); + data.writeStrongBinder(IInterface::asBinder(proxy)); remote()->transact(SET_CAMERA, data, &reply); return reply.readInt32(); } @@ -94,7 +94,7 @@ public: ALOGV("setPreviewSurface(%p)", surface.get()); Parcel data, reply; data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeStrongBinder(surface->asBinder()); + data.writeStrongBinder(IInterface::asBinder(surface)); remote()->transact(SET_PREVIEW_SURFACE, data, &reply); return reply.readInt32(); } @@ -215,7 +215,7 @@ public: ALOGV("setListener(%p)", listener.get()); Parcel data, reply; data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); - data.writeStrongBinder(listener->asBinder()); + data.writeStrongBinder(IInterface::asBinder(listener)); remote()->transact(SET_LISTENER, data, &reply); return reply.readInt32(); } @@ -468,7 +468,7 @@ status_t BnMediaRecorder::onTransact( int returnedNull= (surfaceMediaSource == NULL) ? 1 : 0 ; reply->writeInt32(returnedNull); if (!returnedNull) { - reply->writeStrongBinder(surfaceMediaSource->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(surfaceMediaSource)); } return NO_ERROR; } break; diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index c583d32..e208df9 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -100,7 +100,7 @@ public: Parcel data, reply; data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); data.writeCString(name); - data.writeStrongBinder(observer->asBinder()); + data.writeStrongBinder(IInterface::asBinder(observer)); remote()->transact(ALLOCATE_NODE, data, &reply); status_t err = reply.readInt32(); @@ -248,7 +248,7 @@ public: data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); data.writeInt32((int32_t)node); data.writeInt32(port_index); - data.writeStrongBinder(params->asBinder()); + data.writeStrongBinder(IInterface::asBinder(params)); remote()->transact(USE_BUFFER, data, &reply); status_t err = reply.readInt32(); @@ -418,7 +418,7 @@ public: data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); data.writeInt32((int32_t)node); data.writeInt32(port_index); - data.writeStrongBinder(params->asBinder()); + data.writeStrongBinder(IInterface::asBinder(params)); remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply); status_t err = reply.readInt32(); @@ -775,7 +775,7 @@ status_t BnOMX::onTransact( reply->writeInt32(err); if (err == OK) { - reply->writeStrongBinder(bufferProducer->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); } return NO_ERROR; diff --git a/media/libmedia/IRemoteDisplayClient.cpp b/media/libmedia/IRemoteDisplayClient.cpp index 7190879..9d63bc9 100644 --- a/media/libmedia/IRemoteDisplayClient.cpp +++ b/media/libmedia/IRemoteDisplayClient.cpp @@ -42,7 +42,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(IRemoteDisplayClient::getInterfaceDescriptor()); - data.writeStrongBinder(bufferProducer->asBinder()); + data.writeStrongBinder(IInterface::asBinder(bufferProducer)); data.writeInt32(width); data.writeInt32(height); data.writeInt32(flags); diff --git a/media/libmedia/IStreamSource.cpp b/media/libmedia/IStreamSource.cpp index fe2cc61..d480aef 100644 --- a/media/libmedia/IStreamSource.cpp +++ b/media/libmedia/IStreamSource.cpp @@ -55,7 +55,7 @@ struct BpStreamSource : public BpInterface<IStreamSource> { virtual void setListener(const sp<IStreamListener> &listener) { Parcel data, reply; data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor()); - data.writeStrongBinder(listener->asBinder()); + data.writeStrongBinder(IInterface::asBinder(listener)); remote()->transact(SET_LISTENER, data, &reply); } @@ -64,7 +64,7 @@ struct BpStreamSource : public BpInterface<IStreamSource> { data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor()); data.writeInt64(static_cast<int64_t>(buffers.size())); for (size_t i = 0; i < buffers.size(); ++i) { - data.writeStrongBinder(buffers.itemAt(i)->asBinder()); + data.writeStrongBinder(IInterface::asBinder(buffers.itemAt(i))); } remote()->transact(SET_BUFFERS, data, &reply); } diff --git a/media/libmedia/SingleStateQueue.cpp b/media/libmedia/SingleStateQueue.cpp index 3503baa..c241184 100644 --- a/media/libmedia/SingleStateQueue.cpp +++ b/media/libmedia/SingleStateQueue.cpp @@ -16,7 +16,6 @@ #include <new> #include <cutils/atomic.h> -#include <cutils/atomic-inline.h> // for android_memory_barrier() #include <media/SingleStateQueue.h> namespace android { diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp index 39a239d..8e8a1ed 100644 --- a/media/libmedia/mediametadataretriever.cpp +++ b/media/libmedia/mediametadataretriever.cpp @@ -172,7 +172,7 @@ MediaMetadataRetriever::DeathNotifier::~DeathNotifier() { Mutex::Autolock lock(sServiceLock); if (sService != 0) { - sService->asBinder()->unlinkToDeath(this); + IInterface::asBinder(sService)->unlinkToDeath(this); } } diff --git a/media/libmediaplayerservice/Drm.cpp b/media/libmediaplayerservice/Drm.cpp index 2a8b2c6..73f1a2a 100644 --- a/media/libmediaplayerservice/Drm.cpp +++ b/media/libmediaplayerservice/Drm.cpp @@ -84,10 +84,10 @@ status_t Drm::setListener(const sp<IDrmClient>& listener) { Mutex::Autolock lock(mEventLock); if (mListener != NULL){ - mListener->asBinder()->unlinkToDeath(this); + IInterface::asBinder(mListener)->unlinkToDeath(this); } if (listener != NULL) { - listener->asBinder()->linkToDeath(this); + IInterface::asBinder(listener)->linkToDeath(this); } mListener = listener; return NO_ERROR; @@ -674,10 +674,14 @@ status_t Drm::signRSA(Vector<uint8_t> const &sessionId, void Drm::binderDied(const wp<IBinder> &the_late_who) { + mEventLock.lock(); + mListener.clear(); + mEventLock.unlock(); + + Mutex::Autolock autoLock(mLock); delete mPlugin; mPlugin = NULL; closeFactory(); - mListener.clear(); } } // namespace android diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index c120898..071b894 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -817,8 +817,7 @@ status_t MediaPlayerService::Client::setVideoSurfaceTexture( sp<MediaPlayerBase> p = getPlayer(); if (p == 0) return UNKNOWN_ERROR; - sp<IBinder> binder(bufferProducer == NULL ? NULL : - bufferProducer->asBinder()); + sp<IBinder> binder(IInterface::asBinder(bufferProducer)); if (mConnectedWindowBinder == binder) { return OK; } @@ -2125,6 +2124,7 @@ ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size) // immutable with respect to future writes. // // It is thus safe for another thread to read the AudioCache. + Mutex::Autolock lock(mLock); mCommandComplete = true; mSignal.signal(); } diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index 0e520a8..e619926 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -45,6 +45,10 @@ NuPlayer::GenericSource::GenericSource( bool uidValid, uid_t uid) : Source(notify), + mAudioTimeUs(0), + mAudioLastDequeueTimeUs(0), + mVideoTimeUs(0), + mVideoLastDequeueTimeUs(0), mFetchSubtitleDataGeneration(0), mFetchTimedTextDataGeneration(0), mDurationUs(0ll), @@ -62,8 +66,6 @@ NuPlayer::GenericSource::GenericSource( } void NuPlayer::GenericSource::resetDataSource() { - mAudioTimeUs = 0; - mVideoTimeUs = 0; mHTTPService.clear(); mHttpSource.clear(); mUri.clear(); @@ -644,17 +646,13 @@ void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) { track->mSource->start(); track->mIndex = trackIndex; - status_t avail; - if (!track->mPackets->hasBufferAvailable(&avail)) { - // sync from other source - TRESPASS(); - break; - } - int64_t timeUs, actualTimeUs; const bool formatChange = true; - sp<AMessage> latestMeta = track->mPackets->getLatestEnqueuedMeta(); - CHECK(latestMeta != NULL && latestMeta->findInt64("timeUs", &timeUs)); + if (trackType == MEDIA_TRACK_TYPE_AUDIO) { + timeUs = mAudioLastDequeueTimeUs; + } else { + timeUs = mVideoLastDequeueTimeUs; + } readBuffer(trackType, timeUs, &actualTimeUs, formatChange); readBuffer(counterpartType, -1, NULL, formatChange); ALOGV("timeUs %lld actualTimeUs %lld", timeUs, actualTimeUs); @@ -866,6 +864,11 @@ status_t NuPlayer::GenericSource::dequeueAccessUnit( int64_t timeUs; status_t eosResult; // ignored CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs)); + if (audio) { + mAudioLastDequeueTimeUs = timeUs; + } else { + mVideoLastDequeueTimeUs = timeUs; + } if (mSubtitleTrack.mSource != NULL && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) { @@ -996,11 +999,12 @@ ssize_t NuPlayer::GenericSource::doGetSelectedTrack(media_track_type type) const return -1; } -status_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select) { +status_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select, int64_t timeUs) { ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex); sp<AMessage> msg = new AMessage(kWhatSelectTrack, id()); msg->setInt32("trackIndex", trackIndex); msg->setInt32("select", select); + msg->setInt64("timeUs", timeUs); sp<AMessage> response; status_t err = msg->postAndAwaitResponse(&response); @@ -1013,11 +1017,13 @@ status_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select) { void NuPlayer::GenericSource::onSelectTrack(sp<AMessage> msg) { int32_t trackIndex, select; + int64_t timeUs; CHECK(msg->findInt32("trackIndex", &trackIndex)); CHECK(msg->findInt32("select", &select)); + CHECK(msg->findInt64("timeUs", &timeUs)); sp<AMessage> response = new AMessage; - status_t err = doSelectTrack(trackIndex, select); + status_t err = doSelectTrack(trackIndex, select, timeUs); response->setInt32("err", err); uint32_t replyID; @@ -1025,7 +1031,7 @@ void NuPlayer::GenericSource::onSelectTrack(sp<AMessage> msg) { response->postReply(replyID); } -status_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select) { +status_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select, int64_t timeUs) { if (trackIndex >= mSources.size()) { return BAD_INDEX; } @@ -1078,6 +1084,23 @@ status_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select) mFetchTimedTextDataGeneration++; } + status_t eosResult; // ignored + if (mSubtitleTrack.mSource != NULL + && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) { + sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id()); + msg->setInt64("timeUs", timeUs); + msg->setInt32("generation", mFetchSubtitleDataGeneration); + msg->post(); + } + + if (mTimedTextTrack.mSource != NULL + && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) { + sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, id()); + msg->setInt64("timeUs", timeUs); + msg->setInt32("generation", mFetchTimedTextDataGeneration); + msg->post(); + } + return OK; } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) { bool audio = !strncasecmp(mime, "audio/", 6); @@ -1132,10 +1155,12 @@ status_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs) { readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, &actualTimeUs); seekTimeUs = actualTimeUs; + mVideoLastDequeueTimeUs = seekTimeUs; } if (mAudioTrack.mSource != NULL) { readBuffer(MEDIA_TRACK_TYPE_AUDIO, seekTimeUs); + mAudioLastDequeueTimeUs = seekTimeUs; } setDrmPlaybackStatusIfNeeded(Playback::START, seekTimeUs / 1000); diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index f8601ea..f2528a9 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -67,7 +67,7 @@ struct NuPlayer::GenericSource : public NuPlayer::Source { virtual size_t getTrackCount() const; virtual sp<AMessage> getTrackInfo(size_t trackIndex) const; virtual ssize_t getSelectedTrack(media_track_type type) const; - virtual status_t selectTrack(size_t trackIndex, bool select); + virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs); virtual status_t seekTo(int64_t seekTimeUs); virtual status_t setBuffers(bool audio, Vector<MediaBuffer *> &buffers); @@ -106,8 +106,10 @@ private: Track mAudioTrack; int64_t mAudioTimeUs; + int64_t mAudioLastDequeueTimeUs; Track mVideoTrack; int64_t mVideoTimeUs; + int64_t mVideoLastDequeueTimeUs; Track mSubtitleTrack; Track mTimedTextTrack; @@ -162,7 +164,7 @@ private: ssize_t doGetSelectedTrack(media_track_type type) const; void onSelectTrack(sp<AMessage> msg); - status_t doSelectTrack(size_t trackIndex, bool select); + status_t doSelectTrack(size_t trackIndex, bool select, int64_t timeUs); void onSeek(sp<AMessage> msg); status_t doSeek(int64_t seekTimeUs); diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp index a003c81..a26ef9e 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp @@ -98,6 +98,10 @@ void NuPlayer::HTTPLiveSource::start() { } sp<AMessage> NuPlayer::HTTPLiveSource::getFormat(bool audio) { + if (mLiveSession == NULL) { + return NULL; + } + sp<AMessage> format; status_t err = mLiveSession->getStreamFormat( audio ? LiveSession::STREAMTYPE_AUDIO @@ -135,7 +139,15 @@ sp<AMessage> NuPlayer::HTTPLiveSource::getTrackInfo(size_t trackIndex) const { return mLiveSession->getTrackInfo(trackIndex); } -status_t NuPlayer::HTTPLiveSource::selectTrack(size_t trackIndex, bool select) { +ssize_t NuPlayer::HTTPLiveSource::getSelectedTrack(media_track_type type) const { + if (mLiveSession == NULL) { + return -1; + } else { + return mLiveSession->getSelectedTrack(type); + } +} + +status_t NuPlayer::HTTPLiveSource::selectTrack(size_t trackIndex, bool select, int64_t /*timeUs*/) { status_t err = mLiveSession->selectTrack(trackIndex, select); if (err == OK) { diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h index 6b5f6af..bbb8981 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h @@ -42,7 +42,8 @@ struct NuPlayer::HTTPLiveSource : public NuPlayer::Source { virtual status_t getDuration(int64_t *durationUs); virtual size_t getTrackCount() const; virtual sp<AMessage> getTrackInfo(size_t trackIndex) const; - virtual status_t selectTrack(size_t trackIndex, bool select); + virtual ssize_t getSelectedTrack(media_track_type /* type */) const; + virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs); virtual status_t seekTo(int64_t seekTimeUs); protected: diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 47bd989..5800757 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -165,8 +165,6 @@ NuPlayer::NuPlayer() mTimeDiscontinuityPending(false), mFlushingAudio(NONE), mFlushingVideo(NONE), - mSkipRenderingAudioUntilMediaTimeUs(-1ll), - mSkipRenderingVideoUntilMediaTimeUs(-1ll), mNumFramesTotal(0ll), mNumFramesDropped(0ll), mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW), @@ -455,8 +453,10 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { size_t trackIndex; int32_t select; + int64_t timeUs; CHECK(msg->findSize("trackIndex", &trackIndex)); CHECK(msg->findInt32("select", &select)); + CHECK(msg->findInt64("timeUs", &timeUs)); status_t err = INVALID_OPERATION; @@ -470,7 +470,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { } if (trackIndex < inbandTracks) { - err = mSource->selectTrack(trackIndex, select); + err = mSource->selectTrack(trackIndex, select, timeUs); if (!select && err == OK) { int32_t type; @@ -701,19 +701,14 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { handleFlushComplete(audio, true /* isDecoder */); finishFlushIfPossible(); - } else if (what == Decoder::kWhatOutputFormatChanged) { + } else if (what == Decoder::kWhatVideoSizeChanged) { sp<AMessage> format; CHECK(msg->findMessage("format", &format)); - if (audio) { - openAudioSink(format, false /*offloadOnly*/); - } else { - // video - sp<AMessage> inputFormat = - mSource->getFormat(false /* audio */); + sp<AMessage> inputFormat = + mSource->getFormat(false /* audio */); - updateVideoSize(inputFormat, format); - } + updateVideoSize(inputFormat, format); } else if (what == Decoder::kWhatShutdownCompleted) { ALOGV("%s shutdown completed", audio ? "audio" : "video"); if (audio) { @@ -779,7 +774,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { break; // Finish anyways. } notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); - } else if (what == Decoder::kWhatDrainThisBuffer) { + } else if (what == Decoder::kWhatRenderBufferTime) { renderBuffer(audio, msg); } else { ALOGV("Unhandled decoder notification %d '%c%c%c%c'.", @@ -967,8 +962,6 @@ void NuPlayer::onStart() { mOffloadAudio = false; mAudioEOS = false; mVideoEOS = false; - mSkipRenderingAudioUntilMediaTimeUs = -1; - mSkipRenderingVideoUntilMediaTimeUs = -1; mNumFramesTotal = 0; mNumFramesDropped = 0; mStarted = true; @@ -1024,6 +1017,13 @@ void NuPlayer::onStart() { mRenderer->setVideoFrameRate(rate); } + if (mVideoDecoder != NULL) { + mVideoDecoder->setRenderer(mRenderer); + } + if (mAudioDecoder != NULL) { + mAudioDecoder->setRenderer(mRenderer); + } + postScanSources(); } @@ -1182,16 +1182,16 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { notify->setInt32("generation", mAudioDecoderGeneration); if (mOffloadAudio) { - *decoder = new DecoderPassThrough(notify); + *decoder = new DecoderPassThrough(notify, mSource, mRenderer); } else { - *decoder = new Decoder(notify); + *decoder = new Decoder(notify, mSource, mRenderer); } } else { sp<AMessage> notify = new AMessage(kWhatVideoNotify, id()); ++mVideoDecoderGeneration; notify->setInt32("generation", mVideoDecoderGeneration); - *decoder = new Decoder(notify, mNativeWindow); + *decoder = new Decoder(notify, mSource, mRenderer, mNativeWindow); } (*decoder)->init(); (*decoder)->configure(format); @@ -1280,33 +1280,6 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { ALOGI("%s discontinuity (formatChange=%d, time=%d)", audio ? "audio" : "video", formatChange, timeChange); - if (audio) { - mSkipRenderingAudioUntilMediaTimeUs = -1; - } else { - mSkipRenderingVideoUntilMediaTimeUs = -1; - } - - if (timeChange) { - sp<AMessage> extra; - if (accessUnit->meta()->findMessage("extra", &extra) - && extra != NULL) { - int64_t resumeAtMediaTimeUs; - if (extra->findInt64( - "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) { - ALOGI("suppressing rendering of %s until %lld us", - audio ? "audio" : "video", resumeAtMediaTimeUs); - - if (audio) { - mSkipRenderingAudioUntilMediaTimeUs = - resumeAtMediaTimeUs; - } else { - mSkipRenderingVideoUntilMediaTimeUs = - resumeAtMediaTimeUs; - } - } - } - } - mTimeDiscontinuityPending = mTimeDiscontinuityPending || timeChange; @@ -1447,9 +1420,6 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) { // ALOGV("renderBuffer %s", audio ? "audio" : "video"); - sp<AMessage> reply; - CHECK(msg->findMessage("reply", &reply)); - if ((audio && mFlushingAudio != NONE) || (!audio && mFlushingVideo != NONE)) { // We're currently attempting to flush the decoder, in order @@ -1460,40 +1430,15 @@ void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) { ALOGV("we're still flushing the %s decoder, sending its output buffer" " right back.", audio ? "audio" : "video"); - reply->post(); return; } - sp<ABuffer> buffer; - CHECK(msg->findBuffer("buffer", &buffer)); - int64_t mediaTimeUs; - CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs)); - - int64_t &skipUntilMediaTimeUs = - audio - ? mSkipRenderingAudioUntilMediaTimeUs - : mSkipRenderingVideoUntilMediaTimeUs; - - if (skipUntilMediaTimeUs >= 0) { - - if (mediaTimeUs < skipUntilMediaTimeUs) { - ALOGV("dropping %s buffer at time %lld as requested.", - audio ? "audio" : "video", - mediaTimeUs); - - reply->post(); - return; - } - - skipUntilMediaTimeUs = -1; - } + CHECK(msg->findInt64("timeUs", &mediaTimeUs)); if (!audio && mCCDecoder->isSelected()) { mCCDecoder->display(mediaTimeUs); } - - mRenderer->queueBuffer(audio, buffer, reply); } void NuPlayer::updateVideoSize( @@ -1593,7 +1538,6 @@ void NuPlayer::flushDecoder( mScanSourcesPending = false; decoder->signalFlush(newFormat); - mRenderer->flush(audio); FlushStatus newStatus = needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER; @@ -1682,10 +1626,11 @@ status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const { return err; } -status_t NuPlayer::selectTrack(size_t trackIndex, bool select) { +status_t NuPlayer::selectTrack(size_t trackIndex, bool select, int64_t timeUs) { sp<AMessage> msg = new AMessage(kWhatSelectTrack, id()); msg->setSize("trackIndex", trackIndex); msg->setInt32("select", select); + msg->setInt64("timeUs", timeUs); sp<AMessage> response; status_t err = msg->postAndAwaitResponse(&response); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index 121f7dd..524f197 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -26,7 +26,7 @@ namespace android { struct ABuffer; struct AMessage; -struct MetaData; +class MetaData; struct NuPlayerDriver; struct NuPlayer : public AHandler { @@ -65,7 +65,7 @@ struct NuPlayer : public AHandler { status_t setVideoScalingMode(int32_t mode); status_t getTrackInfo(Parcel* reply) const; status_t getSelectedTrack(int32_t type, Parcel* reply) const; - status_t selectTrack(size_t trackIndex, bool select); + status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs); status_t getCurrentPosition(int64_t *mediaUs); void getStats(int64_t *mNumFramesTotal, int64_t *mNumFramesDropped); @@ -181,9 +181,6 @@ private: FlushStatus mFlushingAudio; FlushStatus mFlushingVideo; - int64_t mSkipRenderingAudioUntilMediaTimeUs; - int64_t mSkipRenderingVideoUntilMediaTimeUs; - int64_t mNumFramesTotal, mNumFramesDropped; int32_t mVideoScalingMode; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index 27f6131..e695c43 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -21,6 +21,9 @@ #include "NuPlayerDecoder.h" +#include "NuPlayerRenderer.h" +#include "NuPlayerSource.h" + #include <media/ICrypto.h> #include <media/stagefright/foundation/ABitReader.h> #include <media/stagefright/foundation/ABuffer.h> @@ -35,9 +38,14 @@ namespace android { NuPlayer::Decoder::Decoder( const sp<AMessage> ¬ify, + const sp<Source> &source, + const sp<Renderer> &renderer, const sp<NativeWindowWrapper> &nativeWindow) : mNotify(notify), mNativeWindow(nativeWindow), + mSource(source), + mRenderer(renderer), + mSkipRenderingUntilMediaTimeUs(-1ll), mBufferGeneration(0), mPaused(true), mComponentName("decoder") { @@ -169,7 +177,9 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { mInputBuffers.size(), mOutputBuffers.size()); - requestCodecNotification(); + if (mRenderer != NULL) { + requestCodecNotification(); + } mPaused = false; } @@ -191,6 +201,7 @@ void NuPlayer::Decoder::releaseAndResetMediaBuffers() { } mPendingInputMessages.clear(); + mSkipRenderingUntilMediaTimeUs = -1; } void NuPlayer::Decoder::requestCodecNotification() { @@ -217,6 +228,12 @@ void NuPlayer::Decoder::configure(const sp<AMessage> &format) { msg->post(); } +void NuPlayer::Decoder::setRenderer(const sp<Renderer> &renderer) { + sp<AMessage> msg = new AMessage(kWhatSetRenderer, id()); + msg->setObject("renderer", renderer); + msg->post(); +} + void NuPlayer::Decoder::signalUpdateFormat(const sp<AMessage> &format) { sp<AMessage> msg = new AMessage(kWhatUpdateFormat, id()); msg->setMessage("format", format); @@ -342,8 +359,6 @@ bool android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) { } } - - if (buffer == NULL /* includes !hasBuffer */) { int32_t streamErr = ERROR_END_OF_STREAM; CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); @@ -375,6 +390,17 @@ bool android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) { handleError(streamErr); } } else { + sp<AMessage> extra; + if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) { + int64_t resumeAtMediaTimeUs; + if (extra->findInt64( + "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) { + ALOGI("[%s] suppressing rendering until %lld us", + mComponentName.c_str(), (long long)resumeAtMediaTimeUs); + mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs; + } + } + int64_t timeUs = 0; uint32_t flags = 0; CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); @@ -454,10 +480,27 @@ bool NuPlayer::Decoder::handleAnOutputBuffer() { return false; } - sp<AMessage> notify = mNotify->dup(); - notify->setInt32("what", kWhatOutputFormatChanged); - notify->setMessage("format", format); - notify->post(); + if (isVideo()) { + sp<AMessage> notify = mNotify->dup(); + notify->setInt32("what", kWhatVideoSizeChanged); + notify->setMessage("format", format); + notify->post(); + } else if (mRenderer != NULL) { + uint32_t flags; + int64_t durationUs; + bool hasVideo = (mSource->getFormat(false /* audio */) != NULL); + if (!hasVideo && + mSource->getDuration(&durationUs) == OK && + durationUs + > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) { + flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; + } else { + flags = AUDIO_OUTPUT_FLAG_NONE; + } + + mRenderer->openAudioSink( + format, false /* offloadOnly */, hasVideo, flags); + } return true; } else if (res == INFO_DISCONTINUITY) { // nothing to do @@ -485,21 +528,26 @@ bool NuPlayer::Decoder::handleAnOutputBuffer() { reply->setSize("buffer-ix", bufferIx); reply->setInt32("generation", mBufferGeneration); - sp<AMessage> notify = mNotify->dup(); - notify->setInt32("what", kWhatDrainThisBuffer); - notify->setBuffer("buffer", buffer); - notify->setMessage("reply", reply); - notify->post(); + if (mSkipRenderingUntilMediaTimeUs >= 0) { + if (timeUs < mSkipRenderingUntilMediaTimeUs) { + ALOGV("[%s] dropping buffer at time %lld as requested.", + mComponentName.c_str(), (long long)timeUs); - // FIXME: This should be handled after rendering is complete, - // but Renderer needs it now - if (flags & MediaCodec::BUFFER_FLAG_EOS) { - ALOGV("queueing eos [%s]", mComponentName.c_str()); - sp<AMessage> notify = mNotify->dup(); - notify->setInt32("what", kWhatEOS); - notify->setInt32("err", ERROR_END_OF_STREAM); - notify->post(); + reply->post(); + return true; + } + + mSkipRenderingUntilMediaTimeUs = -1; + } + + if (mRenderer != NULL) { + // send the buffer to renderer. + mRenderer->queueBuffer(!isVideo(), buffer, reply); + if (flags & MediaCodec::BUFFER_FLAG_EOS) { + mRenderer->queueEOS(!isVideo(), ERROR_END_OF_STREAM); + } } + return true; } @@ -508,6 +556,17 @@ void NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) { int32_t render; size_t bufferIx; CHECK(msg->findSize("buffer-ix", &bufferIx)); + + if (isVideo()) { + int64_t timeUs; + sp<ABuffer> buffer = mOutputBuffers[bufferIx]; + buffer->meta()->findInt64("timeUs", &timeUs); + sp<AMessage> notify = mNotify->dup(); + notify->setInt32("what", kWhatRenderBufferTime); + notify->setInt64("timeUs", timeUs); + notify->post(); + } + if (msg->findInt32("render", &render) && render) { int64_t timestampNs; CHECK(msg->findInt64("timestampNs", ×tampNs)); @@ -523,6 +582,10 @@ void NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) { } void NuPlayer::Decoder::onFlush() { + if (mRenderer != NULL) { + mRenderer->flush(!isVideo()); + } + status_t err = OK; if (mCodec != NULL) { err = mCodec->flush(); @@ -594,6 +657,18 @@ void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { break; } + case kWhatSetRenderer: + { + bool hadNoRenderer = (mRenderer == NULL); + sp<RefBase> obj; + CHECK(msg->findObject("renderer", &obj)); + mRenderer = static_cast<Renderer *>(obj.get()); + if (hadNoRenderer && mRenderer != NULL) { + requestCodecNotification(); + } + break; + } + case kWhatUpdateFormat: { sp<AMessage> format; @@ -772,6 +847,10 @@ bool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetF return seamless; } +bool NuPlayer::Decoder::isVideo() { + return mNativeWindow != NULL; +} + struct CCData { CCData(uint8_t type, uint8_t data1, uint8_t data2) : mType(type), mData1(data1), mData2(data2) { diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h index dba3eee..c6ceb4e 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h @@ -30,11 +30,15 @@ struct MediaBuffer; struct NuPlayer::Decoder : public AHandler { Decoder(const sp<AMessage> ¬ify, + const sp<Source> &source, + const sp<Renderer> &renderer = NULL, const sp<NativeWindowWrapper> &nativeWindow = NULL); virtual void configure(const sp<AMessage> &format); virtual void init(); + virtual void setRenderer(const sp<Renderer> &renderer); + status_t getInputBuffers(Vector<sp<ABuffer> > *dstBuffers) const; virtual void signalFlush(const sp<AMessage> &format = NULL); virtual void signalUpdateFormat(const sp<AMessage> &format); @@ -45,8 +49,8 @@ struct NuPlayer::Decoder : public AHandler { enum { kWhatFillThisBuffer = 'flTB', - kWhatDrainThisBuffer = 'drTB', - kWhatOutputFormatChanged = 'fmtC', + kWhatRenderBufferTime = 'rnBT', + kWhatVideoSizeChanged = 'viSC', kWhatFlushCompleted = 'flsC', kWhatShutdownCompleted = 'shDC', kWhatEOS = 'eos ', @@ -59,10 +63,10 @@ protected: virtual void onMessageReceived(const sp<AMessage> &msg); -private: enum { kWhatCodecNotify = 'cdcN', kWhatConfigure = 'conf', + kWhatSetRenderer = 'setR', kWhatGetInputBuffers = 'gInB', kWhatInputBufferFilled = 'inpF', kWhatRenderBuffer = 'rndr', @@ -71,9 +75,13 @@ private: kWhatUpdateFormat = 'uFmt', }; +private: sp<AMessage> mNotify; sp<NativeWindowWrapper> mNativeWindow; + sp<Source> mSource; + sp<Renderer> mRenderer; + sp<AMessage> mInputFormat; sp<AMessage> mOutputFormat; sp<MediaCodec> mCodec; @@ -89,6 +97,8 @@ private: Vector<bool> mInputBufferIsDequeued; Vector<MediaBuffer *> mMediaBuffers; + int64_t mSkipRenderingUntilMediaTimeUs; + void handleError(int32_t err); bool handleAnInputBuffer(); bool handleAnOutputBuffer(); @@ -110,6 +120,7 @@ private: bool supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const; void rememberCodecSpecificData(const sp<AMessage> &format); + bool isVideo(); DISALLOW_EVIL_CONSTRUCTORS(Decoder); }; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp index f7aacdd..d2721ed 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp @@ -21,6 +21,9 @@ #include "NuPlayerDecoderPassThrough.h" +#include "NuPlayerRenderer.h" +#include "NuPlayerSource.h" + #include <media/ICrypto.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> @@ -36,15 +39,21 @@ static const size_t kMaxCachedBytes = 200000; static const size_t kMaxPendingBuffers = 1 + (kMaxCachedBytes / NuPlayer::kAggregateBufferSizeBytes); NuPlayer::DecoderPassThrough::DecoderPassThrough( - const sp<AMessage> ¬ify) - : Decoder(notify), + const sp<AMessage> ¬ify, + const sp<Source> &source, + const sp<Renderer> &renderer) + : Decoder(notify, source), mNotify(notify), + mSource(source), + mRenderer(renderer), + mSkipRenderingUntilMediaTimeUs(-1ll), mBufferGeneration(0), mReachedEOS(true), mPendingBuffersToFill(0), mPendingBuffersToDrain(0), mCachedBytes(0), mComponentName("pass through decoder") { + ALOGW_IF(renderer == NULL, "expect a non-NULL renderer"); mDecoderLooper = new ALooper; mDecoderLooper->setName("NuPlayerDecoderPassThrough"); mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO); @@ -90,10 +99,17 @@ void NuPlayer::DecoderPassThrough::onConfigure(const sp<AMessage> &format) { requestMaxBuffers(); - sp<AMessage> notify = mNotify->dup(); - notify->setInt32("what", kWhatOutputFormatChanged); - notify->setMessage("format", format); - notify->post(); + uint32_t flags; + int64_t durationUs; + if (mSource->getDuration(&durationUs) == OK && + durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) { + flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; + } else { + flags = AUDIO_OUTPUT_FLAG_NONE; + } + + mRenderer->openAudioSink( + format, true /* offloadOnly */, false /* hasVideo */, flags); } bool NuPlayer::DecoderPassThrough::isStaleReply(const sp<AMessage> &msg) { @@ -138,25 +154,52 @@ void android::NuPlayer::DecoderPassThrough::onInputBufferFilled( msg->findBuffer("buffer", &buffer); if (buffer == NULL) { mReachedEOS = true; - - sp<AMessage> notify = mNotify->dup(); - notify->setInt32("what", kWhatEOS); - notify->setInt32("err", ERROR_END_OF_STREAM); - notify->post(); + if (mRenderer != NULL) { + mRenderer->queueEOS(true /* audio */, ERROR_END_OF_STREAM); + } return; } - mCachedBytes += buffer->size(); + sp<AMessage> extra; + if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) { + int64_t resumeAtMediaTimeUs; + if (extra->findInt64( + "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) { + ALOGI("[%s] suppressing rendering until %lld us", + mComponentName.c_str(), (long long)resumeAtMediaTimeUs); + mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs; + } + } + + int32_t bufferSize = buffer->size(); + mCachedBytes += bufferSize; + + if (mSkipRenderingUntilMediaTimeUs >= 0) { + int64_t timeUs = 0; + CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); + + if (timeUs < mSkipRenderingUntilMediaTimeUs) { + ALOGV("[%s] dropping buffer at time %lld as requested.", + mComponentName.c_str(), (long long)timeUs); + + onBufferConsumed(bufferSize); + return; + } + + mSkipRenderingUntilMediaTimeUs = -1; + } + + if (mRenderer == NULL) { + onBufferConsumed(bufferSize); + return; + } sp<AMessage> reply = new AMessage(kWhatBufferConsumed, id()); reply->setInt32("generation", mBufferGeneration); - reply->setInt32("size", buffer->size()); + reply->setInt32("size", bufferSize); + + mRenderer->queueBuffer(true /* audio */, buffer, reply); - sp<AMessage> notify = mNotify->dup(); - notify->setInt32("what", kWhatDrainThisBuffer); - notify->setBuffer("buffer", buffer); - notify->setMessage("reply", reply); - notify->post(); ++mPendingBuffersToDrain; ALOGV("onInputBufferFilled: #ToFill = %zu, #ToDrain = %zu, cachedBytes = %zu", mPendingBuffersToFill, mPendingBuffersToDrain, mCachedBytes); @@ -172,6 +215,11 @@ void NuPlayer::DecoderPassThrough::onBufferConsumed(int32_t size) { void NuPlayer::DecoderPassThrough::onFlush() { ++mBufferGeneration; + mSkipRenderingUntilMediaTimeUs = -1; + + if (mRenderer != NULL) { + mRenderer->flush(true /* audio */); + } sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatFlushCompleted); @@ -192,6 +240,7 @@ void NuPlayer::DecoderPassThrough::requestMaxBuffers() { void NuPlayer::DecoderPassThrough::onShutdown() { ++mBufferGeneration; + mSkipRenderingUntilMediaTimeUs = -1; sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", kWhatShutdownCompleted); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h index fb20257..7742d30 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h @@ -25,7 +25,9 @@ namespace android { struct NuPlayer::DecoderPassThrough : public Decoder { - DecoderPassThrough(const sp<AMessage> ¬ify); + DecoderPassThrough(const sp<AMessage> ¬ify, + const sp<Source> &source, + const sp<Renderer> &renderer); virtual void configure(const sp<AMessage> &format); virtual void init(); @@ -45,16 +47,15 @@ protected: private: enum { kWhatRequestABuffer = 'reqB', - kWhatConfigure = 'conf', - kWhatInputBufferFilled = 'inpF', kWhatBufferConsumed = 'bufC', - kWhatFlush = 'flus', - kWhatShutdown = 'shuD', }; sp<AMessage> mNotify; sp<ALooper> mDecoderLooper; + sp<Source> mSource; + sp<Renderer> mRenderer; + /** Returns true if a buffer was requested. * Returns false if at EOS or cache already full. */ @@ -68,6 +69,8 @@ private: void requestMaxBuffers(); void onShutdown(); + int64_t mSkipRenderingUntilMediaTimeUs; + int32_t mBufferGeneration; bool mReachedEOS; // TODO mPendingBuffersToFill and mPendingBuffersToDrain are only for diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp index 2b1c559..de16ec9 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp @@ -488,13 +488,16 @@ status_t NuPlayerDriver::invoke(const Parcel &request, Parcel *reply) { case INVOKE_ID_SELECT_TRACK: { int trackIndex = request.readInt32(); - return mPlayer->selectTrack(trackIndex, true /* select */); + int msec = 0; + // getCurrentPosition should always return OK + getCurrentPosition(&msec); + return mPlayer->selectTrack(trackIndex, true /* select */, msec * 1000ll); } case INVOKE_ID_UNSELECT_TRACK: { int trackIndex = request.readInt32(); - return mPlayer->selectTrack(trackIndex, false /* select */); + return mPlayer->selectTrack(trackIndex, false /* select */, 0xdeadbeef /* not used */); } case INVOKE_ID_GET_SELECTED_TRACK: @@ -633,9 +636,24 @@ void NuPlayerDriver::notifyListener_l( case MEDIA_PLAYBACK_COMPLETE: { if (mState != STATE_RESET_IN_PROGRESS) { + if (mAutoLoop) { + audio_stream_type_t streamType = AUDIO_STREAM_MUSIC; + if (mAudioSink != NULL) { + streamType = mAudioSink->getAudioStreamType(); + } + if (streamType == AUDIO_STREAM_NOTIFICATION) { + ALOGW("disabling auto-loop for notification"); + mAutoLoop = false; + } + } if (mLooping || (mAutoLoop && (mAudioSink == NULL || mAudioSink->realtime()))) { mPlayer->seekToAsync(0); + if (mAudioSink != NULL) { + // The renderer has stopped the sink at the end in order to play out + // the last little bit of audio. If we're looping, we need to restart it. + mAudioSink->start(); + } break; } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 5d9001c..73bc829 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -20,8 +20,6 @@ #include "NuPlayerRenderer.h" -#include <cutils/properties.h> - #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> @@ -43,16 +41,6 @@ static const int64_t kOffloadPauseMaxUs = 10000000ll; // static const int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll; -static bool sFrameAccurateAVsync = false; - -static void readProperties() { - char value[PROPERTY_VALUE_MAX]; - if (property_get("persist.sys.media.avsync", value, NULL)) { - sFrameAccurateAVsync = - !strcmp("1", value) || !strcasecmp("true", value); - } -} - NuPlayer::Renderer::Renderer( const sp<MediaPlayerBase::AudioSink> &sink, const sp<AMessage> ¬ify, @@ -87,7 +75,6 @@ NuPlayer::Renderer::Renderer( mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER), mTotalBuffersQueued(0), mLastAudioBufferDrained(0) { - readProperties(); } NuPlayer::Renderer::~Renderer() { @@ -629,6 +616,10 @@ bool NuPlayer::Renderer::onDrainAudioQueue() { mAudioQueue.erase(mAudioQueue.begin()); entry = NULL; + // Need to stop the track here, because that will play out the last + // little bit at the end of the file. Otherwise short files won't play. + mAudioSink->stop(); + mNumFramesWritten = 0; return false; } @@ -792,11 +783,6 @@ void NuPlayer::Renderer::postDrainVideoQueue() { ALOGW_IF(delayUs > 500000, "unusually high delayUs: %" PRId64, delayUs); // post 2 display refreshes before rendering is due - // FIXME currently this increases power consumption, so unless frame-accurate - // AV sync is requested, post closer to required render time (at 0.63 vsyncs) - if (!sFrameAccurateAVsync) { - twoVsyncsUs >>= 4; - } msg->post(delayUs > twoVsyncsUs ? delayUs - twoVsyncsUs : 0); mDrainVideoQueuePending = true; @@ -1174,8 +1160,6 @@ void NuPlayer::Renderer::onPause() { } void NuPlayer::Renderer::onResume() { - readProperties(); - if (!mPaused) { return; } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h index 2f06c31..e92cd36 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h @@ -28,7 +28,6 @@ namespace android { struct ABuffer; -struct MetaData; struct MediaBuffer; struct NuPlayer::Source : public AHandler { @@ -97,7 +96,7 @@ struct NuPlayer::Source : public AHandler { return INVALID_OPERATION; } - virtual status_t selectTrack(size_t /* trackIndex */, bool /* select */) { + virtual status_t selectTrack(size_t /* trackIndex */, bool /* select */, int64_t /* timeUs*/) { return INVALID_OPERATION; } diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 4c8a199..26284e9 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -4419,7 +4419,7 @@ void ACodec::UninitializedState::stateEntered() { ALOGV("Now uninitialized"); if (mDeathNotifier != NULL) { - mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier); + IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier); mDeathNotifier.clear(); } @@ -4512,7 +4512,7 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id()); mDeathNotifier = new DeathNotifier(notify); - if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) { + if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) { // This was a local binder, if it dies so do we, we won't care // about any notifications in the afterlife. mDeathNotifier.clear(); diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index 6a56729..007c090 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -878,6 +878,16 @@ void AwesomePlayer::onStreamDone() { return; } + if (mFlags & AUTO_LOOPING) { + audio_stream_type_t streamType = AUDIO_STREAM_MUSIC; + if (mAudioSink != NULL) { + streamType = mAudioSink->getAudioStreamType(); + } + if (streamType == AUDIO_STREAM_NOTIFICATION) { + ALOGW("disabling auto-loop for notification"); + modifyFlags(AUTO_LOOPING, CLEAR); + } + } if ((mFlags & LOOPING) || ((mFlags & AUTO_LOOPING) && (mAudioSink == NULL || mAudioSink->realtime()))) { diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index c3a940a..ad12bdd 100644 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -219,7 +219,7 @@ status_t CameraSource::isCameraAvailable( mCameraFlags |= FLAGS_HOT_CAMERA; mDeathNotifier = new DeathNotifier(); // isBinderAlive needs linkToDeath to work. - mCameraRecordingProxy->asBinder()->linkToDeath(mDeathNotifier); + IInterface::asBinder(mCameraRecordingProxy)->linkToDeath(mDeathNotifier); } mCamera->lock(); @@ -702,7 +702,7 @@ void CameraSource::releaseCamera() { { Mutex::Autolock autoLock(mLock); if (mCameraRecordingProxy != 0) { - mCameraRecordingProxy->asBinder()->unlinkToDeath(mDeathNotifier); + IInterface::asBinder(mCameraRecordingProxy)->unlinkToDeath(mDeathNotifier); mCameraRecordingProxy.clear(); } mCameraFlags = 0; @@ -825,7 +825,7 @@ status_t CameraSource::read( mFrameAvailableCondition.waitRelative(mLock, mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) { if (mCameraRecordingProxy != 0 && - !mCameraRecordingProxy->asBinder()->isBinderAlive()) { + !IInterface::asBinder(mCameraRecordingProxy)->isBinderAlive()) { ALOGW("camera recording proxy is gone"); return ERROR_END_OF_STREAM; } diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index 673d375..3622eb7 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -1359,9 +1359,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); - if (!(mFlags & kFlagIsComponentAllocated) && mState != INITIALIZED + if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1 + && mState != INITIALIZED && mState != CONFIGURED && !isExecuting()) { - // We may be in "UNINITIALIZED" state already and + // 1) Permit release to shut down the component if allocated. + // + // 2) We may be in "UNINITIALIZED" state already and // also shutdown the encoder/decoder without the // client being aware of this if media server died while // we were being stopped. The client would assume that diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp index 0fecda8..c26e909 100644 --- a/media/libstagefright/MediaCodecSource.cpp +++ b/media/libstagefright/MediaCodecSource.cpp @@ -422,19 +422,11 @@ status_t MediaCodecSource::initEncoder() { } } - err = mEncoder->start(); - - if (err != OK) { - return err; - } - - err = mEncoder->getInputBuffers(&mEncoderInputBuffers); + mEncoderActivityNotify = new AMessage( + kWhatEncoderActivity, mReflector->id()); + mEncoder->setCallback(mEncoderActivityNotify); - if (err != OK) { - return err; - } - - err = mEncoder->getOutputBuffers(&mEncoderOutputBuffers); + err = mEncoder->start(); if (err != OK) { return err; @@ -461,14 +453,6 @@ void MediaCodecSource::releaseEncoder() { mbuf->release(); } } - - for (size_t i = 0; i < mEncoderInputBuffers.size(); ++i) { - sp<ABuffer> accessUnit = mEncoderInputBuffers.itemAt(i); - accessUnit->setMediaBufferBase(NULL); - } - - mEncoderInputBuffers.clear(); - mEncoderOutputBuffers.clear(); } status_t MediaCodecSource::postSynchronouslyAndReturnError( @@ -539,20 +523,6 @@ void MediaCodecSource::resume(int64_t skipFramesBeforeUs) { } } -void MediaCodecSource::scheduleDoMoreWork() { - if (mDoMoreWorkPending) { - return; - } - - mDoMoreWorkPending = true; - - if (mEncoderActivityNotify == NULL) { - mEncoderActivityNotify = new AMessage( - kWhatEncoderActivity, mReflector->id()); - } - mEncoder->requestActivityNotification(mEncoderActivityNotify); -} - status_t MediaCodecSource::feedEncoderInputBuffers() { while (!mInputBufferQueue.empty() && !mAvailEncoderInputIndices.empty()) { @@ -587,16 +557,22 @@ status_t MediaCodecSource::feedEncoderInputBuffers() { #endif // DEBUG_DRIFT_TIME } + sp<ABuffer> inbuf; + status_t err = mEncoder->getInputBuffer(bufferIndex, &inbuf); + if (err != OK || inbuf == NULL) { + mbuf->release(); + signalEOS(); + break; + } + size = mbuf->size(); - memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(), - mbuf->data(), size); + memcpy(inbuf->data(), mbuf->data(), size); if (mIsVideo) { // video encoder will release MediaBuffer when done // with underlying data. - mEncoderInputBuffers.itemAt(bufferIndex)->setMediaBufferBase( - mbuf); + inbuf->setMediaBufferBase(mbuf); } else { mbuf->release(); } @@ -615,113 +591,6 @@ status_t MediaCodecSource::feedEncoderInputBuffers() { return OK; } -status_t MediaCodecSource::doMoreWork(int32_t numInput, int32_t numOutput) { - status_t err = OK; - - if (!(mFlags & FLAG_USE_SURFACE_INPUT)) { - while (numInput-- > 0) { - size_t bufferIndex; - err = mEncoder->dequeueInputBuffer(&bufferIndex); - - if (err != OK) { - break; - } - - mAvailEncoderInputIndices.push_back(bufferIndex); - } - - feedEncoderInputBuffers(); - } - - while (numOutput-- > 0) { - size_t bufferIndex; - size_t offset; - size_t size; - int64_t timeUs; - uint32_t flags; - native_handle_t* handle = NULL; - err = mEncoder->dequeueOutputBuffer( - &bufferIndex, &offset, &size, &timeUs, &flags); - - if (err != OK) { - if (err == INFO_FORMAT_CHANGED) { - continue; - } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) { - mEncoder->getOutputBuffers(&mEncoderOutputBuffers); - continue; - } - - if (err == -EAGAIN) { - err = OK; - } - break; - } - if (!(flags & MediaCodec::BUFFER_FLAG_EOS)) { - sp<ABuffer> outbuf = mEncoderOutputBuffers.itemAt(bufferIndex); - - MediaBuffer *mbuf = new MediaBuffer(outbuf->size()); - memcpy(mbuf->data(), outbuf->data(), outbuf->size()); - - if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) { - if (mIsVideo) { - int64_t decodingTimeUs; - if (mFlags & FLAG_USE_SURFACE_INPUT) { - // GraphicBufferSource is supposed to discard samples - // queued before start, and offset timeUs by start time - CHECK_GE(timeUs, 0ll); - // TODO: - // Decoding time for surface source is unavailable, - // use presentation time for now. May need to move - // this logic into MediaCodec. - decodingTimeUs = timeUs; - } else { - CHECK(!mDecodingTimeQueue.empty()); - decodingTimeUs = *(mDecodingTimeQueue.begin()); - mDecodingTimeQueue.erase(mDecodingTimeQueue.begin()); - } - mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); - - ALOGV("[video] time %" PRId64 " us (%.2f secs), dts/pts diff %" PRId64, - timeUs, timeUs / 1E6, decodingTimeUs - timeUs); - } else { - int64_t driftTimeUs = 0; -#if DEBUG_DRIFT_TIME - CHECK(!mDriftTimeQueue.empty()); - driftTimeUs = *(mDriftTimeQueue.begin()); - mDriftTimeQueue.erase(mDriftTimeQueue.begin()); - mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs); -#endif // DEBUG_DRIFT_TIME - ALOGV("[audio] time %" PRId64 " us (%.2f secs), drift %" PRId64, - timeUs, timeUs / 1E6, driftTimeUs); - } - mbuf->meta_data()->setInt64(kKeyTime, timeUs); - } else { - mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true); - } - if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) { - mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true); - } - mbuf->setObserver(this); - mbuf->add_ref(); - - { - Mutex::Autolock autoLock(mOutputBufferLock); - mOutputBufferQueue.push_back(mbuf); - mOutputBufferCond.signal(); - } - } - - mEncoder->releaseOutputBuffer(bufferIndex); - - if (flags & MediaCodec::BUFFER_FLAG_EOS) { - err = ERROR_END_OF_STREAM; - break; - } - } - - return err; -} - status_t MediaCodecSource::onStart(MetaData *params) { if (mStopping) { ALOGE("Failed to start while we're stopping"); @@ -749,7 +618,6 @@ status_t MediaCodecSource::onStart(MetaData *params) { startTimeUs = -1ll; } resume(startTimeUs); - scheduleDoMoreWork(); } else { CHECK(mPuller != NULL); sp<AMessage> notify = new AMessage( @@ -793,37 +661,110 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) { mInputBufferQueue.push_back(mbuf); feedEncoderInputBuffers(); - scheduleDoMoreWork(); break; } case kWhatEncoderActivity: { - mDoMoreWorkPending = false; - if (mEncoder == NULL) { break; } - int32_t numInput, numOutput; + int32_t cbID; + CHECK(msg->findInt32("callbackID", &cbID)); + if (cbID == MediaCodec::CB_INPUT_AVAILABLE) { + int32_t index; + CHECK(msg->findInt32("index", &index)); + + mAvailEncoderInputIndices.push_back(index); + feedEncoderInputBuffers(); + } else if (cbID == MediaCodec::CB_OUTPUT_AVAILABLE) { + int32_t index; + size_t offset; + size_t size; + int64_t timeUs; + int32_t flags; + native_handle_t* handle = NULL; + + CHECK(msg->findInt32("index", &index)); + CHECK(msg->findSize("offset", &offset)); + CHECK(msg->findSize("size", &size)); + CHECK(msg->findInt64("timeUs", &timeUs)); + CHECK(msg->findInt32("flags", &flags)); + + if (flags & MediaCodec::BUFFER_FLAG_EOS) { + mEncoder->releaseOutputBuffer(index); + signalEOS(); + break; + } - if (!msg->findInt32("input-buffers", &numInput)) { - numInput = INT32_MAX; - } - if (!msg->findInt32("output-buffers", &numOutput)) { - numOutput = INT32_MAX; - } + sp<ABuffer> outbuf; + status_t err = mEncoder->getOutputBuffer(index, &outbuf); + if (err != OK || outbuf == NULL) { + signalEOS(); + break; + } - status_t err = doMoreWork(numInput, numOutput); + MediaBuffer *mbuf = new MediaBuffer(outbuf->size()); + memcpy(mbuf->data(), outbuf->data(), outbuf->size()); - if (err == OK) { - scheduleDoMoreWork(); - } else { - // reached EOS, or error - signalEOS(err); - } + if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) { + if (mIsVideo) { + int64_t decodingTimeUs; + if (mFlags & FLAG_USE_SURFACE_INPUT) { + // GraphicBufferSource is supposed to discard samples + // queued before start, and offset timeUs by start time + CHECK_GE(timeUs, 0ll); + // TODO: + // Decoding time for surface source is unavailable, + // use presentation time for now. May need to move + // this logic into MediaCodec. + decodingTimeUs = timeUs; + } else { + CHECK(!mDecodingTimeQueue.empty()); + decodingTimeUs = *(mDecodingTimeQueue.begin()); + mDecodingTimeQueue.erase(mDecodingTimeQueue.begin()); + } + mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); - break; + ALOGV("[video] time %" PRId64 " us (%.2f secs), dts/pts diff %" PRId64, + timeUs, timeUs / 1E6, decodingTimeUs - timeUs); + } else { + int64_t driftTimeUs = 0; +#if DEBUG_DRIFT_TIME + CHECK(!mDriftTimeQueue.empty()); + driftTimeUs = *(mDriftTimeQueue.begin()); + mDriftTimeQueue.erase(mDriftTimeQueue.begin()); + mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs); +#endif // DEBUG_DRIFT_TIME + ALOGV("[audio] time %" PRId64 " us (%.2f secs), drift %" PRId64, + timeUs, timeUs / 1E6, driftTimeUs); + } + mbuf->meta_data()->setInt64(kKeyTime, timeUs); + } else { + mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true); + } + if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) { + mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true); + } + mbuf->setObserver(this); + mbuf->add_ref(); + + { + Mutex::Autolock autoLock(mOutputBufferLock); + mOutputBufferQueue.push_back(mbuf); + mOutputBufferCond.signal(); + } + + mEncoder->releaseOutputBuffer(index); + } else if (cbID == MediaCodec::CB_ERROR) { + status_t err; + CHECK(msg->findInt32("err", &err)); + ALOGE("Encoder (%s) reported error : 0x%x", + mIsVideo ? "video" : "audio", err); + signalEOS(); + } + break; } case kWhatStart: { diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp index ca031aa..230c1f7 100644 --- a/media/libstagefright/OMXClient.cpp +++ b/media/libstagefright/OMXClient.cpp @@ -37,7 +37,7 @@ struct MuxOMX : public IOMX { MuxOMX(const sp<IOMX> &remoteOMX); virtual ~MuxOMX(); - virtual IBinder *onAsBinder() { return mRemoteOMX->asBinder().get(); } + virtual IBinder *onAsBinder() { return IInterface::asBinder(mRemoteOMX).get(); } virtual bool livesLocally(node_id node, pid_t pid); diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 288e07a..f26563e 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -47,10 +47,11 @@ #include <media/stagefright/SkipCutBuffer.h> #include <utils/Vector.h> -#include <OMX_Audio.h> #include <OMX_AudioExt.h> #include <OMX_Component.h> #include <OMX_IndexExt.h> +#include <OMX_VideoExt.h> +#include <OMX_AsString.h> #include "include/avc_utils.h" @@ -4078,220 +4079,6 @@ void OMXCodec::signalBufferReturned(MediaBuffer *buffer) { CHECK(!"should not be here."); } -static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { - static const char *kNames[] = { - "OMX_IMAGE_CodingUnused", - "OMX_IMAGE_CodingAutoDetect", - "OMX_IMAGE_CodingJPEG", - "OMX_IMAGE_CodingJPEG2K", - "OMX_IMAGE_CodingEXIF", - "OMX_IMAGE_CodingTIFF", - "OMX_IMAGE_CodingGIF", - "OMX_IMAGE_CodingPNG", - "OMX_IMAGE_CodingLZW", - "OMX_IMAGE_CodingBMP", - }; - - size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - - if (type < 0 || (size_t)type >= numNames) { - return "UNKNOWN"; - } else { - return kNames[type]; - } -} - -static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { - static const char *kNames[] = { - "OMX_COLOR_FormatUnused", - "OMX_COLOR_FormatMonochrome", - "OMX_COLOR_Format8bitRGB332", - "OMX_COLOR_Format12bitRGB444", - "OMX_COLOR_Format16bitARGB4444", - "OMX_COLOR_Format16bitARGB1555", - "OMX_COLOR_Format16bitRGB565", - "OMX_COLOR_Format16bitBGR565", - "OMX_COLOR_Format18bitRGB666", - "OMX_COLOR_Format18bitARGB1665", - "OMX_COLOR_Format19bitARGB1666", - "OMX_COLOR_Format24bitRGB888", - "OMX_COLOR_Format24bitBGR888", - "OMX_COLOR_Format24bitARGB1887", - "OMX_COLOR_Format25bitARGB1888", - "OMX_COLOR_Format32bitBGRA8888", - "OMX_COLOR_Format32bitARGB8888", - "OMX_COLOR_FormatYUV411Planar", - "OMX_COLOR_FormatYUV411PackedPlanar", - "OMX_COLOR_FormatYUV420Planar", - "OMX_COLOR_FormatYUV420PackedPlanar", - "OMX_COLOR_FormatYUV420SemiPlanar", - "OMX_COLOR_FormatYUV422Planar", - "OMX_COLOR_FormatYUV422PackedPlanar", - "OMX_COLOR_FormatYUV422SemiPlanar", - "OMX_COLOR_FormatYCbYCr", - "OMX_COLOR_FormatYCrYCb", - "OMX_COLOR_FormatCbYCrY", - "OMX_COLOR_FormatCrYCbY", - "OMX_COLOR_FormatYUV444Interleaved", - "OMX_COLOR_FormatRawBayer8bit", - "OMX_COLOR_FormatRawBayer10bit", - "OMX_COLOR_FormatRawBayer8bitcompressed", - "OMX_COLOR_FormatL2", - "OMX_COLOR_FormatL4", - "OMX_COLOR_FormatL8", - "OMX_COLOR_FormatL16", - "OMX_COLOR_FormatL24", - "OMX_COLOR_FormatL32", - "OMX_COLOR_FormatYUV420PackedSemiPlanar", - "OMX_COLOR_FormatYUV422PackedSemiPlanar", - "OMX_COLOR_Format18BitBGR666", - "OMX_COLOR_Format24BitARGB6666", - "OMX_COLOR_Format24BitABGR6666", - }; - - size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - - if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) { - return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar"; - } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { - return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; - } else if (type < 0 || (size_t)type >= numNames) { - return "UNKNOWN"; - } else { - return kNames[type]; - } -} - -static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { - static const char *kNames[] = { - "OMX_VIDEO_CodingUnused", - "OMX_VIDEO_CodingAutoDetect", - "OMX_VIDEO_CodingMPEG2", - "OMX_VIDEO_CodingH263", - "OMX_VIDEO_CodingMPEG4", - "OMX_VIDEO_CodingWMV", - "OMX_VIDEO_CodingRV", - "OMX_VIDEO_CodingAVC", - "OMX_VIDEO_CodingMJPEG", - }; - - size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - - if (type < 0 || (size_t)type >= numNames) { - return "UNKNOWN"; - } else { - return kNames[type]; - } -} - -static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { - static const char *kNames[] = { - "OMX_AUDIO_CodingUnused", - "OMX_AUDIO_CodingAutoDetect", - "OMX_AUDIO_CodingPCM", - "OMX_AUDIO_CodingADPCM", - "OMX_AUDIO_CodingAMR", - "OMX_AUDIO_CodingGSMFR", - "OMX_AUDIO_CodingGSMEFR", - "OMX_AUDIO_CodingGSMHR", - "OMX_AUDIO_CodingPDCFR", - "OMX_AUDIO_CodingPDCEFR", - "OMX_AUDIO_CodingPDCHR", - "OMX_AUDIO_CodingTDMAFR", - "OMX_AUDIO_CodingTDMAEFR", - "OMX_AUDIO_CodingQCELP8", - "OMX_AUDIO_CodingQCELP13", - "OMX_AUDIO_CodingEVRC", - "OMX_AUDIO_CodingSMV", - "OMX_AUDIO_CodingG711", - "OMX_AUDIO_CodingG723", - "OMX_AUDIO_CodingG726", - "OMX_AUDIO_CodingG729", - "OMX_AUDIO_CodingAAC", - "OMX_AUDIO_CodingMP3", - "OMX_AUDIO_CodingSBC", - "OMX_AUDIO_CodingVORBIS", - "OMX_AUDIO_CodingOPUS", - "OMX_AUDIO_CodingWMA", - "OMX_AUDIO_CodingRA", - "OMX_AUDIO_CodingMIDI", - }; - - size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - - if (type < 0 || (size_t)type >= numNames) { - return "UNKNOWN"; - } else { - return kNames[type]; - } -} - -static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { - static const char *kNames[] = { - "OMX_AUDIO_PCMModeLinear", - "OMX_AUDIO_PCMModeALaw", - "OMX_AUDIO_PCMModeMULaw", - }; - - size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - - if (type < 0 || (size_t)type >= numNames) { - return "UNKNOWN"; - } else { - return kNames[type]; - } -} - -static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) { - static const char *kNames[] = { - "OMX_AUDIO_AMRBandModeUnused", - "OMX_AUDIO_AMRBandModeNB0", - "OMX_AUDIO_AMRBandModeNB1", - "OMX_AUDIO_AMRBandModeNB2", - "OMX_AUDIO_AMRBandModeNB3", - "OMX_AUDIO_AMRBandModeNB4", - "OMX_AUDIO_AMRBandModeNB5", - "OMX_AUDIO_AMRBandModeNB6", - "OMX_AUDIO_AMRBandModeNB7", - "OMX_AUDIO_AMRBandModeWB0", - "OMX_AUDIO_AMRBandModeWB1", - "OMX_AUDIO_AMRBandModeWB2", - "OMX_AUDIO_AMRBandModeWB3", - "OMX_AUDIO_AMRBandModeWB4", - "OMX_AUDIO_AMRBandModeWB5", - "OMX_AUDIO_AMRBandModeWB6", - "OMX_AUDIO_AMRBandModeWB7", - "OMX_AUDIO_AMRBandModeWB8", - }; - - size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - - if (type < 0 || (size_t)type >= numNames) { - return "UNKNOWN"; - } else { - return kNames[type]; - } -} - -static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) { - static const char *kNames[] = { - "OMX_AUDIO_AMRFrameFormatConformance", - "OMX_AUDIO_AMRFrameFormatIF1", - "OMX_AUDIO_AMRFrameFormatIF2", - "OMX_AUDIO_AMRFrameFormatFSF", - "OMX_AUDIO_AMRFrameFormatRTPPayload", - "OMX_AUDIO_AMRFrameFormatITU", - }; - - size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - - if (type < 0 || (size_t)type >= numNames) { - return "UNKNOWN"; - } else { - return kNames[type]; - } -} - void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { OMX_PARAM_PORTDEFINITIONTYPE def; InitOMXParams(&def); @@ -4322,10 +4109,10 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { printf(" nStride = %" PRIu32 "\n", imageDef->nStride); printf(" eCompressionFormat = %s\n", - imageCompressionFormatString(imageDef->eCompressionFormat)); + asString(imageDef->eCompressionFormat)); printf(" eColorFormat = %s\n", - colorFormatString(imageDef->eColorFormat)); + asString(imageDef->eColorFormat)); break; } @@ -4341,10 +4128,10 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { printf(" nStride = %" PRIu32 "\n", videoDef->nStride); printf(" eCompressionFormat = %s\n", - videoCompressionFormatString(videoDef->eCompressionFormat)); + asString(videoDef->eCompressionFormat)); printf(" eColorFormat = %s\n", - colorFormatString(videoDef->eColorFormat)); + asString(videoDef->eColorFormat)); break; } @@ -4356,7 +4143,7 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { printf("\n"); printf(" // Audio\n"); printf(" eEncoding = %s\n", - audioCodingTypeString(audioDef->eEncoding)); + asString(audioDef->eEncoding)); if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) { OMX_AUDIO_PARAM_PCMMODETYPE params; @@ -4376,7 +4163,7 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { params.eNumData == OMX_NumericalDataSigned ? "signed" : "unsigned"); - printf(" ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); + printf(" ePCMMode = %s\n", asString(params.ePCMMode)); } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) { OMX_AUDIO_PARAM_AMRTYPE amr; InitOMXParams(&amr); @@ -4388,9 +4175,9 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { printf(" nChannels = %" PRIu32 "\n", amr.nChannels); printf(" eAMRBandMode = %s\n", - amrBandModeString(amr.eAMRBandMode)); + asString(amr.eAMRBandMode)); printf(" eAMRFrameFormat = %s\n", - amrFrameFormatString(amr.eAMRFrameFormat)); + asString(amr.eAMRFrameFormat)); } break; @@ -4699,12 +4486,7 @@ status_t QueryCodec( const char *componentName, const char *mime, bool isEncoder, CodecCapabilities *caps) { - if (strncmp(componentName, "OMX.", 4)) { - // Not an OpenMax component but a software codec. - caps->mFlags = 0; - caps->mComponentName = componentName; - return OK; - } + bool isVideo = !strncasecmp(mime, "video/", 6); sp<OMXCodecObserver> observer = new OMXCodecObserver; IOMX::node_id node; @@ -4719,59 +4501,62 @@ status_t QueryCodec( caps->mFlags = 0; caps->mComponentName = componentName; - OMX_VIDEO_PARAM_PROFILELEVELTYPE param; - InitOMXParams(¶m); + // NOTE: OMX does not provide a way to query AAC profile support + if (isVideo) { + OMX_VIDEO_PARAM_PROFILELEVELTYPE param; + InitOMXParams(¶m); - param.nPortIndex = !isEncoder ? 0 : 1; + param.nPortIndex = !isEncoder ? 0 : 1; - for (param.nProfileIndex = 0;; ++param.nProfileIndex) { - err = omx->getParameter( - node, OMX_IndexParamVideoProfileLevelQuerySupported, - ¶m, sizeof(param)); + for (param.nProfileIndex = 0;; ++param.nProfileIndex) { + err = omx->getParameter( + node, OMX_IndexParamVideoProfileLevelQuerySupported, + ¶m, sizeof(param)); - if (err != OK) { - break; - } - - CodecProfileLevel profileLevel; - profileLevel.mProfile = param.eProfile; - profileLevel.mLevel = param.eLevel; + if (err != OK) { + break; + } - caps->mProfileLevels.push(profileLevel); - } + CodecProfileLevel profileLevel; + profileLevel.mProfile = param.eProfile; + profileLevel.mLevel = param.eLevel; - // Color format query - // return colors in the order reported by the OMX component - // prefix "flexible" standard ones with the flexible equivalent - OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; - InitOMXParams(&portFormat); - portFormat.nPortIndex = !isEncoder ? 1 : 0; - for (portFormat.nIndex = 0;; ++portFormat.nIndex) { - err = omx->getParameter( - node, OMX_IndexParamVideoPortFormat, - &portFormat, sizeof(portFormat)); - if (err != OK) { - break; + caps->mProfileLevels.push(profileLevel); } - OMX_U32 flexibleEquivalent; - if (ACodec::isFlexibleColorFormat( - omx, node, portFormat.eColorFormat, &flexibleEquivalent)) { - bool marked = false; - for (size_t i = 0; i < caps->mColorFormats.size(); i++) { - if (caps->mColorFormats.itemAt(i) == flexibleEquivalent) { - marked = true; - break; - } + // Color format query + // return colors in the order reported by the OMX component + // prefix "flexible" standard ones with the flexible equivalent + OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; + InitOMXParams(&portFormat); + portFormat.nPortIndex = !isEncoder ? 1 : 0; + for (portFormat.nIndex = 0;; ++portFormat.nIndex) { + err = omx->getParameter( + node, OMX_IndexParamVideoPortFormat, + &portFormat, sizeof(portFormat)); + if (err != OK) { + break; } - if (!marked) { - caps->mColorFormats.push(flexibleEquivalent); + + OMX_U32 flexibleEquivalent; + if (ACodec::isFlexibleColorFormat( + omx, node, portFormat.eColorFormat, &flexibleEquivalent)) { + bool marked = false; + for (size_t i = 0; i < caps->mColorFormats.size(); i++) { + if (caps->mColorFormats.itemAt(i) == flexibleEquivalent) { + marked = true; + break; + } + } + if (!marked) { + caps->mColorFormats.push(flexibleEquivalent); + } } + caps->mColorFormats.push(portFormat.eColorFormat); } - caps->mColorFormats.push(portFormat.eColorFormat); } - if (!isEncoder && !strncmp(mime, "video/", 6)) { + if (isVideo && !isEncoder) { if (omx->storeMetaDataInBuffers( node, 1 /* port index */, OMX_TRUE) == OK || omx->prepareForAdaptivePlayback( diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp index 821bd81..6219053 100644 --- a/media/libstagefright/OggExtractor.cpp +++ b/media/libstagefright/OggExtractor.cpp @@ -38,6 +38,7 @@ extern "C" { int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb); int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb); int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb); + long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); } namespace android { @@ -84,6 +85,8 @@ struct MyVorbisExtractor { private: struct Page { uint64_t mGranulePosition; + int32_t mPrevPacketSize; + uint64_t mPrevPacketPos; uint32_t mSerialNo; uint32_t mPageNo; uint8_t mFlags; @@ -121,6 +124,8 @@ private: status_t verifyHeader( MediaBuffer *buffer, uint8_t type); + int32_t packetBlockSize(MediaBuffer *buffer); + void parseFileMetaData(); status_t findPrevGranulePosition(off64_t pageOffset, uint64_t *granulePos); @@ -373,6 +378,7 @@ status_t MyVorbisExtractor::seekToOffset(off64_t offset) { mFirstPacketInPage = true; mCurrentPageSamples = 0; mCurrentPage.mNumSegments = 0; + mCurrentPage.mPrevPacketSize = -1; mNextLaceIndex = 0; // XXX what if new page continues packet from last??? @@ -489,16 +495,6 @@ status_t MyVorbisExtractor::readNextPacket(MediaBuffer **out) { tmp->set_range(0, buffer->range_length()); buffer->release(); } else { - // XXX Not only is this not technically the correct time for - // this packet, we also stamp every packet in this page - // with the same time. This needs fixing later. - - if (mVi.rate) { - // Rate may not have been initialized yet if we're currently - // reading the configuration packets... - // Fortunately, the timestamp doesn't matter for those. - timeUs = mCurrentPage.mGranulePosition * 1000000ll / mVi.rate; - } tmp->set_range(0, 0); } buffer = tmp; @@ -521,16 +517,34 @@ status_t MyVorbisExtractor::readNextPacket(MediaBuffer **out) { if (gotFullPacket) { // We've just read the entire packet. - if (timeUs >= 0) { - buffer->meta_data()->setInt64(kKeyTime, timeUs); - } - if (mFirstPacketInPage) { buffer->meta_data()->setInt32( kKeyValidSamples, mCurrentPageSamples); mFirstPacketInPage = false; } + if (mVi.rate) { + // Rate may not have been initialized yet if we're currently + // reading the configuration packets... + // Fortunately, the timestamp doesn't matter for those. + int32_t curBlockSize = packetBlockSize(buffer); + if (mCurrentPage.mPrevPacketSize < 0) { + mCurrentPage.mPrevPacketSize = curBlockSize; + mCurrentPage.mPrevPacketPos = + mCurrentPage.mGranulePosition - mCurrentPageSamples; + timeUs = mCurrentPage.mPrevPacketPos * 1000000ll / mVi.rate; + } else { + // The effective block size is the average of the two overlapped blocks + int32_t actualBlockSize = + (curBlockSize + mCurrentPage.mPrevPacketSize) / 2; + timeUs = mCurrentPage.mPrevPacketPos * 1000000ll / mVi.rate; + // The actual size output by the decoder will be half the effective + // size, due to the overlap + mCurrentPage.mPrevPacketPos += actualBlockSize / 2; + mCurrentPage.mPrevPacketSize = curBlockSize; + } + buffer->meta_data()->setInt64(kKeyTime, timeUs); + } *out = buffer; return OK; @@ -686,6 +700,35 @@ void MyVorbisExtractor::buildTableOfContents() { } } +int32_t MyVorbisExtractor::packetBlockSize(MediaBuffer *buffer) { + const uint8_t *data = + (const uint8_t *)buffer->data() + buffer->range_offset(); + + size_t size = buffer->range_length(); + + ogg_buffer buf; + buf.data = (uint8_t *)data; + buf.size = size; + buf.refcount = 1; + buf.ptr.owner = NULL; + + ogg_reference ref; + ref.buffer = &buf; + ref.begin = 0; + ref.length = size; + ref.next = NULL; + + ogg_packet pack; + pack.packet = &ref; + pack.bytes = ref.length; + pack.b_o_s = 0; + pack.e_o_s = 0; + pack.granulepos = 0; + pack.packetno = 0; + + return vorbis_packet_blocksize(&mVi, &pack); +} + status_t MyVorbisExtractor::verifyHeader( MediaBuffer *buffer, uint8_t type) { const uint8_t *data = @@ -730,6 +773,10 @@ status_t MyVorbisExtractor::verifyHeader( ALOGV("upper-bitrate = %ld", mVi.bitrate_upper); ALOGV("nominal-bitrate = %ld", mVi.bitrate_nominal); ALOGV("window-bitrate = %ld", mVi.bitrate_window); + ALOGV("blocksizes: %d/%d", + vorbis_info_blocksize(&mVi, 0), + vorbis_info_blocksize(&mVi, 1) + ); off64_t size; if (mSource->getSize(&size) == OK) { diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp index 4e1c65c..530383b 100644 --- a/media/libstagefright/SurfaceMediaSource.cpp +++ b/media/libstagefright/SurfaceMediaSource.cpp @@ -448,7 +448,7 @@ void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) { } // Part of the BufferQueue::ConsumerListener -void SurfaceMediaSource::onFrameAvailable() { +void SurfaceMediaSource::onFrameAvailable(const BufferItem& /* item */) { ALOGV("onFrameAvailable"); sp<FrameAvailableListener> listener; diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp index 1fdb244..7d15220 100644 --- a/media/libstagefright/TimedEventQueue.cpp +++ b/media/libstagefright/TimedEventQueue.cpp @@ -52,7 +52,7 @@ TimedEventQueue::TimedEventQueue() TimedEventQueue::~TimedEventQueue() { stop(); if (mPowerManager != 0) { - sp<IBinder> binder = mPowerManager->asBinder(); + sp<IBinder> binder = IInterface::asBinder(mPowerManager); binder->unlinkToDeath(mDeathRecipient); } } diff --git a/media/libstagefright/codecs/aacenc/src/bitenc.c b/media/libstagefright/codecs/aacenc/src/bitenc.c index d1fd647..9c81204 100644 --- a/media/libstagefright/codecs/aacenc/src/bitenc.c +++ b/media/libstagefright/codecs/aacenc/src/bitenc.c @@ -547,7 +547,7 @@ static void writeFillElement( const UWord8 *ancBytes, totFillBits = totFillBits - (3+4); - if ((cnt == (1<<4)-1)) { + if (cnt == (1<<4)-1) { esc_count = min( ((totFillBits >> 3) - ((1<<4)-1)), (1<<8)-1); WriteBits(hBitStream,esc_count,8); diff --git a/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp b/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp index 521fe2b..521fe2b 100755..100644 --- a/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp +++ b/media/libstagefright/codecs/amrnb/dec/test/amrnbdec_test.cpp diff --git a/media/libstagefright/codecs/amrwbenc/src/wb_vad.c b/media/libstagefright/codecs/amrwbenc/src/wb_vad.c index 13dd2aa..2beaefd 100644 --- a/media/libstagefright/codecs/amrwbenc/src/wb_vad.c +++ b/media/libstagefright/codecs/amrwbenc/src/wb_vad.c @@ -404,7 +404,7 @@ static void noise_estimate_update( alpha_down = ALPHA_DOWN1; } else { - if ((st->stat_count == 0)) + if (st->stat_count == 0) { alpha_up = ALPHA_UP2; alpha_down = ALPHA_DOWN2; diff --git a/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h b/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h index fe112bc..fe112bc 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h +++ b/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h diff --git a/media/libstagefright/codecs/on2/h264dec/inc/basetype.h b/media/libstagefright/codecs/on2/h264dec/inc/basetype.h index 63d5653..63d5653 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/inc/basetype.h +++ b/media/libstagefright/codecs/on2/h264dec/inc/basetype.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h index 64c1958..64c1958 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_BitDec_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_BitDec_s.h index c738f72..c738f72 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_BitDec_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_BitDec_s.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Bitstream.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Bitstream.h index b699034..b699034 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Bitstream.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Bitstream.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCTTable.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCTTable.h index e0cfdaa..e0cfdaa 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCTTable.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCTTable.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCT_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCT_s.h index 0baa087..0baa087 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCT_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCT_s.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_MaskTable.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_MaskTable.h index 51118fd..51118fd 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_MaskTable.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_MaskTable.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Version.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Version.h index 41b3e1e..41b3e1e 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Version.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Version.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_s.h index 0956bd1..0956bd1 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_s.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armOMX.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armOMX.h index 7a68d14..7a68d14 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armOMX.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armOMX.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h index 912cb0d..912cb0d 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes_s.h index 48703d1..48703d1 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes_s.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM.c index e572a89..e572a89 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_Bitstream.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_Bitstream.c index 9ef9319..9ef9319 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_Bitstream.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_Bitstream.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_IDCTTable.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_IDCTTable.c index 3f5e279..3f5e279 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_IDCTTable.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_IDCTTable.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_MaskTable.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_MaskTable.c index 09f88c3..09f88c3 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_MaskTable.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_MaskTable.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVC.h index 35b510b..35b510b 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVC.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVC.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVCCOMM_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVCCOMM_s.h index 32a0166..32a0166 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVCCOMM_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVCCOMM_s.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/omxVC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/omxVC.h index 7b3cc72..7b3cc72 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/omxVC.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/omxVC.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/omxVC_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/omxVC_s.h index 89f3040..89f3040 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/omxVC_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/omxVC_s.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/api/armVCM4P10_CAVLCTables.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/api/armVCM4P10_CAVLCTables.h index 547a2d9..547a2d9 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/api/armVCM4P10_CAVLCTables.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/api/armVCM4P10_CAVLCTables.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_CAVLCTables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_CAVLCTables.c index 137495d..137495d 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_CAVLCTables.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_CAVLCTables.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c index 40d4d5e..40d4d5e 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c index 619365f..619365f 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c index 4e871bf..4e871bf 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c index b29e576..b29e576 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c index 3ce41be..3ce41be 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h index 74b5505..74b5505 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h index e95203a..e95203a 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c index 38af975..38af975 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Lookup_Tables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Lookup_Tables.c index 6948f80..6948f80 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Lookup_Tables.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Lookup_Tables.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c index 21fa715..21fa715 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c index 796ad6e..796ad6e 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c index b28657c..b28657c 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/src/armVC_Version.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/src/armVC_Version.c index 5d93681..5d93681 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/src/armVC_Version.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/src/armVC_Version.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c b/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c index dcf2ef6..dcf2ef6 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c +++ b/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c b/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c index aadc75f..aadc75f 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c +++ b/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c b/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c index 42170d3..42170d3 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c +++ b/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_byte_stream.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_byte_stream.c index db77f8c..db77f8c 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_byte_stream.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_byte_stream.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_byte_stream.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_byte_stream.h index 36aec76..36aec76 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_byte_stream.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_byte_stream.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cavlc.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cavlc.c index 91d78bd..91d78bd 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cavlc.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cavlc.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cavlc.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cavlc.h index 80353d3..80353d3 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cavlc.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cavlc.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cfg.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cfg.h index 2baba5a..2baba5a 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cfg.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_cfg.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c index 7a262ed..7a262ed 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.h index 3134670..3134670 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_container.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_container.h index 99b74a0..99b74a0 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_container.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_container.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_deblocking.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_deblocking.c index f8c1f76..f8c1f76 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_deblocking.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_deblocking.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_deblocking.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_deblocking.h index 2571dda..2571dda 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_deblocking.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_deblocking.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.c index 9517d0a..9517d0a 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.h index 0e25084..0e25084 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_dpb.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_image.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_image.c index 7b92870..7b92870 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_image.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_image.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_image.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_image.h index ed7c18c..ed7c18c 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_image.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_image.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_inter_prediction.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_inter_prediction.c index 2a81c4a..2a81c4a 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_inter_prediction.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_inter_prediction.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_inter_prediction.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_inter_prediction.h index 94dee25..94dee25 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_inter_prediction.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_inter_prediction.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.c index 52c85e5..52c85e5 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.h index 4652bd5..4652bd5 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.c index 2b3e7f0..2b3e7f0 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.h index 32bc340..32bc340 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_nal_unit.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_nal_unit.c index e44c43a..e44c43a 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_nal_unit.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_nal_unit.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_nal_unit.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_nal_unit.h index 38957bf..38957bf 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_nal_unit.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_nal_unit.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_neighbour.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_neighbour.c index ce5eeff..ce5eeff 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_neighbour.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_neighbour.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_neighbour.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_neighbour.h index fce0ad1..fce0ad1 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_neighbour.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_neighbour.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.c index fb23352..fb23352 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.h index 19741eb..19741eb 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_order_cnt.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_param_set.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_param_set.c index e04dea4..e04dea4 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_param_set.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_param_set.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_param_set.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_param_set.h index 6328638..6328638 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_param_set.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_pic_param_set.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.c index b409a06..b409a06 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.h index 5a1a140..5a1a140 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_reconstruct.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_sei.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_sei.c index 0756c47..0756c47 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_sei.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_sei.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_sei.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_sei.h index efe543a..efe543a 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_sei.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_sei.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_seq_param_set.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_seq_param_set.h index e18df94..e18df94 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_seq_param_set.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_seq_param_set.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.c index c288d4b..c288d4b 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.h index f23d49e..f23d49e 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_data.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_group_map.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_group_map.c index 7cbb534..7cbb534 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_group_map.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_group_map.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_group_map.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_group_map.h index 4bcb6f2..4bcb6f2 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_group_map.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_group_map.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.c index 23401c6..23401c6 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.h index 198898a..198898a 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_slice_header.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c index 3234754..3234754 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.h index ba3b2da..ba3b2da 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_stream.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_stream.c index 20d1083..20d1083 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_stream.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_stream.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_stream.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_stream.h index 4404b66..4404b66 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_stream.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_stream.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_transform.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_transform.c index 4eb6dd0..4eb6dd0 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_transform.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_transform.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_transform.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_transform.h index 4f41a23..4f41a23 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_transform.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_transform.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c index fb97a28..fb97a28 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h index 216ad04..216ad04 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vlc.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vlc.c index 060f35e..060f35e 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vlc.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vlc.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vlc.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vlc.h index 4c16773..4c16773 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vlc.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vlc.h diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vui.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vui.c index 4a9335a..4a9335a 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vui.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vui.c diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vui.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vui.h index 05d52a4..05d52a4 100755..100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vui.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_vui.h diff --git a/media/libstagefright/filters/GraphicBufferListener.cpp b/media/libstagefright/filters/GraphicBufferListener.cpp index e493137..fa38192 100644 --- a/media/libstagefright/filters/GraphicBufferListener.cpp +++ b/media/libstagefright/filters/GraphicBufferListener.cpp @@ -60,7 +60,7 @@ status_t GraphicBufferListener::init( return OK; } -void GraphicBufferListener::onFrameAvailable() { +void GraphicBufferListener::onFrameAvailable(const BufferItem& /* item */) { ALOGV("onFrameAvailable() called"); { diff --git a/media/libstagefright/filters/GraphicBufferListener.h b/media/libstagefright/filters/GraphicBufferListener.h index aefac0d..b3e0ee3 100644 --- a/media/libstagefright/filters/GraphicBufferListener.h +++ b/media/libstagefright/filters/GraphicBufferListener.h @@ -31,7 +31,7 @@ public: const sp<AMessage> ¬ify, size_t bufferWidth, size_t bufferHeight, size_t bufferCount); - virtual void onFrameAvailable(); + virtual void onFrameAvailable(const BufferItem& item); virtual void onBuffersReleased(); virtual void onSidebandStreamChanged(); diff --git a/media/libstagefright/foundation/ADebug.cpp b/media/libstagefright/foundation/ADebug.cpp new file mode 100644 index 0000000..ec4a960 --- /dev/null +++ b/media/libstagefright/foundation/ADebug.cpp @@ -0,0 +1,117 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <errno.h> +#include <stdlib.h> +#include <ctype.h> + +#define LOG_TAG "ADebug" +#include <utils/Log.h> +#include <utils/misc.h> + +#include <cutils/properties.h> + +#include <ADebug.h> +#include <AStringUtils.h> +#include <AUtils.h> + +namespace android { + +//static +ADebug::Level ADebug::GetDebugLevelFromString( + const char *name, const char *value, ADebug::Level def) { + // split on , + const char *next = value, *current; + const unsigned long maxLevel = (unsigned long)kDebugMax; + while (next != NULL) { + current = next; + next = strchr(current, ','); + if (next != NULL) { + ++next; // pass , + } + + while (isspace(*current)) { + ++current; + } + // check for : + char *colon = strchr(current, ':'); + + // get level + char *end; + errno = 0; // strtoul does not clear errno, but it can be set for any return value + unsigned long level = strtoul(current, &end, 10); + while (isspace(*end)) { + ++end; + } + if (errno != 0 || end == current || (end != colon && *end != '\0' && end != next)) { + // invalid level - skip + continue; + } + if (colon != NULL) { + // check if pattern matches + do { // skip colon and spaces + ++colon; + } while (isspace(*colon)); + size_t globLen = (next == NULL ? strlen(colon) : (next - 1 - colon)); + while (globLen > 0 && isspace(colon[globLen - 1])) { + --globLen; // trim glob + } + + if (!AStringUtils::MatchesGlob( + colon, globLen, name, strlen(name), true /* ignoreCase */)) { + continue; + } + } + + // update debug level + def = (Level)min(level, maxLevel); + } + return def; +} + +//static +ADebug::Level ADebug::GetDebugLevelFromProperty( + const char *name, const char *propertyName, ADebug::Level def) { + char value[PROPERTY_VALUE_MAX]; + if (property_get(propertyName, value, NULL)) { + return GetDebugLevelFromString(name, value, def); + } + return def; +} + +//static +char *ADebug::GetDebugName(const char *name) { + char *debugName = strdup(name); + const char *terms[] = { "omx", "video", "audio" }; + for (size_t i = 0; i < NELEM(terms) && debugName != NULL; i++) { + const char *term = terms[i]; + const size_t len = strlen(term); + char *match = strcasestr(debugName, term); + if (match != NULL && (match == debugName || match[-1] == '.' + || match[len] == '.' || match[len] == '\0')) { + char *src = match + len; + if (match == debugName || match[-1] == '.') { + src += (*src == '.'); // remove trailing or double . + } + memmove(match, src, debugName + strlen(debugName) - src + 1); + } + } + + return debugName; +} + +} // namespace android + diff --git a/media/libstagefright/foundation/AStringUtils.cpp b/media/libstagefright/foundation/AStringUtils.cpp new file mode 100644 index 0000000..e5a846c --- /dev/null +++ b/media/libstagefright/foundation/AStringUtils.cpp @@ -0,0 +1,77 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string.h> +#include <AStringUtils.h> + +namespace android { + +// static +int AStringUtils::Compare(const char *a, const char *b, size_t len, bool ignoreCase) { + // this method relies on a trailing '\0' if a or b are shorter than len + return ignoreCase ? strncasecmp(a, b, len) : strncmp(a, b, len); +} + +// static +bool AStringUtils::MatchesGlob( + const char *glob, size_t globLen, const char *str, size_t strLen, bool ignoreCase) { + // this method does not assume a trailing '\0' + size_t ix = 0, globIx = 0; + + // pattern must match until first '*' + while (globIx < globLen && glob[globIx] != '*') { + ++globIx; + } + if (strLen < globIx || Compare(str, glob, globIx /* len */, ignoreCase)) { + return false; + } + ix = globIx; + + // process by * separated sections + while (globIx < globLen) { + ++globIx; + size_t start = globIx; + while (globIx < globLen && glob[globIx] != '*') { + ++globIx; + } + size_t len = globIx - start; + const char *pattern = glob + start; + + if (globIx == globLen) { + // last pattern must match tail + if (ix + len > strLen) { + return false; + } + const char *tail = str + strLen - len; + return !Compare(tail, pattern, len, ignoreCase); + } + // progress after first occurrence of pattern + while (ix + len <= strLen && Compare(str + ix, pattern, len, ignoreCase)) { + ++ix; + } + if (ix + len > strLen) { + return false; + } + ix += len; + // we will loop around as globIx < globLen + } + + // we only get here if there were no * in the pattern + return ix == strLen; +} + +} // namespace android + diff --git a/media/libstagefright/foundation/Android.mk b/media/libstagefright/foundation/Android.mk index 90a6a23..c1dd6ce 100644 --- a/media/libstagefright/foundation/Android.mk +++ b/media/libstagefright/foundation/Android.mk @@ -5,6 +5,7 @@ LOCAL_SRC_FILES:= \ AAtomizer.cpp \ ABitReader.cpp \ ABuffer.cpp \ + ADebug.cpp \ AHandler.cpp \ AHierarchicalStateMachine.cpp \ ALooper.cpp \ @@ -12,6 +13,7 @@ LOCAL_SRC_FILES:= \ AMessage.cpp \ ANetworkSession.cpp \ AString.cpp \ + AStringUtils.cpp \ ParsedMessage.cpp \ base64.cpp \ hexdump.cpp @@ -22,6 +24,7 @@ LOCAL_C_INCLUDES:= \ LOCAL_SHARED_LIBRARIES := \ libbinder \ libutils \ + libcutils \ liblog LOCAL_CFLAGS += -Wno-multichar -Werror diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp index 874c118..5eb4652 100644 --- a/media/libstagefright/httplive/LiveSession.cpp +++ b/media/libstagefright/httplive/LiveSession.cpp @@ -1164,6 +1164,14 @@ status_t LiveSession::selectTrack(size_t index, bool select) { return err; } +ssize_t LiveSession::getSelectedTrack(media_track_type type) const { + if (mPlaylist == NULL) { + return -1; + } else { + return mPlaylist->getSelectedTrack(type); + } +} + bool LiveSession::canSwitchUp() { // Allow upwards bandwidth switch when a stream has buffered at least 10 seconds. status_t err = OK; diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h index 7aacca6..896a8fc 100644 --- a/media/libstagefright/httplive/LiveSession.h +++ b/media/libstagefright/httplive/LiveSession.h @@ -19,6 +19,7 @@ #define LIVE_SESSION_H_ #include <media/stagefright/foundation/AHandler.h> +#include <media/mediaplayer.h> #include <utils/String8.h> @@ -73,6 +74,7 @@ struct LiveSession : public AHandler { size_t getTrackCount() const; sp<AMessage> getTrackInfo(size_t trackIndex) const; status_t selectTrack(size_t index, bool select); + ssize_t getSelectedTrack(media_track_type /* type */) const; bool isSeekable() const; bool hasDynamicDuration() const; diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp index 1651dee..eb62c7a 100644 --- a/media/libstagefright/httplive/M3UParser.cpp +++ b/media/libstagefright/httplive/M3UParser.cpp @@ -66,6 +66,9 @@ protected: virtual ~MediaGroup(); private: + + friend struct M3UParser; + struct Media { AString mName; AString mURI; @@ -356,6 +359,38 @@ ssize_t M3UParser::getSelectedIndex() const { return mSelectedIndex; } +ssize_t M3UParser::getSelectedTrack(media_track_type type) const { + MediaGroup::Type groupType; + switch (type) { + case MEDIA_TRACK_TYPE_VIDEO: + groupType = MediaGroup::TYPE_VIDEO; + break; + + case MEDIA_TRACK_TYPE_AUDIO: + groupType = MediaGroup::TYPE_AUDIO; + break; + + case MEDIA_TRACK_TYPE_SUBTITLE: + groupType = MediaGroup::TYPE_SUBS; + break; + + default: + return -1; + } + + for (size_t i = 0, ii = 0; i < mMediaGroups.size(); ++i) { + sp<MediaGroup> group = mMediaGroups.valueAt(i); + size_t tracks = group->countTracks(); + if (groupType != group->mType) { + ii += tracks; + } else if (group->mSelectedIndex >= 0) { + return ii + group->mSelectedIndex; + } + } + + return -1; +} + bool M3UParser::getTypeURI(size_t index, const char *key, AString *uri) const { if (!mIsVariantPlaylist) { *uri = mBaseURI; diff --git a/media/libstagefright/httplive/M3UParser.h b/media/libstagefright/httplive/M3UParser.h index d588afe..1cad060 100644 --- a/media/libstagefright/httplive/M3UParser.h +++ b/media/libstagefright/httplive/M3UParser.h @@ -21,6 +21,7 @@ #include <media/stagefright/foundation/ABase.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/foundation/AString.h> +#include <media/mediaplayer.h> #include <utils/Vector.h> namespace android { @@ -46,6 +47,7 @@ struct M3UParser : public RefBase { size_t getTrackCount() const; sp<AMessage> getTrackInfo(size_t index) const; ssize_t getSelectedIndex() const; + ssize_t getSelectedTrack(media_track_type /* type */) const; bool getTypeURI(size_t index, const char *key, AString *uri) const; diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp index 89181b5..d8eed5b 100644 --- a/media/libstagefright/httplive/PlaylistFetcher.cpp +++ b/media/libstagefright/httplive/PlaylistFetcher.cpp @@ -700,8 +700,7 @@ status_t PlaylistFetcher::refreshPlaylist() { mRefreshState = (RefreshState)(mRefreshState + 1); } } else { - ALOGE("failed to load playlist at url '%s'", mURI.c_str()); - notifyError(ERROR_IO); + ALOGE("failed to load playlist at url '%s'", uriDebugString(mURI).c_str()); return ERROR_IO; } } else { @@ -724,26 +723,25 @@ bool PlaylistFetcher::bufferStartsWithTsSyncByte(const sp<ABuffer>& buffer) { } void PlaylistFetcher::onDownloadNext() { - if (refreshPlaylist() != OK) { - return; - } - - int32_t firstSeqNumberInPlaylist; - if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( - "media-sequence", &firstSeqNumberInPlaylist)) { - firstSeqNumberInPlaylist = 0; - } - + status_t err = refreshPlaylist(); + int32_t firstSeqNumberInPlaylist = 0; + int32_t lastSeqNumberInPlaylist = 0; bool discontinuity = false; - const int32_t lastSeqNumberInPlaylist = - firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; + if (mPlaylist != NULL) { + if (mPlaylist->meta() != NULL) { + mPlaylist->meta()->findInt32("media-sequence", &firstSeqNumberInPlaylist); + } + + lastSeqNumberInPlaylist = + firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; - if (mDiscontinuitySeq < 0) { - mDiscontinuitySeq = mPlaylist->getDiscontinuitySeq(); + if (mDiscontinuitySeq < 0) { + mDiscontinuitySeq = mPlaylist->getDiscontinuitySeq(); + } } - if (mSeqNumber < 0) { + if (mPlaylist != NULL && mSeqNumber < 0) { CHECK_GE(mStartTimeUs, 0ll); if (mSegmentStartTimeUs < 0) { @@ -785,19 +783,26 @@ void PlaylistFetcher::onDownloadNext() { } } + // if mPlaylist is NULL then err must be non-OK; but the other way around might not be true if (mSeqNumber < firstSeqNumberInPlaylist - || mSeqNumber > lastSeqNumberInPlaylist) { - if (!mPlaylist->isComplete() && mNumRetries < kMaxNumRetries) { + || mSeqNumber > lastSeqNumberInPlaylist + || err != OK) { + if ((err != OK || !mPlaylist->isComplete()) && mNumRetries < kMaxNumRetries) { ++mNumRetries; - if (mSeqNumber > lastSeqNumberInPlaylist) { + if (mSeqNumber > lastSeqNumberInPlaylist || err != OK) { + // make sure we reach this retry logic on refresh failures + // by adding an err != OK clause to all enclosing if's. + // refresh in increasing fraction (1/2, 1/3, ...) of the // playlist's target duration or 3 seconds, whichever is less - int32_t targetDurationSecs; - CHECK(mPlaylist->meta()->findInt32( - "target-duration", &targetDurationSecs)); - int64_t delayUs = mPlaylist->size() * targetDurationSecs * - 1000000ll / (1 + mNumRetries); + int64_t delayUs = kMaxMonitorDelayUs; + if (mPlaylist != NULL && mPlaylist->meta() != NULL) { + int32_t targetDurationSecs; + CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); + delayUs = mPlaylist->size() * targetDurationSecs * + 1000000ll / (1 + mNumRetries); + } if (delayUs > kMaxMonitorDelayUs) { delayUs = kMaxMonitorDelayUs; } @@ -809,13 +814,30 @@ void PlaylistFetcher::onDownloadNext() { return; } - // we've missed the boat, let's start from the lowest sequence + if (err != OK) { + notifyError(err); + return; + } + + // we've missed the boat, let's start 3 segments prior to the latest sequence // number available and signal a discontinuity. ALOGI("We've missed the boat, restarting playback." " mStartup=%d, was looking for %d in %d-%d", mStartup, mSeqNumber, firstSeqNumberInPlaylist, lastSeqNumberInPlaylist); + if (mStopParams != NULL) { + // we should have kept on fetching until we hit the boundaries in mStopParams, + // but since the segments we are supposed to fetch have already rolled off + // the playlist, i.e. we have already missed the boat, we inevitably have to + // skip. + for (size_t i = 0; i < mPacketSources.size(); i++) { + sp<ABuffer> formatChange = mSession->createFormatChangeBuffer(); + mPacketSources.valueAt(i)->queueAccessUnit(formatChange); + } + stopAsync(/* clear = */ false); + return; + } mSeqNumber = lastSeqNumberInPlaylist - 3; if (mSeqNumber < firstSeqNumberInPlaylist) { mSeqNumber = firstSeqNumberInPlaylist; @@ -963,8 +985,8 @@ void PlaylistFetcher::onDownloadNext() { } while (bytesRead != 0); if (bufferStartsWithTsSyncByte(buffer)) { - // If we still don't see a stream after fetching a full ts segment mark it as - // nonexistent. + // If we don't see a stream in the program table after fetching a full ts segment + // mark it as nonexistent. const size_t kNumTypes = ATSParser::NUM_SOURCE_TYPES; ATSParser::SourceType srcTypes[kNumTypes] = { ATSParser::VIDEO, ATSParser::AUDIO }; @@ -979,7 +1001,7 @@ void PlaylistFetcher::onDownloadNext() { static_cast<AnotherPacketSource *>( mTSParser->getSource(srcType).get()); - if (source == NULL) { + if (!mTSParser->hasSource(srcType)) { ALOGW("MPEG2 Transport stream does not contain %s data.", srcType == ATSParser::VIDEO ? "video" : "audio"); @@ -996,7 +1018,7 @@ void PlaylistFetcher::onDownloadNext() { return; } - status_t err = OK; + err = OK; if (tsBuffer != NULL) { AString method; CHECK(buffer->meta()->findString("cipher-method", &method)); @@ -1256,6 +1278,11 @@ status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &bu CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); if (mStartTimeUsNotify != NULL && timeUs > mStartTimeUs) { + int32_t firstSeqNumberInPlaylist; + if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( + "media-sequence", &firstSeqNumberInPlaylist)) { + firstSeqNumberInPlaylist = 0; + } int32_t targetDurationSecs; CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); @@ -1266,6 +1293,8 @@ status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &bu // mStartTimeUs. // mSegmentStartTimeUs >= 0 // mSegmentStartTimeUs is non-negative when adapting or switching tracks + // mSeqNumber > firstSeqNumberInPlaylist + // don't decrement mSeqNumber if it already points to the 1st segment // timeUs - mStartTimeUs > targetDurationUs: // This and the 2 above conditions should only happen when adapting in a live // stream; the old fetcher has already fetched to mStartTimeUs; the new fetcher @@ -1275,6 +1304,7 @@ status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &bu // stop as early as possible. The definition of being "too far ahead" is // arbitrary; here we use targetDurationUs as threshold. if (mStartup && mSegmentStartTimeUs >= 0 + && mSeqNumber > firstSeqNumberInPlaylist && timeUs - mStartTimeUs > targetDurationUs) { // we just guessed a starting timestamp that is too high when adapting in a // live stream; re-adjust based on the actual timestamp extracted from the @@ -1587,6 +1617,7 @@ status_t PlaylistFetcher::extractAndQueueAccessUnits( mStartTimeUsNotify->setInt32("streamMask", LiveSession::STREAMTYPE_AUDIO); mStartTimeUsNotify->post(); mStartTimeUsNotify.clear(); + mStartup = false; } } diff --git a/media/libstagefright/httplive/PlaylistFetcher.h b/media/libstagefright/httplive/PlaylistFetcher.h index 78c358f..76cc852 100644 --- a/media/libstagefright/httplive/PlaylistFetcher.h +++ b/media/libstagefright/httplive/PlaylistFetcher.h @@ -31,7 +31,7 @@ struct DataSource; struct HTTPBase; struct LiveDataSource; struct M3UParser; -struct String8; +class String8; struct PlaylistFetcher : public AHandler { enum { diff --git a/media/libstagefright/include/AACEncoder.h b/media/libstagefright/include/AACEncoder.h index 3d5fc60..52beb0e 100644 --- a/media/libstagefright/include/AACEncoder.h +++ b/media/libstagefright/include/AACEncoder.h @@ -25,7 +25,7 @@ struct VO_MEM_OPERATOR; namespace android { -struct MediaBufferGroup; +class MediaBufferGroup; class AACEncoder: public MediaSource { public: diff --git a/media/libstagefright/include/ID3.h b/media/libstagefright/include/ID3.h index e83f3ef..c2c4a6d 100644 --- a/media/libstagefright/include/ID3.h +++ b/media/libstagefright/include/ID3.h @@ -22,8 +22,8 @@ namespace android { -struct DataSource; -struct String8; +class DataSource; +class String8; struct ID3 { enum Version { diff --git a/media/libstagefright/include/MPEG2TSExtractor.h b/media/libstagefright/include/MPEG2TSExtractor.h index c5e86a6..db1187d 100644 --- a/media/libstagefright/include/MPEG2TSExtractor.h +++ b/media/libstagefright/include/MPEG2TSExtractor.h @@ -28,7 +28,7 @@ namespace android { struct AMessage; struct AnotherPacketSource; struct ATSParser; -struct DataSource; +class DataSource; struct MPEG2TSSource; struct String8; diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h index 24d431c..104dcfc 100644 --- a/media/libstagefright/include/OMXNodeInstance.h +++ b/media/libstagefright/include/OMXNodeInstance.h @@ -31,7 +31,7 @@ struct GraphicBufferSource; struct OMXNodeInstance { OMXNodeInstance( - OMX *owner, const sp<IOMXObserver> &observer); + OMX *owner, const sp<IOMXObserver> &observer, const char *name); void setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle); @@ -149,6 +149,18 @@ private: KeyedVector<OMX_BUFFERHEADERTYPE *, OMX::buffer_id> mBufferHeaderToBufferID; #endif + // For debug support + char *mName; + int DEBUG; + size_t mNumPortBuffers[2]; // modified under mLock, read outside for debug + Mutex mDebugLock; + // following are modified and read under mDebugLock + int DEBUG_BUMP; + SortedVector<OMX_BUFFERHEADERTYPE *> mInputBuffersWithCodec, mOutputBuffersWithCodec; + size_t mDebugLevelBumpPendingBuffers[2]; + void bumpDebugLevel_l(size_t numInputBuffers, size_t numOutputBuffers); + void unbumpDebugLevel_l(size_t portIndex); + ~OMXNodeInstance(); void addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id); @@ -186,6 +198,10 @@ private: OMX_U32 portIndex, OMX_BOOL enable, OMX_BOOL useGraphicBuffer, OMX_BOOL *usingGraphicBufferInMeta); + status_t emptyBuffer_l( + OMX_BUFFERHEADERTYPE *header, + OMX_U32 flags, OMX_TICKS timestamp, intptr_t debugAddr); + sp<GraphicBufferSource> getGraphicBufferSource(); void setGraphicBufferSource(const sp<GraphicBufferSource>& bufferSource); diff --git a/media/libstagefright/include/avc_utils.h b/media/libstagefright/include/avc_utils.h index d517320..c270bc1 100644 --- a/media/libstagefright/include/avc_utils.h +++ b/media/libstagefright/include/avc_utils.h @@ -23,7 +23,7 @@ namespace android { -struct ABitReader; +class ABitReader; enum { kAVCProfileBaseline = 0x42, @@ -49,7 +49,7 @@ status_t getNextNALUnit( const uint8_t **nalStart, size_t *nalSize, bool startCodeFollows = false); -struct MetaData; +class MetaData; sp<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit); bool IsIDR(const sp<ABuffer> &accessUnit); diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp index 2587ec7..4f0862c 100644 --- a/media/libstagefright/matroska/MatroskaExtractor.cpp +++ b/media/libstagefright/matroska/MatroskaExtractor.cpp @@ -413,16 +413,16 @@ void BlockIterator::seek( const mkvparser::CuePoint* pCP; mkvparser::Tracks const *pTracks = pSegment->GetTracks(); - unsigned long int trackCount = pTracks->GetTracksCount(); while (!pCues->DoneParsing()) { pCues->LoadCuePoint(); pCP = pCues->GetLast(); CHECK(pCP); + size_t trackCount = mExtractor->mTracks.size(); for (size_t index = 0; index < trackCount; ++index) { - const mkvparser::Track *pTrack = pTracks->GetTrackByIndex(index); + MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(index); + const mkvparser::Track *pTrack = pTracks->GetTrackByNumber(track.mTrackNum); if (pTrack && pTrack->GetType() == 1 && pCP->Find(pTrack)) { // VIDEO_TRACK - MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(index); track.mCuePoints.push_back(pCP); } } @@ -434,12 +434,13 @@ void BlockIterator::seek( } const mkvparser::CuePoint::TrackPosition *pTP = NULL; - const mkvparser::Track *thisTrack = pTracks->GetTrackByIndex(mIndex); + const mkvparser::Track *thisTrack = pTracks->GetTrackByNumber(mTrackNum); if (thisTrack->GetType() == 1) { // video MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(mIndex); pTP = track.find(seekTimeNs); } else { // The Cue index is built around video keyframes + unsigned long int trackCount = pTracks->GetTracksCount(); for (size_t index = 0; index < trackCount; ++index) { const mkvparser::Track *pTrack = pTracks->GetTrackByIndex(index); if (pTrack && pTrack->GetType() == 1 && pCues->Find(seekTimeNs, pTrack, pCP, pTP)) { diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index eab7616..482ccff 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -63,6 +63,7 @@ struct ATSParser::Program : public RefBase { void signalEOS(status_t finalResult); sp<MediaSource> getSource(SourceType type); + bool hasSource(SourceType type) const; int64_t convertPTSToTimestamp(uint64_t PTS); @@ -119,6 +120,9 @@ struct ATSParser::Stream : public RefBase { sp<MediaSource> getSource(SourceType type); + bool isAudio() const; + bool isVideo() const; + protected: virtual ~Stream(); @@ -146,9 +150,6 @@ private: void extractAACFrames(const sp<ABuffer> &buffer); - bool isAudio() const; - bool isVideo() const; - DISALLOW_EVIL_CONSTRUCTORS(Stream); }; @@ -440,6 +441,19 @@ sp<MediaSource> ATSParser::Program::getSource(SourceType type) { return NULL; } +bool ATSParser::Program::hasSource(SourceType type) const { + for (size_t i = 0; i < mStreams.size(); ++i) { + const sp<Stream> &stream = mStreams.valueAt(i); + if (type == AUDIO && stream->isAudio()) { + return true; + } else if (type == VIDEO && stream->isVideo()) { + return true; + } + } + + return false; +} + int64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) { if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) { if (!mFirstPTSValid) { @@ -665,7 +679,7 @@ void ATSParser::Stream::signalDiscontinuity( int64_t resumeAtMediaTimeUs = mProgram->convertPTSToTimestamp(resumeAtPTS); - extra->setInt64("resume-at-mediatimeUs", resumeAtMediaTimeUs); + extra->setInt64("resume-at-mediaTimeUs", resumeAtMediaTimeUs); } } @@ -1278,6 +1292,17 @@ sp<MediaSource> ATSParser::getSource(SourceType type) { return NULL; } +bool ATSParser::hasSource(SourceType type) const { + for (size_t i = 0; i < mPrograms.size(); ++i) { + const sp<Program> &program = mPrograms.itemAt(i); + if (program->hasSource(type)) { + return true; + } + } + + return false; +} + bool ATSParser::PTSTimeDeltaEstablished() { if (mPrograms.isEmpty()) { return false; diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h index 204934d..75d76dc 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.h +++ b/media/libstagefright/mpeg2ts/ATSParser.h @@ -28,7 +28,7 @@ namespace android { -struct ABitReader; +class ABitReader; struct ABuffer; struct MediaSource; @@ -74,6 +74,7 @@ struct ATSParser : public RefBase { NUM_SOURCE_TYPES = 2 }; sp<MediaSource> getSource(SourceType type); + bool hasSource(SourceType type) const; bool PTSTimeDeltaEstablished(); diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp index ed40bdd..c579d4c 100644 --- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp +++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp @@ -262,15 +262,15 @@ void AnotherPacketSource::queueDiscontinuity( } } + mEOSResult = OK; + mLastQueuedTimeUs = 0; + mLatestEnqueuedMeta = NULL; + if (type == ATSParser::DISCONTINUITY_NONE) { return; } - mEOSResult = OK; - mLastQueuedTimeUs = 0; - mLatestEnqueuedMeta = NULL; ++mQueuedDiscontinuityCount; - sp<ABuffer> buffer = new ABuffer(0); buffer->meta()->setInt32("discontinuity", static_cast<int32_t>(type)); buffer->meta()->setMessage("extra", extra); diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h index a2cca77..45b4624 100644 --- a/media/libstagefright/mpeg2ts/ESQueue.h +++ b/media/libstagefright/mpeg2ts/ESQueue.h @@ -26,7 +26,7 @@ namespace android { struct ABuffer; -struct MetaData; +class MetaData; struct ElementaryStreamQueue { enum Mode { diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp index 3e70956..44c7edc 100644 --- a/media/libstagefright/omx/GraphicBufferSource.cpp +++ b/media/libstagefright/omx/GraphicBufferSource.cpp @@ -750,7 +750,7 @@ int GraphicBufferSource::findMatchingCodecBuffer_l( } // BufferQueue::ConsumerListener callback -void GraphicBufferSource::onFrameAvailable() { +void GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) { Mutex::Autolock autoLock(mMutex); ALOGV("onFrameAvailable exec=%d avail=%zu", diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h index c0860ab..c8e3775 100644 --- a/media/libstagefright/omx/GraphicBufferSource.h +++ b/media/libstagefright/omx/GraphicBufferSource.h @@ -137,7 +137,7 @@ protected: // into the codec buffer, and call Empty[This]Buffer. If we're not yet // executing or there's no codec buffer available, we just increment // mNumFramesAvailable and return. - virtual void onFrameAvailable(); + virtual void onFrameAvailable(const BufferItem& item); // BufferQueue::ConsumerListener interface, called when the client has // released one or more GraphicBuffers. We clear out the appropriate diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index 41407e4..f8d38ff 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -225,7 +225,7 @@ status_t OMX::allocateNode( *node = 0; - OMXNodeInstance *instance = new OMXNodeInstance(this, observer); + OMXNodeInstance *instance = new OMXNodeInstance(this, observer, name); OMX_COMPONENTTYPE *handle; OMX_ERRORTYPE err = mMaster->makeComponentInstance( @@ -245,8 +245,8 @@ status_t OMX::allocateNode( instance->setHandle(*node, handle); - mLiveNodes.add(observer->asBinder(), instance); - observer->asBinder()->linkToDeath(this); + mLiveNodes.add(IInterface::asBinder(observer), instance); + IInterface::asBinder(observer)->linkToDeath(this); return OK; } @@ -256,7 +256,7 @@ status_t OMX::freeNode(node_id node) { { Mutex::Autolock autoLock(mLock); - ssize_t index = mLiveNodes.indexOfKey(instance->observer()->asBinder()); + ssize_t index = mLiveNodes.indexOfKey(IInterface::asBinder(instance->observer())); if (index < 0) { // This could conceivably happen if the observer dies at roughly the // same time that a client attempts to free the node explicitly. @@ -265,7 +265,7 @@ status_t OMX::freeNode(node_id node) { mLiveNodes.removeItemsAt(index); } - instance->observer()->asBinder()->unlinkToDeath(this); + IInterface::asBinder(instance->observer())->unlinkToDeath(this); status_t err = instance->freeNode(mMaster); diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index f9c84e2..c04d95f 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -18,11 +18,15 @@ #define LOG_TAG "OMXNodeInstance" #include <utils/Log.h> +#include <inttypes.h> + #include "../include/OMXNodeInstance.h" #include "OMXMaster.h" #include "GraphicBufferSource.h" #include <OMX_Component.h> +#include <OMX_IndexExt.h> +#include <OMX_AsString.h> #include <binder/IMemory.h> #include <gui/BufferQueue.h> @@ -30,7 +34,68 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/MediaErrors.h> +#include <utils/misc.h> + static const OMX_U32 kPortIndexInput = 0; +static const OMX_U32 kPortIndexOutput = 1; + +#define CLOGW(fmt, ...) ALOGW("[%x:%s] " fmt, mNodeID, mName, ##__VA_ARGS__) + +#define CLOG_ERROR_IF(cond, fn, err, fmt, ...) \ + ALOGE_IF(cond, #fn "(%x:%s, " fmt ") ERROR: %s(%#x)", \ + mNodeID, mName, ##__VA_ARGS__, asString(err), err) +#define CLOG_ERROR(fn, err, fmt, ...) CLOG_ERROR_IF(true, fn, err, fmt, ##__VA_ARGS__) +#define CLOG_IF_ERROR(fn, err, fmt, ...) \ + CLOG_ERROR_IF((err) != OMX_ErrorNone, fn, err, fmt, ##__VA_ARGS__) + +#define CLOGI_(level, fn, fmt, ...) \ + ALOGI_IF(DEBUG >= (level), #fn "(%x:%s, " fmt ")", mNodeID, mName, ##__VA_ARGS__) +#define CLOGD_(level, fn, fmt, ...) \ + ALOGD_IF(DEBUG >= (level), #fn "(%x:%s, " fmt ")", mNodeID, mName, ##__VA_ARGS__) + +#define CLOG_LIFE(fn, fmt, ...) CLOGI_(ADebug::kDebugLifeCycle, fn, fmt, ##__VA_ARGS__) +#define CLOG_STATE(fn, fmt, ...) CLOGI_(ADebug::kDebugState, fn, fmt, ##__VA_ARGS__) +#define CLOG_CONFIG(fn, fmt, ...) CLOGI_(ADebug::kDebugConfig, fn, fmt, ##__VA_ARGS__) +#define CLOG_INTERNAL(fn, fmt, ...) CLOGD_(ADebug::kDebugInternalState, fn, fmt, ##__VA_ARGS__) + +#define CLOG_DEBUG_IF(cond, fn, fmt, ...) \ + ALOGD_IF(cond, #fn "(%x, " fmt ")", mNodeID, ##__VA_ARGS__) + +#define CLOG_BUFFER(fn, fmt, ...) \ + CLOG_DEBUG_IF(DEBUG >= ADebug::kDebugAll, fn, fmt, ##__VA_ARGS__) +#define CLOG_BUMPED_BUFFER(fn, fmt, ...) \ + CLOG_DEBUG_IF(DEBUG_BUMP >= ADebug::kDebugAll, fn, fmt, ##__VA_ARGS__) + +/* buffer formatting */ +#define BUFFER_FMT(port, fmt, ...) "%s:%u " fmt, portString(port), (port), ##__VA_ARGS__ +#define NEW_BUFFER_FMT(buffer_id, port, fmt, ...) \ + BUFFER_FMT(port, fmt ") (#%zu => %#x", ##__VA_ARGS__, mActiveBuffers.size(), (buffer_id)) + +#define SIMPLE_BUFFER(port, size, data) BUFFER_FMT(port, "%zu@%p", (size), (data)) +#define SIMPLE_NEW_BUFFER(buffer_id, port, size, data) \ + NEW_BUFFER_FMT(buffer_id, port, "%zu@%p", (size), (data)) + +#define EMPTY_BUFFER(addr, header) "%#x [%u@%p]", \ + (addr), (header)->nAllocLen, (header)->pBuffer +#define FULL_BUFFER(addr, header) "%#" PRIxPTR " [%u@%p (%u..+%u) f=%x ts=%lld]", \ + (intptr_t)(addr), (header)->nAllocLen, (header)->pBuffer, \ + (header)->nOffset, (header)->nFilledLen, (header)->nFlags, (header)->nTimeStamp + +#define WITH_STATS_WRAPPER(fmt, ...) fmt " { IN=%zu/%zu OUT=%zu/%zu }", ##__VA_ARGS__, \ + mInputBuffersWithCodec.size(), mNumPortBuffers[kPortIndexInput], \ + mOutputBuffersWithCodec.size(), mNumPortBuffers[kPortIndexOutput] +// TRICKY: this is needed so formatting macros expand before substitution +#define WITH_STATS(fmt, ...) WITH_STATS_WRAPPER(fmt, ##__VA_ARGS__) + +template<class T> +static void InitOMXParams(T *params) { + memset(params, 0, sizeof(T)); + params->nSize = sizeof(T); + params->nVersion.s.nVersionMajor = 1; + params->nVersion.s.nVersionMinor = 0; + params->nVersion.s.nRevision = 0; + params->nVersion.s.nStep = 0; +} namespace android { @@ -56,8 +121,8 @@ struct BufferMeta { } memcpy((OMX_U8 *)mMem->pointer() + header->nOffset, - header->pBuffer + header->nOffset, - header->nFilledLen); + header->pBuffer + header->nOffset, + header->nFilledLen); } void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) { @@ -66,8 +131,8 @@ struct BufferMeta { } memcpy(header->pBuffer + header->nOffset, - (const OMX_U8 *)mMem->pointer() + header->nOffset, - header->nFilledLen); + (const OMX_U8 *)mMem->pointer() + header->nOffset, + header->nFilledLen); } void setGraphicBuffer(const sp<GraphicBuffer> &graphicBuffer) { @@ -89,8 +154,17 @@ OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = { &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone }; +static inline const char *portString(OMX_U32 portIndex) { + switch (portIndex) { + case kPortIndexInput: return "Input"; + case kPortIndexOutput: return "Output"; + case ~0: return "All"; + default: return "port"; + } +} + OMXNodeInstance::OMXNodeInstance( - OMX *owner, const sp<IOMXObserver> &observer) + OMX *owner, const sp<IOMXObserver> &observer, const char *name) : mOwner(owner), mNodeID(0), mHandle(NULL), @@ -100,15 +174,25 @@ OMXNodeInstance::OMXNodeInstance( , mBufferIDCount(0) #endif { + mName = ADebug::GetDebugName(name); + DEBUG = ADebug::GetDebugLevelFromProperty(name, "debug.stagefright.omx-debug"); + ALOGV("debug level for %s is %d", name, DEBUG); + DEBUG_BUMP = DEBUG; + mNumPortBuffers[0] = 0; + mNumPortBuffers[1] = 0; + mDebugLevelBumpPendingBuffers[0] = 0; + mDebugLevelBumpPendingBuffers[1] = 0; } OMXNodeInstance::~OMXNodeInstance() { + free(mName); CHECK(mHandle == NULL); } void OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) { - CHECK(mHandle == NULL); mNodeID = node_id; + CLOG_LIFE(allocateNode, "handle=%p", handle); + CHECK(mHandle == NULL); mHandle = handle; } @@ -120,6 +204,7 @@ sp<GraphicBufferSource> OMXNodeInstance::getGraphicBufferSource() { void OMXNodeInstance::setGraphicBufferSource( const sp<GraphicBufferSource>& bufferSource) { Mutex::Autolock autoLock(mGraphicBufferSourceLock); + CLOG_INTERNAL(setGraphicBufferSource, "%p", bufferSource.get()); mGraphicBufferSource = bufferSource; } @@ -140,6 +225,7 @@ static status_t StatusFromOMXError(OMX_ERRORTYPE err) { case OMX_ErrorNone: return OK; case OMX_ErrorUnsupportedSetting: + case OMX_ErrorUnsupportedIndex: return ERROR_UNSUPPORTED; default: return UNKNOWN_ERROR; @@ -147,6 +233,7 @@ static status_t StatusFromOMXError(OMX_ERRORTYPE err) { } status_t OMXNodeInstance::freeNode(OMXMaster *master) { + CLOG_LIFE(freeNode, "handle=%p", mHandle); static int32_t kMaxNumIterations = 10; // exit if we have already freed the node @@ -175,10 +262,11 @@ status_t OMXNodeInstance::freeNode(OMXMaster *master) { OMX_ERRORTYPE err; int32_t iteration = 0; while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone - && state != OMX_StateIdle - && state != OMX_StateInvalid) { + && state != OMX_StateIdle + && state != OMX_StateInvalid) { if (++iteration > kMaxNumIterations) { - ALOGE("component failed to enter Idle state, aborting."); + CLOGW("failed to enter Idle state (now %s(%d), aborting.", + asString(state), state); state = OMX_StateInvalid; break; } @@ -204,10 +292,11 @@ status_t OMXNodeInstance::freeNode(OMXMaster *master) { OMX_ERRORTYPE err; int32_t iteration = 0; while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone - && state != OMX_StateLoaded - && state != OMX_StateInvalid) { + && state != OMX_StateLoaded + && state != OMX_StateInvalid) { if (++iteration > kMaxNumIterations) { - ALOGE("component failed to enter Loaded state, aborting."); + CLOGW("failed to enter Loaded state (now %s(%d), aborting.", + asString(state), state); state = OMX_StateInvalid; break; } @@ -225,20 +314,18 @@ status_t OMXNodeInstance::freeNode(OMXMaster *master) { break; default: - CHECK(!"should not be here, unknown state."); + LOG_ALWAYS_FATAL("unknown state %s(%#x).", asString(state), state); break; } - ALOGV("calling destroyComponentInstance"); + ALOGV("[%x:%s] calling destroyComponentInstance", mNodeID, mName); OMX_ERRORTYPE err = master->destroyComponentInstance( static_cast<OMX_COMPONENTTYPE *>(mHandle)); - ALOGV("destroyComponentInstance returned err %d", err); mHandle = NULL; - - if (err != OMX_ErrorNone) { - ALOGE("FreeHandle FAILED with error 0x%08x.", err); - } + CLOG_IF_ERROR(freeNode, err, ""); + free(mName); + mName = NULL; mOwner->invalidateNodeID(mNodeID); mNodeID = 0; @@ -270,7 +357,17 @@ status_t OMXNodeInstance::sendCommand( Mutex::Autolock autoLock(mLock); + // bump internal-state debug level for 2 input and output frames past a command + { + Mutex::Autolock _l(mDebugLock); + bumpDebugLevel_l(2 /* numInputBuffers */, 2 /* numOutputBuffers */); + } + + const char *paramString = + cmd == OMX_CommandStateSet ? asString((OMX_STATETYPE)param) : portString(param); + CLOG_STATE(sendCommand, "%s(%d), %s(%d)", asString(cmd), cmd, paramString, param); OMX_ERRORTYPE err = OMX_SendCommand(mHandle, cmd, param, NULL); + CLOG_IF_ERROR(sendCommand, err, "%s(%d), %s(%d)", asString(cmd), cmd, paramString, param); return StatusFromOMXError(err); } @@ -279,17 +376,23 @@ status_t OMXNodeInstance::getParameter( Mutex::Autolock autoLock(mLock); OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params); - ALOGE_IF(err != OMX_ErrorNone, "getParameter(%d) ERROR: %#x", index, err); + OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; + // some errors are expected for getParameter + if (err != OMX_ErrorNoMore) { + CLOG_IF_ERROR(getParameter, err, "%s(%#x)", asString(extIndex), index); + } return StatusFromOMXError(err); } status_t OMXNodeInstance::setParameter( - OMX_INDEXTYPE index, const void *params, size_t /* size */) { + OMX_INDEXTYPE index, const void *params, size_t size) { Mutex::Autolock autoLock(mLock); + OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; + CLOG_CONFIG(setParameter, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params); OMX_ERRORTYPE err = OMX_SetParameter( mHandle, index, const_cast<void *>(params)); - ALOGE_IF(err != OMX_ErrorNone, "setParameter(%d) ERROR: %#x", index, err); + CLOG_IF_ERROR(setParameter, err, "%s(%#x)", asString(extIndex), index); return StatusFromOMXError(err); } @@ -298,16 +401,23 @@ status_t OMXNodeInstance::getConfig( Mutex::Autolock autoLock(mLock); OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params); + OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; + // some errors are expected for getConfig + if (err != OMX_ErrorNoMore) { + CLOG_IF_ERROR(getConfig, err, "%s(%#x)", asString(extIndex), index); + } return StatusFromOMXError(err); } status_t OMXNodeInstance::setConfig( - OMX_INDEXTYPE index, const void *params, size_t /* size */) { + OMX_INDEXTYPE index, const void *params, size_t size) { Mutex::Autolock autoLock(mLock); + OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; + CLOG_CONFIG(setConfig, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params); OMX_ERRORTYPE err = OMX_SetConfig( mHandle, index, const_cast<void *>(params)); - + CLOG_IF_ERROR(setConfig, err, "%s(%#x)", asString(extIndex), index); return StatusFromOMXError(err); } @@ -315,13 +425,14 @@ status_t OMXNodeInstance::getState(OMX_STATETYPE* state) { Mutex::Autolock autoLock(mLock); OMX_ERRORTYPE err = OMX_GetState(mHandle, state); - + CLOG_IF_ERROR(getState, err, ""); return StatusFromOMXError(err); } status_t OMXNodeInstance::enableGraphicBuffers( OMX_U32 portIndex, OMX_BOOL enable) { Mutex::Autolock autoLock(mLock); + CLOG_CONFIG(enableGraphicBuffers, "%s:%u, %d", portString(portIndex), portIndex, enable); OMX_STRING name = const_cast<OMX_STRING>( "OMX.google.android.index.enableAndroidNativeBuffers"); @@ -329,32 +440,19 @@ status_t OMXNodeInstance::enableGraphicBuffers( OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); if (err != OMX_ErrorNone) { - if (enable) { - ALOGE("OMX_GetExtensionIndex %s failed", name); - } - + CLOG_ERROR_IF(enable, getExtensionIndex, err, "%s", name); return StatusFromOMXError(err); } - OMX_VERSIONTYPE ver; - ver.s.nVersionMajor = 1; - ver.s.nVersionMinor = 0; - ver.s.nRevision = 0; - ver.s.nStep = 0; - EnableAndroidNativeBuffersParams params = { - sizeof(EnableAndroidNativeBuffersParams), ver, portIndex, enable, - }; + EnableAndroidNativeBuffersParams params; + InitOMXParams(¶ms); + params.nPortIndex = portIndex; + params.enable = enable; err = OMX_SetParameter(mHandle, index, ¶ms); - - if (err != OMX_ErrorNone) { - ALOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)", - err, err); - - return UNKNOWN_ERROR; - } - - return OK; + CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d", name, index, + portString(portIndex), portIndex, enable); + return StatusFromOMXError(err); } status_t OMXNodeInstance::getGraphicBufferUsage( @@ -367,26 +465,19 @@ status_t OMXNodeInstance::getGraphicBufferUsage( OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); if (err != OMX_ErrorNone) { - ALOGE("OMX_GetExtensionIndex %s failed", name); - + CLOG_ERROR(getExtensionIndex, err, "%s", name); return StatusFromOMXError(err); } - OMX_VERSIONTYPE ver; - ver.s.nVersionMajor = 1; - ver.s.nVersionMinor = 0; - ver.s.nRevision = 0; - ver.s.nStep = 0; - GetAndroidNativeBufferUsageParams params = { - sizeof(GetAndroidNativeBufferUsageParams), ver, portIndex, 0, - }; + GetAndroidNativeBufferUsageParams params; + InitOMXParams(¶ms); + params.nPortIndex = portIndex; err = OMX_GetParameter(mHandle, index, ¶ms); - if (err != OMX_ErrorNone) { - ALOGE("OMX_GetAndroidNativeBufferUsage failed with error %d (0x%08x)", - err, err); - return UNKNOWN_ERROR; + CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u", name, index, + portString(portIndex), portIndex); + return StatusFromOMXError(err); } *usage = params.nUsage; @@ -398,6 +489,7 @@ status_t OMXNodeInstance::storeMetaDataInBuffers( OMX_U32 portIndex, OMX_BOOL enable) { Mutex::Autolock autolock(mLock); + CLOG_CONFIG(storeMetaDataInBuffers, "%s:%u en:%d", portString(portIndex), portIndex, enable); return storeMetaDataInBuffers_l( portIndex, enable, OMX_FALSE /* useGraphicBuffer */, NULL /* usingGraphicBufferInMetadata */); @@ -424,37 +516,42 @@ status_t OMXNodeInstance::storeMetaDataInBuffers_l( : OMX_ErrorBadParameter; if (err == OMX_ErrorNone) { *usingGraphicBufferInMetadata = OMX_TRUE; + name = graphicBufferName; } else { - *usingGraphicBufferInMetadata = OMX_FALSE; err = OMX_GetExtensionIndex(mHandle, name, &index); } - if (err != OMX_ErrorNone) { - ALOGE("OMX_GetExtensionIndex %s failed", name); - return StatusFromOMXError(err); - } - - StoreMetaDataInBuffersParams params; - memset(¶ms, 0, sizeof(params)); - params.nSize = sizeof(params); + OMX_ERRORTYPE xerr = err; + if (err == OMX_ErrorNone) { + StoreMetaDataInBuffersParams params; + InitOMXParams(¶ms); + params.nPortIndex = portIndex; + params.bStoreMetaData = enable; - // Version: 1.0.0.0 - params.nVersion.s.nVersionMajor = 1; + err = OMX_SetParameter(mHandle, index, ¶ms); + } - params.nPortIndex = portIndex; - params.bStoreMetaData = enable; - if ((err = OMX_SetParameter(mHandle, index, ¶ms)) != OMX_ErrorNone) { - ALOGE("OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x%08x", err); + // don't log loud error if component does not support metadata mode on the output + if (err != OMX_ErrorNone) { *usingGraphicBufferInMetadata = OMX_FALSE; - return UNKNOWN_ERROR; + if (err == OMX_ErrorUnsupportedIndex && portIndex == kPortIndexOutput) { + CLOGW("component does not support metadata mode; using fallback"); + } else if (xerr != OMX_ErrorNone) { + CLOG_ERROR(getExtensionIndex, xerr, "%s", name); + } else { + CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d GB=%d", name, index, + portString(portIndex), portIndex, enable, useGraphicBuffer); + } } - return err; + return StatusFromOMXError(err); } status_t OMXNodeInstance::prepareForAdaptivePlayback( OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) { Mutex::Autolock autolock(mLock); + CLOG_CONFIG(prepareForAdaptivePlayback, "%s:%u en=%d max=%ux%u", + portString(portIndex), portIndex, enable, maxFrameWidth, maxFrameHeight); OMX_INDEXTYPE index; OMX_STRING name = const_cast<OMX_STRING>( @@ -462,33 +559,29 @@ status_t OMXNodeInstance::prepareForAdaptivePlayback( OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); if (err != OMX_ErrorNone) { - ALOGW_IF(enable, "OMX_GetExtensionIndex %s failed", name); + CLOG_ERROR_IF(enable, getExtensionIndex, err, "%s", name); return StatusFromOMXError(err); } PrepareForAdaptivePlaybackParams params; - params.nSize = sizeof(params); - params.nVersion.s.nVersionMajor = 1; - params.nVersion.s.nVersionMinor = 0; - params.nVersion.s.nRevision = 0; - params.nVersion.s.nStep = 0; - + InitOMXParams(¶ms); params.nPortIndex = portIndex; params.bEnable = enable; params.nMaxFrameWidth = maxFrameWidth; params.nMaxFrameHeight = maxFrameHeight; - if ((err = OMX_SetParameter(mHandle, index, ¶ms)) != OMX_ErrorNone) { - ALOGW("OMX_SetParameter failed for PrepareForAdaptivePlayback " - "with error %d (0x%08x)", err, err); - return UNKNOWN_ERROR; - } - return err; + + err = OMX_SetParameter(mHandle, index, ¶ms); + CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d max=%ux%u", name, index, + portString(portIndex), portIndex, enable, maxFrameWidth, maxFrameHeight); + return StatusFromOMXError(err); } status_t OMXNodeInstance::configureVideoTunnelMode( OMX_U32 portIndex, OMX_BOOL tunneled, OMX_U32 audioHwSync, native_handle_t **sidebandHandle) { Mutex::Autolock autolock(mLock); + CLOG_CONFIG(configureVideoTunnelMode, "%s:%u tun=%d sync=%u", + portString(portIndex), portIndex, tunneled, audioHwSync); OMX_INDEXTYPE index; OMX_STRING name = const_cast<OMX_STRING>( @@ -496,36 +589,33 @@ status_t OMXNodeInstance::configureVideoTunnelMode( OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); if (err != OMX_ErrorNone) { - ALOGE("configureVideoTunnelMode extension is missing!"); + CLOG_ERROR_IF(tunneled, getExtensionIndex, err, "%s", name); return StatusFromOMXError(err); } ConfigureVideoTunnelModeParams tunnelParams; - tunnelParams.nSize = sizeof(tunnelParams); - tunnelParams.nVersion.s.nVersionMajor = 1; - tunnelParams.nVersion.s.nVersionMinor = 0; - tunnelParams.nVersion.s.nRevision = 0; - tunnelParams.nVersion.s.nStep = 0; - + InitOMXParams(&tunnelParams); tunnelParams.nPortIndex = portIndex; tunnelParams.bTunneled = tunneled; tunnelParams.nAudioHwSync = audioHwSync; err = OMX_SetParameter(mHandle, index, &tunnelParams); if (err != OMX_ErrorNone) { - ALOGE("configureVideoTunnelMode failed! (err %d).", err); - return UNKNOWN_ERROR; + CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u tun=%d sync=%u", name, index, + portString(portIndex), portIndex, tunneled, audioHwSync); + return StatusFromOMXError(err); } err = OMX_GetParameter(mHandle, index, &tunnelParams); if (err != OMX_ErrorNone) { - ALOGE("GetVideoTunnelWindow failed! (err %d).", err); - return UNKNOWN_ERROR; + CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u tun=%d sync=%u", name, index, + portString(portIndex), portIndex, tunneled, audioHwSync); + return StatusFromOMXError(err); } if (sidebandHandle) { *sidebandHandle = (native_handle_t*)tunnelParams.pSidebandWindow; } - return err; + return OK; } status_t OMXNodeInstance::useBuffer( @@ -542,14 +632,14 @@ status_t OMXNodeInstance::useBuffer( params->size(), static_cast<OMX_U8 *>(params->pointer())); if (err != OMX_ErrorNone) { - ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err); + CLOG_ERROR(useBuffer, err, SIMPLE_BUFFER(portIndex, params->size(), params->pointer())); delete buffer_meta; buffer_meta = NULL; *buffer = 0; - return UNKNOWN_ERROR; + return StatusFromOMXError(err); } CHECK_EQ(header->pAppPrivate, buffer_meta); @@ -563,6 +653,8 @@ status_t OMXNodeInstance::useBuffer( bufferSource->addCodecBuffer(header); } + CLOG_BUFFER(useBuffer, NEW_BUFFER_FMT( + *buffer, portIndex, "%zu@%p", params->size(), params->pointer())); return OK; } @@ -572,17 +664,14 @@ status_t OMXNodeInstance::useGraphicBuffer2_l( // port definition OMX_PARAM_PORTDEFINITIONTYPE def; - def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); - def.nVersion.s.nVersionMajor = 1; - def.nVersion.s.nVersionMinor = 0; - def.nVersion.s.nRevision = 0; - def.nVersion.s.nStep = 0; + InitOMXParams(&def); def.nPortIndex = portIndex; OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def); - if (err != OMX_ErrorNone) - { - ALOGE("%s::%d:Error getting OMX_IndexParamPortDefinition", __FUNCTION__, __LINE__); - return err; + if (err != OMX_ErrorNone) { + OMX_INDEXTYPE index = OMX_IndexParamPortDefinition; + CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u", + asString(index), index, portString(portIndex), portIndex); + return UNKNOWN_ERROR; } BufferMeta *bufferMeta = new BufferMeta(graphicBuffer); @@ -600,11 +689,11 @@ status_t OMXNodeInstance::useGraphicBuffer2_l( bufferHandle); if (err != OMX_ErrorNone) { - ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err); + CLOG_ERROR(useBuffer, err, BUFFER_FMT(portIndex, "%u@%p", def.nBufferSize, bufferHandle)); delete bufferMeta; bufferMeta = NULL; *buffer = 0; - return UNKNOWN_ERROR; + return StatusFromOMXError(err); } CHECK_EQ(header->pBuffer, bufferHandle); @@ -613,7 +702,8 @@ status_t OMXNodeInstance::useGraphicBuffer2_l( *buffer = makeBufferID(header); addActiveBuffer(portIndex, *buffer); - + CLOG_BUFFER(useGraphicBuffer2, NEW_BUFFER_FMT( + *buffer, portIndex, "%u@%p", def.nBufferSize, bufferHandle)); return OK; } @@ -637,10 +727,8 @@ status_t OMXNodeInstance::useGraphicBuffer( OMX_STRING name = const_cast<OMX_STRING>( "OMX.google.android.index.useAndroidNativeBuffer"); OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); - if (err != OMX_ErrorNone) { - ALOGE("OMX_GetExtensionIndex %s failed", name); - + CLOG_ERROR(getExtensionIndex, err, "%s", name); return StatusFromOMXError(err); } @@ -661,15 +749,15 @@ status_t OMXNodeInstance::useGraphicBuffer( err = OMX_SetParameter(mHandle, index, ¶ms); if (err != OMX_ErrorNone) { - ALOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err, - err); + CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u meta=%p GB=%p", name, index, + portString(portIndex), portIndex, bufferMeta, graphicBuffer->handle); delete bufferMeta; bufferMeta = NULL; *buffer = 0; - return UNKNOWN_ERROR; + return StatusFromOMXError(err); } CHECK_EQ(header->pAppPrivate, bufferMeta); @@ -677,12 +765,13 @@ status_t OMXNodeInstance::useGraphicBuffer( *buffer = makeBufferID(header); addActiveBuffer(portIndex, *buffer); - + CLOG_BUFFER(useGraphicBuffer, NEW_BUFFER_FMT( + *buffer, portIndex, "GB=%p", graphicBuffer->handle)); return OK; } status_t OMXNodeInstance::updateGraphicBufferInMeta( - OMX_U32 /* portIndex */, const sp<GraphicBuffer>& graphicBuffer, + OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer, OMX::buffer_id buffer) { Mutex::Autolock autoLock(mLock); @@ -693,7 +782,8 @@ status_t OMXNodeInstance::updateGraphicBufferInMeta( bufferMeta->setGraphicBuffer(graphicBuffer); metadata->eType = kMetadataBufferTypeGrallocSource; metadata->pHandle = graphicBuffer->handle; - + CLOG_BUFFER(updateGraphicBufferInMeta, "%s:%u, %#x := %p", + portString(portIndex), portIndex, buffer, graphicBuffer->handle); return OK; } @@ -719,19 +809,21 @@ status_t OMXNodeInstance::createInputSurface( // Retrieve the width and height of the graphic buffer, set when the // codec was configured. OMX_PARAM_PORTDEFINITIONTYPE def; - def.nSize = sizeof(def); - def.nVersion.s.nVersionMajor = 1; - def.nVersion.s.nVersionMinor = 0; - def.nVersion.s.nRevision = 0; - def.nVersion.s.nStep = 0; + InitOMXParams(&def); def.nPortIndex = portIndex; OMX_ERRORTYPE oerr = OMX_GetParameter( mHandle, OMX_IndexParamPortDefinition, &def); - CHECK(oerr == OMX_ErrorNone); + if (oerr != OMX_ErrorNone) { + OMX_INDEXTYPE index = OMX_IndexParamPortDefinition; + CLOG_ERROR(getParameter, oerr, "%s(%#x): %s:%u", + asString(index), index, portString(portIndex), portIndex); + return UNKNOWN_ERROR; + } if (def.format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque) { - ALOGE("createInputSurface requires COLOR_FormatSurface " - "(AndroidOpaque) color format"); + CLOGW("createInputSurface requires COLOR_FormatSurface " + "(AndroidOpaque) color format instead of %s(%#x)", + asString(def.format.video.eColorFormat), def.format.video.eColorFormat); return INVALID_OPERATION; } @@ -754,9 +846,9 @@ status_t OMXNodeInstance::signalEndOfInputStream() { // flag set). Seems easier than doing the equivalent from here. sp<GraphicBufferSource> bufferSource(getGraphicBufferSource()); if (bufferSource == NULL) { - ALOGW("signalEndOfInputStream can only be used with Surface input"); + CLOGW("signalEndOfInputStream can only be used with Surface input"); return INVALID_OPERATION; - }; + } return bufferSource->signalEndOfInputStream(); } @@ -773,14 +865,13 @@ status_t OMXNodeInstance::allocateBuffer( mHandle, &header, portIndex, buffer_meta, size); if (err != OMX_ErrorNone) { - ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err); - + CLOG_ERROR(allocateBuffer, err, BUFFER_FMT(portIndex, "%zu@", size)); delete buffer_meta; buffer_meta = NULL; *buffer = 0; - return UNKNOWN_ERROR; + return StatusFromOMXError(err); } CHECK_EQ(header->pAppPrivate, buffer_meta); @@ -794,6 +885,7 @@ status_t OMXNodeInstance::allocateBuffer( if (bufferSource != NULL && portIndex == kPortIndexInput) { bufferSource->addCodecBuffer(header); } + CLOG_BUFFER(allocateBuffer, NEW_BUFFER_FMT(*buffer, portIndex, "%zu@%p", size, *buffer_data)); return OK; } @@ -811,14 +903,14 @@ status_t OMXNodeInstance::allocateBufferWithBackup( mHandle, &header, portIndex, buffer_meta, params->size()); if (err != OMX_ErrorNone) { - ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err); - + CLOG_ERROR(allocateBufferWithBackup, err, + SIMPLE_BUFFER(portIndex, params->size(), params->pointer())); delete buffer_meta; buffer_meta = NULL; *buffer = 0; - return UNKNOWN_ERROR; + return StatusFromOMXError(err); } CHECK_EQ(header->pAppPrivate, buffer_meta); @@ -832,12 +924,16 @@ status_t OMXNodeInstance::allocateBufferWithBackup( bufferSource->addCodecBuffer(header); } + CLOG_BUFFER(allocateBufferWithBackup, NEW_BUFFER_FMT(*buffer, portIndex, "%zu@%p :> %p", + params->size(), params->pointer(), header->pBuffer)); + return OK; } status_t OMXNodeInstance::freeBuffer( OMX_U32 portIndex, OMX::buffer_id buffer) { Mutex::Autolock autoLock(mLock); + CLOG_BUFFER(freeBuffer, "%s:%u %#x", portString(portIndex), portIndex, buffer); removeActiveBuffer(portIndex, buffer); @@ -845,6 +941,7 @@ status_t OMXNodeInstance::freeBuffer( BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate); OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header); + CLOG_IF_ERROR(freeBuffer, err, "%s:%u %#x", portString(portIndex), portIndex, buffer); delete buffer_meta; buffer_meta = NULL; @@ -861,8 +958,18 @@ status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) { header->nOffset = 0; header->nFlags = 0; - OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header); + { + Mutex::Autolock _l(mDebugLock); + mOutputBuffersWithCodec.add(header); + CLOG_BUMPED_BUFFER(fillBuffer, WITH_STATS(EMPTY_BUFFER(buffer, header))); + } + OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header); + if (err != OMX_ErrorNone) { + CLOG_ERROR(fillBuffer, err, EMPTY_BUFFER(buffer, header)); + Mutex::Autolock _l(mDebugLock); + mOutputBuffersWithCodec.remove(header); + } return StatusFromOMXError(err); } @@ -875,14 +982,66 @@ status_t OMXNodeInstance::emptyBuffer( OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer); header->nFilledLen = rangeLength; header->nOffset = rangeOffset; - header->nFlags = flags; - header->nTimeStamp = timestamp; BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate); buffer_meta->CopyToOMX(header); + return emptyBuffer_l(header, flags, timestamp, (intptr_t)buffer); +} + +// log queued buffer activity for the next few input and/or output frames +// if logging at internal state level +void OMXNodeInstance::bumpDebugLevel_l(size_t numInputBuffers, size_t numOutputBuffers) { + if (DEBUG == ADebug::kDebugInternalState) { + DEBUG_BUMP = ADebug::kDebugAll; + if (numInputBuffers > 0) { + mDebugLevelBumpPendingBuffers[kPortIndexInput] = numInputBuffers; + } + if (numOutputBuffers > 0) { + mDebugLevelBumpPendingBuffers[kPortIndexOutput] = numOutputBuffers; + } + } +} + +void OMXNodeInstance::unbumpDebugLevel_l(size_t portIndex) { + if (mDebugLevelBumpPendingBuffers[portIndex]) { + --mDebugLevelBumpPendingBuffers[portIndex]; + } + if (!mDebugLevelBumpPendingBuffers[0] + && !mDebugLevelBumpPendingBuffers[1]) { + DEBUG_BUMP = DEBUG; + } +} + +status_t OMXNodeInstance::emptyBuffer_l( + OMX_BUFFERHEADERTYPE *header, OMX_U32 flags, OMX_TICKS timestamp, intptr_t debugAddr) { + header->nFlags = flags; + header->nTimeStamp = timestamp; + + { + Mutex::Autolock _l(mDebugLock); + mInputBuffersWithCodec.add(header); + + // bump internal-state debug level for 2 input frames past a buffer with CSD + if ((flags & OMX_BUFFERFLAG_CODECCONFIG) != 0) { + bumpDebugLevel_l(2 /* numInputBuffers */, 0 /* numOutputBuffers */); + } + + CLOG_BUMPED_BUFFER(emptyBuffer, WITH_STATS(FULL_BUFFER(debugAddr, header))); + } + OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header); + CLOG_IF_ERROR(emptyBuffer, err, FULL_BUFFER(debugAddr, header)); + + { + Mutex::Autolock _l(mDebugLock); + if (err != OMX_ErrorNone) { + mInputBuffersWithCodec.remove(header); + } else if (!(flags & OMX_BUFFERFLAG_CODECCONFIG)) { + unbumpDebugLevel_l(kPortIndexInput); + } + } return StatusFromOMXError(err); } @@ -896,15 +1055,8 @@ status_t OMXNodeInstance::emptyDirectBuffer( header->nFilledLen = rangeLength; header->nOffset = rangeOffset; - header->nFlags = flags; - header->nTimeStamp = timestamp; - - OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header); - if (err != OMX_ErrorNone) { - ALOGW("emptyDirectBuffer failed, OMX err=0x%x", err); - } - return StatusFromOMXError(err); + return emptyBuffer_l(header, flags, timestamp, (intptr_t)header->pBuffer); } status_t OMXNodeInstance::getExtensionIndex( @@ -917,11 +1069,25 @@ status_t OMXNodeInstance::getExtensionIndex( return StatusFromOMXError(err); } +inline static const char *asString(IOMX::InternalOptionType i, const char *def = "??") { + switch (i) { + case IOMX::INTERNAL_OPTION_SUSPEND: return "SUSPEND"; + case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY: + return "REPEAT_PREVIOUS_FRAME_DELAY"; + case IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP: return "MAX_TIMESTAMP_GAP"; + case IOMX::INTERNAL_OPTION_START_TIME: return "START_TIME"; + case IOMX::INTERNAL_OPTION_TIME_LAPSE: return "TIME_LAPSE"; + default: return def; + } +} + status_t OMXNodeInstance::setInternalOption( OMX_U32 portIndex, IOMX::InternalOptionType type, const void *data, size_t size) { + CLOG_CONFIG(setInternalOption, "%s(%d): %s:%u %zu@%p", + asString(type), type, portString(portIndex), portIndex, size, data); switch (type) { case IOMX::INTERNAL_OPTION_SUSPEND: case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY: @@ -933,6 +1099,7 @@ status_t OMXNodeInstance::setInternalOption( getGraphicBufferSource(); if (bufferSource == NULL || portIndex != kPortIndexInput) { + CLOGW("setInternalOption is only for Surface input"); return ERROR_UNSUPPORTED; } @@ -942,6 +1109,7 @@ status_t OMXNodeInstance::setInternalOption( } bool suspend = *(bool *)data; + CLOG_CONFIG(setInternalOption, "suspend=%d", suspend); bufferSource->suspend(suspend); } else if (type == IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY){ @@ -950,7 +1118,7 @@ status_t OMXNodeInstance::setInternalOption( } int64_t delayUs = *(int64_t *)data; - + CLOG_CONFIG(setInternalOption, "delayUs=%lld", (long long)delayUs); return bufferSource->setRepeatPreviousFrameDelayUs(delayUs); } else if (type == IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP){ @@ -959,7 +1127,7 @@ status_t OMXNodeInstance::setInternalOption( } int64_t maxGapUs = *(int64_t *)data; - + CLOG_CONFIG(setInternalOption, "gapUs=%lld", (long long)maxGapUs); return bufferSource->setMaxTimestampGapUs(maxGapUs); } else if (type == IOMX::INTERNAL_OPTION_START_TIME) { if (size != sizeof(int64_t)) { @@ -967,13 +1135,18 @@ status_t OMXNodeInstance::setInternalOption( } int64_t skipFramesBeforeUs = *(int64_t *)data; - + CLOG_CONFIG(setInternalOption, "beforeUs=%lld", (long long)skipFramesBeforeUs); bufferSource->setSkipFramesBeforeUs(skipFramesBeforeUs); } else { // IOMX::INTERNAL_OPTION_TIME_LAPSE if (size != sizeof(int64_t) * 2) { return INVALID_OPERATION; } + int64_t timePerFrameUs = ((int64_t *)data)[0]; + int64_t timePerCaptureUs = ((int64_t *)data)[1]; + CLOG_CONFIG(setInternalOption, "perFrameUs=%lld perCaptureUs=%lld", + (long long)timePerFrameUs, (long long)timePerCaptureUs); + bufferSource->setTimeLapseUs((int64_t *)data); } @@ -992,6 +1165,16 @@ void OMXNodeInstance::onMessage(const omx_message &msg) { OMX_BUFFERHEADERTYPE *buffer = findBufferHeader(msg.u.extended_buffer_data.buffer); + { + Mutex::Autolock _l(mDebugLock); + mOutputBuffersWithCodec.remove(buffer); + + CLOG_BUMPED_BUFFER( + FBD, WITH_STATS(FULL_BUFFER(msg.u.extended_buffer_data.buffer, buffer))); + + unbumpDebugLevel_l(kPortIndexOutput); + } + BufferMeta *buffer_meta = static_cast<BufferMeta *>(buffer->pAppPrivate); @@ -1007,16 +1190,23 @@ void OMXNodeInstance::onMessage(const omx_message &msg) { return; } } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) { + OMX_BUFFERHEADERTYPE *buffer = + findBufferHeader(msg.u.buffer_data.buffer); + + { + Mutex::Autolock _l(mDebugLock); + mInputBuffersWithCodec.remove(buffer); + + CLOG_BUMPED_BUFFER( + EBD, WITH_STATS(EMPTY_BUFFER(msg.u.buffer_data.buffer, buffer))); + } + if (bufferSource != NULL) { // This is one of the buffers used exclusively by // GraphicBufferSource. // Don't dispatch a message back to ACodec, since it doesn't // know that anyone asked to have the buffer emptied and will // be very confused. - - OMX_BUFFERHEADERTYPE *buffer = - findBufferHeader(msg.u.buffer_data.buffer); - bufferSource->codecBufferEmptied(buffer); return; } @@ -1040,6 +1230,43 @@ void OMXNodeInstance::onGetHandleFailed() { // Don't try to acquire mLock here -- in rare circumstances this will hang. void OMXNodeInstance::onEvent( OMX_EVENTTYPE event, OMX_U32 arg1, OMX_U32 arg2) { + const char *arg1String = "??"; + const char *arg2String = "??"; + ADebug::Level level = ADebug::kDebugInternalState; + + switch (event) { + case OMX_EventCmdComplete: + arg1String = asString((OMX_COMMANDTYPE)arg1); + switch (arg1) { + case OMX_CommandStateSet: + arg2String = asString((OMX_STATETYPE)arg2); + level = ADebug::kDebugState; + break; + case OMX_CommandFlush: + case OMX_CommandPortEnable: + { + // bump internal-state debug level for 2 input and output frames + Mutex::Autolock _l(mDebugLock); + bumpDebugLevel_l(2 /* numInputBuffers */, 2 /* numOutputBuffers */); + } + // fall through + default: + arg2String = portString(arg2); + } + break; + case OMX_EventError: + arg1String = asString((OMX_ERRORTYPE)arg1); + level = ADebug::kDebugLifeCycle; + break; + case OMX_EventPortSettingsChanged: + arg2String = asString((OMX_INDEXEXTTYPE)arg2); + // fall through + default: + arg1String = portString(arg1); + } + + CLOGI_(level, onEvent, "%s(%x), %s(%x), %s(%x)", + asString(event), event, arg1String, arg1, arg2String, arg2); const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource()); if (bufferSource != NULL @@ -1097,23 +1324,27 @@ void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) { active.mPortIndex = portIndex; active.mID = id; mActiveBuffers.push(active); + + if (portIndex < NELEM(mNumPortBuffers)) { + ++mNumPortBuffers[portIndex]; + } } void OMXNodeInstance::removeActiveBuffer( OMX_U32 portIndex, OMX::buffer_id id) { - bool found = false; for (size_t i = 0; i < mActiveBuffers.size(); ++i) { if (mActiveBuffers[i].mPortIndex == portIndex - && mActiveBuffers[i].mID == id) { - found = true; + && mActiveBuffers[i].mID == id) { mActiveBuffers.removeItemsAt(i); - break; + + if (portIndex < NELEM(mNumPortBuffers)) { + --mNumPortBuffers[portIndex]; + } + return; } } - if (!found) { - ALOGW("Attempt to remove an active buffer we know nothing about..."); - } + CLOGW("Attempt to remove an active buffer [%#x] we know nothing about...", id); } void OMXNodeInstance::freeActiveBuffers() { @@ -1134,7 +1365,7 @@ OMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) OMX::buffer_id buffer; do { // handle the very unlikely case of ID overflow if (++mBufferIDCount == 0) { - ++mBufferIDCount; + ++mBufferIDCount; } buffer = (OMX::buffer_id)mBufferIDCount; } while (mBufferIDToBufferHeader.indexOfKey(buffer) >= 0); diff --git a/media/libstagefright/omx/SoftOMXComponent.cpp b/media/libstagefright/omx/SoftOMXComponent.cpp index 646cd32..df978f8 100644 --- a/media/libstagefright/omx/SoftOMXComponent.cpp +++ b/media/libstagefright/omx/SoftOMXComponent.cpp @@ -283,7 +283,7 @@ OMX_ERRORTYPE SoftOMXComponent::setConfig( OMX_ERRORTYPE SoftOMXComponent::getExtensionIndex( const char * /* name */, OMX_INDEXTYPE * /* index */) { - return OMX_ErrorUndefined; + return OMX_ErrorUnsupportedIndex; } OMX_ERRORTYPE SoftOMXComponent::useBuffer( diff --git a/media/libstagefright/rtsp/AMPEG2TSAssembler.h b/media/libstagefright/rtsp/AMPEG2TSAssembler.h index 712e18e..f39c2b5 100644 --- a/media/libstagefright/rtsp/AMPEG2TSAssembler.h +++ b/media/libstagefright/rtsp/AMPEG2TSAssembler.h @@ -24,7 +24,7 @@ namespace android { struct AMessage; struct AString; -struct MetaData; +class MetaData; struct AMPEG2TSAssembler : public ARTPAssembler { AMPEG2TSAssembler( diff --git a/media/libstagefright/rtsp/ARawAudioAssembler.h b/media/libstagefright/rtsp/ARawAudioAssembler.h index ed7af08..bc1dea6 100644 --- a/media/libstagefright/rtsp/ARawAudioAssembler.h +++ b/media/libstagefright/rtsp/ARawAudioAssembler.h @@ -24,7 +24,7 @@ namespace android { struct AMessage; struct AString; -struct MetaData; +class MetaData; struct ARawAudioAssembler : public ARTPAssembler { ARawAudioAssembler( diff --git a/media/libstagefright/rtsp/SDPLoader.cpp b/media/libstagefright/rtsp/SDPLoader.cpp index 424badf..a24eb69 100644 --- a/media/libstagefright/rtsp/SDPLoader.cpp +++ b/media/libstagefright/rtsp/SDPLoader.cpp @@ -105,7 +105,7 @@ void SDPLoader::onLoad(const sp<AMessage> &msg) { headers = NULL; } - off64_t sdpSize; + off64_t sdpSize = 0; if (err == OK && !mCancelled) { err = mHTTPDataSource->getSize(&sdpSize); diff --git a/media/libstagefright/tests/Utils_test.cpp b/media/libstagefright/tests/Utils_test.cpp index f2825dd..43e0269 100644 --- a/media/libstagefright/tests/Utils_test.cpp +++ b/media/libstagefright/tests/Utils_test.cpp @@ -24,6 +24,7 @@ #include <unistd.h> #include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/foundation/AStringUtils.h> #include <media/stagefright/foundation/AUtils.h> #include <media/stagefright/Utils.h> @@ -32,6 +33,100 @@ namespace android { class UtilsTest : public ::testing::Test { }; +TEST_F(UtilsTest, TestStringUtils) { + ASSERT_EQ(AStringUtils::Compare("Audio", "AudioExt", 5, false), 0); + ASSERT_EQ(AStringUtils::Compare("Audio", "audiOExt", 5, true), 0); + ASSERT_NE(AStringUtils::Compare("Audio", "audioExt", 5, false), 0); + ASSERT_NE(AStringUtils::Compare("Audio", "AudiOExt", 5, false), 0); + + ASSERT_LT(AStringUtils::Compare("Audio", "AudioExt", 7, false), 0); + ASSERT_LT(AStringUtils::Compare("Audio", "audiOExt", 7, true), 0); + + ASSERT_GT(AStringUtils::Compare("AudioExt", "Audio", 7, false), 0); + ASSERT_GT(AStringUtils::Compare("audiOext", "Audio", 7, true), 0); + + ASSERT_LT(AStringUtils::Compare("Audio", "Video", 5, false), 0); + ASSERT_LT(AStringUtils::Compare("Audio1", "Audio2", 6, false), 0); + ASSERT_LT(AStringUtils::Compare("audio", "VIDEO", 5, true), 0); + ASSERT_LT(AStringUtils::Compare("audio1", "AUDIO2", 6, true), 0); + + ASSERT_GT(AStringUtils::Compare("Video", "Audio", 5, false), 0); + ASSERT_GT(AStringUtils::Compare("Audio2", "Audio1", 6, false), 0); + ASSERT_GT(AStringUtils::Compare("VIDEO", "audio", 5, true), 0); + ASSERT_GT(AStringUtils::Compare("AUDIO2", "audio1", 6, true), 0); + + ASSERT_TRUE(AStringUtils::MatchesGlob("AudioA", 5, "AudioB", 5, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("AudioA", 6, "AudioA", 5, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("AudioA", 5, "AudioA", 6, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("AudioA", 5, "audiOB", 5, false)); + ASSERT_TRUE(AStringUtils::MatchesGlob("AudioA", 5, "audiOB", 5, true)); + ASSERT_FALSE(AStringUtils::MatchesGlob("AudioA", 6, "AudioA", 5, true)); + ASSERT_FALSE(AStringUtils::MatchesGlob("AudioA", 5, "AudioA", 6, true)); + + ASSERT_TRUE(AStringUtils::MatchesGlob("*1", 1, "String8", 6, true)); + ASSERT_TRUE(AStringUtils::MatchesGlob("*1", 1, "String8", 6, false)); + ASSERT_TRUE(AStringUtils::MatchesGlob("*1", 1, "String8", 0, true)); + ASSERT_TRUE(AStringUtils::MatchesGlob("*1", 1, "String8", 0, false)); + + ASSERT_TRUE(AStringUtils::MatchesGlob("*ring1", 5, "String8", 6, false)); + ASSERT_TRUE(AStringUtils::MatchesGlob("*ring2", 5, "STRING8", 6, true)); + ASSERT_FALSE(AStringUtils::MatchesGlob("*ring4", 5, "StRing8", 6, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("*ring5", 5, "StrinG8", 6, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("*ring8", 5, "String8", 7, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("*ring8", 5, "String8", 7, true)); + + ASSERT_TRUE(AStringUtils::MatchesGlob("Str*1", 4, "String8", 6, false)); + ASSERT_TRUE(AStringUtils::MatchesGlob("Str*2", 4, "STRING8", 6, true)); + ASSERT_FALSE(AStringUtils::MatchesGlob("Str*3", 4, "string8", 6, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("Str*4", 4, "StRing8", 6, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("Str*5", 4, "AString8", 7, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("Str*6", 4, "AString8", 7, true)); + + ASSERT_TRUE(AStringUtils::MatchesGlob("Str*ng1", 6, "String8", 6, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng2", 6, "string8", 6, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng3", 6, "StRing8", 6, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng4", 6, "StriNg8", 6, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng5", 6, "StrinG8", 6, false)); + ASSERT_TRUE(AStringUtils::MatchesGlob("Str*ng6", 6, "STRING8", 6, true)); + ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng8", 6, "AString8", 7, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng1", 6, "String16", 7, false)); + ASSERT_TRUE(AStringUtils::MatchesGlob("Str*ing9", 7, "String8", 6, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ringA", 8, "String8", 6, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng8", 6, "AString8", 7, true)); + ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng1", 6, "String16", 7, true)); + ASSERT_TRUE(AStringUtils::MatchesGlob("Str*ing9", 7, "STRING8", 6, true)); + ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ringA", 8, "String8", 6, true)); + + ASSERT_TRUE(AStringUtils::MatchesGlob("*str*str1", 8, "bestrestroom", 9, false)); + ASSERT_TRUE(AStringUtils::MatchesGlob("*str*str1", 8, "bestrestrestroom", 13, false)); + ASSERT_FALSE(AStringUtils::MatchesGlob("*str*stro", 8, "bestrestrestroom", 14, false)); + ASSERT_TRUE(AStringUtils::MatchesGlob("*str*str*1", 9, "bestrestrestroom", 14, false)); + ASSERT_TRUE(AStringUtils::MatchesGlob("*str*str1", 8, "beSTReSTRoom", 9, true)); + ASSERT_TRUE(AStringUtils::MatchesGlob("*str*str1", 8, "beSTRestreSTRoom", 13, true)); + ASSERT_FALSE(AStringUtils::MatchesGlob("*str*stro", 8, "bestreSTReSTRoom", 14, true)); + ASSERT_TRUE(AStringUtils::MatchesGlob("*str*str*1", 9, "bestreSTReSTRoom", 14, true)); +} + +TEST_F(UtilsTest, TestDebug) { +#define LVL(x) (ADebug::Level)(x) + ASSERT_EQ(ADebug::GetDebugLevelFromString("video", "", LVL(5)), LVL(5)); + ASSERT_EQ(ADebug::GetDebugLevelFromString("video", " \t \n ", LVL(2)), LVL(2)); + ASSERT_EQ(ADebug::GetDebugLevelFromString("video", "3", LVL(5)), LVL(3)); + ASSERT_EQ(ADebug::GetDebugLevelFromString("video", "3:*deo", LVL(5)), LVL(3)); + ASSERT_EQ(ADebug::GetDebugLevelFromString( + "video", "\t\n 3 \t\n:\t\n video \t\n", LVL(5)), LVL(3)); + ASSERT_EQ(ADebug::GetDebugLevelFromString("video", "3:*deo,2:vid*", LVL(5)), LVL(2)); + ASSERT_EQ(ADebug::GetDebugLevelFromString( + "avideo", "\t\n 3 \t\n:\t\n avideo \t\n,\t\n 2 \t\n:\t\n video \t\n", LVL(5)), LVL(3)); + ASSERT_EQ(ADebug::GetDebugLevelFromString( + "audio.omx", "4:*omx,3:*d*o*,2:audio*", LVL(5)), LVL(2)); + ASSERT_EQ(ADebug::GetDebugLevelFromString( + "video.omx", "4:*omx,3:*d*o*,2:audio*", LVL(5)), LVL(3)); + ASSERT_EQ(ADebug::GetDebugLevelFromString("video", "4:*omx,3:*d*o*,2:audio*", LVL(5)), LVL(3)); + ASSERT_EQ(ADebug::GetDebugLevelFromString("omx", "4:*omx,3:*d*o*,2:audio*", LVL(5)), LVL(4)); +#undef LVL +} + TEST_F(UtilsTest, TestFourCC) { ASSERT_EQ(FOURCC('s', 't', 'm' , 'u'), 'stmu'); } diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp index e6e19e3..052b700 100644 --- a/media/mtp/MtpDataPacket.cpp +++ b/media/mtp/MtpDataPacket.cpp @@ -51,104 +51,178 @@ void MtpDataPacket::setTransactionID(MtpTransactionID id) { MtpPacket::putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id); } -uint16_t MtpDataPacket::getUInt16() { +bool MtpDataPacket::getUInt8(uint8_t& value) { + if (mPacketSize - mOffset < sizeof(value)) + return false; + value = mBuffer[mOffset++]; + return true; +} + +bool MtpDataPacket::getUInt16(uint16_t& value) { + if (mPacketSize - mOffset < sizeof(value)) + return false; int offset = mOffset; - uint16_t result = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8); - mOffset += 2; - return result; + value = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8); + mOffset += sizeof(value); + return true; } -uint32_t MtpDataPacket::getUInt32() { +bool MtpDataPacket::getUInt32(uint32_t& value) { + if (mPacketSize - mOffset < sizeof(value)) + return false; int offset = mOffset; - uint32_t result = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) | + value = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) | ((uint32_t)mBuffer[offset + 2] << 16) | ((uint32_t)mBuffer[offset + 3] << 24); - mOffset += 4; - return result; + mOffset += sizeof(value); + return true; } -uint64_t MtpDataPacket::getUInt64() { +bool MtpDataPacket::getUInt64(uint64_t& value) { + if (mPacketSize - mOffset < sizeof(value)) + return false; int offset = mOffset; - uint64_t result = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) | + value = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) | ((uint64_t)mBuffer[offset + 2] << 16) | ((uint64_t)mBuffer[offset + 3] << 24) | ((uint64_t)mBuffer[offset + 4] << 32) | ((uint64_t)mBuffer[offset + 5] << 40) | ((uint64_t)mBuffer[offset + 6] << 48) | ((uint64_t)mBuffer[offset + 7] << 56); - mOffset += 8; - return result; + mOffset += sizeof(value); + return true; } -void MtpDataPacket::getUInt128(uint128_t& value) { - value[0] = getUInt32(); - value[1] = getUInt32(); - value[2] = getUInt32(); - value[3] = getUInt32(); +bool MtpDataPacket::getUInt128(uint128_t& value) { + return getUInt32(value[0]) && getUInt32(value[1]) && getUInt32(value[2]) && getUInt32(value[3]); } -void MtpDataPacket::getString(MtpStringBuffer& string) +bool MtpDataPacket::getString(MtpStringBuffer& string) { - string.readFromPacket(this); + return string.readFromPacket(this); } Int8List* MtpDataPacket::getAInt8() { + uint32_t count; + if (!getUInt32(count)) + return NULL; Int8List* result = new Int8List; - int count = getUInt32(); - for (int i = 0; i < count; i++) - result->push(getInt8()); + for (uint32_t i = 0; i < count; i++) { + int8_t value; + if (!getInt8(value)) { + delete result; + return NULL; + } + result->push(value); + } return result; } UInt8List* MtpDataPacket::getAUInt8() { + uint32_t count; + if (!getUInt32(count)) + return NULL; UInt8List* result = new UInt8List; - int count = getUInt32(); - for (int i = 0; i < count; i++) - result->push(getUInt8()); + for (uint32_t i = 0; i < count; i++) { + uint8_t value; + if (!getUInt8(value)) { + delete result; + return NULL; + } + result->push(value); + } return result; } Int16List* MtpDataPacket::getAInt16() { + uint32_t count; + if (!getUInt32(count)) + return NULL; Int16List* result = new Int16List; - int count = getUInt32(); - for (int i = 0; i < count; i++) - result->push(getInt16()); + for (uint32_t i = 0; i < count; i++) { + int16_t value; + if (!getInt16(value)) { + delete result; + return NULL; + } + result->push(value); + } return result; } UInt16List* MtpDataPacket::getAUInt16() { + uint32_t count; + if (!getUInt32(count)) + return NULL; UInt16List* result = new UInt16List; - int count = getUInt32(); - for (int i = 0; i < count; i++) - result->push(getUInt16()); + for (uint32_t i = 0; i < count; i++) { + uint16_t value; + if (!getUInt16(value)) { + delete result; + return NULL; + } + result->push(value); + } return result; } Int32List* MtpDataPacket::getAInt32() { + uint32_t count; + if (!getUInt32(count)) + return NULL; Int32List* result = new Int32List; - int count = getUInt32(); - for (int i = 0; i < count; i++) - result->push(getInt32()); + for (uint32_t i = 0; i < count; i++) { + int32_t value; + if (!getInt32(value)) { + delete result; + return NULL; + } + result->push(value); + } return result; } UInt32List* MtpDataPacket::getAUInt32() { + uint32_t count; + if (!getUInt32(count)) + return NULL; UInt32List* result = new UInt32List; - int count = getUInt32(); - for (int i = 0; i < count; i++) - result->push(getUInt32()); + for (uint32_t i = 0; i < count; i++) { + uint32_t value; + if (!getUInt32(value)) { + delete result; + return NULL; + } + result->push(value); + } return result; } Int64List* MtpDataPacket::getAInt64() { + uint32_t count; + if (!getUInt32(count)) + return NULL; Int64List* result = new Int64List; - int count = getUInt32(); - for (int i = 0; i < count; i++) - result->push(getInt64()); + for (uint32_t i = 0; i < count; i++) { + int64_t value; + if (!getInt64(value)) { + delete result; + return NULL; + } + result->push(value); + } return result; } UInt64List* MtpDataPacket::getAUInt64() { + uint32_t count; + if (!getUInt32(count)) + return NULL; UInt64List* result = new UInt64List; - int count = getUInt32(); - for (int i = 0; i < count; i++) - result->push(getUInt64()); + for (uint32_t i = 0; i < count; i++) { + uint64_t value; + if (!getUInt64(value)) { + delete result; + return NULL; + } + result->push(value); + } return result; } diff --git a/media/mtp/MtpDataPacket.h b/media/mtp/MtpDataPacket.h index 2b81063..13d3bd9 100644 --- a/media/mtp/MtpDataPacket.h +++ b/media/mtp/MtpDataPacket.h @@ -30,7 +30,7 @@ class MtpStringBuffer; class MtpDataPacket : public MtpPacket { private: // current offset for get/put methods - int mOffset; + size_t mOffset; public: MtpDataPacket(); @@ -42,17 +42,18 @@ public: void setTransactionID(MtpTransactionID id); inline const uint8_t* getData() const { return mBuffer + MTP_CONTAINER_HEADER_SIZE; } - inline uint8_t getUInt8() { return (uint8_t)mBuffer[mOffset++]; } - inline int8_t getInt8() { return (int8_t)mBuffer[mOffset++]; } - uint16_t getUInt16(); - inline int16_t getInt16() { return (int16_t)getUInt16(); } - uint32_t getUInt32(); - inline int32_t getInt32() { return (int32_t)getUInt32(); } - uint64_t getUInt64(); - inline int64_t getInt64() { return (int64_t)getUInt64(); } - void getUInt128(uint128_t& value); - inline void getInt128(int128_t& value) { getUInt128((uint128_t&)value); } - void getString(MtpStringBuffer& string); + + bool getUInt8(uint8_t& value); + inline bool getInt8(int8_t& value) { return getUInt8((uint8_t&)value); } + bool getUInt16(uint16_t& value); + inline bool getInt16(int16_t& value) { return getUInt16((uint16_t&)value); } + bool getUInt32(uint32_t& value); + inline bool getInt32(int32_t& value) { return getUInt32((uint32_t&)value); } + bool getUInt64(uint64_t& value); + inline bool getInt64(int64_t& value) { return getUInt64((uint64_t&)value); } + bool getUInt128(uint128_t& value); + inline bool getInt128(int128_t& value) { return getUInt128((uint128_t&)value); } + bool getString(MtpStringBuffer& string); Int8List* getAInt8(); UInt8List* getAUInt8(); diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp index 96331b5..3eafd6f 100644 --- a/media/mtp/MtpDevice.cpp +++ b/media/mtp/MtpDevice.cpp @@ -322,8 +322,10 @@ MtpDeviceInfo* MtpDevice::getDeviceInfo() { MtpResponseCode ret = readResponse(); if (ret == MTP_RESPONSE_OK) { MtpDeviceInfo* info = new MtpDeviceInfo; - info->read(mData); - return info; + if (info->read(mData)) + return info; + else + delete info; } return NULL; } @@ -355,8 +357,10 @@ MtpStorageInfo* MtpDevice::getStorageInfo(MtpStorageID storageID) { MtpResponseCode ret = readResponse(); if (ret == MTP_RESPONSE_OK) { MtpStorageInfo* info = new MtpStorageInfo(storageID); - info->read(mData); - return info; + if (info->read(mData)) + return info; + else + delete info; } return NULL; } @@ -394,8 +398,10 @@ MtpObjectInfo* MtpDevice::getObjectInfo(MtpObjectHandle handle) { MtpResponseCode ret = readResponse(); if (ret == MTP_RESPONSE_OK) { MtpObjectInfo* info = new MtpObjectInfo(handle); - info->read(mData); - return info; + if (info->read(mData)) + return info; + else + delete info; } return NULL; } @@ -556,8 +562,10 @@ MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) { MtpResponseCode ret = readResponse(); if (ret == MTP_RESPONSE_OK) { MtpProperty* property = new MtpProperty; - property->read(mData); - return property; + if (property->read(mData)) + return property; + else + delete property; } return NULL; } @@ -575,15 +583,17 @@ MtpProperty* MtpDevice::getObjectPropDesc(MtpObjectProperty code, MtpObjectForma MtpResponseCode ret = readResponse(); if (ret == MTP_RESPONSE_OK) { MtpProperty* property = new MtpProperty; - property->read(mData); - return property; + if (property->read(mData)) + return property; + else + delete property; } return NULL; } bool MtpDevice::readObject(MtpObjectHandle handle, bool (* callback)(void* data, int offset, int length, void* clientData), - int objectSize, void* clientData) { + size_t objectSize, void* clientData) { Mutex::Autolock autoLock(mMutex); bool result = false; diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h index b69203e..9b0acbf 100644 --- a/media/mtp/MtpDevice.h +++ b/media/mtp/MtpDevice.h @@ -98,7 +98,7 @@ public: bool readObject(MtpObjectHandle handle, bool (* callback)(void* data, int offset, int length, void* clientData), - int objectSize, void* clientData); + size_t objectSize, void* clientData); bool readObject(MtpObjectHandle handle, const char* destPath, int group, int perm); diff --git a/media/mtp/MtpDeviceInfo.cpp b/media/mtp/MtpDeviceInfo.cpp index 108e2b8..3e1dff7 100644 --- a/media/mtp/MtpDeviceInfo.cpp +++ b/media/mtp/MtpDeviceInfo.cpp @@ -28,7 +28,7 @@ MtpDeviceInfo::MtpDeviceInfo() mVendorExtensionID(0), mVendorExtensionVersion(0), mVendorExtensionDesc(NULL), - mFunctionalCode(0), + mFunctionalMode(0), mOperations(NULL), mEvents(NULL), mDeviceProperties(NULL), @@ -59,39 +59,46 @@ MtpDeviceInfo::~MtpDeviceInfo() { free(mSerial); } -void MtpDeviceInfo::read(MtpDataPacket& packet) { +bool MtpDeviceInfo::read(MtpDataPacket& packet) { MtpStringBuffer string; // read the device info - mStandardVersion = packet.getUInt16(); - mVendorExtensionID = packet.getUInt32(); - mVendorExtensionVersion = packet.getUInt16(); + if (!packet.getUInt16(mStandardVersion)) return false; + if (!packet.getUInt32(mVendorExtensionID)) return false; + if (!packet.getUInt16(mVendorExtensionVersion)) return false; - packet.getString(string); + if (!packet.getString(string)) return false; mVendorExtensionDesc = strdup((const char *)string); - mFunctionalCode = packet.getUInt16(); + if (!packet.getUInt16(mFunctionalMode)) return false; mOperations = packet.getAUInt16(); + if (!mOperations) return false; mEvents = packet.getAUInt16(); + if (!mEvents) return false; mDeviceProperties = packet.getAUInt16(); + if (!mDeviceProperties) return false; mCaptureFormats = packet.getAUInt16(); + if (!mCaptureFormats) return false; mPlaybackFormats = packet.getAUInt16(); + if (!mCaptureFormats) return false; - packet.getString(string); + if (!packet.getString(string)) return false; mManufacturer = strdup((const char *)string); - packet.getString(string); + if (!packet.getString(string)) return false; mModel = strdup((const char *)string); - packet.getString(string); + if (!packet.getString(string)) return false; mVersion = strdup((const char *)string); - packet.getString(string); + if (!packet.getString(string)) return false; mSerial = strdup((const char *)string); + + return true; } void MtpDeviceInfo::print() { ALOGV("Device Info:\n\tmStandardVersion: %d\n\tmVendorExtensionID: %d\n\tmVendorExtensionVersiony: %d\n", mStandardVersion, mVendorExtensionID, mVendorExtensionVersion); - ALOGV("\tmVendorExtensionDesc: %s\n\tmFunctionalCode: %d\n\tmManufacturer: %s\n\tmModel: %s\n\tmVersion: %s\n\tmSerial: %s\n", - mVendorExtensionDesc, mFunctionalCode, mManufacturer, mModel, mVersion, mSerial); + ALOGV("\tmVendorExtensionDesc: %s\n\tmFunctionalMode: %d\n\tmManufacturer: %s\n\tmModel: %s\n\tmVersion: %s\n\tmSerial: %s\n", + mVendorExtensionDesc, mFunctionalMode, mManufacturer, mModel, mVersion, mSerial); } } // namespace android diff --git a/media/mtp/MtpDeviceInfo.h b/media/mtp/MtpDeviceInfo.h index 2abaa10..bcda9a5 100644 --- a/media/mtp/MtpDeviceInfo.h +++ b/media/mtp/MtpDeviceInfo.h @@ -29,7 +29,7 @@ public: uint32_t mVendorExtensionID; uint16_t mVendorExtensionVersion; char* mVendorExtensionDesc; - uint16_t mFunctionalCode; + uint16_t mFunctionalMode; UInt16List* mOperations; UInt16List* mEvents; MtpDevicePropertyList* mDeviceProperties; @@ -44,7 +44,7 @@ public: MtpDeviceInfo(); virtual ~MtpDeviceInfo(); - void read(MtpDataPacket& packet); + bool read(MtpDataPacket& packet); void print(); }; diff --git a/media/mtp/MtpObjectInfo.cpp b/media/mtp/MtpObjectInfo.cpp index cd15343..0573104 100644 --- a/media/mtp/MtpObjectInfo.cpp +++ b/media/mtp/MtpObjectInfo.cpp @@ -55,39 +55,41 @@ MtpObjectInfo::~MtpObjectInfo() { free(mKeywords); } -void MtpObjectInfo::read(MtpDataPacket& packet) { +bool MtpObjectInfo::read(MtpDataPacket& packet) { MtpStringBuffer string; time_t time; - mStorageID = packet.getUInt32(); - mFormat = packet.getUInt16(); - mProtectionStatus = packet.getUInt16(); - mCompressedSize = packet.getUInt32(); - mThumbFormat = packet.getUInt16(); - mThumbCompressedSize = packet.getUInt32(); - mThumbPixWidth = packet.getUInt32(); - mThumbPixHeight = packet.getUInt32(); - mImagePixWidth = packet.getUInt32(); - mImagePixHeight = packet.getUInt32(); - mImagePixDepth = packet.getUInt32(); - mParent = packet.getUInt32(); - mAssociationType = packet.getUInt16(); - mAssociationDesc = packet.getUInt32(); - mSequenceNumber = packet.getUInt32(); + if (!packet.getUInt32(mStorageID)) return false; + if (!packet.getUInt16(mFormat)) return false; + if (!packet.getUInt16(mProtectionStatus)) return false; + if (!packet.getUInt32(mCompressedSize)) return false; + if (!packet.getUInt16(mThumbFormat)) return false; + if (!packet.getUInt32(mThumbCompressedSize)) return false; + if (!packet.getUInt32(mThumbPixWidth)) return false; + if (!packet.getUInt32(mThumbPixHeight)) return false; + if (!packet.getUInt32(mImagePixWidth)) return false; + if (!packet.getUInt32(mImagePixHeight)) return false; + if (!packet.getUInt32(mImagePixDepth)) return false; + if (!packet.getUInt32(mParent)) return false; + if (!packet.getUInt16(mAssociationType)) return false; + if (!packet.getUInt32(mAssociationDesc)) return false; + if (!packet.getUInt32(mSequenceNumber)) return false; - packet.getString(string); + if (!packet.getString(string)) return false; mName = strdup((const char *)string); - packet.getString(string); + if (!packet.getString(string)) return false; if (parseDateTime((const char*)string, time)) mDateCreated = time; - packet.getString(string); + if (!packet.getString(string)) return false; if (parseDateTime((const char*)string, time)) mDateModified = time; - packet.getString(string); + if (!packet.getString(string)) return false; mKeywords = strdup((const char *)string); + + return true; } void MtpObjectInfo::print() { diff --git a/media/mtp/MtpObjectInfo.h b/media/mtp/MtpObjectInfo.h index c7a449c..86780f1 100644 --- a/media/mtp/MtpObjectInfo.h +++ b/media/mtp/MtpObjectInfo.h @@ -50,7 +50,7 @@ public: MtpObjectInfo(MtpObjectHandle handle); virtual ~MtpObjectInfo(); - void read(MtpDataPacket& packet); + bool read(MtpDataPacket& packet); void print(); }; diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp index dd07843..bab1335 100644 --- a/media/mtp/MtpPacket.cpp +++ b/media/mtp/MtpPacket.cpp @@ -52,7 +52,7 @@ void MtpPacket::reset() { memset(mBuffer, 0, mBufferSize); } -void MtpPacket::allocate(int length) { +void MtpPacket::allocate(size_t length) { if (length > mBufferSize) { int newLength = length + mAllocationIncrement; mBuffer = (uint8_t *)realloc(mBuffer, newLength); diff --git a/media/mtp/MtpPacket.h b/media/mtp/MtpPacket.h index 0ffb1d3..037722a 100644 --- a/media/mtp/MtpPacket.h +++ b/media/mtp/MtpPacket.h @@ -28,11 +28,11 @@ class MtpPacket { protected: uint8_t* mBuffer; // current size of the buffer - int mBufferSize; + size_t mBufferSize; // number of bytes to add when resizing the buffer - int mAllocationIncrement; + size_t mAllocationIncrement; // size of the data in the packet - int mPacketSize; + size_t mPacketSize; public: MtpPacket(int bufferSize); @@ -41,7 +41,7 @@ public: // sets packet size to the default container size and sets buffer to zero virtual void reset(); - void allocate(int length); + void allocate(size_t length); void dump(); void copyFrom(const MtpPacket& src); diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp index c500901..d58e2a4 100644 --- a/media/mtp/MtpProperty.cpp +++ b/media/mtp/MtpProperty.cpp @@ -106,15 +106,15 @@ MtpProperty::~MtpProperty() { free(mMinimumValue.str); free(mMaximumValue.str); if (mDefaultArrayValues) { - for (int i = 0; i < mDefaultArrayLength; i++) + for (uint32_t i = 0; i < mDefaultArrayLength; i++) free(mDefaultArrayValues[i].str); } if (mCurrentArrayValues) { - for (int i = 0; i < mCurrentArrayLength; i++) + for (uint32_t i = 0; i < mCurrentArrayLength; i++) free(mCurrentArrayValues[i].str); } if (mEnumValues) { - for (int i = 0; i < mEnumLength; i++) + for (uint16_t i = 0; i < mEnumLength; i++) free(mEnumValues[i].str); } } @@ -123,11 +123,14 @@ MtpProperty::~MtpProperty() { delete[] mEnumValues; } -void MtpProperty::read(MtpDataPacket& packet) { - mCode = packet.getUInt16(); +bool MtpProperty::read(MtpDataPacket& packet) { + uint8_t temp8; + + if (!packet.getUInt16(mCode)) return false; bool deviceProp = isDeviceProperty(); - mType = packet.getUInt16(); - mWriteable = (packet.getUInt8() == 1); + if (!packet.getUInt16(mType)) return false; + if (!packet.getUInt8(temp8)) return false; + mWriteable = (temp8 == 1); switch (mType) { case MTP_TYPE_AINT8: case MTP_TYPE_AUINT8: @@ -140,28 +143,36 @@ void MtpProperty::read(MtpDataPacket& packet) { case MTP_TYPE_AINT128: case MTP_TYPE_AUINT128: mDefaultArrayValues = readArrayValues(packet, mDefaultArrayLength); - if (deviceProp) + if (!mDefaultArrayValues) return false; + if (deviceProp) { mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength); + if (!mCurrentArrayValues) return false; + } break; default: - readValue(packet, mDefaultValue); - if (deviceProp) - readValue(packet, mCurrentValue); + if (!readValue(packet, mDefaultValue)) return false; + if (deviceProp) { + if (!readValue(packet, mCurrentValue)) return false; + } } - if (!deviceProp) - mGroupCode = packet.getUInt32(); - mFormFlag = packet.getUInt8(); + if (!deviceProp) { + if (!packet.getUInt32(mGroupCode)) return false; + } + if (!packet.getUInt8(mFormFlag)) return false; if (mFormFlag == kFormRange) { - readValue(packet, mMinimumValue); - readValue(packet, mMaximumValue); - readValue(packet, mStepSize); + if (!readValue(packet, mMinimumValue)) return false; + if (!readValue(packet, mMaximumValue)) return false; + if (!readValue(packet, mStepSize)) return false; } else if (mFormFlag == kFormEnum) { - mEnumLength = packet.getUInt16(); + if (!packet.getUInt16(mEnumLength)) return false; mEnumValues = new MtpPropertyValue[mEnumLength]; - for (int i = 0; i < mEnumLength; i++) - readValue(packet, mEnumValues[i]); + for (int i = 0; i < mEnumLength; i++) { + if (!readValue(packet, mEnumValues[i])) return false; + } } + + return true; } void MtpProperty::write(MtpDataPacket& packet) { @@ -409,57 +420,59 @@ void MtpProperty::print(MtpPropertyValue& value, MtpString& buffer) { } } -void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) { +bool MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) { MtpStringBuffer stringBuffer; switch (mType) { case MTP_TYPE_INT8: case MTP_TYPE_AINT8: - value.u.i8 = packet.getInt8(); + if (!packet.getInt8(value.u.i8)) return false; break; case MTP_TYPE_UINT8: case MTP_TYPE_AUINT8: - value.u.u8 = packet.getUInt8(); + if (!packet.getUInt8(value.u.u8)) return false; break; case MTP_TYPE_INT16: case MTP_TYPE_AINT16: - value.u.i16 = packet.getInt16(); + if (!packet.getInt16(value.u.i16)) return false; break; case MTP_TYPE_UINT16: case MTP_TYPE_AUINT16: - value.u.u16 = packet.getUInt16(); + if (!packet.getUInt16(value.u.u16)) return false; break; case MTP_TYPE_INT32: case MTP_TYPE_AINT32: - value.u.i32 = packet.getInt32(); + if (!packet.getInt32(value.u.i32)) return false; break; case MTP_TYPE_UINT32: case MTP_TYPE_AUINT32: - value.u.u32 = packet.getUInt32(); + if (!packet.getUInt32(value.u.u32)) return false; break; case MTP_TYPE_INT64: case MTP_TYPE_AINT64: - value.u.i64 = packet.getInt64(); + if (!packet.getInt64(value.u.i64)) return false; break; case MTP_TYPE_UINT64: case MTP_TYPE_AUINT64: - value.u.u64 = packet.getUInt64(); + if (!packet.getUInt64(value.u.u64)) return false; break; case MTP_TYPE_INT128: case MTP_TYPE_AINT128: - packet.getInt128(value.u.i128); + if (!packet.getInt128(value.u.i128)) return false; break; case MTP_TYPE_UINT128: case MTP_TYPE_AUINT128: - packet.getUInt128(value.u.u128); + if (!packet.getUInt128(value.u.u128)) return false; break; case MTP_TYPE_STR: - packet.getString(stringBuffer); + if (!packet.getString(stringBuffer)) return false; value.str = strdup(stringBuffer); break; default: ALOGE("unknown type %04X in MtpProperty::readValue", mType); + return false; } + return true; } void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) { @@ -517,8 +530,9 @@ void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) { } } -MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& length) { - length = packet.getUInt32(); +MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, uint32_t& length) { + if (!packet.getUInt32(length)) return NULL; + // Fail if resulting array is over 2GB. This is because the maximum array // size may be less than SIZE_MAX on some platforms. if ( CC_UNLIKELY( @@ -528,14 +542,17 @@ MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& lengt return NULL; } MtpPropertyValue* result = new MtpPropertyValue[length]; - for (int i = 0; i < length; i++) - readValue(packet, result[i]); + for (uint32_t i = 0; i < length; i++) + if (!readValue(packet, result[i])) { + delete result; + return NULL; + } return result; } -void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length) { +void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, uint32_t length) { packet.putUInt32(length); - for (int i = 0; i < length; i++) + for (uint32_t i = 0; i < length; i++) writeValue(packet, values[i]); } diff --git a/media/mtp/MtpProperty.h b/media/mtp/MtpProperty.h index 06ca56e..2e2ead1 100644 --- a/media/mtp/MtpProperty.h +++ b/media/mtp/MtpProperty.h @@ -49,9 +49,9 @@ public: MtpPropertyValue mCurrentValue; // for array types - int mDefaultArrayLength; + uint32_t mDefaultArrayLength; MtpPropertyValue* mDefaultArrayValues; - int mCurrentArrayLength; + uint32_t mCurrentArrayLength; MtpPropertyValue* mCurrentArrayValues; enum { @@ -70,7 +70,7 @@ public: MtpPropertyValue mStepSize; // for enum form - int mEnumLength; + uint16_t mEnumLength; MtpPropertyValue* mEnumValues; public: @@ -83,7 +83,7 @@ public: inline MtpPropertyCode getPropertyCode() const { return mCode; } - void read(MtpDataPacket& packet); + bool read(MtpDataPacket& packet); void write(MtpDataPacket& packet); void setDefaultValue(const uint16_t* string); @@ -102,11 +102,11 @@ public: } private: - void readValue(MtpDataPacket& packet, MtpPropertyValue& value); + bool readValue(MtpDataPacket& packet, MtpPropertyValue& value); void writeValue(MtpDataPacket& packet, MtpPropertyValue& value); - MtpPropertyValue* readArrayValues(MtpDataPacket& packet, int& length); + MtpPropertyValue* readArrayValues(MtpDataPacket& packet, uint32_t& length); void writeArrayValues(MtpDataPacket& packet, - MtpPropertyValue* values, int length); + MtpPropertyValue* values, uint32_t length); }; }; // namespace android diff --git a/media/mtp/MtpRequestPacket.cpp b/media/mtp/MtpRequestPacket.cpp index 0e58e01..40b11b0 100644 --- a/media/mtp/MtpRequestPacket.cpp +++ b/media/mtp/MtpRequestPacket.cpp @@ -27,7 +27,8 @@ namespace android { MtpRequestPacket::MtpRequestPacket() - : MtpPacket(512) + : MtpPacket(512), + mParameterCount(0) { } @@ -37,10 +38,21 @@ MtpRequestPacket::~MtpRequestPacket() { #ifdef MTP_DEVICE int MtpRequestPacket::read(int fd) { int ret = ::read(fd, mBuffer, mBufferSize); - if (ret >= 0) + if (ret < 0) { + // file read error + return ret; + } + + // request packet should have 12 byte header followed by 0 to 5 32-bit arguments + if (ret >= MTP_CONTAINER_HEADER_SIZE + && ret <= MTP_CONTAINER_HEADER_SIZE + 5 * sizeof(uint32_t) + && ((ret - MTP_CONTAINER_HEADER_SIZE) & 3) == 0) { mPacketSize = ret; - else - mPacketSize = 0; + mParameterCount = (ret - MTP_CONTAINER_HEADER_SIZE) / sizeof(uint32_t); + } else { + ALOGE("Malformed MTP request packet"); + ret = -1; + } return ret; } #endif diff --git a/media/mtp/MtpRequestPacket.h b/media/mtp/MtpRequestPacket.h index 1201f11..79b798d 100644 --- a/media/mtp/MtpRequestPacket.h +++ b/media/mtp/MtpRequestPacket.h @@ -43,6 +43,10 @@ public: inline MtpOperationCode getOperationCode() const { return getContainerCode(); } inline void setOperationCode(MtpOperationCode code) { return setContainerCode(code); } + inline int getParameterCount() const { return mParameterCount; } + +private: + int mParameterCount; }; }; // namespace android diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp index aa43967..931a09d 100644 --- a/media/mtp/MtpServer.cpp +++ b/media/mtp/MtpServer.cpp @@ -495,6 +495,9 @@ MtpResponseCode MtpServer::doOpenSession() { mResponse.setParameter(1, mSessionID); return MTP_RESPONSE_SESSION_ALREADY_OPEN; } + if (mRequest.getParameterCount() < 1) + return MTP_RESPONSE_INVALID_PARAMETER; + mSessionID = mRequest.getParameter(1); mSessionOpen = true; @@ -529,6 +532,9 @@ MtpResponseCode MtpServer::doGetStorageInfo() { if (!mSessionOpen) return MTP_RESPONSE_SESSION_NOT_OPEN; + if (mRequest.getParameterCount() < 1) + return MTP_RESPONSE_INVALID_PARAMETER; + MtpStorageID id = mRequest.getParameter(1); MtpStorage* storage = getStorage(id); if (!storage) @@ -550,6 +556,8 @@ MtpResponseCode MtpServer::doGetStorageInfo() { MtpResponseCode MtpServer::doGetObjectPropsSupported() { if (!mSessionOpen) return MTP_RESPONSE_SESSION_NOT_OPEN; + if (mRequest.getParameterCount() < 1) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectFormat format = mRequest.getParameter(1); MtpObjectPropertyList* properties = mDatabase->getSupportedObjectProperties(format); mData.putAUInt16(properties); @@ -560,6 +568,8 @@ MtpResponseCode MtpServer::doGetObjectPropsSupported() { MtpResponseCode MtpServer::doGetObjectHandles() { if (!mSessionOpen) return MTP_RESPONSE_SESSION_NOT_OPEN; + if (mRequest.getParameterCount() < 3) + return MTP_RESPONSE_INVALID_PARAMETER; MtpStorageID storageID = mRequest.getParameter(1); // 0xFFFFFFFF for all storage MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent @@ -577,6 +587,8 @@ MtpResponseCode MtpServer::doGetObjectHandles() { MtpResponseCode MtpServer::doGetNumObjects() { if (!mSessionOpen) return MTP_RESPONSE_SESSION_NOT_OPEN; + if (mRequest.getParameterCount() < 3) + return MTP_RESPONSE_INVALID_PARAMETER; MtpStorageID storageID = mRequest.getParameter(1); // 0xFFFFFFFF for all storage MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent @@ -599,6 +611,8 @@ MtpResponseCode MtpServer::doGetObjectReferences() { return MTP_RESPONSE_SESSION_NOT_OPEN; if (!hasStorage()) return MTP_RESPONSE_INVALID_OBJECT_HANDLE; + if (mRequest.getParameterCount() < 1) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectHandle handle = mRequest.getParameter(1); // FIXME - check for invalid object handle @@ -617,9 +631,13 @@ MtpResponseCode MtpServer::doSetObjectReferences() { return MTP_RESPONSE_SESSION_NOT_OPEN; if (!hasStorage()) return MTP_RESPONSE_INVALID_OBJECT_HANDLE; + if (mRequest.getParameterCount() < 1) + return MTP_RESPONSE_INVALID_PARAMETER; MtpStorageID handle = mRequest.getParameter(1); MtpObjectHandleList* references = mData.getAUInt32(); + if (!references) + return MTP_RESPONSE_INVALID_PARAMETER; MtpResponseCode result = mDatabase->setObjectReferences(handle, references); delete references; return result; @@ -628,6 +646,8 @@ MtpResponseCode MtpServer::doSetObjectReferences() { MtpResponseCode MtpServer::doGetObjectPropValue() { if (!hasStorage()) return MTP_RESPONSE_INVALID_OBJECT_HANDLE; + if (mRequest.getParameterCount() < 2) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectHandle handle = mRequest.getParameter(1); MtpObjectProperty property = mRequest.getParameter(2); ALOGV("GetObjectPropValue %d %s\n", handle, @@ -639,6 +659,8 @@ MtpResponseCode MtpServer::doGetObjectPropValue() { MtpResponseCode MtpServer::doSetObjectPropValue() { if (!hasStorage()) return MTP_RESPONSE_INVALID_OBJECT_HANDLE; + if (mRequest.getParameterCount() < 2) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectHandle handle = mRequest.getParameter(1); MtpObjectProperty property = mRequest.getParameter(2); ALOGV("SetObjectPropValue %d %s\n", handle, @@ -648,6 +670,8 @@ MtpResponseCode MtpServer::doSetObjectPropValue() { } MtpResponseCode MtpServer::doGetDevicePropValue() { + if (mRequest.getParameterCount() < 1) + return MTP_RESPONSE_INVALID_PARAMETER; MtpDeviceProperty property = mRequest.getParameter(1); ALOGV("GetDevicePropValue %s\n", MtpDebug::getDevicePropCodeName(property)); @@ -656,6 +680,8 @@ MtpResponseCode MtpServer::doGetDevicePropValue() { } MtpResponseCode MtpServer::doSetDevicePropValue() { + if (mRequest.getParameterCount() < 1) + return MTP_RESPONSE_INVALID_PARAMETER; MtpDeviceProperty property = mRequest.getParameter(1); ALOGV("SetDevicePropValue %s\n", MtpDebug::getDevicePropCodeName(property)); @@ -664,6 +690,8 @@ MtpResponseCode MtpServer::doSetDevicePropValue() { } MtpResponseCode MtpServer::doResetDevicePropValue() { + if (mRequest.getParameterCount() < 1) + return MTP_RESPONSE_INVALID_PARAMETER; MtpDeviceProperty property = mRequest.getParameter(1); ALOGV("ResetDevicePropValue %s\n", MtpDebug::getDevicePropCodeName(property)); @@ -674,6 +702,8 @@ MtpResponseCode MtpServer::doResetDevicePropValue() { MtpResponseCode MtpServer::doGetObjectPropList() { if (!hasStorage()) return MTP_RESPONSE_INVALID_OBJECT_HANDLE; + if (mRequest.getParameterCount() < 5) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectHandle handle = mRequest.getParameter(1); // use uint32_t so we can support 0xFFFFFFFF @@ -691,6 +721,8 @@ MtpResponseCode MtpServer::doGetObjectPropList() { MtpResponseCode MtpServer::doGetObjectInfo() { if (!hasStorage()) return MTP_RESPONSE_INVALID_OBJECT_HANDLE; + if (mRequest.getParameterCount() < 1) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectHandle handle = mRequest.getParameter(1); MtpObjectInfo info(handle); MtpResponseCode result = mDatabase->getObjectInfo(handle, info); @@ -732,6 +764,8 @@ MtpResponseCode MtpServer::doGetObjectInfo() { MtpResponseCode MtpServer::doGetObject() { if (!hasStorage()) return MTP_RESPONSE_INVALID_OBJECT_HANDLE; + if (mRequest.getParameterCount() < 1) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectHandle handle = mRequest.getParameter(1); MtpString pathBuf; int64_t fileLength; @@ -765,6 +799,8 @@ MtpResponseCode MtpServer::doGetObject() { } MtpResponseCode MtpServer::doGetThumb() { + if (mRequest.getParameterCount() < 1) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectHandle handle = mRequest.getParameter(1); size_t thumbSize; void* thumb = mDatabase->getThumbnail(handle, thumbSize); @@ -783,6 +819,8 @@ MtpResponseCode MtpServer::doGetThumb() { MtpResponseCode MtpServer::doGetPartialObject(MtpOperationCode operation) { if (!hasStorage()) return MTP_RESPONSE_INVALID_OBJECT_HANDLE; + if (mRequest.getParameterCount() < 4) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectHandle handle = mRequest.getParameter(1); uint64_t offset; uint32_t length; @@ -832,6 +870,11 @@ MtpResponseCode MtpServer::doGetPartialObject(MtpOperationCode operation) { MtpResponseCode MtpServer::doSendObjectInfo() { MtpString path; + uint16_t temp16; + uint32_t temp32; + + if (mRequest.getParameterCount() < 2) + return MTP_RESPONSE_INVALID_PARAMETER; MtpStorageID storageID = mRequest.getParameter(1); MtpStorage* storage = getStorage(storageID); MtpObjectHandle parent = mRequest.getParameter(2); @@ -853,25 +896,29 @@ MtpResponseCode MtpServer::doSendObjectInfo() { } // read only the fields we need - mData.getUInt32(); // storage ID - MtpObjectFormat format = mData.getUInt16(); - mData.getUInt16(); // protection status - mSendObjectFileSize = mData.getUInt32(); - mData.getUInt16(); // thumb format - mData.getUInt32(); // thumb compressed size - mData.getUInt32(); // thumb pix width - mData.getUInt32(); // thumb pix height - mData.getUInt32(); // image pix width - mData.getUInt32(); // image pix height - mData.getUInt32(); // image bit depth - mData.getUInt32(); // parent - uint16_t associationType = mData.getUInt16(); - uint32_t associationDesc = mData.getUInt32(); // association desc - mData.getUInt32(); // sequence number + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // storage ID + if (!mData.getUInt16(temp16)) return MTP_RESPONSE_INVALID_PARAMETER; + MtpObjectFormat format = temp16; + if (!mData.getUInt16(temp16)) return MTP_RESPONSE_INVALID_PARAMETER; // protection status + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; + mSendObjectFileSize = temp32; + if (!mData.getUInt16(temp16)) return MTP_RESPONSE_INVALID_PARAMETER; // thumb format + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // thumb compressed size + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // thumb pix width + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // thumb pix height + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // image pix width + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // image pix height + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // image bit depth + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // parent + if (!mData.getUInt16(temp16)) return MTP_RESPONSE_INVALID_PARAMETER; + uint16_t associationType = temp16; + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; + uint32_t associationDesc = temp32; // association desc + if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // sequence number MtpStringBuffer name, created, modified; - mData.getString(name); // file name - mData.getString(created); // date created - mData.getString(modified); // date modified + if (!mData.getString(name)) return MTP_RESPONSE_INVALID_PARAMETER; // file name + if (!mData.getString(created)) return MTP_RESPONSE_INVALID_PARAMETER; // date created + if (!mData.getString(modified)) return MTP_RESPONSE_INVALID_PARAMETER; // date modified // keywords follow ALOGV("name: %s format: %04X\n", (const char *)name, format); @@ -1066,6 +1113,8 @@ static void deletePath(const char* path) { MtpResponseCode MtpServer::doDeleteObject() { if (!hasStorage()) return MTP_RESPONSE_INVALID_OBJECT_HANDLE; + if (mRequest.getParameterCount() < 2) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectHandle handle = mRequest.getParameter(1); MtpObjectFormat format = mRequest.getParameter(2); // FIXME - support deleting all objects if handle is 0xFFFFFFFF @@ -1087,6 +1136,8 @@ MtpResponseCode MtpServer::doDeleteObject() { } MtpResponseCode MtpServer::doGetObjectPropDesc() { + if (mRequest.getParameterCount() < 2) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectProperty propCode = mRequest.getParameter(1); MtpObjectFormat format = mRequest.getParameter(2); ALOGV("GetObjectPropDesc %s %s\n", MtpDebug::getObjectPropCodeName(propCode), @@ -1100,6 +1151,8 @@ MtpResponseCode MtpServer::doGetObjectPropDesc() { } MtpResponseCode MtpServer::doGetDevicePropDesc() { + if (mRequest.getParameterCount() < 1) + return MTP_RESPONSE_INVALID_PARAMETER; MtpDeviceProperty propCode = mRequest.getParameter(1); ALOGV("GetDevicePropDesc %s\n", MtpDebug::getDevicePropCodeName(propCode)); MtpProperty* property = mDatabase->getDevicePropertyDesc(propCode); @@ -1113,6 +1166,8 @@ MtpResponseCode MtpServer::doGetDevicePropDesc() { MtpResponseCode MtpServer::doSendPartialObject() { if (!hasStorage()) return MTP_RESPONSE_INVALID_OBJECT_HANDLE; + if (mRequest.getParameterCount() < 4) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectHandle handle = mRequest.getParameter(1); uint64_t offset = mRequest.getParameter(2); uint64_t offset2 = mRequest.getParameter(3); @@ -1180,6 +1235,8 @@ MtpResponseCode MtpServer::doSendPartialObject() { } MtpResponseCode MtpServer::doTruncateObject() { + if (mRequest.getParameterCount() < 3) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectHandle handle = mRequest.getParameter(1); ObjectEdit* edit = getEditObject(handle); if (!edit) { @@ -1199,6 +1256,8 @@ MtpResponseCode MtpServer::doTruncateObject() { } MtpResponseCode MtpServer::doBeginEditObject() { + if (mRequest.getParameterCount() < 1) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectHandle handle = mRequest.getParameter(1); if (getEditObject(handle)) { ALOGE("object already open for edit in doBeginEditObject"); @@ -1223,6 +1282,8 @@ MtpResponseCode MtpServer::doBeginEditObject() { } MtpResponseCode MtpServer::doEndEditObject() { + if (mRequest.getParameterCount() < 1) + return MTP_RESPONSE_INVALID_PARAMETER; MtpObjectHandle handle = mRequest.getParameter(1); ObjectEdit* edit = getEditObject(handle); if (!edit) { diff --git a/media/mtp/MtpStorageInfo.cpp b/media/mtp/MtpStorageInfo.cpp index 2b1a9ae..5d4ebbf 100644 --- a/media/mtp/MtpStorageInfo.cpp +++ b/media/mtp/MtpStorageInfo.cpp @@ -45,21 +45,23 @@ MtpStorageInfo::~MtpStorageInfo() { free(mVolumeIdentifier); } -void MtpStorageInfo::read(MtpDataPacket& packet) { +bool MtpStorageInfo::read(MtpDataPacket& packet) { MtpStringBuffer string; // read the device info - mStorageType = packet.getUInt16(); - mFileSystemType = packet.getUInt16(); - mAccessCapability = packet.getUInt16(); - mMaxCapacity = packet.getUInt64(); - mFreeSpaceBytes = packet.getUInt64(); - mFreeSpaceObjects = packet.getUInt32(); + if (!packet.getUInt16(mStorageType)) return false; + if (!packet.getUInt16(mFileSystemType)) return false; + if (!packet.getUInt16(mAccessCapability)) return false; + if (!packet.getUInt64(mMaxCapacity)) return false; + if (!packet.getUInt64(mFreeSpaceBytes)) return false; + if (!packet.getUInt32(mFreeSpaceObjects)) return false; - packet.getString(string); + if (!packet.getString(string)) return false; mStorageDescription = strdup((const char *)string); - packet.getString(string); + if (!packet.getString(string)) return false; mVolumeIdentifier = strdup((const char *)string); + + return true; } void MtpStorageInfo::print() { diff --git a/media/mtp/MtpStorageInfo.h b/media/mtp/MtpStorageInfo.h index 2cb626e..35a8189 100644 --- a/media/mtp/MtpStorageInfo.h +++ b/media/mtp/MtpStorageInfo.h @@ -39,7 +39,7 @@ public: MtpStorageInfo(MtpStorageID id); virtual ~MtpStorageInfo(); - void read(MtpDataPacket& packet); + bool read(MtpDataPacket& packet); void print(); }; diff --git a/media/mtp/MtpStringBuffer.cpp b/media/mtp/MtpStringBuffer.cpp index f3420a4..df04694 100644 --- a/media/mtp/MtpStringBuffer.cpp +++ b/media/mtp/MtpStringBuffer.cpp @@ -123,11 +123,17 @@ void MtpStringBuffer::set(const uint16_t* src) { mByteCount = dest - mBuffer; } -void MtpStringBuffer::readFromPacket(MtpDataPacket* packet) { - int count = packet->getUInt8(); +bool MtpStringBuffer::readFromPacket(MtpDataPacket* packet) { + uint8_t count; + if (!packet->getUInt8(count)) + return false; + uint8_t* dest = mBuffer; for (int i = 0; i < count; i++) { - uint16_t ch = packet->getUInt16(); + uint16_t ch; + + if (!packet->getUInt16(ch)) + return false; if (ch >= 0x0800) { *dest++ = (uint8_t)(0xE0 | (ch >> 12)); *dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F)); @@ -142,6 +148,7 @@ void MtpStringBuffer::readFromPacket(MtpDataPacket* packet) { *dest++ = 0; mCharCount = count; mByteCount = dest - mBuffer; + return true; } void MtpStringBuffer::writeToPacket(MtpDataPacket* packet) const { diff --git a/media/mtp/MtpStringBuffer.h b/media/mtp/MtpStringBuffer.h index e5150df..85d91e8 100644 --- a/media/mtp/MtpStringBuffer.h +++ b/media/mtp/MtpStringBuffer.h @@ -46,7 +46,7 @@ public: void set(const char* src); void set(const uint16_t* src); - void readFromPacket(MtpDataPacket* packet); + bool readFromPacket(MtpDataPacket* packet); void writeToPacket(MtpDataPacket* packet) const; inline int getCharCount() const { return mCharCount; } diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk index 697fb37..f3290c6 100644 --- a/services/audioflinger/Android.mk +++ b/services/audioflinger/Android.mk @@ -23,6 +23,12 @@ include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) +# Clang++ aborts on AudioMixer.cpp, +# b/18373866, "do not know how to split this operator." +ifeq ($(filter $(TARGET_ARCH),arm arm64),$(TARGET_ARCH)) + LOCAL_CLANG := false +endif + LOCAL_SRC_FILES:= \ AudioFlinger.cpp \ Threads.cpp \ @@ -68,13 +74,6 @@ LOCAL_SRC_FILES += FastCapture.cpp FastCaptureState.cpp LOCAL_CFLAGS += -DSTATE_QUEUE_INSTANTIATIONS='"StateQueueInstantiations.cpp"' -# Define ANDROID_SMP appropriately. Used to get inline tracing fast-path. -ifeq ($(TARGET_CPU_SMP),true) - LOCAL_CFLAGS += -DANDROID_SMP=1 -else - LOCAL_CFLAGS += -DANDROID_SMP=0 -endif - LOCAL_CFLAGS += -fvisibility=hidden include $(BUILD_SHARED_LIBRARY) diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 115b60c..a17a49e 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1191,7 +1191,7 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client) mNotificationClients.add(pid, notificationClient); - sp<IBinder> binder = client->asBinder(); + sp<IBinder> binder = IInterface::asBinder(client); binder->linkToDeath(notificationClient); clientAdded = true; } diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 6b9da83..aef1844 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -314,6 +314,64 @@ void CpuStats::sample(const String8 &title // ThreadBase // ---------------------------------------------------------------------------- +// static +const char *AudioFlinger::ThreadBase::threadTypeToString(AudioFlinger::ThreadBase::type_t type) +{ + switch (type) { + case MIXER: + return "MIXER"; + case DIRECT: + return "DIRECT"; + case DUPLICATING: + return "DUPLICATING"; + case RECORD: + return "RECORD"; + case OFFLOAD: + return "OFFLOAD"; + default: + return "unknown"; + } +} + +static String8 outputFlagsToString(audio_output_flags_t flags) +{ + static const struct mapping { + audio_output_flags_t mFlag; + const char * mString; + } mappings[] = { + AUDIO_OUTPUT_FLAG_DIRECT, "DIRECT", + AUDIO_OUTPUT_FLAG_PRIMARY, "PRIMARY", + AUDIO_OUTPUT_FLAG_FAST, "FAST", + AUDIO_OUTPUT_FLAG_DEEP_BUFFER, "DEEP_BUFFER", + AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD, "COMPRESS_OFFLOAAD", + AUDIO_OUTPUT_FLAG_NON_BLOCKING, "NON_BLOCKING", + AUDIO_OUTPUT_FLAG_HW_AV_SYNC, "HW_AV_SYNC", + AUDIO_OUTPUT_FLAG_NONE, "NONE", // must be last + }; + String8 result; + audio_output_flags_t allFlags = AUDIO_OUTPUT_FLAG_NONE; + const mapping *entry; + for (entry = mappings; entry->mFlag != AUDIO_OUTPUT_FLAG_NONE; entry++) { + allFlags = (audio_output_flags_t) (allFlags | entry->mFlag); + if (flags & entry->mFlag) { + if (!result.isEmpty()) { + result.append("|"); + } + result.append(entry->mString); + } + } + if (flags & ~allFlags) { + if (!result.isEmpty()) { + result.append("|"); + } + result.appendFormat("0x%X", flags & ~allFlags); + } + if (result.isEmpty()) { + result.append(entry->mString); + } + return result; +} + AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, audio_devices_t outDevice, audio_devices_t inDevice, type_t type) : Thread(false /*canCallJava*/), @@ -338,7 +396,7 @@ AudioFlinger::ThreadBase::~ThreadBase() // do not lock the mutex in destructor releaseWakeLock_l(); if (mPowerManager != 0) { - sp<IBinder> binder = mPowerManager->asBinder(); + sp<IBinder> binder = IInterface::asBinder(mPowerManager); binder->unlinkToDeath(mDeathRecipient); } } @@ -577,20 +635,21 @@ void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args __u bool locked = AudioFlinger::dumpTryLock(mLock); if (!locked) { - dprintf(fd, "thread %p maybe dead locked\n", this); + dprintf(fd, "thread %p may be deadlocked\n", this); } dprintf(fd, " I/O handle: %d\n", mId); dprintf(fd, " TID: %d\n", getTid()); dprintf(fd, " Standby: %s\n", mStandby ? "yes" : "no"); - dprintf(fd, " Sample rate: %u\n", mSampleRate); + dprintf(fd, " Sample rate: %u Hz\n", mSampleRate); dprintf(fd, " HAL frame count: %zu\n", mFrameCount); + dprintf(fd, " HAL format: 0x%x (%s)\n", mHALFormat, formatToString(mHALFormat)); dprintf(fd, " HAL buffer size: %u bytes\n", mBufferSize); - dprintf(fd, " Channel Count: %u\n", mChannelCount); - dprintf(fd, " Channel Mask: 0x%08x (%s)\n", mChannelMask, + dprintf(fd, " Channel count: %u\n", mChannelCount); + dprintf(fd, " Channel mask: 0x%08x (%s)\n", mChannelMask, channelMaskToString(mChannelMask, mType != RECORD).string()); - dprintf(fd, " Format: 0x%x (%s)\n", mHALFormat, formatToString(mHALFormat)); - dprintf(fd, " Frame size: %zu\n", mFrameSize); + dprintf(fd, " Format: 0x%x (%s)\n", mFormat, formatToString(mFormat)); + dprintf(fd, " Frame size: %zu bytes\n", mFrameSize); dprintf(fd, " Pending config events:"); size_t numConfig = mConfigEvents.size(); if (numConfig) { @@ -1317,7 +1376,7 @@ void AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& ar void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args) { - dprintf(fd, "\nOutput thread %p:\n", this); + dprintf(fd, "\nOutput thread %p type %d (%s):\n", this, type(), threadTypeToString(type())); dprintf(fd, " Normal frame count: %zu\n", mNormalFrameCount); dprintf(fd, " Last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime)); dprintf(fd, " Total writes: %d\n", mNumWrites); @@ -1328,6 +1387,10 @@ void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& dprintf(fd, " Mixer buffer: %p\n", mMixerBuffer); dprintf(fd, " Effect buffer: %p\n", mEffectBuffer); dprintf(fd, " Fast track availMask=%#x\n", mFastTrackAvailMask); + AudioStreamOut *output = mOutput; + audio_output_flags_t flags = output != NULL ? output->flags : AUDIO_OUTPUT_FLAG_NONE; + String8 flagsAsString = outputFlagsToString(flags); + dprintf(fd, " AudioStreamOut: %p flags %#x (%s)\n", output, flags, flagsAsString.string()); dumpBase(fd, args); } @@ -2620,7 +2683,9 @@ bool AudioFlinger::PlaybackThread::threadLoop() } } else { + ATRACE_BEGIN("sleep"); usleep(sleepTime); + ATRACE_END(); } } @@ -2820,6 +2885,7 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud NBAIO_Format format = mOutputSink->format(); NBAIO_Format origformat = format; // adjust format to match that of the Fast Mixer + ALOGV("format changed from %d to %d", format.mFormat, fastMixerFormat); format.mFormat = fastMixerFormat; format.mFrameSize = audio_bytes_per_sample(format.mFormat) * format.mChannelCount; @@ -3383,6 +3449,23 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac } size_t framesReady = track->framesReady(); + if (ATRACE_ENABLED()) { + // I wish we had formatted trace names + char traceName[16]; + strcpy(traceName, "nRdy"); + int name = track->name(); + if (AudioMixer::TRACK0 <= name && + name < (int) (AudioMixer::TRACK0 + AudioMixer::MAX_NUM_TRACKS)) { + name -= AudioMixer::TRACK0; + traceName[4] = (name / 10) + '0'; + traceName[5] = (name % 10) + '0'; + } else { + traceName[4] = '?'; + traceName[5] = '?'; + } + traceName[6] = '\0'; + ATRACE_INT(traceName, framesReady); + } if ((framesReady >= minFrames) && track->isReady() && !track->isPaused() && !track->isTerminated()) { @@ -4661,7 +4744,11 @@ void AudioFlinger::DuplicatingThread::threadLoop_mix() if (outputsReady(outputTracks)) { mAudioMixer->process(AudioBufferProvider::kInvalidPTS); } else { - memset(mSinkBuffer, 0, mSinkBufferSize); + if (mMixerBufferValid) { + memset(mMixerBuffer, 0, mMixerBufferSize); + } else { + memset(mSinkBuffer, 0, mSinkBufferSize); + } } sleepTime = 0; writeFrames = mNormalFrameCount; @@ -5029,7 +5116,9 @@ reacquire_wakelock: // sleep with mutex unlocked if (sleepUs > 0) { + ATRACE_BEGIN("sleep"); usleep(sleepUs); + ATRACE_END(); sleepUs = 0; } diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index bb9aa18..bcdb0e5 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -32,6 +32,8 @@ public: OFFLOAD // Thread class is OffloadThread }; + static const char *threadTypeToString(type_t type); + ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, audio_devices_t outDevice, audio_devices_t inDevice, type_t type); virtual ~ThreadBase(); @@ -406,6 +408,7 @@ protected: audio_channel_mask_t mChannelMask; uint32_t mChannelCount; size_t mFrameSize; + // not HAL frame size, this is for output sink (to pipe to fast mixer) audio_format_t mFormat; // Source format for Recording and // Sink format for Playback. // Sink format may be different than diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp index 7d8d4c8..6ce2d42 100644 --- a/services/audioflinger/Tracks.cpp +++ b/services/audioflinger/Tracks.cpp @@ -611,15 +611,16 @@ status_t AudioFlinger::PlaybackThread::Track::getNextBuffer( // ExtendedAudioBufferProvider interface -// Note that framesReady() takes a mutex on the control block using tryLock(). -// This could result in priority inversion if framesReady() is called by the normal mixer, -// as the normal mixer thread runs at lower -// priority than the client's callback thread: there is a short window within framesReady() -// during which the normal mixer could be preempted, and the client callback would block. -// Another problem can occur if framesReady() is called by the fast mixer: -// the tryLock() could block for up to 1 ms, and a sequence of these could delay fast mixer. -// FIXME Replace AudioTrackShared control block implementation by a non-blocking FIFO queue. +// framesReady() may return an approximation of the number of frames if called +// from a different thread than the one calling Proxy->obtainBuffer() and +// Proxy->releaseBuffer(). Also note there is no mutual exclusion in the +// AudioTrackServerProxy so be especially careful calling with FastTracks. size_t AudioFlinger::PlaybackThread::Track::framesReady() const { + if (mSharedBuffer != 0 && (isStopped() || isStopping())) { + // Static tracks return zero frames immediately upon stopping (for FastTracks). + // The remainder of the buffer is not drained. + return 0; + } return mAudioTrackServerProxy->framesReady(); } diff --git a/services/audioflinger/tests/Android.mk b/services/audioflinger/tests/Android.mk index 7bba05b..8604ef5 100644 --- a/services/audioflinger/tests/Android.mk +++ b/services/audioflinger/tests/Android.mk @@ -10,19 +10,10 @@ LOCAL_SHARED_LIBRARIES := \ liblog \ libutils \ libcutils \ - libstlport \ libaudioutils \ libaudioresampler -LOCAL_STATIC_LIBRARIES := \ - libgtest \ - libgtest_main - LOCAL_C_INCLUDES := \ - bionic \ - bionic/libstdc++/include \ - external/gtest/include \ - external/stlport/stlport \ $(call include-path-for, audio-utils) \ frameworks/av/services/audioflinger @@ -32,21 +23,24 @@ LOCAL_SRC_FILES := \ LOCAL_MODULE := resampler_tests LOCAL_MODULE_TAGS := tests -include $(BUILD_EXECUTABLE) +include $(BUILD_NATIVE_TEST) # # audio mixer test tool # include $(CLEAR_VARS) +# Clang++ aborts on AudioMixer.cpp, +# b/18373866, "do not know how to split this operator." +ifeq ($(filter $(TARGET_ARCH),arm arm64),$(TARGET_ARCH)) + LOCAL_CLANG := false +endif + LOCAL_SRC_FILES:= \ test-mixer.cpp \ ../AudioMixer.cpp.arm \ LOCAL_C_INCLUDES := \ - bionic \ - bionic/libstdc++/include \ - external/stlport/stlport \ $(call include-path-for, audio-effects) \ $(call include-path-for, audio-utils) \ frameworks/av/services/audioflinger @@ -55,7 +49,6 @@ LOCAL_STATIC_LIBRARIES := \ libsndfile LOCAL_SHARED_LIBRARIES := \ - libstlport \ libeffects \ libnbaio \ libcommon_time_client \ @@ -70,4 +63,6 @@ LOCAL_MODULE:= test-mixer LOCAL_MODULE_TAGS := optional +LOCAL_CXX_STL := libc++ + include $(BUILD_EXECUTABLE) diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp index 584e170..20a72b0 100644 --- a/services/audiopolicy/AudioPolicyManager.cpp +++ b/services/audiopolicy/AudioPolicyManager.cpp @@ -3563,7 +3563,8 @@ status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device, // check if one opened input is not needed any more after disconnecting one device for (size_t input_index = 0; input_index < mInputs.size(); input_index++) { desc = mInputs.valueAt(input_index); - if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types())) { + if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types() & + ~AUDIO_DEVICE_BIT_IN)) { ALOGV("checkInputsForDevice(): disconnecting adding input %d", mInputs.keyAt(input_index)); inputs.add(mInputs.keyAt(input_index)); @@ -3578,7 +3579,7 @@ status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device, profile_index < mHwModules[module_index]->mInputProfiles.size(); profile_index++) { sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index]; - if (profile->mSupportedDevices.types() & device) { + if (profile->mSupportedDevices.types() & device & ~AUDIO_DEVICE_BIT_IN) { ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %zu", profile_index, module_index); if (profile->mSamplingRates[0] == 0) { @@ -3795,7 +3796,9 @@ void AudioPolicyManager::checkA2dpSuspend() } bool isScoConnected = - (mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) != 0; + ((mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET & + ~AUDIO_DEVICE_BIT_IN) != 0) || + ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_ALL_SCO) != 0); // suspend A2DP output if: // (NOT already suspended) && // ((SCO device is connected && @@ -3980,9 +3983,17 @@ uint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) // usage to strategy mapping switch (attr->usage) { + case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: + if (isStreamActive(AUDIO_STREAM_RING) || isStreamActive(AUDIO_STREAM_ALARM)) { + return (uint32_t) STRATEGY_SONIFICATION; + } + if (isInCall()) { + return (uint32_t) STRATEGY_PHONE; + } + // FALL THROUGH + case AUDIO_USAGE_MEDIA: case AUDIO_USAGE_GAME: - case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: case AUDIO_USAGE_ASSISTANCE_SONIFICATION: return (uint32_t) STRATEGY_MEDIA; @@ -4182,7 +4193,7 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP if (!isInCall() && (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && - (getA2dpOutput() != 0) && !mA2dpSuspended) { + (getA2dpOutput() != 0)) { device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; if (device) break; device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; @@ -4217,7 +4228,7 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate // A2DP speaker when forcing to speaker output if (!isInCall() && (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && - (getA2dpOutput() != 0) && !mA2dpSuspended) { + (getA2dpOutput() != 0)) { device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; if (device) break; } @@ -4279,7 +4290,7 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate } if ((device2 == AUDIO_DEVICE_NONE) && (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && - (getA2dpOutput() != 0) && !mA2dpSuspended) { + (getA2dpOutput() != 0)) { device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; if (device2 == AUDIO_DEVICE_NONE) { device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; diff --git a/services/audiopolicy/AudioPolicyService.cpp b/services/audiopolicy/AudioPolicyService.cpp index dd4067f..da2defe 100644 --- a/services/audiopolicy/AudioPolicyService.cpp +++ b/services/audiopolicy/AudioPolicyService.cpp @@ -35,6 +35,7 @@ #include <hardware_legacy/power.h> #include <media/AudioEffect.h> #include <media/EffectsFactoryApi.h> +#include <media/AudioParameter.h> #include <hardware/hardware.h> #include <system/audio.h> @@ -160,7 +161,7 @@ void AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& cli mNotificationClients.add(uid, notificationClient); - sp<IBinder> binder = client->asBinder(); + sp<IBinder> binder = IInterface::asBinder(client); binder->linkToDeath(notificationClient); } } diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h index 4e68ab1..a09c084 100644 --- a/services/audiopolicy/AudioPolicyService.h +++ b/services/audiopolicy/AudioPolicyService.h @@ -30,7 +30,9 @@ #include <media/IAudioPolicyService.h> #include <media/ToneGenerator.h> #include <media/AudioEffect.h> +#ifdef USE_LEGACY_AUDIO_POLICY #include <hardware_legacy/AudioPolicyInterface.h> +#endif #include "AudioPolicyEffects.h" #include "AudioPolicyManager.h" diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index fd5a426..4229538 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -755,7 +755,7 @@ status_t CameraService::connect( Mutex::Autolock lock(mServiceLock); sp<BasicClient> clientTmp; if (!canConnectUnsafe(cameraId, clientPackageName, - cameraClient->asBinder(), + IInterface::asBinder(cameraClient), /*out*/clientTmp)) { return -EBUSY; } else if (client.get() != NULL) { @@ -818,7 +818,7 @@ status_t CameraService::connectLegacy( Mutex::Autolock lock(mServiceLock); sp<BasicClient> clientTmp; if (!canConnectUnsafe(cameraId, clientPackageName, - cameraClient->asBinder(), + IInterface::asBinder(cameraClient), /*out*/clientTmp)) { return -EBUSY; } else if (client.get() != NULL) { @@ -888,7 +888,7 @@ status_t CameraService::connectPro( { sp<BasicClient> client; if (!canConnectUnsafe(cameraId, clientPackageName, - cameraCb->asBinder(), + IInterface::asBinder(cameraCb), /*out*/client)) { return -EBUSY; } @@ -961,7 +961,7 @@ status_t CameraService::connectDevice( { sp<BasicClient> client; if (!canConnectUnsafe(cameraId, clientPackageName, - cameraCb->asBinder(), + IInterface::asBinder(cameraCb), /*out*/client)) { return -EBUSY; } @@ -1023,7 +1023,7 @@ status_t CameraService::addListener( Vector<sp<ICameraServiceListener> >::iterator it, end; for (it = mListenerList.begin(); it != mListenerList.end(); ++it) { - if ((*it)->asBinder() == listener->asBinder()) { + if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) { ALOGW("%s: Tried to add listener %p which was already subscribed", __FUNCTION__, listener.get()); return ALREADY_EXISTS; @@ -1056,7 +1056,7 @@ status_t CameraService::removeListener( Vector<sp<ICameraServiceListener> >::iterator it; for (it = mListenerList.begin(); it != mListenerList.end(); ++it) { - if ((*it)->asBinder() == listener->asBinder()) { + if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) { mListenerList.erase(it); return OK; } @@ -1169,7 +1169,7 @@ void CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) { // Found our camera, clear and leave. LOG1("removeClient: clear pro %p", clientPro.get()); - clientPro->getRemoteCallback()->asBinder()->unlinkToDeath(this); + IInterface::asBinder(clientPro->getRemoteCallback())->unlinkToDeath(this); } } @@ -1363,7 +1363,8 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, int cameraId, int cameraFacing, int clientPid, uid_t clientUid, int servicePid) : - CameraService::BasicClient(cameraService, cameraClient->asBinder(), + CameraService::BasicClient(cameraService, + IInterface::asBinder(cameraClient), clientPackageName, cameraId, cameraFacing, clientPid, clientUid, @@ -1476,7 +1477,9 @@ status_t CameraService::BasicClient::finishCameraOps() { } // Always stop watching, even if no camera op is active - mAppOpsManager.stopWatchingMode(mOpsCallback); + if (mOpsCallback != NULL) { + mAppOpsManager.stopWatchingMode(mOpsCallback); + } mOpsCallback.clear(); return OK; @@ -1572,7 +1575,7 @@ CameraService::ProClient::ProClient(const sp<CameraService>& cameraService, int clientPid, uid_t clientUid, int servicePid) - : CameraService::BasicClient(cameraService, remoteCallback->asBinder(), + : CameraService::BasicClient(cameraService, IInterface::asBinder(remoteCallback), clientPackageName, cameraId, cameraFacing, clientPid, clientUid, servicePid) { diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index a7328cf..126d8d9 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -273,7 +273,7 @@ public: } virtual sp<IBinder> asBinderWrapper() { - return asBinder(); + return asBinder(this); } protected: diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp index f3a88a1..3bdeab2 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.cpp +++ b/services/camera/libcameraservice/api1/Camera2Client.cpp @@ -165,7 +165,8 @@ status_t Camera2Client::dump(int fd, const Vector<String16>& args) { String8 result; result.appendFormat("Client2[%d] (%p) Client: %s PID: %d, dump:\n", mCameraId, - getRemoteCallback()->asBinder().get(), + (getRemoteCallback() != NULL ? + (IInterface::asBinder(getRemoteCallback()).get()) : NULL), String8(mClientPackageName).string(), mClientPid); result.append(" State: "); @@ -531,7 +532,7 @@ status_t Camera2Client::setPreviewTarget( sp<IBinder> binder; sp<ANativeWindow> window; if (bufferProducer != 0) { - binder = bufferProducer->asBinder(); + binder = IInterface::asBinder(bufferProducer); // Using controlledByApp flag to ensure that the buffer queue remains in // async mode for the old camera API, where many applications depend // on that behavior. diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp index 1a4d9a6..bbb2fe0 100644 --- a/services/camera/libcameraservice/api1/CameraClient.cpp +++ b/services/camera/libcameraservice/api1/CameraClient.cpp @@ -118,7 +118,8 @@ status_t CameraClient::dump(int fd, const Vector<String16>& args) { size_t len = snprintf(buffer, SIZE, "Client[%d] (%p) PID: %d\n", mCameraId, - getRemoteCallback()->asBinder().get(), + (getRemoteCallback() != NULL ? + IInterface::asBinder(getRemoteCallback()).get() : NULL), mClientPid); len = (len > SIZE - 1) ? SIZE - 1 : len; write(fd, buffer, len); @@ -205,7 +206,7 @@ status_t CameraClient::connect(const sp<ICameraClient>& client) { } if (mRemoteCallback != 0 && - (client->asBinder() == mRemoteCallback->asBinder())) { + (IInterface::asBinder(client) == IInterface::asBinder(mRemoteCallback))) { LOG1("Connect to the same client"); return NO_ERROR; } @@ -328,7 +329,7 @@ status_t CameraClient::setPreviewTarget( sp<IBinder> binder; sp<ANativeWindow> window; if (bufferProducer != 0) { - binder = bufferProducer->asBinder(); + binder = IInterface::asBinder(bufferProducer); // Using controlledByApp flag to ensure that the buffer queue remains in // async mode for the old camera API, where many applications depend // on that behavior. diff --git a/services/camera/libcameraservice/api1/client2/BurstCapture.cpp b/services/camera/libcameraservice/api1/client2/BurstCapture.cpp index 0bfdfd4..5502dcb 100644 --- a/services/camera/libcameraservice/api1/client2/BurstCapture.cpp +++ b/services/camera/libcameraservice/api1/client2/BurstCapture.cpp @@ -44,7 +44,7 @@ status_t BurstCapture::start(Vector<CameraMetadata> &/*metadatas*/, return INVALID_OPERATION; } -void BurstCapture::onFrameAvailable() { +void BurstCapture::onFrameAvailable(const BufferItem &/*item*/) { ALOGV("%s", __FUNCTION__); Mutex::Autolock l(mInputMutex); if(!mInputChanged) { diff --git a/services/camera/libcameraservice/api1/client2/BurstCapture.h b/services/camera/libcameraservice/api1/client2/BurstCapture.h index ea321fd..c3b7722 100644 --- a/services/camera/libcameraservice/api1/client2/BurstCapture.h +++ b/services/camera/libcameraservice/api1/client2/BurstCapture.h @@ -39,7 +39,7 @@ public: BurstCapture(wp<Camera2Client> client, wp<CaptureSequencer> sequencer); virtual ~BurstCapture(); - virtual void onFrameAvailable(); + virtual void onFrameAvailable(const BufferItem& item); virtual status_t start(Vector<CameraMetadata> &metadatas, int32_t firstCaptureId); protected: diff --git a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp index bf3318e..eadaa00 100644 --- a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp @@ -46,7 +46,7 @@ CallbackProcessor::~CallbackProcessor() { deleteStream(); } -void CallbackProcessor::onFrameAvailable() { +void CallbackProcessor::onFrameAvailable(const BufferItem& /*item*/) { Mutex::Autolock l(mInputMutex); if (!mCallbackAvailable) { mCallbackAvailable = true; diff --git a/services/camera/libcameraservice/api1/client2/CallbackProcessor.h b/services/camera/libcameraservice/api1/client2/CallbackProcessor.h index 613f5be..7fdc329 100644 --- a/services/camera/libcameraservice/api1/client2/CallbackProcessor.h +++ b/services/camera/libcameraservice/api1/client2/CallbackProcessor.h @@ -44,7 +44,7 @@ class CallbackProcessor: CallbackProcessor(sp<Camera2Client> client); ~CallbackProcessor(); - void onFrameAvailable(); + void onFrameAvailable(const BufferItem& item); // Set to NULL to disable the direct-to-app callback window status_t setCallbackWindow(sp<ANativeWindow> callbackWindow); diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp index 312a78c..40d53b3 100644 --- a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp @@ -168,6 +168,19 @@ status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, faceIds = entry.data.i32; } + entry = frame.find(ANDROID_SCALER_CROP_REGION); + if (entry.count < 4) { + ALOGE("%s: Camera %d: Unable to read crop region (count = %d)", + __FUNCTION__, client->getCameraId(), entry.count); + return res; + } + + Parameters::CropRegion scalerCrop = { + static_cast<float>(entry.data.i32[0]), + static_cast<float>(entry.data.i32[1]), + static_cast<float>(entry.data.i32[2]), + static_cast<float>(entry.data.i32[3])}; + faces.setCapacity(metadata.number_of_faces); size_t maxFaces = metadata.number_of_faces; @@ -183,26 +196,30 @@ status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, camera_face_t face; - face.rect[0] = l.mParameters.arrayXToNormalized(faceRects[i*4 + 0]); - face.rect[1] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 1]); - face.rect[2] = l.mParameters.arrayXToNormalized(faceRects[i*4 + 2]); - face.rect[3] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 3]); + face.rect[0] = l.mParameters.arrayXToNormalizedWithCrop( + faceRects[i*4 + 0], scalerCrop); + face.rect[1] = l.mParameters.arrayYToNormalizedWithCrop( + faceRects[i*4 + 1], scalerCrop); + face.rect[2] = l.mParameters.arrayXToNormalizedWithCrop( + faceRects[i*4 + 2], scalerCrop); + face.rect[3] = l.mParameters.arrayYToNormalizedWithCrop( + faceRects[i*4 + 3], scalerCrop); face.score = faceScores[i]; if (faceDetectMode == ANDROID_STATISTICS_FACE_DETECT_MODE_FULL) { face.id = faceIds[i]; - face.left_eye[0] = - l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 0]); - face.left_eye[1] = - l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 1]); - face.right_eye[0] = - l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 2]); - face.right_eye[1] = - l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 3]); - face.mouth[0] = - l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 4]); - face.mouth[1] = - l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 5]); + face.left_eye[0] = l.mParameters.arrayXToNormalizedWithCrop( + faceLandmarks[i*6 + 0], scalerCrop); + face.left_eye[1] = l.mParameters.arrayYToNormalizedWithCrop( + faceLandmarks[i*6 + 1], scalerCrop); + face.right_eye[0] = l.mParameters.arrayXToNormalizedWithCrop( + faceLandmarks[i*6 + 2], scalerCrop); + face.right_eye[1] = l.mParameters.arrayYToNormalizedWithCrop( + faceLandmarks[i*6 + 3], scalerCrop); + face.mouth[0] = l.mParameters.arrayXToNormalizedWithCrop( + faceLandmarks[i*6 + 4], scalerCrop); + face.mouth[1] = l.mParameters.arrayYToNormalizedWithCrop( + faceLandmarks[i*6 + 5], scalerCrop); } else { face.id = 0; face.left_eye[0] = face.left_eye[1] = -2000; diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp index b433781..2772267 100644 --- a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp @@ -51,7 +51,7 @@ JpegProcessor::~JpegProcessor() { deleteStream(); } -void JpegProcessor::onFrameAvailable() { +void JpegProcessor::onFrameAvailable(const BufferItem& /*item*/) { Mutex::Autolock l(mInputMutex); if (!mCaptureAvailable) { mCaptureAvailable = true; diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.h b/services/camera/libcameraservice/api1/client2/JpegProcessor.h index b2c05df..2040b30 100644 --- a/services/camera/libcameraservice/api1/client2/JpegProcessor.h +++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.h @@ -47,7 +47,7 @@ class JpegProcessor: ~JpegProcessor(); // CpuConsumer listener implementation - void onFrameAvailable(); + void onFrameAvailable(const BufferItem& item); status_t updateStream(const Parameters ¶ms); status_t deleteStream(); diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp index 42a5507..74bbb9d 100644 --- a/services/camera/libcameraservice/api1/client2/Parameters.cpp +++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp @@ -2619,75 +2619,71 @@ int Parameters::normalizedYToCrop(int y) const { return (y + 1000) * (previewCrop.height - 1) / 2000; } -int Parameters::arrayXToCrop(int x) const { - CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); - return x - previewCrop.left; -} - -int Parameters::arrayYToCrop(int y) const { - CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); - return y - previewCrop.top; -} +int Parameters::normalizedXToArray(int x) const { -int Parameters::cropXToNormalized(int x) const { - CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); - return x * 2000 / (previewCrop.width - 1) - 1000; -} + // Work-around for HAL pre-scaling the coordinates themselves + if (quirks.meteringCropRegion) { + return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000; + } -int Parameters::cropYToNormalized(int y) const { - CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); - return y * 2000 / (previewCrop.height - 1) - 1000; + return cropXToArray(normalizedXToCrop(x)); } -int Parameters::arrayXToNormalized(int width) const { - int ret = cropXToNormalized(arrayXToCrop(width)); - - ALOG_ASSERT(ret >= -1000, "Calculated normalized value out of " - "lower bounds %d", ret); - ALOG_ASSERT(ret <= 1000, "Calculated normalized value out of " - "upper bounds %d", ret); - +int Parameters::normalizedYToArray(int y) const { // Work-around for HAL pre-scaling the coordinates themselves if (quirks.meteringCropRegion) { - return width * 2000 / (fastInfo.arrayWidth - 1) - 1000; + return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000; } - return ret; + return cropYToArray(normalizedYToCrop(y)); } -int Parameters::arrayYToNormalized(int height) const { - int ret = cropYToNormalized(arrayYToCrop(height)); - ALOG_ASSERT(ret >= -1000, "Calculated normalized value out of lower bounds" - " %d", ret); - ALOG_ASSERT(ret <= 1000, "Calculated normalized value out of upper bounds" - " %d", ret); +Parameters::CropRegion Parameters::calculatePreviewCrop( + const CropRegion &scalerCrop) const { + float left, top, width, height; + float previewAspect = static_cast<float>(previewWidth) / previewHeight; + float cropAspect = scalerCrop.width / scalerCrop.height; - // Work-around for HAL pre-scaling the coordinates themselves - if (quirks.meteringCropRegion) { - return height * 2000 / (fastInfo.arrayHeight - 1) - 1000; + if (previewAspect > cropAspect) { + width = scalerCrop.width; + height = cropAspect * scalerCrop.height / previewAspect; + + left = scalerCrop.left; + top = scalerCrop.top + (scalerCrop.height - height) / 2; + } else { + width = previewAspect * scalerCrop.width / cropAspect; + height = scalerCrop.height; + + left = scalerCrop.left + (scalerCrop.width - width) / 2; + top = scalerCrop.top; } - return ret; -} + CropRegion previewCrop = {left, top, width, height}; -int Parameters::normalizedXToArray(int x) const { + return previewCrop; +} +int Parameters::arrayXToNormalizedWithCrop(int x, + const CropRegion &scalerCrop) const { // Work-around for HAL pre-scaling the coordinates themselves if (quirks.meteringCropRegion) { - return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000; + return x * 2000 / (fastInfo.arrayWidth - 1) - 1000; + } else { + CropRegion previewCrop = calculatePreviewCrop(scalerCrop); + return (x - previewCrop.left) * 2000 / (previewCrop.width - 1) - 1000; } - - return cropXToArray(normalizedXToCrop(x)); } -int Parameters::normalizedYToArray(int y) const { +int Parameters::arrayYToNormalizedWithCrop(int y, + const CropRegion &scalerCrop) const { // Work-around for HAL pre-scaling the coordinates themselves if (quirks.meteringCropRegion) { - return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000; + return y * 2000 / (fastInfo.arrayHeight - 1) - 1000; + } else { + CropRegion previewCrop = calculatePreviewCrop(scalerCrop); + return (y - previewCrop.top) * 2000 / (previewCrop.height - 1) - 1000; } - - return cropYToArray(normalizedYToCrop(y)); } status_t Parameters::getFilteredSizes(Size limit, Vector<Size> *sizes) { diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h index 815cc55..389cb92 100644 --- a/services/camera/libcameraservice/api1/client2/Parameters.h +++ b/services/camera/libcameraservice/api1/client2/Parameters.h @@ -325,13 +325,17 @@ struct Parameters { // Note that this doesn't apply to the (deprecated) single FPS value. static const int kFpsToApiScale = 1000; - // Transform between (-1000,-1000)-(1000,1000) normalized coords from camera - // API and HAL2 (0,0)-(activePixelArray.width/height) coordinates - int arrayXToNormalized(int width) const; - int arrayYToNormalized(int height) const; + // Transform from (-1000,-1000)-(1000,1000) normalized coords from camera + // API to HAL2 (0,0)-(activePixelArray.width/height) coordinates int normalizedXToArray(int x) const; int normalizedYToArray(int y) const; + // Transform from HAL3 (0,0)-(activePixelArray.width/height) coordinates to + // (-1000,-1000)-(1000,1000) normalized coordinates given a scaler crop + // region. + int arrayXToNormalizedWithCrop(int x, const CropRegion &scalerCrop) const; + int arrayYToNormalizedWithCrop(int y, const CropRegion &scalerCrop) const; + struct Range { int min; int max; @@ -341,20 +345,20 @@ struct Parameters { private: - // Convert between HAL2 sensor array coordinates and - // viewfinder crop-region relative array coordinates + // Convert from viewfinder crop-region relative array coordinates + // to HAL2 sensor array coordinates int cropXToArray(int x) const; int cropYToArray(int y) const; - int arrayXToCrop(int x) const; - int arrayYToCrop(int y) const; - // Convert between viewfinder crop-region relative array coordinates - // and camera API (-1000,1000)-(1000,1000) normalized coords - int cropXToNormalized(int x) const; - int cropYToNormalized(int y) const; + // Convert from camera API (-1000,1000)-(1000,1000) normalized coords + // to viewfinder crop-region relative array coordinates int normalizedXToCrop(int x) const; int normalizedYToCrop(int y) const; + // Given a scaler crop region, calculate preview crop region based on + // preview aspect ratio. + CropRegion calculatePreviewCrop(const CropRegion &scalerCrop) const; + Vector<Size> availablePreviewSizes; Vector<Size> availableVideoSizes; // Get size list (that are no larger than limit) from static metadata. diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp index 9e7fff8..470624b 100644 --- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp @@ -635,7 +635,7 @@ status_t StreamingProcessor::incrementStreamingIds() { return OK; } -void StreamingProcessor::onFrameAvailable() { +void StreamingProcessor::onFrameAvailable(const BufferItem& /*item*/) { ATRACE_CALL(); Mutex::Autolock l(mMutex); if (!mRecordingFrameAvailable) { diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.h b/services/camera/libcameraservice/api1/client2/StreamingProcessor.h index 8466af4..1d679a4 100644 --- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.h +++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.h @@ -80,7 +80,7 @@ class StreamingProcessor: status_t incrementStreamingIds(); // Callback for new recording frames from HAL - virtual void onFrameAvailable(); + virtual void onFrameAvailable(const BufferItem& item); // Callback from stagefright which returns used recording frames void releaseRecordingFrame(const sp<IMemory>& mem); diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp index 8f78103..8b7e4b4 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp @@ -66,7 +66,7 @@ ZslProcessor::~ZslProcessor() { disconnect(); } -void ZslProcessor::onFrameAvailable() { +void ZslProcessor::onFrameAvailable(const BufferItem& /*item*/) { Mutex::Autolock l(mInputMutex); if (!mZslBufferAvailable) { mZslBufferAvailable = true; diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.h b/services/camera/libcameraservice/api1/client2/ZslProcessor.h index b6533cf..2099c38 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor.h +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.h @@ -53,7 +53,7 @@ class ZslProcessor: ~ZslProcessor(); // From mZslConsumer - virtual void onFrameAvailable(); + virtual void onFrameAvailable(const BufferItem& item); // From FrameProcessor virtual void onResultAvailable(const CaptureResult &result); diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index e3301aa..920adf6 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -42,8 +42,14 @@ CameraDeviceClientBase::CameraDeviceClientBase( int clientPid, uid_t clientUid, int servicePid) : - BasicClient(cameraService, remoteCallback->asBinder(), clientPackageName, - cameraId, cameraFacing, clientPid, clientUid, servicePid), + BasicClient(cameraService, + IInterface::asBinder(remoteCallback), + clientPackageName, + cameraId, + cameraFacing, + clientPid, + clientUid, + servicePid), mRemoteCallback(remoteCallback) { } @@ -157,7 +163,7 @@ status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > request if (surface == 0) continue; sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer(); - int idx = mStreamMap.indexOfKey(gbp->asBinder()); + int idx = mStreamMap.indexOfKey(IInterface::asBinder(gbp)); // Trying to submit request with surface that wasn't created if (idx == NAME_NOT_FOUND) { @@ -327,7 +333,7 @@ status_t CameraDeviceClient::createStream(int width, int height, int format, // Don't create multiple streams for the same target surface { - ssize_t index = mStreamMap.indexOfKey(bufferProducer->asBinder()); + ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer)); if (index != NAME_NOT_FOUND) { ALOGW("%s: Camera %d: Buffer producer already has a stream for it " "(ID %zd)", @@ -353,12 +359,8 @@ status_t CameraDeviceClient::createStream(int width, int height, int format, useAsync = true; } - sp<IBinder> binder; - sp<ANativeWindow> anw; - if (bufferProducer != 0) { - binder = bufferProducer->asBinder(); - anw = new Surface(bufferProducer, useAsync); - } + sp<IBinder> binder = IInterface::asBinder(bufferProducer); + sp<ANativeWindow> anw = new Surface(bufferProducer, useAsync); // TODO: remove w,h,f since we are ignoring them @@ -395,7 +397,7 @@ status_t CameraDeviceClient::createStream(int width, int height, int format, res = mDevice->createStream(anw, width, height, format, &streamId); if (res == OK) { - mStreamMap.add(bufferProducer->asBinder(), streamId); + mStreamMap.add(binder, streamId); ALOGV("%s: Camera %d: Successfully created a new stream ID %d", __FUNCTION__, mCameraId, streamId); @@ -514,7 +516,8 @@ status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) { String8 result; result.appendFormat("CameraDeviceClient[%d] (%p) dump:\n", mCameraId, - getRemoteCallback()->asBinder().get()); + (getRemoteCallback() != NULL ? + IInterface::asBinder(getRemoteCallback()).get() : NULL) ); result.appendFormat(" Current client: %s (PID %d, UID %u)\n", String8(mClientPackageName).string(), mClientPid, mClientUid); diff --git a/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp b/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp index 2ea460f..59e5083 100644 --- a/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp +++ b/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp @@ -276,7 +276,7 @@ status_t ProCamera2Client::createStream(int width, int height, int format, sp<IBinder> binder; sp<ANativeWindow> window; if (bufferProducer != 0) { - binder = bufferProducer->asBinder(); + binder = IInterface::asBinder(bufferProducer); window = new Surface(bufferProducer); } @@ -334,7 +334,8 @@ status_t ProCamera2Client::dump(int fd, const Vector<String16>& args) { String8 result; result.appendFormat("ProCamera2Client[%d] (%p) PID: %d, dump:\n", mCameraId, - getRemoteCallback()->asBinder().get(), + (getRemoteCallback() != NULL ? + IInterface::asBinder(getRemoteCallback()).get() : NULL), mClientPid); result.append(" State:\n"); write(fd, result.string(), result.size()); diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp index d6db151..453c8bd 100644 --- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp +++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp @@ -128,7 +128,8 @@ status_t Camera2ClientBase<TClientBase>::dump(int fd, String8 result; result.appendFormat("Camera2ClientBase[%d] (%p) PID: %d, dump:\n", TClientBase::mCameraId, - TClientBase::getRemoteCallback()->asBinder().get(), + (TClientBase::getRemoteCallback() != NULL ? + IInterface::asBinder(TClientBase::getRemoteCallback()).get() : NULL), TClientBase::mClientPid); result.append(" State: "); diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h index d198e4e..e09c1b5 100644 --- a/services/camera/libcameraservice/common/Camera2ClientBase.h +++ b/services/camera/libcameraservice/common/Camera2ClientBase.h @@ -111,7 +111,7 @@ protected: pid_t mInitialClientPid; virtual sp<IBinder> asBinderWrapper() { - return IInterface::asBinder(); + return IInterface::asBinder(this); } virtual status_t dumpDevice(int fd, const Vector<String16>& args); diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp index 8caadd6..d1158d6 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.cpp +++ b/services/camera/libcameraservice/device2/Camera2Device.cpp @@ -793,11 +793,6 @@ status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf) mStreamSlotCount = 0; return OK; } - camera_metadata_t *buf2 = clone_camera_metadata(buf); - if (!buf2) { - ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__); - return NO_MEMORY; - } if (mStreamSlotCount > 1) { List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin(); @@ -806,9 +801,9 @@ status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf) } if (mStreamSlotCount == 1) { free_camera_metadata( *(mStreamSlot.begin()) ); - *(mStreamSlot.begin()) = buf2; + *(mStreamSlot.begin()) = buf; } else { - mStreamSlot.push_front(buf2); + mStreamSlot.push_front(buf); mStreamSlotCount = 1; } return signalConsumerLocked(); @@ -827,12 +822,7 @@ status_t Camera2Device::MetadataQueue::setStreamSlot( mStreamSlotCount = 0; for (List<camera_metadata_t*>::const_iterator r = bufs.begin(); r != bufs.end(); r++) { - camera_metadata_t *r2 = clone_camera_metadata(*r); - if (!r2) { - ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__); - return NO_MEMORY; - } - mStreamSlot.push_back(r2); + mStreamSlot.push_back(*r); mStreamSlotCount++; } return signalConsumerLocked(); diff --git a/services/camera/libcameraservice/device2/Camera2Device.h b/services/camera/libcameraservice/device2/Camera2Device.h index 2a3f1d9..4def8ae 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.h +++ b/services/camera/libcameraservice/device2/Camera2Device.h @@ -124,8 +124,8 @@ class Camera2Device: public CameraDeviceBase { // Set repeating buffer(s); if the queue is empty on a dequeue call, the // queue copies the contents of the stream slot into the queue, and then - // dequeues the first new entry. The metadata buffers passed in are - // copied. + // dequeues the first new entry. The methods take the ownership of the + // metadata buffers passed in. status_t setStreamSlot(camera_metadata_t *buf); status_t setStreamSlot(const List<camera_metadata_t*> &bufs); diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp index f8562ec..d0f29de 100644 --- a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp +++ b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp @@ -268,7 +268,7 @@ status_t RingBufferConsumer::releaseOldestBufferLocked(size_t* pinnedFrames) { return OK; } -void RingBufferConsumer::onFrameAvailable() { +void RingBufferConsumer::onFrameAvailable(const android::BufferItem& item) { status_t err; { @@ -321,7 +321,7 @@ void RingBufferConsumer::onFrameAvailable() { item.mGraphicBuffer = mSlots[item.mBuf].mGraphicBuffer; } // end of mMutex lock - ConsumerBase::onFrameAvailable(); + ConsumerBase::onFrameAvailable(item); } void RingBufferConsumer::unpinBuffer(const BufferItem& item) { diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.h b/services/camera/libcameraservice/gui/RingBufferConsumer.h index da97a11..90fd734 100644 --- a/services/camera/libcameraservice/gui/RingBufferConsumer.h +++ b/services/camera/libcameraservice/gui/RingBufferConsumer.h @@ -165,7 +165,7 @@ class RingBufferConsumer : public ConsumerBase, private: // Override ConsumerBase::onFrameAvailable - virtual void onFrameAvailable(); + virtual void onFrameAvailable(const android::BufferItem& item); void pinBufferLocked(const BufferItem& item); void unpinBuffer(const BufferItem& item); diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp index b5aaee3..b625b01 100644 --- a/services/soundtrigger/SoundTriggerHwService.cpp +++ b/services/soundtrigger/SoundTriggerHwService.cpp @@ -143,7 +143,7 @@ status_t SoundTriggerHwService::attach(const sound_trigger_module_handle_t handl sp<Module> module = mModules.valueAt(index); module->setClient(client); - client->asBinder()->linkToDeath(module); + IInterface::asBinder(client)->linkToDeath(module); moduleInterface = module; module->setCaptureState_l(mCaptureState); @@ -510,7 +510,7 @@ void SoundTriggerHwService::Module::detach() { mModels.clear(); } if (mClient != 0) { - mClient->asBinder()->unlinkToDeath(this); + IInterface::asBinder(mClient)->unlinkToDeath(this); } sp<SoundTriggerHwService> service = mService.promote(); if (service == 0) { diff --git a/soundtrigger/ISoundTrigger.cpp b/soundtrigger/ISoundTrigger.cpp index 42280d1..eecc1ea 100644 --- a/soundtrigger/ISoundTrigger.cpp +++ b/soundtrigger/ISoundTrigger.cpp @@ -58,7 +58,7 @@ public: } Parcel data, reply; data.writeInterfaceToken(ISoundTrigger::getInterfaceDescriptor()); - data.writeStrongBinder(modelMemory->asBinder()); + data.writeStrongBinder(IInterface::asBinder(modelMemory)); status_t status = remote()->transact(LOAD_SOUND_MODEL, data, &reply); if (status != NO_ERROR || (status = (status_t)reply.readInt32()) != NO_ERROR) { @@ -91,7 +91,7 @@ public: } else { data.writeInt32(dataMemory->size()); } - data.writeStrongBinder(dataMemory->asBinder()); + data.writeStrongBinder(IInterface::asBinder(dataMemory)); status_t status = remote()->transact(START_RECOGNITION, data, &reply); if (status != NO_ERROR) { status = (status_t)reply.readInt32(); diff --git a/soundtrigger/ISoundTriggerClient.cpp b/soundtrigger/ISoundTriggerClient.cpp index b0b4428..e0d3add 100644 --- a/soundtrigger/ISoundTriggerClient.cpp +++ b/soundtrigger/ISoundTriggerClient.cpp @@ -44,7 +44,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(ISoundTriggerClient::getInterfaceDescriptor()); - data.writeStrongBinder(eventMemory->asBinder()); + data.writeStrongBinder(IInterface::asBinder(eventMemory)); remote()->transact(ON_RECOGNITION_EVENT, data, &reply); @@ -54,7 +54,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(ISoundTriggerClient::getInterfaceDescriptor()); - data.writeStrongBinder(eventMemory->asBinder()); + data.writeStrongBinder(IInterface::asBinder(eventMemory)); remote()->transact(ON_SOUNDMODEL_EVENT, data, &reply); @@ -63,7 +63,7 @@ public: { Parcel data, reply; data.writeInterfaceToken(ISoundTriggerClient::getInterfaceDescriptor()); - data.writeStrongBinder(eventMemory->asBinder()); + data.writeStrongBinder(IInterface::asBinder(eventMemory)); remote()->transact(ON_SERVICE_STATE_CHANGE, data, &reply); diff --git a/soundtrigger/ISoundTriggerHwService.cpp b/soundtrigger/ISoundTriggerHwService.cpp index 05728e9..75f68b8 100644 --- a/soundtrigger/ISoundTriggerHwService.cpp +++ b/soundtrigger/ISoundTriggerHwService.cpp @@ -82,7 +82,7 @@ public: Parcel data, reply; data.writeInterfaceToken(ISoundTriggerHwService::getInterfaceDescriptor()); data.write(&handle, sizeof(sound_trigger_module_handle_t)); - data.writeStrongBinder(client->asBinder()); + data.writeStrongBinder(IInterface::asBinder(client)); remote()->transact(ATTACH, data, &reply); status_t status = reply.readInt32(); if (reply.readInt32() != 0) { @@ -147,7 +147,7 @@ status_t BnSoundTriggerHwService::onTransact( reply->writeInt32(status); if (module != 0) { reply->writeInt32(1); - reply->writeStrongBinder(module->asBinder()); + reply->writeStrongBinder(IInterface::asBinder(module)); } else { reply->writeInt32(0); } diff --git a/soundtrigger/SoundTrigger.cpp b/soundtrigger/SoundTrigger.cpp index 0015c30..2138cb7 100644 --- a/soundtrigger/SoundTrigger.cpp +++ b/soundtrigger/SoundTrigger.cpp @@ -104,7 +104,7 @@ sp<SoundTrigger> SoundTrigger::attach(const sound_trigger_module_handle_t module status_t status = service->attach(module, soundTrigger, soundTrigger->mISoundTrigger); if (status == NO_ERROR && soundTrigger->mISoundTrigger != 0) { - soundTrigger->mISoundTrigger->asBinder()->linkToDeath(soundTrigger); + IInterface::asBinder(soundTrigger->mISoundTrigger)->linkToDeath(soundTrigger); } else { ALOGW("Error %d connecting to sound trigger service", status); soundTrigger.clear(); @@ -144,7 +144,7 @@ void SoundTrigger::detach() { mCallback.clear(); if (mISoundTrigger != 0) { mISoundTrigger->detach(); - mISoundTrigger->asBinder()->unlinkToDeath(this); + IInterface::asBinder(mISoundTrigger)->unlinkToDeath(this); mISoundTrigger = 0; } } |