diff options
Diffstat (limited to 'include')
39 files changed, 1948 insertions, 262 deletions
diff --git a/include/camera/Camera.h b/include/camera/Camera.h index ee2b30c..1beac27 100644 --- a/include/camera/Camera.h +++ b/include/camera/Camera.h @@ -113,7 +113,8 @@ class Camera : public BnCameraClient, public IBinder::DeathRecipient public: // construct a camera client from an existing remote static sp<Camera> create(const sp<ICamera>& camera); - static sp<Camera> connect(); + static int32_t getNumberOfCameras(); + static sp<Camera> connect(int cameraId); ~Camera(); void init(); diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h index 5ea83a5..e12a694 100644 --- a/include/camera/CameraParameters.h +++ b/include/camera/CameraParameters.h @@ -65,13 +65,15 @@ public: // Supported preview frame sizes in pixels. // Example value: "800x600,480x320". Read only. static const char KEY_SUPPORTED_PREVIEW_SIZES[]; - // The image format for preview frames. + // The image format for preview frames. See CAMERA_MSG_PREVIEW_FRAME in + // frameworks/base/include/camera/Camera.h. // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read/write. static const char KEY_PREVIEW_FORMAT[]; // Supported image formats for preview frames. // Example value: "yuv420sp,yuv422i-yuyv". Read only. static const char KEY_SUPPORTED_PREVIEW_FORMATS[]; - // Number of preview frames per second. + // Number of preview frames per second. This is the target frame rate. The + // actual frame rate depends on the driver. // Example value: "15". Read/write. static const char KEY_PREVIEW_FRAME_RATE[]; // Supported number of preview frames per second. @@ -83,7 +85,8 @@ public: // Supported dimensions for captured pictures in pixels. // Example value: "2048x1536,1024x768". Read only. static const char KEY_SUPPORTED_PICTURE_SIZES[]; - // The image format for captured pictures. + // The image format for captured pictures. See CAMERA_MSG_COMPRESSED_IMAGE + // in frameworks/base/include/camera/Camera.h. // Example value: "jpeg" or PIXEL_FORMAT_XXX constants. Read/write. static const char KEY_PICTURE_FORMAT[]; // Supported image formats for captured pictures. @@ -119,14 +122,17 @@ public: // should not set default value for this parameter. // Example value: "0" or "90" or "180" or "270". Write only. static const char KEY_ROTATION[]; - // GPS latitude coordinate. This will be stored in JPEG EXIF header. - // Example value: "25.032146". Write only. + // GPS latitude coordinate. GPSLatitude and GPSLatitudeRef will be stored in + // JPEG EXIF header. + // Example value: "25.032146" or "-33.462809". Write only. static const char KEY_GPS_LATITUDE[]; - // GPS longitude coordinate. This will be stored in JPEG EXIF header. - // Example value: "121.564448". Write only. + // GPS longitude coordinate. GPSLongitude and GPSLongitudeRef will be stored + // in JPEG EXIF header. + // Example value: "121.564448" or "-70.660286". Write only. static const char KEY_GPS_LONGITUDE[]; - // GPS altitude. This will be stored in JPEG EXIF header. - // Example value: "21.0". Write only. + // GPS altitude. GPSAltitude and GPSAltitudeRef will be stored in JPEG EXIF + // header. + // Example value: "21.0" or "-5". Write only. static const char KEY_GPS_ALTITUDE[]; // GPS timestamp (UTC in seconds since January 1, 1970). This should be // stored in JPEG EXIF header. @@ -221,9 +227,42 @@ public: // Example value: "true". Read only. static const char KEY_SMOOTH_ZOOM_SUPPORTED[]; + // The distances (in meters) from the camera to where an object appears to + // be in focus. The object is sharpest at the optimal focus distance. The + // depth of field is the far focus distance minus near focus distance. + // + // Applications can read this parameter anytime to get the latest focus + // distances. If the focus mode is FOCUS_MODE_EDOF, the values may be all + // 0, which means focus distance is not applicable. If the focus mode is + // FOCUS_MODE_CONTINUOUS and autofocus has started, focus distances may + // change from time to time. + // + // Far focus distance > optimal focus distance > near focus distance. If + // the far focus distance is infinity, the value should be "Infinity" (case + // sensitive). The format is three float values separated by commas. The + // first is near focus distance. The second is optimal focus distance. The + // third is far focus distance. + // Example value: "0.95,1.9,Infinity" or "0.049,0.05,0.051". Read only. + static const char KEY_FOCUS_DISTANCES[]; + + // The image format for video frames. See CAMERA_MSG_VIDEO_FRAME in + // frameworks/base/include/camera/Camera.h. + // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only. + static const char KEY_VIDEO_FRAME_FORMAT[]; + + // Metering mode. This affects how camera determines exposure. + // Example value: "spot" or METERING_MODE_XXX constants. Read/write. + static const char KEY_METERING_MODE[]; + // Supported metering modes. + // Example value: "center-weighted,frame-average,spot". Read only. + static const char KEY_SUPPORTED_METERING_MODES[]; + // Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED. static const char TRUE[]; + // Value for KEY_FOCUS_DISTANCES. + static const char FOCUS_DISTANCE_INFINITY[]; + // Values for white balance settings. static const char WHITE_BALANCE_AUTO[]; static const char WHITE_BALANCE_INCANDESCENT[]; @@ -309,6 +348,21 @@ public: // continuously. Applications should not call // CameraHardwareInterface.autoFocus in this mode. static const char FOCUS_MODE_EDOF[]; + // Continuous focus mode. The camera continuously tries to focus. This is + // ideal for shooting video or shooting photo of moving object. Continuous + // focus starts when CameraHardwareInterface.autoFocus is called. Focus + // callback will be only called once as soon as the picture is in focus. + static const char FOCUS_MODE_CONTINUOUS[]; + + // The camera determines the exposure by giving more weight to the + // central part of the scene. + static const char METERING_MODE_CENTER_WEIGHTED[]; + // The camera determines the exposure by averaging the entire scene, + // giving no weighting to any particular area. + static const char METERING_MODE_FRAME_AVERAGE[]; + // The camera determines the exposure by a very small area of the scene, + // typically the center. + static const char METERING_MODE_SPOT[]; private: DefaultKeyedVector<String8,String8> mMap; diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h index 82b1283..dcd434f 100644 --- a/include/camera/ICameraService.h +++ b/include/camera/ICameraService.h @@ -30,13 +30,16 @@ class ICameraService : public IInterface { public: enum { - CONNECT = IBinder::FIRST_CALL_TRANSACTION, + GET_NUMBER_OF_CAMERAS = IBinder::FIRST_CALL_TRANSACTION, + CONNECT }; public: DECLARE_META_INTERFACE(CameraService); - virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient) = 0; + virtual int32_t getNumberOfCameras() = 0; + virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, + int cameraId) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/media/AudioCommon.h b/include/media/AudioCommon.h new file mode 100644 index 0000000..245d760 --- /dev/null +++ b/include/media/AudioCommon.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2010 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 ANDROID_AUDIOCOMMON_H_ +#define ANDROID_AUDIOCOMMON_H_ + +#if __cplusplus +extern "C" { +#endif + +///////////////////////////////////////////////// +// Common definitions for PCM audio +///////////////////////////////////////////////// + + +// PCM Sample format +enum audio_format_e { + PCM_FORMAT_S15 = 1, // PCM signed 16 bits, must be 1 for backward compatibility + PCM_FORMAT_U8 = 2, // PCM unsigned 8 bits, must be 2 for backward compatibility + PCM_FORMAT_S7_24 // signed 7.24 fixed point representation +}; + +// Channel mask definitions +enum audio_channels_e { + CHANNEL_FRONT_LEFT = 0x4, // front left channel + CHANNEL_FRONT_RIGHT = 0x8, // front right channel + CHANNEL_FRONT_CENTER = 0x10, // front center channel + CHANNEL_LOW_FREQUENCY = 0x20, // low frequency channel + CHANNEL_BACK_LEFT = 0x40, // back left channel + CHANNEL_BACK_RIGHT = 0x80, // back right channel + CHANNEL_FRONT_LEFT_OF_CENTER = 0x100, // front left of center channel + CHANNEL_FRONT_RIGHT_OF_CENTER = 0x200, // front right of center channel + CHANNEL_BACK_CENTER = 0x400, // back center channel + CHANNEL_MONO = CHANNEL_FRONT_LEFT, + CHANNEL_STEREO = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT), + CHANNEL_QUAD = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | + CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT), + CHANNEL_SURROUND = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | + CHANNEL_FRONT_CENTER | CHANNEL_BACK_CENTER), + CHANNEL_5POINT1 = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | + CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT), + CHANNEL_7POINT1 = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | + CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT | + CHANNEL_FRONT_LEFT_OF_CENTER | CHANNEL_FRONT_RIGHT_OF_CENTER), +}; + +// Render device definitions +enum audio_device_e { + DEVICE_EARPIECE = 0x1, // earpiece + DEVICE_SPEAKER = 0x2, // speaker + DEVICE_WIRED_HEADSET = 0x4, // wired headset, with microphone + DEVICE_WIRED_HEADPHONE = 0x8, // wired headphone, without microphone + DEVICE_BLUETOOTH_SCO = 0x10, // generic bluetooth SCO + DEVICE_BLUETOOTH_SCO_HEADSET = 0x20, // bluetooth SCO headset + DEVICE_BLUETOOTH_SCO_CARKIT = 0x40, // bluetooth SCO car kit + DEVICE_BLUETOOTH_A2DP = 0x80, // generic bluetooth A2DP + DEVICE_BLUETOOTH_A2DP_HEADPHONES = 0x100, // bluetooth A2DP headphones + DEVICE_BLUETOOTH_A2DP_SPEAKER = 0x200, // bluetooth A2DP speakers + DEVICE_AUX_DIGITAL = 0x400 // digital output +}; + +#if __cplusplus +} // extern "C" +#endif + + +#endif /*ANDROID_AUDIOCOMMON_H_*/ diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index 92bc126..d956882 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -142,7 +142,8 @@ public: uint32_t flags = 0, callback_t cbf = 0, void* user = 0, - int notificationFrames = 0); + int notificationFrames = 0, + int sessionId = 0); /* Terminates the AudioRecord and unregisters it from AudioFlinger. @@ -168,7 +169,8 @@ public: callback_t cbf = 0, void* user = 0, int notificationFrames = 0, - bool threadCanCallJava = false); + bool threadCanCallJava = false, + int sessionId = 0); /* Result of constructing the AudioRecord. This must be checked @@ -270,6 +272,16 @@ public: */ audio_io_handle_t getInput(); + /* returns the audio session ID associated to this AudioRecord. + * + * Parameters: + * none. + * + * Returned value: + * AudioRecord session ID. + */ + int getSessionId(); + /* obtains a buffer of "frameCount" frames. The buffer must be * filled entirely. If the track is stopped, obtainBuffer() returns * STOPPED instead of NO_ERROR as long as there are buffers availlable, @@ -356,6 +368,7 @@ private: uint32_t mFlags; uint32_t mChannels; audio_io_handle_t mInput; + int mSessionId; }; }; // namespace android diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index d0ccc50..f21e83d 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -20,6 +20,7 @@ #include <utils/RefBase.h> #include <utils/threads.h> #include <media/IAudioFlinger.h> +#include <media/AudioCommon.h> namespace android { @@ -50,8 +51,8 @@ public: // Audio sub formats (see AudioSystem::audio_format). enum pcm_sub_format { - PCM_SUB_16_BIT = 0x1, // must be 1 for backward compatibility - PCM_SUB_8_BIT = 0x2, // must be 2 for backward compatibility + PCM_SUB_16_BIT = PCM_FORMAT_S15, // must be 1 for backward compatibility + PCM_SUB_8_BIT = PCM_FORMAT_U8, // must be 2 for backward compatibility }; // MP3 sub format field definition : can use 11 LSBs in the same way as MP3 frame header to specify @@ -103,26 +104,21 @@ public: // Channel mask definitions must be kept in sync with JAVA values in /media/java/android/media/AudioFormat.java enum audio_channels { // output channels - CHANNEL_OUT_FRONT_LEFT = 0x4, - CHANNEL_OUT_FRONT_RIGHT = 0x8, - CHANNEL_OUT_FRONT_CENTER = 0x10, - CHANNEL_OUT_LOW_FREQUENCY = 0x20, - CHANNEL_OUT_BACK_LEFT = 0x40, - CHANNEL_OUT_BACK_RIGHT = 0x80, - CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x100, - CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x200, - CHANNEL_OUT_BACK_CENTER = 0x400, - CHANNEL_OUT_MONO = CHANNEL_OUT_FRONT_LEFT, - CHANNEL_OUT_STEREO = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT), - CHANNEL_OUT_QUAD = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | - CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT), - CHANNEL_OUT_SURROUND = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | - CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_CENTER), - CHANNEL_OUT_5POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | - CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT), - CHANNEL_OUT_7POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | - CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT | - CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER), + CHANNEL_OUT_FRONT_LEFT = CHANNEL_FRONT_LEFT, + CHANNEL_OUT_FRONT_RIGHT = CHANNEL_FRONT_RIGHT, + CHANNEL_OUT_FRONT_CENTER = CHANNEL_FRONT_CENTER, + CHANNEL_OUT_LOW_FREQUENCY = CHANNEL_LOW_FREQUENCY, + CHANNEL_OUT_BACK_LEFT = CHANNEL_BACK_LEFT, + CHANNEL_OUT_BACK_RIGHT = CHANNEL_BACK_RIGHT, + CHANNEL_OUT_FRONT_LEFT_OF_CENTER = CHANNEL_FRONT_LEFT_OF_CENTER, + CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = CHANNEL_FRONT_RIGHT_OF_CENTER, + CHANNEL_OUT_BACK_CENTER = CHANNEL_BACK_CENTER, + CHANNEL_OUT_MONO = CHANNEL_MONO, + CHANNEL_OUT_STEREO = CHANNEL_STEREO, + CHANNEL_OUT_QUAD = CHANNEL_QUAD, + CHANNEL_OUT_SURROUND = CHANNEL_SURROUND, + CHANNEL_OUT_5POINT1 = CHANNEL_5POINT1, + CHANNEL_OUT_7POINT1 = CHANNEL_7POINT1, CHANNEL_OUT_ALL = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT | CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER | CHANNEL_OUT_BACK_CENTER), @@ -234,23 +230,25 @@ public: static status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int stream = DEFAULT); static unsigned int getInputFramesLost(audio_io_handle_t ioHandle); + + static int newAudioSessionId(); // // AudioPolicyService interface // enum audio_devices { // output devices - DEVICE_OUT_EARPIECE = 0x1, - DEVICE_OUT_SPEAKER = 0x2, - DEVICE_OUT_WIRED_HEADSET = 0x4, - DEVICE_OUT_WIRED_HEADPHONE = 0x8, - DEVICE_OUT_BLUETOOTH_SCO = 0x10, - DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20, - DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40, - DEVICE_OUT_BLUETOOTH_A2DP = 0x80, - DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100, - DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200, - DEVICE_OUT_AUX_DIGITAL = 0x400, + DEVICE_OUT_EARPIECE = DEVICE_EARPIECE, + DEVICE_OUT_SPEAKER = DEVICE_SPEAKER, + DEVICE_OUT_WIRED_HEADSET = DEVICE_WIRED_HEADSET, + DEVICE_OUT_WIRED_HEADPHONE = DEVICE_WIRED_HEADPHONE, + DEVICE_OUT_BLUETOOTH_SCO = DEVICE_BLUETOOTH_SCO, + DEVICE_OUT_BLUETOOTH_SCO_HEADSET = DEVICE_BLUETOOTH_SCO_HEADSET, + DEVICE_OUT_BLUETOOTH_SCO_CARKIT = DEVICE_BLUETOOTH_SCO_CARKIT, + DEVICE_OUT_BLUETOOTH_A2DP = DEVICE_BLUETOOTH_A2DP, + DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = DEVICE_BLUETOOTH_A2DP_HEADPHONES, + DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = DEVICE_BLUETOOTH_A2DP_SPEAKER, + DEVICE_OUT_AUX_DIGITAL = DEVICE_AUX_DIGITAL, DEVICE_OUT_DEFAULT = 0x8000, DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE | DEVICE_OUT_SPEAKER | DEVICE_OUT_WIRED_HEADSET | DEVICE_OUT_WIRED_HEADPHONE | DEVICE_OUT_BLUETOOTH_SCO | DEVICE_OUT_BLUETOOTH_SCO_HEADSET | diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index 14b30ae..c46df1e 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -138,7 +138,8 @@ public: uint32_t flags = 0, callback_t cbf = 0, void* user = 0, - int notificationFrames = 0); + int notificationFrames = 0, + int sessionId = 0); /* Creates an audio track and registers it with AudioFlinger. With this constructor, * The PCM data to be rendered by AudioTrack is passed in a shared memory buffer @@ -157,7 +158,8 @@ public: uint32_t flags = 0, callback_t cbf = 0, void* user = 0, - int notificationFrames = 0); + int notificationFrames = 0, + int sessionId = 0); /* Terminates the AudioTrack and unregisters it from AudioFlinger. * Also destroys all resources assotiated with the AudioTrack. @@ -182,7 +184,8 @@ public: void* user = 0, int notificationFrames = 0, const sp<IMemory>& sharedBuffer = 0, - bool threadCanCallJava = false); + bool threadCanCallJava = false, + int sessionId = 0); /* Result of constructing the AudioTrack. This must be checked @@ -239,10 +242,17 @@ public: /* set volume for this track, mostly used for games' sound effects + * left and right volumes. Levels must be <= 1.0. */ - void setVolume(float left, float right); + status_t setVolume(float left, float right); void getVolume(float* left, float* right); + /* set the send level for this track. An auxiliary effect should be attached + * to the track with attachEffect(). Level must be <= 1.0. + */ + status_t setSendLevel(float level); + void getSendLevel(float* level); + /* set sample rate for this track, mostly used for games' sound effects */ status_t setSampleRate(int sampleRate); @@ -340,6 +350,31 @@ public: */ audio_io_handle_t getOutput(); + /* returns the unique ID associated to this track. + * + * Parameters: + * none. + * + * Returned value: + * AudioTrack ID. + */ + int getSessionId(); + + + /* Attach track auxiliary output to specified effect. Used effectId = 0 + * to detach track from effect. + * + * Parameters: + * + * effectId: effectId obtained from AudioEffect::id(). + * + * Returned status (from utils/Errors.h) can be: + * - NO_ERROR: successful operation + * - INVALID_OPERATION: the effect is not an auxiliary effect. + * - BAD_VALUE: The specified effect ID is invalid + */ + status_t attachAuxEffect(int effectId); + /* obtains a buffer of "frameCount" frames. The buffer must be * filled entirely. If the track is stopped, obtainBuffer() returns * STOPPED instead of NO_ERROR as long as there are buffers availlable, @@ -398,13 +433,15 @@ private: int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, - audio_io_handle_t output); + audio_io_handle_t output, + bool enforceFrameCount); sp<IAudioTrack> mAudioTrack; sp<IMemory> mCblkMemory; sp<AudioTrackThread> mAudioTrackThread; float mVolume[2]; + float mSendLevel; uint32_t mFrameCount; audio_track_cblk_t* mCblk; @@ -420,7 +457,8 @@ private: callback_t mCbf; void* mUserData; - uint32_t mNotificationFrames; + uint32_t mNotificationFramesReq; // requested number of frames between each notification callback + uint32_t mNotificationFramesAct; // actual number of frames between each notification callback sp<IMemory> mSharedBuffer; int mLoopCount; uint32_t mRemainingFrames; @@ -429,6 +467,7 @@ private: uint32_t mNewPosition; uint32_t mUpdatePeriod; uint32_t mFlags; + int mSessionId; }; diff --git a/include/media/EffectApi.h b/include/media/EffectApi.h new file mode 100644 index 0000000..97874f7 --- /dev/null +++ b/include/media/EffectApi.h @@ -0,0 +1,559 @@ +/* + * Copyright (C) 2010 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 ANDROID_EFFECTAPI_H_ +#define ANDROID_EFFECTAPI_H_ + +#include <errno.h> +#include <stdint.h> +#include <sys/types.h> +#include <media/AudioCommon.h> + +#if __cplusplus +extern "C" { +#endif + +///////////////////////////////////////////////// +// Effect control interface +///////////////////////////////////////////////// + +// The effect control interface is exposed by each effect engine implementation. It consists of +// a set of functions controlling the configuration, activation and process of the engine. +// The functions are grouped in a structure of type effect_interface_s: +// struct effect_interface_s { +// effect_process_t process; +// effect_command_t command; +// }; + + +// effect_interface_t: Effect control interface handle. +// The effect_interface_t serves two purposes regarding the implementation of the effect engine: +// - 1 it is the address of a pointer to an effect_interface_s structure where the functions +// of the effect control API for a particular effect are located. +// - 2 it is the address of the context of a particular effect instance. +// A typical implementation in the effect library would define a structure as follows: +// struct effect_module_s { +// const struct effect_interface_s *itfe; +// effect_config_t config; +// effect_context_t context; +// } +// The implementation of EffectCreate() function would then allocate a structure of this +// type and return its address as effect_interface_t +typedef struct effect_interface_s **effect_interface_t; + + +// Effect API version 1.0 +#define EFFECT_API_VERSION 0x0100 // Format 0xMMmm MM: Major version, mm: minor version + +// Maximum length of character strings in structures defines by this API. +#define EFFECT_STRING_LEN_MAX 64 + +// +//--- Effect descriptor structure effect_descriptor_t +// + +// Unique effect ID (can be generated from the following site: http://www.itu.int/ITU-T/asn1/uuid.html) +// This format is used for both "type" and "uuid" fields of the effect descriptor structure. +// - When used for effect type and the engine is implementing and effect corresponding to a standard OpenSL ES +// interface, this ID must be the one defined in OpenSLES_IID.h for that interface. +// - When used as uuid, it should be a unique UUID for this particular implementation. +typedef struct effect_uuid_s { + uint32_t timeLow; + uint16_t timeMid; + uint16_t timeHiAndVersion; + uint16_t clockSeq; + uint8_t node[6]; +} effect_uuid_t; + +// NULL UUID definition (matches SL_IID_NULL_) +#define EFFECT_UUID_INITIALIZER { 0xec7178ec, 0xe5e1, 0x4432, 0xa3f4, { 0x46, 0x57, 0xe6, 0x79, 0x52, 0x10 } } +static const effect_uuid_t EFFECT_UUID_NULL_ = EFFECT_UUID_INITIALIZER; +const effect_uuid_t * const EFFECT_UUID_NULL = &EFFECT_UUID_NULL_; +const char * const EFFECT_UUID_NULL_STR = "ec7178ec-e5e1-4432-a3f4-4657e6795210"; + +// the effect descriptor contains necessary information to facilitate the enumeration of the effect +// engines present in a library. +typedef struct effect_descriptor_s { + effect_uuid_t type; // UUID corresponding to the OpenSL ES interface implemented by this effect + effect_uuid_t uuid; // UUID for this particular implementation + uint16_t apiVersion; // Version of the effect API implemented: must match current EFFECT_API_VERSION + uint32_t flags; // effect engine capabilities/requirements flags (see below) + char name[EFFECT_STRING_LEN_MAX] ; // human readable effect name + char implementor[EFFECT_STRING_LEN_MAX] ; // human readable effect implementor name +} effect_descriptor_t; + +// definitions for flags field of effect descriptor. +// +---------------------------+-----------+----------------------------------- +// | description | bits | values +// +---------------------------+-----------+----------------------------------- +// | connection mode | 0..1 | 0 insert: after track process +// | | | 1 auxiliary: connect to track auxiliary +// | | | output and use send level +// | | | 2 replace: replaces track process function; +// | | | must implement SRC, volume and mono to stereo. +// | | | 3 reserved +// +---------------------------+-----------+----------------------------------- +// | insertion preference | 2..4 | 0 none +// | | | 1 first of the chain +// | | | 2 last of the chain +// | | | 3 exclusive (only effect in the insert chain) +// | | | 4..7 reserved +// +---------------------------+-----------+----------------------------------- +// | Volume management | 5..6 | 0 none +// | | | 1 implements volume control +// | | | 2 requires volume indication +// | | | 3 reserved +// +---------------------------+-----------+----------------------------------- +// | Device management | 7..8 | 0 none +// | | | 1 requires device updates +// | | | 2..3 reserved +// +---------------------------+-----------+----------------------------------- +// | Sample input mode | 9..10 | 0 direct: process() function or EFFECT_CMD_CONFIGURE +// | | | command must specify a buffer descriptor +// | | | 1 provider: process() function uses the +// | | | bufferProvider indicated by the +// | | | EFFECT_CMD_CONFIGURE command to request input buffers. +// | | | 2 both: both input modes are supported +// | | | 3 reserved +// +---------------------------+-----------+----------------------------------- +// | Sample output mode | 11..12 | 0 direct: process() function or EFFECT_CMD_CONFIGURE +// | | | command must specify a buffer descriptor +// | | | 1 provider: process() function uses the +// | | | bufferProvider indicated by the +// | | | EFFECT_CMD_CONFIGURE command to request output buffers. +// | | | 2 both: both output modes are supported +// | | | 3 reserved +// +---------------------------+-----------+----------------------------------- + +// insert mode +#define EFFECT_FLAG_TYPE_MASK 0x00000003 +#define EFFECT_FLAG_TYPE_INSERT 0x00000000 +#define EFFECT_FLAG_TYPE_AUXILIARY 0x00000001 +#define EFFECT_FLAG_TYPE_REPLACE 0x00000002 + +// insert preference +#define EFFECT_FLAG_INSERT_MASK 0x0000001C +#define EFFECT_FLAG_INSERT_ANY 0x00000000 +#define EFFECT_FLAG_INSERT_FIRST 0x00000004 +#define EFFECT_FLAG_INSERT_LAST 0x00000008 +#define EFFECT_FLAG_INSERT_EXCLUSIVE 0x0000000C + + +// volume control +#define EFFECT_FLAG_VOLUME_MASK 0x00000060 +#define EFFECT_FLAG_VOLUME_CTRL 0x00000020 +#define EFFECT_FLAG_VOLUME_IND 0x00000040 +#define EFFECT_FLAG_VOLUME_NONE 0x00000000 + +// device control +#define EFFECT_FLAG_DEVICE_MASK 0x00000180 +#define EFFECT_FLAG_DEVICE_IND 0x00000080 +#define EFFECT_FLAG_DEVICE_NONE 0x00000000 + +// sample input modes +#define EFFECT_FLAG_INPUT_MASK 0x00000600 +#define EFFECT_FLAG_INPUT_DIRECT 0x00000000 +#define EFFECT_FLAG_INPUT_PROVIDER 0x00000200 +#define EFFECT_FLAG_INPUT_BOTH 0x00000400 + +// sample output modes +#define EFFECT_FLAG_OUTPUT_MASK 0x00001800 +#define EFFECT_FLAG_OUTPUT_DIRECT 0x00000000 +#define EFFECT_FLAG_OUTPUT_PROVIDER 0x00000800 +#define EFFECT_FLAG_OUTPUT_BOTH 0x00001000 + +// forward definition of type audio_buffer_t +typedef struct audio_buffer_s audio_buffer_t; + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: process +// +// Description: Effect process function. Takes input samples as specified +// (count and location) in input buffer descriptor and output processed +// samples as specified in output buffer descriptor. If the buffer descriptor +// is not specified the function must use either the buffer or the +// buffer provider function installed by the EFFECT_CMD_CONFIGURE command. +// +// NOTE: the process() function implementation should be "real-time safe" that is +// it should not perform blocking calls: malloc/free, sleep, read/write/open/close, +// pthread_cond_wait/pthread_mutex_lock... +// +// Input: +// effect_interface_t: handle to the effect interface this function +// is called on. +// inBuffer: buffer descriptor indicating where to read samples to process. +// If NULL, use the configuration passed by EFFECT_CMD_CONFIGURE command. +// +// inBuffer: buffer descriptor indicating where to write processed samples. +// If NULL, use the configuration passed by EFFECT_CMD_CONFIGURE command. +// +// Output: +// returned value: 0 successful operation +// -EINVAL invalid interface handle or +// invalid input/output buffer description +//////////////////////////////////////////////////////////////////////////////// +typedef int32_t (*effect_process_t)(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer); + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: command +// +// Description: Send a command and receive a response to/from effect engine. +// +// Input: +// effect_interface_t: handle to the effect interface this function +// is called on. +// cmdCode: command code: the command can be a standardized command defined in +// effect_command_e (see below) or a proprietary command. +// cmdSize: size of command in bytes +// pCmdData: pointer to command data +// pReplyData: pointer to reply data +// +// Input/Output: +// replySize: maximum size of reply data as input +// actual size of reply data as output +// +// Output: +// returned value: 0 successful operation +// -EINVAL invalid interface handle or +// invalid command/reply size or format according to command code +// The return code should be restricted to indicate problems related to the this +// API specification. Status related to the execution of a particular command should be +// indicated as part of the reply field. +// +// *pReplyData updated with command response +// +//////////////////////////////////////////////////////////////////////////////// +typedef int32_t (*effect_command_t)(effect_interface_t self, int32_t cmdCode, int32_t cmdSize, void *pCmdData, int32_t *replySize, void *pReplyData); + + +// Effect control interface definition +struct effect_interface_s { + effect_process_t process; + effect_command_t command; +}; + + +//--- Standardized command codes for command function +// +--------------------------------+-------------------------------+-------------------------------+-------------------------- +// | description | command code | command format | reply format +// +--------------------------------+-------------------------------+-------------------------------+-------------------------- +// | Initialize effect engine: | EFFECT_CMD_INIT | size: 0 | size: sizeof(int) +// | All configurations return to | | data: N/A | data: status +// | default | | | +// +--------------------------------+-------------------------------+-------------------------------+-------------------------- +// | Apply new audio parameters | EFFECT_CMD_CONFIGURE | size: sizeof(effect_config_t) | size: sizeof(int) +// | configurations for input and | | data: effect_config_t | data: status +// | output buffers | | | +// +--------------------------------+-------------------------------+-------------------------------+-------------------------- +// | Reset effect engine: keep | EFFECT_CMD_RESET | size: 0 | size: 0 +// | configuration but reset state | | data: N/A | data: N/A +// | and buffer content. | | | +// | Called by the framework before | | | +// | enabling the effect | | | +// +--------------------------------+-------------------------------+-------------------------------+-------------------------- +// | Enable the process | EFFECT_CMD_ENABLE | size: 0 | size: sizeof(int) +// | Called by the framework before | | data: N/A | data: status +// | the first call to process() | | | +// +--------------------------------+-------------------------------+-------------------------------+-------------------------- +// | Disable the process | EFFECT_CMD_DISABLE | size: 0 | size: sizeof(int) +// | Called by the framework after | | data: N/A | data: status +// | the last call to process() | | | +// +--------------------------------+-------------------------------+-------------------------------+-------------------------- +// | Set a parameter and apply it | EFFECT_CMD_SET_PARAM | size: sizeof(effect_param_t) | size: sizeof(int) +// | immediately | | + size of param + value | data: status +// | | | data: effect_param_t | +// +--------------------------------+-------------------------------+-------------------------------+-------------------------- +// | Set a parameter but apply it | EFFECT_CMD_SET_PARAM_DEFERRED | size: sizeof(effect_param_t) | size: 0 +// | only when receiving command | | + size of param + value | data: N/A +// | EFFECT_CMD_SET_PARAM_COMMIT | | data: effect_param_t | +// +--------------------------------+-------------------------------+-------------------------------+-------------------------- +// | Apply all previously received | EFFECT_CMD_SET_PARAM_COMMIT | size: 0 | size: sizeof(int) +// | EFFECT_CMD_SET_PARAM_DEFERRED | | data: N/A | data: status +// | commands | | | +// +--------------------------------+-------------------------------+-------------------------------+-------------------------- +// | Get a parameter value | EFFECT_CMD_GET_PARAM | size: sizeof(effect_param_t) | size: sizeof(effect_param_t) +// | | | + size of param | + size of param + value +// | | | data: effect_param_t | data: effect_param_t +// +--------------------------------+-------------------------------+-------------------------------+-------------------------- +// | Set the rendering device the | EFFECT_CMD_SET_DEVICE | size: sizeof(uint32_t) | size: 0 +// | audio output path is connected | | data: audio_device_e | data: N/A +// | to. See audio_device_e in | | | +// | AudioCommon.h for device values| | | +// +--------------------------------+-------------------------------+-------------------------------+-------------------------- +// | Set and get volume. Used by | EFFECT_CMD_SET_VOLUME | size: n * sizeof(uint32_t) | size: n * sizeof(uint32_t) +// | audio framework to delegate | | data: volume for each channel | data: volume for each channel +// | volume control to effect engine| | defined in effect_config_t in | defined in effect_config_t in +// | If volume control flag is set | | 8.24 fixed point format | 8.24 fixed point format +// | in the effect descriptor, the | | | It is legal to receive a null +// | effect engine must return the | | | pointer as pReplyData in which +// | volume that should be applied | | | case the effect framework has +// | before the effect is processed | | | delegated volume control to +// | The overall volume (the volume | | | another effect. +// | actually applied by the effect | | | +// | multiplied by the returned | | | +// | value) should match the | | | +// | requested value | | | +// +--------------------------------+-------------------------------+-------------------------------+-------------------------- +// | All proprietary effect commands| EFFECT_CMD_FIRST_PROPRIETARY | | +// | must use command codes above | | | +// | this value. The size and format| | | +// | of command and response fields | | | +// | is free in this case. | | | +// +--------------------------------+-------------------------------+-------------------------------+-------------------------- + + +enum effect_command_e { + EFFECT_CMD_INIT, // initialize effect engine + EFFECT_CMD_CONFIGURE, // configure effect engine (see effect_config_t) + EFFECT_CMD_RESET, // reset effect engine + EFFECT_CMD_ENABLE, // enable effect process + EFFECT_CMD_DISABLE, // disable effect process + EFFECT_CMD_SET_PARAM, // set parameter immediately (see effect_param_t) + EFFECT_CMD_SET_PARAM_DEFERRED, // set parameter deferred + EFFECT_CMD_SET_PARAM_COMMIT, // commit previous set parameter deferred + EFFECT_CMD_GET_PARAM, // get parameter + EFFECT_CMD_SET_DEVICE, // set audio device (see audio_device_e in AudioCommon.h) + EFFECT_CMD_SET_VOLUME, // set volume + EFFECT_CMD_FIRST_PROPRIETARY = 0x10000 // first proprietary command code +}; + +// Audio buffer descriptor used by process(), bufferProvider() functions and buffer_config_t structure +// Multi-channel audio is always interleaved. The channel order is from LSB to MSB with regard to the +// channel mask definition in audio_channels_e (AudioCommon.h) e.g : +// Stereo: left, right +// 5 point 1: front left, front right, front center, low frequency, back left, back right +// The buffer size is expressed in frame count, a frame being composed of samples for all +// channels at a given time +struct audio_buffer_s { + size_t frameCount; // number of frames in buffer + union { + void* raw; // raw pointer to start of buffer + int32_t* s32; // pointer to signed 32 bit data at start of buffer + int16_t* s16; // pointer to signed 16 bit data at start of buffer + uint8_t* u8; // pointer to unsigned 8 bit data at start of buffer + }; +}; + +// the buffer_provider_s structure contains functions that can be used +// by the effect engine process() function to query and release input +// or output audio buffer. +// The getBuffer() function is called to retrieve a buffer where data +// should read from or written to by process() function. +// The releaseBuffer() function MUST be called when the buffer retrieved +// with getBuffer() is not needed anymore. +// The process function should use the buffer provider mechanism to retrieve +// input or output buffer if the inBuffer or outBuffer passed as argument is NULL +// and the buffer configuration (buffer_config_t) given by the EFFECT_CMD_CONFIGURE +// command did not specify an audio buffer. + +typedef int32_t (* buffer_function_t)(void *cookie, audio_buffer_t *buffer); + +typedef struct buffer_provider_s { + buffer_function_t getBuffer; // retrieve next buffer + buffer_function_t releaseBuffer; // release used buffer + void *cookie; // for use by client of buffer provider functions +} buffer_provider_t; + +// The buffer_config_s structure specifies the input or output audio format +// to be used by the effect engine. It is part of the effect_config_t +// structure that defines both input and output buffer configurations and is +// passed by the EFFECT_CMD_CONFIGURE command. +typedef struct buffer_config_s { + audio_buffer_t buffer; // buffer for use by process() function if not passed explicitly + uint32_t samplingRate; // sampling rate + uint32_t channels; // channel mask (see audio_channels_e in AudioCommon.h) + buffer_provider_t bufferProvider; // buffer provider + uint8_t format; // PCM format (see audio_format_e in AudioCommon.h) + uint8_t accessMode; // read/write or accumulate in buffer (effect_buffer_access_e) + uint16_t mask; // indicates which of the above fields is valid +} buffer_config_t; + +// values for "accessMode" field of buffer_config_t: +// overwrite, read only, accumulate (read/modify/write) +enum effect_buffer_access_e { + EFFECT_BUFFER_ACCESS_WRITE, + EFFECT_BUFFER_ACCESS_READ, + EFFECT_BUFFER_ACCESS_ACCUMULATE + +}; + +// values for bit field "mask" in buffer_config_t. If a bit is set, the corresponding field +// in buffer_config_t must be taken into account when executing the EFFECT_CMD_CONFIGURE command +#define EFFECT_CONFIG_BUFFER 0x0001 // buffer field must be taken into account +#define EFFECT_CONFIG_SMP_RATE 0x0002 // samplingRate field must be taken into account +#define EFFECT_CONFIG_CHANNELS 0x0004 // channels field must be taken into account +#define EFFECT_CONFIG_FORMAT 0x0008 // format field must be taken into account +#define EFFECT_CONFIG_ACC_MODE 0x0010 // accessMode field must be taken into account +#define EFFECT_CONFIG_PROVIDER 0x0020 // bufferProvider field must be taken into account +#define EFFECT_CONFIG_ALL (EFFECT_CONFIG_BUFFER | EFFECT_CONFIG_SMP_RATE | \ + EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT | \ + EFFECT_CONFIG_ACC_MODE | EFFECT_CONFIG_PROVIDER) + +// effect_config_s structure describes the format of the pCmdData argument of EFFECT_CMD_CONFIGURE command +// to configure audio parameters and buffers for effect engine input and output. +typedef struct effect_config_s { + buffer_config_t inputCfg; + buffer_config_t outputCfg;; +} effect_config_t; + +// effect_param_s structure describes the format of the pCmdData argument of EFFECT_CMD_SET_PARAM +// command and pCmdData and pReplyData of EFFECT_CMD_GET_PARAM command. +// psize and vsize represent the actual size of parameter and value. +// +// NOTE: the start of value field inside the data field is always on a 32 bit boundary: +// +// +-----------+ +// | status | sizeof(int) +// +-----------+ +// | psize | sizeof(int) +// +-----------+ +// | vsize | sizeof(int) +// +-----------+ +// | | | | +// ~ parameter ~ > psize | +// | | | > ((psize - 1)/sizeof(int) + 1) * sizeof(int) +// +-----------+ | +// | padding | | +// +-----------+ +// | | | +// ~ value ~ > vsize +// | | | +// +-----------+ + +typedef struct effect_param_s { + int32_t status; // Transaction status (unused for command, used for reply) + uint32_t psize; // Parameter size + uint32_t vsize; // Value size + char data[]; // Start of Parameter + Value data +} effect_param_t; + + +///////////////////////////////////////////////// +// Effect library interface +///////////////////////////////////////////////// + +// An effect library is required to implement and expose the following functions +// to enable effect enumeration and instantiation. The name of these functions must be as +// specified here as the effect framework will get the function address with dlsym(): +// +// - effect_QueryNumberEffects_t EffectQueryNumberEffects; +// - effect_QueryNextEffect_t EffectQueryNext; +// - effect_CreateEffect_t EffectCreate; +// - effect_ReleaseEffect_t EffectRelease; + + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: EffectQueryNumberEffects +// +// Description: Returns the number of different effects exposed by the +// library. Each effect must have a unique effect uuid (see +// effect_descriptor_t). This function together with EffectQueryNext() +// is used to enumerate all effects present in the library. +// Each time EffectQueryNumberEffects() is called, the library must +// reset the index of the effect descriptor returned by next call to +// EffectQueryNext() to restart enumeration from the beginning. +// +// Input/Output: +// pNumEffects: address where the number of effects should be returned. +// +// Output: +// returned value: 0 successful operation. +// -ENODEV library failed to initialize +// -EINVAL invalid pNumEffects +// *pNumEffects: updated with number of effects in library +// +//////////////////////////////////////////////////////////////////////////////// +typedef int32_t (*effect_QueryNumberEffects_t)(uint32_t *pNumEffects); + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: EffectQueryNext +// +// Description: Returns a descriptor of the next available effect. +// See effect_descriptor_t for details on effect descriptors. +// This function together with EffectQueryNext() is used to enumerate all +// effects present in the library. The enumeration sequence is: +// EffectQueryNumberEffects(&num_effects); +// while (num_effects--) +// EffectQueryNext(); +// +// Input/Output: +// pDescriptor: address where to return the effect descriptor. +// +// Output: +// returned value: 0 successful operation. +// -ENODEV library failed to initialize +// -EINVAL invalid pDescriptor +// -ENOENT no more effect available +// *pDescriptor: updated with the effect descriptor. +// +//////////////////////////////////////////////////////////////////////////////// +typedef int32_t (*effect_QueryNextEffect_t)(effect_descriptor_t *pDescriptor); + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: EffectCreate +// +// Description: Creates an effect engine of the specified type and returns an +// effect control interface on this engine. The function will allocate the +// resources for an instance of the requested effect engine and return +// a handle on the effect control interface. +// +// Input: +// pEffectUuid: pointer to the effect uuid. +// +// Input/Output: +// pInterface: address where to return the effect interface. +// +// Output: +// returned value: 0 successful operation. +// -ENODEV library failed to initialize +// -EINVAL invalid pEffectUuid or pInterface +// -ENOENT no effect with this uuid found +// *pInterface: updated with the effect interface handle. +// +//////////////////////////////////////////////////////////////////////////////// +typedef int32_t (*effect_CreateEffect_t)(effect_uuid_t *uuid, effect_interface_t *pInterface); + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: EffectRelease +// +// Description: Releases the effect engine whose handle is given as argument. +// All resources allocated to this particular instance of the effect are +// released. +// +// Input: +// interface: handle on the effect interface to be released. +// +// Output: +// returned value: 0 successful operation. +// -ENODEV library failed to initialize +// -EINVAL invalid interface handle +// +//////////////////////////////////////////////////////////////////////////////// +typedef int32_t (*effect_ReleaseEffect_t)(effect_interface_t interface); + + +#if __cplusplus +} // extern "C" +#endif + + +#endif /*ANDROID_EFFECTAPI_H_*/ diff --git a/include/media/EffectEqualizerApi.h b/include/media/EffectEqualizerApi.h new file mode 100644 index 0000000..e3069d5 --- /dev/null +++ b/include/media/EffectEqualizerApi.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 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 ANDROID_EFFECTEQUALIZERAPI_H_ +#define ANDROID_EFFECTEQUALIZERAPI_H_ + +#include <media/EffectApi.h> + +#if __cplusplus +extern "C" { +#endif + +//TODO replace by openSL ES include when available +static const effect_uuid_t SL_IID_EQUALIZER_ = { 0x0bed4300, 0xddd6, 0x11db, 0x8f34, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }; +const effect_uuid_t * const SL_IID_EQUALIZER = &SL_IID_EQUALIZER_; + +/* enumerated parameters for Equalizer effect */ +typedef enum +{ + EQ_PARAM_NUM_BANDS, // Gets the number of frequency bands that the equalizer supports. + EQ_PARAM_LEVEL_RANGE, // Returns the minimum and maximum band levels supported. + EQ_PARAM_BAND_LEVEL, // Gets/Sets the gain set for the given equalizer band. + EQ_PARAM_CENTER_FREQ, // Gets the center frequency of the given band. + EQ_PARAM_BAND_FREQ_RANGE, // Gets the frequency range of the given frequency band. + EQ_PARAM_GET_BAND, // Gets the band that has the most effect on the given frequency. + EQ_PARAM_CUR_PRESET, // Gets/Sets the current preset. + EQ_PARAM_GET_NUM_OF_PRESETS, // Gets the total number of presets the equalizer supports. + EQ_PARAM_GET_PRESET_NAME // Gets the preset name based on the index. +} t_equalizer_params; + + +#if __cplusplus +} // extern "C" +#endif + + +#endif /*ANDROID_EFFECTEQUALIZERAPI_H_*/ diff --git a/include/media/EffectFactoryApi.h b/include/media/EffectFactoryApi.h new file mode 100644 index 0000000..6cc9932 --- /dev/null +++ b/include/media/EffectFactoryApi.h @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2010 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 ANDROID_EFFECTFACTORYAPI_H_ +#define ANDROID_EFFECTFACTORYAPI_H_ + +#include <errno.h> +#include <stdint.h> +#include <sys/types.h> +#include <media/EffectApi.h> + +#if __cplusplus +extern "C" { +#endif + +///////////////////////////////////////////////// +// Effect factory interface +///////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: EffectQueryNumberEffects +// +// Description: Returns the number of different effects in all loaded libraries. +// Each effect must have a different effect uuid (see +// effect_descriptor_t). This function together with EffectQueryNext() +// is used to enumerate all effects present in all loaded libraries. +// Each time EffectQueryNumberEffects() is called, the factory must +// reset the index of the effect descriptor returned by next call to +// EffectQueryNext() to restart enumeration from the beginning. +// +// Input/Output: +// pNumEffects: address where the number of effects should be returned. +// +// Output: +// returned value: 0 successful operation. +// -ENODEV factory failed to initialize +// -EINVAL invalid pNumEffects +// *pNumEffects: updated with number of effects in factory +// +//////////////////////////////////////////////////////////////////////////////// +int EffectQueryNumberEffects(uint32_t *pNumEffects); + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: EffectQueryNext +// +// Description: Returns a descriptor of the next available effect. +// See effect_descriptor_t for a details on effect descriptor. +// This function together with EffectQueryNext() is used to enumerate all +// effects present in all loaded libraries. The enumeration sequence is: +// EffectQueryNumberEffects(&num_effects); +// while (num_effects--) +// EffectQueryNext(); +// +// Input/Output: +// pDescriptor: address where to return the effect descriptor. +// +// Output: +// returned value: 0 successful operation. +// -ENODEV factory failed to initialize +// -EINVAL invalid pDescriptor +// -ENOENT no more effect available +// *pDescriptor: updated with the effect descriptor. +// +//////////////////////////////////////////////////////////////////////////////// +int EffectQueryNext(effect_descriptor_t *pDescriptor); + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: EffectCreate +// +// Description: Creates an effect engine of the specified type and returns an +// effect control interface on this engine. The function will allocate the +// resources for an instance of the requested effect engine and return +// a handler on the effect control interface. +// +// Input: +// pEffectUuid: pointer to the effect uuid. +// +// Input/Output: +// pInterface: address where to return the effect interface. +// +// Output: +// returned value: 0 successful operation. +// -ENODEV factory failed to initialize +// -EINVAL invalid pEffectUuid or pInterface +// -ENOENT no effect with this uuid found +// *pInterface: updated with the effect interface. +// +//////////////////////////////////////////////////////////////////////////////// +int EffectCreate(effect_uuid_t *pEffectUuid, effect_interface_t *pInterface); + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: EffectRelease +// +// Description: Releases the effect engine whose handler is given as argument. +// All resources allocated to this particular instance of the effect are +// released. +// +// Input: +// interface: handler on the effect interface to be released. +// +// Output: +// returned value: 0 successful operation. +// -ENODEV factory failed to initialize +// -EINVAL invalid interface handler +// +//////////////////////////////////////////////////////////////////////////////// +int EffectRelease(effect_interface_t interface); + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: EffectLoadLibrary +// +// Description: Loads the effect library which path is given as first argument. +// This must be the full path of a dynamic library (.so) implementing one or +// more effect engines and exposing the effect library interface described in +// EffectApi.h. The function returns a handle on the library for used by +// further call to EffectUnloadLibrary() to unload the library. +// +// Input: +// libPath: full path of the dynamic library file in the file system. +// +// handle: address where to return the library handle +// +// Output: +// returned value: 0 successful operation. +// -ENODEV effect factory not initialized or +// library could not be loaded or +// library does not implement required functions +// -EINVAL invalid libPath string or handle +// +//////////////////////////////////////////////////////////////////////////////// +int EffectLoadLibrary(const char *libPath, int *handle); + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: EffectUnloadLibrary +// +// Description: Unloads the effect library which handle is given as argument. +// +// Input: +// handle: library handle +// +// Output: +// returned value: 0 successful operation. +// -ENODEV effect factory not initialized +// -ENOENT invalid handle +// +//////////////////////////////////////////////////////////////////////////////// +int EffectUnloadLibrary(int handle); + + + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: EffectGetDescriptor +// +// Description: Returns the descriptor of the effect which uuid is pointed +// to by first argument. +// +// Input: +// pEffectUuid: pointer to the effect uuid. +// +// Input/Output: +// pDescriptor: address where to return the effect descriptor. +// +// Output: +// returned value: 0 successful operation. +// -ENODEV factory failed to initialize +// -EINVAL invalid pEffectUuid or pDescriptor +// -ENOENT no effect with this uuid found +// *pDescriptor: updated with the effect descriptor. +// +//////////////////////////////////////////////////////////////////////////////// +int EffectGetDescriptor(effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptor); + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: EffectIsNullUuid +// +// Description: Helper function to compare effect uuid to EFFECT_UUID_NULL +// +// Input: +// pEffectUuid: pointer to effect uuid to compare to EFFECT_UUID_NULL. +// +// Output: +// returned value: 0 if uuid is different from EFFECT_UUID_NULL. +// 1 if uuid is equal to EFFECT_UUID_NULL. +// +//////////////////////////////////////////////////////////////////////////////// +int EffectIsNullUuid(effect_uuid_t *pEffectUuid); + +#if __cplusplus +} // extern "C" +#endif + + +#endif /*ANDROID_EFFECTFACTORYAPI_H_*/ diff --git a/include/media/EffectReverbApi.h b/include/media/EffectReverbApi.h new file mode 100644 index 0000000..6371adb --- /dev/null +++ b/include/media/EffectReverbApi.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2010 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 ANDROID_EFFECTREVERBAPI_H_ +#define ANDROID_EFFECTREVERBAPI_H_ + +#include <media/EffectApi.h> + +#if __cplusplus +extern "C" { +#endif + +// TODO: include OpenSLES_IID.h instead +static const effect_uuid_t SL_IID_ENVIRONMENTALREVERB_ = { 0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, { 0x4e, 0x23, 0x4d, 0x6, 0x83, 0x9e } }; +const effect_uuid_t * const SL_IID_ENVIRONMENTALREVERB = &SL_IID_ENVIRONMENTALREVERB_; + +static const effect_uuid_t SL_IID_PRESETREVERB_ = { 0x47382d60, 0xddd8, 0x11db, 0xbf3a, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }; +const effect_uuid_t * const SL_IID_PRESETREVERB = &SL_IID_PRESETREVERB_; + +/* enumerated parameter settings for Reverb effect */ +typedef enum +{ + REVERB_PARAM_BYPASS, + REVERB_PARAM_PRESET, + // Parameters below are as defined in OpenSL ES specification for environmental reverb interface + REVERB_PARAM_ROOM_LEVEL, // in millibels, range -6000 to 0 + REVERB_PARAM_ROOM_HF_LEVEL, // in millibels, range -4000 to 0 + REVERB_PARAM_DECAY_TIME, // in milliseconds, range 100 to 20000 + REVERB_PARAM_DECAY_HF_RATIO, // in permilles, range 100 to 1000 + REVERB_PARAM_REFLECTIONS_LEVEL, // in millibels, range -6000 to 0 + REVERB_PARAM_REFLECTIONS_DELAY, // in milliseconds, range 0 to 65 + REVERB_PARAM_REVERB_LEVEL, // in millibels, range -6000 to 0 + REVERB_PARAM_REVERB_DELAY, // in milliseconds, range 0 to 65 + REVERB_PARAM_DIFFUSION, // in permilles, range 0 to 1000 + REVERB_PARAM_DENSITY, // in permilles, range 0 to 1000 + REVERB_PARAM_PROPERTIES +} t_reverb_params; + + +typedef enum +{ + REVERB_PRESET_LARGE_HALL, + REVERB_PRESET_HALL, + REVERB_PRESET_CHAMBER, + REVERB_PRESET_ROOM, +} t_reverb_presets; + +//t_reverb_properties is equal to SLEnvironmentalReverbSettings defined in OpenSL ES specification. +typedef struct s_reverb_properties { + int16_t roomLevel; + int16_t roomHFLevel; + int32_t decayTime; + int16_t decayHFRatio; + int16_t reflectionsLevel; + int32_t reflectionsDelay; + int32_t reverbDelay; + int16_t reverbLevel; + int16_t diffusion; + int16_t density; + int16_t padding; +} t_reverb_properties; + + +#if __cplusplus +} // extern "C" +#endif + + +#endif /*ANDROID_EFFECTREVERBAPI_H_*/ diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index c147632..ccfa530 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -27,6 +27,9 @@ #include <media/IAudioTrack.h> #include <media/IAudioRecord.h> #include <media/IAudioFlingerClient.h> +#include <media/EffectApi.h> +#include <media/IEffect.h> +#include <media/IEffectClient.h> #include <utils/String8.h> namespace android { @@ -51,6 +54,7 @@ public: uint32_t flags, const sp<IMemory>& sharedBuffer, int output, + int *sessionId, status_t *status) = 0; virtual sp<IAudioRecord> openRecord( @@ -61,6 +65,7 @@ public: int channelCount, int frameCount, uint32_t flags, + int *sessionId, status_t *status) = 0; /* query the audio hardware state. This state never changes, @@ -134,6 +139,28 @@ public: virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output) = 0; virtual unsigned int getInputFramesLost(int ioHandle) = 0; + + virtual int newAudioSessionId() = 0; + + virtual status_t loadEffectLibrary(const char *libPath, int *handle) = 0; + + virtual status_t unloadEffectLibrary(int handle) = 0; + + virtual status_t queryNumberEffects(uint32_t *numEffects) = 0; + + virtual status_t queryNextEffect(effect_descriptor_t *pDescriptor) = 0; + + virtual status_t getEffectDescriptor(effect_uuid_t *pEffectUUID, effect_descriptor_t *pDescriptor) = 0; + + virtual sp<IEffect> createEffect(pid_t pid, + effect_descriptor_t *pDesc, + const sp<IEffectClient>& client, + int32_t priority, + int output, + int sessionId, + status_t *status, + int *id, + int *enabled) = 0; }; diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h index de6426a..47d530b 100644 --- a/include/media/IAudioTrack.h +++ b/include/media/IAudioTrack.h @@ -62,6 +62,11 @@ public: */ virtual void pause() = 0; + /* Attach track auxiliary output to specified effect. Use effectId = 0 + * to detach track from effect. + */ + virtual status_t attachAuxEffect(int effectId) = 0; + /* get this tracks control block */ virtual sp<IMemory> getCblk() const = 0; }; diff --git a/include/media/IEffect.h b/include/media/IEffect.h new file mode 100644 index 0000000..6dad393 --- /dev/null +++ b/include/media/IEffect.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010 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 ANDROID_IEFFECT_H +#define ANDROID_IEFFECT_H + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> +#include <binder/IMemory.h> + +namespace android { + +class IEffect: public IInterface +{ +public: + DECLARE_META_INTERFACE(Effect); + + virtual status_t enable() = 0; + + virtual status_t disable() = 0; + + virtual status_t command(int cmdCode, int cmdSize, void *pCmdData, int *pReplySize, void *pReplyData) = 0; + + virtual void disconnect() = 0; + + virtual sp<IMemory> getCblk() const = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnEffect: public BnInterface<IEffect> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif // ANDROID_IEFFECT_H diff --git a/include/media/IEffectClient.h b/include/media/IEffectClient.h new file mode 100644 index 0000000..d22daf8 --- /dev/null +++ b/include/media/IEffectClient.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 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 ANDROID_IEFFECTCLIENT_H +#define ANDROID_IEFFECTCLIENT_H + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> +#include <binder/IMemory.h> + +namespace android { + +class IEffectClient: public IInterface +{ +public: + DECLARE_META_INTERFACE(EffectClient); + + virtual void controlStatusChanged(bool controlGranted) = 0; + virtual void enableStatusChanged(bool enabled) = 0; + virtual void commandExecuted(int cmdCode, int cmdSize, void *pCmdData, int replySize, void *pReplyData) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnEffectClient: public BnInterface<IEffectClient> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif // ANDROID_IEFFECTCLIENT_H diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h index 9ea6c7b..eead166 100644 --- a/include/media/mediarecorder.h +++ b/include/media/mediarecorder.h @@ -135,7 +135,8 @@ enum media_recorder_error_type { enum media_recorder_info_type { MEDIA_RECORDER_INFO_UNKNOWN = 1, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED = 800, - MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED = 801 + MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED = 801, + MEDIA_RECORDER_INFO_STOP_PREMATURELY = 802 }; // ---------------------------------------------------------------------------- diff --git a/include/media/stagefright/AMRWriter.h b/include/media/stagefright/AMRWriter.h index 372909a..dd11809 100644 --- a/include/media/stagefright/AMRWriter.h +++ b/include/media/stagefright/AMRWriter.h @@ -42,18 +42,20 @@ protected: virtual ~AMRWriter(); private: - Mutex mLock; - FILE *mFile; status_t mInitCheck; sp<MediaSource> mSource; bool mStarted; volatile bool mDone; - bool mReachedEOS; + volatile bool mReachedEOS; pthread_t mThread; + int64_t mEstimatedSizeBytes; + int64_t mEstimatedDurationUs; static void *ThreadWrapper(void *); void threadFunc(); + bool exceedsFileSizeLimit(); + bool exceedsFileDurationLimit(); AMRWriter(const AMRWriter &); AMRWriter &operator=(const AMRWriter &); diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h index eb00140..2519379 100644 --- a/include/media/stagefright/AudioSource.h +++ b/include/media/stagefright/AudioSource.h @@ -46,7 +46,7 @@ protected: virtual ~AudioSource(); private: - enum { kMaxBufferSize = 8192 }; + enum { kMaxBufferSize = 2048 }; AudioRecord *mRecord; status_t mInitCheck; diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h index ea435de..0c7bf6f 100644 --- a/include/media/stagefright/CameraSource.h +++ b/include/media/stagefright/CameraSource.h @@ -28,18 +28,15 @@ namespace android { class ICamera; class IMemory; -class ISurface; class Camera; -class CameraSource : public MediaSource { +class CameraSource : public MediaSource, public MediaBufferObserver { public: static CameraSource *Create(); - static CameraSource *CreateFromICamera(const sp<ICamera> &icamera); + static CameraSource *CreateFromCamera(const sp<Camera> &camera); virtual ~CameraSource(); - void setPreviewSurface(const sp<ISurface> &surface); - virtual status_t start(MetaData *params = NULL); virtual status_t stop(); @@ -48,25 +45,34 @@ public: virtual status_t read( MediaBuffer **buffer, const ReadOptions *options = NULL); + virtual void signalBufferReturned(MediaBuffer* buffer); + private: friend class CameraSourceListener; sp<Camera> mCamera; - sp<ISurface> mPreviewSurface; Mutex mLock; Condition mFrameAvailableCondition; - List<sp<IMemory> > mFrames; + Condition mFrameCompleteCondition; + List<sp<IMemory> > mFramesReceived; + List<sp<IMemory> > mFramesBeingEncoded; List<int64_t> mFrameTimes; int mWidth, mHeight; int64_t mFirstFrameTimeUs; - int32_t mNumFrames; + int64_t mLastFrameTimestampUs; + int32_t mNumFramesReceived; + int32_t mNumFramesEncoded; + int32_t mNumFramesDropped; bool mStarted; CameraSource(const sp<Camera> &camera); - void dataCallback(int32_t msgType, const sp<IMemory> &data); + void dataCallbackTimestamp( + int64_t timestampUs, int32_t msgType, const sp<IMemory> &data); + + void releaseQueuedFrames(); CameraSource(const CameraSource &); CameraSource &operator=(const CameraSource &); diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h index 6b93f19..3c85eca 100644 --- a/include/media/stagefright/MPEG4Writer.h +++ b/include/media/stagefright/MPEG4Writer.h @@ -49,6 +49,8 @@ public: void writeFourcc(const char *fourcc); void write(const void *data, size_t size); void endBox(); + uint32_t interleaveDuration() const { return mInterleaveDurationUs; } + status_t setInterleaveDuration(uint32_t duration); protected: virtual ~MPEG4Writer(); @@ -59,14 +61,33 @@ private: FILE *mFile; off_t mOffset; off_t mMdatOffset; + uint8_t *mMoovBoxBuffer; + off_t mMoovBoxBufferOffset; + bool mWriteMoovBoxToMemory; + off_t mFreeBoxOffset; + bool mStreamableFile; + off_t mEstimatedMoovBoxSize; + uint32_t mInterleaveDurationUs; + int64_t mStartTimestampUs; Mutex mLock; List<Track *> mTracks; List<off_t> mBoxes; - off_t addSample(MediaBuffer *buffer); - off_t addLengthPrefixedSample(MediaBuffer *buffer); + void setStartTimestamp(int64_t timeUs); + int64_t getStartTimestamp(); // Not const + + void lock(); + void unlock(); + + // Acquire lock before calling these methods + off_t addSample_l(MediaBuffer *buffer); + off_t addLengthPrefixedSample_l(MediaBuffer *buffer); + + inline size_t write(const void *ptr, size_t size, size_t nmemb, FILE* stream); + bool exceedsFileSizeLimit(); + bool exceedsFileDurationLimit(); MPEG4Writer(const MPEG4Writer &); MPEG4Writer &operator=(const MPEG4Writer &); diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h index 207195a..a9a0d55 100644 --- a/include/media/stagefright/MediaDefs.h +++ b/include/media/stagefright/MediaDefs.h @@ -22,6 +22,7 @@ namespace android { extern const char *MEDIA_MIMETYPE_IMAGE_JPEG; +extern const char *MEDIA_MIMETYPE_VIDEO_VPX; extern const char *MEDIA_MIMETYPE_VIDEO_AVC; extern const char *MEDIA_MIMETYPE_VIDEO_MPEG4; extern const char *MEDIA_MIMETYPE_VIDEO_H263; @@ -38,6 +39,7 @@ extern const char *MEDIA_MIMETYPE_AUDIO_RAW; extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4; extern const char *MEDIA_MIMETYPE_CONTAINER_WAV; extern const char *MEDIA_MIMETYPE_CONTAINER_OGG; +extern const char *MEDIA_MIMETYPE_CONTAINER_MATROSKA; } // namespace android diff --git a/include/media/stagefright/MediaWriter.h b/include/media/stagefright/MediaWriter.h index b8232c6..b15f69c 100644 --- a/include/media/stagefright/MediaWriter.h +++ b/include/media/stagefright/MediaWriter.h @@ -19,6 +19,7 @@ #define MEDIA_WRITER_H_ #include <utils/RefBase.h> +#include <media/IMediaPlayerClient.h> namespace android { @@ -31,10 +32,23 @@ struct MediaWriter : public RefBase { virtual bool reachedEOS() = 0; virtual status_t start() = 0; virtual void stop() = 0; + virtual void setMaxFileSize(int64_t bytes) { mMaxFileSizeLimitBytes = bytes; } + virtual void setMaxFileDuration(int64_t durationUs) { mMaxFileDurationLimitUs = durationUs; } + virtual void setListener(const sp<IMediaPlayerClient>& listener) { + mListener = listener; + } protected: virtual ~MediaWriter() {} - + int64_t mMaxFileSizeLimitBytes; + int64_t mMaxFileDurationLimitUs; + sp<IMediaPlayerClient> mListener; + + void notify(int msg, int ext1, int ext2) { + if (mListener != NULL) { + mListener->notify(msg, ext1, ext2); + } + } private: MediaWriter(const MediaWriter &); MediaWriter &operator=(const MediaWriter &); diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index 1d76a1a..f836c55 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -156,8 +156,8 @@ private: void setComponentRole(); - void setAMRFormat(bool isWAMR); - void setAACFormat(int32_t numChannels, int32_t sampleRate); + void setAMRFormat(bool isWAMR, int32_t bitRate); + void setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate); status_t setVideoPortFormatType( OMX_U32 portIndex, diff --git a/include/private/media/AudioEffectShared.h b/include/private/media/AudioEffectShared.h new file mode 100644 index 0000000..a3a99a4 --- /dev/null +++ b/include/private/media/AudioEffectShared.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 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 ANDROID_EFFECTCBASESHARED_H +#define ANDROID_EFFECTCBASESHARED_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/threads.h> + +namespace android { + +// ---------------------------------------------------------------------------- + +// Size of buffer used to exchange parameters between application and mediaserver processes. +#define EFFECT_PARAM_BUFFER_SIZE 1024 + + +// Shared memory area used to exchange parameters between application and mediaserver +// process. +struct effect_param_cblk_t +{ + Mutex lock; + volatile uint32_t clientIndex; // Current read/write index for application + volatile uint32_t serverIndex; // Current read/write index for mediaserver + uint8_t* buffer; // start of parameter buffer + + effect_param_cblk_t() + : lock(Mutex::SHARED), clientIndex(0), serverIndex(0) {} +}; + + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_EFFECTCBASESHARED_H diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h index 8e2db20..1510f87 100644 --- a/include/private/media/AudioTrackShared.h +++ b/include/private/media/AudioTrackShared.h @@ -32,6 +32,18 @@ namespace android { #define MAX_RUN_TIMEOUT_MS 1000 #define WAIT_PERIOD_MS 10 +#define CBLK_UNDERRUN_MSK 0x0001 +#define CBLK_UNDERRUN_ON 0x0001 // underrun (out) or overrrun (in) indication +#define CBLK_UNDERRUN_OFF 0x0000 // no underrun +#define CBLK_DIRECTION_MSK 0x0002 +#define CBLK_DIRECTION_OUT 0x0002 // this cblk is for an AudioTrack +#define CBLK_DIRECTION_IN 0x0000 // this cblk is for an AudioRecord +#define CBLK_FORCEREADY_MSK 0x0004 +#define CBLK_FORCEREADY_ON 0x0004 // track is considered ready immediately by AudioFlinger +#define CBLK_FORCEREADY_OFF 0x0000 // track is ready when buffer full +#define CBLK_INVALID_MSK 0x0008 +#define CBLK_INVALID_ON 0x0008 // track buffer is invalidated by AudioFlinger: must be re-created +#define CBLK_INVALID_OFF 0x0000 struct audio_track_cblk_t { @@ -44,12 +56,12 @@ struct audio_track_cblk_t volatile uint32_t server; uint32_t userBase; uint32_t serverBase; - void* buffers; - uint32_t frameCount; - // Cache line boundary - uint32_t loopStart; - uint32_t loopEnd; - int loopCount; + void* buffers; + uint32_t frameCount; + // Cache line boundary + uint32_t loopStart; + uint32_t loopEnd; + int loopCount; volatile union { uint16_t volume[2]; uint32_t volumeLR; @@ -58,15 +70,17 @@ struct audio_track_cblk_t // NOTE: audio_track_cblk_t::frameSize is not equal to AudioTrack::frameSize() for // 8 bit PCM data: in this case, mCblk->frameSize is based on a sample size of // 16 bit because data is converted to 16 bit before being stored in buffer - uint32_t frameSize; - uint8_t channels; - uint8_t flowControlFlag; // underrun (out) or overrrun (in) indication - uint8_t out; // out equals 1 for AudioTrack and 0 for AudioRecord - uint8_t forceReady; + + uint8_t frameSize; + uint8_t channelCount; + uint16_t flags; + uint16_t bufferTimeoutMs; // Maximum cumulated timeout before restarting audioflinger uint16_t waitTimeMs; // Cumulated wait time - // Cache line boundary (32 bytes) + uint16_t sendLevel; + uint16_t reserved; + // Cache line boundary (32 bytes) audio_track_cblk_t(); uint32_t stepUser(uint32_t frameCount); bool stepServer(uint32_t frameCount); diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h index 9b5a1e0..dcce25e 100644 --- a/include/private/surfaceflinger/SharedBufferStack.h +++ b/include/private/surfaceflinger/SharedBufferStack.h @@ -55,12 +55,6 @@ namespace android { * */ -// When changing these values, the COMPILE_TIME_ASSERT at the end of this -// file need to be updated. -const unsigned int NUM_LAYERS_MAX = 31; -const unsigned int NUM_BUFFER_MAX = 4; -const unsigned int NUM_DISPLAY_MAX = 4; - // ---------------------------------------------------------------------------- class Region; @@ -69,7 +63,11 @@ class SharedClient; // ---------------------------------------------------------------------------- -// should be 128 bytes (32 longs) +// 4 * (11 + 7 + (1 + 2*NUM_RECT_MAX) * NUM_BUFFER_MAX) * NUM_LAYERS_MAX +// 4 * (11 + 7 + (1 + 2*7)*16) * 31 +// 1032 * 31 +// = ~27 KiB (31992) + class SharedBufferStack { friend class SharedClient; @@ -78,21 +76,38 @@ class SharedBufferStack friend class SharedBufferServer; public: - struct FlatRegion { // 12 bytes - static const unsigned int NUM_RECT_MAX = 1; - uint32_t count; - uint16_t rects[4*NUM_RECT_MAX]; - }; - + // When changing these values, the COMPILE_TIME_ASSERT at the end of this + // file need to be updated. + static const unsigned int NUM_LAYERS_MAX = 31; + static const unsigned int NUM_BUFFER_MAX = 16; + static const unsigned int NUM_BUFFER_MIN = 2; + static const unsigned int NUM_DISPLAY_MAX = 4; + struct Statistics { // 4 longs typedef int32_t usecs_t; usecs_t totalTime; usecs_t reserved[3]; }; + + struct SmallRect { + uint16_t l, t, r, b; + }; + + struct FlatRegion { // 52 bytes = 4 * (1 + 2*N) + static const unsigned int NUM_RECT_MAX = 6; + uint32_t count; + SmallRect rects[NUM_RECT_MAX]; + }; + + struct BufferData { + FlatRegion dirtyRegion; + SmallRect crop; + }; SharedBufferStack(); void init(int32_t identity); status_t setDirtyRegion(int buffer, const Region& reg); + status_t setCrop(int buffer, const Rect& reg); Region getDirtyRegion(int buffer) const; // these attributes are part of the conditions/updates @@ -104,24 +119,24 @@ public: // not part of the conditions volatile int32_t reallocMask; + volatile int8_t index[NUM_BUFFER_MAX]; int32_t identity; // surface's identity (const) - int32_t reserved32[9]; + int32_t reserved32[2]; Statistics stats; - FlatRegion dirtyRegion[NUM_BUFFER_MAX]; // 12*4=48 bytes + int32_t reserved; + BufferData buffers[NUM_BUFFER_MAX]; // 960 bytes }; // ---------------------------------------------------------------------------- -// 4 KB max +// 32 KB max class SharedClient { public: SharedClient(); ~SharedClient(); - status_t validate(size_t token) const; - uint32_t getIdentity(size_t token) const; private: friend class SharedBufferBase; @@ -131,7 +146,7 @@ private: // FIXME: this should be replaced by a lock-less primitive Mutex lock; Condition cv; - SharedBufferStack surfaces[ NUM_LAYERS_MAX ]; + SharedBufferStack surfaces[ SharedBufferStack::NUM_LAYERS_MAX ]; }; // ============================================================================ @@ -139,18 +154,17 @@ private: class SharedBufferBase { public: - SharedBufferBase(SharedClient* sharedClient, int surface, int num, + SharedBufferBase(SharedClient* sharedClient, int surface, int32_t identity); ~SharedBufferBase(); - uint32_t getIdentity(); status_t getStatus() const; + int32_t getIdentity() const; size_t getFrontBuffer() const; String8 dump(char const* prefix) const; protected: SharedClient* const mSharedClient; SharedBufferStack* const mSharedStack; - const int mNumBuffers; const int mIdentity; friend struct Update; @@ -160,61 +174,22 @@ protected: SharedBufferStack& stack; inline ConditionBase(SharedBufferBase* sbc) : stack(*sbc->mSharedStack) { } + virtual ~ConditionBase() { }; + virtual bool operator()() const = 0; + virtual const char* name() const = 0; }; + status_t waitForCondition(const ConditionBase& condition); struct UpdateBase { SharedBufferStack& stack; inline UpdateBase(SharedBufferBase* sbb) : stack(*sbb->mSharedStack) { } }; - - template <typename T> - status_t waitForCondition(T condition); - template <typename T> status_t updateCondition(T update); }; template <typename T> -status_t SharedBufferBase::waitForCondition(T condition) -{ - const SharedBufferStack& stack( *mSharedStack ); - SharedClient& client( *mSharedClient ); - const nsecs_t TIMEOUT = s2ns(1); - Mutex::Autolock _l(client.lock); - while ((condition()==false) && - (stack.identity == mIdentity) && - (stack.status == NO_ERROR)) - { - status_t err = client.cv.waitRelative(client.lock, TIMEOUT); - - // handle errors and timeouts - if (CC_UNLIKELY(err != NO_ERROR)) { - if (err == TIMED_OUT) { - if (condition()) { - LOGE("waitForCondition(%s) timed out (identity=%d), " - "but condition is true! We recovered but it " - "shouldn't happen." , T::name(), - stack.identity); - break; - } else { - LOGW("waitForCondition(%s) timed out " - "(identity=%d, status=%d). " - "CPU may be pegged. trying again.", T::name(), - stack.identity, stack.status); - } - } else { - LOGE("waitForCondition(%s) error (%s) ", - T::name(), strerror(-err)); - return err; - } - } - } - return (stack.identity != mIdentity) ? status_t(BAD_INDEX) : stack.status; -} - - -template <typename T> status_t SharedBufferBase::updateCondition(T update) { SharedClient& client( *mSharedClient ); Mutex::Autolock _l(client.lock); @@ -238,13 +213,21 @@ public: status_t queue(int buf); bool needNewBuffer(int buffer) const; status_t setDirtyRegion(int buffer, const Region& reg); + status_t setCrop(int buffer, const Rect& reg); + + class SetBufferCountCallback { + friend class SharedBufferClient; + virtual status_t operator()(int bufferCount) const = 0; + protected: + virtual ~SetBufferCountCallback() { } + }; + status_t setBufferCount(int bufferCount, const SetBufferCountCallback& ipc); + private: friend struct Condition; friend struct DequeueCondition; friend struct LockCondition; - - int32_t computeTail() const; struct QueueUpdate : public UpdateBase { inline QueueUpdate(SharedBufferBase* sbb); @@ -260,20 +243,27 @@ private: struct DequeueCondition : public ConditionBase { inline DequeueCondition(SharedBufferClient* sbc); - inline bool operator()(); - static inline const char* name() { return "DequeueCondition"; } + inline bool operator()() const; + inline const char* name() const { return "DequeueCondition"; } }; struct LockCondition : public ConditionBase { int buf; inline LockCondition(SharedBufferClient* sbc, int buf); - inline bool operator()(); - static inline const char* name() { return "LockCondition"; } + inline bool operator()() const; + inline const char* name() const { return "LockCondition"; } }; + int32_t computeTail() const; + + mutable RWLock mLock; + int mNumBuffers; + int32_t tail; + int32_t undoDequeueTail; + int32_t queued_head; // statistics... - nsecs_t mDequeueTime[NUM_BUFFER_MAX]; + nsecs_t mDequeueTime[SharedBufferStack::NUM_BUFFER_MAX]; }; // ---------------------------------------------------------------------------- @@ -287,16 +277,71 @@ public: ssize_t retireAndLock(); status_t unlock(int buffer); void setStatus(status_t status); - status_t reallocate(); + status_t reallocateAll(); + status_t reallocateAllExcept(int buffer); status_t assertReallocate(int buffer); int32_t getQueuedCount() const; - Region getDirtyRegion(int buffer) const; + status_t resize(int newNumBuffers); + SharedBufferStack::Statistics getStats() const; private: + /* + * BufferList is basically a fixed-capacity sorted-vector of + * unsigned 5-bits ints using a 32-bits int as storage. + * it has efficient iterators to find items in the list and not in the list. + */ + class BufferList { + size_t mCapacity; + uint32_t mList; + public: + BufferList(size_t c = SharedBufferStack::NUM_BUFFER_MAX) + : mCapacity(c), mList(0) { } + status_t add(int value); + status_t remove(int value); + uint32_t getMask() const { return mList; } + + class const_iterator { + friend class BufferList; + uint32_t mask, curr; + const_iterator(uint32_t mask) : + mask(mask), curr(__builtin_clz(mask)) { + } + public: + inline bool operator == (const const_iterator& rhs) const { + return mask == rhs.mask; + } + inline bool operator != (const const_iterator& rhs) const { + return mask != rhs.mask; + } + inline int operator *() const { return curr; } + inline const const_iterator& operator ++() { + mask &= ~(1<<(31-curr)); + curr = __builtin_clz(mask); + return *this; + } + }; + + inline const_iterator begin() const { + return const_iterator(mList); + } + inline const_iterator end() const { + return const_iterator(0); + } + inline const_iterator free_begin() const { + uint32_t mask = (1 << (32-mCapacity)) - 1; + return const_iterator( ~(mList | mask) ); + } + }; + + // this protects mNumBuffers and mBufferList + mutable RWLock mLock; + int mNumBuffers; + BufferList mBufferList; + struct UnlockUpdate : public UpdateBase { const int lockedBuffer; inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer); @@ -318,8 +363,8 @@ private: struct ReallocateCondition : public ConditionBase { int buf; inline ReallocateCondition(SharedBufferBase* sbb, int buf); - inline bool operator()(); - static inline const char* name() { return "ReallocateCondition"; } + inline bool operator()() const; + inline const char* name() const { return "ReallocateCondition"; } }; }; @@ -344,13 +389,12 @@ struct surface_flinger_cblk_t // 4KB max uint8_t connected; uint8_t reserved[3]; uint32_t pad[7]; - display_cblk_t displays[NUM_DISPLAY_MAX]; + display_cblk_t displays[SharedBufferStack::NUM_DISPLAY_MAX]; }; // --------------------------------------------------------------------------- -COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 4096) -COMPILE_TIME_ASSERT(sizeof(SharedBufferStack) == 128) +COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 32768) COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096) // --------------------------------------------------------------------------- diff --git a/include/surfaceflinger/ISurface.h b/include/surfaceflinger/ISurface.h index 472f759..ddbe03d 100644 --- a/include/surfaceflinger/ISurface.h +++ b/include/surfaceflinger/ISurface.h @@ -47,13 +47,30 @@ protected: POST_BUFFER, // one-way transaction CREATE_OVERLAY, REQUEST_BUFFER, + SET_BUFFER_COUNT, }; public: DECLARE_META_INTERFACE(Surface); - virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) = 0; + /* + * requests a new buffer for the given index. If w, h, or format are + * null the buffer is created with the parameters assigned to the + * surface it is bound to. Otherwise the buffer's parameters are + * set to those specified. + */ + virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, + uint32_t w, uint32_t h, uint32_t format, uint32_t usage) = 0; + + /* + * sets the number of buffers dequeuable for this surface. + */ + virtual status_t setBufferCount(int bufferCount) = 0; + // ------------------------------------------------------------------------ + // Deprecated... + // ------------------------------------------------------------------------ + class BufferHeap { public: enum { diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h index d1e7785..3271cfd 100644 --- a/include/surfaceflinger/ISurfaceComposer.h +++ b/include/surfaceflinger/ISurfaceComposer.h @@ -27,7 +27,7 @@ #include <ui/PixelFormat.h> -#include <surfaceflinger/ISurfaceFlingerClient.h> +#include <surfaceflinger/ISurfaceComposerClient.h> namespace android { // ---------------------------------------------------------------------------- @@ -86,7 +86,7 @@ public: * ACCESS_SURFACE_FLINGER permission */ - virtual sp<ISurfaceFlingerClient> createConnection() = 0; + virtual sp<ISurfaceComposerClient> createConnection() = 0; /* retrieve the control block */ virtual sp<IMemoryHeap> getCblk() const = 0; diff --git a/include/surfaceflinger/ISurfaceFlingerClient.h b/include/surfaceflinger/ISurfaceComposerClient.h index d257645..b2a4766 100644 --- a/include/surfaceflinger/ISurfaceFlingerClient.h +++ b/include/surfaceflinger/ISurfaceComposerClient.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef ANDROID_SF_ISURFACE_FLINGER_CLIENT_H -#define ANDROID_SF_ISURFACE_FLINGER_CLIENT_H +#ifndef ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H +#define ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H #include <stdint.h> #include <sys/types.h> @@ -26,7 +26,7 @@ #include <binder/IInterface.h> #include <ui/PixelFormat.h> - + #include <surfaceflinger/ISurface.h> namespace android { @@ -42,10 +42,10 @@ typedef int32_t DisplayID; class layer_state_t; -class ISurfaceFlingerClient : public IInterface +class ISurfaceComposerClient : public IInterface { -public: - DECLARE_META_INTERFACE(SurfaceFlingerClient); +public: + DECLARE_META_INTERFACE(SurfaceComposerClient); struct surface_data_t { int32_t token; @@ -56,26 +56,35 @@ public: status_t readFromParcel(const Parcel& parcel); status_t writeToParcel(Parcel* parcel) const; }; - + virtual sp<IMemoryHeap> getControlBlock() const = 0; + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ virtual sp<ISurface> createSurface( surface_data_t* data, - int pid, + int pid, const String8& name, DisplayID display, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) = 0; - + + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ virtual status_t destroySurface(SurfaceID sid) = 0; + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ virtual status_t setState(int32_t count, const layer_state_t* states) = 0; }; // ---------------------------------------------------------------------------- -class BnSurfaceFlingerClient : public BnInterface<ISurfaceFlingerClient> +class BnSurfaceComposerClient : public BnInterface<ISurfaceComposerClient> { public: virtual status_t onTransact( uint32_t code, @@ -88,4 +97,4 @@ public: }; // namespace android -#endif // ANDROID_SF_ISURFACE_FLINGER_CLIENT_H +#endif // ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h index 0279d84..2957970 100644 --- a/include/surfaceflinger/Surface.h +++ b/include/surfaceflinger/Surface.h @@ -28,12 +28,15 @@ #include <ui/egl/android_natives.h> #include <surfaceflinger/ISurface.h> -#include <surfaceflinger/ISurfaceFlingerClient.h> +#include <surfaceflinger/ISurfaceComposerClient.h> + +#define ANDROID_VIEW_SURFACE_JNI_ID "mNativeSurface" namespace android { // --------------------------------------------------------------------------- +class GraphicBuffer; class GraphicBufferMapper; class IOMX; class Rect; @@ -41,6 +44,7 @@ class Surface; class SurfaceComposerClient; class SharedClient; class SharedBufferClient; +class SurfaceClient; // --------------------------------------------------------------------------- @@ -104,7 +108,7 @@ private: SurfaceControl( const sp<SurfaceComposerClient>& client, const sp<ISurface>& surface, - const ISurfaceFlingerClient::surface_data_t& data, + const ISurfaceComposerClient::surface_data_t& data, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags); ~SurfaceControl(); @@ -163,38 +167,36 @@ public: // setSwapRectangle() is intended to be used by GL ES clients void setSwapRectangle(const Rect& r); -private: - // can't be copied - Surface& operator = (Surface& rhs); - Surface(const Surface& rhs); - - Surface(const sp<SurfaceControl>& control); - void init(); - ~Surface(); - - friend class SurfaceComposerClient; - friend class SurfaceControl; - +private: + /* + * Android frameworks friends + * (eventually this should go away and be replaced by proper APIs) + */ // camera and camcorder need access to the ISurface binder interface for preview friend class Camera; friend class MediaRecorder; - // mediaplayer needs access to ISurface for display + // MediaPlayer needs access to ISurface for display friend class MediaPlayer; friend class IOMX; // this is just to be able to write some unit tests friend class Test; - sp<SurfaceComposerClient> getClient() const; - sp<ISurface> getISurface() const; +private: + friend class SurfaceComposerClient; + friend class SurfaceControl; - status_t getBufferLocked(int index, int usage); - - status_t validate() const; + // can't be copied + Surface& operator = (Surface& rhs); + Surface(const Surface& rhs); - inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; } - inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; } - + Surface(const sp<SurfaceControl>& control); + ~Surface(); + + + /* + * android_native_window_t hooks + */ static int setSwapInterval(android_native_window_t* window, int interval); static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer); static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer); @@ -208,21 +210,61 @@ private: int query(int what, int* value); int perform(int operation, va_list args); - status_t dequeueBuffer(sp<GraphicBuffer>* buffer); - void dispatch_setUsage(va_list args); int dispatch_connect(va_list args); int dispatch_disconnect(va_list args); + int dispatch_crop(va_list args); + int dispatch_set_buffer_count(va_list args); + int dispatch_set_buffers_geometry(va_list args); void setUsage(uint32_t reqUsage); int connect(int api); int disconnect(int api); + int crop(Rect const* rect); + int setBufferCount(int bufferCount); + int setBuffersGeometry(int w, int h, int format); - uint32_t getUsage() const; - int getConnectedApi() const; + /* + * private stuff... + */ + void init(); + status_t validate() const; + status_t initCheck() const; + sp<ISurface> getISurface() const; + + inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; } + inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; } + + status_t getBufferLocked(int index, + uint32_t w, uint32_t h, uint32_t format, uint32_t usage); + int getBufferIndex(const sp<GraphicBuffer>& buffer) const; + + int getConnectedApi() const; + bool needNewBuffer(int bufIdx, + uint32_t *pWidth, uint32_t *pHeight, + uint32_t *pFormat, uint32_t *pUsage) const; + + class BufferInfo { + uint32_t mWidth; + uint32_t mHeight; + uint32_t mFormat; + uint32_t mUsage; + mutable uint32_t mDirty; + enum { + GEOMETRY = 0x01 + }; + public: + BufferInfo(); + void set(uint32_t w, uint32_t h, uint32_t format); + void set(uint32_t usage); + void get(uint32_t *pWidth, uint32_t *pHeight, + uint32_t *pFormat, uint32_t *pUsage) const; + bool validateBuffer(const sp<GraphicBuffer>& buffer) const; + }; + // constants - sp<SurfaceComposerClient> mClient; + sp<SurfaceClient> mClient; sp<ISurface> mSurface; SurfaceID mToken; uint32_t mIdentity; @@ -230,22 +272,26 @@ private: uint32_t mFlags; GraphicBufferMapper& mBufferMapper; SharedBufferClient* mSharedBufferClient; + status_t mInitCheck; // protected by mSurfaceLock Rect mSwapRectangle; - uint32_t mUsage; int mConnected; + Rect mNextBufferCrop; + BufferInfo mBufferInfo; // protected by mSurfaceLock. These are also used from lock/unlock // but in that case, they must be called form the same thread. - sp<GraphicBuffer> mBuffers[2]; mutable Region mDirtyRegion; // must be used from the lock/unlock thread sp<GraphicBuffer> mLockedBuffer; sp<GraphicBuffer> mPostedBuffer; mutable Region mOldDirtyRegion; - bool mNeedFullUpdate; + bool mReserved; + + // only used from dequeueBuffer() + Vector< sp<GraphicBuffer> > mBuffers; // query() must be called from dequeueBuffer() thread uint32_t mWidth; diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h index 9d0f0cb..8e28a81 100644 --- a/include/surfaceflinger/SurfaceComposerClient.h +++ b/include/surfaceflinger/SurfaceComposerClient.h @@ -40,7 +40,9 @@ class SharedClient; class ISurfaceComposer; class DisplayInfo; -class SurfaceComposerClient : virtual public RefBase +// --------------------------------------------------------------------------- + +class SurfaceComposerClient : public RefBase { public: SurfaceComposerClient(); @@ -52,10 +54,6 @@ public: // Return the connection of this client sp<IBinder> connection() const; - // Retrieve a client for an existing connection. - static sp<SurfaceComposerClient> - clientForConnection(const sp<IBinder>& conn); - // Forcibly remove connection before all references have gone away. void dispose(); @@ -123,13 +121,6 @@ public: status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient, void* cookie = NULL, uint32_t flags = 0); -private: - friend class Surface; - friend class SurfaceControl; - - SurfaceComposerClient(const sp<ISurfaceComposer>& sm, - const sp<IBinder>& conn); - status_t hide(SurfaceID id); status_t show(SurfaceID id, int32_t layer = -1); status_t freeze(SurfaceID id); @@ -142,32 +133,45 @@ private: status_t setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy); status_t setPosition(SurfaceID id, int32_t x, int32_t y); status_t setSize(SurfaceID id, uint32_t w, uint32_t h); - - void signalServer(); - status_t destroySurface(SurfaceID sid); - void _init(const sp<ISurfaceComposer>& sm, - const sp<ISurfaceFlingerClient>& conn); - - inline layer_state_t* _get_state_l(SurfaceID id); - layer_state_t* _lockLayerState(SurfaceID id); - inline void _unlockLayerState(); +private: + virtual void onFirstRef(); + inline layer_state_t* get_state_l(SurfaceID id); + layer_state_t* lockLayerState(SurfaceID id); + inline void unlockLayerState(); mutable Mutex mLock; - layer_state_t* mPrebuiltLayerState; SortedVector<layer_state_t> mStates; int32_t mTransactionOpen; + layer_state_t* mPrebuiltLayerState; // these don't need to be protected because they never change // after assignment status_t mStatus; - SharedClient* mControl; - sp<IMemoryHeap> mControlMemory; - sp<ISurfaceFlingerClient> mClient; - sp<ISurfaceComposer> mSignalServer; + sp<ISurfaceComposerClient> mClient; }; +// --------------------------------------------------------------------------- + +class SurfaceClient : public RefBase +{ + // all these attributes are constants + status_t mStatus; + SharedClient* mControl; + sp<IMemoryHeap> mControlMemory; + sp<IBinder> mConnection; + sp<ISurfaceComposer> mComposerService; + void init(const sp<IBinder>& conn); +public: + explicit SurfaceClient(const sp<IBinder>& conn); + explicit SurfaceClient(const sp<SurfaceComposerClient>& client); + status_t initCheck() const; + SharedClient* getSharedClient() const; + void signalServer() const; +}; + +// --------------------------------------------------------------------------- }; // namespace android #endif // ANDROID_SF_SURFACE_COMPOSER_CLIENT_H diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h index 741d763..54b8236 100644 --- a/include/ui/GraphicBufferAllocator.h +++ b/include/ui/GraphicBufferAllocator.h @@ -73,9 +73,9 @@ private: struct alloc_rec_t { uint32_t w; uint32_t h; + uint32_t s; PixelFormat format; uint32_t usage; - void* vaddr; size_t size; }; diff --git a/include/ui/android_native_buffer.h b/include/ui/android_native_buffer.h index 9c92af8..402843e 100644 --- a/include/ui/android_native_buffer.h +++ b/include/ui/android_native_buffer.h @@ -33,6 +33,15 @@ typedef struct android_native_buffer_t common.version = sizeof(android_native_buffer_t); memset(common.reserved, 0, sizeof(common.reserved)); } + + // Implement the methods that sp<android_native_buffer_t> expects so that it + // can be used to automatically refcount android_native_buffer_t's. + void incStrong(const void* id) const { + common.incRef(const_cast<android_native_base_t*>(&common)); + } + void decStrong(const void* id) const { + common.decRef(const_cast<android_native_base_t*>(&common)); + } #endif struct android_native_base_t common; diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h index 773fd93..171f3df 100644 --- a/include/ui/egl/android_natives.h +++ b/include/ui/egl/android_natives.h @@ -41,6 +41,14 @@ extern "C" { struct android_native_buffer_t; +typedef struct android_native_rect_t +{ + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +} android_native_rect_t; + // --------------------------------------------------------------------------- typedef struct android_native_base_t @@ -63,15 +71,18 @@ typedef struct android_native_base_t /* attributes queriable with query() */ enum { NATIVE_WINDOW_WIDTH = 0, - NATIVE_WINDOW_HEIGHT = 1, - NATIVE_WINDOW_FORMAT = 2, + NATIVE_WINDOW_HEIGHT, + NATIVE_WINDOW_FORMAT, }; /* valid operations for the (*perform)() hook */ enum { NATIVE_WINDOW_SET_USAGE = 0, - NATIVE_WINDOW_CONNECT = 1, - NATIVE_WINDOW_DISCONNECT = 2 + NATIVE_WINDOW_CONNECT, + NATIVE_WINDOW_DISCONNECT, + NATIVE_WINDOW_SET_CROP, + NATIVE_WINDOW_SET_BUFFER_COUNT, + NATIVE_WINDOW_SET_BUFFERS_GEOMETRY, }; /* parameter for NATIVE_WINDOW_[DIS]CONNECT */ @@ -89,6 +100,15 @@ typedef struct android_native_window_t common.version = sizeof(android_native_window_t); memset(common.reserved, 0, sizeof(common.reserved)); } + + // Implement the methods that sp<android_native_window_t> expects so that it + // can be used to automatically refcount android_native_window_t's. + void incStrong(const void* id) const { + common.incRef(const_cast<android_native_base_t*>(&common)); + } + void decStrong(const void* id) const { + common.decRef(const_cast<android_native_base_t*>(&common)); + } #endif struct android_native_base_t common; @@ -125,7 +145,7 @@ typedef struct android_native_window_t * * Returns 0 on success or -errno on error. */ - int (*dequeueBuffer)(struct android_native_window_t* window, + int (*dequeueBuffer)(struct android_native_window_t* window, struct android_native_buffer_t** buffer); /* @@ -171,6 +191,9 @@ typedef struct android_native_window_t * NATIVE_WINDOW_SET_USAGE * NATIVE_WINDOW_CONNECT * NATIVE_WINDOW_DISCONNECT + * NATIVE_WINDOW_SET_CROP + * NATIVE_WINDOW_SET_BUFFER_COUNT + * NATIVE_WINDOW_SET_BUFFERS_GEOMETRY * */ @@ -182,8 +205,9 @@ typedef struct android_native_window_t /* - * native_window_set_usage() sets the intended usage flags for the next - * buffers acquired with (*lockBuffer)() and on. + * native_window_set_usage(..., usage) + * Sets the intended usage flags for the next buffers + * acquired with (*lockBuffer)() and on. * By default (if this function is never called), a usage of * GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE * is assumed. @@ -198,8 +222,8 @@ static inline int native_window_set_usage( } /* - * native_window_connect(..., NATIVE_WINDOW_API_EGL) must be called - * by EGL when the window is made current. + * native_window_connect(..., NATIVE_WINDOW_API_EGL) + * Must be called by EGL when the window is made current. * Returns -EINVAL if for some reason the window cannot be connected, which * can happen if it's connected to some other API. */ @@ -210,8 +234,8 @@ static inline int native_window_connect( } /* - * native_window_disconnect(..., NATIVE_WINDOW_API_EGL) must be called - * by EGL when the window is made not current. + * native_window_disconnect(..., NATIVE_WINDOW_API_EGL) + * Must be called by EGL when the window is made not current. * An error is returned if for instance the window wasn't connected in the * first place. */ @@ -221,6 +245,54 @@ static inline int native_window_disconnect( return window->perform(window, NATIVE_WINDOW_DISCONNECT, api); } +/* + * native_window_set_crop(..., crop) + * Sets which region of the next queued buffers needs to be considered. + * A buffer's crop region is scaled to match the surface's size. + * + * The specified crop region applies to all buffers queued after it is called. + * + * if 'crop' is NULL, subsequently queued buffers won't be cropped. + * + * An error is returned if for instance the crop region is invalid, + * out of the buffer's bound or if the window is invalid. + */ +static inline int native_window_set_crop( + android_native_window_t* window, + android_native_rect_t const * crop) +{ + return window->perform(window, NATIVE_WINDOW_SET_CROP, crop); +} + +/* + * native_window_set_buffer_count(..., count) + * Sets the number of buffers associated with this native window. + */ +static inline int native_window_set_buffer_count( + android_native_window_t* window, + size_t bufferCount) +{ + return window->perform(window, NATIVE_WINDOW_SET_BUFFER_COUNT, bufferCount); +} + +/* + * native_window_set_buffers_geometry(..., int w, int h, int format) + * All buffers dequeued after this call will have the geometry specified. + * In particular, all buffers will have a fixed-size, independent form the + * native-window size. They will be appropriately scaled to the window-size + * upon composition. + * + * If all parameters are 0, the normal behavior is restored. That is, + * dequeued buffers following this call will be sized to the window's size. + * + */ +static inline int native_window_set_buffers_geometry( + android_native_window_t* window, + int w, int h, int format) +{ + return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY, + w, h, format); +} // --------------------------------------------------------------------------- @@ -263,6 +335,15 @@ namespace android { template <typename NATIVE_TYPE, typename TYPE, typename REF> class EGLNativeBase : public NATIVE_TYPE, public REF { +public: + // Disambiguate between the incStrong in REF and NATIVE_TYPE + void incStrong(const void* id) const { + REF::incStrong(id); + } + void decStrong(const void* id) const { + REF::decStrong(id); + } + protected: typedef EGLNativeBase<NATIVE_TYPE, TYPE, REF> BASE; EGLNativeBase() : NATIVE_TYPE(), REF() { diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h index b701ce7..c7d9ff1 100644 --- a/include/utils/ResourceTypes.h +++ b/include/utils/ResourceTypes.h @@ -933,6 +933,7 @@ struct ResTable_config SCREENSIZE_SMALL = 0x01, SCREENSIZE_NORMAL = 0x02, SCREENSIZE_LARGE = 0x03, + SCREENSIZE_XLARGE = 0x04, // screenLayout bits for wide/long screen variation. MASK_SCREENLONG = 0x30, @@ -1208,7 +1209,28 @@ struct ResTable_config if (screenLayout || o.screenLayout) { if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0 && (requested->screenLayout & MASK_SCREENSIZE)) { - return (screenLayout & MASK_SCREENSIZE); + // A little backwards compatibility here: undefined is + // considered equivalent to normal. But only if the + // requested size is at least normal; otherwise, small + // is better than the default. + int mySL = (screenLayout & MASK_SCREENSIZE); + int oSL = (o.screenLayout & MASK_SCREENSIZE); + int fixedMySL = mySL; + int fixedOSL = oSL; + if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) { + if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL; + if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL; + } + // For screen size, the best match is the one that is + // closest to the requested screen size, but not over + // (the not over part is dealt with in match() below). + if (fixedMySL == fixedOSL) { + // If the two are the same, but 'this' is actually + // undefined, then the other is really a better match. + if (mySL == 0) return false; + return true; + } + return fixedMySL >= fixedOSL; } if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0 && (requested->screenLayout & MASK_SCREENLONG)) { @@ -1370,8 +1392,11 @@ struct ResTable_config if (screenConfig != 0) { const int screenSize = screenLayout&MASK_SCREENSIZE; const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE; - if (setScreenSize != 0 && screenSize != 0 - && screenSize != setScreenSize) { + // Any screen sizes for larger screens than the setting do not + // match. + if ((setScreenSize != 0 && screenSize != 0 + && screenSize > setScreenSize) || + (setScreenSize == 0 && screenSize != 0)) { return false; } diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h index bc7626a8..3b975b4 100644 --- a/include/utils/Singleton.h +++ b/include/utils/Singleton.h @@ -54,11 +54,13 @@ private: * (eg: <TYPE>.cpp) to create the static instance of Singleton<>'s attributes, * and avoid to have a copy of them in each compilation units Singleton<TYPE> * is used. + * NOTE: we use a version of Mutex ctor that takes a parameter, because + * for some unknown reason using the default ctor doesn't emit the variable! */ -#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \ - template class Singleton< TYPE >; \ - template< class TYPE > Mutex Singleton< TYPE >::sLock; \ +#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \ + template class Singleton< TYPE >; \ + template<> Mutex Singleton< TYPE >::sLock(Mutex::PRIVATE); \ template<> TYPE* Singleton< TYPE >::sInstance(0); diff --git a/include/utils/ZipFileCRO.h b/include/utils/ZipFileCRO.h index 30e0036..e38bf66 100644 --- a/include/utils/ZipFileCRO.h +++ b/include/utils/ZipFileCRO.h @@ -47,8 +47,8 @@ extern ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zip, const char* fileName); extern bool ZipFileCRO_getEntryInfo(ZipFileCRO zip, ZipEntryCRO entry, - int* pMethod, long* pUncompLen, - long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32); + int* pMethod, size_t* pUncompLen, + size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32); extern bool ZipFileCRO_uncompressEntry(ZipFileCRO zip, ZipEntryCRO entry, int fd); diff --git a/include/utils/ZipFileRO.h b/include/utils/ZipFileRO.h index 51c4f2f..97d31f4 100644 --- a/include/utils/ZipFileRO.h +++ b/include/utils/ZipFileRO.h @@ -58,14 +58,19 @@ typedef void* ZipEntryRO; class ZipFileRO { public: ZipFileRO() - : mFd(-1), mFileMap(NULL), mHashTableSize(-1), mHashTable(NULL) + : mFd(-1), mFileName(NULL), mFileLength(-1), + mDirectoryMap(NULL), + mNumEntries(-1), mDirectoryOffset(-1), + mHashTableSize(-1), mHashTable(NULL) {} ~ZipFileRO() { free(mHashTable); - if (mFileMap) - mFileMap->release(); + if (mDirectoryMap) + mDirectoryMap->release(); if (mFd >= 0) close(mFd); + if (mFileName) + free(mFileName); } /* @@ -118,8 +123,8 @@ public: * Returns "false" if "entry" is bogus or if the data in the Zip file * appears to be bad. */ - bool getEntryInfo(ZipEntryRO entry, int* pMethod, long* pUncompLen, - long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const; + bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen, + size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const; /* * Create a new FileMap object that maps a subset of the archive. For @@ -155,13 +160,13 @@ public: * Utility function: uncompress deflated data, buffer to buffer. */ static bool inflateBuffer(void* outBuf, const void* inBuf, - long uncompLen, long compLen); + size_t uncompLen, size_t compLen); /* * Utility function: uncompress deflated data, buffer to fd. */ static bool inflateBuffer(int fd, const void* inBuf, - long uncompLen, long compLen); + size_t uncompLen, size_t compLen); /* * Some basic functions for raw data manipulation. "LE" means @@ -179,6 +184,9 @@ private: ZipFileRO(const ZipFileRO& src); ZipFileRO& operator=(const ZipFileRO& src); + /* locate and parse the central directory */ + bool mapCentralDirectory(void); + /* parse the archive, prepping internal structures */ bool parseZipArchive(void); @@ -203,12 +211,21 @@ private: /* open Zip archive */ int mFd; + /* zip file name */ + char* mFileName; + + /* length of file */ + size_t mFileLength; + /* mapped file */ - FileMap* mFileMap; + FileMap* mDirectoryMap; /* number of entries in the Zip archive */ int mNumEntries; + /* CD directory offset in the Zip archive */ + off_t mDirectoryOffset; + /* * We know how many entries are in the Zip archive, so we have a * fixed-size hash table. We probe for an empty slot. diff --git a/include/utils/threads.h b/include/utils/threads.h index 5ac0c5e..1bcfaed 100644 --- a/include/utils/threads.h +++ b/include/utils/threads.h @@ -295,6 +295,96 @@ typedef Mutex::Autolock AutoMutex; /*****************************************************************************/ +#if defined(HAVE_PTHREADS) + +/* + * Simple mutex class. The implementation is system-dependent. + * + * The mutex must be unlocked by the thread that locked it. They are not + * recursive, i.e. the same thread can't lock it multiple times. + */ +class RWLock { +public: + enum { + PRIVATE = 0, + SHARED = 1 + }; + + RWLock(); + RWLock(const char* name); + RWLock(int type, const char* name = NULL); + ~RWLock(); + + status_t readLock(); + status_t tryReadLock(); + status_t writeLock(); + status_t tryWriteLock(); + void unlock(); + + class AutoRLock { + public: + inline AutoRLock(RWLock& rwlock) : mLock(rwlock) { mLock.readLock(); } + inline ~AutoRLock() { mLock.unlock(); } + private: + RWLock& mLock; + }; + + class AutoWLock { + public: + inline AutoWLock(RWLock& rwlock) : mLock(rwlock) { mLock.writeLock(); } + inline ~AutoWLock() { mLock.unlock(); } + private: + RWLock& mLock; + }; + +private: + // A RWLock cannot be copied + RWLock(const RWLock&); + RWLock& operator = (const RWLock&); + + pthread_rwlock_t mRWLock; +}; + +inline RWLock::RWLock() { + pthread_rwlock_init(&mRWLock, NULL); +} +inline RWLock::RWLock(const char* name) { + pthread_rwlock_init(&mRWLock, NULL); +} +inline RWLock::RWLock(int type, const char* name) { + if (type == SHARED) { + pthread_rwlockattr_t attr; + pthread_rwlockattr_init(&attr); + pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + pthread_rwlock_init(&mRWLock, &attr); + pthread_rwlockattr_destroy(&attr); + } else { + pthread_rwlock_init(&mRWLock, NULL); + } +} +inline RWLock::~RWLock() { + pthread_rwlock_destroy(&mRWLock); +} +inline status_t RWLock::readLock() { + return -pthread_rwlock_rdlock(&mRWLock); +} +inline status_t RWLock::tryReadLock() { + return -pthread_rwlock_tryrdlock(&mRWLock); +} +inline status_t RWLock::writeLock() { + return -pthread_rwlock_wrlock(&mRWLock); +} +inline status_t RWLock::tryWriteLock() { + return -pthread_rwlock_trywrlock(&mRWLock); +} +inline void RWLock::unlock() { + pthread_rwlock_unlock(&mRWLock); +} + +#endif // HAVE_PTHREADS + +/*****************************************************************************/ + /* * Condition variable class. The implementation is system-dependent. * |