Moved headers from include/ to appropriate libs
include/camera -> camera/include/camera
include/media/audiohal -> media/libaudiohal/include
include/media/AudioResampler*.h -> media/libaudioprocessing/include
include/media/Audio*.h,IAudio*.h,IEffect*.h,ToneGenerator.h -> media/libaudioclient/include
include/media/EffectsFactoryApi.h -> media/libeffects/include
include/media/stagefright -> media/libstagefright/include
include/media/nbaio -> media/libnbaio/include
include/media/<rest of files> -> media/libmedia/include
include/cpustats -> media/libcpustats/include/cpustats
Added symlinks from old location to new ones
Bug: 33241851
Test: VNDK linked modules will need to add explicit lib dep.
All other modules should compile the same
Change-Id: I0ecf754a2132640ae781a3cc31428fb8c0bd1669
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 03dce0c..ad130e0 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -26,6 +26,8 @@
"libaudioutils",
],
export_shared_lib_headers: ["libbinder"],
+ local_include_dirs: ["include"],
+ export_include_dirs: ["include"],
// for memory heap analysis
static_libs: [
"libc_malloc_debug_backtrace",
diff --git a/media/libaudioclient/include/AudioBufferProvider.h b/media/libaudioclient/include/AudioBufferProvider.h
new file mode 100644
index 0000000..458d170
--- /dev/null
+++ b/media/libaudioclient/include/AudioBufferProvider.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007 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_AUDIO_BUFFER_PROVIDER_H
+#define ANDROID_AUDIO_BUFFER_PROVIDER_H
+
+#include <utils/Errors.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class AudioBufferProvider
+{
+public:
+
+ // FIXME merge with AudioTrackShared::Buffer, AudioTrack::Buffer, and AudioRecord::Buffer
+ // and rename getNextBuffer() to obtainBuffer()
+ struct Buffer {
+ Buffer() : raw(NULL), frameCount(0) { }
+ union {
+ void* raw;
+ short* i16;
+ int8_t* i8;
+ };
+ size_t frameCount;
+ };
+
+ virtual ~AudioBufferProvider() {}
+
+ // On entry:
+ // buffer != NULL
+ // buffer->raw unused
+ // buffer->frameCount maximum number of desired frames
+ // On successful return:
+ // status NO_ERROR
+ // buffer->raw non-NULL pointer to buffer->frameCount contiguous available frames
+ // buffer->frameCount number of contiguous available frames at buffer->raw,
+ // 0 < buffer->frameCount <= entry value
+ // On error return:
+ // status != NO_ERROR
+ // buffer->raw NULL
+ // buffer->frameCount 0
+ virtual status_t getNextBuffer(Buffer* buffer) = 0;
+
+ // Release (a portion of) the buffer previously obtained by getNextBuffer().
+ // It is permissible to call releaseBuffer() multiple times per getNextBuffer().
+ // On entry:
+ // buffer->frameCount number of frames to release, must be <= number of frames
+ // obtained but not yet released
+ // buffer->raw unused
+ // On return:
+ // buffer->frameCount 0; implementation MUST set to zero
+ // buffer->raw undefined; implementation is PERMITTED to set to any value,
+ // so if caller needs to continue using this buffer it must
+ // keep track of the pointer itself
+ virtual void releaseBuffer(Buffer* buffer) = 0;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_AUDIO_BUFFER_PROVIDER_H
diff --git a/media/libaudioclient/include/AudioEffect.h b/media/libaudioclient/include/AudioEffect.h
new file mode 100644
index 0000000..bfc068b
--- /dev/null
+++ b/media/libaudioclient/include/AudioEffect.h
@@ -0,0 +1,488 @@
+/*
+ * Copyright (C) 2009 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_AUDIOEFFECT_H
+#define ANDROID_AUDIOEFFECT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <media/IAudioFlinger.h>
+#include <media/IAudioPolicyService.h>
+#include <media/IEffect.h>
+#include <media/IEffectClient.h>
+#include <media/AudioSystem.h>
+#include <system/audio_effect.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <binder/IInterface.h>
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+struct effect_param_cblk_t;
+
+// ----------------------------------------------------------------------------
+
+class AudioEffect : public RefBase
+{
+public:
+
+ /*
+ * Static methods for effects enumeration.
+ */
+
+ /*
+ * Returns the number of effects available. This method together
+ * with queryEffect() is used to enumerate all effects:
+ * The enumeration sequence is:
+ * queryNumberEffects(&num_effects);
+ * for (i = 0; i < num_effects; i++)
+ * queryEffect(i,...);
+ *
+ * Parameters:
+ * numEffects: address where the number of effects should be returned.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * NO_ERROR successful operation.
+ * PERMISSION_DENIED could not get AudioFlinger interface
+ * NO_INIT effect library failed to initialize
+ * BAD_VALUE invalid numEffects pointer
+ *
+ * Returned value
+ * *numEffects: updated with number of effects available
+ */
+ static status_t queryNumberEffects(uint32_t *numEffects);
+
+ /*
+ * Returns an effect descriptor during effect
+ * enumeration.
+ *
+ * Parameters:
+ * index: index of the queried effect.
+ * descriptor: address where the effect descriptor should be returned.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * NO_ERROR successful operation.
+ * PERMISSION_DENIED could not get AudioFlinger interface
+ * NO_INIT effect library failed to initialize
+ * BAD_VALUE invalid descriptor pointer or index
+ * INVALID_OPERATION effect list has changed since last execution of queryNumberEffects()
+ *
+ * Returned value
+ * *descriptor: updated with effect descriptor
+ */
+ static status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor);
+
+
+ /*
+ * Returns the descriptor for the specified effect uuid.
+ *
+ * Parameters:
+ * uuid: pointer to effect uuid.
+ * descriptor: address where the effect descriptor should be returned.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * NO_ERROR successful operation.
+ * PERMISSION_DENIED could not get AudioFlinger interface
+ * NO_INIT effect library failed to initialize
+ * BAD_VALUE invalid uuid or descriptor pointers
+ * NAME_NOT_FOUND no effect with this uuid found
+ *
+ * Returned value
+ * *descriptor updated with effect descriptor
+ */
+ static status_t getEffectDescriptor(const effect_uuid_t *uuid,
+ effect_descriptor_t *descriptor) /*const*/;
+
+
+ /*
+ * Returns a list of descriptors corresponding to the pre processings enabled by default
+ * on an AudioRecord with the supplied audio session ID.
+ *
+ * Parameters:
+ * audioSession: audio session ID.
+ * descriptors: address where the effect descriptors should be returned.
+ * count: as input, the maximum number of descriptor than should be returned
+ * as output, the number of descriptor returned if status is NO_ERROR or the actual
+ * number of enabled pre processings if status is NO_MEMORY
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * NO_ERROR successful operation.
+ * NO_MEMORY the number of descriptor to return is more than the maximum number
+ * indicated by count.
+ * PERMISSION_DENIED could not get AudioFlinger interface
+ * NO_INIT effect library failed to initialize
+ * BAD_VALUE invalid audio session or descriptor pointers
+ *
+ * Returned value
+ * *descriptor updated with descriptors of pre processings enabled by default
+ * *count number of descriptors returned if returned status is NO_ERROR.
+ * total number of pre processing enabled by default if returned status is
+ * NO_MEMORY. This happens if the count passed as input is less than the number
+ * of descriptors to return.
+ * *count is limited to kMaxPreProcessing on return.
+ */
+ static status_t queryDefaultPreProcessing(audio_session_t audioSession,
+ effect_descriptor_t *descriptors,
+ uint32_t *count);
+
+ /*
+ * Events used by callback function (effect_callback_t).
+ */
+ enum event_type {
+ EVENT_CONTROL_STATUS_CHANGED = 0,
+ EVENT_ENABLE_STATUS_CHANGED = 1,
+ EVENT_PARAMETER_CHANGED = 2,
+ EVENT_ERROR = 3
+ };
+
+ /* Callback function notifying client application of a change in effect engine state or
+ * configuration.
+ * An effect engine can be shared by several applications but only one has the control
+ * of the engine activity and configuration at a time.
+ * The EVENT_CONTROL_STATUS_CHANGED event is received when an application loses or
+ * retrieves the control of the effect engine. Loss of control happens
+ * if another application requests the use of the engine by creating an AudioEffect for
+ * the same effect type but with a higher priority. Control is returned when the
+ * application having the control deletes its AudioEffect object.
+ * The EVENT_ENABLE_STATUS_CHANGED event is received by all applications not having the
+ * control of the effect engine when the effect is enabled or disabled.
+ * The EVENT_PARAMETER_CHANGED event is received by all applications not having the
+ * control of the effect engine when an effect parameter is changed.
+ * The EVENT_ERROR event is received when the media server process dies.
+ *
+ * Parameters:
+ *
+ * event: type of event notified (see enum AudioEffect::event_type).
+ * user: Pointer to context for use by the callback receiver.
+ * info: Pointer to optional parameter according to event type:
+ * - EVENT_CONTROL_STATUS_CHANGED: boolean indicating if control is granted (true)
+ * or stolen (false).
+ * - EVENT_ENABLE_STATUS_CHANGED: boolean indicating if effect is now enabled (true)
+ * or disabled (false).
+ * - EVENT_PARAMETER_CHANGED: pointer to a effect_param_t structure.
+ * - EVENT_ERROR: status_t indicating the error (DEAD_OBJECT when media server dies).
+ */
+
+ typedef void (*effect_callback_t)(int32_t event, void* user, void *info);
+
+
+ /* Constructor.
+ * AudioEffect is the base class for creating and controlling an effect engine from
+ * the application process. Creating an AudioEffect object will create the effect engine
+ * in the AudioFlinger if no engine of the specified type exists. If one exists, this engine
+ * will be used. The application creating the AudioEffect object (or a derived class like
+ * Reverb for instance) will either receive control of the effect engine or not, depending
+ * on the priority parameter. If priority is higher than the priority used by the current
+ * effect engine owner, the control will be transfered to the new application. Otherwise
+ * control will remain to the previous application. In this case, the new application will be
+ * notified of changes in effect engine state or control ownership by the effect callback.
+ * After creating the AudioEffect, the application must call the initCheck() method and
+ * check the creation status before trying to control the effect engine (see initCheck()).
+ * If the effect is to be applied to an AudioTrack or MediaPlayer only the application
+ * must specify the audio session ID corresponding to this player.
+ */
+
+ /* Simple Constructor.
+ *
+ * Parameters:
+ *
+ * opPackageName: The package name used for app op checks.
+ */
+ AudioEffect(const String16& opPackageName);
+
+
+ /* Constructor.
+ *
+ * Parameters:
+ *
+ * type: type of effect created: can be null if uuid is specified. This corresponds to
+ * the OpenSL ES interface implemented by this effect.
+ * opPackageName: The package name used for app op checks.
+ * uuid: Uuid of effect created: can be null if type is specified. This uuid corresponds to
+ * a particular implementation of an effect type.
+ * priority: requested priority for effect control: the priority level corresponds to the
+ * value of priority parameter: negative values indicate lower priorities, positive values
+ * higher priorities, 0 being the normal priority.
+ * cbf: optional callback function (see effect_callback_t)
+ * user: pointer to context for use by the callback receiver.
+ * sessionID: audio session this effect is associated to.
+ * If equal to AUDIO_SESSION_OUTPUT_MIX, the effect will be global to
+ * the output mix. Otherwise, the effect will be applied to all players
+ * (AudioTrack or MediaPLayer) within the same audio session.
+ * io: HAL audio output or input stream to which this effect must be attached. Leave at 0 for
+ * automatic output selection by AudioFlinger.
+ */
+
+ AudioEffect(const effect_uuid_t *type,
+ const String16& opPackageName,
+ const effect_uuid_t *uuid = NULL,
+ int32_t priority = 0,
+ effect_callback_t cbf = NULL,
+ void* user = NULL,
+ audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
+ audio_io_handle_t io = AUDIO_IO_HANDLE_NONE
+ );
+
+ /* Constructor.
+ * Same as above but with type and uuid specified by character strings
+ */
+ AudioEffect(const char *typeStr,
+ const String16& opPackageName,
+ const char *uuidStr = NULL,
+ int32_t priority = 0,
+ effect_callback_t cbf = NULL,
+ void* user = NULL,
+ audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
+ audio_io_handle_t io = AUDIO_IO_HANDLE_NONE
+ );
+
+ /* Terminates the AudioEffect and unregisters it from AudioFlinger.
+ * The effect engine is also destroyed if this AudioEffect was the last controlling
+ * the engine.
+ */
+ ~AudioEffect();
+
+ /* Initialize an uninitialized AudioEffect.
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR or ALREADY_EXISTS: successful initialization
+ * - INVALID_OPERATION: AudioEffect is already initialized
+ * - BAD_VALUE: invalid parameter
+ * - NO_INIT: audio flinger or audio hardware not initialized
+ * */
+ status_t set(const effect_uuid_t *type,
+ const effect_uuid_t *uuid = NULL,
+ int32_t priority = 0,
+ effect_callback_t cbf = NULL,
+ void* user = NULL,
+ audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
+ audio_io_handle_t io = AUDIO_IO_HANDLE_NONE
+ );
+
+ /* Result of constructing the AudioEffect. This must be checked
+ * before using any AudioEffect API.
+ * initCheck() can return:
+ * - NO_ERROR: the effect engine is successfully created and the application has control.
+ * - ALREADY_EXISTS: the effect engine is successfully created but the application does not
+ * have control.
+ * - NO_INIT: the effect creation failed.
+ *
+ */
+ status_t initCheck() const;
+
+
+ /* Returns the unique effect Id for the controlled effect engine. This ID is unique
+ * system wide and is used for instance in the case of auxiliary effects to attach
+ * the effect to an AudioTrack or MediaPlayer.
+ *
+ */
+ int32_t id() const { return mId; }
+
+ /* Returns a descriptor for the effect (see effect_descriptor_t in audio_effect.h).
+ */
+ effect_descriptor_t descriptor() const;
+
+ /* Returns effect control priority of this AudioEffect object.
+ */
+ int32_t priority() const { return mPriority; }
+
+
+ /* Enables or disables the effect engine.
+ *
+ * Parameters:
+ * enabled: requested enable state.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - INVALID_OPERATION: the application does not have control of the effect engine or the
+ * effect is already in the requested state.
+ */
+ virtual status_t setEnabled(bool enabled);
+ bool getEnabled() const;
+
+ /* Sets a parameter value.
+ *
+ * Parameters:
+ * param: pointer to effect_param_t structure containing the parameter
+ * and its value (See audio_effect.h).
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation.
+ * - INVALID_OPERATION: the application does not have control of the effect engine.
+ * - BAD_VALUE: invalid parameter identifier or value.
+ * - DEAD_OBJECT: the effect engine has been deleted.
+ */
+ virtual status_t setParameter(effect_param_t *param);
+
+ /* Prepare a new parameter value that will be set by next call to
+ * setParameterCommit(). This method can be used to set multiple parameters
+ * in a synchronous manner or to avoid multiple binder calls for each
+ * parameter.
+ *
+ * Parameters:
+ * param: pointer to effect_param_t structure containing the parameter
+ * and its value (See audio_effect.h).
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation.
+ * - INVALID_OPERATION: the application does not have control of the effect engine.
+ * - NO_MEMORY: no more space available in shared memory used for deferred parameter
+ * setting.
+ */
+ virtual status_t setParameterDeferred(effect_param_t *param);
+
+ /* Commit all parameter values previously prepared by setParameterDeferred().
+ *
+ * Parameters:
+ * none
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation.
+ * - INVALID_OPERATION: No new parameter values ready for commit.
+ * - BAD_VALUE: invalid parameter identifier or value: there is no indication
+ * as to which of the parameters caused this error.
+ * - DEAD_OBJECT: the effect engine has been deleted.
+ */
+ virtual status_t setParameterCommit();
+
+ /* Gets a parameter value.
+ *
+ * Parameters:
+ * param: pointer to effect_param_t structure containing the parameter
+ * and the returned value (See audio_effect.h).
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation.
+ * - INVALID_OPERATION: the AudioEffect was not successfully initialized.
+ * - BAD_VALUE: invalid parameter identifier.
+ * - DEAD_OBJECT: the effect engine has been deleted.
+ */
+ virtual status_t getParameter(effect_param_t *param);
+
+ /* Sends a command and receives a response to/from effect engine.
+ * See audio_effect.h for details on effect command() function, valid command codes
+ * and formats.
+ */
+ virtual status_t command(uint32_t cmdCode,
+ uint32_t cmdSize,
+ void *cmdData,
+ uint32_t *replySize,
+ void *replyData);
+
+
+ /*
+ * Utility functions.
+ */
+
+ /* Converts the string passed as first argument to the effect_uuid_t
+ * pointed to by second argument
+ */
+ static status_t stringToGuid(const char *str, effect_uuid_t *guid);
+ /* Converts the effect_uuid_t pointed to by first argument to the
+ * string passed as second argument
+ */
+ static status_t guidToString(const effect_uuid_t *guid, char *str, size_t maxLen);
+
+ // kMaxPreProcessing is a reasonable value for the maximum number of preprocessing effects
+ // that can be applied simultaneously.
+ static const uint32_t kMaxPreProcessing = 10;
+
+protected:
+ bool mEnabled; // enable state
+ audio_session_t mSessionId; // audio session ID
+ int32_t mPriority; // priority for effect control
+ status_t mStatus; // effect status
+ effect_callback_t mCbf; // callback function for status, control and
+ // parameter changes notifications
+ void* mUserData; // client context for callback function
+ effect_descriptor_t mDescriptor; // effect descriptor
+ int32_t mId; // system wide unique effect engine instance ID
+ Mutex mLock; // Mutex for mEnabled access
+
+ String16 mOpPackageName; // The package name used for app op checks.
+
+ // IEffectClient
+ virtual void controlStatusChanged(bool controlGranted);
+ virtual void enableStatusChanged(bool enabled);
+ virtual void commandExecuted(uint32_t cmdCode,
+ uint32_t cmdSize,
+ void *pCmdData,
+ uint32_t replySize,
+ void *pReplyData);
+
+private:
+
+ // Implements the IEffectClient interface
+ class EffectClient :
+ public android::BnEffectClient, public android::IBinder::DeathRecipient
+ {
+ public:
+
+ EffectClient(AudioEffect *effect) : mEffect(effect){}
+
+ // IEffectClient
+ virtual void controlStatusChanged(bool controlGranted) {
+ sp<AudioEffect> effect = mEffect.promote();
+ if (effect != 0) {
+ effect->controlStatusChanged(controlGranted);
+ }
+ }
+ virtual void enableStatusChanged(bool enabled) {
+ sp<AudioEffect> effect = mEffect.promote();
+ if (effect != 0) {
+ effect->enableStatusChanged(enabled);
+ }
+ }
+ virtual void commandExecuted(uint32_t cmdCode,
+ uint32_t cmdSize,
+ void *pCmdData,
+ uint32_t replySize,
+ void *pReplyData) {
+ sp<AudioEffect> effect = mEffect.promote();
+ if (effect != 0) {
+ effect->commandExecuted(
+ cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+ }
+ }
+
+ // IBinder::DeathRecipient
+ virtual void binderDied(const wp<IBinder>& /*who*/) {
+ sp<AudioEffect> effect = mEffect.promote();
+ if (effect != 0) {
+ effect->binderDied();
+ }
+ }
+
+ private:
+ wp<AudioEffect> mEffect;
+ };
+
+ void binderDied();
+
+ sp<IEffect> mIEffect; // IEffect binder interface
+ sp<EffectClient> mIEffectClient; // IEffectClient implementation
+ sp<IMemory> mCblkMemory; // shared memory for deferred parameter setting
+ effect_param_cblk_t* mCblk; // control block for deferred parameter setting
+ pid_t mClientPid;
+};
+
+
+}; // namespace android
+
+#endif // ANDROID_AUDIOEFFECT_H
diff --git a/media/libaudioclient/include/AudioIoDescriptor.h b/media/libaudioclient/include/AudioIoDescriptor.h
new file mode 100644
index 0000000..fed86c9
--- /dev/null
+++ b/media/libaudioclient/include/AudioIoDescriptor.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 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_AUDIO_IO_DESCRIPTOR_H
+#define ANDROID_AUDIO_IO_DESCRIPTOR_H
+
+namespace android {
+
+enum audio_io_config_event {
+ AUDIO_OUTPUT_OPENED,
+ AUDIO_OUTPUT_CLOSED,
+ AUDIO_OUTPUT_CONFIG_CHANGED,
+ AUDIO_INPUT_OPENED,
+ AUDIO_INPUT_CLOSED,
+ AUDIO_INPUT_CONFIG_CHANGED,
+};
+
+// audio input/output descriptor used to cache output configurations in client process to avoid
+// frequent calls through IAudioFlinger
+class AudioIoDescriptor : public RefBase {
+public:
+ AudioIoDescriptor() :
+ mIoHandle(AUDIO_IO_HANDLE_NONE),
+ mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(AUDIO_CHANNEL_NONE),
+ mFrameCount(0), mFrameCountHAL(0), mLatency(0)
+ {
+ memset(&mPatch, 0, sizeof(struct audio_patch));
+ }
+
+ virtual ~AudioIoDescriptor() {}
+
+ audio_port_handle_t getDeviceId() {
+ if (mPatch.num_sources != 0 && mPatch.num_sinks != 0) {
+ if (mPatch.sources[0].type == AUDIO_PORT_TYPE_MIX) {
+ // this is an output mix
+ // FIXME: the API only returns the first device in case of multiple device selection
+ return mPatch.sinks[0].id;
+ } else {
+ // this is an input mix
+ return mPatch.sources[0].id;
+ }
+ }
+ return AUDIO_PORT_HANDLE_NONE;
+ }
+
+ audio_io_handle_t mIoHandle;
+ struct audio_patch mPatch;
+ uint32_t mSamplingRate;
+ audio_format_t mFormat;
+ audio_channel_mask_t mChannelMask;
+ size_t mFrameCount;
+ size_t mFrameCountHAL;
+ uint32_t mLatency; // only valid for output
+};
+
+
+}; // namespace android
+
+#endif /*ANDROID_AUDIO_IO_DESCRIPTOR_H*/
diff --git a/media/libaudioclient/include/AudioMixer.h b/media/libaudioclient/include/AudioMixer.h
new file mode 100644
index 0000000..87ada76
--- /dev/null
+++ b/media/libaudioclient/include/AudioMixer.h
@@ -0,0 +1,389 @@
+/*
+**
+** Copyright 2007, 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_AUDIO_MIXER_H
+#define ANDROID_AUDIO_MIXER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <media/AudioBufferProvider.h>
+#include <media/AudioResampler.h>
+#include <media/AudioResamplerPublic.h>
+#include <media/BufferProviders.h>
+#include <media/nbaio/NBLog.h>
+#include <system/audio.h>
+#include <utils/Compat.h>
+#include <utils/threads.h>
+
+// FIXME This is actually unity gain, which might not be max in future, expressed in U.12
+#define MAX_GAIN_INT AudioMixer::UNITY_GAIN_INT
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class AudioMixer
+{
+public:
+ AudioMixer(size_t frameCount, uint32_t sampleRate,
+ uint32_t maxNumTracks = MAX_NUM_TRACKS);
+
+ /*virtual*/ ~AudioMixer(); // non-virtual saves a v-table, restore if sub-classed
+
+
+ // This mixer has a hard-coded upper limit of 32 active track inputs.
+ // Adding support for > 32 tracks would require more than simply changing this value.
+ static const uint32_t MAX_NUM_TRACKS = 32;
+ // maximum number of channels supported by the mixer
+
+ // This mixer has a hard-coded upper limit of 8 channels for output.
+ static const uint32_t MAX_NUM_CHANNELS = 8;
+ static const uint32_t MAX_NUM_VOLUMES = 2; // stereo volume only
+ // maximum number of channels supported for the content
+ static const uint32_t MAX_NUM_CHANNELS_TO_DOWNMIX = AUDIO_CHANNEL_COUNT_MAX;
+
+ static const uint16_t UNITY_GAIN_INT = 0x1000;
+ static const CONSTEXPR float UNITY_GAIN_FLOAT = 1.0f;
+
+ enum { // names
+
+ // track names (MAX_NUM_TRACKS units)
+ TRACK0 = 0x1000,
+
+ // 0x2000 is unused
+
+ // setParameter targets
+ TRACK = 0x3000,
+ RESAMPLE = 0x3001,
+ RAMP_VOLUME = 0x3002, // ramp to new volume
+ VOLUME = 0x3003, // don't ramp
+ TIMESTRETCH = 0x3004,
+
+ // set Parameter names
+ // for target TRACK
+ CHANNEL_MASK = 0x4000,
+ FORMAT = 0x4001,
+ MAIN_BUFFER = 0x4002,
+ AUX_BUFFER = 0x4003,
+ DOWNMIX_TYPE = 0X4004,
+ MIXER_FORMAT = 0x4005, // AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
+ MIXER_CHANNEL_MASK = 0x4006, // Channel mask for mixer output
+ // for target RESAMPLE
+ SAMPLE_RATE = 0x4100, // Configure sample rate conversion on this track name;
+ // parameter 'value' is the new sample rate in Hz.
+ // Only creates a sample rate converter the first time that
+ // the track sample rate is different from the mix sample rate.
+ // If the new sample rate is the same as the mix sample rate,
+ // and a sample rate converter already exists,
+ // then the sample rate converter remains present but is a no-op.
+ RESET = 0x4101, // Reset sample rate converter without changing sample rate.
+ // This clears out the resampler's input buffer.
+ REMOVE = 0x4102, // Remove the sample rate converter on this track name;
+ // the track is restored to the mix sample rate.
+ // for target RAMP_VOLUME and VOLUME (8 channels max)
+ // FIXME use float for these 3 to improve the dynamic range
+ VOLUME0 = 0x4200,
+ VOLUME1 = 0x4201,
+ AUXLEVEL = 0x4210,
+ // for target TIMESTRETCH
+ PLAYBACK_RATE = 0x4300, // Configure timestretch on this track name;
+ // parameter 'value' is a pointer to the new playback rate.
+ };
+
+
+ // For all APIs with "name": TRACK0 <= name < TRACK0 + MAX_NUM_TRACKS
+
+ // Allocate a track name. Returns new track name if successful, -1 on failure.
+ // The failure could be because of an invalid channelMask or format, or that
+ // the track capacity of the mixer is exceeded.
+ int getTrackName(audio_channel_mask_t channelMask,
+ audio_format_t format, int sessionId);
+
+ // Free an allocated track by name
+ void deleteTrackName(int name);
+
+ // Enable or disable an allocated track by name
+ void enable(int name);
+ void disable(int name);
+
+ void setParameter(int name, int target, int param, void *value);
+
+ void setBufferProvider(int name, AudioBufferProvider* bufferProvider);
+ void process();
+
+ uint32_t trackNames() const { return mTrackNames; }
+
+ size_t getUnreleasedFrames(int name) const;
+
+ static inline bool isValidPcmTrackFormat(audio_format_t format) {
+ switch (format) {
+ case AUDIO_FORMAT_PCM_8_BIT:
+ case AUDIO_FORMAT_PCM_16_BIT:
+ case AUDIO_FORMAT_PCM_24_BIT_PACKED:
+ case AUDIO_FORMAT_PCM_32_BIT:
+ case AUDIO_FORMAT_PCM_FLOAT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+private:
+
+ enum {
+ // FIXME this representation permits up to 8 channels
+ NEEDS_CHANNEL_COUNT__MASK = 0x00000007,
+ };
+
+ enum {
+ NEEDS_CHANNEL_1 = 0x00000000, // mono
+ NEEDS_CHANNEL_2 = 0x00000001, // stereo
+
+ // sample format is not explicitly specified, and is assumed to be AUDIO_FORMAT_PCM_16_BIT
+
+ NEEDS_MUTE = 0x00000100,
+ NEEDS_RESAMPLE = 0x00001000,
+ NEEDS_AUX = 0x00010000,
+ };
+
+ struct state_t;
+ struct track_t;
+
+ typedef void (*hook_t)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp,
+ int32_t* aux);
+ static const int BLOCKSIZE = 16; // 4 cache lines
+
+ struct track_t {
+ uint32_t needs;
+
+ // TODO: Eventually remove legacy integer volume settings
+ union {
+ int16_t volume[MAX_NUM_VOLUMES]; // U4.12 fixed point (top bit should be zero)
+ int32_t volumeRL;
+ };
+
+ int32_t prevVolume[MAX_NUM_VOLUMES];
+
+ // 16-byte boundary
+
+ int32_t volumeInc[MAX_NUM_VOLUMES];
+ int32_t auxInc;
+ int32_t prevAuxLevel;
+
+ // 16-byte boundary
+
+ int16_t auxLevel; // 0 <= auxLevel <= MAX_GAIN_INT, but signed for mul performance
+ uint16_t frameCount;
+
+ uint8_t channelCount; // 1 or 2, redundant with (needs & NEEDS_CHANNEL_COUNT__MASK)
+ uint8_t unused_padding; // formerly format, was always 16
+ uint16_t enabled; // actually bool
+ audio_channel_mask_t channelMask;
+
+ // actual buffer provider used by the track hooks, see DownmixerBufferProvider below
+ // for how the Track buffer provider is wrapped by another one when dowmixing is required
+ AudioBufferProvider* bufferProvider;
+
+ // 16-byte boundary
+
+ mutable AudioBufferProvider::Buffer buffer; // 8 bytes
+
+ hook_t hook;
+ const void* in; // current location in buffer
+
+ // 16-byte boundary
+
+ AudioResampler* resampler;
+ uint32_t sampleRate;
+ int32_t* mainBuffer;
+ int32_t* auxBuffer;
+
+ // 16-byte boundary
+
+ /* Buffer providers are constructed to translate the track input data as needed.
+ *
+ * TODO: perhaps make a single PlaybackConverterProvider class to move
+ * all pre-mixer track buffer conversions outside the AudioMixer class.
+ *
+ * 1) mInputBufferProvider: The AudioTrack buffer provider.
+ * 2) mReformatBufferProvider: If not NULL, performs the audio reformat to
+ * match either mMixerInFormat or mDownmixRequiresFormat, if the downmixer
+ * requires reformat. For example, it may convert floating point input to
+ * PCM_16_bit if that's required by the downmixer.
+ * 3) downmixerBufferProvider: If not NULL, performs the channel remixing to match
+ * the number of channels required by the mixer sink.
+ * 4) mPostDownmixReformatBufferProvider: If not NULL, performs reformatting from
+ * the downmixer requirements to the mixer engine input requirements.
+ * 5) mTimestretchBufferProvider: Adds timestretching for playback rate
+ */
+ AudioBufferProvider* mInputBufferProvider; // externally provided buffer provider.
+ PassthruBufferProvider* mReformatBufferProvider; // provider wrapper for reformatting.
+ PassthruBufferProvider* downmixerBufferProvider; // wrapper for channel conversion.
+ PassthruBufferProvider* mPostDownmixReformatBufferProvider;
+ PassthruBufferProvider* mTimestretchBufferProvider;
+
+ int32_t sessionId;
+
+ audio_format_t mMixerFormat; // output mix format: AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
+ audio_format_t mFormat; // input track format
+ audio_format_t mMixerInFormat; // mix internal format AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
+ // each track must be converted to this format.
+ audio_format_t mDownmixRequiresFormat; // required downmixer format
+ // AUDIO_FORMAT_PCM_16_BIT if 16 bit necessary
+ // AUDIO_FORMAT_INVALID if no required format
+
+ float mVolume[MAX_NUM_VOLUMES]; // floating point set volume
+ float mPrevVolume[MAX_NUM_VOLUMES]; // floating point previous volume
+ float mVolumeInc[MAX_NUM_VOLUMES]; // floating point volume increment
+
+ float mAuxLevel; // floating point set aux level
+ float mPrevAuxLevel; // floating point prev aux level
+ float mAuxInc; // floating point aux increment
+
+ audio_channel_mask_t mMixerChannelMask;
+ uint32_t mMixerChannelCount;
+
+ AudioPlaybackRate mPlaybackRate;
+
+ bool needsRamp() { return (volumeInc[0] | volumeInc[1] | auxInc) != 0; }
+ bool setResampler(uint32_t trackSampleRate, uint32_t devSampleRate);
+ bool doesResample() const { return resampler != NULL; }
+ void resetResampler() { if (resampler != NULL) resampler->reset(); }
+ void adjustVolumeRamp(bool aux, bool useFloat = false);
+ size_t getUnreleasedFrames() const { return resampler != NULL ?
+ resampler->getUnreleasedFrames() : 0; };
+
+ status_t prepareForDownmix();
+ void unprepareForDownmix();
+ status_t prepareForReformat();
+ void unprepareForReformat();
+ bool setPlaybackRate(const AudioPlaybackRate &playbackRate);
+ void reconfigureBufferProviders();
+ };
+
+ typedef void (*process_hook_t)(state_t* state);
+
+ // pad to 32-bytes to fill cache line
+ struct state_t {
+ uint32_t enabledTracks;
+ uint32_t needsChanged;
+ size_t frameCount;
+ process_hook_t hook; // one of process__*, never NULL
+ int32_t *outputTemp;
+ int32_t *resampleTemp;
+ NBLog::Writer* mLog;
+ int32_t reserved[1];
+ // FIXME allocate dynamically to save some memory when maxNumTracks < MAX_NUM_TRACKS
+ track_t tracks[MAX_NUM_TRACKS] __attribute__((aligned(32)));
+ };
+
+ // bitmask of allocated track names, where bit 0 corresponds to TRACK0 etc.
+ uint32_t mTrackNames;
+
+ // bitmask of configured track names; ~0 if maxNumTracks == MAX_NUM_TRACKS,
+ // but will have fewer bits set if maxNumTracks < MAX_NUM_TRACKS
+ const uint32_t mConfiguredNames;
+
+ const uint32_t mSampleRate;
+
+ NBLog::Writer mDummyLog;
+public:
+ void setLog(NBLog::Writer* log);
+private:
+ state_t mState __attribute__((aligned(32)));
+
+ // Call after changing either the enabled status of a track, or parameters of an enabled track.
+ // OK to call more often than that, but unnecessary.
+ void invalidateState(uint32_t mask);
+
+ bool setChannelMasks(int name,
+ audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask);
+
+ static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp,
+ int32_t* aux);
+ static void track__nop(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
+ static void track__16BitsStereo(track_t* t, int32_t* out, size_t numFrames, int32_t* temp,
+ int32_t* aux);
+ static void track__16BitsMono(track_t* t, int32_t* out, size_t numFrames, int32_t* temp,
+ int32_t* aux);
+ static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
+ int32_t* aux);
+ static void volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp,
+ int32_t* aux);
+
+ static void process__validate(state_t* state);
+ static void process__nop(state_t* state);
+ static void process__genericNoResampling(state_t* state);
+ static void process__genericResampling(state_t* state);
+ static void process__OneTrack16BitsStereoNoResampling(state_t* state);
+
+ static pthread_once_t sOnceControl;
+ static void sInitRoutine();
+
+ /* multi-format volume mixing function (calls template functions
+ * in AudioMixerOps.h). The template parameters are as follows:
+ *
+ * MIXTYPE (see AudioMixerOps.h MIXTYPE_* enumeration)
+ * USEFLOATVOL (set to true if float volume is used)
+ * ADJUSTVOL (set to true if volume ramp parameters needs adjustment afterwards)
+ * TO: int32_t (Q4.27) or float
+ * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
+ * TA: int32_t (Q4.27)
+ */
+ template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
+ typename TO, typename TI, typename TA>
+ static void volumeMix(TO *out, size_t outFrames,
+ const TI *in, TA *aux, bool ramp, AudioMixer::track_t *t);
+
+ // multi-format process hooks
+ template <int MIXTYPE, typename TO, typename TI, typename TA>
+ static void process_NoResampleOneTrack(state_t* state);
+
+ // multi-format track hooks
+ template <int MIXTYPE, typename TO, typename TI, typename TA>
+ static void track__Resample(track_t* t, TO* out, size_t frameCount,
+ TO* temp __unused, TA* aux);
+ template <int MIXTYPE, typename TO, typename TI, typename TA>
+ static void track__NoResample(track_t* t, TO* out, size_t frameCount,
+ TO* temp __unused, TA* aux);
+
+ static void convertMixerFormat(void *out, audio_format_t mixerOutFormat,
+ void *in, audio_format_t mixerInFormat, size_t sampleCount);
+
+ // hook types
+ enum {
+ PROCESSTYPE_NORESAMPLEONETRACK,
+ };
+ enum {
+ TRACKTYPE_NOP,
+ TRACKTYPE_RESAMPLE,
+ TRACKTYPE_NORESAMPLE,
+ TRACKTYPE_NORESAMPLEMONO,
+ };
+
+ // functions for determining the proper process and track hooks.
+ static process_hook_t getProcessHook(int processType, uint32_t channelCount,
+ audio_format_t mixerInFormat, audio_format_t mixerOutFormat);
+ static hook_t getTrackHook(int trackType, uint32_t channelCount,
+ audio_format_t mixerInFormat, audio_format_t mixerOutFormat);
+};
+
+// ----------------------------------------------------------------------------
+} // namespace android
+
+#endif // ANDROID_AUDIO_MIXER_H
diff --git a/media/libaudioclient/include/AudioParameter.h b/media/libaudioclient/include/AudioParameter.h
new file mode 100644
index 0000000..1ace607
--- /dev/null
+++ b/media/libaudioclient/include/AudioParameter.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2008-2011 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_AUDIOPARAMETER_H_
+#define ANDROID_AUDIOPARAMETER_H_
+
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class AudioParameter {
+
+public:
+ AudioParameter() {}
+ AudioParameter(const String8& keyValuePairs);
+ virtual ~AudioParameter();
+
+ // reserved parameter keys for changing standard parameters with setParameters() function.
+ // Using these keys is mandatory for AudioFlinger to properly monitor audio output/input
+ // configuration changes and act accordingly.
+ // keyRouting: to change audio routing, value is an int in audio_devices_t
+ // keySamplingRate: to change sampling rate routing, value is an int
+ // keyFormat: to change audio format, value is an int in audio_format_t
+ // keyChannels: to change audio channel configuration, value is an int in audio_channels_t
+ // keyFrameCount: to change audio output frame count, value is an int
+ // keyInputSource: to change audio input source, value is an int in audio_source_t
+ // (defined in media/mediarecorder.h)
+ // keyScreenState: either "on" or "off"
+ static const char * const keyRouting;
+ static const char * const keySamplingRate;
+ static const char * const keyFormat;
+ static const char * const keyChannels;
+ static const char * const keyFrameCount;
+ static const char * const keyInputSource;
+ static const char * const keyScreenState;
+
+ // keyBtNrec: BT SCO Noise Reduction + Echo Cancellation parameters
+ // keyHwAvSync: get HW synchronization source identifier from a device
+ // keyMonoOutput: Enable mono audio playback
+ // keyStreamHwAvSync: set HW synchronization source identifier on a stream
+ static const char * const keyBtNrec;
+ static const char * const keyHwAvSync;
+ static const char * const keyMonoOutput;
+ static const char * const keyStreamHwAvSync;
+
+ // keyStreamConnect / Disconnect: value is an int in audio_devices_t
+ static const char * const keyStreamConnect;
+ static const char * const keyStreamDisconnect;
+
+ // For querying stream capabilities. All the returned values are lists.
+ // keyStreamSupportedFormats: audio_format_t
+ // keyStreamSupportedChannels: audio_channel_mask_t
+ // keyStreamSupportedSamplingRates: sampling rate values
+ static const char * const keyStreamSupportedFormats;
+ static const char * const keyStreamSupportedChannels;
+ static const char * const keyStreamSupportedSamplingRates;
+
+ static const char * const valueOn;
+ static const char * const valueOff;
+
+ static const char * const valueListSeparator;
+
+ String8 toString() const { return toStringImpl(true); }
+ String8 keysToString() const { return toStringImpl(false); }
+
+ status_t add(const String8& key, const String8& value);
+ status_t addInt(const String8& key, const int value);
+ status_t addKey(const String8& key);
+ status_t addFloat(const String8& key, const float value);
+
+ status_t remove(const String8& key);
+
+ status_t get(const String8& key, String8& value) const;
+ status_t getInt(const String8& key, int& value) const;
+ status_t getFloat(const String8& key, float& value) const;
+ status_t getAt(size_t index, String8& key) const;
+ status_t getAt(size_t index, String8& key, String8& value) const;
+
+ size_t size() const { return mParameters.size(); }
+
+private:
+ String8 mKeyValuePairs;
+ KeyedVector <String8, String8> mParameters;
+
+ String8 toStringImpl(bool useValues) const;
+};
+
+}; // namespace android
+
+#endif /*ANDROID_AUDIOPARAMETER_H_*/
diff --git a/media/libaudioclient/include/AudioPolicy.h b/media/libaudioclient/include/AudioPolicy.h
new file mode 100644
index 0000000..8da0069
--- /dev/null
+++ b/media/libaudioclient/include/AudioPolicy.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef ANDROID_AUDIO_POLICY_H
+#define ANDROID_AUDIO_POLICY_H
+
+#include <system/audio.h>
+#include <system/audio_policy.h>
+#include <binder/Parcel.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+// Keep in sync with AudioMix.java, AudioMixingRule.java, AudioPolicyConfig.java
+#define RULE_EXCLUSION_MASK 0x8000
+#define RULE_MATCH_ATTRIBUTE_USAGE 0x1
+#define RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET (0x1 << 1)
+#define RULE_MATCH_UID (0x1 << 2)
+#define RULE_EXCLUDE_ATTRIBUTE_USAGE (RULE_EXCLUSION_MASK|RULE_MATCH_ATTRIBUTE_USAGE)
+#define RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET \
+ (RULE_EXCLUSION_MASK|RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET)
+#define RULE_EXCLUDE_UID (RULE_EXCLUSION_MASK|RULE_MATCH_UID)
+
+#define MIX_TYPE_INVALID (-1)
+#define MIX_TYPE_PLAYERS 0
+#define MIX_TYPE_RECORDERS 1
+
+// definition of the different events that can be reported on a dynamic policy from
+// AudioSystem's implementation of the AudioPolicyClient interface
+// keep in sync with AudioSystem.java
+#define DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE 0
+
+#define MIX_STATE_DISABLED (-1)
+#define MIX_STATE_IDLE 0
+#define MIX_STATE_MIXING 1
+
+#define MIX_ROUTE_FLAG_RENDER 0x1
+#define MIX_ROUTE_FLAG_LOOP_BACK (0x1 << 1)
+#define MIX_ROUTE_FLAG_ALL (MIX_ROUTE_FLAG_RENDER | MIX_ROUTE_FLAG_LOOP_BACK)
+
+#define MAX_MIXES_PER_POLICY 10
+#define MAX_CRITERIA_PER_MIX 20
+
+class AudioMixMatchCriterion {
+public:
+ AudioMixMatchCriterion() {}
+ AudioMixMatchCriterion(audio_usage_t usage, audio_source_t source, uint32_t rule);
+
+ status_t readFromParcel(Parcel *parcel);
+ status_t writeToParcel(Parcel *parcel) const;
+
+ union {
+ audio_usage_t mUsage;
+ audio_source_t mSource;
+ uid_t mUid;
+ } mValue;
+ uint32_t mRule;
+};
+
+class AudioMix {
+public:
+ // flag on an AudioMix indicating the activity on this mix (IDLE, MIXING)
+ // must be reported through the AudioPolicyClient interface
+ static const uint32_t kCbFlagNotifyActivity = 0x1;
+
+ AudioMix() {}
+ AudioMix(Vector<AudioMixMatchCriterion> criteria, uint32_t mixType, audio_config_t format,
+ uint32_t routeFlags, String8 registrationId, uint32_t flags) :
+ mCriteria(criteria), mMixType(mixType), mFormat(format),
+ mRouteFlags(routeFlags), mDeviceAddress(registrationId), mCbFlags(flags){}
+
+ status_t readFromParcel(Parcel *parcel);
+ status_t writeToParcel(Parcel *parcel) const;
+
+ Vector<AudioMixMatchCriterion> mCriteria;
+ uint32_t mMixType;
+ audio_config_t mFormat;
+ uint32_t mRouteFlags;
+ audio_devices_t mDeviceType;
+ String8 mDeviceAddress;
+ uint32_t mCbFlags; // flags indicating which callbacks to use, see kCbFlag*
+};
+
+
+// definitions for audio recording configuration updates
+// which update type is reported
+#define RECORD_CONFIG_EVENT_NONE -1
+#define RECORD_CONFIG_EVENT_START 1
+#define RECORD_CONFIG_EVENT_STOP 0
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_POLICY_H
diff --git a/media/libaudioclient/include/AudioPolicyHelper.h b/media/libaudioclient/include/AudioPolicyHelper.h
new file mode 100644
index 0000000..04f6a20
--- /dev/null
+++ b/media/libaudioclient/include/AudioPolicyHelper.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef AUDIO_POLICY_HELPER_H_
+#define AUDIO_POLICY_HELPER_H_
+
+#include <system/audio.h>
+
+static audio_stream_type_t audio_attributes_to_stream_type(const audio_attributes_t *attr)
+{
+ // flags to stream type mapping
+ if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
+ return AUDIO_STREAM_ENFORCED_AUDIBLE;
+ }
+ if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
+ return AUDIO_STREAM_BLUETOOTH_SCO;
+ }
+
+ // usage to stream type mapping
+ switch (attr->usage) {
+ case AUDIO_USAGE_MEDIA:
+ case AUDIO_USAGE_GAME:
+ case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
+ case AUDIO_USAGE_ASSISTANT:
+ return AUDIO_STREAM_MUSIC;
+ case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
+ return AUDIO_STREAM_ACCESSIBILITY;
+ case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
+ return AUDIO_STREAM_SYSTEM;
+ case AUDIO_USAGE_VOICE_COMMUNICATION:
+ return AUDIO_STREAM_VOICE_CALL;
+
+ case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
+ return AUDIO_STREAM_DTMF;
+
+ case AUDIO_USAGE_ALARM:
+ return AUDIO_STREAM_ALARM;
+ case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
+ return AUDIO_STREAM_RING;
+
+ case AUDIO_USAGE_NOTIFICATION:
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
+ case AUDIO_USAGE_NOTIFICATION_EVENT:
+ return AUDIO_STREAM_NOTIFICATION;
+
+ case AUDIO_USAGE_UNKNOWN:
+ default:
+ return AUDIO_STREAM_MUSIC;
+ }
+}
+
+static void stream_type_to_audio_attributes(audio_stream_type_t streamType,
+ audio_attributes_t *attr) {
+ memset(attr, 0, sizeof(audio_attributes_t));
+
+ switch (streamType) {
+ case AUDIO_STREAM_DEFAULT:
+ case AUDIO_STREAM_MUSIC:
+ attr->content_type = AUDIO_CONTENT_TYPE_MUSIC;
+ attr->usage = AUDIO_USAGE_MEDIA;
+ break;
+ case AUDIO_STREAM_VOICE_CALL:
+ attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
+ attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION;
+ break;
+ case AUDIO_STREAM_ENFORCED_AUDIBLE:
+ attr->flags |= AUDIO_FLAG_AUDIBILITY_ENFORCED;
+ // intended fall through, attributes in common with STREAM_SYSTEM
+ case AUDIO_STREAM_SYSTEM:
+ attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ attr->usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+ break;
+ case AUDIO_STREAM_RING:
+ attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ attr->usage = AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+ break;
+ case AUDIO_STREAM_ALARM:
+ attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ attr->usage = AUDIO_USAGE_ALARM;
+ break;
+ case AUDIO_STREAM_NOTIFICATION:
+ attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ attr->usage = AUDIO_USAGE_NOTIFICATION;
+ break;
+ case AUDIO_STREAM_BLUETOOTH_SCO:
+ attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
+ attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION;
+ attr->flags |= AUDIO_FLAG_SCO;
+ break;
+ case AUDIO_STREAM_DTMF:
+ attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+ break;
+ case AUDIO_STREAM_TTS:
+ attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
+ attr->usage = AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+ break;
+ default:
+ ALOGE("invalid stream type %d when converting to attributes", streamType);
+ }
+}
+
+#endif //AUDIO_POLICY_HELPER_H_
diff --git a/media/libaudioclient/include/AudioRecord.h b/media/libaudioclient/include/AudioRecord.h
new file mode 100644
index 0000000..1c8746f
--- /dev/null
+++ b/media/libaudioclient/include/AudioRecord.h
@@ -0,0 +1,659 @@
+/*
+ * Copyright (C) 2008 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_AUDIORECORD_H
+#define ANDROID_AUDIORECORD_H
+
+#include <cutils/sched_policy.h>
+#include <media/AudioSystem.h>
+#include <media/AudioTimestamp.h>
+#include <media/IAudioRecord.h>
+#include <media/Modulo.h>
+#include <utils/threads.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+struct audio_track_cblk_t;
+class AudioRecordClientProxy;
+
+// ----------------------------------------------------------------------------
+
+class AudioRecord : public RefBase
+{
+public:
+
+ /* Events used by AudioRecord callback function (callback_t).
+ * Keep in sync with frameworks/base/media/java/android/media/AudioRecord.java NATIVE_EVENT_*.
+ */
+ enum event_type {
+ EVENT_MORE_DATA = 0, // Request to read available data from buffer.
+ // If this event is delivered but the callback handler
+ // does not want to read the available data, the handler must
+ // explicitly ignore the event by setting frameCount to zero.
+ EVENT_OVERRUN = 1, // Buffer overrun occurred.
+ EVENT_MARKER = 2, // Record head is at the specified marker position
+ // (See setMarkerPosition()).
+ EVENT_NEW_POS = 3, // Record head is at a new position
+ // (See setPositionUpdatePeriod()).
+ EVENT_NEW_IAUDIORECORD = 4, // IAudioRecord was re-created, either due to re-routing and
+ // voluntary invalidation by mediaserver, or mediaserver crash.
+ };
+
+ /* Client should declare a Buffer and pass address to obtainBuffer()
+ * and releaseBuffer(). See also callback_t for EVENT_MORE_DATA.
+ */
+
+ class Buffer
+ {
+ public:
+ // FIXME use m prefix
+ size_t frameCount; // number of sample frames corresponding to size;
+ // on input to obtainBuffer() it is the number of frames desired
+ // on output from obtainBuffer() it is the number of available
+ // frames to be read
+ // on input to releaseBuffer() it is currently ignored
+
+ size_t size; // input/output in bytes == frameCount * frameSize
+ // on input to obtainBuffer() it is ignored
+ // on output from obtainBuffer() it is the number of available
+ // bytes to be read, which is frameCount * frameSize
+ // on input to releaseBuffer() it is the number of bytes to
+ // release
+ // FIXME This is redundant with respect to frameCount. Consider
+ // removing size and making frameCount the primary field.
+
+ union {
+ void* raw;
+ short* i16; // signed 16-bit
+ int8_t* i8; // unsigned 8-bit, offset by 0x80
+ // input to obtainBuffer(): unused, output: pointer to buffer
+ };
+ };
+
+ /* As a convenience, if a callback is supplied, a handler thread
+ * is automatically created with the appropriate priority. This thread
+ * invokes the callback when a new buffer becomes available or various conditions occur.
+ * Parameters:
+ *
+ * event: type of event notified (see enum AudioRecord::event_type).
+ * user: Pointer to context for use by the callback receiver.
+ * info: Pointer to optional parameter according to event type:
+ * - EVENT_MORE_DATA: pointer to AudioRecord::Buffer struct. The callback must not read
+ * more bytes than indicated by 'size' field and update 'size' if
+ * fewer bytes are consumed.
+ * - EVENT_OVERRUN: unused.
+ * - EVENT_MARKER: pointer to const uint32_t containing the marker position in frames.
+ * - EVENT_NEW_POS: pointer to const uint32_t containing the new position in frames.
+ * - EVENT_NEW_IAUDIORECORD: unused.
+ */
+
+ typedef void (*callback_t)(int event, void* user, void *info);
+
+ /* Returns the minimum frame count required for the successful creation of
+ * an AudioRecord object.
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - NO_INIT: audio server or audio hardware not initialized
+ * - BAD_VALUE: unsupported configuration
+ * frameCount is guaranteed to be non-zero if status is NO_ERROR,
+ * and is undefined otherwise.
+ * FIXME This API assumes a route, and so should be deprecated.
+ */
+
+ static status_t getMinFrameCount(size_t* frameCount,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask);
+
+ /* How data is transferred from AudioRecord
+ */
+ enum transfer_type {
+ TRANSFER_DEFAULT, // not specified explicitly; determine from the other parameters
+ TRANSFER_CALLBACK, // callback EVENT_MORE_DATA
+ TRANSFER_OBTAIN, // call obtainBuffer() and releaseBuffer()
+ TRANSFER_SYNC, // synchronous read()
+ };
+
+ /* Constructs an uninitialized AudioRecord. No connection with
+ * AudioFlinger takes place. Use set() after this.
+ *
+ * Parameters:
+ *
+ * opPackageName: The package name used for app ops.
+ */
+ AudioRecord(const String16& opPackageName);
+
+ /* Creates an AudioRecord object and registers it with AudioFlinger.
+ * Once created, the track needs to be started before it can be used.
+ * Unspecified values are set to appropriate default values.
+ *
+ * Parameters:
+ *
+ * inputSource: Select the audio input to record from (e.g. AUDIO_SOURCE_DEFAULT).
+ * sampleRate: Data sink sampling rate in Hz. Zero means to use the source sample rate.
+ * format: Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed
+ * 16 bits per sample).
+ * channelMask: Channel mask, such that audio_is_input_channel(channelMask) is true.
+ * opPackageName: The package name used for app ops.
+ * frameCount: Minimum size of track PCM buffer in frames. This defines the
+ * application's contribution to the
+ * latency of the track. The actual size selected by the AudioRecord could
+ * be larger if the requested size is not compatible with current audio HAL
+ * latency. Zero means to use a default value.
+ * cbf: Callback function. If not null, this function is called periodically
+ * to consume new data in TRANSFER_CALLBACK mode
+ * and inform of marker, position updates, etc.
+ * user: Context for use by the callback receiver.
+ * notificationFrames: The callback function is called each time notificationFrames PCM
+ * frames are ready in record track output buffer.
+ * sessionId: Not yet supported.
+ * transferType: How data is transferred from AudioRecord.
+ * flags: See comments on audio_input_flags_t in <system/audio.h>
+ * pAttributes: If not NULL, supersedes inputSource for use case selection.
+ * threadCanCallJava: Not present in parameter list, and so is fixed at false.
+ */
+
+ AudioRecord(audio_source_t inputSource,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ const String16& opPackageName,
+ size_t frameCount = 0,
+ callback_t cbf = NULL,
+ void* user = NULL,
+ uint32_t notificationFrames = 0,
+ audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
+ transfer_type transferType = TRANSFER_DEFAULT,
+ audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE,
+ uid_t uid = AUDIO_UID_INVALID,
+ pid_t pid = -1,
+ const audio_attributes_t* pAttributes = NULL);
+
+ /* Terminates the AudioRecord and unregisters it from AudioFlinger.
+ * Also destroys all resources associated with the AudioRecord.
+ */
+protected:
+ virtual ~AudioRecord();
+public:
+
+ /* Initialize an AudioRecord that was created using the AudioRecord() constructor.
+ * Don't call set() more than once, or after an AudioRecord() constructor that takes parameters.
+ * set() is not multi-thread safe.
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful intialization
+ * - INVALID_OPERATION: AudioRecord is already initialized or record device is already in use
+ * - BAD_VALUE: invalid parameter (channelMask, format, sampleRate...)
+ * - NO_INIT: audio server or audio hardware not initialized
+ * - PERMISSION_DENIED: recording is not allowed for the requesting process
+ * If status is not equal to NO_ERROR, don't call any other APIs on this AudioRecord.
+ *
+ * Parameters not listed in the AudioRecord constructors above:
+ *
+ * threadCanCallJava: Whether callbacks are made from an attached thread and thus can call JNI.
+ */
+ status_t set(audio_source_t inputSource,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ size_t frameCount = 0,
+ callback_t cbf = NULL,
+ void* user = NULL,
+ uint32_t notificationFrames = 0,
+ bool threadCanCallJava = false,
+ audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
+ transfer_type transferType = TRANSFER_DEFAULT,
+ audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE,
+ uid_t uid = AUDIO_UID_INVALID,
+ pid_t pid = -1,
+ const audio_attributes_t* pAttributes = NULL);
+
+ /* Result of constructing the AudioRecord. This must be checked for successful initialization
+ * before using any AudioRecord API (except for set()), because using
+ * an uninitialized AudioRecord produces undefined results.
+ * See set() method above for possible return codes.
+ */
+ status_t initCheck() const { return mStatus; }
+
+ /* Returns this track's estimated latency in milliseconds.
+ * This includes the latency due to AudioRecord buffer size, resampling if applicable,
+ * and audio hardware driver.
+ */
+ uint32_t latency() const { return mLatency; }
+
+ /* getters, see constructor and set() */
+
+ audio_format_t format() const { return mFormat; }
+ uint32_t channelCount() const { return mChannelCount; }
+ size_t frameCount() const { return mFrameCount; }
+ size_t frameSize() const { return mFrameSize; }
+ audio_source_t inputSource() const { return mAttributes.source; }
+
+ /* After it's created the track is not active. Call start() to
+ * make it active. If set, the callback will start being called.
+ * If event is not AudioSystem::SYNC_EVENT_NONE, the capture start will be delayed until
+ * the specified event occurs on the specified trigger session.
+ */
+ status_t start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
+ audio_session_t triggerSession = AUDIO_SESSION_NONE);
+
+ /* Stop a track. The callback will cease being called. Note that obtainBuffer() still
+ * works and will drain buffers until the pool is exhausted, and then will return WOULD_BLOCK.
+ */
+ void stop();
+ bool stopped() const;
+
+ /* Return the sink sample rate for this record track in Hz.
+ * If specified as zero in constructor or set(), this will be the source sample rate.
+ * Unlike AudioTrack, the sample rate is const after initialization, so doesn't need a lock.
+ */
+ uint32_t getSampleRate() const { return mSampleRate; }
+
+ /* Sets marker position. When record reaches the number of frames specified,
+ * a callback with event type EVENT_MARKER is called. Calling setMarkerPosition
+ * with marker == 0 cancels marker notification callback.
+ * To set a marker at a position which would compute as 0,
+ * a workaround is to set the marker at a nearby position such as ~0 or 1.
+ * If the AudioRecord has been opened with no callback function associated,
+ * the operation will fail.
+ *
+ * Parameters:
+ *
+ * marker: marker position expressed in wrapping (overflow) frame units,
+ * like the return value of getPosition().
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - INVALID_OPERATION: the AudioRecord has no callback installed.
+ */
+ status_t setMarkerPosition(uint32_t marker);
+ status_t getMarkerPosition(uint32_t *marker) const;
+
+ /* Sets position update period. Every time the number of frames specified has been recorded,
+ * a callback with event type EVENT_NEW_POS is called.
+ * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification
+ * callback.
+ * If the AudioRecord has been opened with no callback function associated,
+ * the operation will fail.
+ * Extremely small values may be rounded up to a value the implementation can support.
+ *
+ * Parameters:
+ *
+ * updatePeriod: position update notification period expressed in frames.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - INVALID_OPERATION: the AudioRecord has no callback installed.
+ */
+ status_t setPositionUpdatePeriod(uint32_t updatePeriod);
+ status_t getPositionUpdatePeriod(uint32_t *updatePeriod) const;
+
+ /* Return the total number of frames recorded since recording started.
+ * The counter will wrap (overflow) periodically, e.g. every ~27 hours at 44.1 kHz.
+ * It is reset to zero by stop().
+ *
+ * Parameters:
+ *
+ * position: Address where to return record head position.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - BAD_VALUE: position is NULL
+ */
+ status_t getPosition(uint32_t *position) const;
+
+ /* Return the record timestamp.
+ *
+ * Parameters:
+ * timestamp: A pointer to the timestamp to be filled.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - BAD_VALUE: timestamp is NULL
+ */
+ status_t getTimestamp(ExtendedTimestamp *timestamp);
+
+ /* Returns a handle on the audio input used by this AudioRecord.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returned value:
+ * handle on audio hardware input
+ */
+// FIXME The only known public caller is frameworks/opt/net/voip/src/jni/rtp/AudioGroup.cpp
+ audio_io_handle_t getInput() const __attribute__((__deprecated__))
+ { return getInputPrivate(); }
+private:
+ audio_io_handle_t getInputPrivate() const;
+public:
+
+ /* Returns the audio session ID associated with this AudioRecord.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returned value:
+ * AudioRecord session ID.
+ *
+ * No lock needed because session ID doesn't change after first set().
+ */
+ audio_session_t getSessionId() const { return mSessionId; }
+
+ /* Public API for TRANSFER_OBTAIN mode.
+ * Obtains a buffer of up to "audioBuffer->frameCount" full frames.
+ * After draining these frames of data, the caller should release them with releaseBuffer().
+ * If the track buffer is not empty, obtainBuffer() returns as many contiguous
+ * full frames as are available immediately.
+ *
+ * If nonContig is non-NULL, it is an output parameter that will be set to the number of
+ * additional non-contiguous frames that are predicted to be available immediately,
+ * if the client were to release the first frames and then call obtainBuffer() again.
+ * This value is only a prediction, and needs to be confirmed.
+ * It will be set to zero for an error return.
+ *
+ * If the track buffer is empty and track is stopped, obtainBuffer() returns WOULD_BLOCK
+ * regardless of the value of waitCount.
+ * If the track buffer is empty and track is not stopped, obtainBuffer() blocks with a
+ * maximum timeout based on waitCount; see chart below.
+ * Buffers will be returned until the pool
+ * is exhausted, at which point obtainBuffer() will either block
+ * or return WOULD_BLOCK depending on the value of the "waitCount"
+ * parameter.
+ *
+ * Interpretation of waitCount:
+ * +n limits wait time to n * WAIT_PERIOD_MS,
+ * -1 causes an (almost) infinite wait time,
+ * 0 non-blocking.
+ *
+ * Buffer fields
+ * On entry:
+ * frameCount number of frames requested
+ * size ignored
+ * raw ignored
+ * After error return:
+ * frameCount 0
+ * size 0
+ * raw undefined
+ * After successful return:
+ * frameCount actual number of frames available, <= number requested
+ * size actual number of bytes available
+ * raw pointer to the buffer
+ */
+
+ status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount,
+ size_t *nonContig = NULL);
+
+ // Explicit Routing
+ /**
+ * TODO Document this method.
+ */
+ status_t setInputDevice(audio_port_handle_t deviceId);
+
+ /**
+ * TODO Document this method.
+ */
+ audio_port_handle_t getInputDevice();
+
+ /* Returns the ID of the audio device actually used by the input to which this AudioRecord
+ * is attached.
+ * A value of AUDIO_PORT_HANDLE_NONE indicates the AudioRecord is not attached to any input.
+ *
+ * Parameters:
+ * none.
+ */
+ audio_port_handle_t getRoutedDeviceId();
+
+ /* Add an AudioDeviceCallback. The caller will be notified when the audio device
+ * to which this AudioRecord is routed is updated.
+ * Replaces any previously installed callback.
+ * Parameters:
+ * callback: The callback interface
+ * Returns NO_ERROR if successful.
+ * INVALID_OPERATION if the same callback is already installed.
+ * NO_INIT or PREMISSION_DENIED if AudioFlinger service is not reachable
+ * BAD_VALUE if the callback is NULL
+ */
+ status_t addAudioDeviceCallback(
+ const sp<AudioSystem::AudioDeviceCallback>& callback);
+
+ /* remove an AudioDeviceCallback.
+ * Parameters:
+ * callback: The callback interface
+ * Returns NO_ERROR if successful.
+ * INVALID_OPERATION if the callback is not installed
+ * BAD_VALUE if the callback is NULL
+ */
+ status_t removeAudioDeviceCallback(
+ const sp<AudioSystem::AudioDeviceCallback>& callback);
+
+private:
+ /* If nonContig is non-NULL, it is an output parameter that will be set to the number of
+ * additional non-contiguous frames that are predicted to be available immediately,
+ * if the client were to release the first frames and then call obtainBuffer() again.
+ * This value is only a prediction, and needs to be confirmed.
+ * It will be set to zero for an error return.
+ * FIXME We could pass an array of Buffers instead of only one Buffer to obtainBuffer(),
+ * in case the requested amount of frames is in two or more non-contiguous regions.
+ * FIXME requested and elapsed are both relative times. Consider changing to absolute time.
+ */
+ status_t obtainBuffer(Buffer* audioBuffer, const struct timespec *requested,
+ struct timespec *elapsed = NULL, size_t *nonContig = NULL);
+public:
+
+ /* Public API for TRANSFER_OBTAIN mode.
+ * Release an emptied buffer of "audioBuffer->frameCount" frames for AudioFlinger to re-fill.
+ *
+ * Buffer fields:
+ * frameCount currently ignored but recommend to set to actual number of frames consumed
+ * size actual number of bytes consumed, must be multiple of frameSize
+ * raw ignored
+ */
+ void releaseBuffer(const Buffer* audioBuffer);
+
+ /* As a convenience we provide a read() interface to the audio buffer.
+ * Input parameter 'size' is in byte units.
+ * This is implemented on top of obtainBuffer/releaseBuffer. For best
+ * performance use callbacks. Returns actual number of bytes read >= 0,
+ * or one of the following negative status codes:
+ * INVALID_OPERATION AudioRecord is configured for streaming mode
+ * BAD_VALUE size is invalid
+ * WOULD_BLOCK when obtainBuffer() returns same, or
+ * AudioRecord was stopped during the read
+ * or any other error code returned by IAudioRecord::start() or restoreRecord_l().
+ * Default behavior is to only return when all data has been transferred. Set 'blocking' to
+ * false for the method to return immediately without waiting to try multiple times to read
+ * the full content of the buffer.
+ */
+ ssize_t read(void* buffer, size_t size, bool blocking = true);
+
+ /* Return the number of input frames lost in the audio driver since the last call of this
+ * function. Audio driver is expected to reset the value to 0 and restart counting upon
+ * returning the current value by this function call. Such loss typically occurs when the
+ * user space process is blocked longer than the capacity of audio driver buffers.
+ * Units: the number of input audio frames.
+ * FIXME The side-effect of resetting the counter may be incompatible with multi-client.
+ * Consider making it more like AudioTrack::getUnderrunFrames which doesn't have side effects.
+ */
+ uint32_t getInputFramesLost() const;
+
+ /* Get the flags */
+ audio_input_flags_t getFlags() const { AutoMutex _l(mLock); return mFlags; }
+
+private:
+ /* copying audio record objects is not allowed */
+ AudioRecord(const AudioRecord& other);
+ AudioRecord& operator = (const AudioRecord& other);
+
+ /* a small internal class to handle the callback */
+ class AudioRecordThread : public Thread
+ {
+ public:
+ AudioRecordThread(AudioRecord& receiver, bool bCanCallJava = false);
+
+ // Do not call Thread::requestExitAndWait() without first calling requestExit().
+ // Thread::requestExitAndWait() is not virtual, and the implementation doesn't do enough.
+ virtual void requestExit();
+
+ void pause(); // suspend thread from execution at next loop boundary
+ void resume(); // allow thread to execute, if not requested to exit
+ void wake(); // wake to handle changed notification conditions.
+
+ private:
+ void pauseInternal(nsecs_t ns = 0LL);
+ // like pause(), but only used internally within thread
+
+ friend class AudioRecord;
+ virtual bool threadLoop();
+ AudioRecord& mReceiver;
+ virtual ~AudioRecordThread();
+ Mutex mMyLock; // Thread::mLock is private
+ Condition mMyCond; // Thread::mThreadExitedCondition is private
+ bool mPaused; // whether thread is requested to pause at next loop entry
+ bool mPausedInt; // whether thread internally requests pause
+ nsecs_t mPausedNs; // if mPausedInt then associated timeout, otherwise ignored
+ bool mIgnoreNextPausedInt; // skip any internal pause and go immediately
+ // to processAudioBuffer() as state may have changed
+ // since pause time calculated.
+ };
+
+ // body of AudioRecordThread::threadLoop()
+ // returns the maximum amount of time before we would like to run again, where:
+ // 0 immediately
+ // > 0 no later than this many nanoseconds from now
+ // NS_WHENEVER still active but no particular deadline
+ // NS_INACTIVE inactive so don't run again until re-started
+ // NS_NEVER never again
+ static const nsecs_t NS_WHENEVER = -1, NS_INACTIVE = -2, NS_NEVER = -3;
+ nsecs_t processAudioBuffer();
+
+ // caller must hold lock on mLock for all _l methods
+
+ status_t openRecord_l(const Modulo<uint32_t> &epoch, const String16& opPackageName);
+
+ // FIXME enum is faster than strcmp() for parameter 'from'
+ status_t restoreRecord_l(const char *from);
+
+ sp<AudioRecordThread> mAudioRecordThread;
+ mutable Mutex mLock;
+
+ // Current client state: false = stopped, true = active. Protected by mLock. If more states
+ // are added, consider changing this to enum State { ... } mState as in AudioTrack.
+ bool mActive;
+
+ // for client callback handler
+ callback_t mCbf; // callback handler for events, or NULL
+ void* mUserData;
+
+ // for notification APIs
+ uint32_t mNotificationFramesReq; // requested number of frames between each
+ // notification callback
+ // as specified in constructor or set()
+ uint32_t mNotificationFramesAct; // actual number of frames between each
+ // notification callback
+ bool mRefreshRemaining; // processAudioBuffer() should refresh
+ // mRemainingFrames and mRetryOnPartialBuffer
+
+ // These are private to processAudioBuffer(), and are not protected by a lock
+ uint32_t mRemainingFrames; // number of frames to request in obtainBuffer()
+ bool mRetryOnPartialBuffer; // sleep and retry after partial obtainBuffer()
+ uint32_t mObservedSequence; // last observed value of mSequence
+
+ Modulo<uint32_t> mMarkerPosition; // in wrapping (overflow) frame units
+ bool mMarkerReached;
+ Modulo<uint32_t> mNewPosition; // in frames
+ uint32_t mUpdatePeriod; // in frames, zero means no EVENT_NEW_POS
+
+ status_t mStatus;
+
+ String16 mOpPackageName; // The package name used for app ops.
+
+ size_t mFrameCount; // corresponds to current IAudioRecord, value is
+ // reported back by AudioFlinger to the client
+ size_t mReqFrameCount; // frame count to request the first or next time
+ // a new IAudioRecord is needed, non-decreasing
+
+ int64_t mFramesRead; // total frames read. reset to zero after
+ // the start() following stop(). It is not
+ // changed after restoring the track.
+ int64_t mFramesReadServerOffset; // An offset to server frames read due to
+ // restoring AudioRecord, or stop/start.
+ // constant after constructor or set()
+ uint32_t mSampleRate;
+ audio_format_t mFormat;
+ uint32_t mChannelCount;
+ size_t mFrameSize; // app-level frame size == AudioFlinger frame size
+ uint32_t mLatency; // in ms
+ audio_channel_mask_t mChannelMask;
+
+ audio_input_flags_t mFlags; // same as mOrigFlags, except for bits that may
+ // be denied by client or server, such as
+ // AUDIO_INPUT_FLAG_FAST. mLock must be
+ // held to read or write those bits reliably.
+ audio_input_flags_t mOrigFlags; // as specified in constructor or set(), const
+
+ audio_session_t mSessionId;
+ transfer_type mTransfer;
+
+ // Next 5 fields may be changed if IAudioRecord is re-created, but always != 0
+ // provided the initial set() was successful
+ sp<IAudioRecord> mAudioRecord;
+ sp<IMemory> mCblkMemory;
+ audio_track_cblk_t* mCblk; // re-load after mLock.unlock()
+ sp<IMemory> mBufferMemory;
+ audio_io_handle_t mInput; // returned by AudioSystem::getInput()
+
+ int mPreviousPriority; // before start()
+ SchedPolicy mPreviousSchedulingGroup;
+ bool mAwaitBoost; // thread should wait for priority boost before running
+
+ // The proxy should only be referenced while a lock is held because the proxy isn't
+ // multi-thread safe.
+ // An exception is that a blocking ClientProxy::obtainBuffer() may be called without a lock,
+ // provided that the caller also holds an extra reference to the proxy and shared memory to keep
+ // them around in case they are replaced during the obtainBuffer().
+ sp<AudioRecordClientProxy> mProxy;
+
+ bool mInOverrun; // whether recorder is currently in overrun state
+
+private:
+ class DeathNotifier : public IBinder::DeathRecipient {
+ public:
+ DeathNotifier(AudioRecord* audioRecord) : mAudioRecord(audioRecord) { }
+ protected:
+ virtual void binderDied(const wp<IBinder>& who);
+ private:
+ const wp<AudioRecord> mAudioRecord;
+ };
+
+ sp<DeathNotifier> mDeathNotifier;
+ uint32_t mSequence; // incremented for each new IAudioRecord attempt
+ uid_t mClientUid;
+ pid_t mClientPid;
+ audio_attributes_t mAttributes;
+
+ // For Device Selection API
+ // a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing.
+ audio_port_handle_t mSelectedDeviceId;
+ sp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
+ audio_port_handle_t mPortId; // unique ID allocated by audio policy
+
+};
+
+}; // namespace android
+
+#endif // ANDROID_AUDIORECORD_H
diff --git a/media/libaudioclient/include/AudioSystem.h b/media/libaudioclient/include/AudioSystem.h
new file mode 100644
index 0000000..853d318
--- /dev/null
+++ b/media/libaudioclient/include/AudioSystem.h
@@ -0,0 +1,475 @@
+/*
+ * Copyright (C) 2008 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_AUDIOSYSTEM_H_
+#define ANDROID_AUDIOSYSTEM_H_
+
+#include <sys/types.h>
+
+#include <media/AudioPolicy.h>
+#include <media/AudioIoDescriptor.h>
+#include <media/IAudioFlingerClient.h>
+#include <media/IAudioPolicyServiceClient.h>
+#include <system/audio.h>
+#include <system/audio_effect.h>
+#include <system/audio_policy.h>
+#include <utils/Errors.h>
+#include <utils/Mutex.h>
+
+namespace android {
+
+typedef void (*audio_error_callback)(status_t err);
+typedef void (*dynamic_policy_callback)(int event, String8 regId, int val);
+typedef void (*record_config_callback)(int event, audio_session_t session, int source,
+ const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
+ audio_patch_handle_t patchHandle);
+
+class IAudioFlinger;
+class IAudioPolicyService;
+class String8;
+
+class AudioSystem
+{
+public:
+
+ // FIXME Declare in binder opcode order, similarly to IAudioFlinger.h and IAudioFlinger.cpp
+
+ /* These are static methods to control the system-wide AudioFlinger
+ * only privileged processes can have access to them
+ */
+
+ // mute/unmute microphone
+ static status_t muteMicrophone(bool state);
+ static status_t isMicrophoneMuted(bool *state);
+
+ // set/get master volume
+ static status_t setMasterVolume(float value);
+ static status_t getMasterVolume(float* volume);
+
+ // mute/unmute audio outputs
+ static status_t setMasterMute(bool mute);
+ static status_t getMasterMute(bool* mute);
+
+ // set/get stream volume on specified output
+ static status_t setStreamVolume(audio_stream_type_t stream, float value,
+ audio_io_handle_t output);
+ static status_t getStreamVolume(audio_stream_type_t stream, float* volume,
+ audio_io_handle_t output);
+
+ // mute/unmute stream
+ static status_t setStreamMute(audio_stream_type_t stream, bool mute);
+ static status_t getStreamMute(audio_stream_type_t stream, bool* mute);
+
+ // set audio mode in audio hardware
+ static status_t setMode(audio_mode_t mode);
+
+ // returns true in *state if tracks are active on the specified stream or have been active
+ // in the past inPastMs milliseconds
+ static status_t isStreamActive(audio_stream_type_t stream, bool *state, uint32_t inPastMs);
+ // returns true in *state if tracks are active for what qualifies as remote playback
+ // on the specified stream or have been active in the past inPastMs milliseconds. Remote
+ // playback isn't mutually exclusive with local playback.
+ static status_t isStreamActiveRemotely(audio_stream_type_t stream, bool *state,
+ uint32_t inPastMs);
+ // returns true in *state if a recorder is currently recording with the specified source
+ static status_t isSourceActive(audio_source_t source, bool *state);
+
+ // set/get audio hardware parameters. The function accepts a list of parameters
+ // key value pairs in the form: key1=value1;key2=value2;...
+ // Some keys are reserved for standard parameters (See AudioParameter class).
+ // The versions with audio_io_handle_t are intended for internal media framework use only.
+ static status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs);
+ static String8 getParameters(audio_io_handle_t ioHandle, const String8& keys);
+ // The versions without audio_io_handle_t are intended for JNI.
+ static status_t setParameters(const String8& keyValuePairs);
+ static String8 getParameters(const String8& keys);
+
+ static void setErrorCallback(audio_error_callback cb);
+ static void setDynPolicyCallback(dynamic_policy_callback cb);
+ static void setRecordConfigCallback(record_config_callback);
+
+ // helper function to obtain AudioFlinger service handle
+ static const sp<IAudioFlinger> get_audio_flinger();
+
+ static float linearToLog(int volume);
+ static int logToLinear(float volume);
+
+ // Returned samplingRate and frameCount output values are guaranteed
+ // to be non-zero if status == NO_ERROR
+ // FIXME This API assumes a route, and so should be deprecated.
+ static status_t getOutputSamplingRate(uint32_t* samplingRate,
+ audio_stream_type_t stream);
+ // FIXME This API assumes a route, and so should be deprecated.
+ static status_t getOutputFrameCount(size_t* frameCount,
+ audio_stream_type_t stream);
+ // FIXME This API assumes a route, and so should be deprecated.
+ static status_t getOutputLatency(uint32_t* latency,
+ audio_stream_type_t stream);
+ // returns the audio HAL sample rate
+ static status_t getSamplingRate(audio_io_handle_t ioHandle,
+ uint32_t* samplingRate);
+ // For output threads with a fast mixer, returns the number of frames per normal mixer buffer.
+ // For output threads without a fast mixer, or for input, this is same as getFrameCountHAL().
+ static status_t getFrameCount(audio_io_handle_t ioHandle,
+ size_t* frameCount);
+ // returns the audio output latency in ms. Corresponds to
+ // audio_stream_out->get_latency()
+ static status_t getLatency(audio_io_handle_t output,
+ uint32_t* latency);
+
+ // return status NO_ERROR implies *buffSize > 0
+ // FIXME This API assumes a route, and so should deprecated.
+ static status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+ audio_channel_mask_t channelMask, size_t* buffSize);
+
+ static status_t setVoiceVolume(float volume);
+
+ // return the number of audio frames written by AudioFlinger to audio HAL and
+ // audio dsp to DAC since the specified output has exited standby.
+ // returned status (from utils/Errors.h) can be:
+ // - NO_ERROR: successful operation, halFrames and dspFrames point to valid data
+ // - INVALID_OPERATION: Not supported on current hardware platform
+ // - BAD_VALUE: invalid parameter
+ // NOTE: this feature is not supported on all hardware platforms and it is
+ // necessary to check returned status before using the returned values.
+ static status_t getRenderPosition(audio_io_handle_t output,
+ uint32_t *halFrames,
+ uint32_t *dspFrames);
+
+ // return the number of input frames lost by HAL implementation, or 0 if the handle is invalid
+ static uint32_t getInputFramesLost(audio_io_handle_t ioHandle);
+
+ // Allocate a new unique ID for use as an audio session ID or I/O handle.
+ // If unable to contact AudioFlinger, returns AUDIO_UNIQUE_ID_ALLOCATE instead.
+ // FIXME If AudioFlinger were to ever exhaust the unique ID namespace,
+ // this method could fail by returning either a reserved ID like AUDIO_UNIQUE_ID_ALLOCATE
+ // or an unspecified existing unique ID.
+ static audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use);
+
+ static void acquireAudioSessionId(audio_session_t audioSession, pid_t pid);
+ static void releaseAudioSessionId(audio_session_t audioSession, pid_t pid);
+
+ // Get the HW synchronization source used for an audio session.
+ // Return a valid source or AUDIO_HW_SYNC_INVALID if an error occurs
+ // or no HW sync source is used.
+ static audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId);
+
+ // Indicate JAVA services are ready (scheduling, power management ...)
+ static status_t systemReady();
+
+ // Returns the number of frames per audio HAL buffer.
+ // Corresponds to audio_stream->get_buffer_size()/audio_stream_in_frame_size() for input.
+ // See also getFrameCount().
+ static status_t getFrameCountHAL(audio_io_handle_t ioHandle,
+ size_t* frameCount);
+
+ // Events used to synchronize actions between audio sessions.
+ // For instance SYNC_EVENT_PRESENTATION_COMPLETE can be used to delay recording start until
+ // playback is complete on another audio session.
+ // See definitions in MediaSyncEvent.java
+ enum sync_event_t {
+ SYNC_EVENT_SAME = -1, // used internally to indicate restart with same event
+ SYNC_EVENT_NONE = 0,
+ SYNC_EVENT_PRESENTATION_COMPLETE,
+
+ //
+ // Define new events here: SYNC_EVENT_START, SYNC_EVENT_STOP, SYNC_EVENT_TIME ...
+ //
+ SYNC_EVENT_CNT,
+ };
+
+ // Timeout for synchronous record start. Prevents from blocking the record thread forever
+ // if the trigger event is not fired.
+ static const uint32_t kSyncRecordStartTimeOutMs = 30000;
+
+ //
+ // IAudioPolicyService interface (see AudioPolicyInterface for method descriptions)
+ //
+ static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state,
+ const char *device_address, const char *device_name);
+ static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
+ const char *device_address);
+ static status_t handleDeviceConfigChange(audio_devices_t device,
+ const char *device_address,
+ const char *device_name);
+ static status_t setPhoneState(audio_mode_t state);
+ static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
+ static audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
+
+ // Client must successfully hand off the handle reference to AudioFlinger via createTrack(),
+ // or release it with releaseOutput().
+ static audio_io_handle_t getOutput(audio_stream_type_t stream,
+ uint32_t samplingRate = 0,
+ audio_format_t format = AUDIO_FORMAT_DEFAULT,
+ audio_channel_mask_t channelMask = AUDIO_CHANNEL_OUT_STEREO,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ const audio_offload_info_t *offloadInfo = NULL);
+ static status_t getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ uid_t uid,
+ const audio_config_t *config,
+ audio_output_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *portId);
+ static status_t startOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session);
+ static status_t stopOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session);
+ static void releaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session);
+
+ // Client must successfully hand off the handle reference to AudioFlinger via openRecord(),
+ // or release it with releaseInput().
+ static status_t getInputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *input,
+ audio_session_t session,
+ pid_t pid,
+ uid_t uid,
+ const audio_config_base_t *config,
+ audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *portId);
+
+ static status_t startInput(audio_io_handle_t input,
+ audio_session_t session);
+ static status_t stopInput(audio_io_handle_t input,
+ audio_session_t session);
+ static void releaseInput(audio_io_handle_t input,
+ audio_session_t session);
+ static status_t initStreamVolume(audio_stream_type_t stream,
+ int indexMin,
+ int indexMax);
+ static status_t setStreamVolumeIndex(audio_stream_type_t stream,
+ int index,
+ audio_devices_t device);
+ static status_t getStreamVolumeIndex(audio_stream_type_t stream,
+ int *index,
+ audio_devices_t device);
+
+ static uint32_t getStrategyForStream(audio_stream_type_t stream);
+ static audio_devices_t getDevicesForStream(audio_stream_type_t stream);
+
+ static audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc);
+ static status_t registerEffect(const effect_descriptor_t *desc,
+ audio_io_handle_t io,
+ uint32_t strategy,
+ audio_session_t session,
+ int id);
+ static status_t unregisterEffect(int id);
+ static status_t setEffectEnabled(int id, bool enabled);
+
+ // clear stream to output mapping cache (gStreamOutputMap)
+ // and output configuration cache (gOutputs)
+ static void clearAudioConfigCache();
+
+ static const sp<IAudioPolicyService> get_audio_policy_service();
+
+ // helpers for android.media.AudioManager.getProperty(), see description there for meaning
+ static uint32_t getPrimaryOutputSamplingRate();
+ static size_t getPrimaryOutputFrameCount();
+
+ static status_t setLowRamDevice(bool isLowRamDevice);
+
+ // Check if hw offload is possible for given format, stream type, sample rate,
+ // bit rate, duration, video and streaming or offload property is enabled
+ static bool isOffloadSupported(const audio_offload_info_t& info);
+
+ // check presence of audio flinger service.
+ // returns NO_ERROR if binding to service succeeds, DEAD_OBJECT otherwise
+ static status_t checkAudioFlinger();
+
+ /* List available audio ports and their attributes */
+ static status_t listAudioPorts(audio_port_role_t role,
+ audio_port_type_t type,
+ unsigned int *num_ports,
+ struct audio_port *ports,
+ unsigned int *generation);
+
+ /* Get attributes for a given audio port */
+ static status_t getAudioPort(struct audio_port *port);
+
+ /* Create an audio patch between several source and sink ports */
+ static status_t createAudioPatch(const struct audio_patch *patch,
+ audio_patch_handle_t *handle);
+
+ /* Release an audio patch */
+ static status_t releaseAudioPatch(audio_patch_handle_t handle);
+
+ /* List existing audio patches */
+ static status_t listAudioPatches(unsigned int *num_patches,
+ struct audio_patch *patches,
+ unsigned int *generation);
+ /* Set audio port configuration */
+ static status_t setAudioPortConfig(const struct audio_port_config *config);
+
+
+ static status_t acquireSoundTriggerSession(audio_session_t *session,
+ audio_io_handle_t *ioHandle,
+ audio_devices_t *device);
+ static status_t releaseSoundTriggerSession(audio_session_t session);
+
+ static audio_mode_t getPhoneState();
+
+ static status_t registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration);
+
+ static status_t startAudioSource(const struct audio_port_config *source,
+ const audio_attributes_t *attributes,
+ audio_patch_handle_t *handle);
+ static status_t stopAudioSource(audio_patch_handle_t handle);
+
+ static status_t setMasterMono(bool mono);
+ static status_t getMasterMono(bool *mono);
+
+ // ----------------------------------------------------------------------------
+
+ class AudioPortCallback : public RefBase
+ {
+ public:
+
+ AudioPortCallback() {}
+ virtual ~AudioPortCallback() {}
+
+ virtual void onAudioPortListUpdate() = 0;
+ virtual void onAudioPatchListUpdate() = 0;
+ virtual void onServiceDied() = 0;
+
+ };
+
+ static status_t addAudioPortCallback(const sp<AudioPortCallback>& callback);
+ static status_t removeAudioPortCallback(const sp<AudioPortCallback>& callback);
+
+ class AudioDeviceCallback : public RefBase
+ {
+ public:
+
+ AudioDeviceCallback() {}
+ virtual ~AudioDeviceCallback() {}
+
+ virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo,
+ audio_port_handle_t deviceId) = 0;
+ };
+
+ static status_t addAudioDeviceCallback(const sp<AudioDeviceCallback>& callback,
+ audio_io_handle_t audioIo);
+ static status_t removeAudioDeviceCallback(const sp<AudioDeviceCallback>& callback,
+ audio_io_handle_t audioIo);
+
+ static audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo);
+
+private:
+
+ class AudioFlingerClient: public IBinder::DeathRecipient, public BnAudioFlingerClient
+ {
+ public:
+ AudioFlingerClient() :
+ mInBuffSize(0), mInSamplingRate(0),
+ mInFormat(AUDIO_FORMAT_DEFAULT), mInChannelMask(AUDIO_CHANNEL_NONE) {
+ }
+
+ void clearIoCache();
+ status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+ audio_channel_mask_t channelMask, size_t* buffSize);
+ sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle);
+
+ // DeathRecipient
+ virtual void binderDied(const wp<IBinder>& who);
+
+ // IAudioFlingerClient
+
+ // indicate a change in the configuration of an output or input: keeps the cached
+ // values for output/input parameters up-to-date in client process
+ virtual void ioConfigChanged(audio_io_config_event event,
+ const sp<AudioIoDescriptor>& ioDesc);
+
+
+ status_t addAudioDeviceCallback(const sp<AudioDeviceCallback>& callback,
+ audio_io_handle_t audioIo);
+ status_t removeAudioDeviceCallback(const sp<AudioDeviceCallback>& callback,
+ audio_io_handle_t audioIo);
+
+ audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo);
+
+ private:
+ Mutex mLock;
+ DefaultKeyedVector<audio_io_handle_t, sp<AudioIoDescriptor> > mIoDescriptors;
+ DefaultKeyedVector<audio_io_handle_t, Vector < sp<AudioDeviceCallback> > >
+ mAudioDeviceCallbacks;
+ // cached values for recording getInputBufferSize() queries
+ size_t mInBuffSize; // zero indicates cache is invalid
+ uint32_t mInSamplingRate;
+ audio_format_t mInFormat;
+ audio_channel_mask_t mInChannelMask;
+ sp<AudioIoDescriptor> getIoDescriptor_l(audio_io_handle_t ioHandle);
+ };
+
+ class AudioPolicyServiceClient: public IBinder::DeathRecipient,
+ public BnAudioPolicyServiceClient
+ {
+ public:
+ AudioPolicyServiceClient() {
+ }
+
+ int addAudioPortCallback(const sp<AudioPortCallback>& callback);
+ int removeAudioPortCallback(const sp<AudioPortCallback>& callback);
+
+ // DeathRecipient
+ virtual void binderDied(const wp<IBinder>& who);
+
+ // IAudioPolicyServiceClient
+ virtual void onAudioPortListUpdate();
+ virtual void onAudioPatchListUpdate();
+ virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state);
+ virtual void onRecordingConfigurationUpdate(int event, audio_session_t session,
+ audio_source_t source, const audio_config_base_t *clientConfig,
+ const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
+
+ private:
+ Mutex mLock;
+ Vector <sp <AudioPortCallback> > mAudioPortCallbacks;
+ };
+
+ static const sp<AudioFlingerClient> getAudioFlingerClient();
+ static sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle);
+
+ static sp<AudioFlingerClient> gAudioFlingerClient;
+ static sp<AudioPolicyServiceClient> gAudioPolicyServiceClient;
+ friend class AudioFlingerClient;
+ friend class AudioPolicyServiceClient;
+
+ static Mutex gLock; // protects gAudioFlinger and gAudioErrorCallback,
+ static Mutex gLockAPS; // protects gAudioPolicyService and gAudioPolicyServiceClient
+ static sp<IAudioFlinger> gAudioFlinger;
+ static audio_error_callback gAudioErrorCallback;
+ static dynamic_policy_callback gDynPolicyCallback;
+ static record_config_callback gRecordConfigCallback;
+
+ static size_t gInBuffSize;
+ // previous parameters for recording buffer size queries
+ static uint32_t gPrevInSamplingRate;
+ static audio_format_t gPrevInFormat;
+ static audio_channel_mask_t gPrevInChannelMask;
+
+ static sp<IAudioPolicyService> gAudioPolicyService;
+};
+
+}; // namespace android
+
+#endif /*ANDROID_AUDIOSYSTEM_H_*/
diff --git a/media/libaudioclient/include/AudioTimestamp.h b/media/libaudioclient/include/AudioTimestamp.h
new file mode 100644
index 0000000..498de8e
--- /dev/null
+++ b/media/libaudioclient/include/AudioTimestamp.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2013 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_AUDIO_TIMESTAMP_H
+#define ANDROID_AUDIO_TIMESTAMP_H
+
+#include <string>
+#include <sstream>
+#include <time.h>
+
+namespace android {
+
+class AudioTimestamp {
+public:
+ AudioTimestamp() : mPosition(0) {
+ mTime.tv_sec = 0;
+ mTime.tv_nsec = 0;
+ }
+ // FIXME change type to match android.media.AudioTrack
+ uint32_t mPosition; // a frame position in AudioTrack::getPosition() units
+ struct timespec mTime; // corresponding CLOCK_MONOTONIC when frame is expected to present
+};
+
+struct alignas(8) /* bug 29096183, bug 29108507 */ ExtendedTimestamp {
+ enum Location {
+ LOCATION_INVALID = -1,
+ // Locations in the audio playback / record pipeline.
+ LOCATION_CLIENT, // timestamp of last read frame from client-server track buffer.
+ LOCATION_SERVER, // timestamp of newest frame from client-server track buffer.
+ LOCATION_KERNEL, // timestamp of newest frame in the kernel (alsa) buffer.
+
+ // Historical data: info when the kernel timestamp was OK (prior to the newest frame).
+ // This may be useful when the newest frame kernel timestamp is unavailable.
+ // Available for playback timestamps.
+ LOCATION_SERVER_LASTKERNELOK, // timestamp of server the prior time kernel timestamp OK.
+ LOCATION_KERNEL_LASTKERNELOK, // timestamp of kernel the prior time kernel timestamp OK.
+ LOCATION_MAX // for sizing arrays only
+ };
+
+ // This needs to be kept in sync with android.media.AudioTimestamp
+ enum Timebase {
+ TIMEBASE_MONOTONIC, // Clock monotonic offset (generally 0)
+ TIMEBASE_BOOTTIME,
+ TIMEBASE_MAX,
+ };
+
+ ExtendedTimestamp() {
+ clear();
+ }
+
+ // mPosition is expressed in frame units.
+ // It is generally nonnegative, though we keep this signed for
+ // to potentially express algorithmic latency at the start of the stream
+ // and to prevent unintentional unsigned integer underflow.
+ int64_t mPosition[LOCATION_MAX];
+
+ // mTimeNs is in nanoseconds for the default timebase, monotonic.
+ // If this value is -1, then both time and position are invalid.
+ // If this value is 0, then the time is not valid but the position is valid.
+ int64_t mTimeNs[LOCATION_MAX];
+
+ // mTimebaseOffset is the offset in ns from monotonic when the
+ // timestamp was taken. This may vary due to suspend time
+ // or NTP adjustment.
+ int64_t mTimebaseOffset[TIMEBASE_MAX];
+
+ // Playback only:
+ // mFlushed is number of flushed frames before entering the server mix;
+ // hence not included in mPosition. This is used for adjusting server positions
+ // information for frames "dropped".
+ // FIXME: This variable should be eliminated, with the offset added on the server side
+ // before sending to client, but differences in legacy position offset handling
+ // and new extended timestamps require this to be maintained as a separate quantity.
+ int64_t mFlushed;
+
+ // Call to reset the timestamp to the original (invalid) state
+ void clear() {
+ memset(mPosition, 0, sizeof(mPosition)); // actually not necessary if time is -1
+ for (int i = 0; i < LOCATION_MAX; ++i) {
+ mTimeNs[i] = -1;
+ }
+ memset(mTimebaseOffset, 0, sizeof(mTimebaseOffset));
+ mFlushed = 0;
+ }
+
+ // Returns the best timestamp as judged from the closest-to-hw stage in the
+ // pipeline with a valid timestamp. If the optional location parameter is non-null,
+ // it will be filled with the location where the time was obtained.
+ status_t getBestTimestamp(
+ int64_t *position, int64_t *time, int timebase, Location *location = nullptr) const {
+ if (position == nullptr || time == nullptr
+ || timebase < 0 || timebase >= TIMEBASE_MAX) {
+ return BAD_VALUE;
+ }
+ // look for the closest-to-hw stage in the pipeline with a valid timestamp.
+ // We omit LOCATION_CLIENT as we prefer at least LOCATION_SERVER based accuracy
+ // when getting the best timestamp.
+ for (int i = LOCATION_KERNEL; i >= LOCATION_SERVER; --i) {
+ if (mTimeNs[i] > 0) {
+ *position = mPosition[i];
+ *time = mTimeNs[i] + mTimebaseOffset[timebase];
+ if (location != nullptr) {
+ *location = (Location)i;
+ }
+ return OK;
+ }
+ }
+ return INVALID_OPERATION;
+ }
+
+ status_t getBestTimestamp(AudioTimestamp *timestamp, Location *location = nullptr) const {
+ if (timestamp == nullptr) {
+ return BAD_VALUE;
+ }
+ int64_t position, time;
+ if (getBestTimestamp(&position, &time, TIMEBASE_MONOTONIC, location) == OK) {
+ timestamp->mPosition = position;
+ timestamp->mTime.tv_sec = time / 1000000000;
+ timestamp->mTime.tv_nsec = time - timestamp->mTime.tv_sec * 1000000000LL;
+ return OK;
+ }
+ return INVALID_OPERATION;
+ }
+
+ // convert fields to a printable string
+ std::string toString() {
+ std::stringstream ss;
+
+ ss << "BOOTTIME offset " << mTimebaseOffset[TIMEBASE_BOOTTIME] << "\n";
+ for (int i = 0; i < LOCATION_MAX; ++i) {
+ ss << "ExtendedTimestamp[" << i << "] position: "
+ << mPosition[i] << " time: " << mTimeNs[i] << "\n";
+ }
+ return ss.str();
+ }
+ // TODO:
+ // Consider adding buffer status:
+ // size, available, algorithmic latency
+};
+
+} // namespace
+
+#endif // ANDROID_AUDIO_TIMESTAMP_H
diff --git a/media/libaudioclient/include/AudioTrack.h b/media/libaudioclient/include/AudioTrack.h
new file mode 100644
index 0000000..1996dbe
--- /dev/null
+++ b/media/libaudioclient/include/AudioTrack.h
@@ -0,0 +1,1154 @@
+/*
+ * Copyright (C) 2007 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_AUDIOTRACK_H
+#define ANDROID_AUDIOTRACK_H
+
+#include <cutils/sched_policy.h>
+#include <media/AudioSystem.h>
+#include <media/AudioTimestamp.h>
+#include <media/IAudioTrack.h>
+#include <media/AudioResamplerPublic.h>
+#include <media/Modulo.h>
+#include <utils/threads.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+struct audio_track_cblk_t;
+class AudioTrackClientProxy;
+class StaticAudioTrackClientProxy;
+
+// ----------------------------------------------------------------------------
+
+class AudioTrack : public RefBase
+{
+public:
+
+ /* Events used by AudioTrack callback function (callback_t).
+ * Keep in sync with frameworks/base/media/java/android/media/AudioTrack.java NATIVE_EVENT_*.
+ */
+ enum event_type {
+ EVENT_MORE_DATA = 0, // Request to write more data to buffer.
+ // This event only occurs for TRANSFER_CALLBACK.
+ // If this event is delivered but the callback handler
+ // does not want to write more data, the handler must
+ // ignore the event by setting frameCount to zero.
+ // This might occur, for example, if the application is
+ // waiting for source data or is at the end of stream.
+ //
+ // For data filling, it is preferred that the callback
+ // does not block and instead returns a short count on
+ // the amount of data actually delivered
+ // (or 0, if no data is currently available).
+ EVENT_UNDERRUN = 1, // Buffer underrun occurred. This will not occur for
+ // static tracks.
+ EVENT_LOOP_END = 2, // Sample loop end was reached; playback restarted from
+ // loop start if loop count was not 0 for a static track.
+ EVENT_MARKER = 3, // Playback head is at the specified marker position
+ // (See setMarkerPosition()).
+ EVENT_NEW_POS = 4, // Playback head is at a new position
+ // (See setPositionUpdatePeriod()).
+ EVENT_BUFFER_END = 5, // Playback has completed for a static track.
+ EVENT_NEW_IAUDIOTRACK = 6, // IAudioTrack was re-created, either due to re-routing and
+ // voluntary invalidation by mediaserver, or mediaserver crash.
+ EVENT_STREAM_END = 7, // Sent after all the buffers queued in AF and HW are played
+ // back (after stop is called) for an offloaded track.
+#if 0 // FIXME not yet implemented
+ EVENT_NEW_TIMESTAMP = 8, // Delivered periodically and when there's a significant change
+ // in the mapping from frame position to presentation time.
+ // See AudioTimestamp for the information included with event.
+#endif
+ };
+
+ /* Client should declare a Buffer and pass the address to obtainBuffer()
+ * and releaseBuffer(). See also callback_t for EVENT_MORE_DATA.
+ */
+
+ class Buffer
+ {
+ public:
+ // FIXME use m prefix
+ size_t frameCount; // number of sample frames corresponding to size;
+ // on input to obtainBuffer() it is the number of frames desired,
+ // on output from obtainBuffer() it is the number of available
+ // [empty slots for] frames to be filled
+ // on input to releaseBuffer() it is currently ignored
+
+ size_t size; // input/output in bytes == frameCount * frameSize
+ // on input to obtainBuffer() it is ignored
+ // on output from obtainBuffer() it is the number of available
+ // [empty slots for] bytes to be filled,
+ // which is frameCount * frameSize
+ // on input to releaseBuffer() it is the number of bytes to
+ // release
+ // FIXME This is redundant with respect to frameCount. Consider
+ // removing size and making frameCount the primary field.
+
+ union {
+ void* raw;
+ short* i16; // signed 16-bit
+ int8_t* i8; // unsigned 8-bit, offset by 0x80
+ }; // input to obtainBuffer(): unused, output: pointer to buffer
+ };
+
+ /* As a convenience, if a callback is supplied, a handler thread
+ * is automatically created with the appropriate priority. This thread
+ * invokes the callback when a new buffer becomes available or various conditions occur.
+ * Parameters:
+ *
+ * event: type of event notified (see enum AudioTrack::event_type).
+ * user: Pointer to context for use by the callback receiver.
+ * info: Pointer to optional parameter according to event type:
+ * - EVENT_MORE_DATA: pointer to AudioTrack::Buffer struct. The callback must not write
+ * more bytes than indicated by 'size' field and update 'size' if fewer bytes are
+ * written.
+ * - EVENT_UNDERRUN: unused.
+ * - EVENT_LOOP_END: pointer to an int indicating the number of loops remaining.
+ * - EVENT_MARKER: pointer to const uint32_t containing the marker position in frames.
+ * - EVENT_NEW_POS: pointer to const uint32_t containing the new position in frames.
+ * - EVENT_BUFFER_END: unused.
+ * - EVENT_NEW_IAUDIOTRACK: unused.
+ * - EVENT_STREAM_END: unused.
+ * - EVENT_NEW_TIMESTAMP: pointer to const AudioTimestamp.
+ */
+
+ typedef void (*callback_t)(int event, void* user, void *info);
+
+ /* Returns the minimum frame count required for the successful creation of
+ * an AudioTrack object.
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - NO_INIT: audio server or audio hardware not initialized
+ * - BAD_VALUE: unsupported configuration
+ * frameCount is guaranteed to be non-zero if status is NO_ERROR,
+ * and is undefined otherwise.
+ * FIXME This API assumes a route, and so should be deprecated.
+ */
+
+ static status_t getMinFrameCount(size_t* frameCount,
+ audio_stream_type_t streamType,
+ uint32_t sampleRate);
+
+ /* How data is transferred to AudioTrack
+ */
+ enum transfer_type {
+ TRANSFER_DEFAULT, // not specified explicitly; determine from the other parameters
+ TRANSFER_CALLBACK, // callback EVENT_MORE_DATA
+ TRANSFER_OBTAIN, // call obtainBuffer() and releaseBuffer()
+ TRANSFER_SYNC, // synchronous write()
+ TRANSFER_SHARED, // shared memory
+ };
+
+ /* Constructs an uninitialized AudioTrack. No connection with
+ * AudioFlinger takes place. Use set() after this.
+ */
+ AudioTrack();
+
+ /* Creates an AudioTrack object and registers it with AudioFlinger.
+ * Once created, the track needs to be started before it can be used.
+ * Unspecified values are set to appropriate default values.
+ *
+ * Parameters:
+ *
+ * streamType: Select the type of audio stream this track is attached to
+ * (e.g. AUDIO_STREAM_MUSIC).
+ * sampleRate: Data source sampling rate in Hz. Zero means to use the sink sample rate.
+ * A non-zero value must be specified if AUDIO_OUTPUT_FLAG_DIRECT is set.
+ * 0 will not work with current policy implementation for direct output
+ * selection where an exact match is needed for sampling rate.
+ * format: Audio format. For mixed tracks, any PCM format supported by server is OK.
+ * For direct and offloaded tracks, the possible format(s) depends on the
+ * output sink.
+ * channelMask: Channel mask, such that audio_is_output_channel(channelMask) is true.
+ * frameCount: Minimum size of track PCM buffer in frames. This defines the
+ * application's contribution to the
+ * latency of the track. The actual size selected by the AudioTrack could be
+ * larger if the requested size is not compatible with current audio HAL
+ * configuration. Zero means to use a default value.
+ * flags: See comments on audio_output_flags_t in <system/audio.h>.
+ * cbf: Callback function. If not null, this function is called periodically
+ * to provide new data in TRANSFER_CALLBACK mode
+ * and inform of marker, position updates, etc.
+ * user: Context for use by the callback receiver.
+ * notificationFrames: The callback function is called each time notificationFrames PCM
+ * frames have been consumed from track input buffer by server.
+ * Zero means to use a default value, which is typically:
+ * - fast tracks: HAL buffer size, even if track frameCount is larger
+ * - normal tracks: 1/2 of track frameCount
+ * A positive value means that many frames at initial source sample rate.
+ * A negative value for this parameter specifies the negative of the
+ * requested number of notifications (sub-buffers) in the entire buffer.
+ * For fast tracks, the FastMixer will process one sub-buffer at a time.
+ * The size of each sub-buffer is determined by the HAL.
+ * To get "double buffering", for example, one should pass -2.
+ * The minimum number of sub-buffers is 1 (expressed as -1),
+ * and the maximum number of sub-buffers is 8 (expressed as -8).
+ * Negative is only permitted for fast tracks, and if frameCount is zero.
+ * TODO It is ugly to overload a parameter in this way depending on
+ * whether it is positive, negative, or zero. Consider splitting apart.
+ * sessionId: Specific session ID, or zero to use default.
+ * transferType: How data is transferred to AudioTrack.
+ * offloadInfo: If not NULL, provides offload parameters for
+ * AudioSystem::getOutputForAttr().
+ * uid: User ID of the app which initially requested this AudioTrack
+ * for power management tracking, or -1 for current user ID.
+ * pid: Process ID of the app which initially requested this AudioTrack
+ * for power management tracking, or -1 for current process ID.
+ * pAttributes: If not NULL, supersedes streamType for use case selection.
+ * doNotReconnect: If set to true, AudioTrack won't automatically recreate the IAudioTrack
+ binder to AudioFlinger.
+ It will return an error instead. The application will recreate
+ the track based on offloading or different channel configuration, etc.
+ * maxRequiredSpeed: For PCM tracks, this creates an appropriate buffer size that will allow
+ * maxRequiredSpeed playback. Values less than 1.0f and greater than
+ * AUDIO_TIMESTRETCH_SPEED_MAX will be clamped. For non-PCM tracks
+ * and direct or offloaded tracks, this parameter is ignored.
+ * threadCanCallJava: Not present in parameter list, and so is fixed at false.
+ */
+
+ AudioTrack( audio_stream_type_t streamType,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ size_t frameCount = 0,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ callback_t cbf = NULL,
+ void* user = NULL,
+ int32_t notificationFrames = 0,
+ audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
+ transfer_type transferType = TRANSFER_DEFAULT,
+ const audio_offload_info_t *offloadInfo = NULL,
+ uid_t uid = AUDIO_UID_INVALID,
+ pid_t pid = -1,
+ const audio_attributes_t* pAttributes = NULL,
+ bool doNotReconnect = false,
+ float maxRequiredSpeed = 1.0f);
+
+ /* Creates an audio track and registers it with AudioFlinger.
+ * With this constructor, the track is configured for static buffer mode.
+ * Data to be rendered is passed in a shared memory buffer
+ * identified by the argument sharedBuffer, which should be non-0.
+ * If sharedBuffer is zero, this constructor is equivalent to the previous constructor
+ * but without the ability to specify a non-zero value for the frameCount parameter.
+ * The memory should be initialized to the desired data before calling start().
+ * The write() method is not supported in this case.
+ * It is recommended to pass a callback function to be notified of playback end by an
+ * EVENT_UNDERRUN event.
+ */
+
+ AudioTrack( audio_stream_type_t streamType,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ const sp<IMemory>& sharedBuffer,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ callback_t cbf = NULL,
+ void* user = NULL,
+ int32_t notificationFrames = 0,
+ audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
+ transfer_type transferType = TRANSFER_DEFAULT,
+ const audio_offload_info_t *offloadInfo = NULL,
+ uid_t uid = AUDIO_UID_INVALID,
+ pid_t pid = -1,
+ const audio_attributes_t* pAttributes = NULL,
+ bool doNotReconnect = false,
+ float maxRequiredSpeed = 1.0f);
+
+ /* Terminates the AudioTrack and unregisters it from AudioFlinger.
+ * Also destroys all resources associated with the AudioTrack.
+ */
+protected:
+ virtual ~AudioTrack();
+public:
+
+ /* Initialize an AudioTrack that was created using the AudioTrack() constructor.
+ * Don't call set() more than once, or after the AudioTrack() constructors that take parameters.
+ * set() is not multi-thread safe.
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful initialization
+ * - INVALID_OPERATION: AudioTrack is already initialized
+ * - BAD_VALUE: invalid parameter (channelMask, format, sampleRate...)
+ * - NO_INIT: audio server or audio hardware not initialized
+ * If status is not equal to NO_ERROR, don't call any other APIs on this AudioTrack.
+ * If sharedBuffer is non-0, the frameCount parameter is ignored and
+ * replaced by the shared buffer's total allocated size in frame units.
+ *
+ * Parameters not listed in the AudioTrack constructors above:
+ *
+ * threadCanCallJava: Whether callbacks are made from an attached thread and thus can call JNI.
+ *
+ * Internal state post condition:
+ * (mStreamType == AUDIO_STREAM_DEFAULT) implies this AudioTrack has valid attributes
+ */
+ status_t set(audio_stream_type_t streamType,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ size_t frameCount = 0,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ callback_t cbf = NULL,
+ void* user = NULL,
+ int32_t notificationFrames = 0,
+ const sp<IMemory>& sharedBuffer = 0,
+ bool threadCanCallJava = false,
+ audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
+ transfer_type transferType = TRANSFER_DEFAULT,
+ const audio_offload_info_t *offloadInfo = NULL,
+ uid_t uid = AUDIO_UID_INVALID,
+ pid_t pid = -1,
+ const audio_attributes_t* pAttributes = NULL,
+ bool doNotReconnect = false,
+ float maxRequiredSpeed = 1.0f);
+
+ /* Result of constructing the AudioTrack. This must be checked for successful initialization
+ * before using any AudioTrack API (except for set()), because using
+ * an uninitialized AudioTrack produces undefined results.
+ * See set() method above for possible return codes.
+ */
+ status_t initCheck() const { return mStatus; }
+
+ /* Returns this track's estimated latency in milliseconds.
+ * This includes the latency due to AudioTrack buffer size, AudioMixer (if any)
+ * and audio hardware driver.
+ */
+ uint32_t latency() const { return mLatency; }
+
+ /* Returns the number of application-level buffer underruns
+ * since the AudioTrack was created.
+ */
+ uint32_t getUnderrunCount() const;
+
+ /* getters, see constructors and set() */
+
+ audio_stream_type_t streamType() const;
+ audio_format_t format() const { return mFormat; }
+
+ /* Return frame size in bytes, which for linear PCM is
+ * channelCount * (bit depth per channel / 8).
+ * channelCount is determined from channelMask, and bit depth comes from format.
+ * For non-linear formats, the frame size is typically 1 byte.
+ */
+ size_t frameSize() const { return mFrameSize; }
+
+ uint32_t channelCount() const { return mChannelCount; }
+ size_t frameCount() const { return mFrameCount; }
+
+ // TODO consider notificationFrames() if needed
+
+ /* Return effective size of audio buffer that an application writes to
+ * or a negative error if the track is uninitialized.
+ */
+ ssize_t getBufferSizeInFrames();
+
+ /* Returns the buffer duration in microseconds at current playback rate.
+ */
+ status_t getBufferDurationInUs(int64_t *duration);
+
+ /* Set the effective size of audio buffer that an application writes to.
+ * This is used to determine the amount of available room in the buffer,
+ * which determines when a write will block.
+ * This allows an application to raise and lower the audio latency.
+ * The requested size may be adjusted so that it is
+ * greater or equal to the absolute minimum and
+ * less than or equal to the getBufferCapacityInFrames().
+ * It may also be adjusted slightly for internal reasons.
+ *
+ * Return the final size or a negative error if the track is unitialized
+ * or does not support variable sizes.
+ */
+ ssize_t setBufferSizeInFrames(size_t size);
+
+ /* Return the static buffer specified in constructor or set(), or 0 for streaming mode */
+ sp<IMemory> sharedBuffer() const { return mSharedBuffer; }
+
+ /* After it's created the track is not active. Call start() to
+ * make it active. If set, the callback will start being called.
+ * If the track was previously paused, volume is ramped up over the first mix buffer.
+ */
+ status_t start();
+
+ /* Stop a track.
+ * In static buffer mode, the track is stopped immediately.
+ * In streaming mode, the callback will cease being called. Note that obtainBuffer() still
+ * works and will fill up buffers until the pool is exhausted, and then will return WOULD_BLOCK.
+ * In streaming mode the stop does not occur immediately: any data remaining in the buffer
+ * is first drained, mixed, and output, and only then is the track marked as stopped.
+ */
+ void stop();
+ bool stopped() const;
+
+ /* Flush a stopped or paused track. All previously buffered data is discarded immediately.
+ * This has the effect of draining the buffers without mixing or output.
+ * Flush is intended for streaming mode, for example before switching to non-contiguous content.
+ * This function is a no-op if the track is not stopped or paused, or uses a static buffer.
+ */
+ void flush();
+
+ /* Pause a track. After pause, the callback will cease being called and
+ * obtainBuffer returns WOULD_BLOCK. Note that obtainBuffer() still works
+ * and will fill up buffers until the pool is exhausted.
+ * Volume is ramped down over the next mix buffer following the pause request,
+ * and then the track is marked as paused. It can be resumed with ramp up by start().
+ */
+ void pause();
+
+ /* Set volume for this track, mostly used for games' sound effects
+ * left and right volumes. Levels must be >= 0.0 and <= 1.0.
+ * This is the older API. New applications should use setVolume(float) when possible.
+ */
+ status_t setVolume(float left, float right);
+
+ /* Set volume for all channels. This is the preferred API for new applications,
+ * especially for multi-channel content.
+ */
+ status_t setVolume(float volume);
+
+ /* Set the send level for this track. An auxiliary effect should be attached
+ * to the track with attachEffect(). Level must be >= 0.0 and <= 1.0.
+ */
+ status_t setAuxEffectSendLevel(float level);
+ void getAuxEffectSendLevel(float* level) const;
+
+ /* Set source sample rate for this track in Hz, mostly used for games' sound effects.
+ * Zero is not permitted.
+ */
+ status_t setSampleRate(uint32_t sampleRate);
+
+ /* Return current source sample rate in Hz.
+ * If specified as zero in constructor or set(), this will be the sink sample rate.
+ */
+ uint32_t getSampleRate() const;
+
+ /* Return the original source sample rate in Hz. This corresponds to the sample rate
+ * if playback rate had normal speed and pitch.
+ */
+ uint32_t getOriginalSampleRate() const;
+
+ /* Set source playback rate for timestretch
+ * 1.0 is normal speed: < 1.0 is slower, > 1.0 is faster
+ * 1.0 is normal pitch: < 1.0 is lower pitch, > 1.0 is higher pitch
+ *
+ * AUDIO_TIMESTRETCH_SPEED_MIN <= speed <= AUDIO_TIMESTRETCH_SPEED_MAX
+ * AUDIO_TIMESTRETCH_PITCH_MIN <= pitch <= AUDIO_TIMESTRETCH_PITCH_MAX
+ *
+ * Speed increases the playback rate of media, but does not alter pitch.
+ * Pitch increases the "tonal frequency" of media, but does not affect the playback rate.
+ */
+ status_t setPlaybackRate(const AudioPlaybackRate &playbackRate);
+
+ /* Return current playback rate */
+ const AudioPlaybackRate& getPlaybackRate() const;
+
+ /* Enables looping and sets the start and end points of looping.
+ * Only supported for static buffer mode.
+ *
+ * Parameters:
+ *
+ * loopStart: loop start in frames relative to start of buffer.
+ * loopEnd: loop end in frames relative to start of buffer.
+ * loopCount: number of loops to execute. Calling setLoop() with loopCount == 0 cancels any
+ * pending or active loop. loopCount == -1 means infinite looping.
+ *
+ * For proper operation the following condition must be respected:
+ * loopCount != 0 implies 0 <= loopStart < loopEnd <= frameCount().
+ *
+ * If the loop period (loopEnd - loopStart) is too small for the implementation to support,
+ * setLoop() will return BAD_VALUE. loopCount must be >= -1.
+ *
+ */
+ status_t setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount);
+
+ /* Sets marker position. When playback reaches the number of frames specified, a callback with
+ * event type EVENT_MARKER is called. Calling setMarkerPosition with marker == 0 cancels marker
+ * notification callback. To set a marker at a position which would compute as 0,
+ * a workaround is to set the marker at a nearby position such as ~0 or 1.
+ * If the AudioTrack has been opened with no callback function associated, the operation will
+ * fail.
+ *
+ * Parameters:
+ *
+ * marker: marker position expressed in wrapping (overflow) frame units,
+ * like the return value of getPosition().
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - INVALID_OPERATION: the AudioTrack has no callback installed.
+ */
+ status_t setMarkerPosition(uint32_t marker);
+ status_t getMarkerPosition(uint32_t *marker) const;
+
+ /* Sets position update period. Every time the number of frames specified has been played,
+ * a callback with event type EVENT_NEW_POS is called.
+ * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification
+ * callback.
+ * If the AudioTrack has been opened with no callback function associated, the operation will
+ * fail.
+ * Extremely small values may be rounded up to a value the implementation can support.
+ *
+ * Parameters:
+ *
+ * updatePeriod: position update notification period expressed in frames.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - INVALID_OPERATION: the AudioTrack has no callback installed.
+ */
+ status_t setPositionUpdatePeriod(uint32_t updatePeriod);
+ status_t getPositionUpdatePeriod(uint32_t *updatePeriod) const;
+
+ /* Sets playback head position.
+ * Only supported for static buffer mode.
+ *
+ * Parameters:
+ *
+ * position: New playback head position in frames relative to start of buffer.
+ * 0 <= position <= frameCount(). Note that end of buffer is permitted,
+ * but will result in an immediate underrun if started.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - INVALID_OPERATION: the AudioTrack is not stopped or paused, or is streaming mode.
+ * - BAD_VALUE: The specified position is beyond the number of frames present in AudioTrack
+ * buffer
+ */
+ status_t setPosition(uint32_t position);
+
+ /* Return the total number of frames played since playback start.
+ * The counter will wrap (overflow) periodically, e.g. every ~27 hours at 44.1 kHz.
+ * It is reset to zero by flush(), reload(), and stop().
+ *
+ * Parameters:
+ *
+ * position: Address where to return play head position.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - BAD_VALUE: position is NULL
+ */
+ status_t getPosition(uint32_t *position);
+
+ /* For static buffer mode only, this returns the current playback position in frames
+ * relative to start of buffer. It is analogous to the position units used by
+ * setLoop() and setPosition(). After underrun, the position will be at end of buffer.
+ */
+ status_t getBufferPosition(uint32_t *position);
+
+ /* Forces AudioTrack buffer full condition. When playing a static buffer, this method avoids
+ * rewriting the buffer before restarting playback after a stop.
+ * This method must be called with the AudioTrack in paused or stopped state.
+ * Not allowed in streaming mode.
+ *
+ * Returned status (from utils/Errors.h) can be:
+ * - NO_ERROR: successful operation
+ * - INVALID_OPERATION: the AudioTrack is not stopped or paused, or is streaming mode.
+ */
+ status_t reload();
+
+ /* Returns a handle on the audio output used by this AudioTrack.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returned value:
+ * handle on audio hardware output, or AUDIO_IO_HANDLE_NONE if the
+ * track needed to be re-created but that failed
+ */
+private:
+ audio_io_handle_t getOutput() const;
+public:
+
+ /* Selects the audio device to use for output of this AudioTrack. A value of
+ * AUDIO_PORT_HANDLE_NONE indicates default (AudioPolicyManager) routing.
+ *
+ * Parameters:
+ * The device ID of the selected device (as returned by the AudioDevicesManager API).
+ *
+ * Returned value:
+ * - NO_ERROR: successful operation
+ * TODO: what else can happen here?
+ */
+ status_t setOutputDevice(audio_port_handle_t deviceId);
+
+ /* Returns the ID of the audio device selected for this AudioTrack.
+ * A value of AUDIO_PORT_HANDLE_NONE indicates default (AudioPolicyManager) routing.
+ *
+ * Parameters:
+ * none.
+ */
+ audio_port_handle_t getOutputDevice();
+
+ /* Returns the ID of the audio device actually used by the output to which this AudioTrack is
+ * attached.
+ * A value of AUDIO_PORT_HANDLE_NONE indicates the audio track is not attached to any output.
+ *
+ * Parameters:
+ * none.
+ */
+ audio_port_handle_t getRoutedDeviceId();
+
+ /* Returns the unique session ID associated with this track.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returned value:
+ * AudioTrack session ID.
+ */
+ audio_session_t getSessionId() const { return mSessionId; }
+
+ /* Attach track auxiliary output to specified effect. Use 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);
+
+ /* Public API for TRANSFER_OBTAIN mode.
+ * Obtains a buffer of up to "audioBuffer->frameCount" empty slots for frames.
+ * After filling these slots with data, the caller should release them with releaseBuffer().
+ * If the track buffer is not full, obtainBuffer() returns as many contiguous
+ * [empty slots for] frames as are available immediately.
+ *
+ * If nonContig is non-NULL, it is an output parameter that will be set to the number of
+ * additional non-contiguous frames that are predicted to be available immediately,
+ * if the client were to release the first frames and then call obtainBuffer() again.
+ * This value is only a prediction, and needs to be confirmed.
+ * It will be set to zero for an error return.
+ *
+ * If the track buffer is full and track is stopped, obtainBuffer() returns WOULD_BLOCK
+ * regardless of the value of waitCount.
+ * If the track buffer is full and track is not stopped, obtainBuffer() blocks with a
+ * maximum timeout based on waitCount; see chart below.
+ * Buffers will be returned until the pool
+ * is exhausted, at which point obtainBuffer() will either block
+ * or return WOULD_BLOCK depending on the value of the "waitCount"
+ * parameter.
+ *
+ * Interpretation of waitCount:
+ * +n limits wait time to n * WAIT_PERIOD_MS,
+ * -1 causes an (almost) infinite wait time,
+ * 0 non-blocking.
+ *
+ * Buffer fields
+ * On entry:
+ * frameCount number of [empty slots for] frames requested
+ * size ignored
+ * raw ignored
+ * After error return:
+ * frameCount 0
+ * size 0
+ * raw undefined
+ * After successful return:
+ * frameCount actual number of [empty slots for] frames available, <= number requested
+ * size actual number of bytes available
+ * raw pointer to the buffer
+ */
+ status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount,
+ size_t *nonContig = NULL);
+
+private:
+ /* If nonContig is non-NULL, it is an output parameter that will be set to the number of
+ * additional non-contiguous frames that are predicted to be available immediately,
+ * if the client were to release the first frames and then call obtainBuffer() again.
+ * This value is only a prediction, and needs to be confirmed.
+ * It will be set to zero for an error return.
+ * FIXME We could pass an array of Buffers instead of only one Buffer to obtainBuffer(),
+ * in case the requested amount of frames is in two or more non-contiguous regions.
+ * FIXME requested and elapsed are both relative times. Consider changing to absolute time.
+ */
+ status_t obtainBuffer(Buffer* audioBuffer, const struct timespec *requested,
+ struct timespec *elapsed = NULL, size_t *nonContig = NULL);
+public:
+
+ /* Public API for TRANSFER_OBTAIN mode.
+ * Release a filled buffer of frames for AudioFlinger to process.
+ *
+ * Buffer fields:
+ * frameCount currently ignored but recommend to set to actual number of frames filled
+ * size actual number of bytes filled, must be multiple of frameSize
+ * raw ignored
+ */
+ void releaseBuffer(const Buffer* audioBuffer);
+
+ /* As a convenience we provide a write() interface to the audio buffer.
+ * Input parameter 'size' is in byte units.
+ * This is implemented on top of obtainBuffer/releaseBuffer. For best
+ * performance use callbacks. Returns actual number of bytes written >= 0,
+ * or one of the following negative status codes:
+ * INVALID_OPERATION AudioTrack is configured for static buffer or streaming mode
+ * BAD_VALUE size is invalid
+ * WOULD_BLOCK when obtainBuffer() returns same, or
+ * AudioTrack was stopped during the write
+ * DEAD_OBJECT when AudioFlinger dies or the output device changes and
+ * the track cannot be automatically restored.
+ * The application needs to recreate the AudioTrack
+ * because the audio device changed or AudioFlinger died.
+ * This typically occurs for direct or offload tracks
+ * or if mDoNotReconnect is true.
+ * or any other error code returned by IAudioTrack::start() or restoreTrack_l().
+ * Default behavior is to only return when all data has been transferred. Set 'blocking' to
+ * false for the method to return immediately without waiting to try multiple times to write
+ * the full content of the buffer.
+ */
+ ssize_t write(const void* buffer, size_t size, bool blocking = true);
+
+ /*
+ * Dumps the state of an audio track.
+ * Not a general-purpose API; intended only for use by media player service to dump its tracks.
+ */
+ status_t dump(int fd, const Vector<String16>& args) const;
+
+ /*
+ * Return the total number of frames which AudioFlinger desired but were unavailable,
+ * and thus which resulted in an underrun. Reset to zero by stop().
+ */
+ uint32_t getUnderrunFrames() const;
+
+ /* Get the flags */
+ audio_output_flags_t getFlags() const { AutoMutex _l(mLock); return mFlags; }
+
+ /* Set parameters - only possible when using direct output */
+ status_t setParameters(const String8& keyValuePairs);
+
+ /* Sets the volume shaper object */
+ VolumeShaper::Status applyVolumeShaper(
+ const sp<VolumeShaper::Configuration>& configuration,
+ const sp<VolumeShaper::Operation>& operation);
+
+ /* Gets the volume shaper state */
+ sp<VolumeShaper::State> getVolumeShaperState(int id);
+
+ /* Get parameters */
+ String8 getParameters(const String8& keys);
+
+ /* Poll for a timestamp on demand.
+ * Use if EVENT_NEW_TIMESTAMP is not delivered often enough for your needs,
+ * or if you need to get the most recent timestamp outside of the event callback handler.
+ * Caution: calling this method too often may be inefficient;
+ * if you need a high resolution mapping between frame position and presentation time,
+ * consider implementing that at application level, based on the low resolution timestamps.
+ * Returns NO_ERROR if timestamp is valid.
+ * WOULD_BLOCK if called in STOPPED or FLUSHED state, or if called immediately after
+ * start/ACTIVE, when the number of frames consumed is less than the
+ * overall hardware latency to physical output. In WOULD_BLOCK cases,
+ * one might poll again, or use getPosition(), or use 0 position and
+ * current time for the timestamp.
+ * DEAD_OBJECT if AudioFlinger dies or the output device changes and
+ * the track cannot be automatically restored.
+ * The application needs to recreate the AudioTrack
+ * because the audio device changed or AudioFlinger died.
+ * This typically occurs for direct or offload tracks
+ * or if mDoNotReconnect is true.
+ * INVALID_OPERATION wrong state, or some other error.
+ *
+ * The timestamp parameter is undefined on return, if status is not NO_ERROR.
+ */
+ status_t getTimestamp(AudioTimestamp& timestamp);
+private:
+ status_t getTimestamp_l(AudioTimestamp& timestamp);
+public:
+
+ /* Return the extended timestamp, with additional timebase info and improved drain behavior.
+ *
+ * This is similar to the AudioTrack.java API:
+ * getTimestamp(@NonNull AudioTimestamp timestamp, @AudioTimestamp.Timebase int timebase)
+ *
+ * Some differences between this method and the getTimestamp(AudioTimestamp& timestamp) method
+ *
+ * 1. stop() by itself does not reset the frame position.
+ * A following start() resets the frame position to 0.
+ * 2. flush() by itself does not reset the frame position.
+ * The frame position advances by the number of frames flushed,
+ * when the first frame after flush reaches the audio sink.
+ * 3. BOOTTIME clock offsets are provided to help synchronize with
+ * non-audio streams, e.g. sensor data.
+ * 4. Position is returned with 64 bits of resolution.
+ *
+ * Parameters:
+ * timestamp: A pointer to the caller allocated ExtendedTimestamp.
+ *
+ * Returns NO_ERROR on success; timestamp is filled with valid data.
+ * BAD_VALUE if timestamp is NULL.
+ * WOULD_BLOCK if called immediately after start() when the number
+ * of frames consumed is less than the
+ * overall hardware latency to physical output. In WOULD_BLOCK cases,
+ * one might poll again, or use getPosition(), or use 0 position and
+ * current time for the timestamp.
+ * If WOULD_BLOCK is returned, the timestamp is still
+ * modified with the LOCATION_CLIENT portion filled.
+ * DEAD_OBJECT if AudioFlinger dies or the output device changes and
+ * the track cannot be automatically restored.
+ * The application needs to recreate the AudioTrack
+ * because the audio device changed or AudioFlinger died.
+ * This typically occurs for direct or offloaded tracks
+ * or if mDoNotReconnect is true.
+ * INVALID_OPERATION if called on a offloaded or direct track.
+ * Use getTimestamp(AudioTimestamp& timestamp) instead.
+ */
+ status_t getTimestamp(ExtendedTimestamp *timestamp);
+private:
+ status_t getTimestamp_l(ExtendedTimestamp *timestamp);
+public:
+
+ /* Add an AudioDeviceCallback. The caller will be notified when the audio device to which this
+ * AudioTrack is routed is updated.
+ * Replaces any previously installed callback.
+ * Parameters:
+ * callback: The callback interface
+ * Returns NO_ERROR if successful.
+ * INVALID_OPERATION if the same callback is already installed.
+ * NO_INIT or PREMISSION_DENIED if AudioFlinger service is not reachable
+ * BAD_VALUE if the callback is NULL
+ */
+ status_t addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
+
+ /* remove an AudioDeviceCallback.
+ * Parameters:
+ * callback: The callback interface
+ * Returns NO_ERROR if successful.
+ * INVALID_OPERATION if the callback is not installed
+ * BAD_VALUE if the callback is NULL
+ */
+ status_t removeAudioDeviceCallback(
+ const sp<AudioSystem::AudioDeviceCallback>& callback);
+
+ /* Obtain the pending duration in milliseconds for playback of pure PCM
+ * (mixable without embedded timing) data remaining in AudioTrack.
+ *
+ * This is used to estimate the drain time for the client-server buffer
+ * so the choice of ExtendedTimestamp::LOCATION_SERVER is default.
+ * One may optionally request to find the duration to play through the HAL
+ * by specifying a location ExtendedTimestamp::LOCATION_KERNEL; however,
+ * INVALID_OPERATION may be returned if the kernel location is unavailable.
+ *
+ * Returns NO_ERROR if successful.
+ * INVALID_OPERATION if ExtendedTimestamp::LOCATION_KERNEL cannot be obtained
+ * or the AudioTrack does not contain pure PCM data.
+ * BAD_VALUE if msec is nullptr or location is invalid.
+ */
+ status_t pendingDuration(int32_t *msec,
+ ExtendedTimestamp::Location location = ExtendedTimestamp::LOCATION_SERVER);
+
+ /* hasStarted() is used to determine if audio is now audible at the device after
+ * a start() command. The underlying implementation checks a nonzero timestamp position
+ * or increment for the audible assumption.
+ *
+ * hasStarted() returns true if the track has been started() and audio is audible
+ * and no subsequent pause() or flush() has been called. Immediately after pause() or
+ * flush() hasStarted() will return false.
+ *
+ * If stop() has been called, hasStarted() will return true if audio is still being
+ * delivered or has finished delivery (even if no audio was written) for both offloaded
+ * and normal tracks. This property removes a race condition in checking hasStarted()
+ * for very short clips, where stop() must be called to finish drain.
+ *
+ * In all cases, hasStarted() may turn false briefly after a subsequent start() is called
+ * until audio becomes audible again.
+ */
+ bool hasStarted(); // not const
+
+protected:
+ /* copying audio tracks is not allowed */
+ AudioTrack(const AudioTrack& other);
+ AudioTrack& operator = (const AudioTrack& other);
+
+ /* a small internal class to handle the callback */
+ class AudioTrackThread : public Thread
+ {
+ public:
+ AudioTrackThread(AudioTrack& receiver, bool bCanCallJava = false);
+
+ // Do not call Thread::requestExitAndWait() without first calling requestExit().
+ // Thread::requestExitAndWait() is not virtual, and the implementation doesn't do enough.
+ virtual void requestExit();
+
+ void pause(); // suspend thread from execution at next loop boundary
+ void resume(); // allow thread to execute, if not requested to exit
+ void wake(); // wake to handle changed notification conditions.
+
+ private:
+ void pauseInternal(nsecs_t ns = 0LL);
+ // like pause(), but only used internally within thread
+
+ friend class AudioTrack;
+ virtual bool threadLoop();
+ AudioTrack& mReceiver;
+ virtual ~AudioTrackThread();
+ Mutex mMyLock; // Thread::mLock is private
+ Condition mMyCond; // Thread::mThreadExitedCondition is private
+ bool mPaused; // whether thread is requested to pause at next loop entry
+ bool mPausedInt; // whether thread internally requests pause
+ nsecs_t mPausedNs; // if mPausedInt then associated timeout, otherwise ignored
+ bool mIgnoreNextPausedInt; // skip any internal pause and go immediately
+ // to processAudioBuffer() as state may have changed
+ // since pause time calculated.
+ };
+
+ // body of AudioTrackThread::threadLoop()
+ // returns the maximum amount of time before we would like to run again, where:
+ // 0 immediately
+ // > 0 no later than this many nanoseconds from now
+ // NS_WHENEVER still active but no particular deadline
+ // NS_INACTIVE inactive so don't run again until re-started
+ // NS_NEVER never again
+ static const nsecs_t NS_WHENEVER = -1, NS_INACTIVE = -2, NS_NEVER = -3;
+ nsecs_t processAudioBuffer();
+
+ // caller must hold lock on mLock for all _l methods
+
+ status_t createTrack_l();
+
+ // can only be called when mState != STATE_ACTIVE
+ void flush_l();
+
+ void setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount);
+
+ // FIXME enum is faster than strcmp() for parameter 'from'
+ status_t restoreTrack_l(const char *from);
+
+ uint32_t getUnderrunCount_l() const;
+
+ bool isOffloaded() const;
+ bool isDirect() const;
+ bool isOffloadedOrDirect() const;
+
+ bool isOffloaded_l() const
+ { return (mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0; }
+
+ bool isOffloadedOrDirect_l() const
+ { return (mFlags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|
+ AUDIO_OUTPUT_FLAG_DIRECT)) != 0; }
+
+ bool isDirect_l() const
+ { return (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0; }
+
+ // pure pcm data is mixable (which excludes HW_AV_SYNC, with embedded timing)
+ bool isPurePcmData_l() const
+ { return audio_is_linear_pcm(mFormat)
+ && (mAttributes.flags & AUDIO_FLAG_HW_AV_SYNC) == 0; }
+
+ // increment mPosition by the delta of mServer, and return new value of mPosition
+ Modulo<uint32_t> updateAndGetPosition_l();
+
+ // check sample rate and speed is compatible with AudioTrack
+ bool isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed) const;
+
+ void restartIfDisabled();
+
+ // Next 4 fields may be changed if IAudioTrack is re-created, but always != 0
+ sp<IAudioTrack> mAudioTrack;
+ sp<IMemory> mCblkMemory;
+ audio_track_cblk_t* mCblk; // re-load after mLock.unlock()
+ audio_io_handle_t mOutput; // returned by AudioSystem::getOutput()
+
+ sp<AudioTrackThread> mAudioTrackThread;
+ bool mThreadCanCallJava;
+
+ float mVolume[2];
+ float mSendLevel;
+ mutable uint32_t mSampleRate; // mutable because getSampleRate() can update it
+ uint32_t mOriginalSampleRate;
+ AudioPlaybackRate mPlaybackRate;
+ float mMaxRequiredSpeed; // use PCM buffer size to allow this speed
+
+ // Corresponds to current IAudioTrack, value is reported back by AudioFlinger to the client.
+ // This allocated buffer size is maintained by the proxy.
+ size_t mFrameCount; // maximum size of buffer
+
+ size_t mReqFrameCount; // frame count to request the first or next time
+ // a new IAudioTrack is needed, non-decreasing
+
+ // The following AudioFlinger server-side values are cached in createAudioTrack_l().
+ // These values can be used for informational purposes until the track is invalidated,
+ // whereupon restoreTrack_l() calls createTrack_l() to update the values.
+ uint32_t mAfLatency; // AudioFlinger latency in ms
+ size_t mAfFrameCount; // AudioFlinger frame count
+ uint32_t mAfSampleRate; // AudioFlinger sample rate
+
+ // constant after constructor or set()
+ audio_format_t mFormat; // as requested by client, not forced to 16-bit
+ audio_stream_type_t mStreamType; // mStreamType == AUDIO_STREAM_DEFAULT implies
+ // this AudioTrack has valid attributes
+ uint32_t mChannelCount;
+ audio_channel_mask_t mChannelMask;
+ sp<IMemory> mSharedBuffer;
+ transfer_type mTransfer;
+ audio_offload_info_t mOffloadInfoCopy;
+ const audio_offload_info_t* mOffloadInfo;
+ audio_attributes_t mAttributes;
+
+ size_t mFrameSize; // frame size in bytes
+
+ status_t mStatus;
+
+ // can change dynamically when IAudioTrack invalidated
+ uint32_t mLatency; // in ms
+
+ // Indicates the current track state. Protected by mLock.
+ enum State {
+ STATE_ACTIVE,
+ STATE_STOPPED,
+ STATE_PAUSED,
+ STATE_PAUSED_STOPPING,
+ STATE_FLUSHED,
+ STATE_STOPPING,
+ } mState;
+
+ // for client callback handler
+ callback_t mCbf; // callback handler for events, or NULL
+ void* mUserData;
+
+ // for notification APIs
+
+ // next 2 fields are const after constructor or set()
+ uint32_t mNotificationFramesReq; // requested number of frames between each
+ // notification callback,
+ // at initial source sample rate
+ uint32_t mNotificationsPerBufferReq;
+ // requested number of notifications per buffer,
+ // currently only used for fast tracks with
+ // default track buffer size
+
+ uint32_t mNotificationFramesAct; // actual number of frames between each
+ // notification callback,
+ // at initial source sample rate
+ bool mRefreshRemaining; // processAudioBuffer() should refresh
+ // mRemainingFrames and mRetryOnPartialBuffer
+
+ // used for static track cbf and restoration
+ int32_t mLoopCount; // last setLoop loopCount; zero means disabled
+ uint32_t mLoopStart; // last setLoop loopStart
+ uint32_t mLoopEnd; // last setLoop loopEnd
+ int32_t mLoopCountNotified; // the last loopCount notified by callback.
+ // mLoopCountNotified counts down, matching
+ // the remaining loop count for static track
+ // playback.
+
+ // These are private to processAudioBuffer(), and are not protected by a lock
+ uint32_t mRemainingFrames; // number of frames to request in obtainBuffer()
+ bool mRetryOnPartialBuffer; // sleep and retry after partial obtainBuffer()
+ uint32_t mObservedSequence; // last observed value of mSequence
+
+ Modulo<uint32_t> mMarkerPosition; // in wrapping (overflow) frame units
+ bool mMarkerReached;
+ Modulo<uint32_t> mNewPosition; // in frames
+ uint32_t mUpdatePeriod; // in frames, zero means no EVENT_NEW_POS
+
+ Modulo<uint32_t> mServer; // in frames, last known mProxy->getPosition()
+ // which is count of frames consumed by server,
+ // reset by new IAudioTrack,
+ // whether it is reset by stop() is TBD
+ Modulo<uint32_t> mPosition; // in frames, like mServer except continues
+ // monotonically after new IAudioTrack,
+ // and could be easily widened to uint64_t
+ Modulo<uint32_t> mReleased; // count of frames released to server
+ // but not necessarily consumed by server,
+ // reset by stop() but continues monotonically
+ // after new IAudioTrack to restore mPosition,
+ // and could be easily widened to uint64_t
+ int64_t mStartUs; // the start time after flush or stop.
+ // only used for offloaded and direct tracks.
+ ExtendedTimestamp mStartEts; // Extended timestamp at start for normal
+ // AudioTracks.
+ AudioTimestamp mStartTs; // Timestamp at start for offloaded or direct
+ // AudioTracks.
+
+ bool mPreviousTimestampValid;// true if mPreviousTimestamp is valid
+ bool mTimestampStartupGlitchReported; // reduce log spam
+ bool mRetrogradeMotionReported; // reduce log spam
+ AudioTimestamp mPreviousTimestamp; // used to detect retrograde motion
+ ExtendedTimestamp::Location mPreviousLocation; // location used for previous timestamp
+
+ uint32_t mUnderrunCountOffset; // updated when restoring tracks
+
+ int64_t mFramesWritten; // total frames written. reset to zero after
+ // the start() following stop(). It is not
+ // changed after restoring the track or
+ // after flush.
+ int64_t mFramesWrittenServerOffset; // An offset to server frames due to
+ // restoring AudioTrack, or stop/start.
+ // This offset is also used for static tracks.
+ int64_t mFramesWrittenAtRestore; // Frames written at restore point (or frames
+ // delivered for static tracks).
+ // -1 indicates no previous restore point.
+
+ audio_output_flags_t mFlags; // same as mOrigFlags, except for bits that may
+ // be denied by client or server, such as
+ // AUDIO_OUTPUT_FLAG_FAST. mLock must be
+ // held to read or write those bits reliably.
+ audio_output_flags_t mOrigFlags; // as specified in constructor or set(), const
+
+ bool mDoNotReconnect;
+
+ audio_session_t mSessionId;
+ int mAuxEffectId;
+
+ mutable Mutex mLock;
+
+ int mPreviousPriority; // before start()
+ SchedPolicy mPreviousSchedulingGroup;
+ bool mAwaitBoost; // thread should wait for priority boost before running
+
+ // The proxy should only be referenced while a lock is held because the proxy isn't
+ // multi-thread safe, especially the SingleStateQueue part of the proxy.
+ // An exception is that a blocking ClientProxy::obtainBuffer() may be called without a lock,
+ // provided that the caller also holds an extra reference to the proxy and shared memory to keep
+ // them around in case they are replaced during the obtainBuffer().
+ sp<StaticAudioTrackClientProxy> mStaticProxy; // for type safety only
+ sp<AudioTrackClientProxy> mProxy; // primary owner of the memory
+
+ bool mInUnderrun; // whether track is currently in underrun state
+ uint32_t mPausedPosition;
+
+ // For Device Selection API
+ // a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing.
+ audio_port_handle_t mSelectedDeviceId;
+
+ sp<VolumeHandler> mVolumeHandler;
+
+ int32_t mVolumeShaperId;
+
+private:
+ class DeathNotifier : public IBinder::DeathRecipient {
+ public:
+ DeathNotifier(AudioTrack* audioTrack) : mAudioTrack(audioTrack) { }
+ protected:
+ virtual void binderDied(const wp<IBinder>& who);
+ private:
+ const wp<AudioTrack> mAudioTrack;
+ };
+
+ sp<DeathNotifier> mDeathNotifier;
+ uint32_t mSequence; // incremented for each new IAudioTrack attempt
+ uid_t mClientUid;
+ pid_t mClientPid;
+
+ sp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
+ audio_port_handle_t mPortId; // unique ID allocated by audio policy
+};
+
+}; // namespace android
+
+#endif // ANDROID_AUDIOTRACK_H
diff --git a/media/libaudioclient/include/IAudioFlinger.h b/media/libaudioclient/include/IAudioFlinger.h
new file mode 100644
index 0000000..8c5e61a
--- /dev/null
+++ b/media/libaudioclient/include/IAudioFlinger.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2007 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_IAUDIOFLINGER_H
+#define ANDROID_IAUDIOFLINGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <binder/IInterface.h>
+#include <media/IAudioTrack.h>
+#include <media/IAudioRecord.h>
+#include <media/IAudioFlingerClient.h>
+#include <system/audio.h>
+#include <system/audio_effect.h>
+#include <system/audio_policy.h>
+#include <media/IEffect.h>
+#include <media/IEffectClient.h>
+#include <utils/String8.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class IAudioFlinger : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(AudioFlinger);
+
+
+ // invariant on exit for all APIs that return an sp<>:
+ // (return value != 0) == (*status == NO_ERROR)
+
+ /* create an audio track and registers it with AudioFlinger.
+ * return null if the track cannot be created.
+ */
+ virtual sp<IAudioTrack> createTrack(
+ audio_stream_type_t streamType,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ size_t *pFrameCount,
+ audio_output_flags_t *flags,
+ const sp<IMemory>& sharedBuffer,
+ // On successful return, AudioFlinger takes over the handle
+ // reference and will release it when the track is destroyed.
+ // However on failure, the client is responsible for release.
+ audio_io_handle_t output,
+ pid_t pid,
+ pid_t tid, // -1 means unused, otherwise must be valid non-0
+ audio_session_t *sessionId,
+ int clientUid,
+ status_t *status,
+ audio_port_handle_t portId) = 0;
+
+ virtual sp<IAudioRecord> openRecord(
+ // On successful return, AudioFlinger takes over the handle
+ // reference and will release it when the track is destroyed.
+ // However on failure, the client is responsible for release.
+ audio_io_handle_t input,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ const String16& callingPackage,
+ size_t *pFrameCount,
+ audio_input_flags_t *flags,
+ pid_t pid,
+ pid_t tid, // -1 means unused, otherwise must be valid non-0
+ int clientUid,
+ audio_session_t *sessionId,
+ size_t *notificationFrames,
+ sp<IMemory>& cblk,
+ sp<IMemory>& buffers, // return value 0 means it follows cblk
+ status_t *status,
+ audio_port_handle_t portId) = 0;
+
+ // FIXME Surprisingly, format/latency don't work for input handles
+
+ /* query the audio hardware state. This state never changes,
+ * and therefore can be cached.
+ */
+ virtual uint32_t sampleRate(audio_io_handle_t ioHandle) const = 0;
+
+ // reserved; formerly channelCount()
+
+ virtual audio_format_t format(audio_io_handle_t output) const = 0;
+ virtual size_t frameCount(audio_io_handle_t ioHandle) const = 0;
+
+ // return estimated latency in milliseconds
+ virtual uint32_t latency(audio_io_handle_t output) const = 0;
+
+ /* set/get the audio hardware state. This will probably be used by
+ * the preference panel, mostly.
+ */
+ virtual status_t setMasterVolume(float value) = 0;
+ virtual status_t setMasterMute(bool muted) = 0;
+
+ virtual float masterVolume() const = 0;
+ virtual bool masterMute() const = 0;
+
+ /* set/get stream type state. This will probably be used by
+ * the preference panel, mostly.
+ */
+ virtual status_t setStreamVolume(audio_stream_type_t stream, float value,
+ audio_io_handle_t output) = 0;
+ virtual status_t setStreamMute(audio_stream_type_t stream, bool muted) = 0;
+
+ virtual float streamVolume(audio_stream_type_t stream,
+ audio_io_handle_t output) const = 0;
+ virtual bool streamMute(audio_stream_type_t stream) const = 0;
+
+ // set audio mode
+ virtual status_t setMode(audio_mode_t mode) = 0;
+
+ // mic mute/state
+ virtual status_t setMicMute(bool state) = 0;
+ virtual bool getMicMute() const = 0;
+
+ virtual status_t setParameters(audio_io_handle_t ioHandle,
+ const String8& keyValuePairs) = 0;
+ virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys)
+ const = 0;
+
+ // Register an object to receive audio input/output change and track notifications.
+ // For a given calling pid, AudioFlinger disregards any registrations after the first.
+ // Thus the IAudioFlingerClient must be a singleton per process.
+ virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0;
+
+ // retrieve the audio recording buffer size
+ // FIXME This API assumes a route, and so should be deprecated.
+ virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
+ audio_channel_mask_t channelMask) const = 0;
+
+ virtual status_t openOutput(audio_module_handle_t module,
+ audio_io_handle_t *output,
+ audio_config_t *config,
+ audio_devices_t *devices,
+ const String8& address,
+ uint32_t *latencyMs,
+ audio_output_flags_t flags) = 0;
+ virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
+ audio_io_handle_t output2) = 0;
+ virtual status_t closeOutput(audio_io_handle_t output) = 0;
+ virtual status_t suspendOutput(audio_io_handle_t output) = 0;
+ virtual status_t restoreOutput(audio_io_handle_t output) = 0;
+
+ virtual status_t openInput(audio_module_handle_t module,
+ audio_io_handle_t *input,
+ audio_config_t *config,
+ audio_devices_t *device,
+ const String8& address,
+ audio_source_t source,
+ audio_input_flags_t flags) = 0;
+ virtual status_t closeInput(audio_io_handle_t input) = 0;
+
+ virtual status_t invalidateStream(audio_stream_type_t stream) = 0;
+
+ virtual status_t setVoiceVolume(float volume) = 0;
+
+ virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
+ audio_io_handle_t output) const = 0;
+
+ virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const = 0;
+
+ virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use) = 0;
+
+ virtual void acquireAudioSessionId(audio_session_t audioSession, pid_t pid) = 0;
+ virtual void releaseAudioSessionId(audio_session_t audioSession, pid_t pid) = 0;
+
+ virtual status_t queryNumberEffects(uint32_t *numEffects) const = 0;
+
+ virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) const = 0;
+
+ virtual status_t getEffectDescriptor(const effect_uuid_t *pEffectUUID,
+ effect_descriptor_t *pDescriptor) const = 0;
+
+ virtual sp<IEffect> createEffect(
+ effect_descriptor_t *pDesc,
+ const sp<IEffectClient>& client,
+ int32_t priority,
+ // AudioFlinger doesn't take over handle reference from client
+ audio_io_handle_t output,
+ audio_session_t sessionId,
+ const String16& callingPackage,
+ pid_t pid,
+ status_t *status,
+ int *id,
+ int *enabled) = 0;
+
+ virtual status_t moveEffects(audio_session_t session, audio_io_handle_t srcOutput,
+ audio_io_handle_t dstOutput) = 0;
+
+ virtual audio_module_handle_t loadHwModule(const char *name) = 0;
+
+ // helpers for android.media.AudioManager.getProperty(), see description there for meaning
+ // FIXME move these APIs to AudioPolicy to permit a more accurate implementation
+ // that looks on primary device for a stream with fast flag, primary flag, or first one.
+ virtual uint32_t getPrimaryOutputSamplingRate() = 0;
+ virtual size_t getPrimaryOutputFrameCount() = 0;
+
+ // Intended for AudioService to inform AudioFlinger of device's low RAM attribute,
+ // and should be called at most once. For a definition of what "low RAM" means, see
+ // android.app.ActivityManager.isLowRamDevice().
+ virtual status_t setLowRamDevice(bool isLowRamDevice) = 0;
+
+ /* List available audio ports and their attributes */
+ virtual status_t listAudioPorts(unsigned int *num_ports,
+ struct audio_port *ports) = 0;
+
+ /* Get attributes for a given audio port */
+ virtual status_t getAudioPort(struct audio_port *port) = 0;
+
+ /* Create an audio patch between several source and sink ports */
+ virtual status_t createAudioPatch(const struct audio_patch *patch,
+ audio_patch_handle_t *handle) = 0;
+
+ /* Release an audio patch */
+ virtual status_t releaseAudioPatch(audio_patch_handle_t handle) = 0;
+
+ /* List existing audio patches */
+ virtual status_t listAudioPatches(unsigned int *num_patches,
+ struct audio_patch *patches) = 0;
+ /* Set audio port configuration */
+ virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
+
+ /* Get the HW synchronization source used for an audio session */
+ virtual audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId) = 0;
+
+ /* Indicate JAVA services are ready (scheduling, power management ...) */
+ virtual status_t systemReady() = 0;
+
+ // Returns the number of frames per audio HAL buffer.
+ virtual size_t frameCountHAL(audio_io_handle_t ioHandle) const = 0;
+};
+
+
+// ----------------------------------------------------------------------------
+
+class BnAudioFlinger : public BnInterface<IAudioFlinger>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IAUDIOFLINGER_H
diff --git a/media/libaudioclient/include/IAudioFlingerClient.h b/media/libaudioclient/include/IAudioFlingerClient.h
new file mode 100644
index 0000000..0080bc9
--- /dev/null
+++ b/media/libaudioclient/include/IAudioFlingerClient.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 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_IAUDIOFLINGERCLIENT_H
+#define ANDROID_IAUDIOFLINGERCLIENT_H
+
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <utils/KeyedVector.h>
+#include <system/audio.h>
+#include <media/AudioIoDescriptor.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class IAudioFlingerClient : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(AudioFlingerClient);
+
+ // Notifies a change of audio input/output configuration.
+ virtual void ioConfigChanged(audio_io_config_event event,
+ const sp<AudioIoDescriptor>& ioDesc) = 0;
+
+};
+
+
+// ----------------------------------------------------------------------------
+
+class BnAudioFlingerClient : public BnInterface<IAudioFlingerClient>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IAUDIOFLINGERCLIENT_H
diff --git a/media/libaudioclient/include/IAudioPolicyService.h b/media/libaudioclient/include/IAudioPolicyService.h
new file mode 100644
index 0000000..d111fd2
--- /dev/null
+++ b/media/libaudioclient/include/IAudioPolicyService.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2009 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_IAUDIOPOLICYSERVICE_H
+#define ANDROID_IAUDIOPOLICYSERVICE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <binder/IInterface.h>
+#include <media/AudioSystem.h>
+#include <media/AudioPolicy.h>
+#include <media/IAudioPolicyServiceClient.h>
+
+#include <system/audio_policy.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class IAudioPolicyService : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(AudioPolicyService);
+
+ //
+ // IAudioPolicyService interface (see AudioPolicyInterface for method descriptions)
+ //
+ virtual status_t setDeviceConnectionState(audio_devices_t device,
+ audio_policy_dev_state_t state,
+ const char *device_address,
+ const char *device_name) = 0;
+ virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
+ const char *device_address) = 0;
+ virtual status_t handleDeviceConfigChange(audio_devices_t device,
+ const char *device_address,
+ const char *device_name) = 0;
+ virtual status_t setPhoneState(audio_mode_t state) = 0;
+ virtual status_t setForceUse(audio_policy_force_use_t usage,
+ audio_policy_forced_cfg_t config) = 0;
+ virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) = 0;
+ virtual audio_io_handle_t getOutput(audio_stream_type_t stream,
+ uint32_t samplingRate = 0,
+ audio_format_t format = AUDIO_FORMAT_DEFAULT,
+ audio_channel_mask_t channelMask = 0,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ const audio_offload_info_t *offloadInfo = NULL) = 0;
+ virtual status_t getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ uid_t uid,
+ const audio_config_t *config,
+ audio_output_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *portId) = 0;
+ virtual status_t startOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session) = 0;
+ virtual status_t stopOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session) = 0;
+ virtual void releaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session) = 0;
+ virtual status_t getInputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *input,
+ audio_session_t session,
+ pid_t pid,
+ uid_t uid,
+ const audio_config_base_t *config,
+ audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *portId) = 0;
+ virtual status_t startInput(audio_io_handle_t input,
+ audio_session_t session) = 0;
+ virtual status_t stopInput(audio_io_handle_t input,
+ audio_session_t session) = 0;
+ virtual void releaseInput(audio_io_handle_t input,
+ audio_session_t session) = 0;
+ virtual status_t initStreamVolume(audio_stream_type_t stream,
+ int indexMin,
+ int indexMax) = 0;
+ virtual status_t setStreamVolumeIndex(audio_stream_type_t stream,
+ int index,
+ audio_devices_t device) = 0;
+ virtual status_t getStreamVolumeIndex(audio_stream_type_t stream,
+ int *index,
+ audio_devices_t device) = 0;
+ virtual uint32_t getStrategyForStream(audio_stream_type_t stream) = 0;
+ virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream) = 0;
+ virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc) = 0;
+ virtual status_t registerEffect(const effect_descriptor_t *desc,
+ audio_io_handle_t io,
+ uint32_t strategy,
+ audio_session_t session,
+ int id) = 0;
+ virtual status_t unregisterEffect(int id) = 0;
+ virtual status_t setEffectEnabled(int id, bool enabled) = 0;
+ virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const = 0;
+ virtual bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0)
+ const = 0;
+ virtual bool isSourceActive(audio_source_t source) const = 0;
+ virtual status_t queryDefaultPreProcessing(audio_session_t audioSession,
+ effect_descriptor_t *descriptors,
+ uint32_t *count) = 0;
+ // Check if offload is possible for given format, stream type, sample rate,
+ // bit rate, duration, video and streaming or offload property is enabled
+ virtual bool isOffloadSupported(const audio_offload_info_t& info) = 0;
+
+ /* List available audio ports and their attributes */
+ virtual status_t listAudioPorts(audio_port_role_t role,
+ audio_port_type_t type,
+ unsigned int *num_ports,
+ struct audio_port *ports,
+ unsigned int *generation) = 0;
+
+ /* Get attributes for a given audio port */
+ virtual status_t getAudioPort(struct audio_port *port) = 0;
+
+ /* Create an audio patch between several source and sink ports */
+ virtual status_t createAudioPatch(const struct audio_patch *patch,
+ audio_patch_handle_t *handle) = 0;
+
+ /* Release an audio patch */
+ virtual status_t releaseAudioPatch(audio_patch_handle_t handle) = 0;
+
+ /* List existing audio patches */
+ virtual status_t listAudioPatches(unsigned int *num_patches,
+ struct audio_patch *patches,
+ unsigned int *generation) = 0;
+ /* Set audio port configuration */
+ virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
+
+ virtual void registerClient(const sp<IAudioPolicyServiceClient>& client) = 0;
+
+ virtual void setAudioPortCallbacksEnabled(bool enabled) = 0;
+
+ virtual status_t acquireSoundTriggerSession(audio_session_t *session,
+ audio_io_handle_t *ioHandle,
+ audio_devices_t *device) = 0;
+
+ virtual status_t releaseSoundTriggerSession(audio_session_t session) = 0;
+
+ virtual audio_mode_t getPhoneState() = 0;
+
+ virtual status_t registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration) = 0;
+
+ virtual status_t startAudioSource(const struct audio_port_config *source,
+ const audio_attributes_t *attributes,
+ audio_patch_handle_t *handle) = 0;
+ virtual status_t stopAudioSource(audio_patch_handle_t handle) = 0;
+
+ virtual status_t setMasterMono(bool mono) = 0;
+ virtual status_t getMasterMono(bool *mono) = 0;
+};
+
+
+// ----------------------------------------------------------------------------
+
+class BnAudioPolicyService : public BnInterface<IAudioPolicyService>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IAUDIOPOLICYSERVICE_H
diff --git a/media/libaudioclient/include/IAudioPolicyServiceClient.h b/media/libaudioclient/include/IAudioPolicyServiceClient.h
new file mode 100644
index 0000000..d94ad00
--- /dev/null
+++ b/media/libaudioclient/include/IAudioPolicyServiceClient.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 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_IAUDIOPOLICYSERVICECLIENT_H
+#define ANDROID_IAUDIOPOLICYSERVICECLIENT_H
+
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <system/audio.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class IAudioPolicyServiceClient : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(AudioPolicyServiceClient);
+
+ // Notifies a change of audio port configuration.
+ virtual void onAudioPortListUpdate() = 0;
+ // Notifies a change of audio patch configuration.
+ virtual void onAudioPatchListUpdate() = 0;
+ // Notifies a change in the mixing state of a specific mix in a dynamic audio policy
+ virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0;
+ // Notifies a change of audio recording configuration
+ virtual void onRecordingConfigurationUpdate(int event, audio_session_t session,
+ audio_source_t source,
+ const audio_config_base_t *clientConfig,
+ const audio_config_base_t *deviceConfig,
+ audio_patch_handle_t patchHandle) = 0;
+};
+
+
+// ----------------------------------------------------------------------------
+
+class BnAudioPolicyServiceClient : public BnInterface<IAudioPolicyServiceClient>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IAUDIOPOLICYSERVICECLIENT_H
diff --git a/media/libaudioclient/include/IAudioRecord.h b/media/libaudioclient/include/IAudioRecord.h
new file mode 100644
index 0000000..7768176
--- /dev/null
+++ b/media/libaudioclient/include/IAudioRecord.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007 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 IAUDIORECORD_H_
+#define IAUDIORECORD_H_
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <binder/IInterface.h>
+#include <binder/IMemory.h>
+#include <system/audio.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class IAudioRecord : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(AudioRecord);
+
+ /* After it's created the track is not active. Call start() to
+ * make it active.
+ */
+ virtual status_t start(int /*AudioSystem::sync_event_t*/ event,
+ audio_session_t triggerSession) = 0;
+
+ /* Stop a track. If set, the callback will cease being called and
+ * obtainBuffer will return an error. Buffers that are already released
+ * will be processed, unless flush() is called.
+ */
+ virtual void stop() = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnAudioRecord : public BnInterface<IAudioRecord>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif /*IAUDIORECORD_H_*/
diff --git a/media/libaudioclient/include/IAudioTrack.h b/media/libaudioclient/include/IAudioTrack.h
new file mode 100644
index 0000000..27a62d6
--- /dev/null
+++ b/media/libaudioclient/include/IAudioTrack.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2007 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_IAUDIOTRACK_H
+#define ANDROID_IAUDIOTRACK_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <binder/IInterface.h>
+#include <binder/IMemory.h>
+#include <utils/String8.h>
+#include <media/AudioTimestamp.h>
+#include <media/VolumeShaper.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class IAudioTrack : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(AudioTrack);
+
+ /* Get this track's control block */
+ virtual sp<IMemory> getCblk() const = 0;
+
+ /* After it's created the track is not active. Call start() to
+ * make it active.
+ */
+ virtual status_t start() = 0;
+
+ /* Stop a track. If set, the callback will cease being called and
+ * obtainBuffer will return an error. Buffers that are already released
+ * will continue to be processed, unless/until flush() is called.
+ */
+ virtual void stop() = 0;
+
+ /* Flush a stopped or paused track. All pending/released buffers are discarded.
+ * This function has no effect if the track is not stopped or paused.
+ */
+ virtual void flush() = 0;
+
+ /* Pause a track. If set, the callback will cease being called and
+ * obtainBuffer will return an error. Buffers that are already released
+ * will continue to be processed, unless/until flush() is called.
+ */
+ 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;
+
+ /* Send parameters to the audio hardware */
+ virtual status_t setParameters(const String8& keyValuePairs) = 0;
+
+ /* Return NO_ERROR if timestamp is valid. timestamp is undefined otherwise. */
+ virtual status_t getTimestamp(AudioTimestamp& timestamp) = 0;
+
+ /* Signal the playback thread for a change in control block */
+ virtual void signal() = 0;
+
+ /* Sets the volume shaper */
+ virtual VolumeShaper::Status applyVolumeShaper(
+ const sp<VolumeShaper::Configuration>& configuration,
+ const sp<VolumeShaper::Operation>& operation) = 0;
+
+ /* gets the volume shaper state */
+ virtual sp<VolumeShaper::State> getVolumeShaperState(int id) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnAudioTrack : public BnInterface<IAudioTrack>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IAUDIOTRACK_H
diff --git a/media/libaudioclient/include/IEffect.h b/media/libaudioclient/include/IEffect.h
new file mode 100644
index 0000000..ff04869
--- /dev/null
+++ b/media/libaudioclient/include/IEffect.h
@@ -0,0 +1,60 @@
+/*
+ * 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(uint32_t cmdCode,
+ uint32_t cmdSize,
+ void *pCmdData,
+ uint32_t *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/media/libaudioclient/include/IEffectClient.h b/media/libaudioclient/include/IEffectClient.h
new file mode 100644
index 0000000..2f78c98
--- /dev/null
+++ b/media/libaudioclient/include/IEffectClient.h
@@ -0,0 +1,54 @@
+/*
+ * 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(uint32_t cmdCode,
+ uint32_t cmdSize,
+ void *pCmdData,
+ uint32_t 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/media/libaudioclient/include/ToneGenerator.h b/media/libaudioclient/include/ToneGenerator.h
new file mode 100644
index 0000000..9fd5f61
--- /dev/null
+++ b/media/libaudioclient/include/ToneGenerator.h
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2008 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_TONEGENERATOR_H_
+#define ANDROID_TONEGENERATOR_H_
+
+#include <media/AudioSystem.h>
+#include <media/AudioTrack.h>
+#include <utils/Compat.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class ToneGenerator {
+public:
+
+ // List of all available tones
+ // This enum must be kept consistant with constants in ToneGenerator JAVA class
+ enum tone_type {
+ // DTMF tones ITU-T Recommendation Q.23
+ TONE_DTMF_0 = 0, // 0 key: 1336Hz, 941Hz
+ TONE_DTMF_1, // 1 key: 1209Hz, 697Hz
+ TONE_DTMF_2, // 2 key: 1336Hz, 697Hz
+ TONE_DTMF_3, // 3 key: 1477Hz, 697Hz
+ TONE_DTMF_4, // 4 key: 1209Hz, 770Hz
+ TONE_DTMF_5, // 5 key: 1336Hz, 770Hz
+ TONE_DTMF_6, // 6 key: 1477Hz, 770Hz
+ TONE_DTMF_7, // 7 key: 1209Hz, 852Hz
+ TONE_DTMF_8, // 8 key: 1336Hz, 852Hz
+ TONE_DTMF_9, // 9 key: 1477Hz, 852Hz
+ TONE_DTMF_S, // * key: 1209Hz, 941Hz
+ TONE_DTMF_P, // # key: 1477Hz, 941Hz
+ TONE_DTMF_A, // A key: 1633Hz, 697Hz
+ TONE_DTMF_B, // B key: 1633Hz, 770Hz
+ TONE_DTMF_C, // C key: 1633Hz, 852Hz
+ TONE_DTMF_D, // D key: 1633Hz, 941Hz
+ // Call supervisory tones: 3GPP TS 22.001 (CEPT)
+ TONE_SUP_DIAL, // Dial tone: CEPT: 425Hz, continuous
+ FIRST_SUP_TONE = TONE_SUP_DIAL,
+ TONE_SUP_BUSY, // Busy tone, CEPT: 425Hz, 500ms ON, 500ms OFF...
+ TONE_SUP_CONGESTION, // Congestion tone CEPT, JAPAN: 425Hz, 200ms ON, 200ms OFF...
+ TONE_SUP_RADIO_ACK, // Radio path acknowlegment, CEPT, ANSI: 425Hz, 200ms ON
+ TONE_SUP_RADIO_NOTAVAIL, // Radio path not available: 425Hz, 200ms ON, 200 OFF 3 bursts
+ TONE_SUP_ERROR, // Error/Special info: 950Hz+1400Hz+1800Hz, 330ms ON, 1s OFF...
+ TONE_SUP_CALL_WAITING, // Call Waiting CEPT,JAPAN: 425Hz, 200ms ON, 600ms OFF, 200ms ON, 3s OFF...
+ TONE_SUP_RINGTONE, // Ring Tone CEPT, JAPAN: 425Hz, 1s ON, 4s OFF...
+ LAST_SUP_TONE = TONE_SUP_RINGTONE,
+ // Proprietary tones: 3GPP TS 31.111
+ TONE_PROP_BEEP, // General beep: 400Hz+1200Hz, 35ms ON
+ TONE_PROP_ACK, // Positive Acknowlgement: 1200Hz, 100ms ON, 100ms OFF 2 bursts
+ TONE_PROP_NACK, // Negative Acknowlgement: 300Hz+400Hz+500Hz, 400ms ON
+ TONE_PROP_PROMPT, // Prompt tone: 400Hz+1200Hz, 200ms ON
+ TONE_PROP_BEEP2, // General double beep: 400Hz+1200Hz, 35ms ON, 200ms OFF, 35ms on
+ // Additional call supervisory tones: specified by IS-95 only
+ TONE_SUP_INTERCEPT, // Intercept tone: alternating 440 Hz and 620 Hz tones, each on for 250 ms.
+ TONE_SUP_INTERCEPT_ABBREV, // Abbreviated intercept: intercept tone limited to 4 seconds
+ TONE_SUP_CONGESTION_ABBREV, // Abbreviated congestion: congestion tone limited to 4 seconds
+ TONE_SUP_CONFIRM, // Confirm tone: a 350 Hz tone added to a 440 Hz tone repeated 3 times in a 100 ms on, 100 ms off cycle.
+ TONE_SUP_PIP, // Pip tone: four bursts of 480 Hz tone (0.1 s on, 0.1 s off).
+
+ // CDMA Tones
+ TONE_CDMA_DIAL_TONE_LITE,
+ TONE_CDMA_NETWORK_USA_RINGBACK,
+ TONE_CDMA_INTERCEPT,
+ TONE_CDMA_ABBR_INTERCEPT,
+ TONE_CDMA_REORDER,
+ TONE_CDMA_ABBR_REORDER,
+ TONE_CDMA_NETWORK_BUSY,
+ TONE_CDMA_CONFIRM,
+ TONE_CDMA_ANSWER,
+ TONE_CDMA_NETWORK_CALLWAITING,
+ TONE_CDMA_PIP,
+
+ // ISDN
+ TONE_CDMA_CALL_SIGNAL_ISDN_NORMAL, // ISDN Alert Normal
+ TONE_CDMA_CALL_SIGNAL_ISDN_INTERGROUP, // ISDN Intergroup
+ TONE_CDMA_CALL_SIGNAL_ISDN_SP_PRI, // ISDN SP PRI
+ TONE_CDMA_CALL_SIGNAL_ISDN_PAT3, // ISDN Alert PAT3
+ TONE_CDMA_CALL_SIGNAL_ISDN_PING_RING, // ISDN Alert PING RING
+ TONE_CDMA_CALL_SIGNAL_ISDN_PAT5, // ISDN Alert PAT5
+ TONE_CDMA_CALL_SIGNAL_ISDN_PAT6, // ISDN Alert PAT6
+ TONE_CDMA_CALL_SIGNAL_ISDN_PAT7, // ISDN Alert PAT7
+ // ISDN end
+
+ // IS54
+ TONE_CDMA_HIGH_L, // IS54 High Pitch Long
+ TONE_CDMA_MED_L, // IS54 Med Pitch Long
+ TONE_CDMA_LOW_L, // IS54 Low Pitch Long
+ TONE_CDMA_HIGH_SS, // IS54 High Pitch Short Short
+ TONE_CDMA_MED_SS, // IS54 Medium Pitch Short Short
+ TONE_CDMA_LOW_SS, // IS54 Low Pitch Short Short
+ TONE_CDMA_HIGH_SSL, // IS54 High Pitch Short Short Long
+ TONE_CDMA_MED_SSL, // IS54 Medium Pitch Short Short Long
+ TONE_CDMA_LOW_SSL, // IS54 Low Pitch Short Short Long
+ TONE_CDMA_HIGH_SS_2, // IS54 High Pitch Short Short 2
+ TONE_CDMA_MED_SS_2, // IS54 Med Pitch Short Short 2
+ TONE_CDMA_LOW_SS_2, // IS54 Low Pitch Short Short 2
+ TONE_CDMA_HIGH_SLS, // IS54 High Pitch Short Long Short
+ TONE_CDMA_MED_SLS, // IS54 Med Pitch Short Long Short
+ TONE_CDMA_LOW_SLS, // IS54 Low Pitch Short Long Short
+ TONE_CDMA_HIGH_S_X4, // IS54 High Pitch Short Short Short Short
+ TONE_CDMA_MED_S_X4, // IS54 Med Pitch Short Short Short Short
+ TONE_CDMA_LOW_S_X4, // IS54 Low Pitch Short Short Short Short
+ TONE_CDMA_HIGH_PBX_L, // PBX High Pitch Long
+ TONE_CDMA_MED_PBX_L, // PBX Med Pitch Long
+ TONE_CDMA_LOW_PBX_L, // PBX Low Pitch Long
+ TONE_CDMA_HIGH_PBX_SS, // PBX High Short Short
+ TONE_CDMA_MED_PBX_SS, // PBX Med Short Short
+ TONE_CDMA_LOW_PBX_SS, // PBX Low Short Short
+ TONE_CDMA_HIGH_PBX_SSL, // PBX High Short Short Long
+ TONE_CDMA_MED_PBX_SSL, // PBX Med Short Short Long
+ TONE_CDMA_LOW_PBX_SSL, // PBX Low Short Short Long
+ TONE_CDMA_HIGH_PBX_SLS, // PBX High SLS
+ TONE_CDMA_MED_PBX_SLS, // PBX Med SLS
+ TONE_CDMA_LOW_PBX_SLS, // PBX Low SLS
+ TONE_CDMA_HIGH_PBX_S_X4, // PBX High SSSS
+ TONE_CDMA_MED_PBX_S_X4, // PBX Med SSSS
+ TONE_CDMA_LOW_PBX_S_X4, // PBX LOW SSSS
+ //IS54 end
+ // proprietary
+ TONE_CDMA_ALERT_NETWORK_LITE,
+ TONE_CDMA_ALERT_AUTOREDIAL_LITE,
+ TONE_CDMA_ONE_MIN_BEEP,
+ TONE_CDMA_KEYPAD_VOLUME_KEY_LITE,
+ TONE_CDMA_PRESSHOLDKEY_LITE,
+ TONE_CDMA_ALERT_INCALL_LITE,
+ TONE_CDMA_EMERGENCY_RINGBACK,
+ TONE_CDMA_ALERT_CALL_GUARD,
+ TONE_CDMA_SOFT_ERROR_LITE,
+ TONE_CDMA_CALLDROP_LITE,
+ // proprietary end
+ TONE_CDMA_NETWORK_BUSY_ONE_SHOT,
+ TONE_CDMA_ABBR_ALERT,
+ TONE_CDMA_SIGNAL_OFF,
+ //CDMA end
+ NUM_TONES,
+ NUM_SUP_TONES = LAST_SUP_TONE-FIRST_SUP_TONE+1
+ };
+
+ ToneGenerator(audio_stream_type_t streamType, float volume, bool threadCanCallJava = false);
+ ~ToneGenerator();
+
+ bool startTone(tone_type toneType, int durationMs = -1);
+ void stopTone();
+
+ bool isInited() { return (mState == TONE_IDLE)?false:true;}
+
+ // returns the audio session this ToneGenerator belongs to or 0 if an error occured.
+ int getSessionId() { return (mpAudioTrack == 0) ? 0 : mpAudioTrack->getSessionId(); }
+
+private:
+
+ enum tone_state {
+ TONE_IDLE, // ToneGenerator is being initialized or initialization failed
+ TONE_INIT, // ToneGenerator has been successfully initialized and is not playing
+ TONE_STARTING, // ToneGenerator is starting playing
+ TONE_PLAYING, // ToneGenerator is playing
+ TONE_STOPPING, // ToneGenerator is stoping
+ TONE_STOPPED, // ToneGenerator is stopped: the AudioTrack will be stopped
+ TONE_RESTARTING // A start request was received in active state (playing or stopping)
+ };
+
+
+ // Region specific tones.
+ // These supervisory tones are different depending on the region (USA/CANADA, JAPAN, rest of the world).
+ // When a tone in the range [FIRST_SUP_TONE, LAST_SUP_TONE] is requested, the region is determined
+ // from system property gsm.operator.iso-country and the proper tone descriptor is selected with the
+ // help of sToneMappingTable[]
+ enum regional_tone_type {
+ // ANSI supervisory tones
+ TONE_ANSI_DIAL = NUM_TONES, // Dial tone: a continuous 350 Hz + 440 Hz tone.
+ TONE_ANSI_BUSY, // Busy tone on: a 480 Hz + 620 Hz tone repeated in a 500 ms on, 500 ms off cycle.
+ TONE_ANSI_CONGESTION, // Network congestion (reorder) tone on: a 480 Hz + 620 Hz tone repeated in a 250 ms on, 250 ms off cycle.
+ TONE_ANSI_CALL_WAITING, // Call waiting tone on: 440 Hz, on for 300 ms, 9,7 s off followed by
+ // (440 Hz, on for 100 ms off for 100 ms, on for 100 ms, 9,7s off and repeated as necessary).
+ TONE_ANSI_RINGTONE, // Ring Tone: a 440 Hz + 480 Hz tone repeated in a 2 s on, 4 s off pattern.
+ // JAPAN Supervisory tones
+ TONE_JAPAN_DIAL, // Dial tone: 400Hz, continuous
+ TONE_JAPAN_BUSY, // Busy tone: 400Hz, 500ms ON, 500ms OFF...
+ TONE_JAPAN_RADIO_ACK, // Radio path acknowlegment: 400Hz, 1s ON, 2s OFF...
+ // GB Supervisory tones
+ TONE_GB_RINGTONE, // Ring Tone: A 400Hz + 450Hz tone repeated in a 0.4s on, 0.2s off, 0.4s on, 2.0s off pattern.
+ // AUSTRALIA Supervisory tones
+ TONE_AUSTRALIA_RINGTONE, // Ring tone: A 400Hz + 450Hz tone repeated in a 0.4s on, 0.2s off, 0.4s on, 2.0s off pattern.
+ TONE_AUSTRALIA_BUSY, // Busy tone: 425 Hz repeated in a 0.375s on, 0.375s off pattern.
+ TONE_AUSTRALIA_CALL_WAITING,// Call waiting tone: 425Hz tone repeated in a 0.2s on, 0.2s off, 0.2s on, 4.4s off pattern.
+ TONE_AUSTRALIA_CONGESTION, // Congestion tone: 425Hz tone repeated in a 0.375s on, 0.375s off pattern
+ NUM_ALTERNATE_TONES
+ };
+
+ enum region {
+ ANSI,
+ JAPAN,
+ GB,
+ AUSTRALIA,
+ CEPT,
+ NUM_REGIONS
+ };
+
+ static const unsigned char sToneMappingTable[NUM_REGIONS-1][NUM_SUP_TONES];
+
+ static const unsigned int TONEGEN_MAX_WAVES = 3; // Maximun number of sine waves in a tone segment
+ static const unsigned int TONEGEN_MAX_SEGMENTS = 12; // Maximun number of segments in a tone descriptor
+ static const unsigned int TONEGEN_INF = 0xFFFFFFFF; // Represents infinite time duration
+ static const CONSTEXPR float TONEGEN_GAIN = 0.9; // Default gain passed to WaveGenerator().
+
+ // ToneDescriptor class contains all parameters needed to generate a tone:
+ // - The array waveFreq[]:
+ // 1 for static tone descriptors: contains the frequencies of all individual waves making the multi-tone.
+ // 2 for active tone descritors: contains the indexes of the WaveGenerator objects in mWaveGens
+ // The number of sine waves varies from 1 to TONEGEN_MAX_WAVES.
+ // The first null value indicates that no more waves are needed.
+ // - The array segments[] is used to generate the tone pulses. A segment is a period of time
+ // during which the tone is ON or OFF. Segments with even index (starting from 0)
+ // correspond to tone ON state and segments with odd index to OFF state.
+ // The data stored in segments[] is the duration of the corresponding period in ms.
+ // The first segment encountered with a 0 duration indicates that no more segment follows.
+ // - loopCnt - Number of times to repeat a sequence of seqments after playing this
+ // - loopIndx - The segment index to go back and play is loopcnt > 0
+ // - repeatCnt indicates the number of times the sequence described by segments[] array must be repeated.
+ // When the tone generator encounters the first 0 duration segment, it will compare repeatCnt to mCurCount.
+ // If mCurCount > repeatCnt, the tone is stopped automatically. Otherwise, tone sequence will be
+ // restarted from segment repeatSegment.
+ // - repeatSegment number of the first repeated segment when repeatCnt is not null
+
+ class ToneSegment {
+ public:
+ unsigned int duration;
+ unsigned short waveFreq[TONEGEN_MAX_WAVES+1];
+ unsigned short loopCnt;
+ unsigned short loopIndx;
+ };
+
+ class ToneDescriptor {
+ public:
+ ToneSegment segments[TONEGEN_MAX_SEGMENTS+1];
+ unsigned long repeatCnt;
+ unsigned long repeatSegment;
+ };
+
+ static const ToneDescriptor sToneDescriptors[];
+
+ bool mThreadCanCallJava;
+ unsigned int mTotalSmp; // Total number of audio samples played (gives current time)
+ unsigned int mNextSegSmp; // Position of next segment transition expressed in samples
+ // NOTE: because mTotalSmp, mNextSegSmp are stored on 32 bit, current design will operate properly
+ // only if tone duration is less than about 27 Hours(@44100Hz sampling rate). If this time is exceeded,
+ // no crash will occur but tone sequence will show a glitch.
+ unsigned int mMaxSmp; // Maximum number of audio samples played (maximun tone duration)
+ int mDurationMs; // Maximum tone duration in ms
+
+ unsigned short mCurSegment; // Current segment index in ToneDescriptor segments[]
+ unsigned short mCurCount; // Current sequence repeat count
+ volatile unsigned short mState; // ToneGenerator state (tone_state)
+ unsigned short mRegion;
+ const ToneDescriptor *mpToneDesc; // pointer to active tone descriptor
+ const ToneDescriptor *mpNewToneDesc; // pointer to next active tone descriptor
+
+ unsigned short mLoopCounter; // Current tone loopback count
+
+ uint32_t mSamplingRate; // AudioFlinger Sampling rate
+ sp<AudioTrack> mpAudioTrack; // Pointer to audio track used for playback
+ Mutex mLock; // Mutex to control concurent access to ToneGenerator object from audio callback and application API
+ Mutex mCbkCondLock; // Mutex associated to mWaitCbkCond
+ Condition mWaitCbkCond; // condition enabling interface to wait for audio callback completion after a change is requested
+ float mVolume; // Volume applied to audio track
+ audio_stream_type_t mStreamType; // Audio stream used for output
+ unsigned int mProcessSize; // Size of audio blocks generated at a time by audioCallback() (in PCM frames).
+ struct timespec mStartTime; // tone start time: needed to guaranty actual tone duration
+
+ bool initAudioTrack();
+ static void audioCallback(int event, void* user, void *info);
+ bool prepareWave();
+ unsigned int numWaves(unsigned int segmentIdx);
+ void clearWaveGens();
+ tone_type getToneForRegion(tone_type toneType);
+
+ // WaveGenerator generates a single sine wave
+ class WaveGenerator {
+ public:
+ enum gen_command {
+ WAVEGEN_START, // Start/restart wave from phase 0
+ WAVEGEN_CONT, // Continue wave from current phase
+ WAVEGEN_STOP // Stop wave on zero crossing
+ };
+
+ WaveGenerator(unsigned short samplingRate, unsigned short frequency,
+ float volume);
+ ~WaveGenerator();
+
+ void getSamples(short *outBuffer, unsigned int count,
+ unsigned int command);
+
+ private:
+ static const short GEN_AMP = 32000; // amplitude of generator
+ static const short S_Q14 = 14; // shift for Q14
+ static const short S_Q15 = 15; // shift for Q15
+
+ short mA1_Q14; // Q14 coefficient
+ // delay line of full amplitude generator
+ long mS1, mS2; // delay line S2 oldest
+ short mS2_0; // saved value for reinitialisation
+ short mAmplitude_Q15; // Q15 amplitude
+ };
+
+ KeyedVector<unsigned short, WaveGenerator *> mWaveGens; // list of active wave generators.
+};
+
+}
+; // namespace android
+
+#endif /*ANDROID_TONEGENERATOR_H_*/
diff --git a/media/libaudiohal/Android.mk b/media/libaudiohal/Android.mk
index 286c6b7..032b3e9 100644
--- a/media/libaudiohal/Android.mk
+++ b/media/libaudiohal/Android.mk
@@ -52,6 +52,10 @@
endif # USE_LEGACY_LOCAL_AUDIO_HAL
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+
LOCAL_MODULE := libaudiohal
LOCAL_CFLAGS := -Wall -Werror
diff --git a/media/libaudiohal/include/DeviceHalInterface.h b/media/libaudiohal/include/DeviceHalInterface.h
new file mode 100644
index 0000000..caf01be
--- /dev/null
+++ b/media/libaudiohal/include/DeviceHalInterface.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2016 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_HARDWARE_DEVICE_HAL_INTERFACE_H
+#define ANDROID_HARDWARE_DEVICE_HAL_INTERFACE_H
+
+#include <system/audio.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class StreamInHalInterface;
+class StreamOutHalInterface;
+
+class DeviceHalInterface : public RefBase
+{
+ public:
+ // Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
+ virtual status_t getSupportedDevices(uint32_t *devices) = 0;
+
+ // Check to see if the audio hardware interface has been initialized.
+ virtual status_t initCheck() = 0;
+
+ // Set the audio volume of a voice call. Range is between 0.0 and 1.0.
+ virtual status_t setVoiceVolume(float volume) = 0;
+
+ // Set the audio volume for all audio activities other than voice call.
+ virtual status_t setMasterVolume(float volume) = 0;
+
+ // Get the current master volume value for the HAL.
+ virtual status_t getMasterVolume(float *volume) = 0;
+
+ // Called when the audio mode changes.
+ virtual status_t setMode(audio_mode_t mode) = 0;
+
+ // Muting control.
+ virtual status_t setMicMute(bool state) = 0;
+ virtual status_t getMicMute(bool *state) = 0;
+ virtual status_t setMasterMute(bool state) = 0;
+ virtual status_t getMasterMute(bool *state) = 0;
+
+ // Set global audio parameters.
+ virtual status_t setParameters(const String8& kvPairs) = 0;
+
+ // Get global audio parameters.
+ virtual status_t getParameters(const String8& keys, String8 *values) = 0;
+
+ // Returns audio input buffer size according to parameters passed.
+ virtual status_t getInputBufferSize(const struct audio_config *config,
+ size_t *size) = 0;
+
+ // Creates and opens the audio hardware output stream. The stream is closed
+ // by releasing all references to the returned object.
+ virtual status_t openOutputStream(
+ audio_io_handle_t handle,
+ audio_devices_t devices,
+ audio_output_flags_t flags,
+ struct audio_config *config,
+ const char *address,
+ sp<StreamOutHalInterface> *outStream) = 0;
+
+ // Creates and opens the audio hardware input stream. The stream is closed
+ // by releasing all references to the returned object.
+ virtual status_t openInputStream(
+ audio_io_handle_t handle,
+ audio_devices_t devices,
+ struct audio_config *config,
+ audio_input_flags_t flags,
+ const char *address,
+ audio_source_t source,
+ sp<StreamInHalInterface> *inStream) = 0;
+
+ // Returns whether createAudioPatch and releaseAudioPatch operations are supported.
+ virtual status_t supportsAudioPatches(bool *supportsPatches) = 0;
+
+ // Creates an audio patch between several source and sink ports.
+ virtual status_t createAudioPatch(
+ unsigned int num_sources,
+ const struct audio_port_config *sources,
+ unsigned int num_sinks,
+ const struct audio_port_config *sinks,
+ audio_patch_handle_t *patch) = 0;
+
+ // Releases an audio patch.
+ virtual status_t releaseAudioPatch(audio_patch_handle_t patch) = 0;
+
+ // Fills the list of supported attributes for a given audio port.
+ virtual status_t getAudioPort(struct audio_port *port) = 0;
+
+ // Set audio port configuration.
+ virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
+
+ virtual status_t dump(int fd) = 0;
+
+ protected:
+ // Subclasses can not be constructed directly by clients.
+ DeviceHalInterface() {}
+
+ // The destructor automatically closes the device.
+ virtual ~DeviceHalInterface() {}
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DEVICE_HAL_INTERFACE_H
diff --git a/media/libaudiohal/include/DevicesFactoryHalInterface.h b/media/libaudiohal/include/DevicesFactoryHalInterface.h
new file mode 100644
index 0000000..14af384
--- /dev/null
+++ b/media/libaudiohal/include/DevicesFactoryHalInterface.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 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_HARDWARE_DEVICES_FACTORY_HAL_INTERFACE_H
+#define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_INTERFACE_H
+
+#include <media/audiohal/DeviceHalInterface.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+class DevicesFactoryHalInterface : public RefBase
+{
+ public:
+ // Opens a device with the specified name. To close the device, it is
+ // necessary to release references to the returned object.
+ virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device) = 0;
+
+ static sp<DevicesFactoryHalInterface> create();
+
+ protected:
+ // Subclasses can not be constructed directly by clients.
+ DevicesFactoryHalInterface() {}
+
+ virtual ~DevicesFactoryHalInterface() {}
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DEVICES_FACTORY_HAL_INTERFACE_H
diff --git a/media/libaudiohal/include/EffectBufferHalInterface.h b/media/libaudiohal/include/EffectBufferHalInterface.h
new file mode 100644
index 0000000..6fa7940
--- /dev/null
+++ b/media/libaudiohal/include/EffectBufferHalInterface.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 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_HARDWARE_EFFECT_BUFFER_HAL_INTERFACE_H
+#define ANDROID_HARDWARE_EFFECT_BUFFER_HAL_INTERFACE_H
+
+#include <system/audio_effect.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+// Abstraction for an audio buffer. It may be a "mirror" for
+// a buffer that the effect chain doesn't own, or a buffer owned by
+// the effect chain.
+class EffectBufferHalInterface : public RefBase
+{
+ public:
+ virtual audio_buffer_t* audioBuffer() = 0;
+ virtual void* externalData() const = 0;
+ // To be used when interacting with the code that doesn't know about
+ // "mirrored" buffers.
+ virtual void* ptr() {
+ return externalData() != nullptr ? externalData() : audioBuffer()->raw;
+ }
+
+ virtual void setExternalData(void* external) = 0;
+ virtual void setFrameCount(size_t frameCount) = 0;
+
+ virtual void update() = 0; // copies data from the external buffer, noop for allocated buffers
+ virtual void commit() = 0; // copies data to the external buffer, noop for allocated buffers
+ virtual void update(size_t size) = 0; // copies partial data from external buffer
+ virtual void commit(size_t size) = 0; // copies partial data to external buffer
+
+ static status_t allocate(size_t size, sp<EffectBufferHalInterface>* buffer);
+ static status_t mirror(void* external, size_t size, sp<EffectBufferHalInterface>* buffer);
+
+ protected:
+ // Subclasses can not be constructed directly by clients.
+ EffectBufferHalInterface() {}
+
+ virtual ~EffectBufferHalInterface() {}
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_EFFECT_BUFFER_HAL_INTERFACE_H
diff --git a/media/libaudiohal/include/EffectHalInterface.h b/media/libaudiohal/include/EffectHalInterface.h
new file mode 100644
index 0000000..7f9a6fd
--- /dev/null
+++ b/media/libaudiohal/include/EffectHalInterface.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2016 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_HARDWARE_EFFECT_HAL_INTERFACE_H
+#define ANDROID_HARDWARE_EFFECT_HAL_INTERFACE_H
+
+#include <media/audiohal/EffectBufferHalInterface.h>
+#include <system/audio_effect.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+class EffectHalInterface : public RefBase
+{
+ public:
+ // Set the input buffer.
+ virtual status_t setInBuffer(const sp<EffectBufferHalInterface>& buffer) = 0;
+
+ // Set the output buffer.
+ virtual status_t setOutBuffer(const sp<EffectBufferHalInterface>& buffer) = 0;
+
+ // Effect process function. Takes input samples as specified
+ // in input buffer descriptor and output processed samples as specified
+ // in output buffer descriptor.
+ virtual status_t process() = 0;
+
+ // Process reverse stream function. This function is used to pass
+ // a reference stream to the effect engine.
+ virtual status_t processReverse() = 0;
+
+ // Send a command and receive a response to/from effect engine.
+ virtual status_t command(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData,
+ uint32_t *replySize, void *pReplyData) = 0;
+
+ // Returns the effect descriptor.
+ virtual status_t getDescriptor(effect_descriptor_t *pDescriptor) = 0;
+
+ // Free resources on the remote side.
+ virtual status_t close() = 0;
+
+ protected:
+ // Subclasses can not be constructed directly by clients.
+ EffectHalInterface() {}
+
+ // The destructor automatically releases the effect.
+ virtual ~EffectHalInterface() {}
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_EFFECT_HAL_INTERFACE_H
diff --git a/media/libaudiohal/include/EffectsFactoryHalInterface.h b/media/libaudiohal/include/EffectsFactoryHalInterface.h
new file mode 100644
index 0000000..a616e86
--- /dev/null
+++ b/media/libaudiohal/include/EffectsFactoryHalInterface.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 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_HARDWARE_EFFECTS_FACTORY_HAL_INTERFACE_H
+#define ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_INTERFACE_H
+
+#include <media/audiohal/EffectHalInterface.h>
+#include <system/audio_effect.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+class EffectsFactoryHalInterface : public RefBase
+{
+ public:
+ // Returns the number of different effects in all loaded libraries.
+ virtual status_t queryNumberEffects(uint32_t *pNumEffects) = 0;
+
+ // Returns a descriptor of the next available effect.
+ virtual status_t getDescriptor(uint32_t index,
+ effect_descriptor_t *pDescriptor) = 0;
+
+ virtual status_t getDescriptor(const effect_uuid_t *pEffectUuid,
+ effect_descriptor_t *pDescriptor) = 0;
+
+ // Creates an effect engine of the specified type.
+ // To release the effect engine, it is necessary to release references
+ // to the returned effect object.
+ virtual status_t createEffect(const effect_uuid_t *pEffectUuid,
+ int32_t sessionId, int32_t ioId,
+ sp<EffectHalInterface> *effect) = 0;
+
+ virtual status_t dumpEffects(int fd) = 0;
+
+ static sp<EffectsFactoryHalInterface> create();
+
+ // Helper function to compare effect uuid to EFFECT_UUID_NULL.
+ static bool isNullUuid(const effect_uuid_t *pEffectUuid);
+
+ protected:
+ // Subclasses can not be constructed directly by clients.
+ EffectsFactoryHalInterface() {}
+
+ virtual ~EffectsFactoryHalInterface() {}
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_INTERFACE_H
diff --git a/media/libaudiohal/include/StreamHalInterface.h b/media/libaudiohal/include/StreamHalInterface.h
new file mode 100644
index 0000000..7419c34
--- /dev/null
+++ b/media/libaudiohal/include/StreamHalInterface.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2016 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_HARDWARE_STREAM_HAL_INTERFACE_H
+#define ANDROID_HARDWARE_STREAM_HAL_INTERFACE_H
+
+#include <media/audiohal/EffectHalInterface.h>
+#include <system/audio.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class StreamHalInterface : public virtual RefBase
+{
+ public:
+ // Return the sampling rate in Hz - eg. 44100.
+ virtual status_t getSampleRate(uint32_t *rate) = 0;
+
+ // Return size of input/output buffer in bytes for this stream - eg. 4800.
+ virtual status_t getBufferSize(size_t *size) = 0;
+
+ // Return the channel mask.
+ virtual status_t getChannelMask(audio_channel_mask_t *mask) = 0;
+
+ // Return the audio format - e.g. AUDIO_FORMAT_PCM_16_BIT.
+ virtual status_t getFormat(audio_format_t *format) = 0;
+
+ // Convenience method.
+ virtual status_t getAudioProperties(
+ uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format) = 0;
+
+ // Set audio stream parameters.
+ virtual status_t setParameters(const String8& kvPairs) = 0;
+
+ // Get audio stream parameters.
+ virtual status_t getParameters(const String8& keys, String8 *values) = 0;
+
+ // Return the frame size (number of bytes per sample) of a stream.
+ virtual status_t getFrameSize(size_t *size) = 0;
+
+ // Add or remove the effect on the stream.
+ virtual status_t addEffect(sp<EffectHalInterface> effect) = 0;
+ virtual status_t removeEffect(sp<EffectHalInterface> effect) = 0;
+
+ // Put the audio hardware input/output into standby mode.
+ virtual status_t standby() = 0;
+
+ virtual status_t dump(int fd) = 0;
+
+ // Start a stream operating in mmap mode.
+ virtual status_t start() = 0;
+
+ // Stop a stream operating in mmap mode.
+ virtual status_t stop() = 0;
+
+ // Retrieve information on the data buffer in mmap mode.
+ virtual status_t createMmapBuffer(int32_t minSizeFrames,
+ struct audio_mmap_buffer_info *info) = 0;
+
+ // Get current read/write position in the mmap buffer
+ virtual status_t getMmapPosition(struct audio_mmap_position *position) = 0;
+
+ // Set the priority of the thread that interacts with the HAL
+ // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
+ virtual status_t setHalThreadPriority(int priority) = 0;
+
+ protected:
+ // Subclasses can not be constructed directly by clients.
+ StreamHalInterface() {}
+
+ // The destructor automatically closes the stream.
+ virtual ~StreamHalInterface() {}
+};
+
+class StreamOutHalInterfaceCallback : public virtual RefBase {
+ public:
+ virtual void onWriteReady() {}
+ virtual void onDrainReady() {}
+ virtual void onError() {}
+
+ protected:
+ StreamOutHalInterfaceCallback() {}
+ virtual ~StreamOutHalInterfaceCallback() {}
+};
+
+class StreamOutHalInterface : public virtual StreamHalInterface {
+ public:
+ // Return the audio hardware driver estimated latency in milliseconds.
+ virtual status_t getLatency(uint32_t *latency) = 0;
+
+ // Use this method in situations where audio mixing is done in the hardware.
+ virtual status_t setVolume(float left, float right) = 0;
+
+ // Write audio buffer to driver.
+ virtual status_t write(const void *buffer, size_t bytes, size_t *written) = 0;
+
+ // Return the number of audio frames written by the audio dsp to DAC since
+ // the output has exited standby.
+ virtual status_t getRenderPosition(uint32_t *dspFrames) = 0;
+
+ // Get the local time at which the next write to the audio driver will be presented.
+ virtual status_t getNextWriteTimestamp(int64_t *timestamp) = 0;
+
+ // Set the callback for notifying completion of non-blocking write and drain.
+ // The callback must be owned by someone else. The output stream does not own it
+ // to avoid strong pointer loops.
+ virtual status_t setCallback(wp<StreamOutHalInterfaceCallback> callback) = 0;
+
+ // Returns whether pause and resume operations are supported.
+ virtual status_t supportsPauseAndResume(bool *supportsPause, bool *supportsResume) = 0;
+
+ // Notifies to the audio driver to resume playback following a pause.
+ virtual status_t pause() = 0;
+
+ // Notifies to the audio driver to resume playback following a pause.
+ virtual status_t resume() = 0;
+
+ // Returns whether drain operation is supported.
+ virtual status_t supportsDrain(bool *supportsDrain) = 0;
+
+ // Requests notification when data buffered by the driver/hardware has been played.
+ virtual status_t drain(bool earlyNotify) = 0;
+
+ // Notifies to the audio driver to flush the queued data.
+ virtual status_t flush() = 0;
+
+ // Return a recent count of the number of audio frames presented to an external observer.
+ virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp) = 0;
+
+ protected:
+ virtual ~StreamOutHalInterface() {}
+};
+
+class StreamInHalInterface : public virtual StreamHalInterface {
+ public:
+ // Set the input gain for the audio driver.
+ virtual status_t setGain(float gain) = 0;
+
+ // Read audio buffer in from driver.
+ virtual status_t read(void *buffer, size_t bytes, size_t *read) = 0;
+
+ // Return the amount of input frames lost in the audio driver.
+ virtual status_t getInputFramesLost(uint32_t *framesLost) = 0;
+
+ // Return a recent count of the number of audio frames received and
+ // the clock time associated with that frame count.
+ virtual status_t getCapturePosition(int64_t *frames, int64_t *time) = 0;
+
+ protected:
+ virtual ~StreamInHalInterface() {}
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_STREAM_HAL_INTERFACE_H
diff --git a/media/libaudiohal/include/hidl/HalDeathHandler.h b/media/libaudiohal/include/hidl/HalDeathHandler.h
new file mode 100644
index 0000000..c9b7084
--- /dev/null
+++ b/media/libaudiohal/include/hidl/HalDeathHandler.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 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_HARDWARE_HIDL_HAL_DEATH_HANDLER_H
+#define ANDROID_HARDWARE_HIDL_HAL_DEATH_HANDLER_H
+
+#include <functional>
+#include <mutex>
+#include <unordered_map>
+
+#include <hidl/HidlSupport.h>
+#include <utils/Singleton.h>
+
+using android::hardware::hidl_death_recipient;
+using android::hidl::base::V1_0::IBase;
+
+namespace android {
+
+class HalDeathHandler : public hidl_death_recipient, private Singleton<HalDeathHandler> {
+ public:
+ typedef std::function<void()> AtExitHandler;
+
+ // Note that the exit handler gets called using a thread from
+ // RPC threadpool, thus it needs to be thread-safe.
+ void registerAtExitHandler(void* cookie, AtExitHandler handler);
+ void unregisterAtExitHandler(void* cookie);
+
+ // hidl_death_recipient
+ virtual void serviceDied(uint64_t cookie, const wp<IBase>& who);
+
+ // Used both for (un)registering handlers, and for passing to
+ // '(un)linkToDeath'.
+ static sp<HalDeathHandler> getInstance();
+
+ private:
+ friend class Singleton<HalDeathHandler>;
+ typedef std::unordered_map<void*, AtExitHandler> Handlers;
+
+ HalDeathHandler();
+ virtual ~HalDeathHandler();
+
+ sp<HalDeathHandler> mSelf; // Allows the singleton instance to live forever.
+ std::mutex mHandlersLock;
+ Handlers mHandlers;
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_HIDL_HAL_DEATH_HANDLER_H
diff --git a/media/libaudioprocessing/Android.mk b/media/libaudioprocessing/Android.mk
index b7ea99e..c850984 100644
--- a/media/libaudioprocessing/Android.mk
+++ b/media/libaudioprocessing/Android.mk
@@ -14,6 +14,9 @@
LOCAL_C_INCLUDES := \
$(TOP) \
$(call include-path-for, audio-utils) \
+ $(LOCAL_PATH)/include \
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_SHARED_LIBRARIES := \
libaudiohal \
diff --git a/media/libaudioprocessing/include/AudioResampler.h b/media/libaudioprocessing/include/AudioResampler.h
new file mode 100644
index 0000000..c4627e8
--- /dev/null
+++ b/media/libaudioprocessing/include/AudioResampler.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2007 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_AUDIO_RESAMPLER_H
+#define ANDROID_AUDIO_RESAMPLER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/compiler.h>
+#include <utils/Compat.h>
+
+#include <media/AudioBufferProvider.h>
+#include <system/audio.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class ANDROID_API AudioResampler {
+public:
+ // Determines quality of SRC.
+ // LOW_QUALITY: linear interpolator (1st order)
+ // MED_QUALITY: cubic interpolator (3rd order)
+ // HIGH_QUALITY: fixed multi-tap FIR (e.g. 48KHz->44.1KHz)
+ // NOTE: high quality SRC will only be supported for
+ // certain fixed rate conversions. Sample rate cannot be
+ // changed dynamically.
+ enum src_quality {
+ DEFAULT_QUALITY=0,
+ LOW_QUALITY=1,
+ MED_QUALITY=2,
+ HIGH_QUALITY=3,
+ VERY_HIGH_QUALITY=4,
+ DYN_LOW_QUALITY=5,
+ DYN_MED_QUALITY=6,
+ DYN_HIGH_QUALITY=7,
+ };
+
+ static const CONSTEXPR float UNITY_GAIN_FLOAT = 1.0f;
+
+ static AudioResampler* create(audio_format_t format, int inChannelCount,
+ int32_t sampleRate, src_quality quality=DEFAULT_QUALITY);
+
+ virtual ~AudioResampler();
+
+ virtual void init() = 0;
+ virtual void setSampleRate(int32_t inSampleRate);
+ virtual void setVolume(float left, float right);
+
+ // Resample int16_t samples from provider and accumulate into 'out'.
+ // A mono provider delivers a sequence of samples.
+ // A stereo provider delivers a sequence of interleaved pairs of samples.
+ //
+ // In either case, 'out' holds interleaved pairs of fixed-point Q4.27.
+ // That is, for a mono provider, there is an implicit up-channeling.
+ // Since this method accumulates, the caller is responsible for clearing 'out' initially.
+ //
+ // For a float resampler, 'out' holds interleaved pairs of float samples.
+ //
+ // Multichannel interleaved frames for n > 2 is supported for quality DYN_LOW_QUALITY,
+ // DYN_MED_QUALITY, and DYN_HIGH_QUALITY.
+ //
+ // Returns the number of frames resampled into the out buffer.
+ virtual size_t resample(int32_t* out, size_t outFrameCount,
+ AudioBufferProvider* provider) = 0;
+
+ virtual void reset();
+ virtual size_t getUnreleasedFrames() const { return mInputIndex; }
+
+ // called from destructor, so must not be virtual
+ src_quality getQuality() const { return mQuality; }
+
+protected:
+ // number of bits for phase fraction - 30 bits allows nearly 2x downsampling
+ static const int kNumPhaseBits = 30;
+
+ // phase mask for fraction
+ static const uint32_t kPhaseMask = (1LU<<kNumPhaseBits)-1;
+
+ // multiplier to calculate fixed point phase increment
+ static const double kPhaseMultiplier;
+
+ AudioResampler(int inChannelCount, int32_t sampleRate, src_quality quality);
+
+ // prevent copying
+ AudioResampler(const AudioResampler&);
+ AudioResampler& operator=(const AudioResampler&);
+
+ const int32_t mChannelCount;
+ const int32_t mSampleRate;
+ int32_t mInSampleRate;
+ AudioBufferProvider::Buffer mBuffer;
+ union {
+ int16_t mVolume[2];
+ uint32_t mVolumeRL;
+ };
+ int16_t mTargetVolume[2];
+ size_t mInputIndex;
+ int32_t mPhaseIncrement;
+ uint32_t mPhaseFraction;
+
+ // returns the inFrameCount required to generate outFrameCount frames.
+ //
+ // Placed here to be a consistent for all resamplers.
+ //
+ // Right now, we use the upper bound without regards to the current state of the
+ // input buffer using integer arithmetic, as follows:
+ //
+ // (static_cast<uint64_t>(outFrameCount)*mInSampleRate + (mSampleRate - 1))/mSampleRate;
+ //
+ // The double precision equivalent (float may not be precise enough):
+ // ceil(static_cast<double>(outFrameCount) * mInSampleRate / mSampleRate);
+ //
+ // this relies on the fact that the mPhaseIncrement is rounded down from
+ // #phases * mInSampleRate/mSampleRate and the fact that Sum(Floor(x)) <= Floor(Sum(x)).
+ // http://www.proofwiki.org/wiki/Sum_of_Floors_Not_Greater_Than_Floor_of_Sums
+ //
+ // (so long as double precision is computed accurately enough to be considered
+ // greater than or equal to the Floor(x) value in int32_t arithmetic; thus this
+ // will not necessarily hold for floats).
+ //
+ // TODO:
+ // Greater accuracy and a tight bound is obtained by:
+ // 1) subtract and adjust for the current state of the AudioBufferProvider buffer.
+ // 2) using the exact integer formula where (ignoring 64b casting)
+ // inFrameCount = (mPhaseIncrement * (outFrameCount - 1) + mPhaseFraction) / phaseWrapLimit;
+ // phaseWrapLimit is the wraparound (1 << kNumPhaseBits), if not specified explicitly.
+ //
+ inline size_t getInFrameCountRequired(size_t outFrameCount) {
+ return (static_cast<uint64_t>(outFrameCount)*mInSampleRate
+ + (mSampleRate - 1))/mSampleRate;
+ }
+
+ inline float clampFloatVol(float volume) {
+ if (volume > UNITY_GAIN_FLOAT) {
+ return UNITY_GAIN_FLOAT;
+ } else if (volume >= 0.) {
+ return volume;
+ }
+ return 0.; // NaN or negative volume maps to 0.
+ }
+
+private:
+ const src_quality mQuality;
+
+ // Return 'true' if the quality level is supported without explicit request
+ static bool qualityIsSupported(src_quality quality);
+
+ // For pthread_once()
+ static void init_routine();
+
+ // Return the estimated CPU load for specific resampler in MHz.
+ // The absolute number is irrelevant, it's the relative values that matter.
+ static uint32_t qualityMHz(src_quality quality);
+};
+
+// ----------------------------------------------------------------------------
+} // namespace android
+
+#endif // ANDROID_AUDIO_RESAMPLER_H
diff --git a/media/libaudioprocessing/include/AudioResamplerPublic.h b/media/libaudioprocessing/include/AudioResamplerPublic.h
new file mode 100644
index 0000000..055f724
--- /dev/null
+++ b/media/libaudioprocessing/include/AudioResamplerPublic.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIO_RESAMPLER_PUBLIC_H
+#define ANDROID_AUDIO_RESAMPLER_PUBLIC_H
+
+#include <stdint.h>
+#include <math.h>
+
+namespace android {
+
+// AUDIO_RESAMPLER_DOWN_RATIO_MAX is the maximum ratio between the original
+// audio sample rate and the target rate when downsampling,
+// as permitted in the audio framework, e.g. AudioTrack and AudioFlinger.
+// In practice, it is not recommended to downsample more than 6:1
+// for best audio quality, even though the audio framework permits a larger
+// downsampling ratio.
+// TODO: replace with an API
+#define AUDIO_RESAMPLER_DOWN_RATIO_MAX 256
+
+// AUDIO_RESAMPLER_UP_RATIO_MAX is the maximum suggested ratio between the original
+// audio sample rate and the target rate when upsampling. It is loosely enforced by
+// the system. One issue with large upsampling ratios is the approximation by
+// an int32_t of the phase increments, making the resulting sample rate inexact.
+#define AUDIO_RESAMPLER_UP_RATIO_MAX 65536
+
+// AUDIO_TIMESTRETCH_SPEED_MIN and AUDIO_TIMESTRETCH_SPEED_MAX define the min and max time stretch
+// speeds supported by the system. These are enforced by the system and values outside this range
+// will result in a runtime error.
+// Depending on the AudioPlaybackRate::mStretchMode, the effective limits might be narrower than
+// the ones specified here
+// AUDIO_TIMESTRETCH_SPEED_MIN_DELTA is the minimum absolute speed difference that might trigger a
+// parameter update
+#define AUDIO_TIMESTRETCH_SPEED_MIN 0.01f
+#define AUDIO_TIMESTRETCH_SPEED_MAX 20.0f
+#define AUDIO_TIMESTRETCH_SPEED_NORMAL 1.0f
+#define AUDIO_TIMESTRETCH_SPEED_MIN_DELTA 0.0001f
+
+// AUDIO_TIMESTRETCH_PITCH_MIN and AUDIO_TIMESTRETCH_PITCH_MAX define the min and max time stretch
+// pitch shifting supported by the system. These are not enforced by the system and values
+// outside this range might result in a pitch different than the one requested.
+// Depending on the AudioPlaybackRate::mStretchMode, the effective limits might be narrower than
+// the ones specified here.
+// AUDIO_TIMESTRETCH_PITCH_MIN_DELTA is the minimum absolute pitch difference that might trigger a
+// parameter update
+#define AUDIO_TIMESTRETCH_PITCH_MIN 0.25f
+#define AUDIO_TIMESTRETCH_PITCH_MAX 4.0f
+#define AUDIO_TIMESTRETCH_PITCH_NORMAL 1.0f
+#define AUDIO_TIMESTRETCH_PITCH_MIN_DELTA 0.0001f
+
+
+//Determines the current algorithm used for stretching
+enum AudioTimestretchStretchMode : int32_t {
+ AUDIO_TIMESTRETCH_STRETCH_DEFAULT = 0,
+ AUDIO_TIMESTRETCH_STRETCH_SPEECH = 1,
+ //TODO: add more stretch modes/algorithms
+};
+
+//Limits for AUDIO_TIMESTRETCH_STRETCH_SPEECH mode
+#define TIMESTRETCH_SONIC_SPEED_MIN 0.1f
+#define TIMESTRETCH_SONIC_SPEED_MAX 6.0f
+
+//Determines behavior of Timestretch if current algorithm can't perform
+//with current parameters.
+// FALLBACK_CUT_REPEAT: (internal only) for speed <1.0 will truncate frames
+// for speed > 1.0 will repeat frames
+// FALLBACK_MUTE: will set all processed frames to zero
+// FALLBACK_FAIL: will stop program execution and log a fatal error
+enum AudioTimestretchFallbackMode : int32_t {
+ AUDIO_TIMESTRETCH_FALLBACK_CUT_REPEAT = -1,
+ AUDIO_TIMESTRETCH_FALLBACK_DEFAULT = 0,
+ AUDIO_TIMESTRETCH_FALLBACK_MUTE = 1,
+ AUDIO_TIMESTRETCH_FALLBACK_FAIL = 2,
+};
+
+struct AudioPlaybackRate {
+ float mSpeed;
+ float mPitch;
+ enum AudioTimestretchStretchMode mStretchMode;
+ enum AudioTimestretchFallbackMode mFallbackMode;
+};
+
+static const AudioPlaybackRate AUDIO_PLAYBACK_RATE_DEFAULT = {
+ AUDIO_TIMESTRETCH_SPEED_NORMAL,
+ AUDIO_TIMESTRETCH_PITCH_NORMAL,
+ AUDIO_TIMESTRETCH_STRETCH_DEFAULT,
+ AUDIO_TIMESTRETCH_FALLBACK_DEFAULT
+};
+
+static inline bool isAudioPlaybackRateEqual(const AudioPlaybackRate &pr1,
+ const AudioPlaybackRate &pr2) {
+ return fabs(pr1.mSpeed - pr2.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA &&
+ fabs(pr1.mPitch - pr2.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA &&
+ pr2.mStretchMode == pr2.mStretchMode &&
+ pr2.mFallbackMode == pr2.mFallbackMode;
+}
+
+static inline bool isAudioPlaybackRateValid(const AudioPlaybackRate &playbackRate) {
+ if (playbackRate.mFallbackMode == AUDIO_TIMESTRETCH_FALLBACK_FAIL &&
+ (playbackRate.mStretchMode == AUDIO_TIMESTRETCH_STRETCH_SPEECH ||
+ playbackRate.mStretchMode == AUDIO_TIMESTRETCH_STRETCH_DEFAULT)) {
+ //test sonic specific constraints
+ return playbackRate.mSpeed >= TIMESTRETCH_SONIC_SPEED_MIN &&
+ playbackRate.mSpeed <= TIMESTRETCH_SONIC_SPEED_MAX &&
+ playbackRate.mPitch >= AUDIO_TIMESTRETCH_PITCH_MIN &&
+ playbackRate.mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX;
+ } else {
+ return playbackRate.mSpeed >= AUDIO_TIMESTRETCH_SPEED_MIN &&
+ playbackRate.mSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX &&
+ playbackRate.mPitch >= AUDIO_TIMESTRETCH_PITCH_MIN &&
+ playbackRate.mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX;
+ }
+}
+
+// TODO: Consider putting these inlines into a class scope
+
+// Returns the source frames needed to resample to destination frames. This is not a precise
+// value and depends on the resampler (and possibly how it handles rounding internally).
+// Nevertheless, this should be an upper bound on the requirements of the resampler.
+// If srcSampleRate and dstSampleRate are equal, then it returns destination frames, which
+// may not be true if the resampler is asynchronous.
+static inline size_t sourceFramesNeeded(
+ uint32_t srcSampleRate, size_t dstFramesRequired, uint32_t dstSampleRate) {
+ // +1 for rounding - always do this even if matched ratio (resampler may use phases not ratio)
+ // +1 for additional sample needed for interpolation
+ return srcSampleRate == dstSampleRate ? dstFramesRequired :
+ size_t((uint64_t)dstFramesRequired * srcSampleRate / dstSampleRate + 1 + 1);
+}
+
+// An upper bound for the number of destination frames possible from srcFrames
+// after sample rate conversion. This may be used for buffer sizing.
+static inline size_t destinationFramesPossible(size_t srcFrames, uint32_t srcSampleRate,
+ uint32_t dstSampleRate) {
+ if (srcSampleRate == dstSampleRate) {
+ return srcFrames;
+ }
+ uint64_t dstFrames = (uint64_t)srcFrames * dstSampleRate / srcSampleRate;
+ return dstFrames > 2 ? dstFrames - 2 : 0;
+}
+
+static inline size_t sourceFramesNeededWithTimestretch(
+ uint32_t srcSampleRate, size_t dstFramesRequired, uint32_t dstSampleRate,
+ float speed) {
+ // required is the number of input frames the resampler needs
+ size_t required = sourceFramesNeeded(srcSampleRate, dstFramesRequired, dstSampleRate);
+ // to deliver this, the time stretcher requires:
+ return required * (double)speed + 1 + 1; // accounting for rounding dependencies
+}
+
+// Identifies sample rates that we associate with music
+// and thus eligible for better resampling and fast capture.
+// This is somewhat less than 44100 to allow for pitch correction
+// involving resampling as well as asynchronous resampling.
+#define AUDIO_PROCESSING_MUSIC_RATE 40000
+
+static inline bool isMusicRate(uint32_t sampleRate) {
+ return sampleRate >= AUDIO_PROCESSING_MUSIC_RATE;
+}
+
+} // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_AUDIO_RESAMPLER_PUBLIC_H
diff --git a/media/libcpustats/include/cpustats/CentralTendencyStatistics.h b/media/libcpustats/include/cpustats/CentralTendencyStatistics.h
new file mode 100644
index 0000000..21b6981
--- /dev/null
+++ b/media/libcpustats/include/cpustats/CentralTendencyStatistics.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 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 _CENTRAL_TENDENCY_STATISTICS_H
+#define _CENTRAL_TENDENCY_STATISTICS_H
+
+#include <math.h>
+
+// Not multithread safe
+class CentralTendencyStatistics {
+
+public:
+
+ CentralTendencyStatistics() :
+ mMean(NAN), mMedian(NAN), mMinimum(INFINITY), mMaximum(-INFINITY), mN(0), mM2(0),
+ mVariance(NAN), mVarianceKnownForN(0), mStddev(NAN), mStddevKnownForN(0) { }
+
+ ~CentralTendencyStatistics() { }
+
+ // add x to the set of samples
+ void sample(double x);
+
+ // return the arithmetic mean of all samples so far
+ double mean() const { return mMean; }
+
+ // return the minimum of all samples so far
+ double minimum() const { return mMinimum; }
+
+ // return the maximum of all samples so far
+ double maximum() const { return mMaximum; }
+
+ // return the variance of all samples so far
+ double variance() const;
+
+ // return the standard deviation of all samples so far
+ double stddev() const;
+
+ // return the number of samples added so far
+ unsigned n() const { return mN; }
+
+ // reset the set of samples to be empty
+ void reset();
+
+private:
+ double mMean;
+ double mMedian;
+ double mMinimum;
+ double mMaximum;
+ unsigned mN; // number of samples so far
+ double mM2;
+
+ // cached variance, and n at time of caching
+ mutable double mVariance;
+ mutable unsigned mVarianceKnownForN;
+
+ // cached standard deviation, and n at time of caching
+ mutable double mStddev;
+ mutable unsigned mStddevKnownForN;
+
+};
+
+#endif // _CENTRAL_TENDENCY_STATISTICS_H
diff --git a/media/libcpustats/include/cpustats/README.txt b/media/libcpustats/include/cpustats/README.txt
new file mode 100644
index 0000000..14439f0
--- /dev/null
+++ b/media/libcpustats/include/cpustats/README.txt
@@ -0,0 +1,6 @@
+This is a static library of CPU usage statistics, originally written
+for audio but most are not actually specific to audio.
+
+Requirements to be here:
+ * should be related to CPU usage statistics
+ * should be portable to host; avoid Android OS dependencies without a conditional
diff --git a/media/libcpustats/include/cpustats/ThreadCpuUsage.h b/media/libcpustats/include/cpustats/ThreadCpuUsage.h
new file mode 100644
index 0000000..9756844
--- /dev/null
+++ b/media/libcpustats/include/cpustats/ThreadCpuUsage.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2011 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 _THREAD_CPU_USAGE_H
+#define _THREAD_CPU_USAGE_H
+
+#include <fcntl.h>
+#include <pthread.h>
+
+namespace android {
+
+// Track CPU usage for the current thread.
+// Units are in per-thread CPU ns, as reported by
+// clock_gettime(CLOCK_THREAD_CPUTIME_ID). Simple usage: for cyclic
+// threads where you want to measure the execution time of the whole
+// cycle, just call sampleAndEnable() at the start of each cycle.
+// For acyclic threads, or for cyclic threads where you want to measure/track
+// only part of each cycle, call enable(), disable(), and/or setEnabled()
+// to demarcate the region(s) of interest, and then call sample() periodically.
+// This class is not thread-safe for concurrent calls from multiple threads;
+// the methods of this class may only be called by the current thread
+// which constructed the object.
+
+class ThreadCpuUsage
+{
+
+public:
+ ThreadCpuUsage() :
+ mIsEnabled(false),
+ mWasEverEnabled(false),
+ mAccumulator(0),
+ // mPreviousTs
+ // mMonotonicTs
+ mMonotonicKnown(false)
+ {
+ (void) pthread_once(&sOnceControl, &init);
+ for (int i = 0; i < sKernelMax; ++i) {
+ mCurrentkHz[i] = (uint32_t) ~0; // unknown
+ }
+ }
+
+ ~ThreadCpuUsage() { }
+
+ // Return whether currently tracking CPU usage by current thread
+ bool isEnabled() const { return mIsEnabled; }
+
+ // Enable tracking of CPU usage by current thread;
+ // any CPU used from this point forward will be tracked.
+ // Returns the previous enabled status.
+ bool enable() { return setEnabled(true); }
+
+ // Disable tracking of CPU usage by current thread;
+ // any CPU used from this point forward will be ignored.
+ // Returns the previous enabled status.
+ bool disable() { return setEnabled(false); }
+
+ // Set the enabled status and return the previous enabled status.
+ // This method is intended to be used for safe nested enable/disabling.
+ bool setEnabled(bool isEnabled);
+
+ // Add a sample point, and also enable tracking if needed.
+ // If tracking has never been enabled, then this call enables tracking but
+ // does _not_ add a sample -- it is not possible to add a sample the
+ // first time because there is no previous point to subtract from.
+ // Otherwise, if tracking is enabled,
+ // then adds a sample for tracked CPU ns since the previous
+ // sample, or since the first call to sampleAndEnable(), enable(), or
+ // setEnabled(true). If there was a previous sample but tracking is
+ // now disabled, then adds a sample for the tracked CPU ns accumulated
+ // up until the most recent disable(), resets this accumulator, and then
+ // enables tracking. Calling this method rather than enable() followed
+ // by sample() avoids a race condition for the first sample.
+ // Returns true if the sample 'ns' is valid, or false if invalid.
+ // Note that 'ns' is an output parameter passed by reference.
+ // The caller does not need to initialize this variable.
+ // The units are CPU nanoseconds consumed by current thread.
+ bool sampleAndEnable(double& ns);
+
+ // Add a sample point, but do not
+ // change the tracking enabled status. If tracking has either never been
+ // enabled, or has never been enabled since the last sample, then log a warning
+ // and don't add sample. Otherwise, adds a sample for tracked CPU ns since
+ // the previous sample or since the first call to sampleAndEnable(),
+ // enable(), or setEnabled(true) if no previous sample.
+ // Returns true if the sample is valid, or false if invalid.
+ // Note that 'ns' is an output parameter passed by reference.
+ // The caller does not need to initialize this variable.
+ // The units are CPU nanoseconds consumed by current thread.
+ bool sample(double& ns);
+
+ // Return the elapsed delta wall clock ns since initial enable or reset,
+ // as reported by clock_gettime(CLOCK_MONOTONIC).
+ long long elapsed() const;
+
+ // Reset elapsed wall clock. Has no effect on tracking or accumulator.
+ void resetElapsed();
+
+ // Return current clock frequency for specified CPU, in kHz.
+ // You can get your CPU number using sched_getcpu(2). Note that, unless CPU affinity
+ // has been configured appropriately, the CPU number can change.
+ // Also note that, unless the CPU governor has been configured appropriately,
+ // the CPU frequency can change. And even if the CPU frequency is locked down
+ // to a particular value, that the frequency might still be adjusted
+ // to prevent thermal overload. Therefore you should poll for your thread's
+ // current CPU number and clock frequency periodically.
+ uint32_t getCpukHz(int cpuNum);
+
+private:
+ bool mIsEnabled; // whether tracking is currently enabled
+ bool mWasEverEnabled; // whether tracking was ever enabled
+ long long mAccumulator; // accumulated thread CPU time since last sample, in ns
+ struct timespec mPreviousTs; // most recent thread CPU time, valid only if mIsEnabled is true
+ struct timespec mMonotonicTs; // most recent monotonic time
+ bool mMonotonicKnown; // whether mMonotonicTs has been set
+
+ static const int MAX_CPU = 8;
+ static int sScalingFds[MAX_CPU];// file descriptor per CPU for reading scaling_cur_freq
+ uint32_t mCurrentkHz[MAX_CPU]; // current CPU frequency in kHz, not static to avoid a race
+ static pthread_once_t sOnceControl;
+ static int sKernelMax; // like MAX_CPU, but determined at runtime == cpu/kernel_max + 1
+ static void init(); // called once at first ThreadCpuUsage construction
+ static pthread_mutex_t sMutex; // protects sScalingFds[] after initialization
+};
+
+} // namespace android
+
+#endif // _THREAD_CPU_USAGE_H
diff --git a/media/libeffects/factory/Android.bp b/media/libeffects/factory/Android.bp
index 0d8b6eb..e0e0d13 100644
--- a/media/libeffects/factory/Android.bp
+++ b/media/libeffects/factory/Android.bp
@@ -10,4 +10,8 @@
],
include_dirs: ["system/media/audio_effects/include"],
+
+ local_include_dirs:["include"],
+
+ export_include_dirs: ["include"],
}
diff --git a/media/libeffects/factory/include/EffectsFactoryApi.h b/media/libeffects/factory/include/EffectsFactoryApi.h
new file mode 100644
index 0000000..64a3212
--- /dev/null
+++ b/media/libeffects/factory/include/EffectsFactoryApi.h
@@ -0,0 +1,181 @@
+/*
+ * 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_EFFECTSFACTORYAPI_H_
+#define ANDROID_EFFECTSFACTORYAPI_H_
+
+#include <errno.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <hardware/audio_effect.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 EffectQueryEffect()
+// 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
+// EffectQueryEffect() 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: EffectQueryEffect
+//
+// Description: Returns a descriptor of the next available effect.
+// See effect_descriptor_t for a details on effect descriptor.
+// This function together with EffectQueryNumberEffects() is used to enumerate all
+// effects present in all loaded libraries. The enumeration sequence is:
+// EffectQueryNumberEffects(&num_effects);
+// for (i = 0; i < num_effects; i++)
+// EffectQueryEffect(i,...);
+//
+// Input/Output:
+// pDescriptor: address where to return the effect descriptor.
+//
+// Output:
+// returned value: 0 successful operation.
+// -ENOENT no more effect available
+// -ENODEV factory failed to initialize
+// -EINVAL invalid pDescriptor
+// -ENOSYS effect list has changed since last execution of
+// EffectQueryNumberEffects()
+// *pDescriptor: updated with the effect descriptor.
+//
+////////////////////////////////////////////////////////////////////////////////
+int EffectQueryEffect(uint32_t index, 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.
+// sessionId: audio session to which this effect instance will be attached. All effects
+// created with the same session ID are connected in series and process the same signal
+// stream. Knowing that two effects are part of the same effect chain can help the
+// library implement some kind of optimizations.
+// ioId: identifies the output or input stream this effect is directed to at audio HAL.
+// For future use especially with tunneled HW accelerated effects
+//
+// Input/Output:
+// pHandle: address where to return the effect handle.
+//
+// Output:
+// returned value: 0 successful operation.
+// -ENODEV factory failed to initialize
+// -EINVAL invalid pEffectUuid or pHandle
+// -ENOENT no effect with this uuid found
+// *pHandle: updated with the effect handle.
+//
+////////////////////////////////////////////////////////////////////////////////
+int EffectCreate(const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId,
+ effect_handle_t *pHandle);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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:
+// handle: handle on the effect interface to be released.
+//
+// Output:
+// returned value: 0 successful operation.
+// -ENODEV factory failed to initialize
+// -EINVAL invalid interface handle
+//
+////////////////////////////////////////////////////////////////////////////////
+int EffectRelease(effect_handle_t 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(const 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(const effect_uuid_t *pEffectUuid);
+
+int EffectDumpEffects(int fd);
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+
+#endif /*ANDROID_EFFECTSFACTORYAPI_H_*/
diff --git a/media/libmedia/include/AVSyncSettings.h b/media/libmedia/include/AVSyncSettings.h
new file mode 100644
index 0000000..10e3bcc
--- /dev/null
+++ b/media/libmedia/include/AVSyncSettings.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2015 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_AV_SYNC_SETTINGS_H
+#define ANDROID_AV_SYNC_SETTINGS_H
+
+namespace android {
+
+enum AVSyncSource : unsigned {
+ // let the system decide the best sync source
+ AVSYNC_SOURCE_DEFAULT = 0,
+ // sync to the system clock
+ AVSYNC_SOURCE_SYSTEM_CLOCK = 1,
+ // sync to the audio track
+ AVSYNC_SOURCE_AUDIO = 2,
+ // sync to the display vsync
+ AVSYNC_SOURCE_VSYNC = 3,
+ AVSYNC_SOURCE_MAX,
+};
+
+enum AVSyncAudioAdjustMode : unsigned {
+ // let the system decide the best audio adjust mode
+ AVSYNC_AUDIO_ADJUST_MODE_DEFAULT = 0,
+ // adjust audio by time stretching
+ AVSYNC_AUDIO_ADJUST_MODE_STRETCH = 1,
+ // adjust audio by resampling
+ AVSYNC_AUDIO_ADJUST_MODE_RESAMPLE = 2,
+ AVSYNC_AUDIO_ADJUST_MODE_MAX,
+};
+
+// max tolerance when adjusting playback speed to desired playback speed
+#define AVSYNC_TOLERANCE_MAX 1.0f
+
+struct AVSyncSettings {
+ AVSyncSource mSource;
+ AVSyncAudioAdjustMode mAudioAdjustMode;
+ float mTolerance;
+ AVSyncSettings()
+ : mSource(AVSYNC_SOURCE_DEFAULT),
+ mAudioAdjustMode(AVSYNC_AUDIO_ADJUST_MODE_DEFAULT),
+ mTolerance(.044f) { }
+};
+
+} // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_AV_SYNC_SETTINGS_H
diff --git a/media/libmedia/include/BufferProviders.h b/media/libmedia/include/BufferProviders.h
new file mode 100644
index 0000000..9d026f6
--- /dev/null
+++ b/media/libmedia/include/BufferProviders.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2015 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_BUFFER_PROVIDERS_H
+#define ANDROID_BUFFER_PROVIDERS_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <media/AudioBufferProvider.h>
+#include <media/AudioResamplerPublic.h>
+#include <system/audio.h>
+#include <system/audio_effect.h>
+#include <utils/StrongPointer.h>
+
+// external forward declaration from external/sonic/sonic.h
+struct sonicStreamStruct;
+typedef struct sonicStreamStruct *sonicStream;
+
+namespace android {
+
+class EffectBufferHalInterface;
+class EffectHalInterface;
+class EffectsFactoryHalInterface;
+
+// ----------------------------------------------------------------------------
+
+class PassthruBufferProvider : public AudioBufferProvider {
+public:
+ PassthruBufferProvider() : mTrackBufferProvider(NULL) { }
+
+ virtual ~PassthruBufferProvider() { }
+
+ // call this to release the buffer to the upstream provider.
+ // treat it as an audio discontinuity for future samples.
+ virtual void reset() { }
+
+ // set the upstream buffer provider. Consider calling "reset" before this function.
+ virtual void setBufferProvider(AudioBufferProvider *p) {
+ mTrackBufferProvider = p;
+ }
+
+protected:
+ AudioBufferProvider *mTrackBufferProvider;
+};
+
+// Base AudioBufferProvider class used for DownMixerBufferProvider, RemixBufferProvider,
+// and ReformatBufferProvider.
+// It handles a private buffer for use in converting format or channel masks from the
+// input data to a form acceptable by the mixer.
+// TODO: Make a ResamplerBufferProvider when integers are entirely removed from the
+// processing pipeline.
+class CopyBufferProvider : public PassthruBufferProvider {
+public:
+ // Use a private buffer of bufferFrameCount frames (each frame is outputFrameSize bytes).
+ // If bufferFrameCount is 0, no private buffer is created and in-place modification of
+ // the upstream buffer provider's buffers is performed by copyFrames().
+ CopyBufferProvider(size_t inputFrameSize, size_t outputFrameSize,
+ size_t bufferFrameCount);
+ virtual ~CopyBufferProvider();
+
+ // Overrides AudioBufferProvider methods
+ virtual status_t getNextBuffer(Buffer *buffer);
+ virtual void releaseBuffer(Buffer *buffer);
+
+ // Overrides PassthruBufferProvider
+ virtual void reset();
+
+ // this function should be supplied by the derived class. It converts
+ // #frames in the *src pointer to the *dst pointer. It is public because
+ // some providers will allow this to work on arbitrary buffers outside
+ // of the internal buffers.
+ virtual void copyFrames(void *dst, const void *src, size_t frames) = 0;
+
+protected:
+ const size_t mInputFrameSize;
+ const size_t mOutputFrameSize;
+private:
+ AudioBufferProvider::Buffer mBuffer;
+ const size_t mLocalBufferFrameCount;
+ void *mLocalBufferData;
+ size_t mConsumed;
+};
+
+// DownmixerBufferProvider derives from CopyBufferProvider to provide
+// position dependent downmixing by an Audio Effect.
+class DownmixerBufferProvider : public CopyBufferProvider {
+public:
+ DownmixerBufferProvider(audio_channel_mask_t inputChannelMask,
+ audio_channel_mask_t outputChannelMask, audio_format_t format,
+ uint32_t sampleRate, int32_t sessionId, size_t bufferFrameCount);
+ virtual ~DownmixerBufferProvider();
+ //Overrides
+ virtual void copyFrames(void *dst, const void *src, size_t frames);
+
+ bool isValid() const { return mDownmixInterface.get() != NULL; }
+ static status_t init();
+ static bool isMultichannelCapable() { return sIsMultichannelCapable; }
+
+protected:
+ sp<EffectsFactoryHalInterface> mEffectsFactory;
+ sp<EffectHalInterface> mDownmixInterface;
+ size_t mInFrameSize;
+ size_t mOutFrameSize;
+ sp<EffectBufferHalInterface> mInBuffer;
+ sp<EffectBufferHalInterface> mOutBuffer;
+ effect_config_t mDownmixConfig;
+
+ // effect descriptor for the downmixer used by the mixer
+ static effect_descriptor_t sDwnmFxDesc;
+ // indicates whether a downmix effect has been found and is usable by this mixer
+ static bool sIsMultichannelCapable;
+ // FIXME: should we allow effects outside of the framework?
+ // We need to here. A special ioId that must be <= -2 so it does not map to a session.
+ static const int32_t SESSION_ID_INVALID_AND_IGNORED = -2;
+};
+
+// RemixBufferProvider derives from CopyBufferProvider to perform an
+// upmix or downmix to the proper channel count and mask.
+class RemixBufferProvider : public CopyBufferProvider {
+public:
+ RemixBufferProvider(audio_channel_mask_t inputChannelMask,
+ audio_channel_mask_t outputChannelMask, audio_format_t format,
+ size_t bufferFrameCount);
+ //Overrides
+ virtual void copyFrames(void *dst, const void *src, size_t frames);
+
+protected:
+ const audio_format_t mFormat;
+ const size_t mSampleSize;
+ const size_t mInputChannels;
+ const size_t mOutputChannels;
+ int8_t mIdxAry[sizeof(uint32_t) * 8]; // 32 bits => channel indices
+};
+
+// ReformatBufferProvider derives from CopyBufferProvider to convert the input data
+// to an acceptable mixer input format type.
+class ReformatBufferProvider : public CopyBufferProvider {
+public:
+ ReformatBufferProvider(int32_t channelCount,
+ audio_format_t inputFormat, audio_format_t outputFormat,
+ size_t bufferFrameCount);
+ virtual void copyFrames(void *dst, const void *src, size_t frames);
+
+protected:
+ const uint32_t mChannelCount;
+ const audio_format_t mInputFormat;
+ const audio_format_t mOutputFormat;
+};
+
+// TimestretchBufferProvider derives from PassthruBufferProvider for time stretching
+class TimestretchBufferProvider : public PassthruBufferProvider {
+public:
+ TimestretchBufferProvider(int32_t channelCount,
+ audio_format_t format, uint32_t sampleRate,
+ const AudioPlaybackRate &playbackRate);
+ virtual ~TimestretchBufferProvider();
+
+ // Overrides AudioBufferProvider methods
+ virtual status_t getNextBuffer(Buffer* buffer);
+ virtual void releaseBuffer(Buffer* buffer);
+
+ // Overrides PassthruBufferProvider
+ virtual void reset();
+
+ virtual status_t setPlaybackRate(const AudioPlaybackRate &playbackRate);
+
+ // processes frames
+ // dstBuffer is where to place the data
+ // dstFrames [in/out] is the desired frames (return with actual placed in buffer)
+ // srcBuffer is the source data
+ // srcFrames [in/out] is the available source frames (return with consumed)
+ virtual void processFrames(void *dstBuffer, size_t *dstFrames,
+ const void *srcBuffer, size_t *srcFrames);
+
+protected:
+ const uint32_t mChannelCount;
+ const audio_format_t mFormat;
+ const uint32_t mSampleRate; // const for now (TODO change this)
+ const size_t mFrameSize;
+ AudioPlaybackRate mPlaybackRate;
+
+private:
+ AudioBufferProvider::Buffer mBuffer; // for upstream request
+ size_t mLocalBufferFrameCount; // size of local buffer
+ void *mLocalBufferData; // internally allocated buffer for data returned
+ // to caller
+ size_t mRemaining; // remaining data in local buffer
+ sonicStream mSonicStream; // handle to sonic timestretch object
+ //FIXME: this dependency should be abstracted out
+ bool mFallbackFailErrorShown; // log fallback error only once
+ bool mAudioPlaybackRateValid; // flag for current parameters validity
+};
+
+// ----------------------------------------------------------------------------
+} // namespace android
+
+#endif // ANDROID_BUFFER_PROVIDERS_H
diff --git a/media/libmedia/include/BufferingSettings.h b/media/libmedia/include/BufferingSettings.h
new file mode 100644
index 0000000..e812d2a
--- /dev/null
+++ b/media/libmedia/include/BufferingSettings.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2016 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_BUFFERING_SETTINGS_H
+#define ANDROID_BUFFERING_SETTINGS_H
+
+#include <binder/Parcelable.h>
+
+namespace android {
+
+enum BufferingMode : int {
+ // Do not support buffering.
+ BUFFERING_MODE_NONE = 0,
+ // Support only time based buffering.
+ BUFFERING_MODE_TIME_ONLY = 1,
+ // Support only size based buffering.
+ BUFFERING_MODE_SIZE_ONLY = 2,
+ // Support both time and size based buffering, time based calculation precedes size based.
+ // Size based calculation will be used only when time information is not available for
+ // the stream.
+ BUFFERING_MODE_TIME_THEN_SIZE = 3,
+ // Number of modes.
+ BUFFERING_MODE_COUNT = 4,
+};
+
+struct BufferingSettings : public Parcelable {
+ static const int kNoWatermark = -1;
+
+ static bool IsValidBufferingMode(int mode);
+ static bool IsTimeBasedBufferingMode(int mode);
+ static bool IsSizeBasedBufferingMode(int mode);
+
+ BufferingMode mInitialBufferingMode; // for prepare
+ BufferingMode mRebufferingMode; // for playback
+
+ int mInitialWatermarkMs; // time based
+ int mInitialWatermarkKB; // size based
+
+ // When cached data is below this mark, playback will be paused for buffering
+ // till data reach |mRebufferingWatermarkHighMs| or end of stream.
+ int mRebufferingWatermarkLowMs;
+ // When cached data is above this mark, buffering will be paused.
+ int mRebufferingWatermarkHighMs;
+
+ // When cached data is below this mark, playback will be paused for buffering
+ // till data reach |mRebufferingWatermarkHighKB| or end of stream.
+ int mRebufferingWatermarkLowKB;
+ // When cached data is above this mark, buffering will be paused.
+ int mRebufferingWatermarkHighKB;
+
+ BufferingSettings();
+
+ status_t writeToParcel(Parcel* parcel) const override;
+ status_t readFromParcel(const Parcel* parcel) override;
+
+ String8 toString() const;
+};
+
+} // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_BUFFERING_SETTINGS_H
diff --git a/media/libmedia/include/CharacterEncodingDetector.h b/media/libmedia/include/CharacterEncodingDetector.h
new file mode 100644
index 0000000..deaa377
--- /dev/null
+++ b/media/libmedia/include/CharacterEncodingDetector.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2013 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 _CHARACTER_ENCODING_DETECTOR_H
+#define _CHARACTER_ENCODING_DETECTOR_H
+
+#include <media/mediascanner.h>
+
+#include "StringArray.h"
+
+#include "unicode/ucnv.h"
+#include "unicode/ucsdet.h"
+#include "unicode/ustring.h"
+
+namespace android {
+
+class CharacterEncodingDetector {
+
+ public:
+ CharacterEncodingDetector();
+ ~CharacterEncodingDetector();
+
+ void addTag(const char *name, const char *value);
+ size_t size();
+
+ void detectAndConvert();
+ status_t getTag(int index, const char **name, const char**value);
+
+ private:
+ const UCharsetMatch *getPreferred(
+ const char *input, size_t len,
+ const UCharsetMatch** ucma, size_t matches,
+ bool *goodmatch, int *highestmatch);
+
+ bool isFrequent(const uint16_t *values, uint32_t c);
+
+ // cached name and value strings, for native encoding support.
+ // TODO: replace these with byte blob arrays that don't require the data to be
+ // singlenullbyte-terminated
+ StringArray mNames;
+ StringArray mValues;
+
+ UConverter* mUtf8Conv;
+};
+
+
+
+}; // namespace android
+
+#endif
diff --git a/media/libmedia/include/Crypto.h b/media/libmedia/include/Crypto.h
new file mode 100644
index 0000000..ce08f98
--- /dev/null
+++ b/media/libmedia/include/Crypto.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2012 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 CRYPTO_H_
+
+#define CRYPTO_H_
+
+#include <media/ICrypto.h>
+#include <utils/threads.h>
+#include <utils/KeyedVector.h>
+
+#include "SharedLibrary.h"
+
+namespace android {
+
+struct CryptoFactory;
+struct CryptoPlugin;
+
+struct Crypto : public BnCrypto {
+ Crypto();
+ virtual ~Crypto();
+
+ virtual status_t initCheck() const;
+
+ virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]);
+
+ virtual status_t createPlugin(
+ const uint8_t uuid[16], const void *data, size_t size);
+
+ virtual status_t destroyPlugin();
+
+ virtual bool requiresSecureDecoderComponent(
+ const char *mime) const;
+
+ virtual void notifyResolution(uint32_t width, uint32_t height);
+
+ virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId);
+
+ virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16],
+ CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
+ const sp<IMemory> &source, size_t offset,
+ const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
+ const DestinationBuffer &destination, AString *errorDetailMsg);
+
+private:
+ mutable Mutex mLock;
+
+ status_t mInitCheck;
+ sp<SharedLibrary> mLibrary;
+ CryptoFactory *mFactory;
+ CryptoPlugin *mPlugin;
+
+ static KeyedVector<Vector<uint8_t>, String8> mUUIDToLibraryPathMap;
+ static KeyedVector<String8, wp<SharedLibrary> > mLibraryPathToOpenLibraryMap;
+ static Mutex mMapLock;
+
+ void findFactoryForScheme(const uint8_t uuid[16]);
+ bool loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]);
+ void closeFactory();
+
+ DISALLOW_EVIL_CONSTRUCTORS(Crypto);
+};
+
+} // namespace android
+
+#endif // CRYPTO_H_
diff --git a/media/libmedia/include/CryptoHal.h b/media/libmedia/include/CryptoHal.h
new file mode 100644
index 0000000..9d0c3e4
--- /dev/null
+++ b/media/libmedia/include/CryptoHal.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 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 CRYPTO_HAL_H_
+
+#define CRYPTO_HAL_H_
+
+#include <android/hardware/drm/1.0/ICryptoFactory.h>
+#include <android/hardware/drm/1.0/ICryptoPlugin.h>
+#include <media/ICrypto.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+
+#include "SharedLibrary.h"
+
+class IMemoryHeap;
+
+namespace android {
+
+struct CryptoHal : public BnCrypto {
+ CryptoHal();
+ virtual ~CryptoHal();
+
+ virtual status_t initCheck() const;
+
+ virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]);
+
+ virtual status_t createPlugin(
+ const uint8_t uuid[16], const void *data, size_t size);
+
+ virtual status_t destroyPlugin();
+
+ virtual bool requiresSecureDecoderComponent(
+ const char *mime) const;
+
+ virtual void notifyResolution(uint32_t width, uint32_t height);
+
+ virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId);
+
+ virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16],
+ CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
+ const sp<IMemory> &source, size_t offset,
+ const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
+ const ICrypto::DestinationBuffer &destination,
+ AString *errorDetailMsg);
+
+private:
+ mutable Mutex mLock;
+
+ sp<SharedLibrary> mLibrary;
+ sp<::android::hardware::drm::V1_0::ICryptoFactory> mFactory;
+ sp<::android::hardware::drm::V1_0::ICryptoPlugin> mPlugin;
+
+ /**
+ * mInitCheck is:
+ * NO_INIT if a plugin hasn't been created yet
+ * ERROR_UNSUPPORTED if a plugin can't be created for the uuid
+ * OK after a plugin has been created and mPlugin is valid
+ */
+ status_t mInitCheck;
+
+ KeyedVector<void *, uint32_t> mHeapBases;
+ uint32_t mNextBufferId;
+
+ sp<::android::hardware::drm::V1_0::ICryptoFactory>
+ makeCryptoFactory();
+ sp<::android::hardware::drm::V1_0::ICryptoPlugin>
+ makeCryptoPlugin(const uint8_t uuid[16], const void *initData,
+ size_t size);
+
+ void setHeapBase(const sp<IMemoryHeap>& heap);
+
+ status_t toSharedBuffer(const sp<IMemory>& memory,
+ ::android::hardware::drm::V1_0::SharedBuffer* buffer);
+
+ DISALLOW_EVIL_CONSTRUCTORS(CryptoHal);
+};
+
+} // namespace android
+
+#endif // CRYPTO_HAL_H_
diff --git a/media/libmedia/include/Drm.h b/media/libmedia/include/Drm.h
new file mode 100644
index 0000000..fc869cc
--- /dev/null
+++ b/media/libmedia/include/Drm.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2013 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 DRM_H_
+
+#define DRM_H_
+
+#include "SharedLibrary.h"
+
+#include <media/IDrm.h>
+#include <media/IDrmClient.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class DrmFactory;
+class DrmPlugin;
+struct DrmSessionClientInterface;
+
+struct Drm : public BnDrm,
+ public IBinder::DeathRecipient,
+ public DrmPluginListener {
+ Drm();
+ virtual ~Drm();
+
+ virtual status_t initCheck() const;
+
+ virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType);
+
+ virtual status_t createPlugin(const uint8_t uuid[16], const String8 &appPackageName);
+
+ virtual status_t destroyPlugin();
+
+ virtual status_t openSession(Vector<uint8_t> &sessionId);
+
+ virtual status_t closeSession(Vector<uint8_t> const &sessionId);
+
+ virtual status_t
+ getKeyRequest(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &initData,
+ String8 const &mimeType, DrmPlugin::KeyType keyType,
+ KeyedVector<String8, String8> const &optionalParameters,
+ Vector<uint8_t> &request, String8 &defaultUrl,
+ DrmPlugin::KeyRequestType *keyRequestType);
+
+ virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &response,
+ Vector<uint8_t> &keySetId);
+
+ virtual status_t removeKeys(Vector<uint8_t> const &keySetId);
+
+ virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keySetId);
+
+ virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
+ KeyedVector<String8, String8> &infoMap) const;
+
+ virtual status_t getProvisionRequest(String8 const &certType,
+ String8 const &certAuthority,
+ Vector<uint8_t> &request,
+ String8 &defaulUrl);
+
+ virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
+ Vector<uint8_t> &certificate,
+ Vector<uint8_t> &wrappedKey);
+
+ virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops);
+ virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop);
+
+ virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease);
+ virtual status_t releaseAllSecureStops();
+
+ virtual status_t getPropertyString(String8 const &name, String8 &value ) const;
+ virtual status_t getPropertyByteArray(String8 const &name,
+ Vector<uint8_t> &value ) const;
+ virtual status_t setPropertyString(String8 const &name, String8 const &value ) const;
+ virtual status_t setPropertyByteArray(String8 const &name,
+ Vector<uint8_t> const &value ) const;
+
+ virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm);
+
+ virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm);
+
+ virtual status_t encrypt(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &input,
+ Vector<uint8_t> const &iv,
+ Vector<uint8_t> &output);
+
+ virtual status_t decrypt(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &input,
+ Vector<uint8_t> const &iv,
+ Vector<uint8_t> &output);
+
+ virtual status_t sign(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> &signature);
+
+ virtual status_t verify(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &signature,
+ bool &match);
+
+ virtual status_t signRSA(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &wrappedKey,
+ Vector<uint8_t> &signature);
+
+ virtual status_t setListener(const sp<IDrmClient>& listener);
+
+ virtual void sendEvent(DrmPlugin::EventType eventType, int extra,
+ Vector<uint8_t> const *sessionId,
+ Vector<uint8_t> const *data);
+
+ virtual void sendExpirationUpdate(Vector<uint8_t> const *sessionId,
+ int64_t expiryTimeInMS);
+
+ virtual void sendKeysChange(Vector<uint8_t> const *sessionId,
+ Vector<DrmPlugin::KeyStatus> const *keyStatusList,
+ bool hasNewUsableKey);
+
+ virtual void binderDied(const wp<IBinder> &the_late_who);
+
+private:
+ static Mutex mLock;
+
+ status_t mInitCheck;
+
+ sp<DrmSessionClientInterface> mDrmSessionClient;
+
+ sp<IDrmClient> mListener;
+ mutable Mutex mEventLock;
+ mutable Mutex mNotifyLock;
+
+ sp<SharedLibrary> mLibrary;
+ DrmFactory *mFactory;
+ DrmPlugin *mPlugin;
+
+ static KeyedVector<Vector<uint8_t>, String8> mUUIDToLibraryPathMap;
+ static KeyedVector<String8, wp<SharedLibrary> > mLibraryPathToOpenLibraryMap;
+ static Mutex mMapLock;
+
+ void findFactoryForScheme(const uint8_t uuid[16]);
+ bool loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]);
+ void closeFactory();
+ void writeByteArray(Parcel &obj, Vector<uint8_t> const *array);
+
+ DISALLOW_EVIL_CONSTRUCTORS(Drm);
+};
+
+} // namespace android
+
+#endif // CRYPTO_H_
diff --git a/media/libmedia/include/DrmHal.h b/media/libmedia/include/DrmHal.h
new file mode 100644
index 0000000..82d2555
--- /dev/null
+++ b/media/libmedia/include/DrmHal.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2017 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 DRM_HAL_H_
+
+#define DRM_HAL_H_
+
+#include <android/hardware/drm/1.0/IDrmPlugin.h>
+#include <android/hardware/drm/1.0/IDrmPluginListener.h>
+#include <android/hardware/drm/1.0/IDrmFactory.h>
+
+#include <media/IDrm.h>
+#include <media/IDrmClient.h>
+#include <utils/threads.h>
+
+using ::android::hardware::drm::V1_0::EventType;
+using ::android::hardware::drm::V1_0::IDrmFactory;
+using ::android::hardware::drm::V1_0::IDrmPlugin;
+using ::android::hardware::drm::V1_0::IDrmPluginListener;
+using ::android::hardware::drm::V1_0::KeyStatus;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+namespace android {
+
+struct DrmSessionClientInterface;
+
+struct DrmHal : public BnDrm,
+ public IBinder::DeathRecipient,
+ public IDrmPluginListener {
+ DrmHal();
+ virtual ~DrmHal();
+
+ virtual status_t initCheck() const;
+
+ virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType);
+
+ virtual status_t createPlugin(const uint8_t uuid[16],
+ const String8 &appPackageName);
+
+ virtual status_t destroyPlugin();
+
+ virtual status_t openSession(Vector<uint8_t> &sessionId);
+
+ virtual status_t closeSession(Vector<uint8_t> const &sessionId);
+
+ virtual status_t
+ getKeyRequest(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &initData,
+ String8 const &mimeType, DrmPlugin::KeyType keyType,
+ KeyedVector<String8, String8> const &optionalParameters,
+ Vector<uint8_t> &request, String8 &defaultUrl,
+ DrmPlugin::KeyRequestType *keyRequestType);
+
+ virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &response,
+ Vector<uint8_t> &keySetId);
+
+ virtual status_t removeKeys(Vector<uint8_t> const &keySetId);
+
+ virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keySetId);
+
+ virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
+ KeyedVector<String8, String8> &infoMap) const;
+
+ virtual status_t getProvisionRequest(String8 const &certType,
+ String8 const &certAuthority,
+ Vector<uint8_t> &request,
+ String8 &defaulUrl);
+
+ virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
+ Vector<uint8_t> &certificate,
+ Vector<uint8_t> &wrappedKey);
+
+ virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops);
+ virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop);
+
+ virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease);
+ virtual status_t releaseAllSecureStops();
+
+ virtual status_t getPropertyString(String8 const &name, String8 &value ) const;
+ virtual status_t getPropertyByteArray(String8 const &name,
+ Vector<uint8_t> &value ) const;
+ virtual status_t setPropertyString(String8 const &name, String8 const &value ) const;
+ virtual status_t setPropertyByteArray(String8 const &name,
+ Vector<uint8_t> const &value ) const;
+
+ virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm);
+
+ virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm);
+
+ virtual status_t encrypt(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &input,
+ Vector<uint8_t> const &iv,
+ Vector<uint8_t> &output);
+
+ virtual status_t decrypt(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &input,
+ Vector<uint8_t> const &iv,
+ Vector<uint8_t> &output);
+
+ virtual status_t sign(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> &signature);
+
+ virtual status_t verify(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &signature,
+ bool &match);
+
+ virtual status_t signRSA(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &wrappedKey,
+ Vector<uint8_t> &signature);
+
+ virtual status_t setListener(const sp<IDrmClient>& listener);
+
+ // Methods of IDrmPluginListener
+ Return<void> sendEvent(EventType eventType,
+ const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data);
+
+ Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
+ int64_t expiryTimeInMS);
+
+ Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey);
+
+ virtual void binderDied(const wp<IBinder> &the_late_who);
+
+private:
+ static Mutex mLock;
+
+ sp<DrmSessionClientInterface> mDrmSessionClient;
+
+ sp<IDrmClient> mListener;
+ mutable Mutex mEventLock;
+ mutable Mutex mNotifyLock;
+
+ sp<IDrmFactory> mFactory;
+ sp<IDrmPlugin> mPlugin;
+
+ /**
+ * mInitCheck is:
+ * NO_INIT if a plugin hasn't been created yet
+ * ERROR_UNSUPPORTED if a plugin can't be created for the uuid
+ * OK after a plugin has been created and mPlugin is valid
+ */
+ status_t mInitCheck;
+
+ sp<IDrmFactory> makeDrmFactory();
+ sp<IDrmPlugin> makeDrmPlugin(const uint8_t uuid[16],
+ const String8 &appPackageName);
+
+ void writeByteArray(Parcel &obj, const hidl_vec<uint8_t>& array);
+
+ DISALLOW_EVIL_CONSTRUCTORS(DrmHal);
+};
+
+} // namespace android
+
+#endif // DRM_HAL_H_
diff --git a/media/libmedia/include/DrmSessionClientInterface.h b/media/libmedia/include/DrmSessionClientInterface.h
new file mode 100644
index 0000000..17faf08
--- /dev/null
+++ b/media/libmedia/include/DrmSessionClientInterface.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 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 DRM_PROXY_INTERFACE_H_
+#define DRM_PROXY_INTERFACE_H_
+
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct DrmSessionClientInterface : public RefBase {
+ virtual bool reclaimSession(const Vector<uint8_t>& sessionId) = 0;
+
+protected:
+ virtual ~DrmSessionClientInterface() {}
+};
+
+} // namespace android
+
+#endif // DRM_PROXY_INTERFACE_H_
diff --git a/media/libmedia/include/DrmSessionManager.h b/media/libmedia/include/DrmSessionManager.h
new file mode 100644
index 0000000..ba27199
--- /dev/null
+++ b/media/libmedia/include/DrmSessionManager.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015 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 DRM_SESSION_MANAGER_H_
+
+#define DRM_SESSION_MANAGER_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/RefBase.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class DrmSessionManagerTest;
+struct DrmSessionClientInterface;
+struct ProcessInfoInterface;
+
+bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2);
+
+struct SessionInfo {
+ sp<DrmSessionClientInterface> drm;
+ Vector<uint8_t> sessionId;
+ int64_t timeStamp;
+};
+
+typedef Vector<SessionInfo > SessionInfos;
+typedef KeyedVector<int, SessionInfos > PidSessionInfosMap;
+
+struct DrmSessionManager : public RefBase {
+ static sp<DrmSessionManager> Instance();
+
+ DrmSessionManager();
+ explicit DrmSessionManager(sp<ProcessInfoInterface> processInfo);
+
+ void addSession(int pid, const sp<DrmSessionClientInterface>& drm, const Vector<uint8_t>& sessionId);
+ void useSession(const Vector<uint8_t>& sessionId);
+ void removeSession(const Vector<uint8_t>& sessionId);
+ void removeDrm(const sp<DrmSessionClientInterface>& drm);
+ bool reclaimSession(int callingPid);
+
+protected:
+ virtual ~DrmSessionManager();
+
+private:
+ friend class DrmSessionManagerTest;
+
+ int64_t getTime_l();
+ bool getLowestPriority_l(int* lowestPriorityPid, int* lowestPriority);
+ bool getLeastUsedSession_l(
+ int pid, sp<DrmSessionClientInterface>* drm, Vector<uint8_t>* sessionId);
+
+ sp<ProcessInfoInterface> mProcessInfo;
+ mutable Mutex mLock;
+ PidSessionInfosMap mSessionMap;
+ int64_t mTime;
+
+ DISALLOW_EVIL_CONSTRUCTORS(DrmSessionManager);
+};
+
+} // namespace android
+
+#endif // DRM_SESSION_MANAGER_H_
diff --git a/media/libmedia/include/ExtendedAudioBufferProvider.h b/media/libmedia/include/ExtendedAudioBufferProvider.h
new file mode 100644
index 0000000..51e4713
--- /dev/null
+++ b/media/libmedia/include/ExtendedAudioBufferProvider.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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_EXTENDED_AUDIO_BUFFER_PROVIDER_H
+#define ANDROID_EXTENDED_AUDIO_BUFFER_PROVIDER_H
+
+#include <media/AudioBufferProvider.h>
+#include <media/AudioTimestamp.h>
+
+namespace android {
+
+class ExtendedAudioBufferProvider : public AudioBufferProvider {
+public:
+ virtual size_t framesReady() const = 0; // see description at AudioFlinger.h
+
+ // Return the total number of frames that have been obtained and released
+ virtual int64_t framesReleased() const { return 0; }
+
+ // Invoked by buffer consumer when a new timestamp is available.
+ // Default implementation ignores the timestamp.
+ virtual void onTimestamp(const ExtendedTimestamp& /*timestamp*/) { }
+};
+
+} // namespace android
+
+#endif // ANDROID_EXTENDED_AUDIO_BUFFER_PROVIDER_H
diff --git a/media/libmedia/include/ICrypto.h b/media/libmedia/include/ICrypto.h
new file mode 100644
index 0000000..8990f4b
--- /dev/null
+++ b/media/libmedia/include/ICrypto.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/IInterface.h>
+#include <cutils/native_handle.h>
+#include <media/hardware/CryptoAPI.h>
+#include <media/stagefright/foundation/ABase.h>
+
+#ifndef ANDROID_ICRYPTO_H_
+
+#define ANDROID_ICRYPTO_H_
+
+namespace android {
+
+struct AString;
+class IMemory;
+
+struct ICrypto : public IInterface {
+ DECLARE_META_INTERFACE(Crypto);
+
+ virtual status_t initCheck() const = 0;
+
+ virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) = 0;
+
+ virtual status_t createPlugin(
+ const uint8_t uuid[16], const void *data, size_t size) = 0;
+
+ virtual status_t destroyPlugin() = 0;
+
+ virtual bool requiresSecureDecoderComponent(
+ const char *mime) const = 0;
+
+ virtual void notifyResolution(uint32_t width, uint32_t height) = 0;
+
+ virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId) = 0;
+
+ enum DestinationType {
+ kDestinationTypeSharedMemory, // non-secure
+ kDestinationTypeNativeHandle // secure
+ };
+
+ struct DestinationBuffer {
+ DestinationType mType;
+ native_handle_t *mHandle;
+ sp<IMemory> mSharedMemory;
+ };
+
+ virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16],
+ CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
+ const sp<IMemory> &source, size_t offset,
+ const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
+ const DestinationBuffer &destination, AString *errorDetailMsg) = 0;
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(ICrypto);
+};
+
+struct BnCrypto : public BnInterface<ICrypto> {
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+private:
+ void readVector(const Parcel &data, Vector<uint8_t> &vector) const;
+ void writeVector(Parcel *reply, Vector<uint8_t> const &vector) const;
+};
+
+} // namespace android
+
+#endif // ANDROID_ICRYPTO_H_
diff --git a/media/libmedia/include/IDataSource.h b/media/libmedia/include/IDataSource.h
new file mode 100644
index 0000000..655f337
--- /dev/null
+++ b/media/libmedia/include/IDataSource.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2015 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_IDATASOURCE_H
+#define ANDROID_IDATASOURCE_H
+
+#include <binder/IInterface.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/Errors.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class IMemory;
+class DecryptHandle;
+
+// A binder interface for implementing a stagefright DataSource remotely.
+class IDataSource : public IInterface {
+public:
+ DECLARE_META_INTERFACE(DataSource);
+
+ // Get the memory that readAt writes into.
+ virtual sp<IMemory> getIMemory() = 0;
+ // Read up to |size| bytes into the memory returned by getIMemory(). Returns
+ // the number of bytes read, or -1 on error. |size| must not be larger than
+ // the buffer.
+ virtual ssize_t readAt(off64_t offset, size_t size) = 0;
+ // Get the size, or -1 if the size is unknown.
+ virtual status_t getSize(off64_t* size) = 0;
+ // This should be called before deleting |this|. The other methods may
+ // return errors if they're called after calling close().
+ virtual void close() = 0;
+ // Get the flags of the source.
+ // Refer to DataSource:Flags for the definition of the flags.
+ virtual uint32_t getFlags() = 0;
+ // get a description of the source, e.g. the url or filename it is based on
+ virtual String8 toString() = 0;
+ // Initialize DRM and return a DecryptHandle.
+ virtual sp<DecryptHandle> DrmInitialization(const char *mime) = 0;
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(IDataSource);
+};
+
+// ----------------------------------------------------------------------------
+
+class BnDataSource : public BnInterface<IDataSource> {
+public:
+ virtual status_t onTransact(uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IDATASOURCE_H
diff --git a/media/libmedia/include/IDrm.h b/media/libmedia/include/IDrm.h
new file mode 100644
index 0000000..a57e372
--- /dev/null
+++ b/media/libmedia/include/IDrm.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/IInterface.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <media/drm/DrmAPI.h>
+#include <media/IDrmClient.h>
+
+#ifndef ANDROID_IDRM_H_
+
+#define ANDROID_IDRM_H_
+
+namespace android {
+
+struct AString;
+
+struct IDrm : public IInterface {
+ DECLARE_META_INTERFACE(Drm);
+
+ virtual status_t initCheck() const = 0;
+
+ virtual bool isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) = 0;
+
+ virtual status_t createPlugin(const uint8_t uuid[16],
+ const String8 &appPackageName) = 0;
+
+ virtual status_t destroyPlugin() = 0;
+
+ virtual status_t openSession(Vector<uint8_t> &sessionId) = 0;
+
+ virtual status_t closeSession(Vector<uint8_t> const &sessionId) = 0;
+
+ virtual status_t
+ getKeyRequest(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &initData,
+ String8 const &mimeType, DrmPlugin::KeyType keyType,
+ KeyedVector<String8, String8> const &optionalParameters,
+ Vector<uint8_t> &request, String8 &defaultUrl,
+ DrmPlugin::KeyRequestType *keyRequestType) = 0;
+
+ virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &response,
+ Vector<uint8_t> &keySetId) = 0;
+
+ virtual status_t removeKeys(Vector<uint8_t> const &keySetId) = 0;
+
+ virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keySetId) = 0;
+
+ virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
+ KeyedVector<String8, String8> &infoMap) const = 0;
+
+ virtual status_t getProvisionRequest(String8 const &certType,
+ String8 const &certAuthority,
+ Vector<uint8_t> &request,
+ String8 &defaulUrl) = 0;
+
+ virtual status_t provideProvisionResponse(Vector<uint8_t> const &response,
+ Vector<uint8_t> &certificate,
+ Vector<uint8_t> &wrappedKey) = 0;
+
+ virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0;
+ virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) = 0;
+
+ virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0;
+ virtual status_t releaseAllSecureStops() = 0;
+
+ virtual status_t getPropertyString(String8 const &name, String8 &value) const = 0;
+ virtual status_t getPropertyByteArray(String8 const &name,
+ Vector<uint8_t> &value) const = 0;
+ virtual status_t setPropertyString(String8 const &name,
+ String8 const &value ) const = 0;
+ virtual status_t setPropertyByteArray(String8 const &name,
+ Vector<uint8_t> const &value) const = 0;
+
+ virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm) = 0;
+
+ virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm) = 0;
+
+ virtual status_t encrypt(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &input,
+ Vector<uint8_t> const &iv,
+ Vector<uint8_t> &output) = 0;
+
+ virtual status_t decrypt(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &input,
+ Vector<uint8_t> const &iv,
+ Vector<uint8_t> &output) = 0;
+
+ virtual status_t sign(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> &signature) = 0;
+
+ virtual status_t verify(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &signature,
+ bool &match) = 0;
+
+ virtual status_t signRSA(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &wrappedKey,
+ Vector<uint8_t> &signature) = 0;
+
+ virtual status_t setListener(const sp<IDrmClient>& listener) = 0;
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(IDrm);
+};
+
+struct BnDrm : public BnInterface<IDrm> {
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+private:
+ void readVector(const Parcel &data, Vector<uint8_t> &vector) const;
+ void writeVector(Parcel *reply, Vector<uint8_t> const &vector) const;
+};
+
+} // namespace android
+
+#endif // ANDROID_IDRM_H_
diff --git a/media/libmedia/include/IDrmClient.h b/media/libmedia/include/IDrmClient.h
new file mode 100644
index 0000000..3b2fc7c
--- /dev/null
+++ b/media/libmedia/include/IDrmClient.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 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_IDRMCLIENT_H
+#define ANDROID_IDRMCLIENT_H
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include <media/drm/DrmAPI.h>
+
+namespace android {
+
+class IDrmClient: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(DrmClient);
+
+ virtual void notify(DrmPlugin::EventType eventType, int extra, const Parcel *obj) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnDrmClient: public BnInterface<IDrmClient>
+{
+public:
+ virtual status_t onTransact(uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IDRMCLIENT_H
diff --git a/media/libmedia/include/IHDCP.h b/media/libmedia/include/IHDCP.h
new file mode 100644
index 0000000..352561e
--- /dev/null
+++ b/media/libmedia/include/IHDCP.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/IInterface.h>
+#include <media/hardware/HDCPAPI.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <ui/GraphicBuffer.h>
+
+namespace android {
+
+struct IHDCPObserver : public IInterface {
+ DECLARE_META_INTERFACE(HDCPObserver);
+
+ virtual void notify(
+ int msg, int ext1, int ext2, const Parcel *obj) = 0;
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(IHDCPObserver);
+};
+
+struct IHDCP : public IInterface {
+ DECLARE_META_INTERFACE(HDCP);
+
+ // Called to specify the observer that receives asynchronous notifications
+ // from the HDCP implementation to signal completion/failure of asynchronous
+ // operations (such as initialization) or out of band events.
+ virtual status_t setObserver(const sp<IHDCPObserver> &observer) = 0;
+
+ // Request to setup an HDCP session with the specified host listening
+ // on the specified port.
+ virtual status_t initAsync(const char *host, unsigned port) = 0;
+
+ // Request to shutdown the active HDCP session.
+ virtual status_t shutdownAsync() = 0;
+
+ // Returns the capability bitmask of this HDCP session.
+ // Possible return values (please refer to HDCAPAPI.h):
+ // HDCP_CAPS_ENCRYPT: mandatory, meaning the HDCP module can encrypt
+ // from an input byte-array buffer to an output byte-array buffer
+ // HDCP_CAPS_ENCRYPT_NATIVE: the HDCP module supports encryption from
+ // a native buffer to an output byte-array buffer. The format of the
+ // input native buffer is specific to vendor's encoder implementation.
+ // It is the same format as that used by the encoder when
+ // "storeMetaDataInBuffers" extension is enabled on its output port.
+ virtual uint32_t getCaps() = 0;
+
+ // ENCRYPTION only:
+ // Encrypt data according to the HDCP spec. "size" bytes of data are
+ // available at "inData" (virtual address), "size" may not be a multiple
+ // of 128 bits (16 bytes). An equal number of encrypted bytes should be
+ // written to the buffer at "outData" (virtual address).
+ // This operation is to be synchronous, i.e. this call does not return
+ // until outData contains size bytes of encrypted data.
+ // streamCTR will be assigned by the caller (to 0 for the first PES stream,
+ // 1 for the second and so on)
+ // inputCTR _will_be_maintained_by_the_callee_ for each PES stream.
+ virtual status_t encrypt(
+ const void *inData, size_t size, uint32_t streamCTR,
+ uint64_t *outInputCTR, void *outData) = 0;
+
+ // Encrypt data according to the HDCP spec. "size" bytes of data starting
+ // at location "offset" are available in "buffer" (buffer handle). "size"
+ // may not be a multiple of 128 bits (16 bytes). An equal number of
+ // encrypted bytes should be written to the buffer at "outData" (virtual
+ // address). This operation is to be synchronous, i.e. this call does not
+ // return until outData contains size bytes of encrypted data.
+ // streamCTR will be assigned by the caller (to 0 for the first PES stream,
+ // 1 for the second and so on)
+ // inputCTR _will_be_maintained_by_the_callee_ for each PES stream.
+ virtual status_t encryptNative(
+ const sp<GraphicBuffer> &graphicBuffer,
+ size_t offset, size_t size, uint32_t streamCTR,
+ uint64_t *outInputCTR, void *outData) = 0;
+
+ // DECRYPTION only:
+ // Decrypt data according to the HDCP spec.
+ // "size" bytes of encrypted data are available at "inData"
+ // (virtual address), "size" may not be a multiple of 128 bits (16 bytes).
+ // An equal number of decrypted bytes should be written to the buffer
+ // at "outData" (virtual address).
+ // This operation is to be synchronous, i.e. this call does not return
+ // until outData contains size bytes of decrypted data.
+ // Both streamCTR and inputCTR will be provided by the caller.
+ virtual status_t decrypt(
+ const void *inData, size_t size,
+ uint32_t streamCTR, uint64_t inputCTR,
+ void *outData) = 0;
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(IHDCP);
+};
+
+struct BnHDCPObserver : public BnInterface<IHDCPObserver> {
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+};
+
+struct BnHDCP : public BnInterface<IHDCP> {
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+};
+
+} // namespace android
+
+
diff --git a/media/libmedia/include/IMediaAnalyticsService.h b/media/libmedia/include/IMediaAnalyticsService.h
new file mode 100644
index 0000000..f635e94
--- /dev/null
+++ b/media/libmedia/include/IMediaAnalyticsService.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 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_IMEDIAANALYTICSSERVICE_H
+#define ANDROID_IMEDIAANALYTICSSERVICE_H
+
+#include <utils/String8.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+#include <sys/types.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <utils/List.h>
+
+#include <binder/IServiceManager.h>
+
+#include <media/MediaAnalyticsItem.h>
+// nope...#include <media/MediaAnalytics.h>
+
+namespace android {
+
+class IMediaAnalyticsService: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MediaAnalyticsService);
+
+ // generate a unique sessionID to use across multiple requests
+ // 'unique' is within this device, since last reboot
+ virtual MediaAnalyticsItem::SessionID_t generateUniqueSessionID() = 0;
+
+ // submit the indicated record to the mediaanalytics service, where
+ // it will be merged (if appropriate) with incomplete records that
+ // share the same key and sessionid.
+ // 'forcenew' marks any matching incomplete record as complete before
+ // inserting this new record.
+ // returns the sessionID associated with that item.
+ // caller continues to own the passed item
+ virtual MediaAnalyticsItem::SessionID_t submit(MediaAnalyticsItem *item, bool forcenew) = 0;
+
+};
+
+// ----------------------------------------------------------------------------
+
+class BnMediaAnalyticsService: public BnInterface<IMediaAnalyticsService>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IMEDIASTATISTICSSERVICE_H
diff --git a/media/libmedia/include/IMediaCodecList.h b/media/libmedia/include/IMediaCodecList.h
new file mode 100644
index 0000000..12b52d7
--- /dev/null
+++ b/media/libmedia/include/IMediaCodecList.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_IMEDIACODECLIST_H
+#define ANDROID_IMEDIACODECLIST_H
+
+#include <utils/Errors.h> // for status_t
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+#include <media/stagefright/foundation/AMessage.h>
+
+namespace android {
+
+struct MediaCodecInfo;
+
+class IMediaCodecList: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MediaCodecList);
+
+ virtual size_t countCodecs() const = 0;
+ virtual sp<MediaCodecInfo> getCodecInfo(size_t index) const = 0;
+
+ virtual const sp<AMessage> getGlobalSettings() const = 0;
+
+ virtual ssize_t findCodecByType(
+ const char *type, bool encoder, size_t startIndex = 0) const = 0;
+
+ virtual ssize_t findCodecByName(const char *name) const = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnMediaCodecList: public BnInterface<IMediaCodecList>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IMEDIACODECLIST_H
diff --git a/media/libmedia/include/IMediaCodecService.h b/media/libmedia/include/IMediaCodecService.h
new file mode 100644
index 0000000..984a0fd
--- /dev/null
+++ b/media/libmedia/include/IMediaCodecService.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 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_IMEDIACODECSERVICE_H
+#define ANDROID_IMEDIACODECSERVICE_H
+
+#include <binder/IInterface.h>
+#include <binder/IMemory.h>
+#include <binder/Parcel.h>
+#include <media/IDataSource.h>
+#include <include/OMX.h>
+
+namespace android {
+
+class IMediaCodecService: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MediaCodecService);
+
+ virtual sp<IOMX> getOMX() = 0;
+};
+
+class BnMediaCodecService: public BnInterface<IMediaCodecService>
+{
+public:
+ virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+ uint32_t flags = 0);
+};
+
+} // namespace android
+
+#endif // ANDROID_IMEDIACODECSERVICE_H
diff --git a/media/libmedia/include/IMediaDeathNotifier.h b/media/libmedia/include/IMediaDeathNotifier.h
new file mode 100644
index 0000000..aca6678
--- /dev/null
+++ b/media/libmedia/include/IMediaDeathNotifier.h
@@ -0,0 +1,61 @@
+/*
+ * 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_IMEDIADEATHNOTIFIER_H
+#define ANDROID_IMEDIADEATHNOTIFIER_H
+
+#include <utils/threads.h>
+#include <media/IMediaPlayerService.h>
+#include <utils/SortedVector.h>
+
+namespace android {
+
+class IMediaDeathNotifier: virtual public RefBase
+{
+public:
+ IMediaDeathNotifier() { addObitRecipient(this); }
+ virtual ~IMediaDeathNotifier() { removeObitRecipient(this); }
+
+ virtual void died() = 0;
+ static const sp<IMediaPlayerService> getMediaPlayerService();
+
+private:
+ IMediaDeathNotifier &operator=(const IMediaDeathNotifier &);
+ IMediaDeathNotifier(const IMediaDeathNotifier &);
+
+ static void addObitRecipient(const wp<IMediaDeathNotifier>& recipient);
+ static void removeObitRecipient(const wp<IMediaDeathNotifier>& recipient);
+
+ class DeathNotifier: public IBinder::DeathRecipient
+ {
+ public:
+ DeathNotifier() {}
+ virtual ~DeathNotifier();
+
+ virtual void binderDied(const wp<IBinder>& who);
+ };
+
+ friend class DeathNotifier;
+
+ static Mutex sServiceLock;
+ static sp<IMediaPlayerService> sMediaPlayerService;
+ static sp<DeathNotifier> sDeathNotifier;
+ static SortedVector< wp<IMediaDeathNotifier> > sObitRecipients;
+};
+
+}; // namespace android
+
+#endif // ANDROID_IMEDIADEATHNOTIFIER_H
diff --git a/media/libmedia/include/IMediaDrmService.h b/media/libmedia/include/IMediaDrmService.h
new file mode 100644
index 0000000..323fae5
--- /dev/null
+++ b/media/libmedia/include/IMediaDrmService.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 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_IMEDIADRMSERVICE_H
+#define ANDROID_IMEDIADRMSERVICE_H
+
+#include <utils/Errors.h> // for status_t
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+struct ICrypto;
+struct IDrm;
+
+class IMediaDrmService: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MediaDrmService);
+
+ virtual sp<ICrypto> makeCrypto() = 0;
+ virtual sp<IDrm> makeDrm() = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnMediaDrmService: public BnInterface<IMediaDrmService>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IMEDIADRMSERVICE_H
diff --git a/media/libmedia/include/IMediaExtractor.h b/media/libmedia/include/IMediaExtractor.h
new file mode 100644
index 0000000..cf1b9fb
--- /dev/null
+++ b/media/libmedia/include/IMediaExtractor.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2009 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 IMEDIA_EXTRACTOR_BASE_H_
+
+#define IMEDIA_EXTRACTOR_BASE_H_
+
+#include <media/IMediaSource.h>
+#include <media/stagefright/DataSource.h>
+
+namespace android {
+
+class MetaData;
+namespace media {
+class ICas;
+};
+using namespace media;
+
+class IMediaExtractor : public IInterface {
+public:
+ DECLARE_META_INTERFACE(MediaExtractor);
+
+ virtual size_t countTracks() = 0;
+ virtual sp<IMediaSource> getTrack(size_t index) = 0;
+
+ enum GetTrackMetaDataFlags {
+ kIncludeExtensiveMetaData = 1
+ };
+ virtual sp<MetaData> getTrackMetaData(
+ size_t index, uint32_t flags = 0) = 0;
+
+ // Return container specific meta-data. The default implementation
+ // returns an empty metadata object.
+ virtual sp<MetaData> getMetaData() = 0;
+
+ virtual status_t getMetrics(Parcel *reply) = 0;
+
+ enum Flags {
+ CAN_SEEK_BACKWARD = 1, // the "seek 10secs back button"
+ CAN_SEEK_FORWARD = 2, // the "seek 10secs forward button"
+ CAN_PAUSE = 4,
+ CAN_SEEK = 8, // the "seek bar"
+ };
+
+ // If subclasses do _not_ override this, the default is
+ // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
+ virtual uint32_t flags() const = 0;
+
+ // for DRM
+ virtual char* getDrmTrackInfo(size_t trackID, int *len) = 0;
+
+ virtual status_t setMediaCas(const sp<ICas> &cas) = 0;
+
+ virtual void setUID(uid_t uid) = 0;
+
+ virtual const char * name() = 0;
+};
+
+
+class BnMediaExtractor: public BnInterface<IMediaExtractor>
+{
+public:
+ virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+ uint32_t flags = 0);
+};
+
+void registerMediaExtractor(
+ const sp<IMediaExtractor> &extractor,
+ const sp<DataSource> &source,
+ const char *mime);
+
+void registerMediaSource(
+ const sp<IMediaExtractor> &extractor,
+ const sp<IMediaSource> &source);
+
+status_t dumpExtractors(int fd, const Vector<String16>& args);
+
+
+} // namespace android
+
+#endif // IMEDIA_EXTRACTOR_BASE_H_
diff --git a/media/libmedia/include/IMediaExtractorService.h b/media/libmedia/include/IMediaExtractorService.h
new file mode 100644
index 0000000..4d7b317
--- /dev/null
+++ b/media/libmedia/include/IMediaExtractorService.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 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_IMEDIAEXTRACTORSERVICE_H
+#define ANDROID_IMEDIAEXTRACTORSERVICE_H
+
+#include <binder/IInterface.h>
+#include <binder/IMemory.h>
+#include <binder/Parcel.h>
+#include <media/IDataSource.h>
+#include <media/IMediaExtractor.h>
+
+namespace android {
+
+class IMediaExtractorService: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MediaExtractorService);
+
+ virtual sp<IMediaExtractor> makeExtractor(const sp<IDataSource> &source, const char *mime) = 0;
+
+};
+
+class BnMediaExtractorService: public BnInterface<IMediaExtractorService>
+{
+public:
+ virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+ uint32_t flags = 0);
+};
+
+} // namespace android
+
+#endif // ANDROID_IMEDIAEXTRACTORSERVICE_H
diff --git a/media/libmedia/include/IMediaHTTPConnection.h b/media/libmedia/include/IMediaHTTPConnection.h
new file mode 100644
index 0000000..2a63eb7
--- /dev/null
+++ b/media/libmedia/include/IMediaHTTPConnection.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013 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 I_MEDIA_HTTP_CONNECTION_H_
+
+#define I_MEDIA_HTTP_CONNECTION_H_
+
+#include <binder/IInterface.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/KeyedVector.h>
+
+namespace android {
+
+struct IMediaHTTPConnection;
+
+/** MUST stay in sync with IMediaHTTPConnection.aidl */
+
+struct IMediaHTTPConnection : public IInterface {
+ DECLARE_META_INTERFACE(MediaHTTPConnection);
+
+ virtual bool connect(
+ const char *uri, const KeyedVector<String8, String8> *headers) = 0;
+
+ virtual void disconnect() = 0;
+ virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;
+ virtual off64_t getSize() = 0;
+ virtual status_t getMIMEType(String8 *mimeType) = 0;
+ virtual status_t getUri(String8 *uri) = 0;
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(IMediaHTTPConnection);
+};
+
+} // namespace android
+
+#endif // I_MEDIA_HTTP_CONNECTION_H_
diff --git a/media/libmedia/include/IMediaHTTPService.h b/media/libmedia/include/IMediaHTTPService.h
new file mode 100644
index 0000000..f66d6c8
--- /dev/null
+++ b/media/libmedia/include/IMediaHTTPService.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 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 I_MEDIA_HTTP_SERVICE_H_
+
+#define I_MEDIA_HTTP_SERVICE_H_
+
+#include <binder/IInterface.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+struct IMediaHTTPConnection;
+
+/** MUST stay in sync with IMediaHTTPService.aidl */
+
+struct IMediaHTTPService : public IInterface {
+ DECLARE_META_INTERFACE(MediaHTTPService);
+
+ virtual sp<IMediaHTTPConnection> makeHTTPConnection() = 0;
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(IMediaHTTPService);
+};
+
+} // namespace android
+
+#endif // I_MEDIA_HTTP_SERVICE_H_
diff --git a/media/libmedia/include/IMediaLogService.h b/media/libmedia/include/IMediaLogService.h
new file mode 100644
index 0000000..1f5777e
--- /dev/null
+++ b/media/libmedia/include/IMediaLogService.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2013 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_IMEDIALOGSERVICE_H
+#define ANDROID_IMEDIALOGSERVICE_H
+
+#include <binder/IInterface.h>
+#include <binder/IMemory.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+class IMediaLogService: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MediaLogService);
+
+ virtual void registerWriter(const sp<IMemory>& shared, size_t size, const char *name) = 0;
+ virtual void unregisterWriter(const sp<IMemory>& shared) = 0;
+
+};
+
+class BnMediaLogService: public BnInterface<IMediaLogService>
+{
+public:
+ virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+ uint32_t flags = 0);
+};
+
+} // namespace android
+
+#endif // ANDROID_IMEDIALOGSERVICE_H
diff --git a/media/libmedia/include/IMediaMetadataRetriever.h b/media/libmedia/include/IMediaMetadataRetriever.h
new file mode 100644
index 0000000..c90f254
--- /dev/null
+++ b/media/libmedia/include/IMediaMetadataRetriever.h
@@ -0,0 +1,63 @@
+/*
+**
+** Copyright (C) 2008 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_IMEDIAMETADATARETRIEVER_H
+#define ANDROID_IMEDIAMETADATARETRIEVER_H
+
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include <binder/IMemory.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+class IDataSource;
+struct IMediaHTTPService;
+
+class IMediaMetadataRetriever: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MediaMetadataRetriever);
+ virtual void disconnect() = 0;
+
+ virtual status_t setDataSource(
+ const sp<IMediaHTTPService> &httpService,
+ const char *srcUrl,
+ const KeyedVector<String8, String8> *headers = NULL) = 0;
+
+ virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0;
+ virtual status_t setDataSource(const sp<IDataSource>& dataSource) = 0;
+ virtual sp<IMemory> getFrameAtTime(int64_t timeUs, int option) = 0;
+ virtual sp<IMemory> extractAlbumArt() = 0;
+ virtual const char* extractMetadata(int keyCode) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnMediaMetadataRetriever: public BnInterface<IMediaMetadataRetriever>
+{
+public:
+ virtual status_t onTransact(uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IMEDIAMETADATARETRIEVER_H
diff --git a/media/libmedia/include/IMediaPlayer.h b/media/libmedia/include/IMediaPlayer.h
new file mode 100644
index 0000000..e5a98dd
--- /dev/null
+++ b/media/libmedia/include/IMediaPlayer.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2008 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_IMEDIAPLAYER_H
+#define ANDROID_IMEDIAPLAYER_H
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include <utils/KeyedVector.h>
+#include <system/audio.h>
+
+#include <media/IMediaSource.h>
+#include <media/VolumeShaper.h>
+
+// Fwd decl to make sure everyone agrees that the scope of struct sockaddr_in is
+// global, and not in android::
+struct sockaddr_in;
+
+namespace android {
+
+class Parcel;
+class Surface;
+class IDataSource;
+struct IStreamSource;
+class IGraphicBufferProducer;
+struct IMediaHTTPService;
+struct AudioPlaybackRate;
+struct AVSyncSettings;
+struct BufferingSettings;
+
+typedef IMediaSource::ReadOptions::SeekMode MediaPlayerSeekMode;
+
+class IMediaPlayer: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MediaPlayer);
+
+ virtual void disconnect() = 0;
+
+ virtual status_t setDataSource(
+ const sp<IMediaHTTPService> &httpService,
+ const char *url,
+ const KeyedVector<String8, String8>* headers) = 0;
+
+ virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0;
+ virtual status_t setDataSource(const sp<IStreamSource>& source) = 0;
+ virtual status_t setDataSource(const sp<IDataSource>& source) = 0;
+ virtual status_t setVideoSurfaceTexture(
+ const sp<IGraphicBufferProducer>& bufferProducer) = 0;
+ virtual status_t getDefaultBufferingSettings(
+ BufferingSettings* buffering /* nonnull */) = 0;
+ virtual status_t setBufferingSettings(const BufferingSettings& buffering) = 0;
+ virtual status_t prepareAsync() = 0;
+ virtual status_t start() = 0;
+ virtual status_t stop() = 0;
+ virtual status_t pause() = 0;
+ virtual status_t isPlaying(bool* state) = 0;
+ virtual status_t setPlaybackSettings(const AudioPlaybackRate& rate) = 0;
+ virtual status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) = 0;
+ virtual status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) = 0;
+ virtual status_t getSyncSettings(AVSyncSettings* sync /* nonnull */,
+ float* videoFps /* nonnull */) = 0;
+ virtual status_t seekTo(
+ int msec,
+ MediaPlayerSeekMode mode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC) = 0;
+ virtual status_t getCurrentPosition(int* msec) = 0;
+ virtual status_t getDuration(int* msec) = 0;
+ virtual status_t reset() = 0;
+ virtual status_t setAudioStreamType(audio_stream_type_t type) = 0;
+ virtual status_t setLooping(int loop) = 0;
+ virtual status_t setVolume(float leftVolume, float rightVolume) = 0;
+ virtual status_t setAuxEffectSendLevel(float level) = 0;
+ virtual status_t attachAuxEffect(int effectId) = 0;
+ virtual status_t setParameter(int key, const Parcel& request) = 0;
+ virtual status_t getParameter(int key, Parcel* reply) = 0;
+ virtual status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint) = 0;
+ virtual status_t getRetransmitEndpoint(struct sockaddr_in* endpoint) = 0;
+ virtual status_t setNextPlayer(const sp<IMediaPlayer>& next) = 0;
+
+ virtual VolumeShaper::Status applyVolumeShaper(
+ const sp<VolumeShaper::Configuration>& configuration,
+ const sp<VolumeShaper::Operation>& operation) = 0;
+ virtual sp<VolumeShaper::State> getVolumeShaperState(int id) = 0;
+
+ // Modular DRM
+ virtual status_t prepareDrm(const uint8_t uuid[16],
+ const Vector<uint8_t>& drmSessionId) = 0;
+ virtual status_t releaseDrm() = 0;
+
+ // Invoke a generic method on the player by using opaque parcels
+ // for the request and reply.
+ // @param request Parcel that must start with the media player
+ // interface token.
+ // @param[out] reply Parcel to hold the reply data. Cannot be null.
+ // @return OK if the invocation was made successfully.
+ virtual status_t invoke(const Parcel& request, Parcel *reply) = 0;
+
+ // Set a new metadata filter.
+ // @param filter A set of allow and drop rules serialized in a Parcel.
+ // @return OK if the invocation was made successfully.
+ virtual status_t setMetadataFilter(const Parcel& filter) = 0;
+
+ // Retrieve a set of metadata.
+ // @param update_only Include only the metadata that have changed
+ // since the last invocation of getMetadata.
+ // The set is built using the unfiltered
+ // notifications the native player sent to the
+ // MediaPlayerService during that period of
+ // time. If false, all the metadatas are considered.
+ // @param apply_filter If true, once the metadata set has been built based
+ // on the value update_only, the current filter is
+ // applied.
+ // @param[out] metadata On exit contains a set (possibly empty) of metadata.
+ // Valid only if the call returned OK.
+ // @return OK if the invocation was made successfully.
+ virtual status_t getMetadata(bool update_only,
+ bool apply_filter,
+ Parcel *metadata) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnMediaPlayer: public BnInterface<IMediaPlayer>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IMEDIAPLAYER_H
diff --git a/media/libmedia/include/IMediaPlayerClient.h b/media/libmedia/include/IMediaPlayerClient.h
new file mode 100644
index 0000000..8f1843e
--- /dev/null
+++ b/media/libmedia/include/IMediaPlayerClient.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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_IMEDIAPLAYERCLIENT_H
+#define ANDROID_IMEDIAPLAYERCLIENT_H
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+class IMediaPlayerClient: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MediaPlayerClient);
+
+ virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnMediaPlayerClient: public BnInterface<IMediaPlayerClient>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IMEDIAPLAYERCLIENT_H
diff --git a/media/libmedia/include/IMediaPlayerService.h b/media/libmedia/include/IMediaPlayerService.h
new file mode 100644
index 0000000..f21bb3a
--- /dev/null
+++ b/media/libmedia/include/IMediaPlayerService.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2008 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_IMEDIAPLAYERSERVICE_H
+#define ANDROID_IMEDIAPLAYERSERVICE_H
+
+#include <utils/Errors.h> // for status_t
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include <system/audio.h>
+
+#include <media/IMediaPlayerClient.h>
+#include <media/IMediaPlayer.h>
+#include <media/IMediaMetadataRetriever.h>
+
+namespace android {
+
+struct IHDCP;
+class IMediaCodecList;
+struct IMediaHTTPService;
+class IMediaRecorder;
+class IOMX;
+class IRemoteDisplay;
+class IRemoteDisplayClient;
+struct IStreamSource;
+
+class IMediaPlayerService: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MediaPlayerService);
+
+ virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName) = 0;
+ virtual sp<IMediaMetadataRetriever> createMetadataRetriever() = 0;
+ virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client,
+ audio_session_t audioSessionId = AUDIO_SESSION_ALLOCATE) = 0;
+ virtual sp<IOMX> getOMX() = 0;
+ virtual sp<IHDCP> makeHDCP(bool createEncryptionModule) = 0;
+ virtual sp<IMediaCodecList> getCodecList() const = 0;
+
+ // Connects to a remote display.
+ // 'iface' specifies the address of the local interface on which to listen for
+ // a connection from the remote display as an ip address and port number
+ // of the form "x.x.x.x:y". The media server should call back into the provided remote
+ // display client when display connection, disconnection or errors occur.
+ // The assumption is that at most one remote display will be connected to the
+ // provided interface at a time.
+ virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName,
+ const sp<IRemoteDisplayClient>& client, const String8& iface) = 0;
+
+ // codecs and audio devices usage tracking for the battery app
+ enum BatteryDataBits {
+ // tracking audio codec
+ kBatteryDataTrackAudio = 0x1,
+ // tracking video codec
+ kBatteryDataTrackVideo = 0x2,
+ // codec is started, otherwise codec is paused
+ kBatteryDataCodecStarted = 0x4,
+ // tracking decoder (for media player),
+ // otherwise tracking encoder (for media recorder)
+ kBatteryDataTrackDecoder = 0x8,
+ // start to play an audio on an audio device
+ kBatteryDataAudioFlingerStart = 0x10,
+ // stop/pause the audio playback
+ kBatteryDataAudioFlingerStop = 0x20,
+ // audio is rounted to speaker
+ kBatteryDataSpeakerOn = 0x40,
+ // audio is rounted to devices other than speaker
+ kBatteryDataOtherAudioDeviceOn = 0x80,
+ };
+
+ virtual void addBatteryData(uint32_t params) = 0;
+ virtual status_t pullBatteryData(Parcel* reply) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IMEDIAPLAYERSERVICE_H
diff --git a/media/libmedia/include/IMediaRecorder.h b/media/libmedia/include/IMediaRecorder.h
new file mode 100644
index 0000000..9d0341a
--- /dev/null
+++ b/media/libmedia/include/IMediaRecorder.h
@@ -0,0 +1,82 @@
+/*
+ **
+ ** Copyright 2008, 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_IMEDIARECORDER_H
+#define ANDROID_IMEDIARECORDER_H
+
+#include <binder/IInterface.h>
+
+namespace android {
+
+class Surface;
+namespace hardware {
+class ICamera;
+}
+class ICameraRecordingProxy;
+class IMediaRecorderClient;
+class IGraphicBufferProducer;
+struct PersistentSurface;
+
+class IMediaRecorder: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MediaRecorder);
+
+ virtual status_t setCamera(const sp<hardware::ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy) = 0;
+ virtual status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface) = 0;
+ virtual status_t setVideoSource(int vs) = 0;
+ virtual status_t setAudioSource(int as) = 0;
+ virtual status_t setOutputFormat(int of) = 0;
+ virtual status_t setVideoEncoder(int ve) = 0;
+ virtual status_t setAudioEncoder(int ae) = 0;
+ virtual status_t setOutputFile(int fd) = 0;
+ virtual status_t setNextOutputFile(int fd) = 0;
+ virtual status_t setVideoSize(int width, int height) = 0;
+ virtual status_t setVideoFrameRate(int frames_per_second) = 0;
+ virtual status_t setParameters(const String8& params) = 0;
+ virtual status_t setListener(const sp<IMediaRecorderClient>& listener) = 0;
+ virtual status_t setClientName(const String16& clientName) = 0;
+ virtual status_t prepare() = 0;
+ virtual status_t getMaxAmplitude(int* max) = 0;
+ virtual status_t getMetrics(Parcel *reply) = 0;
+ virtual status_t start() = 0;
+ virtual status_t stop() = 0;
+ virtual status_t reset() = 0;
+ virtual status_t pause() = 0;
+ virtual status_t resume() = 0;
+ virtual status_t init() = 0;
+ virtual status_t close() = 0;
+ virtual status_t release() = 0;
+ virtual status_t setInputSurface(const sp<PersistentSurface>& surface) = 0;
+ virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnMediaRecorder: public BnInterface<IMediaRecorder>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IMEDIARECORDER_H
diff --git a/media/libmedia/include/IMediaRecorderClient.h b/media/libmedia/include/IMediaRecorderClient.h
new file mode 100644
index 0000000..e7d0229
--- /dev/null
+++ b/media/libmedia/include/IMediaRecorderClient.h
@@ -0,0 +1,47 @@
+/*
+ * 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_IMEDIARECORDERCLIENT_H
+#define ANDROID_IMEDIARECORDERCLIENT_H
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+class IMediaRecorderClient: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MediaRecorderClient);
+
+ virtual void notify(int msg, int ext1, int ext2) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnMediaRecorderClient: public BnInterface<IMediaRecorderClient>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IMEDIARECORDERCLIENT_H
diff --git a/media/libmedia/include/IMediaSource.h b/media/libmedia/include/IMediaSource.h
new file mode 100644
index 0000000..2bde782
--- /dev/null
+++ b/media/libmedia/include/IMediaSource.h
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2009 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 IMEDIA_SOURCE_BASE_H_
+
+#define IMEDIA_SOURCE_BASE_H_
+
+#include <map>
+
+#include <binder/IInterface.h>
+#include <binder/IMemory.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaErrors.h>
+
+namespace android {
+
+struct MediaSource;
+class MetaData;
+class MediaBufferGroup;
+
+class IMediaSource : public IInterface {
+public:
+ DECLARE_META_INTERFACE(MediaSource);
+
+ enum {
+ // Maximum number of buffers would be read in readMultiple.
+ kMaxNumReadMultiple = 128,
+ };
+
+ // To be called before any other methods on this object, except
+ // getFormat().
+ virtual status_t start(MetaData *params = NULL) = 0;
+
+ // Any blocking read call returns immediately with a result of NO_INIT.
+ // It is an error to call any methods other than start after this call
+ // returns. Any buffers the object may be holding onto at the time of
+ // the stop() call are released.
+ // Also, it is imperative that any buffers output by this object and
+ // held onto by callers be released before a call to stop() !!!
+ virtual status_t stop() = 0;
+
+ // Returns the format of the data output by this media source.
+ virtual sp<MetaData> getFormat() = 0;
+
+ // Options that modify read() behaviour. The default is to
+ // a) not request a seek
+ // b) not be late, i.e. lateness_us = 0
+ struct ReadOptions {
+ enum SeekMode : int32_t {
+ SEEK_PREVIOUS_SYNC,
+ SEEK_NEXT_SYNC,
+ SEEK_CLOSEST_SYNC,
+ SEEK_CLOSEST,
+ };
+
+ ReadOptions();
+
+ // Reset everything back to defaults.
+ void reset();
+
+ void setSeekTo(int64_t time_us, SeekMode mode = SEEK_CLOSEST_SYNC);
+ void clearSeekTo();
+ bool getSeekTo(int64_t *time_us, SeekMode *mode) const;
+
+ // TODO: remove this if unused.
+ void setLateBy(int64_t lateness_us);
+ int64_t getLateBy() const;
+
+ void setNonBlocking();
+ void clearNonBlocking();
+ bool getNonBlocking() const;
+
+ // Used to clear all non-persistent options for multiple buffer reads.
+ void clearNonPersistent() {
+ clearSeekTo();
+ }
+
+ private:
+ enum Options {
+ kSeekTo_Option = 1,
+ };
+
+ uint32_t mOptions;
+ int64_t mSeekTimeUs;
+ SeekMode mSeekMode;
+ int64_t mLatenessUs;
+ bool mNonBlocking;
+ } __attribute__((packed)); // sent through Binder
+
+ // Returns a new buffer of data. Call blocks until a
+ // buffer is available, an error is encountered or the end of the stream
+ // is reached.
+ // End of stream is signalled by a result of ERROR_END_OF_STREAM.
+ // A result of INFO_FORMAT_CHANGED indicates that the format of this
+ // MediaSource has changed mid-stream, the client can continue reading
+ // but should be prepared for buffers of the new configuration.
+ //
+ // TODO: consider removing read() in favor of readMultiple().
+ virtual status_t read(
+ MediaBuffer **buffer, const ReadOptions *options = NULL) = 0;
+
+ // Returns a vector of new buffers of data, where the new buffers are added
+ // to the end of the vector.
+ // Call blocks until an error is encountered, or the end of the stream is
+ // reached, or format change is hit, or |kMaxNumReadMultiple| buffers have
+ // been read.
+ // End of stream is signaled by a result of ERROR_END_OF_STREAM.
+ // A result of INFO_FORMAT_CHANGED indicates that the format of this
+ // MediaSource has changed mid-stream, the client can continue reading
+ // but should be prepared for buffers of the new configuration.
+ //
+ // ReadOptions may be specified. Persistent options apply to all reads;
+ // non-persistent options (e.g. seek) apply only to the first read.
+ virtual status_t readMultiple(
+ Vector<MediaBuffer *> *buffers, uint32_t maxNumBuffers = 1,
+ const ReadOptions *options = nullptr) = 0;
+
+ // Returns true if |readMultiple| is supported, otherwise false.
+ virtual bool supportReadMultiple() = 0;
+
+ // Returns true if |read| supports nonblocking option, otherwise false.
+ // |readMultiple| if supported, always allows the nonblocking option.
+ virtual bool supportNonblockingRead() = 0;
+
+ // Causes this source to suspend pulling data from its upstream source
+ // until a subsequent read-with-seek. Currently only supported by
+ // OMXCodec.
+ virtual status_t pause() = 0;
+
+ // The consumer of this media source requests that the given buffers
+ // are to be returned exclusively in response to read calls.
+ // This will be called after a successful start() and before the
+ // first read() call.
+ // Callee assumes ownership of the buffers if no error is returned.
+ virtual status_t setBuffers(const Vector<MediaBuffer *> & /* buffers */) = 0;
+
+};
+
+class BnMediaSource: public BnInterface<IMediaSource>
+{
+public:
+ BnMediaSource();
+
+ virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+ uint32_t flags = 0);
+
+ virtual status_t pause() {
+ return ERROR_UNSUPPORTED;
+ }
+
+ virtual status_t setBuffers(const Vector<MediaBuffer *> & /* buffers */) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ // TODO: Implement this for local media sources.
+ virtual status_t readMultiple(
+ Vector<MediaBuffer *> * /* buffers */, uint32_t /* maxNumBuffers = 1 */,
+ const ReadOptions * /* options = nullptr */) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ virtual bool supportReadMultiple() {
+ return false;
+ }
+
+ // Override in source if nonblocking reads are supported.
+ virtual bool supportNonblockingRead() {
+ return false;
+ }
+
+ static const size_t kBinderMediaBuffers = 4; // buffers managed by BnMediaSource
+ static const size_t kTransferSharedAsSharedThreshold = 4 * 1024; // if >= shared, else inline
+ static const size_t kTransferInlineAsSharedThreshold = 64 * 1024; // if >= shared, else inline
+ static const size_t kInlineMaxTransfer = 256 * 1024; // Binder size limited to BINDER_VM_SIZE.
+
+protected:
+ virtual ~BnMediaSource();
+
+private:
+ uint32_t mBuffersSinceStop; // Buffer tracking variable
+
+ std::unique_ptr<MediaBufferGroup> mGroup;
+
+ // To prevent marshalling IMemory with each read transaction, we cache the IMemory pointer
+ // into a map.
+ //
+ // This is converted into an index, which is used to identify the associated memory
+ // on the receiving side. We hold a reference to the IMemory here to ensure it doesn't
+ // change underneath us.
+
+ struct IndexCache {
+ IndexCache() : mIndex(0) { }
+
+ // Returns the index of the IMemory stored in cache or 0 if not found.
+ uint64_t lookup(const sp<IMemory> &mem) {
+ auto p = mMemoryToIndex.find(mem.get());
+ if (p == mMemoryToIndex.end()) {
+ return 0;
+ }
+ if (MediaBuffer::isDeadObject(p->second.first)) {
+ // this object's dead
+ ALOGW("Attempting to lookup a dead IMemory");
+ (void)mMemoryToIndex.erase(p);
+ return 0;
+ }
+ ALOGW_IF(p->second.first.get() != mem.get(), "Mismatched buffers without reset");
+ return p->second.second;
+ }
+
+ // Returns the index of the IMemory stored in the index cache.
+ uint64_t insert(const sp<IMemory> &mem) {
+ auto p = mMemoryToIndex.find(mem.get());
+ if (p == mMemoryToIndex.end()) {
+ if (mIndex == UINT64_MAX) {
+ ALOGE("Index overflow");
+ mIndex = 1; // skip overflow condition and hope for the best
+ } else {
+ ++mIndex;
+ }
+ (void)mMemoryToIndex.emplace(// C++11 mem.get(), std::make_pair(mem, mIndex))
+ std::piecewise_construct,
+ std::forward_as_tuple(mem.get()), std::forward_as_tuple(mem, mIndex));
+ return mIndex;
+ }
+ ALOGW("IMemory already inserted into cache");
+ return p->second.second;
+ }
+
+ void reset() {
+ mMemoryToIndex.clear();
+ mIndex = 0;
+ }
+
+ void gc() {
+ for (auto it = mMemoryToIndex.begin(); it != mMemoryToIndex.end(); ) {
+ if (MediaBuffer::isDeadObject(it->second.first)) {
+ it = mMemoryToIndex.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+
+ private:
+ uint64_t mIndex;
+ // C++14 unordered_map erase on iterator is stable; C++11 has no guarantee.
+ // Could key on uintptr_t instead of IMemory *
+ std::map<IMemory *, std::pair<sp<IMemory>, uint64_t>> mMemoryToIndex;
+ } mIndexCache;
+};
+
+} // namespace android
+
+#endif // IMEDIA_SOURCE_BASE_H_
diff --git a/media/libmedia/include/IOMX.h b/media/libmedia/include/IOMX.h
new file mode 100644
index 0000000..39b9ad4
--- /dev/null
+++ b/media/libmedia/include/IOMX.h
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2009 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_IOMX_H_
+
+#define ANDROID_IOMX_H_
+
+#include <binder/IInterface.h>
+#include <utils/List.h>
+#include <utils/String8.h>
+#include <cutils/native_handle.h>
+
+#include <list>
+
+#include <media/hardware/MetadataBufferType.h>
+
+#include <OMX_Core.h>
+#include <OMX_Video.h>
+
+namespace android {
+
+class IGraphicBufferProducer;
+class IGraphicBufferSource;
+class IMemory;
+class IOMXBufferSource;
+class IOMXNode;
+class IOMXObserver;
+class NativeHandle;
+class OMXBuffer;
+struct omx_message;
+
+class IOMX : public IInterface {
+public:
+ DECLARE_META_INTERFACE(OMX);
+
+ typedef uint32_t buffer_id;
+
+ enum {
+ kFenceTimeoutMs = 1000
+ };
+
+ enum PortMode {
+ kPortModePresetStart = 0,
+ kPortModePresetByteBuffer,
+ kPortModePresetANWBuffer,
+ kPortModePresetSecureBuffer,
+ kPortModePresetEnd,
+
+ kPortModeDynamicStart = 100,
+ kPortModeDynamicANWBuffer, // uses metadata mode kMetadataBufferTypeANWBuffer
+ // or kMetadataBufferTypeGrallocSource
+ kPortModeDynamicNativeHandle, // uses metadata mode kMetadataBufferTypeNativeHandleSource
+ kPortModeDynamicEnd,
+ };
+
+ struct ComponentInfo {
+ String8 mName;
+ List<String8> mRoles;
+ };
+ virtual status_t listNodes(List<ComponentInfo> *list) = 0;
+
+ virtual status_t allocateNode(
+ const char *name, const sp<IOMXObserver> &observer,
+ sp<IOMXNode> *omxNode) = 0;
+
+ virtual status_t createInputSurface(
+ sp<IGraphicBufferProducer> *bufferProducer,
+ sp<IGraphicBufferSource> *bufferSource) = 0;
+};
+
+class IOMXNode : public IInterface {
+public:
+ DECLARE_META_INTERFACE(OMXNode);
+
+ typedef IOMX::buffer_id buffer_id;
+
+ virtual status_t freeNode() = 0;
+
+ virtual status_t sendCommand(
+ OMX_COMMANDTYPE cmd, OMX_S32 param) = 0;
+
+ virtual status_t getParameter(
+ OMX_INDEXTYPE index, void *params, size_t size) = 0;
+
+ virtual status_t setParameter(
+ OMX_INDEXTYPE index, const void *params, size_t size) = 0;
+
+ virtual status_t getConfig(
+ OMX_INDEXTYPE index, void *params, size_t size) = 0;
+
+ virtual status_t setConfig(
+ OMX_INDEXTYPE index, const void *params, size_t size) = 0;
+
+ virtual status_t setPortMode(
+ OMX_U32 port_index, IOMX::PortMode mode) = 0;
+
+ virtual status_t prepareForAdaptivePlayback(
+ OMX_U32 portIndex, OMX_BOOL enable,
+ OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) = 0;
+
+ virtual status_t configureVideoTunnelMode(
+ OMX_U32 portIndex, OMX_BOOL tunneled,
+ OMX_U32 audioHwSync, native_handle_t **sidebandHandle) = 0;
+
+ virtual status_t getGraphicBufferUsage(
+ OMX_U32 port_index, OMX_U32* usage) = 0;
+
+ virtual status_t setInputSurface(
+ const sp<IOMXBufferSource> &bufferSource) = 0;
+
+ // Allocate an opaque buffer as a native handle. If component supports returning native
+ // handles, those are returned in *native_handle. Otherwise, the allocated buffer is
+ // returned in *buffer_data. This clearly only makes sense if the caller lives in the
+ // same process as the callee, i.e. is the media_server, as the returned "buffer_data"
+ // pointer is just that, a pointer into local address space.
+ virtual status_t allocateSecureBuffer(
+ OMX_U32 port_index, size_t size, buffer_id *buffer,
+ void **buffer_data, sp<NativeHandle> *native_handle) = 0;
+
+ // Instructs the component to use the buffer passed in via |omxBuf| on the
+ // specified port. Returns in |*buffer| the buffer id that the component
+ // assigns to this buffer. |omxBuf| must be one of:
+ // 1) OMXBuffer::sPreset for meta-mode,
+ // 2) type kBufferTypeANWBuffer for non-meta-graphic buffer mode,
+ // 3) type kBufferTypeSharedMem for bytebuffer mode.
+ virtual status_t useBuffer(
+ OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) = 0;
+
+ // Frees the buffer on the specified port with buffer id |buffer|.
+ virtual status_t freeBuffer(
+ OMX_U32 port_index, buffer_id buffer) = 0;
+
+ // Calls OMX_FillBuffer on buffer. Passes |fenceFd| to component if it
+ // supports fences. Otherwise, it waits on |fenceFd| before calling
+ // OMX_FillBuffer. Takes ownership of |fenceFd| even if this call fails.
+ // If the port is in metadata mode, the buffer will be updated to point
+ // to the new buffer passed in via |omxBuf| before OMX_FillBuffer is called.
+ // Otherwise info in the |omxBuf| is not used.
+ virtual status_t fillBuffer(
+ buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd = -1) = 0;
+
+ // Calls OMX_EmptyBuffer on buffer. Passes |fenceFd| to component if it
+ // supports fences. Otherwise, it waits on |fenceFd| before calling
+ // OMX_EmptyBuffer. Takes ownership of |fenceFd| even if this call fails.
+ // If the port is in metadata mode, the buffer will be updated to point
+ // to the new buffer passed in via |omxBuf| before OMX_EmptyBuffer is called.
+ virtual status_t emptyBuffer(
+ buffer_id buffer, const OMXBuffer &omxBuf,
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd = -1) = 0;
+
+ virtual status_t getExtensionIndex(
+ const char *parameter_name,
+ OMX_INDEXTYPE *index) = 0;
+
+ virtual status_t dispatchMessage(const omx_message &msg) = 0;
+
+ // TODO: this is temporary, will be removed when quirks move to OMX side
+ virtual status_t setQuirks(OMX_U32 quirks) = 0;
+};
+
+struct omx_message {
+ enum {
+ EVENT,
+ EMPTY_BUFFER_DONE,
+ FILL_BUFFER_DONE,
+ FRAME_RENDERED,
+ } type;
+
+ int fenceFd; // used for EMPTY_BUFFER_DONE and FILL_BUFFER_DONE; client must close this
+
+ union {
+ // if type == EVENT
+ struct {
+ OMX_EVENTTYPE event;
+ OMX_U32 data1;
+ OMX_U32 data2;
+ OMX_U32 data3;
+ OMX_U32 data4;
+ } event_data;
+
+ // if type == EMPTY_BUFFER_DONE
+ struct {
+ IOMX::buffer_id buffer;
+ } buffer_data;
+
+ // if type == FILL_BUFFER_DONE
+ struct {
+ IOMX::buffer_id buffer;
+ OMX_U32 range_offset;
+ OMX_U32 range_length;
+ OMX_U32 flags;
+ OMX_TICKS timestamp;
+ } extended_buffer_data;
+
+ // if type == FRAME_RENDERED
+ struct {
+ OMX_TICKS timestamp;
+ OMX_S64 nanoTime;
+ } render_data;
+ } u;
+};
+
+class IOMXObserver : public IInterface {
+public:
+ DECLARE_META_INTERFACE(OMXObserver);
+
+ // Handle (list of) messages.
+ virtual void onMessages(const std::list<omx_message> &messages) = 0;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class BnOMX : public BnInterface<IOMX> {
+public:
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+};
+
+class BnOMXNode : public BnInterface<IOMXNode> {
+public:
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+
+protected:
+ // check if the codec is secure.
+ virtual bool isSecure() const {
+ return false;
+ }
+};
+
+class BnOMXObserver : public BnInterface<IOMXObserver> {
+public:
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+};
+
+} // namespace android
+
+#endif // ANDROID_IOMX_H_
diff --git a/media/libmedia/include/IRemoteDisplay.h b/media/libmedia/include/IRemoteDisplay.h
new file mode 100644
index 0000000..c8baae9
--- /dev/null
+++ b/media/libmedia/include/IRemoteDisplay.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2012 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_IREMOTEDISPLAY_H
+#define ANDROID_IREMOTEDISPLAY_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+/*
+ * Represents a remote display, such as a Wifi display.
+ *
+ * When the remote display is created, it may not yet be connected to the
+ * display. The remote display asynchronously reports events such as successful
+ * connection, disconnection and errors to an IRemoteDisplayClient interface provided by
+ * the client.
+ */
+class IRemoteDisplay : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(RemoteDisplay);
+
+ virtual status_t pause() = 0;
+ virtual status_t resume() = 0;
+
+ // Disconnects the remote display and stops listening for new connections.
+ virtual status_t dispose() = 0;
+};
+
+
+// ----------------------------------------------------------------------------
+
+class BnRemoteDisplay : public BnInterface<IRemoteDisplay>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IREMOTEDISPLAY_H
diff --git a/media/libmedia/include/IRemoteDisplayClient.h b/media/libmedia/include/IRemoteDisplayClient.h
new file mode 100644
index 0000000..0e6d55d
--- /dev/null
+++ b/media/libmedia/include/IRemoteDisplayClient.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2012 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_IREMOTEDISPLAYCLIENT_H
+#define ANDROID_IREMOTEDISPLAYCLIENT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+class IGraphicBufferProducer;
+
+class IRemoteDisplayClient : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(RemoteDisplayClient);
+
+ enum {
+ // Flag: The remote display is using a secure transport protocol such as HDCP.
+ kDisplayFlagSecure = 1 << 0,
+ };
+
+ enum {
+ // Error: An unknown / generic error occurred.
+ kDisplayErrorUnknown = 1,
+ // Error: The connection was dropped unexpectedly.
+ kDisplayErrorConnectionDropped = 2,
+ };
+
+ // Indicates that the remote display has been connected successfully.
+ // Provides a surface texture that the client should use to stream buffers to
+ // the remote display.
+ virtual void onDisplayConnected(const sp<IGraphicBufferProducer>& bufferProducer,
+ uint32_t width, uint32_t height, uint32_t flags, uint32_t session) = 0; // one-way
+
+ // Indicates that the remote display has been disconnected normally.
+ // This method should only be called once the client has called 'dispose()'
+ // on the IRemoteDisplay.
+ // It is currently an error for the display to disconnect for any other reason.
+ virtual void onDisplayDisconnected() = 0; // one-way
+
+ // Indicates that a connection could not be established to the remote display
+ // or an unrecoverable error occurred and the connection was severed.
+ virtual void onDisplayError(int32_t error) = 0; // one-way
+};
+
+
+// ----------------------------------------------------------------------------
+
+class BnRemoteDisplayClient : public BnInterface<IRemoteDisplayClient>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IREMOTEDISPLAYCLIENT_H
diff --git a/media/libmedia/include/IResourceManagerClient.h b/media/libmedia/include/IResourceManagerClient.h
new file mode 100644
index 0000000..aa0cd88
--- /dev/null
+++ b/media/libmedia/include/IResourceManagerClient.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2015 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_IRESOURCEMANAGERCLIENT_H
+#define ANDROID_IRESOURCEMANAGERCLIENT_H
+
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+class IResourceManagerClient: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(ResourceManagerClient);
+
+ virtual bool reclaimResource() = 0;
+ virtual String8 getName() = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnResourceManagerClient: public BnInterface<IResourceManagerClient>
+{
+public:
+ virtual status_t onTransact(uint32_t code,
+ const Parcel &data,
+ Parcel *reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IRESOURCEMANAGERCLIENT_H
diff --git a/media/libmedia/include/IResourceManagerService.h b/media/libmedia/include/IResourceManagerService.h
new file mode 100644
index 0000000..1e4f6de
--- /dev/null
+++ b/media/libmedia/include/IResourceManagerService.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2015 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_IRESOURCEMANAGERSERVICE_H
+#define ANDROID_IRESOURCEMANAGERSERVICE_H
+
+#include <utils/Errors.h> // for status_t
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+#include <media/IResourceManagerClient.h>
+#include <media/MediaResource.h>
+#include <media/MediaResourcePolicy.h>
+
+namespace android {
+
+class IResourceManagerService: public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(ResourceManagerService);
+
+ virtual void config(const Vector<MediaResourcePolicy> &policies) = 0;
+
+ virtual void addResource(
+ int pid,
+ int64_t clientId,
+ const sp<IResourceManagerClient> client,
+ const Vector<MediaResource> &resources) = 0;
+
+ virtual void removeResource(int pid, int64_t clientId) = 0;
+
+ virtual bool reclaimResource(
+ int callingPid,
+ const Vector<MediaResource> &resources) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnResourceManagerService: public BnInterface<IResourceManagerService>
+{
+public:
+ virtual status_t onTransact(uint32_t code,
+ const Parcel &data,
+ Parcel *reply,
+ uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_IRESOURCEMANAGERSERVICE_H
diff --git a/media/libmedia/include/IStreamSource.h b/media/libmedia/include/IStreamSource.h
new file mode 100644
index 0000000..4a6aafd
--- /dev/null
+++ b/media/libmedia/include/IStreamSource.h
@@ -0,0 +1,111 @@
+/*
+ * 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_ISTREAMSOURCE_H_
+
+#define ANDROID_ISTREAMSOURCE_H_
+
+#include <binder/IInterface.h>
+
+namespace android {
+
+struct AMessage;
+class IMemory;
+struct IStreamListener;
+
+struct IStreamSource : public IInterface {
+ DECLARE_META_INTERFACE(StreamSource);
+
+ virtual void setListener(const sp<IStreamListener> &listener) = 0;
+ virtual void setBuffers(const Vector<sp<IMemory> > &buffers) = 0;
+
+ virtual void onBufferAvailable(size_t index) = 0;
+
+ enum {
+ // Video PES packets contain exactly one (aligned) access unit.
+ kFlagAlignedVideoData = 1,
+
+ // Timestamps are in ALooper::GetNowUs() units.
+ kFlagIsRealTimeData = 2,
+ };
+ virtual uint32_t flags() const { return 0; }
+};
+
+struct IStreamListener : public IInterface {
+ DECLARE_META_INTERFACE(StreamListener);
+
+ enum Command {
+ EOS,
+ DISCONTINUITY,
+ };
+
+ virtual void queueBuffer(size_t index, size_t size) = 0;
+
+ // When signalling a discontinuity you can optionally
+ // specify an int64_t PTS timestamp in "msg".
+ // If present, rendering of data following the discontinuity
+ // will be suppressed until media time reaches this timestamp.
+ static const char *const kKeyResumeAtPTS;
+
+ // When signalling a discontinuity you can optionally
+ // specify the type(s) of discontinuity, i.e. if the
+ // audio format has changed, the video format has changed,
+ // time has jumped or any combination thereof.
+ // To do so, include a non-zero int32_t value
+ // under the key "kKeyDiscontinuityMask" when issuing the DISCONTINUITY
+ // command.
+ // If there is a change in audio/video format, The new logical stream
+ // must start with proper codec initialization
+ // information for playback to continue, i.e. SPS and PPS in the case
+ // of AVC video etc.
+ // If this key is not present, only a time discontinuity is assumed.
+ // The value should be a bitmask of values from
+ // ATSParser::DiscontinuityType.
+ static const char *const kKeyDiscontinuityMask;
+
+ // Optionally signalled as part of a discontinuity that includes
+ // DISCONTINUITY_TIME. It indicates the media time (in us) to be associated
+ // with the next PTS occuring in the stream. The value is of type int64_t.
+ static const char *const kKeyMediaTimeUs;
+
+ // Optionally signalled as part of a discontinuity that includes
+ // DISCONTINUITY_TIME. It indicates the media time (in us) of a recent
+ // sample from the same content, and is used as a hint for the parser to
+ // handle PTS wraparound. This is required when a new parser is created
+ // to continue parsing content from the same timeline.
+ static const char *const kKeyRecentMediaTimeUs;
+
+ virtual void issueCommand(
+ Command cmd, bool synchronous, const sp<AMessage> &msg = NULL) = 0;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct BnStreamSource : public BnInterface<IStreamSource> {
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+};
+
+struct BnStreamListener : public BnInterface<IStreamListener> {
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+};
+
+} // namespace android
+
+#endif // ANDROID_ISTREAMSOURCE_H_
diff --git a/media/libmedia/include/JetPlayer.h b/media/libmedia/include/JetPlayer.h
new file mode 100644
index 0000000..63d1980
--- /dev/null
+++ b/media/libmedia/include/JetPlayer.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008 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 JETPLAYER_H_
+#define JETPLAYER_H_
+
+#include <utils/threads.h>
+
+#include <libsonivox/jet.h>
+#include <libsonivox/eas_types.h>
+#include <media/AudioTrack.h>
+#include <media/MidiIoWrapper.h>
+
+
+namespace android {
+
+typedef void (*jetevent_callback)(int eventType, int val1, int val2, void *cookie);
+
+class JetPlayer {
+
+public:
+
+ // to keep in sync with the JetPlayer class constants
+ // defined in frameworks/base/media/java/android/media/JetPlayer.java
+ static const int JET_EVENT = 1;
+ static const int JET_USERID_UPDATE = 2;
+ static const int JET_NUMQUEUEDSEGMENT_UPDATE = 3;
+ static const int JET_PAUSE_UPDATE = 4;
+
+ JetPlayer(void *javaJetPlayer,
+ int maxTracks = 32,
+ int trackBufferSize = 1200);
+ ~JetPlayer();
+ int init();
+ int release();
+
+ int loadFromFile(const char* url);
+ int loadFromFD(const int fd, const long long offset, const long long length);
+ int closeFile();
+ int play();
+ int pause();
+ int queueSegment(int segmentNum, int libNum, int repeatCount, int transpose,
+ EAS_U32 muteFlags, EAS_U8 userID);
+ int setMuteFlags(EAS_U32 muteFlags, bool sync);
+ int setMuteFlag(int trackNum, bool muteFlag, bool sync);
+ int triggerClip(int clipId);
+ int clearQueue();
+
+ void setEventCallback(jetevent_callback callback);
+
+ int getMaxTracks() { return mMaxTracks; };
+
+
+private:
+ int render();
+ void fireUpdateOnStatusChange();
+ void fireEventsFromJetQueue();
+
+ JetPlayer() {} // no default constructor
+ void dump();
+ void dumpJetStatus(S_JET_STATUS* pJetStatus);
+
+ jetevent_callback mEventCallback;
+
+ void* mJavaJetPlayerRef;
+ Mutex mMutex; // mutex to sync the render and playback thread with the JET calls
+ pid_t mTid;
+ Condition mCondition;
+ volatile bool mRender;
+ bool mPaused;
+
+ EAS_STATE mState;
+ int* mMemFailedVar;
+
+ int mMaxTracks; // max number of MIDI tracks, usually 32
+ EAS_DATA_HANDLE mEasData;
+ sp<MidiIoWrapper> mIoWrapper;
+ EAS_PCM* mAudioBuffer;// EAS renders the MIDI data into this buffer,
+ sp<AudioTrack> mAudioTrack; // and we play it in this audio track
+ int mTrackBufferSize;
+ S_JET_STATUS mJetStatus;
+ S_JET_STATUS mPreviousJetStatus;
+
+ class JetPlayerThread : public Thread {
+ public:
+ JetPlayerThread(JetPlayer *player) : mPlayer(player) {
+ }
+
+ protected:
+ virtual ~JetPlayerThread() {}
+
+ private:
+ JetPlayer *mPlayer;
+
+ bool threadLoop() {
+ int result;
+ result = mPlayer->render();
+ return false;
+ }
+
+ JetPlayerThread(const JetPlayerThread &);
+ JetPlayerThread &operator=(const JetPlayerThread &);
+ };
+
+ sp<JetPlayerThread> mThread;
+
+}; // end class JetPlayer
+
+} // end namespace android
+
+
+
+#endif /*JETPLAYER_H_*/
diff --git a/media/libmedia/include/LinearMap.h b/media/libmedia/include/LinearMap.h
new file mode 100644
index 0000000..2220a0c
--- /dev/null
+++ b/media/libmedia/include/LinearMap.h
@@ -0,0 +1,366 @@
+/*
+ * Copyright 2015 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_LINEAR_MAP_H
+#define ANDROID_LINEAR_MAP_H
+
+#include <stdint.h>
+
+namespace android {
+
+/*
+A general purpose lookup utility that defines a mapping between X and Y as a
+continuous set of line segments with shared (x, y) end-points.
+The (x, y) points must be added in order, monotonically increasing in both x and y;
+a log warning is emitted if this does not happen (See general usage notes below).
+
+A limited history of (x, y) points is kept for space reasons (See general usage notes).
+
+In AudioFlinger, we use the LinearMap to associate track frames to
+sink frames. When we want to obtain a client track timestamp, we first
+get a timestamp from the sink. The sink timestamp's position (mPosition)
+corresponds to the sink frames written. We use LinearMap to figure out which track frame
+the sink frame corresponds to. This allows us to substitute a track frame for the
+the sink frame (keeping the mTime identical) and return that timestamp back to the client.
+
+The method findX() can be used to retrieve an x value from a given y value and is
+used for timestamps, similarly for findY() which is provided for completeness.
+
+We update the (track frame, sink frame) points in the LinearMap each time we write data
+to the sink by the AudioFlinger PlaybackThread (MixerThread).
+
+
+AudioFlinger Timestamp Notes:
+
+1) Example: Obtaining a track timestamp during playback. In this case, the LinearMap
+looks something like this:
+
+Track Frame Sink Frame
+(track start)
+0 50000 (track starts here, the sink may already be running)
+1000 51000
+2000 52000
+
+When we request a track timestamp, we call the sink getTimestamp() and get for example
+mPosition = 51020. Using the LinearMap, we find we have played to track frame 1020.
+We substitute the sink mPosition of 51020 with the track position 1020,
+and return that timestamp to the app.
+
+2) Example: Obtaining a track timestamp duing pause. In this case, the LinearMap
+looks something like this:
+
+Track Frame Sink Frame
+... (some time has gone by)
+15000 30000
+16000 31000
+17000 32000
+(pause here)
+(suppose we call sink getTimestamp() here and get sink mPosition = 31100; that means
+ we have played to track frame 16100. The track timestamp mPosition will
+ continue to advance until the sink timestamp returns a value of mPosition
+ greater than 32000, corresponding to track frame 17000 when the pause was called).
+17000 33000
+17000 34000
+...
+
+3) If the track underruns, it appears as if a pause was called on that track.
+
+4) If there is an underrun in the HAL layer, then it may be possible that
+the sink getTimestamp() will return a value greater than the number of frames written
+(it should always be less). This should be rare, if not impossible by some
+HAL implementations of the sink getTimestamp. In that case, timing is lost
+and we will return the most recent track frame written.
+
+5) When called with no points in the map, findX() returns the start value (default 0).
+This is consistent with starting after a stop() or flush().
+
+6) Resuming after Track standby will be similar to coming out of pause, as the HAL ensures
+framesWritten() and getTimestamp() are contiguous for non-offloaded/direct tracks.
+
+7) LinearMap works for different speeds and sample rates as it uses
+linear interpolation. Since AudioFlinger only updates speed and sample rate
+exactly at the sample points pushed into the LinearMap, the returned values
+from findX() and findY() are accurate regardless of how many speed or sample
+rate changes are made, so long as the coordinate looked up is within the
+sample history.
+
+General usage notes:
+
+1) In order for the LinearMap to work reliably, you cannot look backwards more
+than the size of its circular buffer history, set upon creation (typically 16).
+If you look back further, the position is extrapolated either from a passed in
+extrapolation parameter or from the oldest line segment.
+
+2) Points must monotonically increase in x and y. The increment between adjacent
+points cannot be greater than signed 32 bits. Wrap in the x, y coordinates are supported,
+since we use differences in our computation.
+
+3) If the frame data is discontinuous (due to stop or flush) call reset() to clear
+the sample counter.
+
+4) If (x, y) are not strictly monotonic increasing, i.e. (x2 > x1) and (y2 > y1),
+then one or both of the inverses y = f(x) or x = g(y) may have multiple solutions.
+In that case, the most recent solution is returned by findX() or findY(). We
+do not warn if (x2 == x1) or (y2 == y1), but we do logcat warn if (x2 < x1) or
+(y2 < y1).
+
+5) Due to rounding it is possible x != findX(findY(x)) or y != findY(findX(y))
+even when the inverse exists. Nevertheless, the values should be close.
+
+*/
+
+template <typename T>
+class LinearMap {
+public:
+ // This enumeration describes the reliability of the findX() or findY() estimation
+ // in descending order.
+ enum FindMethod {
+ FIND_METHOD_INTERPOLATION, // High reliability (errors due to rounding)
+ FIND_METHOD_FORWARD_EXTRAPOLATION, // Reliability based on no future speed changes
+ FIND_METHOD_BACKWARD_EXTRAPOLATION, // Reliability based on prior estimated speed
+ FIND_METHOD_START_VALUE, // No samples in history, using start value
+ };
+
+ explicit LinearMap(size_t size)
+ : mSize(size),
+ mPos(0), // a circular buffer, so could start anywhere. the first sample is at 1.
+ mSamples(0),
+ // mStepValid(false), // only valid if mSamples > 1
+ // mExtrapolateTail(false), // only valid if mSamples > 0
+ mX(new T[size]),
+ mY(new T[size]) { }
+
+ ~LinearMap() {
+ delete[] mX;
+ delete[] mY;
+ }
+
+ // Add a new sample point to the linear map.
+ //
+ // The difference between the new sample and the previous sample
+ // in the x or y coordinate must be less than INT32_MAX for purposes
+ // of the linear interpolation or extrapolation.
+ //
+ // The value should be monotonic increasing (e.g. diff >= 0);
+ // logcat warnings are issued if they are not.
+ __attribute__((no_sanitize("integer")))
+ void push(T x, T y) {
+ // Assumption: we assume x, y are monotonic increasing values,
+ // which (can) wrap in precision no less than 32 bits and have
+ // "step" or differences between adjacent points less than 32 bits.
+
+ if (mSamples > 0) {
+ const bool lastStepValid = mStepValid;
+ int32_t xdiff;
+ int32_t ydiff;
+ // check difference assumption here
+ mStepValid = checkedDiff(&xdiff, x, mX[mPos], "x")
+ & /* bitwise AND to always warn for ydiff, though logical AND is also OK */
+ checkedDiff(&ydiff, y, mY[mPos], "y");
+
+ // Optimization: do not add a new sample if the line segment would
+ // simply extend the previous line segment. This extends the useful
+ // history by removing redundant points.
+ if (mSamples > 1 && mStepValid && lastStepValid) {
+ const size_t prev = previousPosition();
+ const int32_t xdiff2 = x - mX[prev];
+ const int32_t ydiff2 = y - mY[prev];
+
+ // if both current step and previous step are valid (non-negative and
+ // less than INT32_MAX for precision greater than 4 bytes)
+ // then the sum of the two steps is valid when the
+ // int32_t difference is non-negative.
+ if (xdiff2 >= 0 && ydiff2 >= 0
+ && (int64_t)xdiff2 * ydiff == (int64_t)ydiff2 * xdiff) {
+ // ALOGD("reusing sample! (%u, %u) sample depth %zd", x, y, mSamples);
+ mX[mPos] = x;
+ mY[mPos] = y;
+ return;
+ }
+ }
+ }
+ if (++mPos >= mSize) {
+ mPos = 0;
+ }
+ if (mSamples < mSize) {
+ mExtrapolateTail = false;
+ ++mSamples;
+ } else {
+ // we enable extrapolation beyond the oldest sample
+ // if the sample buffers are completely full and we
+ // no longer know the full history.
+ mExtrapolateTail = true;
+ }
+ mX[mPos] = x;
+ mY[mPos] = y;
+ }
+
+ // clear all samples from the circular array
+ void reset() {
+ // no need to reset mPos, we use a circular buffer.
+ // computed values such as mStepValid are set after a subsequent push().
+ mSamples = 0;
+ }
+
+ // returns true if LinearMap contains at least one sample.
+ bool hasData() const {
+ return mSamples != 0;
+ }
+
+ // find the corresponding X point from a Y point.
+ // See findU for details.
+ __attribute__((no_sanitize("integer")))
+ T findX(T y, FindMethod *method = NULL, double extrapolation = 0.0, T startValue = 0) const {
+ return findU(y, mX, mY, method, extrapolation, startValue);
+ }
+
+ // find the corresponding Y point from a X point.
+ // See findU for details.
+ __attribute__((no_sanitize("integer")))
+ T findY(T x, FindMethod *method = NULL, double extrapolation = 0.0, T startValue = 0) const {
+ return findU(x, mY, mX, method, extrapolation, startValue);
+ }
+
+protected:
+
+ // returns false if the diff is out of int32_t bounds or negative.
+ __attribute__((no_sanitize("integer")))
+ static inline bool checkedDiff(int32_t *diff, T x2, T x1, const char *coord) {
+ if (sizeof(T) >= 8) {
+ const int64_t diff64 = x2 - x1;
+ *diff = (int32_t)diff64; // intentionally lose precision
+ if (diff64 > INT32_MAX) {
+ ALOGW("LinearMap: %s overflow diff(%lld) from %llu - %llu exceeds INT32_MAX",
+ coord, (long long)diff64,
+ (unsigned long long)x2, (unsigned long long)x1);
+ return false;
+ } else if (diff64 < 0) {
+ ALOGW("LinearMap: %s negative diff(%lld) from %llu - %llu",
+ coord, (long long)diff64,
+ (unsigned long long)x2, (unsigned long long)x1);
+ return false;
+ }
+ return true;
+ }
+ // for 32 bit integers we cannot detect overflow (it
+ // shows up as a negative difference).
+ *diff = x2 - x1;
+ if (*diff < 0) {
+ ALOGW("LinearMap: %s negative diff(%d) from %u - %u",
+ coord, *diff, (unsigned)x2, (unsigned)x1);
+ return false;
+ }
+ return true;
+ }
+
+ // Returns the previous position in the mSamples array
+ // going backwards back steps.
+ //
+ // Parameters:
+ // back: number of backward steps, cannot be less than zero or greater than mSamples.
+ //
+ __attribute__((no_sanitize("integer")))
+ size_t previousPosition(ssize_t back = 1) const {
+ LOG_ALWAYS_FATAL_IF(back < 0 || (size_t)back > mSamples, "Invalid back(%zd)", back);
+ ssize_t position = mPos - back;
+ if (position < 0) position += mSize;
+ return (size_t)position;
+ }
+
+ // A generic implementation of finding the "other coordinate" with coordinates
+ // (u, v) = (x, y) or (u, v) = (y, x).
+ //
+ // Parameters:
+ // uArray: the u axis samples.
+ // vArray: the v axis samples.
+ // method: [out] how the returned value was computed.
+ // extrapolation: the slope used when extrapolating from the
+ // first sample value or the last sample value in the history.
+ // If mExtrapolateTail is set, the slope of the last line segment
+ // is used if the extrapolation parameter is zero to continue the tail of history.
+ // At this time, we do not use a different value for forward extrapolation from the
+ // head of history from backward extrapolation from the tail of history.
+ // TODO: back extrapolation value could be stored along with mX, mY in history.
+ // startValue: used only when there are no samples in history. One can detect
+ // whether there are samples in history by the method hasData().
+ //
+ __attribute__((no_sanitize("integer")))
+ T findU(T v, T *uArray, T *vArray, FindMethod *method,
+ double extrapolation, T startValue) const {
+ if (mSamples == 0) {
+ if (method != NULL) {
+ *method = FIND_METHOD_START_VALUE;
+ }
+ return startValue; // nothing yet
+ }
+ ssize_t previous = 0;
+ int32_t diff = 0;
+ for (ssize_t i = 0; i < (ssize_t)mSamples; ++i) {
+ size_t current = previousPosition(i);
+
+ // Assumption: even though the type "T" may have precision greater
+ // than 32 bits, the difference between adjacent points is limited to 32 bits.
+ diff = v - vArray[current];
+ if (diff >= 0 ||
+ (i == (ssize_t)mSamples - 1 && mExtrapolateTail && extrapolation == 0.0)) {
+ // ALOGD("depth = %zd out of %zd", i, limit);
+ if (i == 0) {
+ if (method != NULL) {
+ *method = FIND_METHOD_FORWARD_EXTRAPOLATION;
+ }
+ return uArray[current] + diff * extrapolation;
+ }
+ // interpolate / extrapolate: For this computation, we
+ // must use differentials here otherwise we have inconsistent
+ // values on modulo wrap. previous is always valid here since
+ // i > 0. we also perform rounding with the assumption
+ // that uStep, vStep, and diff are non-negative.
+ int32_t uStep = uArray[previous] - uArray[current]; // non-negative
+ int32_t vStep = vArray[previous] - vArray[current]; // positive
+ T u = uStep <= 0 || vStep <= 0 ? // we do not permit negative ustep or vstep
+ uArray[current]
+ : ((int64_t)diff * uStep + (vStep >> 1)) / vStep + uArray[current];
+ // ALOGD("u:%u diff:%d uStep:%d vStep:%d u_current:%d",
+ // u, diff, uStep, vStep, uArray[current]);
+ if (method != NULL) {
+ *method = (diff >= 0) ?
+ FIND_METHOD_INTERPOLATION : FIND_METHOD_BACKWARD_EXTRAPOLATION;
+ }
+ return u;
+ }
+ previous = current;
+ }
+ // previous is always valid here.
+ if (method != NULL) {
+ *method = FIND_METHOD_BACKWARD_EXTRAPOLATION;
+ }
+ return uArray[previous] + diff * extrapolation;
+ }
+
+private:
+ const size_t mSize; // Size of mX and mY arrays (history).
+ size_t mPos; // Index in mX and mY of last pushed data;
+ // (incremented after push) [0, mSize - 1].
+ size_t mSamples; // Number of valid samples in the array [0, mSize].
+ bool mStepValid; // Last sample step was valid (non-negative)
+ bool mExtrapolateTail; // extrapolate tail using oldest line segment
+ T * const mX; // History of X values as a circular array.
+ T * const mY; // History of Y values as a circular array.
+};
+
+} // namespace android
+
+#endif // ANDROID_LINEAR_MAP_H
diff --git a/media/libmedia/include/MediaAnalyticsItem.h b/media/libmedia/include/MediaAnalyticsItem.h
new file mode 100644
index 0000000..f050e7f
--- /dev/null
+++ b/media/libmedia/include/MediaAnalyticsItem.h
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2016 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_MEDIA_MEDIAANALYTICSITEM_H
+#define ANDROID_MEDIA_MEDIAANALYTICSITEM_H
+
+#include <cutils/properties.h>
+#include <sys/types.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+#include <utils/StrongPointer.h>
+#include <utils/Timers.h>
+
+#include <media/stagefright/foundation/AString.h>
+
+namespace android {
+
+
+
+class IMediaAnalyticsService;
+
+// the class interface
+//
+
+class MediaAnalyticsItem {
+
+ friend class MediaAnalyticsService;
+ friend class IMediaAnalyticsService;
+ friend class MediaMetricsJNI;
+
+ public:
+
+ enum Type {
+ kTypeNone = 0,
+ kTypeInt32 = 1,
+ kTypeInt64 = 2,
+ kTypeDouble = 3,
+ kTypeCString = 4,
+ kTypeRate = 5,
+ };
+
+ // sessionid
+ // unique within device, within boot,
+ typedef int64_t SessionID_t;
+ static constexpr SessionID_t SessionIDInvalid = -1;
+ static constexpr SessionID_t SessionIDNone = 0;
+
+ // Key: the record descriminator
+ // values for the record discriminator
+ // values can be "component/component"
+ // basic values: "video", "audio", "drm"
+ // XXX: need to better define the format
+ typedef AString Key;
+ static const Key kKeyNone; // ""
+ static const Key kKeyAny; // "*"
+
+ // Attr: names for attributes within a record
+ // format "prop1" or "prop/subprop"
+ // XXX: need to better define the format
+ typedef const char *Attr;
+
+
+ public:
+
+ // access functions for the class
+ MediaAnalyticsItem();
+ MediaAnalyticsItem(Key);
+ ~MediaAnalyticsItem();
+
+ // so clients can send intermediate values to be overlaid later
+ MediaAnalyticsItem &setFinalized(bool);
+ bool getFinalized() const;
+
+ // SessionID ties multiple submissions for same key together
+ // so that if video "height" and "width" are known at one point
+ // and "framerate" is only known later, they can be be brought
+ // together.
+ MediaAnalyticsItem &setSessionID(SessionID_t);
+ MediaAnalyticsItem &clearSessionID();
+ SessionID_t getSessionID() const;
+ // generates and stores a new ID iff mSessionID == SessionIDNone
+ SessionID_t generateSessionID();
+
+ // reset all contents, discarding any extra data
+ void clear();
+ MediaAnalyticsItem *dup();
+
+ // set the key discriminator for the record.
+ // most often initialized as part of the constructor
+ MediaAnalyticsItem &setKey(MediaAnalyticsItem::Key);
+ MediaAnalyticsItem::Key getKey();
+
+ // # of attributes in the record
+ int32_t count() const;
+
+ // set values appropriately
+ void setInt32(Attr, int32_t value);
+ void setInt64(Attr, int64_t value);
+ void setDouble(Attr, double value);
+ void setRate(Attr, int64_t count, int64_t duration);
+ void setCString(Attr, const char *value);
+
+ // fused get/add/set; if attr wasn't there, it's a simple set.
+ // type-mismatch counts as "wasn't there".
+ void addInt32(Attr, int32_t value);
+ void addInt64(Attr, int64_t value);
+ void addDouble(Attr, double value);
+ void addRate(Attr, int64_t count, int64_t duration);
+
+ // find & extract values
+ // return indicates whether attr exists (and thus value filled in)
+ // NULL parameter value suppresses storage of value.
+ bool getInt32(Attr, int32_t *value);
+ bool getInt64(Attr, int64_t *value);
+ bool getDouble(Attr, double *value);
+ bool getRate(Attr, int64_t *count, int64_t *duration, double *rate);
+ // Caller owns the returned string
+ bool getCString(Attr, char **value);
+
+ // parameter indicates whether to close any existing open
+ // record with same key before establishing a new record
+ // caller retains ownership of 'this'.
+ bool selfrecord(bool);
+ bool selfrecord();
+
+ // remove indicated attributes and their values
+ // filterNot() could also be called keepOnly()
+ // return value is # attributes removed
+ // XXX: perhaps 'remove' instead of 'filter'
+ // XXX: filterNot would become 'keep'
+ int32_t filter(int count, Attr attrs[]);
+ int32_t filterNot(int count, Attr attrs[]);
+ int32_t filter(Attr attr);
+
+ // below here are used on server side or to talk to server
+ // clients need not worry about these.
+
+ // timestamp, pid, and uid only used on server side
+ // timestamp is in 'nanoseconds, unix time'
+ MediaAnalyticsItem &setTimestamp(nsecs_t);
+ nsecs_t getTimestamp() const;
+
+ MediaAnalyticsItem &setPid(pid_t);
+ pid_t getPid() const;
+
+ MediaAnalyticsItem &setUid(uid_t);
+ uid_t getUid() const;
+
+ // our serialization code for binder calls
+ int32_t writeToParcel(Parcel *);
+ int32_t readFromParcel(const Parcel&);
+
+ AString toString();
+
+ // are we collecting analytics data
+ static bool isEnabled();
+
+ protected:
+
+ // merge fields from arg into this
+ // with rules for first/last/add, etc
+ // XXX: document semantics and how they are indicated
+ // caller continues to own 'incoming'
+ bool merge(MediaAnalyticsItem *incoming);
+
+ // enabled 1, disabled 0
+ static const char * const EnabledProperty;
+ static const char * const EnabledPropertyPersist;
+ static const int EnabledProperty_default;
+
+ private:
+
+ // to help validate that A doesn't mess with B's records
+ pid_t mPid;
+ uid_t mUid;
+
+ // let's reuse a binder connection
+ static sp<IMediaAnalyticsService> sAnalyticsService;
+ static sp<IMediaAnalyticsService> getInstance();
+
+ // tracking information
+ SessionID_t mSessionID; // grouping similar records
+ nsecs_t mTimestamp; // ns, system_time_monotonic
+
+ // will this record accept further updates
+ bool mFinalized;
+
+ Key mKey;
+
+ struct Prop {
+
+ Type mType;
+ const char *mName;
+ size_t mNameLen; // the strlen(), doesn't include the null
+ union {
+ int32_t int32Value;
+ int64_t int64Value;
+ double doubleValue;
+ char *CStringValue;
+ struct { int64_t count, duration; } rate;
+ } u;
+ void setName(const char *name, size_t len);
+ };
+
+ void initProp(Prop *item);
+ void clearProp(Prop *item);
+ void clearPropValue(Prop *item);
+ void copyProp(Prop *dst, const Prop *src);
+ enum {
+ kGrowProps = 10
+ };
+ void growProps(int increment = kGrowProps);
+ size_t findPropIndex(const char *name, size_t len);
+ Prop *findProp(const char *name);
+ Prop *allocateProp(const char *name);
+
+ size_t mPropCount;
+ size_t mPropSize;
+ Prop *mProps;
+
+};
+
+} // namespace android
+
+#endif
diff --git a/media/libmedia/include/MediaCodecBuffer.h b/media/libmedia/include/MediaCodecBuffer.h
new file mode 100644
index 0000000..501c00b
--- /dev/null
+++ b/media/libmedia/include/MediaCodecBuffer.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2016, 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 MEDIA_CODEC_BUFFER_H_
+
+#define MEDIA_CODEC_BUFFER_H_
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+struct ABuffer;
+struct AMessage;
+class MediaBufferBase;
+
+/**
+ * Buffers used by MediaCodec.
+ */
+class MediaCodecBuffer : public RefBase {
+public:
+ MediaCodecBuffer(const sp<AMessage> &format, const sp<ABuffer> &buffer);
+
+ /**
+ * MediaCodec will release all references to the buffer when it's done using
+ * it, so the destructor should return the buffer to the owner, such as OMX
+ * components, buffer allocators, surfaces, etc.
+ */
+ virtual ~MediaCodecBuffer() = default;
+
+ // ABuffer-like interface
+ uint8_t *base();
+ uint8_t *data();
+ size_t capacity() const;
+ size_t size() const;
+ size_t offset() const;
+ // Default implementation calls ABuffer::setRange() and returns OK.
+ virtual status_t setRange(size_t offset, size_t size);
+ // TODO: These can be removed if we finish replacing all MediaBuffer's.
+ MediaBufferBase *getMediaBufferBase();
+ void setMediaBufferBase(MediaBufferBase *mediaBuffer);
+
+ // TODO: Specify each field for meta/format.
+ sp<AMessage> meta();
+ sp<AMessage> format();
+
+ void setFormat(const sp<AMessage> &format);
+
+private:
+ MediaCodecBuffer() = delete;
+
+ const sp<AMessage> mMeta;
+ sp<AMessage> mFormat;
+ const sp<ABuffer> mBuffer;
+ MediaBufferBase *mMediaBufferBase;
+};
+
+} // namespace android
+
+#endif // MEDIA_CODEC_BUFFER_H_
diff --git a/media/libmedia/include/MediaCodecInfo.h b/media/libmedia/include/MediaCodecInfo.h
new file mode 100644
index 0000000..6b50f22
--- /dev/null
+++ b/media/libmedia/include/MediaCodecInfo.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_CODEC_INFO_H_
+
+#define MEDIA_CODEC_INFO_H_
+
+#include <binder/Parcel.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AString.h>
+
+#include <sys/types.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+struct AMessage;
+class Parcel;
+
+typedef KeyedVector<AString, AString> CodecSettings;
+
+struct MediaCodecInfo : public RefBase {
+ struct ProfileLevel {
+ uint32_t mProfile;
+ uint32_t mLevel;
+ };
+
+ struct Capabilities : public RefBase {
+ enum {
+ // decoder flags
+ kFlagSupportsAdaptivePlayback = 1 << 0,
+ kFlagSupportsSecurePlayback = 1 << 1,
+ kFlagSupportsTunneledPlayback = 1 << 2,
+
+ // encoder flags
+ kFlagSupportsIntraRefresh = 1 << 0,
+
+ };
+
+ void getSupportedProfileLevels(Vector<ProfileLevel> *profileLevels) const;
+ void getSupportedColorFormats(Vector<uint32_t> *colorFormats) const;
+ uint32_t getFlags() const;
+ const sp<AMessage> getDetails() const;
+
+ protected:
+ Vector<ProfileLevel> mProfileLevels;
+ Vector<uint32_t> mColorFormats;
+ uint32_t mFlags;
+ sp<AMessage> mDetails;
+
+ Capabilities();
+
+ private:
+ // read object from parcel even if object creation fails
+ static sp<Capabilities> FromParcel(const Parcel &parcel);
+ status_t writeToParcel(Parcel *parcel) const;
+
+ DISALLOW_EVIL_CONSTRUCTORS(Capabilities);
+
+ friend struct MediaCodecInfo;
+ };
+
+ // Use a subclass to allow setting fields on construction without allowing
+ // to do the same throughout the framework.
+ struct CapabilitiesBuilder : public Capabilities {
+ void addProfileLevel(uint32_t profile, uint32_t level);
+ void addColorFormat(uint32_t format);
+ void addFlags(uint32_t flags);
+ };
+
+ bool isEncoder() const;
+ bool hasQuirk(const char *name) const;
+ void getSupportedMimes(Vector<AString> *mimes) const;
+ const sp<Capabilities> getCapabilitiesFor(const char *mime) const;
+ const char *getCodecName() const;
+
+ /**
+ * Serialization over Binder
+ */
+ static sp<MediaCodecInfo> FromParcel(const Parcel &parcel);
+ status_t writeToParcel(Parcel *parcel) const;
+
+private:
+ // variable set only in constructor - these are accessed by MediaCodecList
+ // to avoid duplication of same variables
+ AString mName;
+ bool mIsEncoder;
+ bool mHasSoleMime; // was initialized with mime
+
+ Vector<AString> mQuirks;
+ KeyedVector<AString, sp<Capabilities> > mCaps;
+
+ sp<Capabilities> mCurrentCaps; // currently initalized capabilities
+
+ ssize_t getCapabilityIndex(const char *mime) const;
+
+ /* Methods used by MediaCodecList to construct the info
+ * object from XML.
+ *
+ * After info object is created:
+ * - additional quirks can be added
+ * - additional mimes can be added
+ * - OMX codec capabilities can be set for the current mime-type
+ * - a capability detail can be set for the current mime-type
+ * - a feature can be set for the current mime-type
+ * - info object can be completed when parsing of a mime-type is done
+ */
+ MediaCodecInfo(AString name, bool encoder, const char *mime);
+ void addQuirk(const char *name);
+ status_t addMime(const char *mime);
+ status_t updateMime(const char *mime);
+
+ status_t initializeCapabilities(const sp<Capabilities> &caps);
+ void addDetail(const AString &key, const AString &value);
+ void addFeature(const AString &key, int32_t value);
+ void addFeature(const AString &key, const char *value);
+ void removeMime(const char *mime);
+ void complete();
+
+ DISALLOW_EVIL_CONSTRUCTORS(MediaCodecInfo);
+
+ friend struct MediaCodecList;
+ friend class MediaCodecListOverridesTest;
+};
+
+} // namespace android
+
+#endif // MEDIA_CODEC_INFO_H_
+
+
diff --git a/media/libmedia/include/MediaDefs.h b/media/libmedia/include/MediaDefs.h
new file mode 100644
index 0000000..7f17013
--- /dev/null
+++ b/media/libmedia/include/MediaDefs.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2009 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 MEDIA_DEFS_H_
+
+#define MEDIA_DEFS_H_
+
+namespace android {
+
+extern const char *MEDIA_MIMETYPE_IMAGE_JPEG;
+
+extern const char *MEDIA_MIMETYPE_VIDEO_VP8;
+extern const char *MEDIA_MIMETYPE_VIDEO_VP9;
+extern const char *MEDIA_MIMETYPE_VIDEO_AVC;
+extern const char *MEDIA_MIMETYPE_VIDEO_HEVC;
+extern const char *MEDIA_MIMETYPE_VIDEO_MPEG4;
+extern const char *MEDIA_MIMETYPE_VIDEO_H263;
+extern const char *MEDIA_MIMETYPE_VIDEO_MPEG2;
+extern const char *MEDIA_MIMETYPE_VIDEO_RAW;
+extern const char *MEDIA_MIMETYPE_VIDEO_DOLBY_VISION;
+extern const char *MEDIA_MIMETYPE_VIDEO_SCRAMBLED;
+
+extern const char *MEDIA_MIMETYPE_AUDIO_AMR_NB;
+extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB;
+extern const char *MEDIA_MIMETYPE_AUDIO_MPEG; // layer III
+extern const char *MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I;
+extern const char *MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II;
+extern const char *MEDIA_MIMETYPE_AUDIO_MIDI;
+extern const char *MEDIA_MIMETYPE_AUDIO_AAC;
+extern const char *MEDIA_MIMETYPE_AUDIO_QCELP;
+extern const char *MEDIA_MIMETYPE_AUDIO_VORBIS;
+extern const char *MEDIA_MIMETYPE_AUDIO_OPUS;
+extern const char *MEDIA_MIMETYPE_AUDIO_G711_ALAW;
+extern const char *MEDIA_MIMETYPE_AUDIO_G711_MLAW;
+extern const char *MEDIA_MIMETYPE_AUDIO_RAW;
+extern const char *MEDIA_MIMETYPE_AUDIO_FLAC;
+extern const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS;
+extern const char *MEDIA_MIMETYPE_AUDIO_MSGSM;
+extern const char *MEDIA_MIMETYPE_AUDIO_AC3;
+extern const char *MEDIA_MIMETYPE_AUDIO_EAC3;
+extern const char *MEDIA_MIMETYPE_AUDIO_SCRAMBLED;
+
+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;
+extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG2TS;
+extern const char *MEDIA_MIMETYPE_CONTAINER_AVI;
+extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG2PS;
+
+extern const char *MEDIA_MIMETYPE_TEXT_3GPP;
+extern const char *MEDIA_MIMETYPE_TEXT_SUBRIP;
+extern const char *MEDIA_MIMETYPE_TEXT_VTT;
+extern const char *MEDIA_MIMETYPE_TEXT_CEA_608;
+extern const char *MEDIA_MIMETYPE_TEXT_CEA_708;
+extern const char *MEDIA_MIMETYPE_DATA_TIMED_ID3;
+
+// These are values exported to JAVA API that need to be in sync with
+// frameworks/base/media/java/android/media/AudioFormat.java. Unfortunately,
+// they are not defined in frameworks/av, so defining them here.
+enum AudioEncoding {
+ kAudioEncodingPcm16bit = 2,
+ kAudioEncodingPcm8bit = 3,
+ kAudioEncodingPcmFloat = 4,
+};
+
+} // namespace android
+
+#endif // MEDIA_DEFS_H_
diff --git a/media/libmedia/include/MediaMetadataRetrieverInterface.h b/media/libmedia/include/MediaMetadataRetrieverInterface.h
new file mode 100644
index 0000000..a5e1350
--- /dev/null
+++ b/media/libmedia/include/MediaMetadataRetrieverInterface.h
@@ -0,0 +1,64 @@
+/*
+**
+** Copyright (C) 2008 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_MEDIAMETADATARETRIEVERINTERFACE_H
+#define ANDROID_MEDIAMETADATARETRIEVERINTERFACE_H
+
+#include <utils/RefBase.h>
+#include <media/mediametadataretriever.h>
+#include <media/mediascanner.h>
+#include <private/media/VideoFrame.h>
+
+namespace android {
+
+class DataSource;
+struct IMediaHTTPService;
+
+// Abstract base class
+class MediaMetadataRetrieverBase : public RefBase
+{
+public:
+ MediaMetadataRetrieverBase() {}
+ virtual ~MediaMetadataRetrieverBase() {}
+
+ virtual status_t setDataSource(
+ const sp<IMediaHTTPService> &httpService,
+ const char *url,
+ const KeyedVector<String8, String8> *headers = NULL) = 0;
+
+ virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0;
+ virtual status_t setDataSource(const sp<DataSource>& source) = 0;
+ virtual VideoFrame* getFrameAtTime(int64_t timeUs, int option) = 0;
+ virtual MediaAlbumArt* extractAlbumArt() = 0;
+ virtual const char* extractMetadata(int keyCode) = 0;
+};
+
+// MediaMetadataRetrieverInterface
+class MediaMetadataRetrieverInterface : public MediaMetadataRetrieverBase
+{
+public:
+ MediaMetadataRetrieverInterface() {}
+
+ virtual ~MediaMetadataRetrieverInterface() {}
+ virtual VideoFrame* getFrameAtTime(int64_t /*timeUs*/, int /*option*/) { return NULL; }
+ virtual MediaAlbumArt* extractAlbumArt() { return NULL; }
+ virtual const char* extractMetadata(int /*keyCode*/) { return NULL; }
+};
+
+}; // namespace android
+
+#endif // ANDROID_MEDIAMETADATARETRIEVERINTERFACE_H
diff --git a/media/libmedia/include/MediaProfiles.h b/media/libmedia/include/MediaProfiles.h
new file mode 100644
index 0000000..e02918f
--- /dev/null
+++ b/media/libmedia/include/MediaProfiles.h
@@ -0,0 +1,452 @@
+/*
+ **
+ ** Copyright 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_MEDIAPROFILES_H
+#define ANDROID_MEDIAPROFILES_H
+
+#include <utils/threads.h>
+#include <media/mediarecorder.h>
+
+namespace android {
+
+enum camcorder_quality {
+ CAMCORDER_QUALITY_LIST_START = 0,
+ CAMCORDER_QUALITY_LOW = 0,
+ CAMCORDER_QUALITY_HIGH = 1,
+ CAMCORDER_QUALITY_QCIF = 2,
+ CAMCORDER_QUALITY_CIF = 3,
+ CAMCORDER_QUALITY_480P = 4,
+ CAMCORDER_QUALITY_720P = 5,
+ CAMCORDER_QUALITY_1080P = 6,
+ CAMCORDER_QUALITY_QVGA = 7,
+ CAMCORDER_QUALITY_2160P = 8,
+ CAMCORDER_QUALITY_LIST_END = 8,
+
+ CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000,
+ CAMCORDER_QUALITY_TIME_LAPSE_LOW = 1000,
+ CAMCORDER_QUALITY_TIME_LAPSE_HIGH = 1001,
+ CAMCORDER_QUALITY_TIME_LAPSE_QCIF = 1002,
+ CAMCORDER_QUALITY_TIME_LAPSE_CIF = 1003,
+ CAMCORDER_QUALITY_TIME_LAPSE_480P = 1004,
+ CAMCORDER_QUALITY_TIME_LAPSE_720P = 1005,
+ CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006,
+ CAMCORDER_QUALITY_TIME_LAPSE_QVGA = 1007,
+ CAMCORDER_QUALITY_TIME_LAPSE_2160P = 1008,
+ CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1008,
+
+ CAMCORDER_QUALITY_HIGH_SPEED_LIST_START = 2000,
+ CAMCORDER_QUALITY_HIGH_SPEED_LOW = 2000,
+ CAMCORDER_QUALITY_HIGH_SPEED_HIGH = 2001,
+ CAMCORDER_QUALITY_HIGH_SPEED_480P = 2002,
+ CAMCORDER_QUALITY_HIGH_SPEED_720P = 2003,
+ CAMCORDER_QUALITY_HIGH_SPEED_1080P = 2004,
+ CAMCORDER_QUALITY_HIGH_SPEED_2160P = 2005,
+ CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2005,
+};
+
+enum video_decoder {
+ VIDEO_DECODER_WMV,
+};
+
+enum audio_decoder {
+ AUDIO_DECODER_WMA,
+};
+
+
+class MediaProfiles
+{
+public:
+
+ /**
+ * Returns the singleton instance for subsequence queries.
+ * or NULL if error.
+ */
+ static MediaProfiles* getInstance();
+
+ /**
+ * Returns the value for the given param name for the given camera at
+ * the given quality level, or -1 if error.
+ *
+ * Supported param name are:
+ * duration - the recording duration.
+ * file.format - output file format. see mediarecorder.h for details
+ * vid.codec - video encoder. see mediarecorder.h for details.
+ * aud.codec - audio encoder. see mediarecorder.h for details.
+ * vid.width - video frame width
+ * vid.height - video frame height
+ * vid.fps - video frame rate
+ * vid.bps - video bit rate
+ * aud.bps - audio bit rate
+ * aud.hz - audio sample rate
+ * aud.ch - number of audio channels
+ */
+ int getCamcorderProfileParamByName(const char *name, int cameraId,
+ camcorder_quality quality) const;
+
+ /**
+ * Returns true if a profile for the given camera at the given quality exists,
+ * or false if not.
+ */
+ bool hasCamcorderProfile(int cameraId, camcorder_quality quality) const;
+
+ /**
+ * Returns the output file formats supported.
+ */
+ Vector<output_format> getOutputFileFormats() const;
+
+ /**
+ * Returns the video encoders supported.
+ */
+ Vector<video_encoder> getVideoEncoders() const;
+
+ /**
+ * Returns the value for the given param name for the given video encoder
+ * returned from getVideoEncoderByIndex or -1 if error.
+ *
+ * Supported param name are:
+ * enc.vid.width.min - min video frame width
+ * enc.vid.width.max - max video frame width
+ * enc.vid.height.min - min video frame height
+ * enc.vid.height.max - max video frame height
+ * enc.vid.bps.min - min bit rate in bits per second
+ * enc.vid.bps.max - max bit rate in bits per second
+ * enc.vid.fps.min - min frame rate in frames per second
+ * enc.vid.fps.max - max frame rate in frames per second
+ */
+ int getVideoEncoderParamByName(const char *name, video_encoder codec) const;
+
+ /**
+ * Returns the audio encoders supported.
+ */
+ Vector<audio_encoder> getAudioEncoders() const;
+
+ /**
+ * Returns the value for the given param name for the given audio encoder
+ * returned from getAudioEncoderByIndex or -1 if error.
+ *
+ * Supported param name are:
+ * enc.aud.ch.min - min number of channels
+ * enc.aud.ch.max - max number of channels
+ * enc.aud.bps.min - min bit rate in bits per second
+ * enc.aud.bps.max - max bit rate in bits per second
+ * enc.aud.hz.min - min sample rate in samples per second
+ * enc.aud.hz.max - max sample rate in samples per second
+ */
+ int getAudioEncoderParamByName(const char *name, audio_encoder codec) const;
+
+ /**
+ * Returns the video decoders supported.
+ */
+ Vector<video_decoder> getVideoDecoders() const;
+
+ /**
+ * Returns the audio decoders supported.
+ */
+ Vector<audio_decoder> getAudioDecoders() const;
+
+ /**
+ * Returns the number of image encoding quality levels supported.
+ */
+ Vector<int> getImageEncodingQualityLevels(int cameraId) const;
+
+ /**
+ * Returns the start time offset (in ms) for the given camera Id.
+ * If the given camera Id does not exist, -1 will be returned.
+ */
+ int getStartTimeOffsetMs(int cameraId) const;
+
+private:
+ enum {
+ // Camcorder profiles (high/low) and timelapse profiles (high/low)
+ kNumRequiredProfiles = 4,
+ };
+
+ MediaProfiles& operator=(const MediaProfiles&); // Don't call me
+ MediaProfiles(const MediaProfiles&); // Don't call me
+ MediaProfiles() {} // Dummy default constructor
+ ~MediaProfiles(); // Don't delete me
+
+ struct VideoCodec {
+ VideoCodec(video_encoder codec, int bitRate, int frameWidth, int frameHeight, int frameRate)
+ : mCodec(codec),
+ mBitRate(bitRate),
+ mFrameWidth(frameWidth),
+ mFrameHeight(frameHeight),
+ mFrameRate(frameRate) {}
+
+ VideoCodec(const VideoCodec& copy) {
+ mCodec = copy.mCodec;
+ mBitRate = copy.mBitRate;
+ mFrameWidth = copy.mFrameWidth;
+ mFrameHeight = copy.mFrameHeight;
+ mFrameRate = copy.mFrameRate;
+ }
+
+ ~VideoCodec() {}
+
+ video_encoder mCodec;
+ int mBitRate;
+ int mFrameWidth;
+ int mFrameHeight;
+ int mFrameRate;
+ };
+
+ struct AudioCodec {
+ AudioCodec(audio_encoder codec, int bitRate, int sampleRate, int channels)
+ : mCodec(codec),
+ mBitRate(bitRate),
+ mSampleRate(sampleRate),
+ mChannels(channels) {}
+
+ AudioCodec(const AudioCodec& copy) {
+ mCodec = copy.mCodec;
+ mBitRate = copy.mBitRate;
+ mSampleRate = copy.mSampleRate;
+ mChannels = copy.mChannels;
+ }
+
+ ~AudioCodec() {}
+
+ audio_encoder mCodec;
+ int mBitRate;
+ int mSampleRate;
+ int mChannels;
+ };
+
+ struct CamcorderProfile {
+ CamcorderProfile()
+ : mCameraId(0),
+ mFileFormat(OUTPUT_FORMAT_THREE_GPP),
+ mQuality(CAMCORDER_QUALITY_HIGH),
+ mDuration(0),
+ mVideoCodec(0),
+ mAudioCodec(0) {}
+
+ CamcorderProfile(const CamcorderProfile& copy) {
+ mCameraId = copy.mCameraId;
+ mFileFormat = copy.mFileFormat;
+ mQuality = copy.mQuality;
+ mDuration = copy.mDuration;
+ mVideoCodec = new VideoCodec(*copy.mVideoCodec);
+ mAudioCodec = new AudioCodec(*copy.mAudioCodec);
+ }
+
+ ~CamcorderProfile() {
+ delete mVideoCodec;
+ delete mAudioCodec;
+ }
+
+ int mCameraId;
+ output_format mFileFormat;
+ camcorder_quality mQuality;
+ int mDuration;
+ VideoCodec *mVideoCodec;
+ AudioCodec *mAudioCodec;
+ };
+
+ struct VideoEncoderCap {
+ // Ugly constructor
+ VideoEncoderCap(video_encoder codec,
+ int minBitRate, int maxBitRate,
+ int minFrameWidth, int maxFrameWidth,
+ int minFrameHeight, int maxFrameHeight,
+ int minFrameRate, int maxFrameRate)
+ : mCodec(codec),
+ mMinBitRate(minBitRate), mMaxBitRate(maxBitRate),
+ mMinFrameWidth(minFrameWidth), mMaxFrameWidth(maxFrameWidth),
+ mMinFrameHeight(minFrameHeight), mMaxFrameHeight(maxFrameHeight),
+ mMinFrameRate(minFrameRate), mMaxFrameRate(maxFrameRate) {}
+
+ ~VideoEncoderCap() {}
+
+ video_encoder mCodec;
+ int mMinBitRate, mMaxBitRate;
+ int mMinFrameWidth, mMaxFrameWidth;
+ int mMinFrameHeight, mMaxFrameHeight;
+ int mMinFrameRate, mMaxFrameRate;
+ };
+
+ struct AudioEncoderCap {
+ // Ugly constructor
+ AudioEncoderCap(audio_encoder codec,
+ int minBitRate, int maxBitRate,
+ int minSampleRate, int maxSampleRate,
+ int minChannels, int maxChannels)
+ : mCodec(codec),
+ mMinBitRate(minBitRate), mMaxBitRate(maxBitRate),
+ mMinSampleRate(minSampleRate), mMaxSampleRate(maxSampleRate),
+ mMinChannels(minChannels), mMaxChannels(maxChannels) {}
+
+ ~AudioEncoderCap() {}
+
+ audio_encoder mCodec;
+ int mMinBitRate, mMaxBitRate;
+ int mMinSampleRate, mMaxSampleRate;
+ int mMinChannels, mMaxChannels;
+ };
+
+ struct VideoDecoderCap {
+ VideoDecoderCap(video_decoder codec): mCodec(codec) {}
+ ~VideoDecoderCap() {}
+
+ video_decoder mCodec;
+ };
+
+ struct AudioDecoderCap {
+ AudioDecoderCap(audio_decoder codec): mCodec(codec) {}
+ ~AudioDecoderCap() {}
+
+ audio_decoder mCodec;
+ };
+
+ struct NameToTagMap {
+ const char* name;
+ int tag;
+ };
+
+ struct ImageEncodingQualityLevels {
+ int mCameraId;
+ Vector<int> mLevels;
+ };
+
+ int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const;
+ void initRequiredProfileRefs(const Vector<int>& cameraIds);
+ int getRequiredProfileRefIndex(int cameraId);
+
+ // Debug
+ static void logVideoCodec(const VideoCodec& codec);
+ static void logAudioCodec(const AudioCodec& codec);
+ static void logVideoEncoderCap(const VideoEncoderCap& cap);
+ static void logAudioEncoderCap(const AudioEncoderCap& cap);
+ static void logVideoDecoderCap(const VideoDecoderCap& cap);
+ static void logAudioDecoderCap(const AudioDecoderCap& cap);
+
+ // If the xml configuration file does exist, use the settings
+ // from the xml
+ static MediaProfiles* createInstanceFromXmlFile(const char *xml);
+ static output_format createEncoderOutputFileFormat(const char **atts);
+ static VideoCodec* createVideoCodec(const char **atts, MediaProfiles *profiles);
+ static AudioCodec* createAudioCodec(const char **atts, MediaProfiles *profiles);
+ static AudioDecoderCap* createAudioDecoderCap(const char **atts);
+ static VideoDecoderCap* createVideoDecoderCap(const char **atts);
+ static VideoEncoderCap* createVideoEncoderCap(const char **atts);
+ static AudioEncoderCap* createAudioEncoderCap(const char **atts);
+
+ static CamcorderProfile* createCamcorderProfile(
+ int cameraId, const char **atts, Vector<int>& cameraIds);
+
+ static int getCameraId(const char **atts);
+
+ void addStartTimeOffset(int cameraId, const char **atts);
+
+ ImageEncodingQualityLevels* findImageEncodingQualityLevels(int cameraId) const;
+ void addImageEncodingQualityLevel(int cameraId, const char** atts);
+
+ // Customized element tag handler for parsing the xml configuration file.
+ static void startElementHandler(void *userData, const char *name, const char **atts);
+
+ // If the xml configuration file does not exist, use hard-coded values
+ static MediaProfiles* createDefaultInstance();
+
+ static CamcorderProfile *createDefaultCamcorderQcifProfile(camcorder_quality quality);
+ static CamcorderProfile *createDefaultCamcorderCifProfile(camcorder_quality quality);
+ static void createDefaultCamcorderLowProfiles(
+ MediaProfiles::CamcorderProfile **lowProfile,
+ MediaProfiles::CamcorderProfile **lowSpecificProfile);
+ static void createDefaultCamcorderHighProfiles(
+ MediaProfiles::CamcorderProfile **highProfile,
+ MediaProfiles::CamcorderProfile **highSpecificProfile);
+
+ static CamcorderProfile *createDefaultCamcorderTimeLapseQcifProfile(camcorder_quality quality);
+ static CamcorderProfile *createDefaultCamcorderTimeLapse480pProfile(camcorder_quality quality);
+ static void createDefaultCamcorderTimeLapseLowProfiles(
+ MediaProfiles::CamcorderProfile **lowTimeLapseProfile,
+ MediaProfiles::CamcorderProfile **lowSpecificTimeLapseProfile);
+ static void createDefaultCamcorderTimeLapseHighProfiles(
+ MediaProfiles::CamcorderProfile **highTimeLapseProfile,
+ MediaProfiles::CamcorderProfile **highSpecificTimeLapseProfile);
+
+ static void createDefaultCamcorderProfiles(MediaProfiles *profiles);
+ static void createDefaultVideoEncoders(MediaProfiles *profiles);
+ static void createDefaultAudioEncoders(MediaProfiles *profiles);
+ static void createDefaultVideoDecoders(MediaProfiles *profiles);
+ static void createDefaultAudioDecoders(MediaProfiles *profiles);
+ static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles);
+ static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles);
+ static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles);
+
+ static VideoEncoderCap* createDefaultH263VideoEncoderCap();
+ static VideoEncoderCap* createDefaultM4vVideoEncoderCap();
+ static AudioEncoderCap* createDefaultAmrNBEncoderCap();
+
+ static int findTagForName(const NameToTagMap *map, size_t nMappings, const char *name);
+
+ /**
+ * Check on existing profiles with the following criteria:
+ * 1. Low quality profile must have the lowest video
+ * resolution product (width x height)
+ * 2. High quality profile must have the highest video
+ * resolution product (width x height)
+ *
+ * and add required low/high quality camcorder/timelapse
+ * profiles if they are not found. This allows to remove
+ * duplicate profile definitions in the media_profiles.xml
+ * file.
+ */
+ void checkAndAddRequiredProfilesIfNecessary();
+
+
+ // Mappings from name (for instance, codec name) to enum value
+ static const NameToTagMap sVideoEncoderNameMap[];
+ static const NameToTagMap sAudioEncoderNameMap[];
+ static const NameToTagMap sFileFormatMap[];
+ static const NameToTagMap sVideoDecoderNameMap[];
+ static const NameToTagMap sAudioDecoderNameMap[];
+ static const NameToTagMap sCamcorderQualityNameMap[];
+
+ static bool sIsInitialized;
+ static MediaProfiles *sInstance;
+ static Mutex sLock;
+ int mCurrentCameraId;
+
+ Vector<CamcorderProfile*> mCamcorderProfiles;
+ Vector<AudioEncoderCap*> mAudioEncoders;
+ Vector<VideoEncoderCap*> mVideoEncoders;
+ Vector<AudioDecoderCap*> mAudioDecoders;
+ Vector<VideoDecoderCap*> mVideoDecoders;
+ Vector<output_format> mEncoderOutputFileFormats;
+ Vector<ImageEncodingQualityLevels *> mImageEncodingQualityLevels;
+ KeyedVector<int, int> mStartTimeOffsets;
+
+ typedef struct {
+ bool mHasRefProfile; // Refers to an existing profile
+ int mRefProfileIndex; // Reference profile index
+ int mResolutionProduct; // width x height
+ } RequiredProfileRefInfo; // Required low and high profiles
+
+ typedef struct {
+ RequiredProfileRefInfo mRefs[kNumRequiredProfiles];
+ int mCameraId;
+ } RequiredProfiles;
+
+ RequiredProfiles *mRequiredProfileRefs;
+ Vector<int> mCameraIds;
+};
+
+}; // namespace android
+
+#endif // ANDROID_MEDIAPROFILES_H
diff --git a/media/libmedia/include/MediaRecorderBase.h b/media/libmedia/include/MediaRecorderBase.h
new file mode 100644
index 0000000..0b0f916
--- /dev/null
+++ b/media/libmedia/include/MediaRecorderBase.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2009 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 MEDIA_RECORDER_BASE_H_
+
+#define MEDIA_RECORDER_BASE_H_
+
+#include <media/mediarecorder.h>
+
+#include <system/audio.h>
+
+namespace android {
+
+class ICameraRecordingProxy;
+class IGraphicBufferProducer;
+struct PersistentSurface;
+
+struct MediaRecorderBase {
+ MediaRecorderBase(const String16 &opPackageName)
+ : mOpPackageName(opPackageName) {}
+ virtual ~MediaRecorderBase() {}
+
+ virtual status_t init() = 0;
+ virtual status_t setAudioSource(audio_source_t as) = 0;
+ virtual status_t setVideoSource(video_source vs) = 0;
+ virtual status_t setOutputFormat(output_format of) = 0;
+ virtual status_t setAudioEncoder(audio_encoder ae) = 0;
+ virtual status_t setVideoEncoder(video_encoder ve) = 0;
+ virtual status_t setVideoSize(int width, int height) = 0;
+ virtual status_t setVideoFrameRate(int frames_per_second) = 0;
+ virtual status_t setCamera(const sp<hardware::ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy) = 0;
+ virtual status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface) = 0;
+ virtual status_t setOutputFile(int fd) = 0;
+ virtual status_t setNextOutputFile(int fd) {return INVALID_OPERATION;}
+ virtual status_t setOutputFileAuxiliary(int /*fd*/) {return INVALID_OPERATION;}
+ virtual status_t setParameters(const String8& params) = 0;
+ virtual status_t setListener(const sp<IMediaRecorderClient>& listener) = 0;
+ virtual status_t setClientName(const String16& clientName) = 0;
+ virtual status_t prepare() = 0;
+ virtual status_t start() = 0;
+ virtual status_t stop() = 0;
+ virtual status_t pause() = 0;
+ virtual status_t resume() = 0;
+ virtual status_t close() = 0;
+ virtual status_t reset() = 0;
+ virtual status_t getMaxAmplitude(int *max) = 0;
+ virtual status_t getMetrics(Parcel *reply) = 0;
+ virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
+ virtual status_t setInputSurface(const sp<PersistentSurface>& surface) = 0;
+ virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() const = 0;
+
+
+protected:
+ String16 mOpPackageName;
+
+private:
+ MediaRecorderBase(const MediaRecorderBase &);
+ MediaRecorderBase &operator=(const MediaRecorderBase &);
+};
+
+} // namespace android
+
+#endif // MEDIA_RECORDER_BASE_H_
diff --git a/media/libmedia/include/MediaResource.h b/media/libmedia/include/MediaResource.h
new file mode 100644
index 0000000..1957a45
--- /dev/null
+++ b/media/libmedia/include/MediaResource.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2015 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_MEDIA_RESOURCE_H
+#define ANDROID_MEDIA_RESOURCE_H
+
+#include <binder/Parcel.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class MediaResource {
+public:
+ enum Type {
+ kUnspecified = 0,
+ kSecureCodec,
+ kNonSecureCodec,
+ kGraphicMemory
+ };
+
+ enum SubType {
+ kUnspecifiedSubType = 0,
+ kAudioCodec,
+ kVideoCodec
+ };
+
+ MediaResource();
+ MediaResource(Type type, uint64_t value);
+ MediaResource(Type type, SubType subType, uint64_t value);
+
+ void readFromParcel(const Parcel &parcel);
+ void writeToParcel(Parcel *parcel) const;
+
+ String8 toString() const;
+
+ bool operator==(const MediaResource &other) const;
+ bool operator!=(const MediaResource &other) const;
+
+ Type mType;
+ SubType mSubType;
+ uint64_t mValue;
+};
+
+inline static const char *asString(MediaResource::Type i, const char *def = "??") {
+ switch (i) {
+ case MediaResource::kUnspecified: return "unspecified";
+ case MediaResource::kSecureCodec: return "secure-codec";
+ case MediaResource::kNonSecureCodec: return "non-secure-codec";
+ case MediaResource::kGraphicMemory: return "graphic-memory";
+ default: return def;
+ }
+}
+
+inline static const char *asString(MediaResource::SubType i, const char *def = "??") {
+ switch (i) {
+ case MediaResource::kUnspecifiedSubType: return "unspecified";
+ case MediaResource::kAudioCodec: return "audio-codec";
+ case MediaResource::kVideoCodec: return "video-codec";
+ default: return def;
+ }
+}
+
+}; // namespace android
+
+#endif // ANDROID_MEDIA_RESOURCE_H
diff --git a/media/libmedia/include/MediaResourcePolicy.h b/media/libmedia/include/MediaResourcePolicy.h
new file mode 100644
index 0000000..9bc2eec
--- /dev/null
+++ b/media/libmedia/include/MediaResourcePolicy.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2015 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_MEDIA_RESOURCE_POLICY_H
+#define ANDROID_MEDIA_RESOURCE_POLICY_H
+
+#include <binder/Parcel.h>
+#include <utils/String8.h>
+
+namespace android {
+
+extern const char kPolicySupportsMultipleSecureCodecs[];
+extern const char kPolicySupportsSecureWithNonSecureCodec[];
+
+class MediaResourcePolicy {
+public:
+ MediaResourcePolicy();
+ MediaResourcePolicy(String8 type, String8 value);
+
+ void readFromParcel(const Parcel &parcel);
+ void writeToParcel(Parcel *parcel) const;
+
+ String8 toString() const;
+
+ String8 mType;
+ String8 mValue;
+};
+
+}; // namespace android
+
+#endif // ANDROID_MEDIA_RESOURCE_POLICY_H
diff --git a/media/libmedia/include/MemoryLeakTrackUtil.h b/media/libmedia/include/MemoryLeakTrackUtil.h
new file mode 100644
index 0000000..4c1a60c
--- /dev/null
+++ b/media/libmedia/include/MemoryLeakTrackUtil.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011, 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 MEMORY_LEAK_TRACK_UTIL_H
+#define MEMORY_LEAK_TRACK_UTIL_H
+
+#include <iostream>
+
+namespace android {
+/*
+ * Dump the heap memory of the calling process, sorted by total size
+ * (allocation size * number of allocations).
+ *
+ * limit is the number of unique allocations to return.
+ */
+extern std::string dumpMemoryAddresses(size_t limit);
+
+};
+
+#endif // MEMORY_LEAK_TRACK_UTIL_H
diff --git a/media/libmedia/include/Metadata.h b/media/libmedia/include/Metadata.h
new file mode 100644
index 0000000..07567eb
--- /dev/null
+++ b/media/libmedia/include/Metadata.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2009 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_MEDIA_METADATA_H__
+#define ANDROID_MEDIA_METADATA_H__
+
+#include <sys/types.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/SortedVector.h>
+
+namespace android {
+class Parcel;
+
+namespace media {
+
+// Metadata is a class to build/serialize a set of metadata in a Parcel.
+//
+// This class should be kept in sync with android/media/Metadata.java.
+// It provides all the metadata ids available and methods to build the
+// header, add records and adjust the set size header field.
+//
+// Typical Usage:
+// ==============
+// Parcel p;
+// media::Metadata data(&p);
+//
+// data.appendHeader();
+// data.appendBool(Metadata::kPauseAvailable, true);
+// ... more append ...
+// data.updateLength();
+//
+
+class Metadata {
+ public:
+ typedef int32_t Type;
+ typedef SortedVector<Type> Filter;
+
+ static const Type kAny = 0;
+
+ // Playback capabilities.
+ static const Type kPauseAvailable = 1; // Boolean
+ static const Type kSeekBackwardAvailable = 2; // Boolean
+ static const Type kSeekForwardAvailable = 3; // Boolean
+ static const Type kSeekAvailable = 4; // Boolean
+
+ // Keep in sync with android/media/Metadata.java
+ static const Type kTitle = 5; // String
+ static const Type kComment = 6; // String
+ static const Type kCopyright = 7; // String
+ static const Type kAlbum = 8; // String
+ static const Type kArtist = 9; // String
+ static const Type kAuthor = 10; // String
+ static const Type kComposer = 11; // String
+ static const Type kGenre = 12; // String
+ static const Type kDate = 13; // Date
+ static const Type kDuration = 14; // Integer(millisec)
+ static const Type kCdTrackNum = 15; // Integer 1-based
+ static const Type kCdTrackMax = 16; // Integer
+ static const Type kRating = 17; // String
+ static const Type kAlbumArt = 18; // byte[]
+ static const Type kVideoFrame = 19; // Bitmap
+
+ static const Type kBitRate = 20; // Integer, Aggregate rate of
+ // all the streams in bps.
+
+ static const Type kAudioBitRate = 21; // Integer, bps
+ static const Type kVideoBitRate = 22; // Integer, bps
+ static const Type kAudioSampleRate = 23; // Integer, Hz
+ static const Type kVideoframeRate = 24; // Integer, Hz
+
+ // See RFC2046 and RFC4281.
+ static const Type kMimeType = 25; // String
+ static const Type kAudioCodec = 26; // String
+ static const Type kVideoCodec = 27; // String
+
+ static const Type kVideoHeight = 28; // Integer
+ static const Type kVideoWidth = 29; // Integer
+ static const Type kNumTracks = 30; // Integer
+ static const Type kDrmCrippled = 31; // Boolean
+
+ // @param p[inout] The parcel to append the metadata records
+ // to. The global metadata header should have been set already.
+ explicit Metadata(Parcel *p);
+ ~Metadata();
+
+ // Rewind the underlying parcel, undoing all the changes.
+ void resetParcel();
+
+ // Append the size and 'META' marker.
+ bool appendHeader();
+
+ // Once all the records have been added, call this to update the
+ // lenght field in the header.
+ void updateLength();
+
+ // append* are methods to append metadata.
+ // @param key Is the metadata Id.
+ // @param val Is the value of the metadata.
+ // @return true if successful, false otherwise.
+ // TODO: add more as needed to handle other types.
+ bool appendBool(Type key, bool val);
+ bool appendInt32(Type key, int32_t val);
+
+ private:
+ Metadata(const Metadata&);
+ Metadata& operator=(const Metadata&);
+
+
+ // Checks the key is valid and not already present.
+ bool checkKey(Type key);
+
+ Parcel *mData;
+ size_t mBegin;
+};
+
+} // namespace android::media
+} // namespace android
+
+#endif // ANDROID_MEDIA_METADATA_H__
diff --git a/media/libmedia/include/MidiDeviceInfo.h b/media/libmedia/include/MidiDeviceInfo.h
new file mode 100644
index 0000000..5b4a241
--- /dev/null
+++ b/media/libmedia/include/MidiDeviceInfo.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 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_MEDIA_MIDI_DEVICE_INFO_H
+#define ANDROID_MEDIA_MIDI_DEVICE_INFO_H
+
+#include <binder/Parcelable.h>
+#include <binder/PersistableBundle.h>
+#include <utils/String16.h>
+#include <utils/Vector.h>
+
+namespace android {
+namespace media {
+namespace midi {
+
+class MidiDeviceInfo : public Parcelable {
+public:
+ MidiDeviceInfo() = default;
+ virtual ~MidiDeviceInfo() = default;
+ MidiDeviceInfo(const MidiDeviceInfo& midiDeviceInfo) = default;
+
+ status_t writeToParcel(Parcel* parcel) const override;
+ status_t readFromParcel(const Parcel* parcel) override;
+
+ int getType() const { return mType; }
+ int getUid() const { return mId; }
+ bool isPrivate() const { return mIsPrivate; }
+ const Vector<String16>& getInputPortNames() const { return mInputPortNames; }
+ const Vector<String16>& getOutputPortNames() const { return mOutputPortNames; }
+ String16 getProperty(const char* propertyName);
+
+ // The constants need to be kept in sync with MidiDeviceInfo.java
+ enum {
+ TYPE_USB = 1,
+ TYPE_VIRTUAL = 2,
+ TYPE_BLUETOOTH = 3,
+ };
+ static const char* const PROPERTY_NAME;
+ static const char* const PROPERTY_MANUFACTURER;
+ static const char* const PROPERTY_PRODUCT;
+ static const char* const PROPERTY_VERSION;
+ static const char* const PROPERTY_SERIAL_NUMBER;
+ static const char* const PROPERTY_ALSA_CARD;
+ static const char* const PROPERTY_ALSA_DEVICE;
+
+ friend bool operator==(const MidiDeviceInfo& lhs, const MidiDeviceInfo& rhs);
+ friend bool operator!=(const MidiDeviceInfo& lhs, const MidiDeviceInfo& rhs) {
+ return !(lhs == rhs);
+ }
+
+private:
+ status_t readStringVector(
+ const Parcel* parcel, Vector<String16> *vectorPtr, size_t defaultLength);
+ status_t writeStringVector(Parcel* parcel, const Vector<String16>& vector) const;
+
+ int32_t mType;
+ int32_t mId;
+ Vector<String16> mInputPortNames;
+ Vector<String16> mOutputPortNames;
+ os::PersistableBundle mProperties;
+ bool mIsPrivate;
+};
+
+} // namespace midi
+} // namespace media
+} // namespace android
+
+#endif // ANDROID_MEDIA_MIDI_DEVICE_INFO_H
diff --git a/media/libmedia/include/MidiIoWrapper.h b/media/libmedia/include/MidiIoWrapper.h
new file mode 100644
index 0000000..e6f8cf7
--- /dev/null
+++ b/media/libmedia/include/MidiIoWrapper.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MIDI_IO_WRAPPER_H_
+#define MIDI_IO_WRAPPER_H_
+
+#include <libsonivox/eas_types.h>
+
+#include "media/stagefright/DataSource.h"
+
+namespace android {
+
+class MidiIoWrapper : public RefBase {
+public:
+ MidiIoWrapper(const char *path);
+ MidiIoWrapper(int fd, off64_t offset, int64_t size);
+ MidiIoWrapper(const sp<DataSource> &source);
+
+ ~MidiIoWrapper();
+
+ int readAt(void *buffer, int offset, int size);
+ int size();
+
+ EAS_FILE_LOCATOR getLocator();
+
+private:
+ int mFd;
+ off64_t mBase;
+ int64_t mLength;
+ sp<DataSource> mDataSource;
+ EAS_FILE mEasFile;
+};
+
+
+} // namespace android
+
+#endif // MIDI_IO_WRAPPER_H_
diff --git a/media/libmedia/include/Modulo.h b/media/libmedia/include/Modulo.h
new file mode 100644
index 0000000..23280ac
--- /dev/null
+++ b/media/libmedia/include/Modulo.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2015 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_MODULO_H
+#define ANDROID_MODULO_H
+
+namespace android {
+
+// Modulo class is used for intentionally wrapping variables such as
+// counters and timers.
+//
+// It may also be used for variables whose computation depends on the
+// associativity of addition or subtraction.
+//
+// Features:
+// 1) Modulo checks type sizes before performing operations to ensure
+// that the wrap points match. This is critical for safe modular arithmetic.
+// 2) Modulo returns Modulo types from arithmetic operations, thereby
+// avoiding unintentional use in a non-modular computation. A Modulo
+// type is converted to its base non-Modulo type through the value() function.
+// 3) Modulo separates out overflowable types from non-overflowable types.
+// A signed overflow is technically undefined in C and C++.
+// Modulo types do not participate in sanitization.
+// 4) Modulo comparisons are based on signed differences to account for wrap;
+// this is not the same as the direct comparison of values.
+// 5) Safe use of binary arithmetic operations relies on conversions of
+// signed operands to unsigned operands (which are modular arithmetic safe).
+// Conversions which are implementation-defined are assumed to use 2's complement
+// representation. (See A, B, C, D from the ISO/IEC FDIS 14882
+// Information technology — Programming languages — C++).
+//
+// A: ISO/IEC 14882:2011(E) p84 section 4.7 Integral conversions
+// (2) If the destination type is unsigned, the resulting value is the least unsigned
+// integer congruent to the source integer (modulo 2^n where n is the number of bits
+// used to represent the unsigned type). [ Note: In a two’s complement representation,
+// this conversion is conceptual and there is no change in the bit pattern (if there
+// is no truncation). — end note ]
+// (3) If the destination type is signed, the value is unchanged if it can be represented
+// in the destination type (and bit-field width); otherwise, the value is
+// implementation-defined.
+//
+// B: ISO/IEC 14882:2011(E) p88 section 5 Expressions
+// (9) Many binary operators that expect operands of arithmetic or enumeration type
+// cause conversions and yield result types in a similar way. The purpose is to
+// yield a common type, which is also the type of the result. This pattern is called
+// the usual arithmetic conversions, which are defined as follows:
+// [...]
+// Otherwise, if both operands have signed integer types or both have unsigned
+// integer types, the operand with the type of lesser integer conversion rank shall be
+// converted to the type of the operand with greater rank.
+// — Otherwise, if the operand that has unsigned integer type has rank greater than
+// or equal to the rank of the type of the other operand, the operand with signed
+// integer type shall be converted to the type of the operand with unsigned integer type.
+//
+// C: ISO/IEC 14882:2011(E) p86 section 4.13 Integer conversion rank
+// [...] The rank of long long int shall be greater than the rank of long int,
+// which shall be greater than the rank of int, which shall be greater than the
+// rank of short int, which shall be greater than the rank of signed char.
+// — The rank of any unsigned integer type shall equal the rank of the corresponding
+// signed integer type.
+//
+// D: ISO/IEC 14882:2011(E) p75 section 3.9.1 Fundamental types
+// [...] Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo
+// 2^n where n is the number of bits in the value representation of that particular
+// size of integer.
+//
+// Note:
+// Other libraries do exist for safe integer operations which can detect the
+// possibility of overflow (SafeInt from MS and safe-iop in android).
+// Signed safe computation is also possible from the art header safe_math.h.
+
+template <typename T> class Modulo {
+ T mValue;
+
+public:
+ typedef typename std::make_signed<T>::type signedT;
+ typedef typename std::make_unsigned<T>::type unsignedT;
+
+ Modulo() { } // intentionally uninitialized data
+ Modulo(const T &value) { mValue = value; }
+ const T & value() const { return mValue; } // not assignable
+ signedT signedValue() const { return mValue; }
+ unsignedT unsignedValue() const { return mValue; }
+ void getValue(T *value) const { *value = mValue; } // more type safe than value()
+
+ // modular operations valid only if size of T <= size of S.
+ template <typename S>
+ __attribute__((no_sanitize("integer")))
+ Modulo<T> operator +=(const Modulo<S> &other) {
+ static_assert(sizeof(T) <= sizeof(S), "argument size mismatch");
+ mValue += other.unsignedValue();
+ return *this;
+ }
+
+ template <typename S>
+ __attribute__((no_sanitize("integer")))
+ Modulo<T> operator -=(const Modulo<S> &other) {
+ static_assert(sizeof(T) <= sizeof(S), "argument size mismatch");
+ mValue -= other.unsignedValue();
+ return *this;
+ }
+
+ // modular operations resulting in a value valid only at the smaller of the two
+ // Modulo base type sizes, but we only allow equal sizes to avoid confusion.
+ template <typename S>
+ __attribute__((no_sanitize("integer")))
+ const Modulo<T> operator +(const Modulo<S> &other) const {
+ static_assert(sizeof(T) == sizeof(S), "argument size mismatch");
+ return Modulo<T>(mValue + other.unsignedValue());
+ }
+
+ template <typename S>
+ __attribute__((no_sanitize("integer")))
+ const Modulo<T> operator -(const Modulo<S> &other) const {
+ static_assert(sizeof(T) == sizeof(S), "argument size mismatch");
+ return Modulo<T>(mValue - other.unsignedValue());
+ }
+
+ // modular operations that should be checked only at the smaller of
+ // the two type sizes, but we only allow equal sizes to avoid confusion.
+ //
+ // Caution: These relational and comparison operations are not equivalent to
+ // the base type operations.
+ template <typename S>
+ __attribute__((no_sanitize("integer")))
+ bool operator >(const Modulo<S> &other) const {
+ static_assert(sizeof(T) == sizeof(S), "argument size mismatch");
+ return static_cast<signedT>(mValue - other.unsignedValue()) > 0;
+ }
+
+ template <typename S>
+ __attribute__((no_sanitize("integer")))
+ bool operator >=(const Modulo<S> &other) const {
+ static_assert(sizeof(T) == sizeof(S), "argument size mismatch");
+ return static_cast<signedT>(mValue - other.unsignedValue()) >= 0;
+ }
+
+ template <typename S>
+ __attribute__((no_sanitize("integer")))
+ bool operator ==(const Modulo<S> &other) const {
+ static_assert(sizeof(T) == sizeof(S), "argument size mismatch");
+ return static_cast<signedT>(mValue - other.unsignedValue()) == 0;
+ }
+
+ template <typename S>
+ __attribute__((no_sanitize("integer")))
+ bool operator <=(const Modulo<S> &other) const {
+ static_assert(sizeof(T) == sizeof(S), "argument size mismatch");
+ return static_cast<signedT>(mValue - other.unsignedValue()) <= 0;
+ }
+
+ template <typename S>
+ __attribute__((no_sanitize("integer")))
+ bool operator <(const Modulo<S> &other) const {
+ static_assert(sizeof(T) == sizeof(S), "argument size mismatch");
+ return static_cast<signedT>(mValue - other.unsignedValue()) < 0;
+ }
+
+
+ // modular operations with a non-Modulo type allowed with wrapping
+ // because there should be no confusion as to the meaning.
+ template <typename S>
+ __attribute__((no_sanitize("integer")))
+ Modulo<T> operator +=(const S &other) {
+ mValue += unsignedT(other);
+ return *this;
+ }
+
+ template <typename S>
+ __attribute__((no_sanitize("integer")))
+ Modulo<T> operator -=(const S &other) {
+ mValue -= unsignedT(other);
+ return *this;
+ }
+
+ // modular operations with a non-Modulo type allowed with wrapping,
+ // but we restrict this only when size of T is greater than or equal to
+ // the size of S to avoid confusion with the nature of overflow.
+ //
+ // Use of this follows left-associative style.
+ //
+ // Note: a Modulo type may be promoted by using "differences" off of
+ // a larger sized type, but we do not automate this.
+ template <typename S>
+ __attribute__((no_sanitize("integer")))
+ const Modulo<T> operator +(const S &other) const {
+ static_assert(sizeof(T) >= sizeof(S), "argument size mismatch");
+ return Modulo<T>(mValue + unsignedT(other));
+ }
+
+ template <typename S>
+ __attribute__((no_sanitize("integer")))
+ const Modulo<T> operator -(const S &other) const {
+ static_assert(sizeof(T) >= sizeof(S), "argument size mismatch");
+ return Modulo<T>(mValue - unsignedT(other));
+ }
+
+ // multiply is intentionally omitted, but it is a common operator in
+ // modular arithmetic.
+
+ // shift operations are intentionally omitted, but perhaps useful.
+ // For example, left-shifting a negative number is undefined in C++11.
+};
+
+} // namespace android
+
+#endif /* ANDROID_MODULO_H */
diff --git a/media/libmedia/include/OMXBuffer.h b/media/libmedia/include/OMXBuffer.h
new file mode 100644
index 0000000..6f79182
--- /dev/null
+++ b/media/libmedia/include/OMXBuffer.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2016, 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 _OMXBUFFER_H_
+#define _OMXBUFFER_H_
+
+#include <cutils/native_handle.h>
+#include <media/IOMX.h>
+#include <system/window.h>
+#include <utils/StrongPointer.h>
+#include <hidl/HidlSupport.h>
+
+namespace android {
+
+class OMXBuffer;
+
+// This is needed temporarily for the OMX HIDL transition.
+namespace hardware { namespace media { namespace omx {
+namespace V1_0 {
+ struct CodecBuffer;
+namespace implementation {
+ inline bool wrapAs(::android::hardware::media::omx::V1_0::CodecBuffer* t,
+ ::android::OMXBuffer const& l);
+ inline bool convertTo(::android::OMXBuffer* l,
+ ::android::hardware::media::omx::V1_0::CodecBuffer const& t);
+}
+namespace utils {
+ inline bool wrapAs(::android::hardware::media::omx::V1_0::CodecBuffer* t,
+ ::android::OMXBuffer const& l);
+ inline bool convertTo(::android::OMXBuffer* l,
+ ::android::hardware::media::omx::V1_0::CodecBuffer const& t);
+}
+}}}}
+
+class GraphicBuffer;
+class IMemory;
+class MediaCodecBuffer;
+class NativeHandle;
+struct OMXNodeInstance;
+using hardware::hidl_memory;
+
+// TODO: After complete HIDL transition, this class would be replaced by
+// CodecBuffer.
+class OMXBuffer {
+public:
+ // sPreset is used in places where we are referring to a pre-registered
+ // buffer on a port. It has type kBufferTypePreset and mRangeLength of 0.
+ static OMXBuffer sPreset;
+
+ // Default constructor, constructs a buffer of type kBufferTypeInvalid.
+ OMXBuffer();
+
+ // Constructs a buffer of type kBufferTypePreset with mRangeOffset set to
+ // |codecBuffer|'s offset and mRangeLength set to |codecBuffer|'s size (or 0
+ // if |codecBuffer| is NULL).
+ OMXBuffer(const sp<MediaCodecBuffer> &codecBuffer);
+
+ // Constructs a buffer of type kBufferTypePreset with specified mRangeOffset
+ // and mRangeLength.
+ OMXBuffer(OMX_U32 rangeOffset, OMX_U32 rangeLength);
+
+ // Constructs a buffer of type kBufferTypeSharedMem.
+ OMXBuffer(const sp<IMemory> &mem);
+
+ // Constructs a buffer of type kBufferTypeANWBuffer.
+ OMXBuffer(const sp<GraphicBuffer> &gbuf);
+
+ // Constructs a buffer of type kBufferTypeNativeHandle.
+ OMXBuffer(const sp<NativeHandle> &handle);
+
+ // Constructs a buffer of type kBufferTypeHidlMemory.
+ OMXBuffer(const hidl_memory &hidlMemory);
+
+ // Parcelling/Un-parcelling.
+ status_t writeToParcel(Parcel *parcel) const;
+ status_t readFromParcel(const Parcel *parcel);
+
+ ~OMXBuffer();
+
+private:
+ friend struct OMXNodeInstance;
+
+ // This is needed temporarily for OMX HIDL transition.
+ friend inline bool (::android::hardware::media::omx::V1_0::implementation::
+ wrapAs)(::android::hardware::media::omx::V1_0::CodecBuffer* t,
+ OMXBuffer const& l);
+ friend inline bool (::android::hardware::media::omx::V1_0::implementation::
+ convertTo)(OMXBuffer* l,
+ ::android::hardware::media::omx::V1_0::CodecBuffer const& t);
+ friend inline bool (::android::hardware::media::omx::V1_0::utils::
+ wrapAs)(::android::hardware::media::omx::V1_0::CodecBuffer* t,
+ OMXBuffer const& l);
+ friend inline bool (::android::hardware::media::omx::V1_0::utils::
+ convertTo)(OMXBuffer* l,
+ ::android::hardware::media::omx::V1_0::CodecBuffer const& t);
+
+ enum BufferType {
+ kBufferTypeInvalid = 0,
+ kBufferTypePreset,
+ kBufferTypeSharedMem,
+ kBufferTypeANWBuffer, // Use only for non-Treble
+ kBufferTypeNativeHandle,
+ kBufferTypeHidlMemory // Mapped to CodecBuffer::Type::SHARED_MEM.
+ };
+
+ BufferType mBufferType;
+
+ // kBufferTypePreset
+ // If the port is operating in byte buffer mode, mRangeLength is the valid
+ // range length. Otherwise the range info should also be ignored.
+ OMX_U32 mRangeOffset;
+ OMX_U32 mRangeLength;
+
+ // kBufferTypeSharedMem
+ sp<IMemory> mMem;
+
+ // kBufferTypeANWBuffer
+ sp<GraphicBuffer> mGraphicBuffer;
+
+ // kBufferTypeNativeHandle
+ sp<NativeHandle> mNativeHandle;
+
+ // kBufferTypeHidlMemory
+ hidl_memory mHidlMemory;
+
+ // Move assignment
+ OMXBuffer &operator=(OMXBuffer&&);
+
+ // Deleted copy constructor and assignment.
+ OMXBuffer(const OMXBuffer&) = delete;
+ OMXBuffer& operator=(const OMXBuffer&) = delete;
+};
+
+} // namespace android
+
+#endif // _OMXBUFFER_H_
diff --git a/media/libmedia/include/OMXFenceParcelable.h b/media/libmedia/include/OMXFenceParcelable.h
new file mode 100644
index 0000000..2a8da87
--- /dev/null
+++ b/media/libmedia/include/OMXFenceParcelable.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2016 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 _OMX_FENCE_PARCELABLE_
+#define _OMX_FENCE_PARCELABLE_
+
+#include <binder/Parcel.h>
+
+namespace android {
+
+struct OMXFenceParcelable;
+
+// This is needed temporarily for the OMX HIDL transition.
+namespace hardware {
+ struct hidl_handle;
+namespace media { namespace omx { namespace V1_0 {
+namespace implementation {
+ void wrapAs(::android::OMXFenceParcelable* l,
+ ::android::hardware::hidl_handle const& t);
+ bool convertTo(::android::OMXFenceParcelable* l,
+ ::android::hardware::hidl_handle const& t);
+}
+namespace utils {
+ void wrapAs(::android::OMXFenceParcelable* l,
+ ::android::hardware::hidl_handle const& t);
+ bool convertTo(::android::OMXFenceParcelable* l,
+ ::android::hardware::hidl_handle const& t);
+}
+}}}}
+
+struct OMXFenceParcelable : public Parcelable {
+ OMXFenceParcelable() : mFenceFd(-1) {}
+ OMXFenceParcelable(int fenceFd) : mFenceFd(fenceFd) {}
+
+ int get() const { return mFenceFd; }
+
+ status_t readFromParcel(const Parcel* parcel) override;
+ status_t writeToParcel(Parcel* parcel) const override;
+
+private:
+ // Disable copy ctor and operator=
+ OMXFenceParcelable(const OMXFenceParcelable &);
+ OMXFenceParcelable &operator=(const OMXFenceParcelable &);
+
+ int mFenceFd;
+
+ // This is needed temporarily for OMX HIDL transition.
+ friend void (::android::hardware::media::omx::V1_0::implementation::
+ wrapAs)(OMXFenceParcelable* l,
+ ::android::hardware::hidl_handle const& t);
+ friend bool (::android::hardware::media::omx::V1_0::implementation::
+ convertTo)(OMXFenceParcelable* l,
+ ::android::hardware::hidl_handle const& t);
+ friend void (::android::hardware::media::omx::V1_0::utils::
+ wrapAs)(OMXFenceParcelable* l,
+ ::android::hardware::hidl_handle const& t);
+ friend bool (::android::hardware::media::omx::V1_0::utils::
+ convertTo)(OMXFenceParcelable* l,
+ ::android::hardware::hidl_handle const& t);
+};
+
+inline status_t OMXFenceParcelable::readFromParcel(const Parcel* parcel) {
+ int32_t haveFence;
+ status_t err = parcel->readInt32(&haveFence);
+ if (err == OK && haveFence) {
+ int fd = ::dup(parcel->readFileDescriptor());
+ if (fd < 0) {
+ return fd;
+ }
+ mFenceFd = fd;
+ }
+ return err;
+}
+
+inline status_t OMXFenceParcelable::writeToParcel(Parcel* parcel) const {
+ status_t err = parcel->writeInt32(mFenceFd >= 0);
+ if (err == OK && mFenceFd >= 0) {
+ err = parcel->writeFileDescriptor(mFenceFd, true /* takeOwnership */);
+ }
+ return err;
+}
+
+} // namespace android
+
+#endif // _OMX_FENCE_PARCELABLE_
diff --git a/media/libmedia/include/PluginLoader.h b/media/libmedia/include/PluginLoader.h
new file mode 100644
index 0000000..a626e16
--- /dev/null
+++ b/media/libmedia/include/PluginLoader.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (C) 2016 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 PLUGIN_LOADER_H_
+#define PLUGIN_LOADER_H_
+
+#include "SharedLibrary.h"
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+template <class T>
+class PluginLoader {
+
+ public:
+ PluginLoader(const char *dir, const char *entry) {
+ /**
+ * scan all plugins in the plugin directory and add them to the
+ * factories list.
+ */
+ String8 pluginDir(dir);
+
+ DIR* pDir = opendir(pluginDir.string());
+ if (pDir == NULL) {
+ ALOGE("Failed to find plugin directory %s", pluginDir.string());
+ } else {
+ struct dirent* pEntry;
+ while ((pEntry = readdir(pDir))) {
+ String8 file(pEntry->d_name);
+ if (file.getPathExtension() == ".so") {
+ String8 path = pluginDir + "/" + pEntry->d_name;
+ T *plugin = loadOne(path, entry);
+ if (plugin) {
+ factories.push(plugin);
+ }
+ }
+ }
+ closedir(pDir);
+ }
+ }
+
+ ~PluginLoader() {
+ for (size_t i = 0; i < factories.size(); i++) {
+ delete factories[i];
+ }
+ }
+
+ T *getFactory(size_t i) const {
+ return factories[i];
+ }
+
+ size_t factoryCount() const {return factories.size();}
+
+ private:
+ T* loadOne(const char *path, const char *entry) {
+ sp<SharedLibrary> library = new SharedLibrary(String8(path));
+ if (!library.get()) {
+ ALOGE("Failed to open plugin library %s: %s", path,
+ library->lastError());
+ } else {
+ typedef T *(*CreateFactoryFunc)();
+ CreateFactoryFunc createFactoryFunc =
+ (CreateFactoryFunc)library->lookup(entry);
+ if (createFactoryFunc) {
+ ALOGV("Found plugin factory entry %s in %s", entry, path);
+ libraries.push(library);
+ T* result = createFactoryFunc();
+ return result;
+ }
+ }
+ return NULL;
+ }
+
+ Vector<T *> factories;
+ Vector<sp<SharedLibrary> > libraries;
+
+ PluginLoader(const PluginLoader &) = delete;
+ void operator=(const PluginLoader &) = delete;
+};
+
+} // namespace android
+
+#endif // PLUGIN_LOADER_H_
+
diff --git a/media/libmedia/include/RecordBufferConverter.h b/media/libmedia/include/RecordBufferConverter.h
new file mode 100644
index 0000000..2abc45e
--- /dev/null
+++ b/media/libmedia/include/RecordBufferConverter.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2017 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_RECORD_BUFFER_CONVERTER_H
+#define ANDROID_RECORD_BUFFER_CONVERTER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <media/AudioBufferProvider.h>
+#include <system/audio.h>
+
+class AudioResampler;
+class PassthruBufferProvider;
+
+namespace android {
+
+/* The RecordBufferConverter is used for format, channel, and sample rate
+ * conversion for a RecordTrack.
+ *
+ * RecordBufferConverter uses the convert() method rather than exposing a
+ * buffer provider interface; this is to save a memory copy.
+ *
+ * There are legacy conversion requirements for this converter, specifically
+ * due to mono handling, so be careful about modifying.
+ *
+ * Original source audioflinger/Threads.{h,cpp}
+ */
+class RecordBufferConverter
+{
+public:
+ RecordBufferConverter(
+ audio_channel_mask_t srcChannelMask, audio_format_t srcFormat,
+ uint32_t srcSampleRate,
+ audio_channel_mask_t dstChannelMask, audio_format_t dstFormat,
+ uint32_t dstSampleRate);
+
+ ~RecordBufferConverter();
+
+ /* Converts input data from an AudioBufferProvider by format, channelMask,
+ * and sampleRate to a destination buffer.
+ *
+ * Parameters
+ * dst: buffer to place the converted data.
+ * provider: buffer provider to obtain source data.
+ * frames: number of frames to convert
+ *
+ * Returns the number of frames converted.
+ */
+ size_t convert(void *dst, AudioBufferProvider *provider, size_t frames);
+
+ // returns NO_ERROR if constructor was successful
+ status_t initCheck() const {
+ // mSrcChannelMask set on successful updateParameters
+ return mSrcChannelMask != AUDIO_CHANNEL_INVALID ? NO_ERROR : NO_INIT;
+ }
+
+ // allows dynamic reconfigure of all parameters
+ status_t updateParameters(
+ audio_channel_mask_t srcChannelMask, audio_format_t srcFormat,
+ uint32_t srcSampleRate,
+ audio_channel_mask_t dstChannelMask, audio_format_t dstFormat,
+ uint32_t dstSampleRate);
+
+ // called to reset resampler buffers on record track discontinuity
+ void reset();
+
+private:
+ // format conversion when not using resampler
+ void convertNoResampler(void *dst, const void *src, size_t frames);
+
+ // format conversion when using resampler; modifies src in-place
+ void convertResampler(void *dst, /*not-a-const*/ void *src, size_t frames);
+
+ // user provided information
+ audio_channel_mask_t mSrcChannelMask;
+ audio_format_t mSrcFormat;
+ uint32_t mSrcSampleRate;
+ audio_channel_mask_t mDstChannelMask;
+ audio_format_t mDstFormat;
+ uint32_t mDstSampleRate;
+
+ // derived information
+ uint32_t mSrcChannelCount;
+ uint32_t mDstChannelCount;
+ size_t mDstFrameSize;
+
+ // format conversion buffer
+ void *mBuf;
+ size_t mBufFrames;
+ size_t mBufFrameSize;
+
+ // resampler info
+ AudioResampler *mResampler;
+
+ bool mIsLegacyDownmix; // legacy stereo to mono conversion needed
+ bool mIsLegacyUpmix; // legacy mono to stereo conversion needed
+ bool mRequiresFloat; // data processing requires float (e.g. resampler)
+ PassthruBufferProvider *mInputConverterProvider; // converts input to float
+ int8_t mIdxAry[sizeof(uint32_t) * 8]; // used for channel mask conversion
+};
+
+// ----------------------------------------------------------------------------
+} // namespace android
+
+#endif // ANDROID_RECORD_BUFFER_CONVERTER_H
diff --git a/media/libmedia/include/RingBuffer.h b/media/libmedia/include/RingBuffer.h
new file mode 100644
index 0000000..4d92d87
--- /dev/null
+++ b/media/libmedia/include/RingBuffer.h
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2015 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_SERVICE_UTILS_RING_BUFFER_H
+#define ANDROID_SERVICE_UTILS_RING_BUFFER_H
+
+#include <utils/Log.h>
+#include <cutils/compiler.h>
+
+#include <iterator>
+#include <utility>
+#include <vector>
+
+namespace android {
+
+/**
+ * A RingBuffer class that maintains an array of objects that can grow up to a certain size.
+ * Elements added to the RingBuffer are inserted in the logical front of the buffer, and
+ * invalidate all current iterators for that RingBuffer object.
+ */
+template <class T>
+class RingBuffer final {
+public:
+
+ /**
+ * Construct a RingBuffer that can grow up to the given length.
+ */
+ explicit RingBuffer(size_t length);
+
+ /**
+ * Forward iterator to this class. Implements an std:forward_iterator.
+ */
+ class iterator : public std::iterator<std::forward_iterator_tag, T> {
+ public:
+ iterator(T* ptr, size_t size, size_t pos, size_t ctr);
+
+ iterator& operator++();
+
+ iterator operator++(int);
+
+ bool operator==(const iterator& rhs);
+
+ bool operator!=(const iterator& rhs);
+
+ T& operator*();
+
+ T* operator->();
+
+ private:
+ T* mPtr;
+ size_t mSize;
+ size_t mPos;
+ size_t mCtr;
+ };
+
+ /**
+ * Constant forward iterator to this class. Implements an std:forward_iterator.
+ */
+ class const_iterator : public std::iterator<std::forward_iterator_tag, T> {
+ public:
+ const_iterator(const T* ptr, size_t size, size_t pos, size_t ctr);
+
+ const_iterator& operator++();
+
+ const_iterator operator++(int);
+
+ bool operator==(const const_iterator& rhs);
+
+ bool operator!=(const const_iterator& rhs);
+
+ const T& operator*();
+
+ const T* operator->();
+
+ private:
+ const T* mPtr;
+ size_t mSize;
+ size_t mPos;
+ size_t mCtr;
+ };
+
+ /**
+ * Adds item to the front of this RingBuffer. If the RingBuffer is at its maximum length,
+ * this will result in the last element being replaced (this is done using the element's
+ * assignment operator).
+ *
+ * All current iterators are invalidated.
+ */
+ void add(const T& item);
+
+ /**
+ * Moves item to the front of this RingBuffer. Following a call to this, item should no
+ * longer be used. If the RingBuffer is at its maximum length, this will result in the
+ * last element being replaced (this is done using the element's assignment operator).
+ *
+ * All current iterators are invalidated.
+ */
+ void add(T&& item);
+
+ /**
+ * Construct item in-place in the front of this RingBuffer using the given arguments. If
+ * the RingBuffer is at its maximum length, this will result in the last element being
+ * replaced (this is done using the element's assignment operator).
+ *
+ * All current iterators are invalidated.
+ */
+ template <class... Args>
+ void emplace(Args&&... args);
+
+ /**
+ * Get an iterator to the front of this RingBuffer.
+ */
+ iterator begin();
+
+ /**
+ * Get an iterator to the end of this RingBuffer.
+ */
+ iterator end();
+
+ /**
+ * Get a const_iterator to the front of this RingBuffer.
+ */
+ const_iterator begin() const;
+
+ /**
+ * Get a const_iterator to the end of this RingBuffer.
+ */
+ const_iterator end() const;
+
+ /**
+ * Return a reference to the element at a given index. If the index is out of range for
+ * this ringbuffer, [0, size), the behavior for this is undefined.
+ */
+ T& operator[](size_t index);
+
+ /**
+ * Return a const reference to the element at a given index. If the index is out of range
+ * for this ringbuffer, [0, size), the behavior for this is undefined.
+ */
+ const T& operator[](size_t index) const;
+
+ /**
+ * Return the current size of this RingBuffer.
+ */
+ size_t size() const;
+
+ /**
+ * Remove all elements from this RingBuffer and set the size to 0.
+ */
+ void clear();
+
+private:
+ size_t mFrontIdx;
+ size_t mMaxBufferSize;
+ std::vector<T> mBuffer;
+}; // class RingBuffer
+
+
+template <class T>
+RingBuffer<T>::RingBuffer(size_t length) : mFrontIdx{0}, mMaxBufferSize{length} {}
+
+template <class T>
+RingBuffer<T>::iterator::iterator(T* ptr, size_t size, size_t pos, size_t ctr) :
+ mPtr{ptr}, mSize{size}, mPos{pos}, mCtr{ctr} {}
+
+template <class T>
+typename RingBuffer<T>::iterator& RingBuffer<T>::iterator::operator++() {
+ ++mCtr;
+
+ if (CC_UNLIKELY(mCtr == mSize)) {
+ mPos = mSize;
+ return *this;
+ }
+
+ mPos = ((CC_UNLIKELY(mPos == 0)) ? mSize - 1 : mPos - 1);
+ return *this;
+}
+
+template <class T>
+typename RingBuffer<T>::iterator RingBuffer<T>::iterator::operator++(int) {
+ iterator tmp{mPtr, mSize, mPos, mCtr};
+ ++(*this);
+ return tmp;
+}
+
+template <class T>
+bool RingBuffer<T>::iterator::operator==(const iterator& rhs) {
+ return (mPtr + mPos) == (rhs.mPtr + rhs.mPos);
+}
+
+template <class T>
+bool RingBuffer<T>::iterator::operator!=(const iterator& rhs) {
+ return (mPtr + mPos) != (rhs.mPtr + rhs.mPos);
+}
+
+template <class T>
+T& RingBuffer<T>::iterator::operator*() {
+ return *(mPtr + mPos);
+}
+
+template <class T>
+T* RingBuffer<T>::iterator::operator->() {
+ return mPtr + mPos;
+}
+
+template <class T>
+RingBuffer<T>::const_iterator::const_iterator(const T* ptr, size_t size, size_t pos, size_t ctr) :
+ mPtr{ptr}, mSize{size}, mPos{pos}, mCtr{ctr} {}
+
+template <class T>
+typename RingBuffer<T>::const_iterator& RingBuffer<T>::const_iterator::operator++() {
+ ++mCtr;
+
+ if (CC_UNLIKELY(mCtr == mSize)) {
+ mPos = mSize;
+ return *this;
+ }
+
+ mPos = ((CC_UNLIKELY(mPos == 0)) ? mSize - 1 : mPos - 1);
+ return *this;
+}
+
+template <class T>
+typename RingBuffer<T>::const_iterator RingBuffer<T>::const_iterator::operator++(int) {
+ const_iterator tmp{mPtr, mSize, mPos, mCtr};
+ ++(*this);
+ return tmp;
+}
+
+template <class T>
+bool RingBuffer<T>::const_iterator::operator==(const const_iterator& rhs) {
+ return (mPtr + mPos) == (rhs.mPtr + rhs.mPos);
+}
+
+template <class T>
+bool RingBuffer<T>::const_iterator::operator!=(const const_iterator& rhs) {
+ return (mPtr + mPos) != (rhs.mPtr + rhs.mPos);
+}
+
+template <class T>
+const T& RingBuffer<T>::const_iterator::operator*() {
+ return *(mPtr + mPos);
+}
+
+template <class T>
+const T* RingBuffer<T>::const_iterator::operator->() {
+ return mPtr + mPos;
+}
+
+template <class T>
+void RingBuffer<T>::add(const T& item) {
+ if (mBuffer.size() < mMaxBufferSize) {
+ mBuffer.push_back(item);
+ mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize);
+ return;
+ }
+
+ mBuffer[mFrontIdx] = item;
+ mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize);
+}
+
+template <class T>
+void RingBuffer<T>::add(T&& item) {
+ if (mBuffer.size() != mMaxBufferSize) {
+ mBuffer.push_back(std::forward<T>(item));
+ mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize);
+ return;
+ }
+
+ // Only works for types with move assignment operator
+ mBuffer[mFrontIdx] = std::forward<T>(item);
+ mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize);
+}
+
+template <class T>
+template <class... Args>
+void RingBuffer<T>::emplace(Args&&... args) {
+ if (mBuffer.size() != mMaxBufferSize) {
+ mBuffer.emplace_back(std::forward<Args>(args)...);
+ mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize);
+ return;
+ }
+
+ // Only works for types with move assignment operator
+ mBuffer[mFrontIdx] = T(std::forward<Args>(args)...);
+ mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize);
+}
+
+template <class T>
+typename RingBuffer<T>::iterator RingBuffer<T>::begin() {
+ size_t tmp = (mBuffer.size() == 0) ? 0 : mBuffer.size() - 1;
+ return iterator(mBuffer.data(), mBuffer.size(), (mFrontIdx == 0) ? tmp : mFrontIdx - 1, 0);
+}
+
+template <class T>
+typename RingBuffer<T>::iterator RingBuffer<T>::end() {
+ size_t s = mBuffer.size();
+ return iterator(mBuffer.data(), s, s, s);
+}
+
+template <class T>
+typename RingBuffer<T>::const_iterator RingBuffer<T>::begin() const {
+ size_t tmp = (mBuffer.size() == 0) ? 0 : mBuffer.size() - 1;
+ return const_iterator(mBuffer.data(), mBuffer.size(),
+ (mFrontIdx == 0) ? tmp : mFrontIdx - 1, 0);
+}
+
+template <class T>
+typename RingBuffer<T>::const_iterator RingBuffer<T>::end() const {
+ size_t s = mBuffer.size();
+ return const_iterator(mBuffer.data(), s, s, s);
+}
+
+template <class T>
+T& RingBuffer<T>::operator[](size_t index) {
+ LOG_ALWAYS_FATAL_IF(index >= mBuffer.size(), "Index %zu out of bounds, size is %zu.",
+ index, mBuffer.size());
+ size_t pos = (index >= mFrontIdx) ?
+ mBuffer.size() - 1 - (index - mFrontIdx) : mFrontIdx - 1 - index;
+ return mBuffer[pos];
+}
+
+template <class T>
+const T& RingBuffer<T>::operator[](size_t index) const {
+ LOG_ALWAYS_FATAL_IF(index >= mBuffer.size(), "Index %zu out of bounds, size is %zu.",
+ index, mBuffer.size());
+ size_t pos = (index >= mFrontIdx) ?
+ mBuffer.size() - 1 - (index - mFrontIdx) : mFrontIdx - 1 - index;
+ return mBuffer[pos];
+}
+
+template <class T>
+size_t RingBuffer<T>::size() const {
+ return mBuffer.size();
+}
+
+template <class T>
+void RingBuffer<T>::clear() {
+ mBuffer.clear();
+ mFrontIdx = 0;
+}
+
+}; // namespace android
+
+#endif // ANDROID_SERVICE_UTILS_RING_BUFFER_H
+
+
diff --git a/media/libmedia/include/SharedLibrary.h b/media/libmedia/include/SharedLibrary.h
new file mode 100644
index 0000000..fd02203
--- /dev/null
+++ b/media/libmedia/include/SharedLibrary.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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 SHARED_LIBRARY_H_
+#define SHARED_LIBRARY_H_
+
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+ class SharedLibrary : public RefBase {
+ public:
+ explicit SharedLibrary(const String8 &path);
+ ~SharedLibrary();
+
+ bool operator!() const;
+ void *lookup(const char *symbol) const;
+ const char *lastError() const;
+
+ private:
+ void *mLibHandle;
+ DISALLOW_EVIL_CONSTRUCTORS(SharedLibrary);
+ };
+};
+
+#endif // SHARED_LIBRARY_H_
diff --git a/media/libmedia/include/SingleStateQueue.h b/media/libmedia/include/SingleStateQueue.h
new file mode 100644
index 0000000..d423962
--- /dev/null
+++ b/media/libmedia/include/SingleStateQueue.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2012 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 SINGLE_STATE_QUEUE_H
+#define SINGLE_STATE_QUEUE_H
+
+// Non-blocking single element state queue, or
+// Non-blocking single-reader / single-writer multi-word atomic load / store
+
+#include <stdint.h>
+#include <cutils/atomic.h>
+
+namespace android {
+
+template<typename T> class SingleStateQueue {
+
+public:
+
+ class Mutator;
+ class Observer;
+
+ enum SSQ_STATUS {
+ SSQ_PENDING, /* = 0 */
+ SSQ_READ,
+ SSQ_DONE,
+ };
+
+ struct Shared {
+ // needs to be part of a union so don't define constructor or destructor
+
+ friend class Mutator;
+ friend class Observer;
+
+private:
+ void init() { mAck = 0; mSequence = 0; }
+
+ volatile int32_t mAck;
+ volatile int32_t mSequence;
+ T mValue;
+ };
+
+ class Mutator {
+ public:
+ Mutator(Shared *shared)
+ : mSequence(0), mShared(shared)
+ {
+ // exactly one of Mutator and Observer must initialize, currently it is Observer
+ // shared->init();
+ }
+
+ // push new value onto state queue, overwriting previous value;
+ // returns a sequence number which can be used with ack()
+ int32_t push(const T& value)
+ {
+ Shared *shared = mShared;
+ int32_t sequence = mSequence;
+ sequence++;
+ android_atomic_acquire_store(sequence, &shared->mSequence);
+ shared->mValue = value;
+ sequence++;
+ android_atomic_release_store(sequence, &shared->mSequence);
+ mSequence = sequence;
+ // consider signalling a futex here, if we know that observer is waiting
+ return sequence;
+ }
+
+ // returns the status of the last state push. This may be a stale value.
+ //
+ // SSQ_PENDING, or 0, means it has not been observed
+ // SSQ_READ means it has been read
+ // SSQ_DONE means it has been acted upon, after Observer::done() is called
+ enum SSQ_STATUS ack() const
+ {
+ // in the case of SSQ_DONE, prevent any subtle data-races of subsequent reads
+ // being performed (out-of-order) before the ack read, should the caller be
+ // depending on sequentiality of reads.
+ const int32_t ack = android_atomic_acquire_load(&mShared->mAck);
+ return ack - mSequence & ~1 ? SSQ_PENDING /* seq differ */ :
+ ack & 1 ? SSQ_DONE : SSQ_READ;
+ }
+
+ // return true if a push with specified sequence number or later has been observed
+ bool ack(int32_t sequence) const
+ {
+ // this relies on 2's complement rollover to detect an ancient sequence number
+ return mShared->mAck - sequence >= 0;
+ }
+
+ private:
+ int32_t mSequence;
+ Shared * const mShared;
+ };
+
+ class Observer {
+ public:
+ Observer(Shared *shared)
+ : mSequence(0), mSeed(1), mShared(shared)
+ {
+ // exactly one of Mutator and Observer must initialize, currently it is Observer
+ shared->init();
+ }
+
+ // return true if value has changed
+ bool poll(T& value)
+ {
+ Shared *shared = mShared;
+ int32_t before = shared->mSequence;
+ if (before == mSequence) {
+ return false;
+ }
+ for (int tries = 0; ; ) {
+ const int MAX_TRIES = 5;
+ if (before & 1) {
+ if (++tries >= MAX_TRIES) {
+ return false;
+ }
+ before = shared->mSequence;
+ } else {
+ android_memory_barrier();
+ T temp = shared->mValue;
+ int32_t after = android_atomic_release_load(&shared->mSequence);
+ if (after == before) {
+ value = temp;
+ shared->mAck = before;
+ mSequence = before; // mSequence is even after poll success
+ return true;
+ }
+ if (++tries >= MAX_TRIES) {
+ return false;
+ }
+ before = after;
+ }
+ }
+ }
+
+ // (optional) used to indicate to the Mutator that the state that has been polled
+ // has also been acted upon.
+ void done()
+ {
+ const int32_t ack = mShared->mAck + 1;
+ // ensure all previous writes have been performed.
+ android_atomic_release_store(ack, &mShared->mAck); // mSequence is odd after "done"
+ }
+
+ private:
+ int32_t mSequence;
+ int mSeed; // for PRNG
+ Shared * const mShared;
+ };
+
+#if 0
+ SingleStateQueue(void /*Shared*/ *shared);
+ /*virtual*/ ~SingleStateQueue() { }
+
+ static size_t size() { return sizeof(Shared); }
+#endif
+
+};
+
+} // namespace android
+
+#endif // SINGLE_STATE_QUEUE_H
diff --git a/media/libmedia/include/StringArray.h b/media/libmedia/include/StringArray.h
new file mode 100644
index 0000000..48d98bf
--- /dev/null
+++ b/media/libmedia/include/StringArray.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+//
+// Sortable array of strings. STL-ish, but STL-free.
+//
+#ifndef _LIBS_MEDIA_STRING_ARRAY_H
+#define _LIBS_MEDIA_STRING_ARRAY_H
+
+#include <stdlib.h>
+#include <string.h>
+
+namespace android {
+
+//
+// An expanding array of strings. Add, get, sort, delete.
+//
+class StringArray {
+public:
+ StringArray();
+ virtual ~StringArray();
+
+ //
+ // Add a string. A copy of the string is made.
+ //
+ bool push_back(const char* str);
+
+ //
+ // Delete an entry.
+ //
+ void erase(int idx);
+
+ //
+ // Sort the array.
+ //
+ void sort(int (*compare)(const void*, const void*));
+
+ //
+ // Pass this to the sort routine to do an ascending alphabetical sort.
+ //
+ static int cmpAscendingAlpha(const void* pstr1, const void* pstr2);
+
+ //
+ // Get the #of items in the array.
+ //
+ inline int size(void) const { return mCurrent; }
+
+ //
+ // Return entry N.
+ // [should use operator[] here]
+ //
+ const char* getEntry(int idx) const {
+ return (unsigned(idx) >= unsigned(mCurrent)) ? NULL : mArray[idx];
+ }
+
+ //
+ // Set entry N to specified string.
+ // [should use operator[] here]
+ //
+ void setEntry(int idx, const char* str);
+
+private:
+ int mMax;
+ int mCurrent;
+ char** mArray;
+};
+
+}; // namespace android
+
+#endif // _LIBS_MEDIA_STRING_ARRAY_H
diff --git a/media/libmedia/include/TypeConverter.h b/media/libmedia/include/TypeConverter.h
new file mode 100644
index 0000000..e262eef
--- /dev/null
+++ b/media/libmedia/include/TypeConverter.h
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2016 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_TYPE_CONVERTER_H_
+#define ANDROID_TYPE_CONVERTER_H_
+
+#include <string>
+#include <string.h>
+
+#include <system/audio.h>
+#include <utils/Log.h>
+#include <utils/Vector.h>
+#include <utils/SortedVector.h>
+
+#include "convert.h"
+#include "AudioParameter.h"
+
+namespace android {
+
+struct SampleRateTraits
+{
+ typedef uint32_t Type;
+ typedef SortedVector<Type> Collection;
+};
+struct DeviceTraits
+{
+ typedef audio_devices_t Type;
+ typedef Vector<Type> Collection;
+};
+struct OutputDeviceTraits : public DeviceTraits {};
+struct InputDeviceTraits : public DeviceTraits {};
+struct OutputFlagTraits
+{
+ typedef audio_output_flags_t Type;
+ typedef Vector<Type> Collection;
+};
+struct InputFlagTraits
+{
+ typedef audio_input_flags_t Type;
+ typedef Vector<Type> Collection;
+};
+struct FormatTraits
+{
+ typedef audio_format_t Type;
+ typedef Vector<Type> Collection;
+};
+struct ChannelTraits
+{
+ typedef audio_channel_mask_t Type;
+ typedef SortedVector<Type> Collection;
+};
+struct OutputChannelTraits : public ChannelTraits {};
+struct InputChannelTraits : public ChannelTraits {};
+struct ChannelIndexTraits : public ChannelTraits {};
+struct GainModeTraits
+{
+ typedef audio_gain_mode_t Type;
+ typedef Vector<Type> Collection;
+};
+struct StreamTraits
+{
+ typedef audio_stream_type_t Type;
+ typedef Vector<Type> Collection;
+};
+struct AudioModeTraits
+{
+ typedef audio_mode_t Type;
+ typedef Vector<Type> Collection;
+};
+struct UsageTraits
+{
+ typedef audio_usage_t Type;
+ typedef Vector<Type> Collection;
+};
+struct SourceTraits
+{
+ typedef audio_source_t Type;
+ typedef Vector<Type> Collection;
+};
+template <typename T>
+struct DefaultTraits
+{
+ typedef T Type;
+ typedef Vector<Type> Collection;
+};
+
+template <class Traits>
+static void collectionFromString(const std::string &str, typename Traits::Collection &collection,
+ const char *del = AudioParameter::valueListSeparator)
+{
+ char *literal = strdup(str.c_str());
+ for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) {
+ typename Traits::Type value;
+ if (utilities::convertTo<std::string, typename Traits::Type >(cstr, value)) {
+ collection.add(value);
+ }
+ }
+ free(literal);
+}
+
+template <class Traits>
+class TypeConverter
+{
+public:
+ static bool toString(const typename Traits::Type &value, std::string &str);
+
+ static bool fromString(const std::string &str, typename Traits::Type &result);
+
+ static void collectionFromString(const std::string &str,
+ typename Traits::Collection &collection,
+ const char *del = AudioParameter::valueListSeparator);
+
+ static uint32_t maskFromString(
+ const std::string &str, const char *del = AudioParameter::valueListSeparator);
+
+ static void maskToString(
+ uint32_t mask, std::string &str, const char *del = AudioParameter::valueListSeparator);
+
+protected:
+ struct Table {
+ const char *literal;
+ typename Traits::Type value;
+ };
+
+ static const Table mTable[];
+};
+
+template <class Traits>
+inline bool TypeConverter<Traits>::toString(const typename Traits::Type &value, std::string &str)
+{
+ for (size_t i = 0; mTable[i].literal; i++) {
+ if (mTable[i].value == value) {
+ str = mTable[i].literal;
+ return true;
+ }
+ }
+ char result[64];
+ snprintf(result, sizeof(result), "Unknown enum value %d", value);
+ str = result;
+ return false;
+}
+
+template <class Traits>
+inline bool TypeConverter<Traits>::fromString(const std::string &str, typename Traits::Type &result)
+{
+ for (size_t i = 0; mTable[i].literal; i++) {
+ if (strcmp(mTable[i].literal, str.c_str()) == 0) {
+ ALOGV("stringToEnum() found %s", mTable[i].literal);
+ result = mTable[i].value;
+ return true;
+ }
+ }
+ return false;
+}
+
+template <class Traits>
+inline void TypeConverter<Traits>::collectionFromString(const std::string &str,
+ typename Traits::Collection &collection,
+ const char *del)
+{
+ char *literal = strdup(str.c_str());
+
+ for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) {
+ typename Traits::Type value;
+ if (fromString(cstr, value)) {
+ collection.add(value);
+ }
+ }
+ free(literal);
+}
+
+template <class Traits>
+inline uint32_t TypeConverter<Traits>::maskFromString(const std::string &str, const char *del)
+{
+ char *literal = strdup(str.c_str());
+ uint32_t value = 0;
+ for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) {
+ typename Traits::Type type;
+ if (fromString(cstr, type)) {
+ value |= static_cast<uint32_t>(type);
+ }
+ }
+ free(literal);
+ return value;
+}
+
+template <class Traits>
+inline void TypeConverter<Traits>::maskToString(uint32_t mask, std::string &str, const char *del)
+{
+ if (mask != 0) {
+ bool first_flag = true;
+ for (size_t i = 0; mTable[i].literal; i++) {
+ if (mTable[i].value != 0 && (mask & mTable[i].value) == mTable[i].value) {
+ if (!first_flag) str += del;
+ first_flag = false;
+ str += mTable[i].literal;
+ }
+ }
+ } else {
+ toString(static_cast<typename Traits::Type>(0), str);
+ }
+}
+
+typedef TypeConverter<OutputDeviceTraits> OutputDeviceConverter;
+typedef TypeConverter<InputDeviceTraits> InputDeviceConverter;
+typedef TypeConverter<OutputFlagTraits> OutputFlagConverter;
+typedef TypeConverter<InputFlagTraits> InputFlagConverter;
+typedef TypeConverter<FormatTraits> FormatConverter;
+typedef TypeConverter<OutputChannelTraits> OutputChannelConverter;
+typedef TypeConverter<InputChannelTraits> InputChannelConverter;
+typedef TypeConverter<ChannelIndexTraits> ChannelIndexConverter;
+typedef TypeConverter<GainModeTraits> GainModeConverter;
+typedef TypeConverter<StreamTraits> StreamTypeConverter;
+typedef TypeConverter<AudioModeTraits> AudioModeConverter;
+typedef TypeConverter<UsageTraits> UsageTypeConverter;
+typedef TypeConverter<SourceTraits> SourceTypeConverter;
+
+bool deviceFromString(const std::string& literalDevice, audio_devices_t& device);
+
+bool deviceToString(audio_devices_t device, std::string& literalDevice);
+
+SampleRateTraits::Collection samplingRatesFromString(
+ const std::string &samplingRates, const char *del = AudioParameter::valueListSeparator);
+
+FormatTraits::Collection formatsFromString(
+ const std::string &formats, const char *del = AudioParameter::valueListSeparator);
+
+audio_format_t formatFromString(
+ const std::string &literalFormat, audio_format_t defaultFormat = AUDIO_FORMAT_DEFAULT);
+
+audio_channel_mask_t channelMaskFromString(const std::string &literalChannels);
+
+ChannelTraits::Collection channelMasksFromString(
+ const std::string &channels, const char *del = AudioParameter::valueListSeparator);
+
+InputChannelTraits::Collection inputChannelMasksFromString(
+ const std::string &inChannels, const char *del = AudioParameter::valueListSeparator);
+
+OutputChannelTraits::Collection outputChannelMasksFromString(
+ const std::string &outChannels, const char *del = AudioParameter::valueListSeparator);
+
+}; // namespace android
+
+#endif /*ANDROID_TYPE_CONVERTER_H_*/
diff --git a/media/libmedia/include/Visualizer.h b/media/libmedia/include/Visualizer.h
new file mode 100644
index 0000000..f8f4f50
--- /dev/null
+++ b/media/libmedia/include/Visualizer.h
@@ -0,0 +1,178 @@
+/*
+ * 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_MEDIA_VISUALIZER_H
+#define ANDROID_MEDIA_VISUALIZER_H
+
+#include <media/AudioEffect.h>
+#include <system/audio_effects/effect_visualizer.h>
+#include <utils/Thread.h>
+
+/**
+ * The Visualizer class enables application to retrieve part of the currently playing audio for
+ * visualization purpose. It is not an audio recording interface and only returns partial and low
+ * quality audio content. However, to protect privacy of certain audio data (e.g voice mail) the use
+ * of the visualizer requires the permission android.permission.RECORD_AUDIO.
+ * The audio session ID passed to the constructor indicates which audio content should be
+ * visualized:
+ * - If the session is 0, the audio output mix is visualized
+ * - If the session is not 0, the audio from a particular MediaPlayer or AudioTrack
+ * using this audio session is visualized
+ * Two types of representation of audio content can be captured:
+ * - Waveform data: consecutive 8-bit (unsigned) mono samples by using the getWaveForm() method
+ * - Frequency data: 8-bit magnitude FFT by using the getFft() method
+ *
+ * The length of the capture can be retrieved or specified by calling respectively
+ * getCaptureSize() and setCaptureSize() methods. Note that the size of the FFT
+ * is half of the specified capture size but both sides of the spectrum are returned yielding in a
+ * number of bytes equal to the capture size. The capture size must be a power of 2 in the range
+ * returned by getMinCaptureSize() and getMaxCaptureSize().
+ * In addition to the polling capture mode, a callback mode is also available by installing a
+ * callback function by use of the setCaptureCallBack() method. The rate at which the callback
+ * is called as well as the type of data returned is specified.
+ * Before capturing data, the Visualizer must be enabled by calling the setEnabled() method.
+ * When data capture is not needed any more, the Visualizer should be disabled.
+ */
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class Visualizer: public AudioEffect {
+public:
+
+ enum callback_flags {
+ CAPTURE_WAVEFORM = 0x00000001, // capture callback returns a PCM wave form
+ CAPTURE_FFT = 0x00000002, // apture callback returns a frequency representation
+ CAPTURE_CALL_JAVA = 0x00000004 // the callback thread can call java
+ };
+
+
+ /* Constructor.
+ * See AudioEffect constructor for details on parameters.
+ */
+ Visualizer(const String16& opPackageName,
+ int32_t priority = 0,
+ effect_callback_t cbf = NULL,
+ void* user = NULL,
+ audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX);
+
+ ~Visualizer();
+
+ virtual status_t setEnabled(bool enabled);
+
+ // maximum capture size in samples
+ static uint32_t getMaxCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MAX; }
+ // minimum capture size in samples
+ static uint32_t getMinCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MIN; }
+ // maximum capture rate in millihertz
+ static uint32_t getMaxCaptureRate() { return CAPTURE_RATE_MAX; }
+
+ // callback used to return periodic PCM or FFT captures to the application. Either one or both
+ // types of data are returned (PCM and FFT) according to flags indicated when installing the
+ // callback. When a type of data is not present, the corresponding size (waveformSize or
+ // fftSize) is 0.
+ typedef void (*capture_cbk_t)(void* user,
+ uint32_t waveformSize,
+ uint8_t *waveform,
+ uint32_t fftSize,
+ uint8_t *fft,
+ uint32_t samplingrate);
+
+ // install a callback to receive periodic captures. The capture rate is specified in milliHertz
+ // and the capture format is according to flags (see callback_flags).
+ status_t setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate);
+
+ // set the capture size capture size must be a power of two in the range
+ // [VISUALIZER_CAPTURE_SIZE_MAX. VISUALIZER_CAPTURE_SIZE_MIN]
+ // must be called when the visualizer is not enabled
+ status_t setCaptureSize(uint32_t size);
+ uint32_t getCaptureSize() { return mCaptureSize; }
+
+ // returns the capture rate indicated when installing the callback
+ uint32_t getCaptureRate() { return mCaptureRate; }
+
+ // returns the sampling rate of the audio being captured
+ uint32_t getSamplingRate() { return mSampleRate; }
+
+ // set the way volume affects the captured data
+ // mode must one of VISUALIZER_SCALING_MODE_NORMALIZED,
+ // VISUALIZER_SCALING_MODE_AS_PLAYED
+ status_t setScalingMode(uint32_t mode);
+ uint32_t getScalingMode() { return mScalingMode; }
+
+ // set which measurements are done on the audio buffers processed by the effect.
+ // valid measurements (mask): MEASUREMENT_MODE_PEAK_RMS
+ status_t setMeasurementMode(uint32_t mode);
+ uint32_t getMeasurementMode() { return mMeasurementMode; }
+
+ // return a set of int32_t measurements
+ status_t getIntMeasurements(uint32_t type, uint32_t number, int32_t *measurements);
+
+ // return a capture in PCM 8 bit unsigned format. The size of the capture is equal to
+ // getCaptureSize()
+ status_t getWaveForm(uint8_t *waveform);
+
+ // return a capture in FFT 8 bit signed format. The size of the capture is equal to
+ // getCaptureSize() but the length of the FFT is half of the size (both parts of the spectrum
+ // are returned
+ status_t getFft(uint8_t *fft);
+
+protected:
+ // from IEffectClient
+ virtual void controlStatusChanged(bool controlGranted);
+
+private:
+
+ static const uint32_t CAPTURE_RATE_MAX = 20000;
+ static const uint32_t CAPTURE_RATE_DEF = 10000;
+ static const uint32_t CAPTURE_SIZE_DEF = VISUALIZER_CAPTURE_SIZE_MAX;
+
+ /* internal class to handle the callback */
+ class CaptureThread : public Thread
+ {
+ public:
+ CaptureThread(Visualizer& receiver, uint32_t captureRate, bool bCanCallJava = false);
+
+ private:
+ friend class Visualizer;
+ virtual bool threadLoop();
+ Visualizer& mReceiver;
+ Mutex mLock;
+ uint32_t mSleepTimeUs;
+ };
+
+ status_t doFft(uint8_t *fft, uint8_t *waveform);
+ void periodicCapture();
+ uint32_t initCaptureSize();
+
+ Mutex mCaptureLock;
+ uint32_t mCaptureRate;
+ uint32_t mCaptureSize;
+ uint32_t mSampleRate;
+ uint32_t mScalingMode;
+ uint32_t mMeasurementMode;
+ capture_cbk_t mCaptureCallBack;
+ void *mCaptureCbkUser;
+ sp<CaptureThread> mCaptureThread;
+ uint32_t mCaptureFlags;
+};
+
+
+}; // namespace android
+
+#endif // ANDROID_MEDIA_VISUALIZER_H
diff --git a/media/libmedia/include/convert.h b/media/libmedia/include/convert.h
new file mode 100644
index 0000000..980b5d5
--- /dev/null
+++ b/media/libmedia/include/convert.h
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#pragma once
+
+#include <limits>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <stdint.h>
+#include <cmath>
+
+namespace android
+{
+
+namespace utilities
+{
+
+/**
+ * Convert a given source type to a given destination type.
+ *
+ * String conversion to T reads the value of the type T in the given string.
+ * The function does not allow to have white spaces around the value to parse
+ * and tries to parse the whole string, which means that if some bytes were not
+ * read in the string, the function fails.
+ * Hexadecimal representation (ie. numbers starting with 0x) is supported only
+ * for integral types conversions.
+ *
+ * Numeric conversion to string formats the source value to decimal space.
+ *
+ * Vector to vector conversion calls convertTo on each element.
+ *
+ * @tparam srcType source type, default value is string type
+ * @tparam dstType destination type
+ * @param[in] input The source to convert from.
+ * @param[out] result Converted value if success, undefined on failure.
+ *
+ * @return true if conversion was successful, false otherwise.
+ */
+template <typename srcType, typename dstType>
+static inline bool convertTo(const srcType &input, dstType &result);
+
+/* details namespace is here to hide implementation details to header end user. It
+ * is NOT intended to be used outside. */
+namespace details
+{
+
+/** Helper class to limit instantiation of templates */
+template <typename T>
+struct ConversionFromStringAllowed;
+template <typename T>
+struct ConversionToStringAllowed;
+
+/* List of allowed types for conversion */
+template <>
+struct ConversionFromStringAllowed<bool> {};
+template <>
+struct ConversionFromStringAllowed<uint64_t> {};
+template <>
+struct ConversionFromStringAllowed<int64_t> {};
+template <>
+struct ConversionFromStringAllowed<uint32_t> {};
+template <>
+struct ConversionFromStringAllowed<int32_t> {};
+template <>
+struct ConversionFromStringAllowed<uint16_t> {};
+template <>
+struct ConversionFromStringAllowed<int16_t> {};
+template <>
+struct ConversionFromStringAllowed<float> {};
+template <>
+struct ConversionFromStringAllowed<double> {};
+
+template <>
+struct ConversionToStringAllowed<int64_t> {};
+template <>
+struct ConversionToStringAllowed<uint64_t> {};
+template <>
+struct ConversionToStringAllowed<uint32_t> {};
+template <>
+struct ConversionToStringAllowed<int32_t> {};
+template <>
+struct ConversionToStringAllowed<double> {};
+template <>
+struct ConversionToStringAllowed<float> {};
+
+/**
+ * Set the decimal precision to 10 digits.
+ * Note that this setting is aligned with Android Audio Parameter
+ * policy concerning float storage into string.
+ */
+static const uint32_t gFloatPrecision = 10;
+
+template <typename T>
+static inline bool fromString(const std::string &str, T &result)
+{
+ /* Check that conversion to that type is allowed.
+ * If this fails, this means that this template was not intended to be used
+ * with this type, thus that the result is undefined. */
+ ConversionFromStringAllowed<T>();
+
+ if (str.find_first_of(std::string("\r\n\t\v ")) != std::string::npos) {
+ return false;
+ }
+
+ /* Check for a '-' in string. If type is unsigned and a - is found, the
+ * parsing fails. This is made necessary because "-1" is read as 65535 for
+ * uint16_t, for example */
+ if (str.find("-") != std::string::npos
+ && !std::numeric_limits<T>::is_signed) {
+ return false;
+ }
+
+ std::stringstream ss(str);
+
+ /* Sadly, the stream conversion does not handle hexadecimal format, thus
+ * check is done manually */
+ if (str.substr(0, 2) == "0x") {
+ if (std::numeric_limits<T>::is_integer) {
+ ss >> std::hex >> result;
+ } else {
+ /* Conversion undefined for non integers */
+ return false;
+ }
+ } else {
+ ss >> result;
+ }
+
+ return ss.eof() && !ss.fail() && !ss.bad();
+}
+
+template <typename T>
+static inline bool toString(const T &value, std::string &str)
+{
+ /* Check that conversion from that type is allowed.
+ * If this fails, this means that this template was not intended to be used
+ * with this type, thus that the result is undefined. */
+ ConversionToStringAllowed<T>();
+
+ std::stringstream oss;
+ oss.precision(gFloatPrecision);
+ oss << value;
+ str = oss.str();
+ return !oss.fail() && !oss.bad();
+}
+
+template <typename srcType, typename dstType>
+class Converter;
+
+template <typename dstType>
+class Converter<std::string, dstType>
+{
+public:
+ static inline bool run(const std::string &str, dstType &result)
+ {
+ return fromString<dstType>(str, result);
+ }
+};
+
+template <typename srcType>
+class Converter<srcType, std::string>
+{
+public:
+ static inline bool run(const srcType &str, std::string &result)
+ {
+ return toString<srcType>(str, result);
+ }
+};
+
+/** Convert a vector by applying convertTo on each element.
+ *
+ * @tparam SrcElem Type of the src elements.
+ * @tparam DstElem Type of the destination elements.
+ */
+template <typename SrcElem, typename DstElem>
+class Converter<std::vector<SrcElem>, std::vector<DstElem> >
+{
+public:
+ typedef const std::vector<SrcElem> Src;
+ typedef std::vector<DstElem> Dst;
+
+ static inline bool run(Src &src, Dst &dst)
+ {
+ typedef typename Src::const_iterator SrcIt;
+ dst.clear();
+ dst.reserve(src.size());
+ for (SrcIt it = src.begin(); it != src.end(); ++it) {
+ DstElem dstElem;
+ if (not convertTo(*it, dstElem)) {
+ return false;
+ }
+ dst.push_back(dstElem);
+ }
+ return true;
+ }
+};
+
+} // namespace details
+
+template <typename srcType, typename dstType>
+static inline bool convertTo(const srcType &input, dstType &result)
+{
+ return details::Converter<srcType, dstType>::run(input, result);
+}
+
+/**
+ * Specialization for int16_t of convertTo template function.
+ *
+ * This function follows the same paradigm than it's generic version.
+ *
+ * The specific implementation is made necessary because the stlport version of
+ * string streams is bugged and does not fail when giving overflowed values.
+ * This specialisation can be safely removed when stlport behaviour is fixed.
+ *
+ * @param[in] str the string to parse.
+ * @param[out] result reference to object where to store the result.
+ *
+ * @return true if conversion was successful, false otherwise.
+ */
+template <>
+inline bool convertTo<std::string, int16_t>(const std::string &str, int16_t &result)
+{
+ int64_t res;
+
+ if (!convertTo<std::string, int64_t>(str, res)) {
+ return false;
+ }
+
+ if (res > std::numeric_limits<int16_t>::max() || res < std::numeric_limits<int16_t>::min()) {
+ return false;
+ }
+
+ result = static_cast<int16_t>(res);
+ return true;
+}
+
+/**
+ * Specialization for float of convertTo template function.
+ *
+ * This function follows the same paradigm than it's generic version and is
+ * based on it but makes furthers checks on the returned value.
+ *
+ * The specific implementation is made necessary because the stlport conversion
+ * from string to float behaves differently than GNU STL: overflow produce
+ * +/-Infinity rather than an error.
+ *
+ * @param[in] str the string to parse.
+ * @param[out] result reference to object where to store the result.
+ *
+ * @return true if conversion was successful, false otherwise.
+ */
+template <>
+inline bool convertTo<std::string, float>(const std::string &str, float &result)
+{
+ if (!details::Converter<std::string, float>::run(str, result)) {
+ return false;
+ }
+
+ if (std::abs(result) == std::numeric_limits<float>::infinity() ||
+ result == std::numeric_limits<float>::quiet_NaN()) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Specialization for double of convertTo template function.
+ *
+ * This function follows the same paradigm than it's generic version and is
+ * based on it but makes furthers checks on the returned value.
+ *
+ * The specific implementation is made necessary because the stlport conversion
+ * from string to double behaves differently than GNU STL: overflow produce
+ * +/-Infinity rather than an error.
+ *
+ * @param[in] str the string to parse.
+ * @param[out] result reference to object where to store the result.
+ *
+ * @return true if conversion was successful, false otherwise.
+ */
+template <>
+inline bool convertTo<std::string, double>(const std::string &str, double &result)
+{
+ if (!details::Converter<std::string, double>::run(str, result)) {
+ return false;
+ }
+
+ if (std::abs(result) == std::numeric_limits<double>::infinity() ||
+ result == std::numeric_limits<double>::quiet_NaN()) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Specialization for boolean of convertTo template function.
+ *
+ * This function follows the same paradigm than it's generic version.
+ * This function accepts to parse boolean as "0/1" or "false/true" or
+ * "FALSE/TRUE".
+ * The specific implementation is made necessary because the behaviour of
+ * string streams when parsing boolean values is not sufficient to fit our
+ * requirements. Indeed, parsing "true" will correctly parse the value, but the
+ * end of stream is not reached which makes the ss.eof() fails in the generic
+ * implementation.
+ *
+ * @param[in] str the string to parse.
+ * @param[out] result reference to object where to store the result.
+ *
+ * @return true if conversion was successful, false otherwise.
+ */
+template <>
+inline bool convertTo<std::string, bool>(const std::string &str, bool &result)
+{
+ if (str == "0" || str == "FALSE" || str == "false") {
+ result = false;
+ return true;
+ }
+
+ if (str == "1" || str == "TRUE" || str == "true") {
+ result = true;
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Specialization for boolean to string of convertTo template function.
+ *
+ * This function follows the same paradigm than it's generic version.
+ * This function arbitrarily decides to return "false/true".
+ * It is compatible with the specialization from string to boolean.
+ *
+ * @param[in] isSet boolean to convert to a string.
+ * @param[out] result reference to object where to store the result.
+ *
+ * @return true if conversion was successful, false otherwise.
+ */
+template <>
+inline bool convertTo<bool, std::string>(const bool &isSet, std::string &result)
+{
+ result = isSet ? "true" : "false";
+ return true;
+}
+
+/**
+ * Specialization for string to string of convertTo template function.
+ *
+ * This function is a dummy conversion from string to string.
+ * In case of clients using template as well, this implementation avoids adding extra
+ * specialization to bypass the conversion from string to string.
+ *
+ * @param[in] str the string to parse.
+ * @param[out] result reference to object where to store the result.
+ *
+ * @return true if conversion was successful, false otherwise.
+ */
+template <>
+inline bool convertTo<std::string, std::string>(const std::string &str, std::string &result)
+{
+ result = str;
+ return true;
+}
+
+} // namespace utilities
+
+} // namespace android
diff --git a/media/libmedia/include/mediametadataretriever.h b/media/libmedia/include/mediametadataretriever.h
new file mode 100644
index 0000000..8ed07ee
--- /dev/null
+++ b/media/libmedia/include/mediametadataretriever.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2008 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 MEDIAMETADATARETRIEVER_H
+#define MEDIAMETADATARETRIEVER_H
+
+#include <utils/Errors.h> // for status_t
+#include <utils/threads.h>
+#include <binder/IMemory.h>
+#include <media/IMediaMetadataRetriever.h>
+
+namespace android {
+
+class IDataSource;
+struct IMediaHTTPService;
+class IMediaPlayerService;
+class IMediaMetadataRetriever;
+
+// Keep these in synch with the constants defined in MediaMetadataRetriever.java
+// class.
+enum {
+ METADATA_KEY_CD_TRACK_NUMBER = 0,
+ METADATA_KEY_ALBUM = 1,
+ METADATA_KEY_ARTIST = 2,
+ METADATA_KEY_AUTHOR = 3,
+ METADATA_KEY_COMPOSER = 4,
+ METADATA_KEY_DATE = 5,
+ METADATA_KEY_GENRE = 6,
+ METADATA_KEY_TITLE = 7,
+ METADATA_KEY_YEAR = 8,
+ METADATA_KEY_DURATION = 9,
+ METADATA_KEY_NUM_TRACKS = 10,
+ METADATA_KEY_WRITER = 11,
+ METADATA_KEY_MIMETYPE = 12,
+ METADATA_KEY_ALBUMARTIST = 13,
+ METADATA_KEY_DISC_NUMBER = 14,
+ METADATA_KEY_COMPILATION = 15,
+ METADATA_KEY_HAS_AUDIO = 16,
+ METADATA_KEY_HAS_VIDEO = 17,
+ METADATA_KEY_VIDEO_WIDTH = 18,
+ METADATA_KEY_VIDEO_HEIGHT = 19,
+ METADATA_KEY_BITRATE = 20,
+ METADATA_KEY_TIMED_TEXT_LANGUAGES = 21,
+ METADATA_KEY_IS_DRM = 22,
+ METADATA_KEY_LOCATION = 23,
+ METADATA_KEY_VIDEO_ROTATION = 24,
+ METADATA_KEY_CAPTURE_FRAMERATE = 25,
+
+ // Add more here...
+};
+
+class MediaMetadataRetriever: public RefBase
+{
+public:
+ MediaMetadataRetriever();
+ ~MediaMetadataRetriever();
+ void disconnect();
+
+ status_t setDataSource(
+ const sp<IMediaHTTPService> &httpService,
+ const char *dataSourceUrl,
+ const KeyedVector<String8, String8> *headers = NULL);
+
+ status_t setDataSource(int fd, int64_t offset, int64_t length);
+ status_t setDataSource(const sp<IDataSource>& dataSource);
+ sp<IMemory> getFrameAtTime(int64_t timeUs, int option);
+ sp<IMemory> extractAlbumArt();
+ const char* extractMetadata(int keyCode);
+
+private:
+ static const sp<IMediaPlayerService> getService();
+
+ class DeathNotifier: public IBinder::DeathRecipient
+ {
+ public:
+ DeathNotifier() {}
+ virtual ~DeathNotifier();
+ virtual void binderDied(const wp<IBinder>& who);
+ };
+
+ static sp<DeathNotifier> sDeathNotifier;
+ static Mutex sServiceLock;
+ static sp<IMediaPlayerService> sService;
+
+ Mutex mLock;
+ sp<IMediaMetadataRetriever> mRetriever;
+
+};
+
+}; // namespace android
+
+#endif // MEDIAMETADATARETRIEVER_H
diff --git a/media/libmedia/include/mediaplayer.h b/media/libmedia/include/mediaplayer.h
new file mode 100644
index 0000000..18d69a7
--- /dev/null
+++ b/media/libmedia/include/mediaplayer.h
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2007 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_MEDIAPLAYER_H
+#define ANDROID_MEDIAPLAYER_H
+
+#include <arpa/inet.h>
+
+#include <binder/IMemory.h>
+
+#include <media/AudioResamplerPublic.h>
+#include <media/BufferingSettings.h>
+#include <media/IMediaPlayerClient.h>
+#include <media/IMediaPlayer.h>
+#include <media/IMediaDeathNotifier.h>
+#include <media/IStreamSource.h>
+
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+struct ANativeWindow;
+
+namespace android {
+
+struct AVSyncSettings;
+class IGraphicBufferProducer;
+class Surface;
+
+enum media_event_type {
+ MEDIA_NOP = 0, // interface test message
+ MEDIA_PREPARED = 1,
+ MEDIA_PLAYBACK_COMPLETE = 2,
+ MEDIA_BUFFERING_UPDATE = 3,
+ MEDIA_SEEK_COMPLETE = 4,
+ MEDIA_SET_VIDEO_SIZE = 5,
+ MEDIA_STARTED = 6,
+ MEDIA_PAUSED = 7,
+ MEDIA_STOPPED = 8,
+ MEDIA_SKIPPED = 9,
+ MEDIA_TIMED_TEXT = 99,
+ MEDIA_ERROR = 100,
+ MEDIA_INFO = 200,
+ MEDIA_SUBTITLE_DATA = 201,
+ MEDIA_META_DATA = 202,
+ MEDIA_DRM_INFO = 210,
+};
+
+// Generic error codes for the media player framework. Errors are fatal, the
+// playback must abort.
+//
+// Errors are communicated back to the client using the
+// MediaPlayerListener::notify method defined below.
+// In this situation, 'notify' is invoked with the following:
+// 'msg' is set to MEDIA_ERROR.
+// 'ext1' should be a value from the enum media_error_type.
+// 'ext2' contains an implementation dependant error code to provide
+// more details. Should default to 0 when not used.
+//
+// The codes are distributed as follow:
+// 0xx: Reserved
+// 1xx: Android Player errors. Something went wrong inside the MediaPlayer.
+// 2xx: Media errors (e.g Codec not supported). There is a problem with the
+// media itself.
+// 3xx: Runtime errors. Some extraordinary condition arose making the playback
+// impossible.
+//
+enum media_error_type {
+ // 0xx
+ MEDIA_ERROR_UNKNOWN = 1,
+ // 1xx
+ MEDIA_ERROR_SERVER_DIED = 100,
+ // 2xx
+ MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200,
+ // 3xx
+};
+
+
+// Info and warning codes for the media player framework. These are non fatal,
+// the playback is going on but there might be some user visible issues.
+//
+// Info and warning messages are communicated back to the client using the
+// MediaPlayerListener::notify method defined below. In this situation,
+// 'notify' is invoked with the following:
+// 'msg' is set to MEDIA_INFO.
+// 'ext1' should be a value from the enum media_info_type.
+// 'ext2' contains an implementation dependant info code to provide
+// more details. Should default to 0 when not used.
+//
+// The codes are distributed as follow:
+// 0xx: Reserved
+// 7xx: Android Player info/warning (e.g player lagging behind.)
+// 8xx: Media info/warning (e.g media badly interleaved.)
+//
+enum media_info_type {
+ // 0xx
+ MEDIA_INFO_UNKNOWN = 1,
+ // The player was started because it was used as the next player for another
+ // player, which just completed playback
+ MEDIA_INFO_STARTED_AS_NEXT = 2,
+ // The player just pushed the very first video frame for rendering
+ MEDIA_INFO_RENDERING_START = 3,
+ // 7xx
+ // The video is too complex for the decoder: it can't decode frames fast
+ // enough. Possibly only the audio plays fine at this stage.
+ MEDIA_INFO_VIDEO_TRACK_LAGGING = 700,
+ // MediaPlayer is temporarily pausing playback internally in order to
+ // buffer more data.
+ MEDIA_INFO_BUFFERING_START = 701,
+ // MediaPlayer is resuming playback after filling buffers.
+ MEDIA_INFO_BUFFERING_END = 702,
+ // Bandwidth in recent past
+ MEDIA_INFO_NETWORK_BANDWIDTH = 703,
+
+ // 8xx
+ // Bad interleaving means that a media has been improperly interleaved or not
+ // interleaved at all, e.g has all the video samples first then all the audio
+ // ones. Video is playing but a lot of disk seek may be happening.
+ MEDIA_INFO_BAD_INTERLEAVING = 800,
+ // The media is not seekable (e.g live stream).
+ MEDIA_INFO_NOT_SEEKABLE = 801,
+ // New media metadata is available.
+ MEDIA_INFO_METADATA_UPDATE = 802,
+
+ //9xx
+ MEDIA_INFO_TIMED_TEXT_ERROR = 900,
+};
+
+
+
+enum media_player_states {
+ MEDIA_PLAYER_STATE_ERROR = 0,
+ MEDIA_PLAYER_IDLE = 1 << 0,
+ MEDIA_PLAYER_INITIALIZED = 1 << 1,
+ MEDIA_PLAYER_PREPARING = 1 << 2,
+ MEDIA_PLAYER_PREPARED = 1 << 3,
+ MEDIA_PLAYER_STARTED = 1 << 4,
+ MEDIA_PLAYER_PAUSED = 1 << 5,
+ MEDIA_PLAYER_STOPPED = 1 << 6,
+ MEDIA_PLAYER_PLAYBACK_COMPLETE = 1 << 7
+};
+
+// Keep KEY_PARAMETER_* in sync with MediaPlayer.java.
+// The same enum space is used for both set and get, in case there are future keys that
+// can be both set and get. But as of now, all parameters are either set only or get only.
+enum media_parameter_keys {
+ // Streaming/buffering parameters
+ KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS = 1100, // set only
+
+ // Return a Parcel containing a single int, which is the channel count of the
+ // audio track, or zero for error (e.g. no audio track) or unknown.
+ KEY_PARAMETER_AUDIO_CHANNEL_COUNT = 1200, // get only
+
+ // Playback rate expressed in permille (1000 is normal speed), saved as int32_t, with negative
+ // values used for rewinding or reverse playback.
+ KEY_PARAMETER_PLAYBACK_RATE_PERMILLE = 1300, // set only
+
+ // Set a Parcel containing the value of a parcelled Java AudioAttribute instance
+ KEY_PARAMETER_AUDIO_ATTRIBUTES = 1400 // set only
+};
+
+// Keep INVOKE_ID_* in sync with MediaPlayer.java.
+enum media_player_invoke_ids {
+ INVOKE_ID_GET_TRACK_INFO = 1,
+ INVOKE_ID_ADD_EXTERNAL_SOURCE = 2,
+ INVOKE_ID_ADD_EXTERNAL_SOURCE_FD = 3,
+ INVOKE_ID_SELECT_TRACK = 4,
+ INVOKE_ID_UNSELECT_TRACK = 5,
+ INVOKE_ID_SET_VIDEO_SCALING_MODE = 6,
+ INVOKE_ID_GET_SELECTED_TRACK = 7
+};
+
+// Keep MEDIA_TRACK_TYPE_* in sync with MediaPlayer.java.
+enum media_track_type {
+ MEDIA_TRACK_TYPE_UNKNOWN = 0,
+ MEDIA_TRACK_TYPE_VIDEO = 1,
+ MEDIA_TRACK_TYPE_AUDIO = 2,
+ MEDIA_TRACK_TYPE_TIMEDTEXT = 3,
+ MEDIA_TRACK_TYPE_SUBTITLE = 4,
+ MEDIA_TRACK_TYPE_METADATA = 5,
+};
+
+// ----------------------------------------------------------------------------
+// ref-counted object for callbacks
+class MediaPlayerListener: virtual public RefBase
+{
+public:
+ virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) = 0;
+};
+
+struct IMediaHTTPService;
+
+class MediaPlayer : public BnMediaPlayerClient,
+ public virtual IMediaDeathNotifier
+{
+public:
+ MediaPlayer();
+ ~MediaPlayer();
+ void died();
+ void disconnect();
+
+ status_t setDataSource(
+ const sp<IMediaHTTPService> &httpService,
+ const char *url,
+ const KeyedVector<String8, String8> *headers);
+
+ status_t setDataSource(int fd, int64_t offset, int64_t length);
+ status_t setDataSource(const sp<IDataSource> &source);
+ status_t setVideoSurfaceTexture(
+ const sp<IGraphicBufferProducer>& bufferProducer);
+ status_t setListener(const sp<MediaPlayerListener>& listener);
+ status_t getDefaultBufferingSettings(BufferingSettings* buffering /* nonnull */);
+ status_t getBufferingSettings(BufferingSettings* buffering /* nonnull */);
+ status_t setBufferingSettings(const BufferingSettings& buffering);
+ status_t prepare();
+ status_t prepareAsync();
+ status_t start();
+ status_t stop();
+ status_t pause();
+ bool isPlaying();
+ status_t setPlaybackSettings(const AudioPlaybackRate& rate);
+ status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */);
+ status_t setSyncSettings(const AVSyncSettings& sync, float videoFpsHint);
+ status_t getSyncSettings(
+ AVSyncSettings* sync /* nonnull */,
+ float* videoFps /* nonnull */);
+ status_t getVideoWidth(int *w);
+ status_t getVideoHeight(int *h);
+ status_t seekTo(
+ int msec,
+ MediaPlayerSeekMode mode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC);
+ status_t getCurrentPosition(int *msec);
+ status_t getDuration(int *msec);
+ status_t reset();
+ status_t setAudioStreamType(audio_stream_type_t type);
+ status_t getAudioStreamType(audio_stream_type_t *type);
+ status_t setLooping(int loop);
+ bool isLooping();
+ status_t setVolume(float leftVolume, float rightVolume);
+ void notify(int msg, int ext1, int ext2, const Parcel *obj = NULL);
+ status_t invoke(const Parcel& request, Parcel *reply);
+ status_t setMetadataFilter(const Parcel& filter);
+ status_t getMetadata(bool update_only, bool apply_filter, Parcel *metadata);
+ status_t setAudioSessionId(audio_session_t sessionId);
+ audio_session_t getAudioSessionId();
+ status_t setAuxEffectSendLevel(float level);
+ status_t attachAuxEffect(int effectId);
+ status_t setParameter(int key, const Parcel& request);
+ status_t getParameter(int key, Parcel* reply);
+ status_t setRetransmitEndpoint(const char* addrString, uint16_t port);
+ status_t setNextMediaPlayer(const sp<MediaPlayer>& player);
+
+ VolumeShaper::Status applyVolumeShaper(
+ const sp<VolumeShaper::Configuration>& configuration,
+ const sp<VolumeShaper::Operation>& operation);
+ sp<VolumeShaper::State> getVolumeShaperState(int id);
+ // Modular DRM
+ status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId);
+ status_t releaseDrm();
+
+private:
+ void clear_l();
+ status_t seekTo_l(int msec, MediaPlayerSeekMode mode);
+ status_t prepareAsync_l();
+ status_t getDuration_l(int *msec);
+ status_t attachNewPlayer(const sp<IMediaPlayer>& player);
+ status_t reset_l();
+ status_t doSetRetransmitEndpoint(const sp<IMediaPlayer>& player);
+ status_t checkStateForKeySet_l(int key);
+
+ sp<IMediaPlayer> mPlayer;
+ thread_id_t mLockThreadId;
+ Mutex mLock;
+ Mutex mNotifyLock;
+ Condition mSignal;
+ sp<MediaPlayerListener> mListener;
+ void* mCookie;
+ media_player_states mCurrentState;
+ int mCurrentPosition;
+ MediaPlayerSeekMode mCurrentSeekMode;
+ int mSeekPosition;
+ MediaPlayerSeekMode mSeekMode;
+ bool mPrepareSync;
+ status_t mPrepareStatus;
+ audio_stream_type_t mStreamType;
+ Parcel* mAudioAttributesParcel;
+ bool mLoop;
+ float mLeftVolume;
+ float mRightVolume;
+ int mVideoWidth;
+ int mVideoHeight;
+ audio_session_t mAudioSessionId;
+ float mSendLevel;
+ struct sockaddr_in mRetransmitEndpoint;
+ bool mRetransmitEndpointValid;
+ BufferingSettings mCurrentBufferingSettings;
+};
+
+}; // namespace android
+
+#endif // ANDROID_MEDIAPLAYER_H
diff --git a/media/libmedia/include/mediarecorder.h b/media/libmedia/include/mediarecorder.h
new file mode 100644
index 0000000..071e7a1
--- /dev/null
+++ b/media/libmedia/include/mediarecorder.h
@@ -0,0 +1,278 @@
+/*
+ ** Copyright (C) 2008 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_MEDIARECORDER_H
+#define ANDROID_MEDIARECORDER_H
+
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <utils/List.h>
+#include <utils/Errors.h>
+#include <media/IMediaRecorderClient.h>
+#include <media/IMediaDeathNotifier.h>
+
+namespace android {
+
+class Surface;
+class IMediaRecorder;
+class ICameraRecordingProxy;
+class IGraphicBufferProducer;
+struct PersistentSurface;
+class Surface;
+
+namespace hardware {
+class ICamera;
+}
+
+typedef void (*media_completion_f)(status_t status, void *cookie);
+
+enum video_source {
+ VIDEO_SOURCE_DEFAULT = 0,
+ VIDEO_SOURCE_CAMERA = 1,
+ VIDEO_SOURCE_SURFACE = 2,
+
+ VIDEO_SOURCE_LIST_END // must be last - used to validate audio source type
+};
+
+//Please update media/java/android/media/MediaRecorder.java if the following is updated.
+enum output_format {
+ OUTPUT_FORMAT_DEFAULT = 0,
+ OUTPUT_FORMAT_THREE_GPP = 1,
+ OUTPUT_FORMAT_MPEG_4 = 2,
+
+
+ OUTPUT_FORMAT_AUDIO_ONLY_START = 3, // Used in validating the output format. Should be the
+ // at the start of the audio only output formats.
+
+ /* These are audio only file formats */
+ OUTPUT_FORMAT_RAW_AMR = 3, //to be backward compatible
+ OUTPUT_FORMAT_AMR_NB = 3,
+ OUTPUT_FORMAT_AMR_WB = 4,
+ OUTPUT_FORMAT_AAC_ADIF = 5,
+ OUTPUT_FORMAT_AAC_ADTS = 6,
+
+ OUTPUT_FORMAT_AUDIO_ONLY_END = 7, // Used in validating the output format. Should be the
+ // at the end of the audio only output formats.
+
+ /* Stream over a socket, limited to a single stream */
+ OUTPUT_FORMAT_RTP_AVP = 7,
+
+ /* H.264/AAC data encapsulated in MPEG2/TS */
+ OUTPUT_FORMAT_MPEG2TS = 8,
+
+ /* VP8/VORBIS data in a WEBM container */
+ OUTPUT_FORMAT_WEBM = 9,
+
+ OUTPUT_FORMAT_LIST_END // must be last - used to validate format type
+};
+
+enum audio_encoder {
+ AUDIO_ENCODER_DEFAULT = 0,
+ AUDIO_ENCODER_AMR_NB = 1,
+ AUDIO_ENCODER_AMR_WB = 2,
+ AUDIO_ENCODER_AAC = 3,
+ AUDIO_ENCODER_HE_AAC = 4,
+ AUDIO_ENCODER_AAC_ELD = 5,
+ AUDIO_ENCODER_VORBIS = 6,
+
+ AUDIO_ENCODER_LIST_END // must be the last - used to validate the audio encoder type
+};
+
+enum video_encoder {
+ VIDEO_ENCODER_DEFAULT = 0,
+ VIDEO_ENCODER_H263 = 1,
+ VIDEO_ENCODER_H264 = 2,
+ VIDEO_ENCODER_MPEG_4_SP = 3,
+ VIDEO_ENCODER_VP8 = 4,
+ VIDEO_ENCODER_HEVC = 5,
+
+ VIDEO_ENCODER_LIST_END // must be the last - used to validate the video encoder type
+};
+
+/*
+ * The state machine of the media_recorder.
+ */
+enum media_recorder_states {
+ // Error state.
+ MEDIA_RECORDER_ERROR = 0,
+
+ // Recorder was just created.
+ MEDIA_RECORDER_IDLE = 1 << 0,
+
+ // Recorder has been initialized.
+ MEDIA_RECORDER_INITIALIZED = 1 << 1,
+
+ // Configuration of the recorder has been completed.
+ MEDIA_RECORDER_DATASOURCE_CONFIGURED = 1 << 2,
+
+ // Recorder is ready to start.
+ MEDIA_RECORDER_PREPARED = 1 << 3,
+
+ // Recording is in progress.
+ MEDIA_RECORDER_RECORDING = 1 << 4,
+};
+
+// The "msg" code passed to the listener in notify.
+enum media_recorder_event_type {
+ MEDIA_RECORDER_EVENT_LIST_START = 1,
+ MEDIA_RECORDER_EVENT_ERROR = 1,
+ MEDIA_RECORDER_EVENT_INFO = 2,
+ MEDIA_RECORDER_EVENT_LIST_END = 99,
+
+ // Track related event types
+ MEDIA_RECORDER_TRACK_EVENT_LIST_START = 100,
+ MEDIA_RECORDER_TRACK_EVENT_ERROR = 100,
+ MEDIA_RECORDER_TRACK_EVENT_INFO = 101,
+ MEDIA_RECORDER_TRACK_EVENT_LIST_END = 1000,
+};
+
+/*
+ * The (part of) "what" code passed to the listener in notify.
+ * When the error or info type is track specific, the what has
+ * the following layout:
+ * the left-most 16-bit is meant for error or info type.
+ * the right-most 4-bit is meant for track id.
+ * the rest is reserved.
+ *
+ * | track id | reserved | error or info type |
+ * 31 28 16 0
+ *
+ */
+enum media_recorder_error_type {
+ MEDIA_RECORDER_ERROR_UNKNOWN = 1,
+
+ // Track related error type
+ MEDIA_RECORDER_TRACK_ERROR_LIST_START = 100,
+ MEDIA_RECORDER_TRACK_ERROR_GENERAL = 100,
+ MEDIA_RECORDER_ERROR_VIDEO_NO_SYNC_FRAME = 200,
+ MEDIA_RECORDER_TRACK_ERROR_LIST_END = 1000,
+};
+
+// The codes are distributed as follow:
+// 0xx: Reserved
+// 8xx: General info/warning
+//
+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_APPROACHING = 802,
+ MEDIA_RECORDER_INFO_NEXT_OUTPUT_FILE_STARTED = 803,
+
+ // All track related informtional events start here
+ MEDIA_RECORDER_TRACK_INFO_LIST_START = 1000,
+ MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS = 1000,
+ MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME = 1001,
+ MEDIA_RECORDER_TRACK_INFO_TYPE = 1002,
+ MEDIA_RECORDER_TRACK_INFO_DURATION_MS = 1003,
+
+ // The time to measure the max chunk duration
+ MEDIA_RECORDER_TRACK_INFO_MAX_CHUNK_DUR_MS = 1004,
+
+ MEDIA_RECORDER_TRACK_INFO_ENCODED_FRAMES = 1005,
+
+ // The time to measure how well the audio and video
+ // track data is interleaved.
+ MEDIA_RECORDER_TRACK_INTER_CHUNK_TIME_MS = 1006,
+
+ // The time to measure system response. Note that
+ // the delay does not include the intentional delay
+ // we use to eliminate the recording sound.
+ MEDIA_RECORDER_TRACK_INFO_INITIAL_DELAY_MS = 1007,
+
+ // The time used to compensate for initial A/V sync.
+ MEDIA_RECORDER_TRACK_INFO_START_OFFSET_MS = 1008,
+
+ // Total number of bytes of the media data.
+ MEDIA_RECORDER_TRACK_INFO_DATA_KBYTES = 1009,
+
+ MEDIA_RECORDER_TRACK_INFO_LIST_END = 2000,
+};
+
+// ----------------------------------------------------------------------------
+// ref-counted object for callbacks
+class MediaRecorderListener: virtual public RefBase
+{
+public:
+ virtual void notify(int msg, int ext1, int ext2) = 0;
+};
+
+class MediaRecorder : public BnMediaRecorderClient,
+ public virtual IMediaDeathNotifier
+{
+public:
+ MediaRecorder(const String16& opPackageName);
+ ~MediaRecorder();
+
+ void died();
+ status_t initCheck();
+ status_t setCamera(const sp<hardware::ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy);
+ status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface);
+ status_t setVideoSource(int vs);
+ status_t setAudioSource(int as);
+ status_t setOutputFormat(int of);
+ status_t setVideoEncoder(int ve);
+ status_t setAudioEncoder(int ae);
+ status_t setOutputFile(int fd);
+ status_t setNextOutputFile(int fd);
+ status_t setVideoSize(int width, int height);
+ status_t setVideoFrameRate(int frames_per_second);
+ status_t setParameters(const String8& params);
+ status_t setListener(const sp<MediaRecorderListener>& listener);
+ status_t setClientName(const String16& clientName);
+ status_t prepare();
+ status_t getMaxAmplitude(int* max);
+ status_t start();
+ status_t stop();
+ status_t reset();
+ status_t pause();
+ status_t resume();
+ status_t init();
+ status_t close();
+ status_t release();
+ void notify(int msg, int ext1, int ext2);
+ status_t setInputSurface(const sp<PersistentSurface>& surface);
+ sp<IGraphicBufferProducer> querySurfaceMediaSourceFromMediaServer();
+ status_t getMetrics(Parcel *reply);
+
+private:
+ void doCleanUp();
+ status_t doReset();
+
+ sp<IMediaRecorder> mMediaRecorder;
+ sp<MediaRecorderListener> mListener;
+
+ // Reference to IGraphicBufferProducer
+ // for encoding GL Frames. That is useful only when the
+ // video source is set to VIDEO_SOURCE_GRALLOC_BUFFER
+ sp<IGraphicBufferProducer> mSurfaceMediaSource;
+
+ media_recorder_states mCurrentState;
+ bool mIsAudioSourceSet;
+ bool mIsVideoSourceSet;
+ bool mIsAudioEncoderSet;
+ bool mIsVideoEncoderSet;
+ bool mIsOutputFileSet;
+ Mutex mLock;
+ Mutex mNotifyLock;
+};
+
+}; // namespace android
+
+#endif // ANDROID_MEDIARECORDER_H
diff --git a/media/libmedia/include/mediascanner.h b/media/libmedia/include/mediascanner.h
new file mode 100644
index 0000000..d555279
--- /dev/null
+++ b/media/libmedia/include/mediascanner.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2008 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 MEDIASCANNER_H
+#define MEDIASCANNER_H
+
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <utils/List.h>
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <pthread.h>
+
+struct dirent;
+
+namespace android {
+
+class MediaScannerClient;
+class StringArray;
+class CharacterEncodingDetector;
+
+enum MediaScanResult {
+ // This file or directory was scanned successfully.
+ MEDIA_SCAN_RESULT_OK,
+ // This file or directory was skipped because it was not found, could
+ // not be opened, was of an unsupported type, or was malfored in some way.
+ MEDIA_SCAN_RESULT_SKIPPED,
+ // The scan should be aborted due to a fatal error such as out of memory
+ // or an exception.
+ MEDIA_SCAN_RESULT_ERROR,
+};
+
+struct MediaAlbumArt {
+public:
+ static MediaAlbumArt *fromData(int32_t size, const void* data);
+
+ static void init(MediaAlbumArt* instance, int32_t size, const void* data);
+
+ MediaAlbumArt *clone();
+
+ const char *data() {
+ return &mData[0];
+ }
+
+ int32_t size() {
+ return mSize;
+ }
+
+private:
+ int32_t mSize;
+ char mData[];
+
+ // You can't construct instances of this class directly because this is a
+ // variable-sized object passed through the binder.
+ MediaAlbumArt();
+} __packed;
+
+struct MediaScanner {
+ MediaScanner();
+ virtual ~MediaScanner();
+
+ virtual MediaScanResult processFile(
+ const char *path, const char *mimeType, MediaScannerClient &client) = 0;
+
+ virtual MediaScanResult processDirectory(
+ const char *path, MediaScannerClient &client);
+
+ void setLocale(const char *locale);
+
+ virtual MediaAlbumArt *extractAlbumArt(int fd) = 0;
+
+protected:
+ const char *locale() const;
+
+private:
+ // current locale (like "ja_JP"), created/destroyed with strdup()/free()
+ char *mLocale;
+ char *mSkipList;
+ int *mSkipIndex;
+
+ MediaScanResult doProcessDirectory(
+ char *path, int pathRemaining, MediaScannerClient &client, bool noMedia);
+ MediaScanResult doProcessDirectoryEntry(
+ char *path, int pathRemaining, MediaScannerClient &client, bool noMedia,
+ struct dirent* entry, char* fileSpot);
+ void loadSkipList();
+ bool shouldSkipDirectory(char *path);
+
+
+ MediaScanner(const MediaScanner &);
+ MediaScanner &operator=(const MediaScanner &);
+};
+
+class MediaScannerClient
+{
+public:
+ MediaScannerClient();
+ virtual ~MediaScannerClient();
+ void setLocale(const char* locale);
+ void beginFile();
+ status_t addStringTag(const char* name, const char* value);
+ void endFile();
+
+ virtual status_t scanFile(const char* path, long long lastModified,
+ long long fileSize, bool isDirectory, bool noMedia) = 0;
+ virtual status_t handleStringTag(const char* name, const char* value) = 0;
+ virtual status_t setMimeType(const char* mimeType) = 0;
+
+protected:
+ // default encoding from MediaScanner::mLocale
+ String8 mLocale;
+};
+
+}; // namespace android
+
+#endif // MEDIASCANNER_H
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 035cd8a..f7e1ff5 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -52,7 +52,7 @@
$(TOP)/frameworks/av/media/libstagefright/rtsp \
$(TOP)/frameworks/av/media/libstagefright/wifi-display \
$(TOP)/frameworks/av/media/libstagefright/webm \
- $(TOP)/frameworks/av/include/media \
+ $(LOCAL_PATH)/include/media \
$(TOP)/frameworks/av/include/camera \
$(TOP)/frameworks/native/include/media/openmax \
$(TOP)/frameworks/native/include/media/hardware \
diff --git a/media/libmediaplayerservice/include/MediaPlayerInterface.h b/media/libmediaplayerservice/include/MediaPlayerInterface.h
new file mode 100644
index 0000000..a01f7f2
--- /dev/null
+++ b/media/libmediaplayerservice/include/MediaPlayerInterface.h
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2007 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_MEDIAPLAYERINTERFACE_H
+#define ANDROID_MEDIAPLAYERINTERFACE_H
+
+#ifdef __cplusplus
+
+#include <sys/types.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include <utils/RefBase.h>
+
+#include <media/mediaplayer.h>
+#include <media/AudioResamplerPublic.h>
+#include <media/AudioSystem.h>
+#include <media/AudioTimestamp.h>
+#include <media/AVSyncSettings.h>
+#include <media/BufferingSettings.h>
+#include <media/Metadata.h>
+
+// Fwd decl to make sure everyone agrees that the scope of struct sockaddr_in is
+// global, and not in android::
+struct sockaddr_in;
+
+namespace android {
+
+class DataSource;
+class Parcel;
+class Surface;
+class IGraphicBufferProducer;
+
+template<typename T> class SortedVector;
+
+enum player_type {
+ STAGEFRIGHT_PLAYER = 3,
+ NU_PLAYER = 4,
+ // Test players are available only in the 'test' and 'eng' builds.
+ // The shared library with the test player is passed passed as an
+ // argument to the 'test:' url in the setDataSource call.
+ TEST_PLAYER = 5,
+};
+
+
+#define DEFAULT_AUDIOSINK_BUFFERCOUNT 4
+#define DEFAULT_AUDIOSINK_BUFFERSIZE 1200
+#define DEFAULT_AUDIOSINK_SAMPLERATE 44100
+
+// when the channel mask isn't known, use the channel count to derive a mask in AudioSink::open()
+#define CHANNEL_MASK_USE_CHANNEL_ORDER 0
+
+// duration below which we do not allow deep audio buffering
+#define AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US 5000000
+
+// callback mechanism for passing messages to MediaPlayer object
+typedef void (*notify_callback_f)(void* cookie,
+ int msg, int ext1, int ext2, const Parcel *obj);
+
+// abstract base class - use MediaPlayerInterface
+class MediaPlayerBase : public RefBase
+{
+public:
+ // AudioSink: abstraction layer for audio output
+ class AudioSink : public RefBase {
+ public:
+ enum cb_event_t {
+ CB_EVENT_FILL_BUFFER, // Request to write more data to buffer.
+ CB_EVENT_STREAM_END, // Sent after all the buffers queued in AF and HW are played
+ // back (after stop is called)
+ CB_EVENT_TEAR_DOWN // The AudioTrack was invalidated due to use case change:
+ // Need to re-evaluate offloading options
+ };
+
+ // Callback returns the number of bytes actually written to the buffer.
+ typedef size_t (*AudioCallback)(
+ AudioSink *audioSink, void *buffer, size_t size, void *cookie,
+ cb_event_t event);
+
+ virtual ~AudioSink() {}
+ virtual bool ready() const = 0; // audio output is open and ready
+ virtual ssize_t bufferSize() const = 0;
+ virtual ssize_t frameCount() const = 0;
+ virtual ssize_t channelCount() const = 0;
+ virtual ssize_t frameSize() const = 0;
+ virtual uint32_t latency() const = 0;
+ virtual float msecsPerFrame() const = 0;
+ virtual status_t getPosition(uint32_t *position) const = 0;
+ virtual status_t getTimestamp(AudioTimestamp &ts) const = 0;
+ virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const = 0;
+ virtual status_t getFramesWritten(uint32_t *frameswritten) const = 0;
+ virtual audio_session_t getSessionId() const = 0;
+ virtual audio_stream_type_t getAudioStreamType() const = 0;
+ virtual uint32_t getSampleRate() const = 0;
+ virtual int64_t getBufferDurationInUs() const = 0;
+
+ // If no callback is specified, use the "write" API below to submit
+ // audio data.
+ virtual status_t open(
+ uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
+ audio_format_t format=AUDIO_FORMAT_PCM_16_BIT,
+ int bufferCount=DEFAULT_AUDIOSINK_BUFFERCOUNT,
+ AudioCallback cb = NULL,
+ void *cookie = NULL,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ const audio_offload_info_t *offloadInfo = NULL,
+ bool doNotReconnect = false,
+ uint32_t suggestedFrameCount = 0) = 0;
+
+ virtual status_t start() = 0;
+
+ /* Input parameter |size| is in byte units stored in |buffer|.
+ * Data is copied over and actual number of bytes written (>= 0)
+ * is returned, or no data is copied and a negative status code
+ * is returned (even when |blocking| is true).
+ * When |blocking| is false, AudioSink will immediately return after
+ * part of or full |buffer| is copied over.
+ * When |blocking| is true, AudioSink will wait to copy the entire
+ * buffer, unless an error occurs or the copy operation is
+ * prematurely stopped.
+ */
+ virtual ssize_t write(const void* buffer, size_t size, bool blocking = true) = 0;
+
+ virtual void stop() = 0;
+ virtual void flush() = 0;
+ virtual void pause() = 0;
+ virtual void close() = 0;
+
+ virtual status_t setPlaybackRate(const AudioPlaybackRate& rate) = 0;
+ virtual status_t getPlaybackRate(AudioPlaybackRate* rate /* nonnull */) = 0;
+ virtual bool needsTrailingPadding() { return true; }
+
+ virtual status_t setParameters(const String8& /* keyValuePairs */) { return NO_ERROR; }
+ virtual String8 getParameters(const String8& /* keys */) { return String8::empty(); }
+
+ virtual VolumeShaper::Status applyVolumeShaper(
+ const sp<VolumeShaper::Configuration>& configuration,
+ const sp<VolumeShaper::Operation>& operation);
+ virtual sp<VolumeShaper::State> getVolumeShaperState(int id);
+ };
+
+ MediaPlayerBase() : mCookie(0), mNotify(0) {}
+ virtual ~MediaPlayerBase() {}
+ virtual status_t initCheck() = 0;
+ virtual bool hardwareOutput() = 0;
+
+ virtual status_t setUID(uid_t /* uid */) {
+ return INVALID_OPERATION;
+ }
+
+ virtual status_t setDataSource(
+ const sp<IMediaHTTPService> &httpService,
+ const char *url,
+ const KeyedVector<String8, String8> *headers = NULL) = 0;
+
+ virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0;
+
+ virtual status_t setDataSource(const sp<IStreamSource>& /* source */) {
+ return INVALID_OPERATION;
+ }
+
+ virtual status_t setDataSource(const sp<DataSource>& /* source */) {
+ return INVALID_OPERATION;
+ }
+
+ // pass the buffered IGraphicBufferProducer to the media player service
+ virtual status_t setVideoSurfaceTexture(
+ const sp<IGraphicBufferProducer>& bufferProducer) = 0;
+
+ virtual status_t getDefaultBufferingSettings(
+ BufferingSettings* buffering /* nonnull */) {
+ *buffering = BufferingSettings();
+ return OK;
+ }
+ virtual status_t setBufferingSettings(const BufferingSettings& /* buffering */) {
+ return OK;
+ }
+
+ virtual status_t prepare() = 0;
+ virtual status_t prepareAsync() = 0;
+ virtual status_t start() = 0;
+ virtual status_t stop() = 0;
+ virtual status_t pause() = 0;
+ virtual bool isPlaying() = 0;
+ virtual status_t setPlaybackSettings(const AudioPlaybackRate& rate) {
+ // by default, players only support setting rate to the default
+ if (!isAudioPlaybackRateEqual(rate, AUDIO_PLAYBACK_RATE_DEFAULT)) {
+ return BAD_VALUE;
+ }
+ return OK;
+ }
+ virtual status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) {
+ *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
+ return OK;
+ }
+ virtual status_t setSyncSettings(const AVSyncSettings& sync, float /* videoFps */) {
+ // By default, players only support setting sync source to default; all other sync
+ // settings are ignored. There is no requirement for getters to return set values.
+ if (sync.mSource != AVSYNC_SOURCE_DEFAULT) {
+ return BAD_VALUE;
+ }
+ return OK;
+ }
+ virtual status_t getSyncSettings(
+ AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) {
+ *sync = AVSyncSettings();
+ *videoFps = -1.f;
+ return OK;
+ }
+ virtual status_t seekTo(
+ int msec, MediaPlayerSeekMode mode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC) = 0;
+ virtual status_t getCurrentPosition(int *msec) = 0;
+ virtual status_t getDuration(int *msec) = 0;
+ virtual status_t reset() = 0;
+ virtual status_t setLooping(int loop) = 0;
+ virtual player_type playerType() = 0;
+ virtual status_t setParameter(int key, const Parcel &request) = 0;
+ virtual status_t getParameter(int key, Parcel *reply) = 0;
+
+ // default no-op implementation of optional extensions
+ virtual status_t setRetransmitEndpoint(const struct sockaddr_in* /* endpoint */) {
+ return INVALID_OPERATION;
+ }
+ virtual status_t getRetransmitEndpoint(struct sockaddr_in* /* endpoint */) {
+ return INVALID_OPERATION;
+ }
+ virtual status_t setNextPlayer(const sp<MediaPlayerBase>& /* next */) {
+ return OK;
+ }
+
+ // Invoke a generic method on the player by using opaque parcels
+ // for the request and reply.
+ //
+ // @param request Parcel that is positioned at the start of the
+ // data sent by the java layer.
+ // @param[out] reply Parcel to hold the reply data. Cannot be null.
+ // @return OK if the call was successful.
+ virtual status_t invoke(const Parcel& request, Parcel *reply) = 0;
+
+ // The Client in the MetadataPlayerService calls this method on
+ // the native player to retrieve all or a subset of metadata.
+ //
+ // @param ids SortedList of metadata ID to be fetch. If empty, all
+ // the known metadata should be returned.
+ // @param[inout] records Parcel where the player appends its metadata.
+ // @return OK if the call was successful.
+ virtual status_t getMetadata(const media::Metadata::Filter& /* ids */,
+ Parcel* /* records */) {
+ return INVALID_OPERATION;
+ };
+
+ void setNotifyCallback(
+ void* cookie, notify_callback_f notifyFunc) {
+ Mutex::Autolock autoLock(mNotifyLock);
+ mCookie = cookie; mNotify = notifyFunc;
+ }
+
+ void sendEvent(int msg, int ext1=0, int ext2=0,
+ const Parcel *obj=NULL) {
+ notify_callback_f notifyCB;
+ void* cookie;
+ {
+ Mutex::Autolock autoLock(mNotifyLock);
+ notifyCB = mNotify;
+ cookie = mCookie;
+ }
+
+ if (notifyCB) notifyCB(cookie, msg, ext1, ext2, obj);
+ }
+
+ virtual status_t dump(int /* fd */, const Vector<String16>& /* args */) const {
+ return INVALID_OPERATION;
+ }
+
+ // Modular DRM
+ virtual status_t prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId) {
+ return INVALID_OPERATION;
+ }
+ virtual status_t releaseDrm() {
+ return INVALID_OPERATION;
+ }
+
+private:
+ friend class MediaPlayerService;
+
+ Mutex mNotifyLock;
+ void* mCookie;
+ notify_callback_f mNotify;
+};
+
+// Implement this class for media players that use the AudioFlinger software mixer
+class MediaPlayerInterface : public MediaPlayerBase
+{
+public:
+ virtual ~MediaPlayerInterface() { }
+ virtual bool hardwareOutput() { return false; }
+ virtual void setAudioSink(const sp<AudioSink>& audioSink) { mAudioSink = audioSink; }
+protected:
+ sp<AudioSink> mAudioSink;
+};
+
+// Implement this class for media players that output audio directly to hardware
+class MediaPlayerHWInterface : public MediaPlayerBase
+{
+public:
+ virtual ~MediaPlayerHWInterface() {}
+ virtual bool hardwareOutput() { return true; }
+ virtual status_t setVolume(float leftVolume, float rightVolume) = 0;
+ virtual status_t setAudioStreamType(audio_stream_type_t streamType) = 0;
+};
+
+}; // namespace android
+
+#endif // __cplusplus
+
+
+#endif // ANDROID_MEDIAPLAYERINTERFACE_H
diff --git a/media/libnbaio/Android.bp b/media/libnbaio/Android.bp
index fd7af4f..f511876 100644
--- a/media/libnbaio/Android.bp
+++ b/media/libnbaio/Android.bp
@@ -34,4 +34,8 @@
],
include_dirs: ["system/media/audio_utils/include"],
+
+ local_include_dirs: ["include"],
+
+ export_include_dirs: ["include"],
}
diff --git a/media/libnbaio/include/AudioBufferProviderSource.h b/media/libnbaio/include/AudioBufferProviderSource.h
new file mode 100644
index 0000000..4747dcf
--- /dev/null
+++ b/media/libnbaio/include/AudioBufferProviderSource.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+// Implementation of NBAIO_Source that wraps an AudioBufferProvider
+
+#ifndef ANDROID_AUDIO_BUFFER_PROVIDER_SOURCE_H
+#define ANDROID_AUDIO_BUFFER_PROVIDER_SOURCE_H
+
+#include "NBAIO.h"
+#include <media/AudioBufferProvider.h>
+
+namespace android {
+
+class AudioBufferProviderSource : public NBAIO_Source {
+
+public:
+ AudioBufferProviderSource(AudioBufferProvider *provider, const NBAIO_Format& format);
+ virtual ~AudioBufferProviderSource();
+
+ // NBAIO_Port interface
+
+ //virtual ssize_t negotiate(const NBAIO_Format offers[], size_t numOffers,
+ // NBAIO_Format counterOffers[], size_t& numCounterOffers);
+ //virtual NBAIO_Format format();
+
+ // NBAIO_Source interface
+
+ //virtual size_t framesRead() const;
+ //virtual size_t framesOverrun();
+ //virtual size_t overruns();
+ virtual ssize_t availableToRead();
+ virtual ssize_t read(void *buffer, size_t count);
+ virtual ssize_t readVia(readVia_t via, size_t total, void *user, size_t block);
+
+private:
+ AudioBufferProvider * const mProvider;
+ AudioBufferProvider::Buffer mBuffer; // current buffer
+ size_t mConsumed; // number of frames consumed so far from current buffer
+};
+
+} // namespace android
+
+#endif // ANDROID_AUDIO_BUFFER_PROVIDER_SOURCE_H
diff --git a/media/libnbaio/include/AudioStreamInSource.h b/media/libnbaio/include/AudioStreamInSource.h
new file mode 100644
index 0000000..508e0fe
--- /dev/null
+++ b/media/libnbaio/include/AudioStreamInSource.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 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_AUDIO_STREAM_IN_SOURCE_H
+#define ANDROID_AUDIO_STREAM_IN_SOURCE_H
+
+#include "NBAIO.h"
+
+namespace android {
+
+class StreamInHalInterface;
+
+// not multi-thread safe
+class AudioStreamInSource : public NBAIO_Source {
+
+public:
+ AudioStreamInSource(sp<StreamInHalInterface> stream);
+ virtual ~AudioStreamInSource();
+
+ // NBAIO_Port interface
+
+ virtual ssize_t negotiate(const NBAIO_Format offers[], size_t numOffers,
+ NBAIO_Format counterOffers[], size_t& numCounterOffers);
+ //virtual NBAIO_Format format() const;
+
+ // NBAIO_Sink interface
+
+ //virtual size_t framesRead() const;
+ virtual int64_t framesOverrun();
+ virtual int64_t overruns() { (void) framesOverrun(); return mOverruns; }
+
+ // This is an over-estimate, and could dupe the caller into making a blocking read()
+ // FIXME Use an audio HAL API to query the buffer filling status when it's available.
+ virtual ssize_t availableToRead() { return mStreamBufferSizeBytes / mFrameSize; }
+
+ virtual ssize_t read(void *buffer, size_t count);
+
+ // NBAIO_Sink end
+
+#if 0 // until necessary
+ sp<StreamInHalInterface> stream() const { return mStream; }
+#endif
+
+private:
+ sp<StreamInHalInterface> mStream;
+ size_t mStreamBufferSizeBytes; // as reported by get_buffer_size()
+ int64_t mFramesOverrun;
+ int64_t mOverruns;
+};
+
+} // namespace android
+
+#endif // ANDROID_AUDIO_STREAM_IN_SOURCE_H
diff --git a/media/libnbaio/include/AudioStreamOutSink.h b/media/libnbaio/include/AudioStreamOutSink.h
new file mode 100644
index 0000000..56a2a38
--- /dev/null
+++ b/media/libnbaio/include/AudioStreamOutSink.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 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_AUDIO_STREAM_OUT_SINK_H
+#define ANDROID_AUDIO_STREAM_OUT_SINK_H
+
+#include "NBAIO.h"
+
+namespace android {
+
+class StreamOutHalInterface;
+
+// not multi-thread safe
+class AudioStreamOutSink : public NBAIO_Sink {
+
+public:
+ AudioStreamOutSink(sp<StreamOutHalInterface> stream);
+ virtual ~AudioStreamOutSink();
+
+ // NBAIO_Port interface
+
+ virtual ssize_t negotiate(const NBAIO_Format offers[], size_t numOffers,
+ NBAIO_Format counterOffers[], size_t& numCounterOffers);
+ //virtual NBAIO_Format format();
+
+ // NBAIO_Sink interface
+
+ //virtual size_t framesWritten() const;
+ //virtual size_t framesUnderrun() const;
+ //virtual size_t underruns() const;
+
+ // This is an over-estimate, and could dupe the caller into making a blocking write()
+ // FIXME Use an audio HAL API to query the buffer emptying status when it's available.
+ virtual ssize_t availableToWrite() { return mStreamBufferSizeBytes / mFrameSize; }
+
+ virtual ssize_t write(const void *buffer, size_t count);
+
+ virtual status_t getTimestamp(ExtendedTimestamp ×tamp);
+
+ // NBAIO_Sink end
+
+#if 0 // until necessary
+ sp<StreamOutHalInterface> stream() const { return mStream; }
+#endif
+
+private:
+ sp<StreamOutHalInterface> mStream;
+ size_t mStreamBufferSizeBytes; // as reported by get_buffer_size()
+};
+
+} // namespace android
+
+#endif // ANDROID_AUDIO_STREAM_OUT_SINK_H
diff --git a/media/libnbaio/include/LibsndfileSink.h b/media/libnbaio/include/LibsndfileSink.h
new file mode 100644
index 0000000..97a57e0
--- /dev/null
+++ b/media/libnbaio/include/LibsndfileSink.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 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_AUDIO_LIBSNDFILE_SINK_H
+#define ANDROID_AUDIO_LIBSNDFILE_SINK_H
+
+#include "NBAIO.h"
+#include "sndfile.h"
+
+// Implementation of NBAIO_Sink that wraps a libsndfile opened in SFM_WRITE mode
+
+namespace android {
+
+class LibsndfileSink : public NBAIO_Sink {
+
+public:
+ LibsndfileSink(SNDFILE *sndfile, const SF_INFO &sfinfo);
+ virtual ~LibsndfileSink();
+
+ // NBAIO_Port interface
+
+ //virtual ssize_t negotiate(const NBAIO_Format offers[], size_t numOffers,
+ // NBAIO_Format counterOffers[], size_t& numCounterOffers);
+ //virtual NBAIO_Format format() const;
+
+ // NBAIO_Sink interface
+
+ //virtual size_t framesWritten() const;
+ //virtual size_t framesUnderrun() const;
+ //virtual size_t underruns() const;
+ //virtual ssize_t availableToWrite();
+ virtual ssize_t write(const void *buffer, size_t count);
+ //virtual ssize_t writeVia(writeVia_t via, size_t total, void *user, size_t block);
+
+private:
+ SNDFILE * mSndfile;
+};
+
+} // namespace android
+
+#endif // ANDROID_AUDIO_LIBSNDFILE_SINK_H
diff --git a/media/libnbaio/include/LibsndfileSource.h b/media/libnbaio/include/LibsndfileSource.h
new file mode 100644
index 0000000..4fbdb4b
--- /dev/null
+++ b/media/libnbaio/include/LibsndfileSource.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 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_AUDIO_LIBSNDFILE_SOURCE_H
+#define ANDROID_AUDIO_LIBSNDFILE_SOURCE_H
+
+#include "NBAIO.h"
+#include "sndfile.h"
+
+// Implementation of NBAIO_Source that wraps a libsndfile opened in SFM_READ mode
+
+namespace android {
+
+class LibsndfileSource : public NBAIO_Source {
+
+public:
+ // If 'loop' is true and it permits seeking, then we'll act as an infinite source
+ LibsndfileSource(SNDFILE *sndfile, const SF_INFO &sfinfo, bool loop = false);
+ virtual ~LibsndfileSource();
+
+ // NBAIO_Port interface
+
+ //virtual ssize_t negotiate(const NBAIO_Format offers[], size_t numOffers,
+ // NBAIO_Format counterOffers[], size_t& numCounterOffers);
+ //virtual NBAIO_Format format() const;
+
+ // NBAIO_Source interface
+
+ //virtual size_t framesRead() const;
+ //virtual size_t framesOverrun();
+ //virtual size_t overruns();
+ virtual ssize_t availableToRead();
+ virtual ssize_t read(void *buffer, size_t count);
+ //virtual ssize_t readVia(readVia_t via, size_t total, void *user, size_t block);
+
+private:
+ SNDFILE * mSndfile;
+ sf_count_t mEstimatedFramesUntilEOF;
+ bool mLooping;
+ bool mReadAnyFramesThisLoopCycle;
+};
+
+} // namespace android
+
+#endif // ANDROID_AUDIO_LIBSNDFILE_SOURCE_H
diff --git a/media/libnbaio/include/MonoPipe.h b/media/libnbaio/include/MonoPipe.h
new file mode 100644
index 0000000..60ae92e
--- /dev/null
+++ b/media/libnbaio/include/MonoPipe.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2012 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_AUDIO_MONO_PIPE_H
+#define ANDROID_AUDIO_MONO_PIPE_H
+
+#include <time.h>
+#include <audio_utils/fifo.h>
+#include <media/SingleStateQueue.h>
+#include "NBAIO.h"
+
+namespace android {
+
+typedef SingleStateQueue<ExtendedTimestamp> ExtendedTimestampSingleStateQueue;
+
+// MonoPipe is similar to Pipe except:
+// - supports only a single reader, called MonoPipeReader
+// - write() cannot overrun; instead it will return a short actual count if insufficient space
+// - write() can optionally block if the pipe is full
+// Like Pipe, it is not multi-thread safe for either writer or reader
+// but writer and reader can be different threads.
+class MonoPipe : public NBAIO_Sink {
+
+ friend class MonoPipeReader;
+
+public:
+ // reqFrames will be rounded up to a power of 2, and all slots are available. Must be >= 2.
+ // Note: whatever shares this object with another thread needs to do so in an SMP-safe way (like
+ // creating it the object before creating the other thread, or storing the object with a
+ // release_store). Otherwise the other thread could see a partially-constructed object.
+ MonoPipe(size_t reqFrames, const NBAIO_Format& format, bool writeCanBlock = false);
+ virtual ~MonoPipe();
+
+ // NBAIO_Port interface
+
+ //virtual ssize_t negotiate(const NBAIO_Format offers[], size_t numOffers,
+ // NBAIO_Format counterOffers[], size_t& numCounterOffers);
+ //virtual NBAIO_Format format() const;
+
+ // NBAIO_Sink interface
+
+ //virtual int64_t framesWritten() const;
+ //virtual int64_t framesUnderrun() const;
+ //virtual int64_t underruns() const;
+
+ // returns n where 0 <= n <= mMaxFrames, or a negative status_t
+ // including the private status codes in NBAIO.h
+ virtual ssize_t availableToWrite();
+
+ virtual ssize_t write(const void *buffer, size_t count);
+ //virtual ssize_t writeVia(writeVia_t via, size_t total, void *user, size_t block);
+
+ // average number of frames present in the pipe under normal conditions.
+ // See throttling mechanism in MonoPipe::write()
+ size_t getAvgFrames() const { return mSetpoint; }
+ void setAvgFrames(size_t setpoint);
+ size_t maxFrames() const { return mMaxFrames; }
+
+ // Set the shutdown state for the write side of a pipe.
+ // This may be called by an unrelated thread. When shutdown state is 'true',
+ // a write that would otherwise block instead returns a short transfer count.
+ // There is no guarantee how long it will take for the shutdown to be recognized,
+ // but it will not be an unbounded amount of time.
+ // The state can be restored to normal by calling shutdown(false).
+ void shutdown(bool newState = true);
+
+ // Return true if the write side of a pipe is currently shutdown.
+ bool isShutdown();
+
+ // Return NO_ERROR if there is a timestamp available
+ status_t getTimestamp(ExtendedTimestamp ×tamp);
+
+private:
+ const size_t mMaxFrames; // as requested in constructor, rounded up to a power of 2
+ void * const mBuffer;
+ audio_utils_fifo mFifo;
+ audio_utils_fifo_writer mFifoWriter;
+ bool mWriteTsValid; // whether mWriteTs is valid
+ struct timespec mWriteTs; // time that the previous write() completed
+ size_t mSetpoint; // target value for pipe fill depth
+ const bool mWriteCanBlock; // whether write() should block if the pipe is full
+
+ bool mIsShutdown; // whether shutdown(true) was called, no barriers are needed
+
+ ExtendedTimestampSingleStateQueue::Shared mTimestampShared;
+ ExtendedTimestampSingleStateQueue::Mutator mTimestampMutator;
+ ExtendedTimestampSingleStateQueue::Observer mTimestampObserver;
+};
+
+} // namespace android
+
+#endif // ANDROID_AUDIO_MONO_PIPE_H
diff --git a/media/libnbaio/include/MonoPipeReader.h b/media/libnbaio/include/MonoPipeReader.h
new file mode 100644
index 0000000..0776ecd
--- /dev/null
+++ b/media/libnbaio/include/MonoPipeReader.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 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_AUDIO_MONO_PIPE_READER_H
+#define ANDROID_AUDIO_MONO_PIPE_READER_H
+
+#include "MonoPipe.h"
+
+namespace android {
+
+// MonoPipeReader is safe for only a single reader thread
+class MonoPipeReader : public NBAIO_Source {
+
+public:
+
+ // Construct a MonoPipeReader and associate it with a MonoPipe;
+ // any data already in the pipe is visible to this MonoPipeReader.
+ // There can be only a single MonoPipeReader per MonoPipe.
+ // FIXME make this constructor a factory method of MonoPipe.
+ MonoPipeReader(MonoPipe* pipe);
+ virtual ~MonoPipeReader();
+
+ // NBAIO_Port interface
+
+ //virtual ssize_t negotiate(const NBAIO_Format offers[], size_t numOffers,
+ // NBAIO_Format counterOffers[], size_t& numCounterOffers);
+ //virtual NBAIO_Format format() const;
+
+ // NBAIO_Source interface
+
+ //virtual size_t framesRead() const;
+ //virtual size_t framesOverrun();
+ //virtual size_t overruns();
+
+ virtual ssize_t availableToRead();
+
+ virtual ssize_t read(void *buffer, size_t count);
+
+ virtual void onTimestamp(const ExtendedTimestamp ×tamp);
+
+ // NBAIO_Source end
+
+#if 0 // until necessary
+ MonoPipe* pipe() const { return mPipe; }
+#endif
+
+private:
+ MonoPipe * const mPipe;
+ audio_utils_fifo_reader mFifoReader;
+};
+
+} // namespace android
+
+#endif // ANDROID_AUDIO_MONO_PIPE_READER_H
diff --git a/media/libnbaio/include/NBAIO.h b/media/libnbaio/include/NBAIO.h
new file mode 100644
index 0000000..f8ec38b
--- /dev/null
+++ b/media/libnbaio/include/NBAIO.h
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2012 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_AUDIO_NBAIO_H
+#define ANDROID_AUDIO_NBAIO_H
+
+// Non-blocking audio I/O interface
+//
+// This header file has the abstract interfaces only. Concrete implementation classes are declared
+// elsewhere. Implementations _should_ be non-blocking for all methods, especially read() and
+// write(), but this is not enforced. In general, implementations do not need to be multi-thread
+// safe, and any exceptions are noted in the particular implementation.
+
+#include <limits.h>
+#include <stdlib.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <media/AudioTimestamp.h>
+#include <system/audio.h>
+
+namespace android {
+
+// In addition to the usual status_t
+enum {
+ NEGOTIATE = (UNKNOWN_ERROR + 0x100), // Must (re-)negotiate format. For negotiate() only,
+ // the offeree doesn't accept offers, and proposes
+ // counter-offers
+ OVERRUN = (UNKNOWN_ERROR + 0x101), // availableToRead(), read(), or readVia() detected
+ // lost input due to overrun; an event is counted and
+ // the caller should re-try
+ UNDERRUN = (UNKNOWN_ERROR + 0x102), // availableToWrite(), write(), or writeVia() detected
+ // a gap in output due to underrun (not being called
+ // often enough, or with enough data); an event is
+ // counted and the caller should re-try
+};
+
+// Negotiation of format is based on the data provider and data sink, or the data consumer and
+// data source, exchanging prioritized arrays of offers and counter-offers until a single offer is
+// mutually agreed upon. Each offer is an NBAIO_Format. For simplicity and performance,
+// NBAIO_Format is a typedef that ties together the most important combinations of the various
+// attributes, rather than a struct with separate fields for format, sample rate, channel count,
+// interleave, packing, alignment, etc. The reason is that NBAIO_Format tries to abstract out only
+// the combinations that are actually needed within AudioFlinger. If the list of combinations grows
+// too large, then this decision should be re-visited.
+// Sample rate and channel count are explicit, PCM interleaved 16-bit is assumed.
+struct NBAIO_Format {
+// FIXME make this a class, and change Format_... global methods to class methods
+//private:
+ unsigned mSampleRate;
+ unsigned mChannelCount;
+ audio_format_t mFormat;
+ size_t mFrameSize;
+};
+
+extern const NBAIO_Format Format_Invalid;
+
+// Return the frame size of an NBAIO_Format in bytes
+size_t Format_frameSize(const NBAIO_Format& format);
+
+// Convert a sample rate in Hz and channel count to an NBAIO_Format
+// FIXME rename
+NBAIO_Format Format_from_SR_C(unsigned sampleRate, unsigned channelCount, audio_format_t format);
+
+// Return the sample rate in Hz of an NBAIO_Format
+unsigned Format_sampleRate(const NBAIO_Format& format);
+
+// Return the channel count of an NBAIO_Format
+unsigned Format_channelCount(const NBAIO_Format& format);
+
+// Callbacks used by NBAIO_Sink::writeVia() and NBAIO_Source::readVia() below.
+typedef ssize_t (*writeVia_t)(void *user, void *buffer, size_t count);
+typedef ssize_t (*readVia_t)(void *user, const void *buffer, size_t count);
+
+// Check whether an NBAIO_Format is valid
+bool Format_isValid(const NBAIO_Format& format);
+
+// Compare two NBAIO_Format values
+bool Format_isEqual(const NBAIO_Format& format1, const NBAIO_Format& format2);
+
+// Abstract class (interface) representing a data port.
+class NBAIO_Port : public RefBase {
+
+public:
+
+ // negotiate() must called first. The purpose of negotiate() is to check compatibility of
+ // formats, not to automatically adapt if they are incompatible. It's the responsibility of
+ // whoever sets up the graph connections to make sure formats are compatible, and this method
+ // just verifies that. The edges are "dumb" and don't attempt to adapt to bad connections.
+ // How it works: offerer proposes an array of formats, in descending order of preference from
+ // offers[0] to offers[numOffers - 1]. If offeree accepts one of these formats, it returns
+ // the index of that offer. Otherwise, offeree sets numCounterOffers to the number of
+ // counter-offers (up to a maximumum of the entry value of numCounterOffers), fills in the
+ // provided array counterOffers[] with its counter-offers, in descending order of preference
+ // from counterOffers[0] to counterOffers[numCounterOffers - 1], and returns NEGOTIATE.
+ // Note that since the offerer allocates space for counter-offers, but only the offeree knows
+ // how many counter-offers it has, there may be insufficient space for all counter-offers.
+ // In that case, the offeree sets numCounterOffers to the requested number of counter-offers
+ // (which is greater than the entry value of numCounterOffers), fills in as many of the most
+ // important counterOffers as will fit, and returns NEGOTIATE. As this implies a re-allocation,
+ // it should be used as a last resort. It is preferable for the offerer to simply allocate a
+ // larger space to begin with, and/or for the offeree to tolerate a smaller space than desired.
+ // Alternatively, the offerer can pass NULL for offers and counterOffers, and zero for
+ // numOffers. This indicates that it has not allocated space for any counter-offers yet.
+ // In this case, the offerree should set numCounterOffers appropriately and return NEGOTIATE.
+ // Then the offerer will allocate the correct amount of memory and retry.
+ // Format_Invalid is not allowed as either an offer or counter-offer.
+ // Returns:
+ // >= 0 Offer accepted.
+ // NEGOTIATE No offer accepted, and counter-offer(s) optionally made. See above for details.
+ virtual ssize_t negotiate(const NBAIO_Format offers[], size_t numOffers,
+ NBAIO_Format counterOffers[], size_t& numCounterOffers);
+
+ // Return the current negotiated format, or Format_Invalid if negotiation has not been done,
+ // or if re-negotiation is required.
+ virtual NBAIO_Format format() const { return mNegotiated ? mFormat : Format_Invalid; }
+
+protected:
+ NBAIO_Port(const NBAIO_Format& format) : mNegotiated(false), mFormat(format),
+ mFrameSize(Format_frameSize(format)) { }
+ virtual ~NBAIO_Port() { }
+
+ // Implementations are free to ignore these if they don't need them
+
+ bool mNegotiated; // mNegotiated implies (mFormat != Format_Invalid)
+ NBAIO_Format mFormat; // (mFormat != Format_Invalid) does not imply mNegotiated
+ size_t mFrameSize; // assign in parallel with any assignment to mFormat
+};
+
+// Abstract class (interface) representing a non-blocking data sink, for use by a data provider.
+class NBAIO_Sink : public NBAIO_Port {
+
+public:
+
+ // For the next two APIs:
+ // 32 bits rolls over after 27 hours at 44.1 kHz; if that concerns you then poll periodically.
+
+ // Return the number of frames written successfully since construction.
+ virtual int64_t framesWritten() const { return mFramesWritten; }
+
+ // Number of frames lost due to underrun since construction.
+ virtual int64_t framesUnderrun() const { return 0; }
+
+ // Number of underruns since construction, where a set of contiguous lost frames is one event.
+ virtual int64_t underruns() const { return 0; }
+
+ // Estimate of number of frames that could be written successfully now without blocking.
+ // When a write() is actually attempted, the implementation is permitted to return a smaller or
+ // larger transfer count, however it will make a good faith effort to give an accurate estimate.
+ // Errors:
+ // NEGOTIATE (Re-)negotiation is needed.
+ // UNDERRUN write() has not been called frequently enough, or with enough frames to keep up.
+ // An underrun event is counted, and the caller should re-try this operation.
+ // WOULD_BLOCK Determining how many frames can be written without blocking would itself block.
+ virtual ssize_t availableToWrite() {
+ if (!mNegotiated) {
+ return NEGOTIATE;
+ }
+ return SSIZE_MAX;
+ }
+
+ // Transfer data to sink from single input buffer. Implies a copy.
+ // Inputs:
+ // buffer Non-NULL buffer owned by provider.
+ // count Maximum number of frames to transfer.
+ // Return value:
+ // > 0 Number of frames successfully transferred prior to first error.
+ // = 0 Count was zero.
+ // < 0 status_t error occurred prior to the first frame transfer.
+ // Errors:
+ // NEGOTIATE (Re-)negotiation is needed.
+ // WOULD_BLOCK No frames can be transferred without blocking.
+ // UNDERRUN write() has not been called frequently enough, or with enough frames to keep up.
+ // An underrun event is counted, and the caller should re-try this operation.
+ virtual ssize_t write(const void *buffer, size_t count) = 0;
+
+ // Transfer data to sink using a series of callbacks. More suitable for zero-fill, synthesis,
+ // and non-contiguous transfers (e.g. circular buffer or writev).
+ // Inputs:
+ // via Callback function that the sink will call as many times as needed to consume data.
+ // total Estimate of the number of frames the provider has available. This is an estimate,
+ // and it can provide a different number of frames during the series of callbacks.
+ // user Arbitrary void * reserved for data provider.
+ // block Number of frames per block, that is a suggested value for 'count' in each callback.
+ // Zero means no preference. This parameter is a hint only, and may be ignored.
+ // Return value:
+ // > 0 Total number of frames successfully transferred prior to first error.
+ // = 0 Count was zero.
+ // < 0 status_t error occurred prior to the first frame transfer.
+ // Errors:
+ // NEGOTIATE (Re-)negotiation is needed.
+ // WOULD_BLOCK No frames can be transferred without blocking.
+ // UNDERRUN write() has not been called frequently enough, or with enough frames to keep up.
+ // An underrun event is counted, and the caller should re-try this operation.
+ //
+ // The 'via' callback is called by the data sink as follows:
+ // Inputs:
+ // user Arbitrary void * reserved for data provider.
+ // buffer Non-NULL buffer owned by sink that callback should fill in with data,
+ // up to a maximum of 'count' frames.
+ // count Maximum number of frames to transfer during this callback.
+ // Return value:
+ // > 0 Number of frames successfully transferred during this callback prior to first error.
+ // = 0 Count was zero.
+ // < 0 status_t error occurred prior to the first frame transfer during this callback.
+ virtual ssize_t writeVia(writeVia_t via, size_t total, void *user, size_t block = 0);
+
+ // Returns NO_ERROR if a timestamp is available. The timestamp includes the total number
+ // of frames presented to an external observer, together with the value of CLOCK_MONOTONIC
+ // as of this presentation count. The timestamp parameter is undefined if error is returned.
+ virtual status_t getTimestamp(ExtendedTimestamp& /*timestamp*/) { return INVALID_OPERATION; }
+
+protected:
+ NBAIO_Sink(const NBAIO_Format& format = Format_Invalid) : NBAIO_Port(format), mFramesWritten(0)
+ { }
+ virtual ~NBAIO_Sink() { }
+
+ // Implementations are free to ignore these if they don't need them
+ int64_t mFramesWritten;
+};
+
+// Abstract class (interface) representing a non-blocking data source, for use by a data consumer.
+class NBAIO_Source : public NBAIO_Port {
+
+public:
+
+ // For the next two APIs:
+ // 32 bits rolls over after 27 hours at 44.1 kHz; if that concerns you then poll periodically.
+
+ // Number of frames read successfully since construction.
+ virtual int64_t framesRead() const { return mFramesRead; }
+
+ // Number of frames lost due to overrun since construction.
+ // Not const because implementations may need to do I/O.
+ virtual int64_t framesOverrun() /*const*/ { return 0; }
+
+ // Number of overruns since construction, where a set of contiguous lost frames is one event.
+ // Not const because implementations may need to do I/O.
+ virtual int64_t overruns() /*const*/ { return 0; }
+
+ // Estimate of number of frames that could be read successfully now.
+ // When a read() is actually attempted, the implementation is permitted to return a smaller or
+ // larger transfer count, however it will make a good faith effort to give an accurate estimate.
+ // Errors:
+ // NEGOTIATE (Re-)negotiation is needed.
+ // OVERRUN One or more frames were lost due to overrun, try again to read more recent data.
+ // WOULD_BLOCK Determining how many frames can be read without blocking would itself block.
+ virtual ssize_t availableToRead() { return SSIZE_MAX; }
+
+ // Transfer data from source into single destination buffer. Implies a copy.
+ // Inputs:
+ // buffer Non-NULL destination buffer owned by consumer.
+ // count Maximum number of frames to transfer.
+ // Return value:
+ // > 0 Number of frames successfully transferred prior to first error.
+ // = 0 Count was zero.
+ // < 0 status_t error occurred prior to the first frame transfer.
+ // Errors:
+ // NEGOTIATE (Re-)negotiation is needed.
+ // WOULD_BLOCK No frames can be transferred without blocking.
+ // OVERRUN read() has not been called frequently enough, or with enough frames to keep up.
+ // One or more frames were lost due to overrun, try again to read more recent data.
+ virtual ssize_t read(void *buffer, size_t count) = 0;
+
+ // Flush data from buffer. There is no notion of overrun as all data is dropped.
+ // Flushed frames also count towards frames read.
+ //
+ // Return value:
+ // >= 0 Number of frames successfully flushed
+ // < 0 status_t error occurred
+ // Errors:
+ // NEGOTIATE (Re-)negotiation is needed.
+ // INVALID_OPERATION Not implemented
+ virtual ssize_t flush() { return INVALID_OPERATION; }
+
+ // Transfer data from source using a series of callbacks. More suitable for zero-fill,
+ // synthesis, and non-contiguous transfers (e.g. circular buffer or readv).
+ // Inputs:
+ // via Callback function that the source will call as many times as needed to provide data.
+ // total Estimate of the number of frames the consumer desires. This is an estimate,
+ // and it can consume a different number of frames during the series of callbacks.
+ // user Arbitrary void * reserved for data consumer.
+ // block Number of frames per block, that is a suggested value for 'count' in each callback.
+ // Zero means no preference. This parameter is a hint only, and may be ignored.
+ // Return value:
+ // > 0 Total number of frames successfully transferred prior to first error.
+ // = 0 Count was zero.
+ // < 0 status_t error occurred prior to the first frame transfer.
+ // Errors:
+ // NEGOTIATE (Re-)negotiation is needed.
+ // WOULD_BLOCK No frames can be transferred without blocking.
+ // OVERRUN read() has not been called frequently enough, or with enough frames to keep up.
+ // One or more frames were lost due to overrun, try again to read more recent data.
+ //
+ // The 'via' callback is called by the data source as follows:
+ // Inputs:
+ // user Arbitrary void * reserved for data consumer.
+ // dest Non-NULL buffer owned by source that callback should consume data from,
+ // up to a maximum of 'count' frames.
+ // count Maximum number of frames to transfer during this callback.
+ // Return value:
+ // > 0 Number of frames successfully transferred during this callback prior to first error.
+ // = 0 Count was zero.
+ // < 0 status_t error occurred prior to the first frame transfer during this callback.
+ virtual ssize_t readVia(readVia_t via, size_t total, void *user, size_t block = 0);
+
+ // Invoked asynchronously by corresponding sink when a new timestamp is available.
+ // Default implementation ignores the timestamp.
+ virtual void onTimestamp(const ExtendedTimestamp& /*timestamp*/) { }
+
+protected:
+ NBAIO_Source(const NBAIO_Format& format = Format_Invalid) : NBAIO_Port(format), mFramesRead(0)
+ { }
+ virtual ~NBAIO_Source() { }
+
+ // Implementations are free to ignore these if they don't need them
+ int64_t mFramesRead;
+};
+
+} // namespace android
+
+#endif // ANDROID_AUDIO_NBAIO_H
diff --git a/media/libnbaio/include/NBLog.h b/media/libnbaio/include/NBLog.h
new file mode 100644
index 0000000..043f15e
--- /dev/null
+++ b/media/libnbaio/include/NBLog.h
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+// Non-blocking event logger intended for safe communication between processes via shared memory
+
+#ifndef ANDROID_MEDIA_NBLOG_H
+#define ANDROID_MEDIA_NBLOG_H
+
+#include <binder/IMemory.h>
+#include <utils/Mutex.h>
+#include <audio_utils/fifo.h>
+
+#include <vector>
+
+namespace android {
+
+class String8;
+
+class NBLog {
+
+public:
+
+class Writer;
+class Reader;
+
+private:
+
+enum Event {
+ EVENT_RESERVED,
+ EVENT_STRING, // ASCII string, not NUL-terminated
+ EVENT_TIMESTAMP, // clock_gettime(CLOCK_MONOTONIC)
+ EVENT_INTEGER, // integer value entry
+ EVENT_FLOAT, // floating point value entry
+ EVENT_PID, // process ID and process name
+ EVENT_AUTHOR, // author index (present in merged logs) tracks entry's original log
+ EVENT_START_FMT, // logFormat start event: entry includes format string, following
+ // entries contain format arguments
+ EVENT_END_FMT, // end of logFormat argument list
+};
+
+
+// ---------------------------------------------------------------------------
+// API for handling format entry operations
+
+// a formatted entry has the following structure:
+// * START_FMT entry, containing the format string
+// * author entry of the thread that generated it (optional, present in merged log)
+// * TIMESTAMP entry
+// * format arg1
+// * format arg2
+// * ...
+// * END_FMT entry
+
+class FormatEntry {
+public:
+ // build a Format Entry starting in the given pointer
+ class iterator;
+ explicit FormatEntry(const uint8_t *entry);
+ explicit FormatEntry(const iterator &it);
+
+ // entry representation in memory
+ struct entry {
+ const uint8_t type;
+ const uint8_t length;
+ const uint8_t data[0];
+ };
+
+ // entry tail representation (after data)
+ struct ending {
+ uint8_t length;
+ uint8_t next[0];
+ };
+
+ // entry iterator
+ class iterator {
+ public:
+ iterator(const uint8_t *entry);
+ iterator(const iterator &other);
+
+ // dereference underlying entry
+ const entry& operator*() const;
+ const entry* operator->() const;
+ // advance to next entry
+ iterator& operator++(); // ++i
+ // back to previous entry
+ iterator& operator--(); // --i
+ bool operator!=(const iterator &other) const;
+ int operator-(const iterator &other) const;
+
+ bool hasConsistentLength() const;
+ void copyTo(std::unique_ptr<audio_utils_fifo_writer> &dst) const;
+ void copyData(uint8_t *dst) const;
+
+ template<typename T>
+ inline const T& payload() {
+ return *reinterpret_cast<const T *>(ptr + 2);
+ }
+
+ private:
+ friend class FormatEntry;
+ const uint8_t *ptr;
+ };
+
+ // Entry's format string
+ const char* formatString() const;
+
+ // Enrty's format string length
+ size_t formatStringLength() const;
+
+ // Format arguments (excluding format string, timestamp and author)
+ iterator args() const;
+
+ // get format entry timestamp
+ timespec timestamp() const;
+
+ // entry's author index (-1 if none present)
+ // a Merger has a vector of Readers, author simply points to the index of the
+ // Reader that originated the entry
+ int author() const;
+
+ // copy entry, adding author before timestamp, returns size of original entry
+ size_t copyTo(std::unique_ptr<audio_utils_fifo_writer> &dst, int author) const;
+
+ iterator begin() const;
+
+private:
+ // copies ordinary entry from src to dst, and returns length of entry
+ // size_t copyEntry(audio_utils_fifo_writer *dst, const iterator &it);
+ const uint8_t *mEntry;
+};
+
+// ---------------------------------------------------------------------------
+
+// representation of a single log entry in private memory
+struct Entry {
+ Entry(Event event, const void *data, size_t length)
+ : mEvent(event), mLength(length), mData(data) { }
+ /*virtual*/ ~Entry() { }
+
+ int readAt(size_t offset) const;
+
+private:
+ friend class Writer;
+ Event mEvent; // event type
+ uint8_t mLength; // length of additional data, 0 <= mLength <= kMaxLength
+ const void *mData; // event type-specific data
+ static const size_t kMaxLength = 255;
+public:
+ // mEvent, mLength, mData[...], duplicate mLength
+ static const size_t kOverhead = sizeof(FormatEntry::entry) + sizeof(FormatEntry::ending);
+ // endind length of previous entry
+ static const size_t kPreviousLengthOffset = - sizeof(FormatEntry::ending) +
+ offsetof(FormatEntry::ending, length);
+};
+
+// representation of a single log entry in shared memory
+// byte[0] mEvent
+// byte[1] mLength
+// byte[2] mData[0]
+// ...
+// byte[2+i] mData[i]
+// ...
+// byte[2+mLength-1] mData[mLength-1]
+// byte[2+mLength] duplicate copy of mLength to permit reverse scan
+// byte[3+mLength] start of next log entry
+
+ static void appendInt(String8 *body, const void *data);
+ static void appendFloat(String8 *body, const void *data);
+ static void appendPID(String8 *body, const void *data, size_t length);
+ static void appendTimestamp(String8 *body, const void *data);
+ static size_t fmtEntryLength(const uint8_t *data);
+
+public:
+
+// Located in shared memory, must be POD.
+// Exactly one process must explicitly call the constructor or use placement new.
+// Since this is a POD, the destructor is empty and unnecessary to call it explicitly.
+struct Shared {
+ Shared() /* mRear initialized via default constructor */ { }
+ /*virtual*/ ~Shared() { }
+
+ audio_utils_fifo_index mRear; // index one byte past the end of most recent Entry
+ char mBuffer[0]; // circular buffer for entries
+};
+
+public:
+
+// ---------------------------------------------------------------------------
+
+// FIXME Timeline was intended to wrap Writer and Reader, but isn't actually used yet.
+// For now it is just a namespace for sharedSize().
+class Timeline : public RefBase {
+public:
+#if 0
+ Timeline(size_t size, void *shared = NULL);
+ virtual ~Timeline();
+#endif
+
+ // Input parameter 'size' is the desired size of the timeline in byte units.
+ // Returns the size rounded up to a power-of-2, plus the constant size overhead for indices.
+ static size_t sharedSize(size_t size);
+
+#if 0
+private:
+ friend class Writer;
+ friend class Reader;
+
+ const size_t mSize; // circular buffer size in bytes, must be a power of 2
+ bool mOwn; // whether I own the memory at mShared
+ Shared* const mShared; // pointer to shared memory
+#endif
+};
+
+// ---------------------------------------------------------------------------
+
+// Writer is thread-safe with respect to Reader, but not with respect to multiple threads
+// calling Writer methods. If you need multi-thread safety for writing, use LockedWriter.
+class Writer : public RefBase {
+public:
+ Writer(); // dummy nop implementation without shared memory
+
+ // Input parameter 'size' is the desired size of the timeline in byte units.
+ // The size of the shared memory must be at least Timeline::sharedSize(size).
+ Writer(void *shared, size_t size);
+ Writer(const sp<IMemory>& iMemory, size_t size);
+
+ virtual ~Writer();
+
+ virtual void log(const char *string);
+ virtual void logf(const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+ virtual void logvf(const char *fmt, va_list ap);
+ virtual void logTimestamp();
+ virtual void logTimestamp(const struct timespec &ts);
+ virtual void logInteger(const int x);
+ virtual void logFloat(const float x);
+ virtual void logPID();
+ virtual void logFormat(const char *fmt, ...);
+ virtual void logVFormat(const char *fmt, va_list ap);
+ virtual void logStart(const char *fmt);
+ virtual void logEnd();
+
+
+ virtual bool isEnabled() const;
+
+ // return value for all of these is the previous isEnabled()
+ virtual bool setEnabled(bool enabled); // but won't enable if no shared memory
+ bool enable() { return setEnabled(true); }
+ bool disable() { return setEnabled(false); }
+
+ sp<IMemory> getIMemory() const { return mIMemory; }
+
+private:
+ // 0 <= length <= kMaxLength
+ void log(Event event, const void *data, size_t length);
+ void log(const Entry *entry, bool trusted = false);
+
+ Shared* const mShared; // raw pointer to shared memory
+ sp<IMemory> mIMemory; // ref-counted version, initialized in constructor and then const
+ audio_utils_fifo * const mFifo; // FIFO itself,
+ // non-NULL unless constructor fails
+ audio_utils_fifo_writer * const mFifoWriter; // used to write to FIFO,
+ // non-NULL unless dummy constructor used
+ bool mEnabled; // whether to actually log
+
+ // cached pid and process name to use in %p format specifier
+ // total tag length is mPidTagSize and process name is not zero terminated
+ char *mPidTag;
+ size_t mPidTagSize;
+};
+
+// ---------------------------------------------------------------------------
+
+// Similar to Writer, but safe for multiple threads to call concurrently
+class LockedWriter : public Writer {
+public:
+ LockedWriter();
+ LockedWriter(void *shared, size_t size);
+
+ virtual void log(const char *string);
+ virtual void logf(const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+ virtual void logvf(const char *fmt, va_list ap);
+ virtual void logTimestamp();
+ virtual void logTimestamp(const struct timespec &ts);
+ virtual void logInteger(const int x);
+ virtual void logFloat(const float x);
+ virtual void logPID();
+ virtual void logStart(const char *fmt);
+ virtual void logEnd();
+
+ virtual bool isEnabled() const;
+ virtual bool setEnabled(bool enabled);
+
+private:
+ mutable Mutex mLock;
+};
+
+// ---------------------------------------------------------------------------
+
+class Reader : public RefBase {
+public:
+
+ // A snapshot of a readers buffer
+ class Snapshot {
+ public:
+ Snapshot() : mData(NULL), mAvail(0), mLost(0) {}
+
+ Snapshot(size_t bufferSize) : mData(new uint8_t[bufferSize]) {}
+
+ ~Snapshot() { delete[] mData; }
+
+ // copy of the buffer
+ const uint8_t *data() const { return mData; }
+
+ // amount of data available (given by audio_utils_fifo_reader)
+ size_t available() const { return mAvail; }
+
+ // amount of data lost (given by audio_utils_fifo_reader)
+ size_t lost() const { return mLost; }
+
+ private:
+ friend class Reader;
+ const uint8_t *mData;
+ size_t mAvail;
+ size_t mLost;
+ };
+
+ // Input parameter 'size' is the desired size of the timeline in byte units.
+ // The size of the shared memory must be at least Timeline::sharedSize(size).
+ Reader(const void *shared, size_t size);
+ Reader(const sp<IMemory>& iMemory, size_t size);
+
+ virtual ~Reader();
+
+ // get snapshot of readers fifo buffer, effectively consuming the buffer
+ std::unique_ptr<Snapshot> getSnapshot();
+ // dump a particular snapshot of the reader
+ void dump(int fd, size_t indent, Snapshot & snap);
+ // dump the current content of the reader's buffer
+ void dump(int fd, size_t indent = 0);
+ bool isIMemory(const sp<IMemory>& iMemory) const;
+
+private:
+ /*const*/ Shared* const mShared; // raw pointer to shared memory, actually const but not
+ // declared as const because audio_utils_fifo() constructor
+ sp<IMemory> mIMemory; // ref-counted version, assigned only in constructor
+ int mFd; // file descriptor
+ int mIndent; // indentation level
+ audio_utils_fifo * const mFifo; // FIFO itself,
+ // non-NULL unless constructor fails
+ audio_utils_fifo_reader * const mFifoReader; // used to read from FIFO,
+ // non-NULL unless constructor fails
+
+ void dumpLine(const String8& timestamp, String8& body);
+
+ FormatEntry::iterator handleFormat(const FormatEntry &fmtEntry,
+ String8 *timestamp,
+ String8 *body);
+ // dummy method for handling absent author entry
+ virtual size_t handleAuthor(const FormatEntry &fmtEntry, String8 *body) { return 0; }
+
+ static const size_t kSquashTimestamp = 5; // squash this many or more adjacent timestamps
+};
+
+// Wrapper for a reader with a name. Contains a pointer to the reader and a pointer to the name
+class NamedReader {
+public:
+ NamedReader() { mName[0] = '\0'; } // for Vector
+ NamedReader(const sp<NBLog::Reader>& reader, const char *name) :
+ mReader(reader)
+ { strlcpy(mName, name, sizeof(mName)); }
+ ~NamedReader() { }
+ const sp<NBLog::Reader>& reader() const { return mReader; }
+ const char* name() const { return mName; }
+
+private:
+ sp<NBLog::Reader> mReader;
+ static const size_t kMaxName = 32;
+ char mName[kMaxName];
+};
+
+// ---------------------------------------------------------------------------
+
+class Merger : public RefBase {
+public:
+ Merger(const void *shared, size_t size);
+
+ virtual ~Merger() {}
+
+ void addReader(const NamedReader &reader);
+ // TODO add removeReader
+ void merge();
+ const std::vector<NamedReader> *getNamedReaders() const;
+private:
+ // vector of the readers the merger is supposed to merge from.
+ // every reader reads from a writer's buffer
+ std::vector<NamedReader> mNamedReaders;
+ uint8_t *mBuffer;
+ Shared * const mShared;
+ std::unique_ptr<audio_utils_fifo> mFifo;
+ std::unique_ptr<audio_utils_fifo_writer> mFifoWriter;
+
+ static struct timespec getTimestamp(const uint8_t *data);
+};
+
+class MergeReader : public Reader {
+public:
+ MergeReader(const void *shared, size_t size, Merger &merger);
+private:
+ const std::vector<NamedReader> *mNamedReaders;
+ // handle author entry by looking up the author's name and appending it to the body
+ // returns number of bytes read from fmtEntry
+ size_t handleAuthor(const FormatEntry &fmtEntry, String8 *body);
+};
+
+}; // class NBLog
+
+} // namespace android
+
+#endif // ANDROID_MEDIA_NBLOG_H
diff --git a/media/libnbaio/include/Pipe.h b/media/libnbaio/include/Pipe.h
new file mode 100644
index 0000000..58b9750
--- /dev/null
+++ b/media/libnbaio/include/Pipe.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2012 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_AUDIO_PIPE_H
+#define ANDROID_AUDIO_PIPE_H
+
+#include <audio_utils/fifo.h>
+#include "NBAIO.h"
+
+namespace android {
+
+// Pipe is multi-thread safe for readers (see PipeReader), but safe for only a single writer thread.
+// It cannot UNDERRUN on write, unless we allow designation of a master reader that provides the
+// time-base. Readers can be added and removed dynamically, and it's OK to have no readers.
+class Pipe : public NBAIO_Sink {
+
+ friend class PipeReader;
+
+public:
+ // maxFrames will be rounded up to a power of 2, and all slots are available. Must be >= 2.
+ // buffer is an optional parameter specifying the virtual address of the pipe buffer,
+ // which must be of size roundup(maxFrames) * Format_frameSize(format) bytes.
+ Pipe(size_t maxFrames, const NBAIO_Format& format, void *buffer = NULL);
+
+ // If a buffer was specified in the constructor, it is not automatically freed by destructor.
+ virtual ~Pipe();
+
+ // NBAIO_Port interface
+
+ //virtual ssize_t negotiate(const NBAIO_Format offers[], size_t numOffers,
+ // NBAIO_Format counterOffers[], size_t& numCounterOffers);
+ //virtual NBAIO_Format format() const;
+
+ // NBAIO_Sink interface
+
+ //virtual int64_t framesWritten() const;
+ //virtual int64_t framesUnderrun() const;
+ //virtual int64_t underruns() const;
+
+ // The write side of a pipe permits overruns; flow control is the caller's responsibility.
+ // It doesn't return +infinity because that would guarantee an overrun.
+ virtual ssize_t availableToWrite() { return mMaxFrames; }
+
+ virtual ssize_t write(const void *buffer, size_t count);
+ //virtual ssize_t writeVia(writeVia_t via, size_t total, void *user, size_t block);
+
+private:
+ const size_t mMaxFrames; // always a power of 2
+ void * const mBuffer;
+ audio_utils_fifo mFifo;
+ audio_utils_fifo_writer mFifoWriter;
+ volatile int32_t mReaders; // number of PipeReader clients currently attached to this Pipe
+ const bool mFreeBufferInDestructor;
+};
+
+} // namespace android
+
+#endif // ANDROID_AUDIO_PIPE_H
diff --git a/media/libnbaio/include/PipeReader.h b/media/libnbaio/include/PipeReader.h
new file mode 100644
index 0000000..70ecb34
--- /dev/null
+++ b/media/libnbaio/include/PipeReader.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 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_AUDIO_PIPE_READER_H
+#define ANDROID_AUDIO_PIPE_READER_H
+
+#include "Pipe.h"
+
+namespace android {
+
+// PipeReader is safe for only a single thread
+class PipeReader : public NBAIO_Source {
+
+public:
+
+ // Construct a PipeReader and associate it with a Pipe
+ // FIXME make this constructor a factory method of Pipe.
+ PipeReader(Pipe& pipe);
+ virtual ~PipeReader();
+
+ // NBAIO_Port interface
+
+ //virtual ssize_t negotiate(const NBAIO_Format offers[], size_t numOffers,
+ // NBAIO_Format counterOffers[], size_t& numCounterOffers);
+ //virtual NBAIO_Format format() const;
+
+ // NBAIO_Source interface
+
+ //virtual size_t framesRead() const;
+ virtual int64_t framesOverrun() { return mFramesOverrun; }
+ virtual int64_t overruns() { return mOverruns; }
+
+ virtual ssize_t availableToRead();
+
+ virtual ssize_t read(void *buffer, size_t count);
+
+ virtual ssize_t flush();
+
+ // NBAIO_Source end
+
+#if 0 // until necessary
+ Pipe& pipe() const { return mPipe; }
+#endif
+
+private:
+ Pipe& mPipe;
+ audio_utils_fifo_reader mFifoReader;
+ int64_t mFramesOverrun;
+ int64_t mOverruns;
+};
+
+} // namespace android
+
+#endif // ANDROID_AUDIO_PIPE_READER_H
diff --git a/media/libnbaio/include/SourceAudioBufferProvider.h b/media/libnbaio/include/SourceAudioBufferProvider.h
new file mode 100644
index 0000000..ae49903
--- /dev/null
+++ b/media/libnbaio/include/SourceAudioBufferProvider.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+// Implementation of AudioBufferProvider that wraps an NBAIO_Source
+
+#ifndef ANDROID_SOURCE_AUDIO_BUFFER_PROVIDER_H
+#define ANDROID_SOURCE_AUDIO_BUFFER_PROVIDER_H
+
+#include "NBAIO.h"
+#include <media/ExtendedAudioBufferProvider.h>
+
+namespace android {
+
+class SourceAudioBufferProvider : public ExtendedAudioBufferProvider {
+
+public:
+ SourceAudioBufferProvider(const sp<NBAIO_Source>& source);
+ virtual ~SourceAudioBufferProvider();
+
+ // AudioBufferProvider interface
+ virtual status_t getNextBuffer(Buffer *buffer);
+ virtual void releaseBuffer(Buffer *buffer);
+
+ // ExtendedAudioBufferProvider interface
+ virtual size_t framesReady() const;
+ virtual int64_t framesReleased() const;
+ virtual void onTimestamp(const ExtendedTimestamp ×tamp);
+
+private:
+ const sp<NBAIO_Source> mSource; // the wrapped source
+ /*const*/ size_t mFrameSize; // frame size in bytes
+ void* mAllocated; // pointer to base of allocated memory
+ size_t mSize; // size of mAllocated in frames
+ size_t mOffset; // frame offset within mAllocated of valid data
+ size_t mRemaining; // frame count within mAllocated of valid data
+ size_t mGetCount; // buffer.frameCount of the most recent getNextBuffer
+ int64_t mFramesReleased; // counter of the total number of frames released
+};
+
+} // namespace android
+
+#endif // ANDROID_SOURCE_AUDIO_BUFFER_PROVIDER_H
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index 0557d95..3548f96 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -26,6 +26,8 @@
include_dirs: ["frameworks/av/include/media/stagefright/foundation"],
+ export_include_dirs: ["include"],
+
shared_libs: [
"libbinder",
"libutils",
diff --git a/media/libstagefright/foundation/include b/media/libstagefright/foundation/include
new file mode 120000
index 0000000..3a1af68
--- /dev/null
+++ b/media/libstagefright/foundation/include
@@ -0,0 +1 @@
+../include/
\ No newline at end of file
diff --git a/media/libstagefright/include/AACWriter.h b/media/libstagefright/include/AACWriter.h
new file mode 100644
index 0000000..a1f63d7
--- /dev/null
+++ b/media/libstagefright/include/AACWriter.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2011 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 AAC_WRITER_H_
+#define AAC_WRITER_H_
+
+#include "foundation/ABase.h"
+#include <media/stagefright/MediaWriter.h>
+#include <utils/threads.h>
+
+namespace android {
+
+struct MediaSource;
+class MetaData;
+
+struct AACWriter : public MediaWriter {
+ AACWriter(int fd);
+
+ status_t initCheck() const;
+
+ virtual status_t addSource(const sp<IMediaSource> &source);
+ virtual bool reachedEOS();
+ virtual status_t start(MetaData *params = NULL);
+ virtual status_t stop() { return reset(); }
+ virtual status_t pause();
+
+protected:
+ virtual ~AACWriter();
+
+private:
+ enum {
+ kAdtsHeaderLength = 7, // # of bytes for the adts header
+ kSamplesPerFrame = 1024, // # of samples in a frame
+ };
+
+ int mFd;
+ status_t mInitCheck;
+ sp<IMediaSource> mSource;
+ bool mStarted;
+ volatile bool mPaused;
+ volatile bool mResumed;
+ volatile bool mDone;
+ volatile bool mReachedEOS;
+ pthread_t mThread;
+ int64_t mEstimatedSizeBytes;
+ int64_t mEstimatedDurationUs;
+ int32_t mChannelCount;
+ int32_t mSampleRate;
+ int32_t mAACProfile;
+ int32_t mFrameDurationUs;
+
+ static void *ThreadWrapper(void *);
+ status_t threadFunc();
+ bool exceedsFileSizeLimit();
+ bool exceedsFileDurationLimit();
+ status_t writeAdtsHeader(uint32_t frameLength);
+ status_t reset();
+
+ DISALLOW_EVIL_CONSTRUCTORS(AACWriter);
+};
+
+} // namespace android
+
+#endif // AAC_WRITER_H_
diff --git a/media/libstagefright/include/ACodec.h b/media/libstagefright/include/ACodec.h
new file mode 100644
index 0000000..998716f
--- /dev/null
+++ b/media/libstagefright/include/ACodec.h
@@ -0,0 +1,560 @@
+/*
+ * 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 A_CODEC_H_
+
+#define A_CODEC_H_
+
+#include <stdint.h>
+#include <android/native_window.h>
+#include <media/hardware/MetadataBufferType.h>
+#include <media/IOMX.h>
+#include <media/stagefright/foundation/AHierarchicalStateMachine.h>
+#include <media/stagefright/CodecBase.h>
+#include <media/stagefright/FrameRenderTracker.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/SkipCutBuffer.h>
+#include <utils/NativeHandle.h>
+#include <OMX_Audio.h>
+#include <hardware/gralloc.h>
+
+#define TRACK_BUFFER_TIMING 0
+
+namespace android {
+
+struct ABuffer;
+class ACodecBufferChannel;
+class MediaCodecBuffer;
+class MemoryDealer;
+struct DescribeColorFormat2Params;
+struct DataConverter;
+
+// Treble shared memory
+namespace hidl {
+namespace allocator {
+namespace V1_0 {
+struct IAllocator;
+} // V1_0
+} // allocator
+namespace memory {
+namespace V1_0 {
+struct IMemory;
+} // V1_0
+} // memory
+} // hidl
+
+typedef hidl::allocator::V1_0::IAllocator TAllocator;
+typedef hidl::memory::V1_0::IMemory TMemory;
+
+struct ACodec : public AHierarchicalStateMachine, public CodecBase {
+ ACodec();
+
+ void initiateSetup(const sp<AMessage> &msg);
+
+ virtual std::shared_ptr<BufferChannelBase> getBufferChannel() override;
+ virtual void initiateAllocateComponent(const sp<AMessage> &msg);
+ virtual void initiateConfigureComponent(const sp<AMessage> &msg);
+ virtual void initiateCreateInputSurface();
+ virtual void initiateSetInputSurface(const sp<PersistentSurface> &surface);
+ virtual void initiateStart();
+ virtual void initiateShutdown(bool keepComponentAllocated = false);
+
+ virtual status_t queryCapabilities(
+ const AString &name, const AString &mime, bool isEncoder,
+ sp<MediaCodecInfo::Capabilities> *caps);
+
+ virtual status_t setSurface(const sp<Surface> &surface);
+
+ virtual void signalFlush();
+ virtual void signalResume();
+
+ virtual void signalSetParameters(const sp<AMessage> &msg);
+ virtual void signalEndOfInputStream();
+ virtual void signalRequestIDRFrame();
+
+ // AHierarchicalStateMachine implements the message handling
+ virtual void onMessageReceived(const sp<AMessage> &msg) {
+ handleMessage(msg);
+ }
+
+ // Returns 0 if configuration is not supported. NOTE: this is treated by
+ // some OMX components as auto level, and by others as invalid level.
+ static int /* OMX_VIDEO_AVCLEVELTYPE */ getAVCLevelFor(
+ int width, int height, int rate, int bitrate,
+ OMX_VIDEO_AVCPROFILETYPE profile = OMX_VIDEO_AVCProfileBaseline);
+
+ // Quirk still supported, even though deprecated
+ enum Quirks {
+ kRequiresAllocateBufferOnInputPorts = 1,
+ kRequiresAllocateBufferOnOutputPorts = 2,
+ };
+
+ static status_t getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]);
+
+ // Save the flag.
+ void setTrebleFlag(bool trebleFlag);
+ // Return the saved flag.
+ bool getTrebleFlag() const;
+
+protected:
+ virtual ~ACodec();
+
+private:
+ struct BaseState;
+ struct UninitializedState;
+ struct LoadedState;
+ struct LoadedToIdleState;
+ struct IdleToExecutingState;
+ struct ExecutingState;
+ struct OutputPortSettingsChangedState;
+ struct ExecutingToIdleState;
+ struct IdleToLoadedState;
+ struct FlushingState;
+ struct DeathNotifier;
+
+ enum {
+ kWhatSetup = 'setu',
+ kWhatOMXMessage = 'omx ',
+ // same as kWhatOMXMessage - but only used with
+ // handleMessage during OMX message-list handling
+ kWhatOMXMessageItem = 'omxI',
+ kWhatOMXMessageList = 'omxL',
+ kWhatInputBufferFilled = 'inpF',
+ kWhatOutputBufferDrained = 'outD',
+ kWhatShutdown = 'shut',
+ kWhatFlush = 'flus',
+ kWhatResume = 'resm',
+ kWhatDrainDeferredMessages = 'drai',
+ kWhatAllocateComponent = 'allo',
+ kWhatConfigureComponent = 'conf',
+ kWhatSetSurface = 'setS',
+ kWhatCreateInputSurface = 'cisf',
+ kWhatSetInputSurface = 'sisf',
+ kWhatSignalEndOfInputStream = 'eois',
+ kWhatStart = 'star',
+ kWhatRequestIDRFrame = 'ridr',
+ kWhatSetParameters = 'setP',
+ kWhatSubmitOutputMetadataBufferIfEOS = 'subm',
+ kWhatOMXDied = 'OMXd',
+ kWhatReleaseCodecInstance = 'relC',
+ };
+
+ enum {
+ kPortIndexInput = 0,
+ kPortIndexOutput = 1
+ };
+
+ enum {
+ kFlagIsSecure = 1,
+ kFlagPushBlankBuffersToNativeWindowOnShutdown = 2,
+ kFlagIsGrallocUsageProtected = 4,
+ };
+
+ enum {
+ kVideoGrallocUsage = (GRALLOC_USAGE_HW_TEXTURE
+ | GRALLOC_USAGE_HW_COMPOSER
+ | GRALLOC_USAGE_EXTERNAL_DISP),
+ };
+
+ struct BufferInfo {
+ enum Status {
+ OWNED_BY_US,
+ OWNED_BY_COMPONENT,
+ OWNED_BY_UPSTREAM,
+ OWNED_BY_DOWNSTREAM,
+ OWNED_BY_NATIVE_WINDOW,
+ UNRECOGNIZED, // not a tracked buffer
+ };
+
+ static inline Status getSafeStatus(BufferInfo *info) {
+ return info == NULL ? UNRECOGNIZED : info->mStatus;
+ }
+
+ IOMX::buffer_id mBufferID;
+ Status mStatus;
+ unsigned mDequeuedAt;
+
+ sp<MediaCodecBuffer> mData; // the client's buffer; if not using data conversion, this is
+ // the codec buffer; otherwise, it is allocated separately
+ sp<RefBase> mMemRef; // and a reference to the IMemory, so it does not go away
+ sp<MediaCodecBuffer> mCodecData; // the codec's buffer
+ sp<RefBase> mCodecRef; // and a reference to the IMemory
+
+ sp<GraphicBuffer> mGraphicBuffer;
+ bool mNewGraphicBuffer;
+ int mFenceFd;
+ FrameRenderTracker::Info *mRenderInfo;
+
+ // The following field and 4 methods are used for debugging only
+ bool mIsReadFence;
+ // Store |fenceFd| and set read/write flag. Log error, if there is already a fence stored.
+ void setReadFence(int fenceFd, const char *dbg);
+ void setWriteFence(int fenceFd, const char *dbg);
+ // Log error, if the current fence is not a read/write fence.
+ void checkReadFence(const char *dbg);
+ void checkWriteFence(const char *dbg);
+ };
+
+ static const char *_asString(BufferInfo::Status s);
+ void dumpBuffers(OMX_U32 portIndex);
+
+ // If |fd| is non-negative, waits for fence with |fd| and logs an error if it fails. Returns
+ // the error code or OK on success. If |fd| is negative, it returns OK
+ status_t waitForFence(int fd, const char *dbg);
+
+#if TRACK_BUFFER_TIMING
+ struct BufferStats {
+ int64_t mEmptyBufferTimeUs;
+ int64_t mFillBufferDoneTimeUs;
+ };
+
+ KeyedVector<int64_t, BufferStats> mBufferStats;
+#endif
+
+ sp<UninitializedState> mUninitializedState;
+ sp<LoadedState> mLoadedState;
+ sp<LoadedToIdleState> mLoadedToIdleState;
+ sp<IdleToExecutingState> mIdleToExecutingState;
+ sp<ExecutingState> mExecutingState;
+ sp<OutputPortSettingsChangedState> mOutputPortSettingsChangedState;
+ sp<ExecutingToIdleState> mExecutingToIdleState;
+ sp<IdleToLoadedState> mIdleToLoadedState;
+ sp<FlushingState> mFlushingState;
+ sp<SkipCutBuffer> mSkipCutBuffer;
+ int32_t mSampleRate;
+
+ AString mComponentName;
+ uint32_t mFlags;
+ sp<IOMX> mOMX;
+ sp<IOMXNode> mOMXNode;
+ int32_t mNodeGeneration;
+ bool mTrebleFlag;
+ sp<TAllocator> mAllocator[2];
+ sp<MemoryDealer> mDealer[2];
+
+ bool mUsingNativeWindow;
+ sp<ANativeWindow> mNativeWindow;
+ int mNativeWindowUsageBits;
+ android_native_rect_t mLastNativeWindowCrop;
+ int32_t mLastNativeWindowDataSpace;
+ sp<AMessage> mConfigFormat;
+ sp<AMessage> mInputFormat;
+ sp<AMessage> mOutputFormat;
+
+ // Initial output format + configuration params that is reused as the base for all subsequent
+ // format updates. This will equal to mOutputFormat until the first actual frame is received.
+ sp<AMessage> mBaseOutputFormat;
+
+ FrameRenderTracker mRenderTracker; // render information for buffers rendered by ACodec
+ Vector<BufferInfo> mBuffers[2];
+ bool mPortEOS[2];
+ status_t mInputEOSResult;
+
+ List<sp<AMessage> > mDeferredQueue;
+
+ sp<AMessage> mLastOutputFormat;
+ bool mIsVideo;
+ bool mIsEncoder;
+ bool mFatalError;
+ bool mShutdownInProgress;
+ bool mExplicitShutdown;
+ bool mIsLegacyVP9Decoder;
+
+ // If "mKeepComponentAllocated" we only transition back to Loaded state
+ // and do not release the component instance.
+ bool mKeepComponentAllocated;
+
+ int32_t mEncoderDelay;
+ int32_t mEncoderPadding;
+ int32_t mRotationDegrees;
+
+ bool mChannelMaskPresent;
+ int32_t mChannelMask;
+ unsigned mDequeueCounter;
+ IOMX::PortMode mPortMode[2];
+ int32_t mMetadataBuffersToSubmit;
+ size_t mNumUndequeuedBuffers;
+ sp<DataConverter> mConverter[2];
+
+ sp<IGraphicBufferSource> mGraphicBufferSource;
+ int64_t mRepeatFrameDelayUs;
+ int64_t mMaxPtsGapUs;
+ float mMaxFps;
+ int64_t mTimePerFrameUs;
+ int64_t mTimePerCaptureUs;
+ bool mCreateInputBuffersSuspended;
+
+ bool mTunneled;
+
+ OMX_INDEXTYPE mDescribeColorAspectsIndex;
+ OMX_INDEXTYPE mDescribeHDRStaticInfoIndex;
+
+ std::shared_ptr<ACodecBufferChannel> mBufferChannel;
+
+ status_t setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode);
+ status_t allocateBuffersOnPort(OMX_U32 portIndex);
+ status_t freeBuffersOnPort(OMX_U32 portIndex);
+ status_t freeBuffer(OMX_U32 portIndex, size_t i);
+
+ status_t handleSetSurface(const sp<Surface> &surface);
+ status_t setPortMode(int32_t portIndex, IOMX::PortMode mode);
+ status_t setupNativeWindowSizeFormatAndUsage(
+ ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */,
+ bool reconnect);
+
+ status_t configureOutputBuffersFromNativeWindow(
+ OMX_U32 *nBufferCount, OMX_U32 *nBufferSize,
+ OMX_U32 *nMinUndequeuedBuffers, bool preregister);
+ status_t allocateOutputMetadataBuffers();
+ status_t submitOutputMetadataBuffer();
+ void signalSubmitOutputMetadataBufferIfEOS_workaround();
+ status_t allocateOutputBuffersFromNativeWindow();
+ status_t cancelBufferToNativeWindow(BufferInfo *info);
+ status_t freeOutputBuffersNotOwnedByComponent();
+ BufferInfo *dequeueBufferFromNativeWindow();
+
+ inline bool storingMetadataInDecodedBuffers() {
+ return (mPortMode[kPortIndexOutput] == IOMX::kPortModeDynamicANWBuffer) && !mIsEncoder;
+ }
+
+ inline bool usingSecureBufferOnEncoderOutput() {
+ return (mPortMode[kPortIndexOutput] == IOMX::kPortModePresetSecureBuffer) && mIsEncoder;
+ }
+
+ BufferInfo *findBufferByID(
+ uint32_t portIndex, IOMX::buffer_id bufferID,
+ ssize_t *index = NULL);
+
+ status_t fillBuffer(BufferInfo *info);
+
+ status_t setComponentRole(bool isEncoder, const char *mime);
+
+ status_t configureCodec(const char *mime, const sp<AMessage> &msg);
+
+ status_t configureTunneledVideoPlayback(int32_t audioHwSync,
+ const sp<ANativeWindow> &nativeWindow);
+
+ status_t setVideoPortFormatType(
+ OMX_U32 portIndex,
+ OMX_VIDEO_CODINGTYPE compressionFormat,
+ OMX_COLOR_FORMATTYPE colorFormat,
+ bool usingNativeBuffers = false);
+
+ status_t setSupportedOutputFormat(bool getLegacyFlexibleFormat);
+
+ status_t setupVideoDecoder(
+ const char *mime, const sp<AMessage> &msg, bool usingNativeBuffers, bool haveSwRenderer,
+ sp<AMessage> &outputformat);
+
+ status_t setupVideoEncoder(
+ const char *mime, const sp<AMessage> &msg,
+ sp<AMessage> &outputformat, sp<AMessage> &inputformat);
+
+ status_t setVideoFormatOnPort(
+ OMX_U32 portIndex,
+ int32_t width, int32_t height,
+ OMX_VIDEO_CODINGTYPE compressionFormat, float frameRate = -1.0);
+
+ // sets |portIndex| port buffer numbers to be |bufferNum|. NOTE: Component could reject
+ // this setting if the |bufferNum| is less than the minimum buffer num of the port.
+ status_t setPortBufferNum(OMX_U32 portIndex, int bufferNum);
+
+ // gets index or sets it to 0 on error. Returns error from codec.
+ status_t initDescribeColorAspectsIndex();
+
+ // sets |params|. If |readBack| is true, it re-gets them afterwards if set succeeded.
+ // returns the codec error.
+ status_t setCodecColorAspects(DescribeColorAspectsParams ¶ms, bool readBack = false);
+
+ // gets |params|; returns the codec error. |param| should not change on error.
+ status_t getCodecColorAspects(DescribeColorAspectsParams ¶ms);
+
+ // gets dataspace guidance from codec and platform. |params| should be set up with the color
+ // aspects to use. If |tryCodec| is true, the codec is queried first. If it succeeds, we
+ // return OK. Otherwise, we fall back to the platform guidance and return the codec error;
+ // though, we return OK if the codec failed with UNSUPPORTED, as codec guidance is optional.
+ status_t getDataSpace(
+ DescribeColorAspectsParams ¶ms, android_dataspace *dataSpace /* nonnull */,
+ bool tryCodec);
+
+ // sets color aspects for the encoder for certain |width/height| based on |configFormat|, and
+ // set resulting color config into |outputFormat|. If |usingNativeWindow| is true, we use
+ // video defaults if config is unspecified. Returns error from the codec.
+ status_t setColorAspectsForVideoDecoder(
+ int32_t width, int32_t height, bool usingNativeWindow,
+ const sp<AMessage> &configFormat, sp<AMessage> &outputFormat);
+
+ // gets color aspects for the encoder for certain |width/height| based on |configFormat|, and
+ // set resulting color config into |outputFormat|. If |dataSpace| is non-null, it requests
+ // dataspace guidance from the codec and platform and sets it into |dataSpace|. Returns the
+ // error from the codec.
+ status_t getColorAspectsAndDataSpaceForVideoDecoder(
+ int32_t width, int32_t height, const sp<AMessage> &configFormat,
+ sp<AMessage> &outputFormat, android_dataspace *dataSpace);
+
+ // sets color aspects for the video encoder assuming bytebuffer mode for certain |configFormat|
+ // and sets resulting color config into |outputFormat|. For mediarecorder, also set dataspace
+ // into |inputFormat|. Returns the error from the codec.
+ status_t setColorAspectsForVideoEncoder(
+ const sp<AMessage> &configFormat,
+ sp<AMessage> &outputFormat, sp<AMessage> &inputFormat);
+
+ // sets color aspects for the video encoder in surface mode. This basically sets the default
+ // video values for unspecified aspects and sets the dataspace to use in the input format.
+ // Also sets the dataspace into |dataSpace|.
+ // Returns any codec errors during this configuration, except for optional steps.
+ status_t setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
+ android_dataspace *dataSpace /* nonnull */);
+
+ // gets color aspects for the video encoder input port and sets them into the |format|.
+ // Returns any codec errors.
+ status_t getInputColorAspectsForVideoEncoder(sp<AMessage> &format);
+
+ // updates the encoder output format with |aspects| defaulting to |dataSpace| for
+ // unspecified values.
+ void onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects);
+
+ // gets index or sets it to 0 on error. Returns error from codec.
+ status_t initDescribeHDRStaticInfoIndex();
+
+ // sets HDR static metadata for the video encoder/decoder based on |configFormat|, and
+ // sets resulting HDRStaticInfo config into |outputFormat|. Returns error from the codec.
+ status_t setHDRStaticInfoForVideoCodec(
+ OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat);
+
+ // sets |params|. Returns the codec error.
+ status_t setHDRStaticInfo(const DescribeHDRStaticInfoParams ¶ms);
+
+ // gets |params|. Returns the codec error.
+ status_t getHDRStaticInfo(DescribeHDRStaticInfoParams ¶ms);
+
+ // gets HDR static information for the video encoder/decoder port and sets them into |format|.
+ status_t getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format);
+
+ typedef struct drcParams {
+ int32_t drcCut;
+ int32_t drcBoost;
+ int32_t heavyCompression;
+ int32_t targetRefLevel;
+ int32_t encodedTargetLevel;
+ } drcParams_t;
+
+ status_t setupAACCodec(
+ bool encoder,
+ int32_t numChannels, int32_t sampleRate, int32_t bitRate,
+ int32_t aacProfile, bool isADTS, int32_t sbrMode,
+ int32_t maxOutputChannelCount, const drcParams_t& drc,
+ int32_t pcmLimiterEnable);
+
+ status_t setupAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
+
+ status_t setupEAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
+
+ status_t selectAudioPortFormat(
+ OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);
+
+ status_t setupAMRCodec(bool encoder, bool isWAMR, int32_t bitRate);
+ status_t setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels);
+
+ status_t setupFlacCodec(
+ bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel);
+
+ status_t setupRawAudioFormat(
+ OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels,
+ AudioEncoding encoding = kAudioEncodingPcm16bit);
+
+ status_t setPriority(int32_t priority);
+ status_t setOperatingRate(float rateFloat, bool isVideo);
+ status_t getIntraRefreshPeriod(uint32_t *intraRefreshPeriod);
+ status_t setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure);
+
+ // Configures temporal layering based on |msg|. |inConfigure| shall be true iff this is called
+ // during configure() call. on success the configured layering is set in |outputFormat|. If
+ // |outputFormat| is mOutputFormat, it is copied to trigger an output format changed event.
+ status_t configureTemporalLayers(
+ const sp<AMessage> &msg, bool inConfigure, sp<AMessage> &outputFormat);
+
+ status_t setMinBufferSize(OMX_U32 portIndex, size_t size);
+
+ status_t setupMPEG4EncoderParameters(const sp<AMessage> &msg);
+ status_t setupH263EncoderParameters(const sp<AMessage> &msg);
+ status_t setupAVCEncoderParameters(const sp<AMessage> &msg);
+ status_t setupHEVCEncoderParameters(const sp<AMessage> &msg);
+ status_t setupVPXEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat);
+
+ status_t verifySupportForProfileAndLevel(int32_t profile, int32_t level);
+
+ status_t configureBitrate(
+ int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode);
+
+ status_t setupErrorCorrectionParameters();
+
+ // Returns true iff all buffers on the given port have status
+ // OWNED_BY_US or OWNED_BY_NATIVE_WINDOW.
+ bool allYourBuffersAreBelongToUs(OMX_U32 portIndex);
+
+ bool allYourBuffersAreBelongToUs();
+
+ void waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
+
+ size_t countBuffersOwnedByComponent(OMX_U32 portIndex) const;
+ size_t countBuffersOwnedByNativeWindow() const;
+
+ void deferMessage(const sp<AMessage> &msg);
+ void processDeferredMessages();
+
+ void onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
+ // called when we have dequeued a buffer |buf| from the native window to track render info.
+ // |fenceFd| is the dequeue fence, and |info| points to the buffer info where this buffer is
+ // stored.
+ void updateRenderInfoForDequeuedBuffer(
+ ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info);
+
+ // Checks to see if any frames have rendered up until |until|, and to notify client
+ // (MediaCodec) of rendered frames up-until the frame pointed to by |until| or the first
+ // unrendered frame. These frames are removed from the render queue.
+ // If |dropIncomplete| is true, unrendered frames up-until |until| will be dropped from the
+ // queue, allowing all rendered framed up till then to be notified of.
+ // (This will effectively clear the render queue up-until (and including) |until|.)
+ // If |until| is NULL, or is not in the rendered queue, this method will check all frames.
+ void notifyOfRenderedFrames(
+ bool dropIncomplete = false, FrameRenderTracker::Info *until = NULL);
+
+ // Pass |expectedFormat| to print a warning if the format differs from it.
+ // Using sp<> instead of const sp<>& because expectedFormat is likely the current mOutputFormat
+ // which will get updated inside.
+ void onOutputFormatChanged(sp<const AMessage> expectedFormat = NULL);
+ void addKeyFormatChangesToRenderBufferNotification(sp<AMessage> ¬ify);
+ void sendFormatChange();
+
+ status_t getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify);
+
+ void signalError(
+ OMX_ERRORTYPE error = OMX_ErrorUndefined,
+ status_t internalError = UNKNOWN_ERROR);
+
+ status_t requestIDRFrame();
+ status_t setParameters(const sp<AMessage> ¶ms);
+
+ // Send EOS on input stream.
+ void onSignalEndOfInputStream();
+
+ DISALLOW_EVIL_CONSTRUCTORS(ACodec);
+};
+
+} // namespace android
+
+#endif // A_CODEC_H_
diff --git a/media/libstagefright/include/AMRWriter.h b/media/libstagefright/include/AMRWriter.h
new file mode 100644
index 0000000..fbbdf2e
--- /dev/null
+++ b/media/libstagefright/include/AMRWriter.h
@@ -0,0 +1,70 @@
+/*
+ * 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 AMR_WRITER_H_
+
+#define AMR_WRITER_H_
+
+#include <stdio.h>
+
+#include <media/IMediaSource.h>
+#include <media/stagefright/MediaWriter.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class MetaData;
+
+struct AMRWriter : public MediaWriter {
+ AMRWriter(int fd);
+
+ status_t initCheck() const;
+
+ virtual status_t addSource(const sp<IMediaSource> &source);
+ virtual bool reachedEOS();
+ virtual status_t start(MetaData *params = NULL);
+ virtual status_t stop() { return reset(); }
+ virtual status_t pause();
+
+protected:
+ virtual ~AMRWriter();
+
+private:
+ int mFd;
+ status_t mInitCheck;
+ sp<IMediaSource> mSource;
+ bool mStarted;
+ volatile bool mPaused;
+ volatile bool mResumed;
+ volatile bool mDone;
+ volatile bool mReachedEOS;
+ pthread_t mThread;
+ int64_t mEstimatedSizeBytes;
+ int64_t mEstimatedDurationUs;
+
+ static void *ThreadWrapper(void *);
+ status_t threadFunc();
+ bool exceedsFileSizeLimit();
+ bool exceedsFileDurationLimit();
+ status_t reset();
+
+ AMRWriter(const AMRWriter &);
+ AMRWriter &operator=(const AMRWriter &);
+};
+
+} // namespace android
+
+#endif // AMR_WRITER_H_
diff --git a/media/libstagefright/include/AudioPlayer.h b/media/libstagefright/include/AudioPlayer.h
new file mode 100644
index 0000000..f7499b6
--- /dev/null
+++ b/media/libstagefright/include/AudioPlayer.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2009 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 AUDIO_PLAYER_H_
+
+#define AUDIO_PLAYER_H_
+
+#include <media/IMediaSource.h>
+#include <media/MediaPlayerInterface.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <utils/threads.h>
+
+namespace android {
+
+struct AudioPlaybackRate;
+class AudioTrack;
+struct AwesomePlayer;
+
+class AudioPlayer {
+public:
+ enum {
+ REACHED_EOS,
+ SEEK_COMPLETE
+ };
+
+ enum {
+ ALLOW_DEEP_BUFFERING = 0x01,
+ USE_OFFLOAD = 0x02,
+ HAS_VIDEO = 0x1000,
+ IS_STREAMING = 0x2000
+
+ };
+
+ AudioPlayer(const sp<MediaPlayerBase::AudioSink> &audioSink,
+ uint32_t flags = 0);
+
+ virtual ~AudioPlayer();
+
+ // Caller retains ownership of "source".
+ void setSource(const sp<IMediaSource> &source);
+
+ status_t start(bool sourceAlreadyStarted = false);
+
+ void pause(bool playPendingSamples = false);
+ status_t resume();
+
+ status_t seekTo(int64_t time_us);
+
+ bool isSeeking();
+ bool reachedEOS(status_t *finalStatus);
+
+ status_t setPlaybackRate(const AudioPlaybackRate &rate);
+ status_t getPlaybackRate(AudioPlaybackRate *rate /* nonnull */);
+
+private:
+ sp<IMediaSource> mSource;
+ sp<AudioTrack> mAudioTrack;
+
+ MediaBuffer *mInputBuffer;
+
+ int mSampleRate;
+ int64_t mLatencyUs;
+ size_t mFrameSize;
+
+ Mutex mLock;
+ int64_t mNumFramesPlayed;
+ int64_t mNumFramesPlayedSysTimeUs;
+
+ int64_t mPositionTimeMediaUs;
+ int64_t mPositionTimeRealUs;
+
+ bool mSeeking;
+ bool mReachedEOS;
+ status_t mFinalStatus;
+ int64_t mSeekTimeUs;
+
+ bool mStarted;
+
+ bool mIsFirstBuffer;
+ status_t mFirstBufferResult;
+ MediaBuffer *mFirstBuffer;
+
+ sp<MediaPlayerBase::AudioSink> mAudioSink;
+
+ bool mPlaying;
+ int64_t mStartPosUs;
+ const uint32_t mCreateFlags;
+
+ static void AudioCallback(int event, void *user, void *info);
+ void AudioCallback(int event, void *info);
+
+ static size_t AudioSinkCallback(
+ MediaPlayerBase::AudioSink *audioSink,
+ void *data, size_t size, void *me,
+ MediaPlayerBase::AudioSink::cb_event_t event);
+
+ size_t fillBuffer(void *data, size_t size);
+
+ void reset();
+
+ int64_t getOutputPlayPositionUs_l();
+
+ bool allowDeepBuffering() const { return (mCreateFlags & ALLOW_DEEP_BUFFERING) != 0; }
+ bool useOffload() const { return (mCreateFlags & USE_OFFLOAD) != 0; }
+
+ AudioPlayer(const AudioPlayer &);
+ AudioPlayer &operator=(const AudioPlayer &);
+};
+
+} // namespace android
+
+#endif // AUDIO_PLAYER_H_
diff --git a/media/libstagefright/include/AudioSource.h b/media/libstagefright/include/AudioSource.h
new file mode 100644
index 0000000..f20c2cd
--- /dev/null
+++ b/media/libstagefright/include/AudioSource.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2009 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 AUDIO_SOURCE_H_
+
+#define AUDIO_SOURCE_H_
+
+#include <media/AudioRecord.h>
+#include <media/AudioSystem.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <utils/List.h>
+
+#include <system/audio.h>
+
+namespace android {
+
+class AudioRecord;
+
+struct AudioSource : public MediaSource, public MediaBufferObserver {
+ // Note that the "channels" parameter _is_ the number of channels,
+ // _not_ a bitmask of audio_channels_t constants.
+ AudioSource(
+ audio_source_t inputSource,
+ const String16 &opPackageName,
+ uint32_t sampleRate,
+ uint32_t channels,
+ uint32_t outSampleRate = 0,
+ uid_t uid = -1,
+ pid_t pid = -1);
+
+ status_t initCheck() const;
+
+ virtual status_t start(MetaData *params = NULL);
+ virtual status_t stop() { return reset(); }
+ virtual sp<MetaData> getFormat();
+
+ // Returns the maximum amplitude since last call.
+ int16_t getMaxAmplitude();
+
+ virtual status_t read(
+ MediaBuffer **buffer, const ReadOptions *options = NULL);
+
+ status_t dataCallback(const AudioRecord::Buffer& buffer);
+ virtual void signalBufferReturned(MediaBuffer *buffer);
+
+protected:
+ virtual ~AudioSource();
+
+private:
+ enum {
+ kMaxBufferSize = 2048,
+
+ // After the initial mute, we raise the volume linearly
+ // over kAutoRampDurationUs.
+ kAutoRampDurationUs = 300000,
+
+ // This is the initial mute duration to suppress
+ // the video recording signal tone
+ kAutoRampStartUs = 0,
+ };
+
+ Mutex mLock;
+ Condition mFrameAvailableCondition;
+ Condition mFrameEncodingCompletionCondition;
+
+ sp<AudioRecord> mRecord;
+ status_t mInitCheck;
+ bool mStarted;
+ int32_t mSampleRate;
+ int32_t mOutSampleRate;
+
+ bool mTrackMaxAmplitude;
+ int64_t mStartTimeUs;
+ int16_t mMaxAmplitude;
+ int64_t mPrevSampleTimeUs;
+ int64_t mInitialReadTimeUs;
+ int64_t mNumFramesReceived;
+ int64_t mNumFramesSkipped;
+ int64_t mNumFramesLost;
+ int64_t mNumClientOwnedBuffers;
+
+ List<MediaBuffer * > mBuffersReceived;
+
+ void trackMaxAmplitude(int16_t *data, int nSamples);
+
+ // This is used to raise the volume from mute to the
+ // actual level linearly.
+ void rampVolume(
+ int32_t startFrame, int32_t rampDurationFrames,
+ uint8_t *data, size_t bytes);
+
+ void queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs);
+ void releaseQueuedFrames_l();
+ void waitOutstandingEncodingFrames_l();
+ status_t reset();
+
+ AudioSource(const AudioSource &);
+ AudioSource &operator=(const AudioSource &);
+};
+
+} // namespace android
+
+#endif // AUDIO_SOURCE_H_
diff --git a/media/libstagefright/include/BufferProducerWrapper.h b/media/libstagefright/include/BufferProducerWrapper.h
new file mode 100644
index 0000000..4caa2c6
--- /dev/null
+++ b/media/libstagefright/include/BufferProducerWrapper.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 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 BUFFER_PRODUCER_WRAPPER_H_
+
+#define BUFFER_PRODUCER_WRAPPER_H_
+
+#include <gui/IGraphicBufferProducer.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+// Can't use static_cast to cast a RefBase back to an IGraphicBufferProducer,
+// because IGBP's parent (IInterface) uses virtual inheritance. This class
+// wraps IGBP while we pass it through AMessage.
+
+struct BufferProducerWrapper : RefBase {
+ BufferProducerWrapper(
+ const sp<IGraphicBufferProducer>& bufferProducer) :
+ mBufferProducer(bufferProducer) { }
+
+ sp<IGraphicBufferProducer> getBufferProducer() const {
+ return mBufferProducer;
+ }
+
+private:
+ const sp<IGraphicBufferProducer> mBufferProducer;
+
+ DISALLOW_EVIL_CONSTRUCTORS(BufferProducerWrapper);
+};
+
+} // namespace android
+
+#endif // BUFFER_PRODUCER_WRAPPER_H_
diff --git a/media/libstagefright/include/CameraSource.h b/media/libstagefright/include/CameraSource.h
new file mode 100644
index 0000000..c604f2d
--- /dev/null
+++ b/media/libstagefright/include/CameraSource.h
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2009 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 CAMERA_SOURCE_H_
+
+#define CAMERA_SOURCE_H_
+
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaSource.h>
+#include <camera/android/hardware/ICamera.h>
+#include <camera/ICameraRecordingProxy.h>
+#include <camera/ICameraRecordingProxyListener.h>
+#include <camera/CameraParameters.h>
+#include <gui/BufferItemConsumer.h>
+#include <utils/List.h>
+#include <utils/RefBase.h>
+#include <utils/String16.h>
+#include <MetadataBufferType.h>
+
+namespace android {
+
+class IMemory;
+class Camera;
+class Surface;
+
+class CameraSource : public MediaSource, public MediaBufferObserver {
+public:
+ /**
+ * Factory method to create a new CameraSource using the current
+ * settings (such as video size, frame rate, color format, etc)
+ * from the default camera.
+ *
+ * @param clientName The package/process name of the client application.
+ * This is used for permissions checking.
+ * @return NULL on error.
+ */
+ static CameraSource *Create(const String16 &clientName);
+
+ /**
+ * Factory method to create a new CameraSource.
+ *
+ * @param camera the video input frame data source. If it is NULL,
+ * we will try to connect to the camera with the given
+ * cameraId.
+ *
+ * @param cameraId the id of the camera that the source will connect
+ * to if camera is NULL; otherwise ignored.
+ * @param clientName the package/process name of the camera-using
+ * application if camera is NULL; otherwise ignored. Used for
+ * permissions checking.
+ * @param clientUid the UID of the camera-using application if camera is
+ * NULL; otherwise ignored. Used for permissions checking.
+ * @param clientPid the PID of the camera-using application if camera is
+ * NULL; otherwise ignored. Used for permissions checking.
+ * @param videoSize the dimension (in pixels) of the video frame
+ * @param frameRate the target frames per second
+ * @param surface the preview surface for display where preview
+ * frames are sent to
+ * @param storeMetaDataInVideoBuffers true to request the camera
+ * source to store meta data in video buffers; false to
+ * request the camera source to store real YUV frame data
+ * in the video buffers. The camera source may not support
+ * storing meta data in video buffers, if so, a request
+ * to do that will NOT be honored. To find out whether
+ * meta data is actually being stored in video buffers
+ * during recording, call isMetaDataStoredInVideoBuffers().
+ *
+ * @return NULL on error.
+ */
+ static CameraSource *CreateFromCamera(const sp<hardware::ICamera> &camera,
+ const sp<ICameraRecordingProxy> &proxy,
+ int32_t cameraId,
+ const String16& clientName,
+ uid_t clientUid,
+ pid_t clientPid,
+ Size videoSize,
+ int32_t frameRate,
+ const sp<IGraphicBufferProducer>& surface,
+ bool storeMetaDataInVideoBuffers = true);
+
+ virtual ~CameraSource();
+
+ virtual status_t start(MetaData *params = NULL);
+ virtual status_t stop() { return reset(); }
+ virtual status_t read(
+ MediaBuffer **buffer, const ReadOptions *options = NULL);
+
+ /**
+ * Check whether a CameraSource object is properly initialized.
+ * Must call this method before stop().
+ * @return OK if initialization has successfully completed.
+ */
+ virtual status_t initCheck() const;
+
+ /**
+ * Returns the MetaData associated with the CameraSource,
+ * including:
+ * kKeyColorFormat: YUV color format of the video frames
+ * kKeyWidth, kKeyHeight: dimension (in pixels) of the video frames
+ * kKeySampleRate: frame rate in frames per second
+ * kKeyMIMEType: always fixed to be MEDIA_MIMETYPE_VIDEO_RAW
+ */
+ virtual sp<MetaData> getFormat();
+
+ /**
+ * Tell whether this camera source stores meta data or real YUV
+ * frame data in video buffers.
+ *
+ * @return a valid type if meta data is stored in the video
+ * buffers; kMetadataBufferTypeInvalid if real YUV data is stored in
+ * the video buffers.
+ */
+ MetadataBufferType metaDataStoredInVideoBuffers() const;
+
+ virtual void signalBufferReturned(MediaBuffer* buffer);
+
+protected:
+
+ /**
+ * The class for listening to BnCameraRecordingProxyListener. This is used to receive video
+ * buffers in VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV and VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA
+ * mode. When a frame is available, CameraSource::dataCallbackTimestamp() will be called.
+ */
+ class ProxyListener: public BnCameraRecordingProxyListener {
+ public:
+ ProxyListener(const sp<CameraSource>& source);
+ virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
+ const sp<IMemory> &data);
+ virtual void recordingFrameHandleCallbackTimestamp(int64_t timestampUs,
+ native_handle_t* handle);
+
+ private:
+ sp<CameraSource> mSource;
+ };
+
+ /**
+ * The class for listening to BufferQueue's onFrameAvailable. This is used to receive video
+ * buffers in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode. When a frame is available,
+ * CameraSource::processBufferQueueFrame() will be called.
+ */
+ class BufferQueueListener : public Thread, public BufferItemConsumer::FrameAvailableListener {
+ public:
+ BufferQueueListener(const sp<BufferItemConsumer> &consumer,
+ const sp<CameraSource> &cameraSource);
+ virtual void onFrameAvailable(const BufferItem& item);
+ virtual bool threadLoop();
+ private:
+ static const nsecs_t kFrameAvailableTimeout = 50000000; // 50ms
+
+ sp<BufferItemConsumer> mConsumer;
+ sp<CameraSource> mCameraSource;
+
+ Mutex mLock;
+ Condition mFrameAvailableSignal;
+ bool mFrameAvailable;
+ };
+
+ // isBinderAlive needs linkToDeath to work.
+ class DeathNotifier: public IBinder::DeathRecipient {
+ public:
+ DeathNotifier() {}
+ virtual void binderDied(const wp<IBinder>& who);
+ };
+
+ enum CameraFlags {
+ FLAGS_SET_CAMERA = 1L << 0,
+ FLAGS_HOT_CAMERA = 1L << 1,
+ };
+
+ int32_t mCameraFlags;
+ Size mVideoSize;
+ int32_t mNumInputBuffers;
+ int32_t mVideoFrameRate;
+ int32_t mColorFormat;
+ int32_t mEncoderFormat;
+ int32_t mEncoderDataSpace;
+ status_t mInitCheck;
+
+ sp<Camera> mCamera;
+ sp<ICameraRecordingProxy> mCameraRecordingProxy;
+ sp<DeathNotifier> mDeathNotifier;
+ sp<IGraphicBufferProducer> mSurface;
+ sp<MetaData> mMeta;
+
+ int64_t mStartTimeUs;
+ int32_t mNumFramesReceived;
+ int64_t mLastFrameTimestampUs;
+ bool mStarted;
+ int32_t mNumFramesEncoded;
+
+ // Time between capture of two frames.
+ int64_t mTimeBetweenFrameCaptureUs;
+
+ CameraSource(const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
+ int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid,
+ Size videoSize, int32_t frameRate,
+ const sp<IGraphicBufferProducer>& surface,
+ bool storeMetaDataInVideoBuffers);
+
+ virtual status_t startCameraRecording();
+ virtual void releaseRecordingFrame(const sp<IMemory>& frame);
+ virtual void releaseRecordingFrameHandle(native_handle_t* handle);
+
+ // Returns true if need to skip the current frame.
+ // Called from dataCallbackTimestamp.
+ virtual bool skipCurrentFrame(int64_t /*timestampUs*/) {return false;}
+
+ // Callback called when still camera raw data is available.
+ virtual void dataCallback(int32_t /*msgType*/, const sp<IMemory>& /*data*/) {}
+
+ virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
+ const sp<IMemory> &data);
+
+ virtual void recordingFrameHandleCallbackTimestamp(int64_t timestampUs,
+ native_handle_t* handle);
+
+ // Process a buffer item received in BufferQueueListener.
+ virtual void processBufferQueueFrame(BufferItem& buffer);
+
+ void releaseCamera();
+
+private:
+ friend struct CameraSourceListener;
+
+ Mutex mLock;
+ Condition mFrameAvailableCondition;
+ Condition mFrameCompleteCondition;
+ List<sp<IMemory> > mFramesReceived;
+ List<sp<IMemory> > mFramesBeingEncoded;
+ List<int64_t> mFrameTimes;
+
+ int64_t mFirstFrameTimeUs;
+ int32_t mNumFramesDropped;
+ int32_t mNumGlitches;
+ int64_t mGlitchDurationThresholdUs;
+ bool mCollectStats;
+
+ // The mode video buffers are received from camera. One of VIDEO_BUFFER_MODE_*.
+ int32_t mVideoBufferMode;
+
+ static const uint32_t kDefaultVideoBufferCount = 32;
+
+ /**
+ * The following variables are used in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode.
+ */
+ static const size_t kConsumerBufferCount = 8;
+ static const nsecs_t kMemoryBaseAvailableTimeoutNs = 200000000; // 200ms
+ // Consumer and producer of the buffer queue between this class and camera.
+ sp<BufferItemConsumer> mVideoBufferConsumer;
+ sp<IGraphicBufferProducer> mVideoBufferProducer;
+ // Memory used to send the buffers to encoder, where sp<IMemory> stores VideoNativeMetadata.
+ sp<IMemoryHeap> mMemoryHeapBase;
+ List<sp<IMemory>> mMemoryBases;
+ // The condition that will be signaled when there is an entry available in mMemoryBases.
+ Condition mMemoryBaseAvailableCond;
+ // A mapping from ANativeWindowBuffer sent to encoder to BufferItem received from camera.
+ // This is protected by mLock.
+ KeyedVector<ANativeWindowBuffer*, BufferItem> mReceivedBufferItemMap;
+ sp<BufferQueueListener> mBufferQueueListener;
+
+ void releaseQueuedFrames();
+ void releaseOneRecordingFrame(const sp<IMemory>& frame);
+ void createVideoBufferMemoryHeap(size_t size, uint32_t bufferCount);
+
+ status_t init(const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
+ int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid,
+ Size videoSize, int32_t frameRate, bool storeMetaDataInVideoBuffers);
+
+ status_t initWithCameraAccess(
+ const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
+ int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid,
+ Size videoSize, int32_t frameRate, bool storeMetaDataInVideoBuffers);
+
+ // Initialize the buffer queue used in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode.
+ status_t initBufferQueue(uint32_t width, uint32_t height, uint32_t format,
+ android_dataspace dataSpace, uint32_t bufferCount);
+
+ status_t isCameraAvailable(const sp<hardware::ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy,
+ int32_t cameraId,
+ const String16& clientName,
+ uid_t clientUid,
+ pid_t clientPid);
+
+ status_t isCameraColorFormatSupported(const CameraParameters& params);
+ status_t configureCamera(CameraParameters* params,
+ int32_t width, int32_t height,
+ int32_t frameRate);
+
+ status_t checkVideoSize(const CameraParameters& params,
+ int32_t width, int32_t height);
+
+ status_t checkFrameRate(const CameraParameters& params,
+ int32_t frameRate);
+
+ // Check if this frame should be skipped based on the frame's timestamp in microsecond.
+ // mLock must be locked before calling this function.
+ bool shouldSkipFrameLocked(int64_t timestampUs);
+
+ void stopCameraRecording();
+ status_t reset();
+
+ CameraSource(const CameraSource &);
+ CameraSource &operator=(const CameraSource &);
+};
+
+} // namespace android
+
+#endif // CAMERA_SOURCE_H_
diff --git a/media/libstagefright/include/CameraSourceTimeLapse.h b/media/libstagefright/include/CameraSourceTimeLapse.h
new file mode 100644
index 0000000..871c1d9
--- /dev/null
+++ b/media/libstagefright/include/CameraSourceTimeLapse.h
@@ -0,0 +1,188 @@
+/*
+ * 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 CAMERA_SOURCE_TIME_LAPSE_H_
+
+#define CAMERA_SOURCE_TIME_LAPSE_H_
+
+#include <pthread.h>
+
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <utils/String16.h>
+
+namespace android {
+
+namespace hardware {
+class ICamera;
+}
+
+class IMemory;
+class Camera;
+
+class CameraSourceTimeLapse : public CameraSource {
+public:
+ static CameraSourceTimeLapse *CreateFromCamera(
+ const sp<hardware::ICamera> &camera,
+ const sp<ICameraRecordingProxy> &proxy,
+ int32_t cameraId,
+ const String16& clientName,
+ uid_t clientUid,
+ pid_t clientPid,
+ Size videoSize,
+ int32_t videoFrameRate,
+ const sp<IGraphicBufferProducer>& surface,
+ int64_t timeBetweenTimeLapseFrameCaptureUs,
+ bool storeMetaDataInVideoBuffers = true);
+
+ virtual ~CameraSourceTimeLapse();
+
+ // If the frame capture interval is large, read will block for a long time.
+ // Due to the way the mediaRecorder framework works, a stop() call from
+ // mediaRecorder waits until the read returns, causing a long wait for
+ // stop() to return. To avoid this, we can make read() return a copy of the
+ // last read frame with the same time stamp frequently. This keeps the
+ // read() call from blocking too long. Calling this function quickly
+ // captures another frame, keeps its copy, and enables this mode of read()
+ // returning quickly.
+ void startQuickReadReturns();
+
+private:
+ // size of the encoded video.
+ int32_t mVideoWidth;
+ int32_t mVideoHeight;
+
+ // Time between two frames in final video (1/frameRate)
+ int64_t mTimeBetweenTimeLapseVideoFramesUs;
+
+ // Real timestamp of the last encoded time lapse frame
+ int64_t mLastTimeLapseFrameRealTimestampUs;
+
+ // Variable set in dataCallbackTimestamp() to help skipCurrentFrame()
+ // to know if current frame needs to be skipped.
+ bool mSkipCurrentFrame;
+
+ // Lock for accessing mCameraIdle
+ Mutex mCameraIdleLock;
+
+ // Condition variable to wait on if camera is is not yet idle. Once the
+ // camera gets idle, this variable will be signalled.
+ Condition mCameraIdleCondition;
+
+ // True if camera is in preview mode and ready for takePicture().
+ // False after a call to takePicture() but before the final compressed
+ // data callback has been called and preview has been restarted.
+ volatile bool mCameraIdle;
+
+ // True if stop() is waiting for camera to get idle, i.e. for the last
+ // takePicture() to complete. This is needed so that dataCallbackTimestamp()
+ // can return immediately.
+ volatile bool mStopWaitingForIdleCamera;
+
+ // Lock for accessing quick stop variables.
+ Mutex mQuickStopLock;
+
+ // mQuickStop is set to true if we use quick read() returns, otherwise it is set
+ // to false. Once in this mode read() return a copy of the last read frame
+ // with the same time stamp. See startQuickReadReturns().
+ volatile bool mQuickStop;
+
+ // Forces the next frame passed to dataCallbackTimestamp() to be read
+ // as a time lapse frame. Used by startQuickReadReturns() so that the next
+ // frame wakes up any blocking read.
+ volatile bool mForceRead;
+
+ // Stores a copy of the MediaBuffer read in the last read() call after
+ // mQuickStop was true.
+ MediaBuffer* mLastReadBufferCopy;
+
+ // Status code for last read.
+ status_t mLastReadStatus;
+
+ CameraSourceTimeLapse(
+ const sp<hardware::ICamera> &camera,
+ const sp<ICameraRecordingProxy> &proxy,
+ int32_t cameraId,
+ const String16& clientName,
+ uid_t clientUid,
+ pid_t clientPid,
+ Size videoSize,
+ int32_t videoFrameRate,
+ const sp<IGraphicBufferProducer>& surface,
+ int64_t timeBetweenTimeLapseFrameCaptureUs,
+ bool storeMetaDataInVideoBuffers = true);
+
+ // Wrapper over CameraSource::signalBufferReturned() to implement quick stop.
+ // It only handles the case when mLastReadBufferCopy is signalled. Otherwise
+ // it calls the base class' function.
+ virtual void signalBufferReturned(MediaBuffer* buffer);
+
+ // Wrapper over CameraSource::read() to implement quick stop.
+ virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL);
+
+ // mSkipCurrentFrame is set to true in dataCallbackTimestamp() if the current
+ // frame needs to be skipped and this function just returns the value of mSkipCurrentFrame.
+ virtual bool skipCurrentFrame(int64_t timestampUs);
+
+ // In the video camera case calls skipFrameAndModifyTimeStamp() to modify
+ // timestamp and set mSkipCurrentFrame.
+ // Then it calls the base CameraSource::dataCallbackTimestamp()
+ // This will be called in VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV and
+ // VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA mode.
+ virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
+ const sp<IMemory> &data);
+
+ // In the video camera case calls skipFrameAndModifyTimeStamp() to modify
+ // timestamp and set mSkipCurrentFrame.
+ // Then it calls the base CameraSource::recordingFrameHandleCallbackTimestamp()
+ // This will be called in VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA mode when
+ // the metadata is VideoNativeHandleMetadata.
+ virtual void recordingFrameHandleCallbackTimestamp(int64_t timestampUs,
+ native_handle_t* handle);
+
+ // Process a buffer item received in CameraSource::BufferQueueListener.
+ // This will be called in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode.
+ virtual void processBufferQueueFrame(BufferItem& buffer);
+
+ // Convenience function to fill mLastReadBufferCopy from the just read
+ // buffer.
+ void fillLastReadBufferCopy(MediaBuffer& sourceBuffer);
+
+ // If the passed in size (width x height) is a supported video/preview size,
+ // the function sets the camera's video/preview size to it and returns true.
+ // Otherwise returns false.
+ bool trySettingVideoSize(int32_t width, int32_t height);
+
+ // When video camera is used for time lapse capture, returns true
+ // until enough time has passed for the next time lapse frame. When
+ // the frame needs to be encoded, it returns false and also modifies
+ // the time stamp to be one frame time ahead of the last encoded
+ // frame's time stamp.
+ bool skipFrameAndModifyTimeStamp(int64_t *timestampUs);
+
+ // Wrapper to enter threadTimeLapseEntry()
+ static void *ThreadTimeLapseWrapper(void *me);
+
+ // Creates a copy of source_data into a new memory of final type MemoryBase.
+ sp<IMemory> createIMemoryCopy(const sp<IMemory> &source_data);
+
+ CameraSourceTimeLapse(const CameraSourceTimeLapse &);
+ CameraSourceTimeLapse &operator=(const CameraSourceTimeLapse &);
+};
+
+} // namespace android
+
+#endif // CAMERA_SOURCE_TIME_LAPSE_H_
diff --git a/media/libstagefright/include/CodecBase.h b/media/libstagefright/include/CodecBase.h
new file mode 100644
index 0000000..cfbaea4
--- /dev/null
+++ b/media/libstagefright/include/CodecBase.h
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC_BASE_H_
+
+#define CODEC_BASE_H_
+
+#include <memory>
+
+#include <stdint.h>
+
+#define STRINGIFY_ENUMS
+
+#include <media/ICrypto.h>
+#include <media/IOMX.h>
+#include <media/MediaCodecInfo.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/foundation/ColorUtils.h>
+#include <media/hardware/HardwareAPI.h>
+
+#include <utils/NativeHandle.h>
+
+#include <system/graphics.h>
+
+namespace android {
+
+class BufferChannelBase;
+class BufferProducerWrapper;
+class MediaCodecBuffer;
+struct PersistentSurface;
+struct RenderedFrameInfo;
+class Surface;
+
+struct CodecBase : public AHandler, /* static */ ColorUtils {
+ /**
+ * This interface defines events firing from CodecBase back to MediaCodec.
+ * All methods must not block.
+ */
+ class CodecCallback {
+ public:
+ virtual ~CodecCallback() = default;
+
+ /**
+ * Notify MediaCodec for seeing an output EOS.
+ *
+ * @param err the underlying cause of the EOS. If the value is neither
+ * OK nor ERROR_END_OF_STREAM, the EOS is declared
+ * prematurely for that error.
+ */
+ virtual void onEos(status_t err) = 0;
+ /**
+ * Notify MediaCodec that start operation is complete.
+ */
+ virtual void onStartCompleted() = 0;
+ /**
+ * Notify MediaCodec that stop operation is complete.
+ */
+ virtual void onStopCompleted() = 0;
+ /**
+ * Notify MediaCodec that release operation is complete.
+ */
+ virtual void onReleaseCompleted() = 0;
+ /**
+ * Notify MediaCodec that flush operation is complete.
+ */
+ virtual void onFlushCompleted() = 0;
+ /**
+ * Notify MediaCodec that an error is occurred.
+ *
+ * @param err an error code for the occurred error.
+ * @param actionCode an action code for severity of the error.
+ */
+ virtual void onError(status_t err, enum ActionCode actionCode) = 0;
+ /**
+ * Notify MediaCodec that the underlying component is allocated.
+ *
+ * @param componentName the unique name of the component specified in
+ * MediaCodecList.
+ */
+ virtual void onComponentAllocated(const char *componentName) = 0;
+ /**
+ * Notify MediaCodec that the underlying component is configured.
+ *
+ * @param inputFormat an input format at configure time.
+ * @param outputFormat an output format at configure time.
+ */
+ virtual void onComponentConfigured(
+ const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) = 0;
+ /**
+ * Notify MediaCodec that the input surface is created.
+ *
+ * @param inputFormat an input format at surface creation. Formats
+ * could change from the previous state as a result
+ * of creating a surface.
+ * @param outputFormat an output format at surface creation.
+ * @param inputSurface the created surface.
+ */
+ virtual void onInputSurfaceCreated(
+ const sp<AMessage> &inputFormat,
+ const sp<AMessage> &outputFormat,
+ const sp<BufferProducerWrapper> &inputSurface) = 0;
+ /**
+ * Notify MediaCodec that the input surface creation is failed.
+ *
+ * @param err an error code of the cause.
+ */
+ virtual void onInputSurfaceCreationFailed(status_t err) = 0;
+ /**
+ * Notify MediaCodec that the component accepted the provided input
+ * surface.
+ *
+ * @param inputFormat an input format at surface assignment. Formats
+ * could change from the previous state as a result
+ * of assigning a surface.
+ * @param outputFormat an output format at surface assignment.
+ */
+ virtual void onInputSurfaceAccepted(
+ const sp<AMessage> &inputFormat,
+ const sp<AMessage> &outputFormat) = 0;
+ /**
+ * Notify MediaCodec that the component declined the provided input
+ * surface.
+ *
+ * @param err an error code of the cause.
+ */
+ virtual void onInputSurfaceDeclined(status_t err) = 0;
+ /**
+ * Noitfy MediaCodec that the requested input EOS is sent to the input
+ * surface.
+ *
+ * @param err an error code returned from the surface. If there is no
+ * input surface, the value is INVALID_OPERATION.
+ */
+ virtual void onSignaledInputEOS(status_t err) = 0;
+ /**
+ * Notify MediaCodec that output frames are rendered with information on
+ * those frames.
+ *
+ * @param done a list of rendered frames.
+ */
+ virtual void onOutputFramesRendered(const std::list<RenderedFrameInfo> &done) = 0;
+ /**
+ * Notify MediaCodec that output buffers are changed.
+ */
+ virtual void onOutputBuffersChanged() = 0;
+ };
+
+ /**
+ * This interface defines events firing from BufferChannelBase back to MediaCodec.
+ * All methods must not block.
+ */
+ class BufferCallback {
+ public:
+ virtual ~BufferCallback() = default;
+
+ /**
+ * Notify MediaCodec that an input buffer is available with given index.
+ * When BufferChannelBase::getInputBufferArray() is not called,
+ * BufferChannelBase may report different buffers with the same index if
+ * MediaCodec already queued/discarded the buffer. After calling
+ * BufferChannelBase::getInputBufferArray(), the buffer and index match the
+ * returned array.
+ */
+ virtual void onInputBufferAvailable(
+ size_t index, const sp<MediaCodecBuffer> &buffer) = 0;
+ /**
+ * Notify MediaCodec that an output buffer is available with given index.
+ * When BufferChannelBase::getOutputBufferArray() is not called,
+ * BufferChannelBase may report different buffers with the same index if
+ * MediaCodec already queued/discarded the buffer. After calling
+ * BufferChannelBase::getOutputBufferArray(), the buffer and index match the
+ * returned array.
+ */
+ virtual void onOutputBufferAvailable(
+ size_t index, const sp<MediaCodecBuffer> &buffer) = 0;
+ };
+ enum {
+ kMaxCodecBufferSize = 8192 * 4096 * 4, // 8K RGBA
+ };
+
+ inline void setCallback(std::unique_ptr<CodecCallback> &&callback) {
+ mCallback = std::move(callback);
+ }
+ virtual std::shared_ptr<BufferChannelBase> getBufferChannel() = 0;
+
+ virtual void initiateAllocateComponent(const sp<AMessage> &msg) = 0;
+ virtual void initiateConfigureComponent(const sp<AMessage> &msg) = 0;
+ virtual void initiateCreateInputSurface() = 0;
+ virtual void initiateSetInputSurface(
+ const sp<PersistentSurface> &surface) = 0;
+ virtual void initiateStart() = 0;
+ virtual void initiateShutdown(bool keepComponentAllocated = false) = 0;
+
+ // require an explicit message handler
+ virtual void onMessageReceived(const sp<AMessage> &msg) = 0;
+
+ virtual status_t queryCapabilities(
+ const AString& /*name*/, const AString& /*mime*/, bool /*isEncoder*/,
+ sp<MediaCodecInfo::Capabilities>* /*caps*/ /* nonnull */) { return INVALID_OPERATION; }
+
+ virtual status_t setSurface(const sp<Surface>& /*surface*/) { return INVALID_OPERATION; }
+
+ virtual void signalFlush() = 0;
+ virtual void signalResume() = 0;
+
+ virtual void signalRequestIDRFrame() = 0;
+ virtual void signalSetParameters(const sp<AMessage> &msg) = 0;
+ virtual void signalEndOfInputStream() = 0;
+
+ /*
+ * Codec-related defines
+ */
+
+protected:
+ CodecBase() = default;
+ virtual ~CodecBase() = default;
+
+ std::unique_ptr<CodecCallback> mCallback;
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(CodecBase);
+};
+
+/**
+ * A channel between MediaCodec and CodecBase object which manages buffer
+ * passing. Only MediaCodec is expected to call these methods, and
+ * underlying CodecBase implementation should define its own interface
+ * separately for itself.
+ *
+ * Concurrency assumptions:
+ *
+ * 1) Clients may access the object at multiple threads concurrently.
+ * 2) All methods do not call underlying CodecBase object while holding a lock.
+ * 3) Code inside critical section executes within 1ms.
+ */
+class BufferChannelBase {
+public:
+ virtual ~BufferChannelBase() = default;
+
+ inline void setCallback(std::unique_ptr<CodecBase::BufferCallback> &&callback) {
+ mCallback = std::move(callback);
+ }
+
+ inline void setCrypto(const sp<ICrypto> &crypto) {
+ mCrypto = crypto;
+ }
+
+ /**
+ * Queue an input buffer into the buffer channel.
+ *
+ * @return OK if successful;
+ * -ENOENT if the buffer is not known (TODO: this should be
+ * handled gracefully in the future, here and below).
+ */
+ virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) = 0;
+ /**
+ * Queue a secure input buffer into the buffer channel.
+ *
+ * @return OK if successful;
+ * -ENOENT if the buffer is not known;
+ * -ENOSYS if mCrypto is not set so that decryption is not
+ * possible;
+ * other errors if decryption failed.
+ */
+ virtual status_t queueSecureInputBuffer(
+ const sp<MediaCodecBuffer> &buffer,
+ bool secure,
+ const uint8_t *key,
+ const uint8_t *iv,
+ CryptoPlugin::Mode mode,
+ CryptoPlugin::Pattern pattern,
+ const CryptoPlugin::SubSample *subSamples,
+ size_t numSubSamples,
+ AString *errorDetailMsg) = 0;
+ /**
+ * Request buffer rendering at specified time.
+ *
+ * @param timestampNs nanosecond timestamp for rendering time.
+ * @return OK if successful;
+ * -ENOENT if the buffer is not known.
+ */
+ virtual status_t renderOutputBuffer(
+ const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) = 0;
+ /**
+ * Discard a buffer to the underlying CodecBase object.
+ *
+ * TODO: remove once this operation can be handled by just clearing the
+ * reference.
+ *
+ * @return OK if successful;
+ * -ENOENT if the buffer is not known.
+ */
+ virtual status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) = 0;
+ /**
+ * Clear and fill array with input buffers.
+ */
+ virtual void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0;
+ /**
+ * Clear and fill array with output buffers.
+ */
+ virtual void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0;
+
+protected:
+ std::unique_ptr<CodecBase::BufferCallback> mCallback;
+ sp<ICrypto> mCrypto;
+};
+
+} // namespace android
+
+#endif // CODEC_BASE_H_
+
diff --git a/media/libstagefright/include/ColorConverter.h b/media/libstagefright/include/ColorConverter.h
new file mode 100644
index 0000000..270c809
--- /dev/null
+++ b/media/libstagefright/include/ColorConverter.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2009 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 COLOR_CONVERTER_H_
+
+#define COLOR_CONVERTER_H_
+
+#include <sys/types.h>
+
+#include <stdint.h>
+#include <utils/Errors.h>
+
+#include <OMX_Video.h>
+
+namespace android {
+
+struct ColorConverter {
+ ColorConverter(OMX_COLOR_FORMATTYPE from, OMX_COLOR_FORMATTYPE to);
+ ~ColorConverter();
+
+ bool isValid() const;
+
+ status_t convert(
+ const void *srcBits,
+ size_t srcWidth, size_t srcHeight,
+ size_t srcCropLeft, size_t srcCropTop,
+ size_t srcCropRight, size_t srcCropBottom,
+ void *dstBits,
+ size_t dstWidth, size_t dstHeight,
+ size_t dstCropLeft, size_t dstCropTop,
+ size_t dstCropRight, size_t dstCropBottom);
+
+private:
+ struct BitmapParams {
+ BitmapParams(
+ void *bits,
+ size_t width, size_t height,
+ size_t cropLeft, size_t cropTop,
+ size_t cropRight, size_t cropBottom);
+
+ size_t cropWidth() const;
+ size_t cropHeight() const;
+
+ void *mBits;
+ size_t mWidth, mHeight;
+ size_t mCropLeft, mCropTop, mCropRight, mCropBottom;
+ };
+
+ OMX_COLOR_FORMATTYPE mSrcFormat, mDstFormat;
+ uint8_t *mClip;
+
+ uint8_t *initClip();
+
+ status_t convertCbYCrY(
+ const BitmapParams &src, const BitmapParams &dst);
+
+ status_t convertYUV420Planar(
+ const BitmapParams &src, const BitmapParams &dst);
+
+ status_t convertYUV420PlanarUseLibYUV(
+ const BitmapParams &src, const BitmapParams &dst);
+
+ status_t convertQCOMYUV420SemiPlanar(
+ const BitmapParams &src, const BitmapParams &dst);
+
+ status_t convertYUV420SemiPlanar(
+ const BitmapParams &src, const BitmapParams &dst);
+
+ status_t convertTIYUV420PackedSemiPlanar(
+ const BitmapParams &src, const BitmapParams &dst);
+
+ ColorConverter(const ColorConverter &);
+ ColorConverter &operator=(const ColorConverter &);
+};
+
+} // namespace android
+
+#endif // COLOR_CONVERTER_H_
diff --git a/media/libstagefright/include/DataSource.h b/media/libstagefright/include/DataSource.h
new file mode 100644
index 0000000..e7135a2
--- /dev/null
+++ b/media/libstagefright/include/DataSource.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2009 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 DATA_SOURCE_H_
+
+#define DATA_SOURCE_H_
+
+#include <sys/types.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaErrors.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/List.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <drm/DrmManagerClient.h>
+
+namespace android {
+
+struct AMessage;
+struct AString;
+class IDataSource;
+struct IMediaHTTPService;
+class String8;
+struct HTTPBase;
+
+class DataSource : public RefBase {
+public:
+ enum Flags {
+ kWantsPrefetching = 1,
+ kStreamedFromLocalHost = 2,
+ kIsCachingDataSource = 4,
+ kIsHTTPBasedSource = 8,
+ kIsLocalFileSource = 16,
+ };
+
+ static sp<DataSource> CreateFromURI(
+ const sp<IMediaHTTPService> &httpService,
+ const char *uri,
+ const KeyedVector<String8, String8> *headers = NULL,
+ String8 *contentType = NULL,
+ HTTPBase *httpSource = NULL);
+
+ static sp<DataSource> CreateMediaHTTP(const sp<IMediaHTTPService> &httpService);
+ static sp<DataSource> CreateFromIDataSource(const sp<IDataSource> &source);
+
+ DataSource() {}
+
+ virtual status_t initCheck() const = 0;
+
+ // Returns the number of bytes read, or -1 on failure. It's not an error if
+ // this returns zero; it just means the given offset is equal to, or
+ // beyond, the end of the source.
+ virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;
+
+ // Convenience methods:
+ bool getUInt16(off64_t offset, uint16_t *x);
+ bool getUInt24(off64_t offset, uint32_t *x); // 3 byte int, returned as a 32-bit int
+ bool getUInt32(off64_t offset, uint32_t *x);
+ bool getUInt64(off64_t offset, uint64_t *x);
+
+ // Reads in "count" entries of type T into vector *x.
+ // Returns true if "count" entries can be read.
+ // If fewer than "count" entries can be read, return false. In this case,
+ // the output vector *x will still have those entries that were read. Call
+ // x->size() to obtain the number of entries read.
+ // The optional parameter chunkSize specifies how many entries should be
+ // read from the data source at one time into a temporary buffer. Increasing
+ // chunkSize can improve the performance at the cost of extra memory usage.
+ // The default value for chunkSize is set to read at least 4k bytes at a
+ // time, depending on sizeof(T).
+ template <typename T>
+ bool getVector(off64_t offset, Vector<T>* x, size_t count,
+ size_t chunkSize = (4095 / sizeof(T)) + 1);
+
+ // May return ERROR_UNSUPPORTED.
+ virtual status_t getSize(off64_t *size);
+
+ virtual uint32_t flags() {
+ return 0;
+ }
+
+ virtual String8 toString() {
+ return String8("<unspecified>");
+ }
+
+ virtual status_t reconnectAtOffset(off64_t /*offset*/) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ // for DRM
+ virtual sp<DecryptHandle> DrmInitialization(const char * /*mime*/ = NULL) {
+ return NULL;
+ }
+ virtual void getDrmInfo(sp<DecryptHandle> &/*handle*/, DrmManagerClient ** /*client*/) {};
+
+ virtual String8 getUri() {
+ return String8();
+ }
+
+ virtual String8 getMIMEType() const;
+
+ virtual void close() {};
+
+protected:
+ virtual ~DataSource() {}
+
+private:
+ DataSource(const DataSource &);
+ DataSource &operator=(const DataSource &);
+};
+
+template <typename T>
+bool DataSource::getVector(off64_t offset, Vector<T>* x, size_t count,
+ size_t chunkSize)
+{
+ x->clear();
+ if (chunkSize == 0) {
+ return false;
+ }
+ if (count == 0) {
+ return true;
+ }
+
+ T tmp[chunkSize];
+ ssize_t numBytesRead;
+ size_t numBytesPerChunk = chunkSize * sizeof(T);
+ size_t i;
+
+ for (i = 0; i + chunkSize < count; i += chunkSize) {
+ // This loops is executed when more than chunkSize records need to be
+ // read.
+ numBytesRead = this->readAt(offset, (void*)&tmp, numBytesPerChunk);
+ if (numBytesRead == -1) { // If readAt() returns -1, there is an error.
+ return false;
+ }
+ if (numBytesRead < numBytesPerChunk) {
+ // This case is triggered when the stream ends before the whole
+ // chunk is read.
+ x->appendArray(tmp, (size_t)numBytesRead / sizeof(T));
+ return false;
+ }
+ x->appendArray(tmp, chunkSize);
+ offset += numBytesPerChunk;
+ }
+
+ // There are (count - i) more records to read.
+ // Right now, (count - i) <= chunkSize.
+ // We do the same thing as above, but with chunkSize replaced by count - i.
+ numBytesRead = this->readAt(offset, (void*)&tmp, (count - i) * sizeof(T));
+ if (numBytesRead == -1) {
+ return false;
+ }
+ x->appendArray(tmp, (size_t)numBytesRead / sizeof(T));
+ return x->size() == count;
+}
+
+} // namespace android
+
+#endif // DATA_SOURCE_H_
diff --git a/media/libstagefright/include/DataURISource.h b/media/libstagefright/include/DataURISource.h
new file mode 100644
index 0000000..693562e
--- /dev/null
+++ b/media/libstagefright/include/DataURISource.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DATA_URI_SOURCE_H_
+
+#define DATA_URI_SOURCE_H_
+
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+struct ABuffer;
+
+struct DataURISource : public DataSource {
+ static sp<DataURISource> Create(const char *uri);
+
+ virtual status_t initCheck() const;
+ virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+ virtual status_t getSize(off64_t *size);
+
+protected:
+ virtual ~DataURISource();
+
+private:
+ sp<ABuffer> mBuffer;
+
+ DataURISource(const sp<ABuffer> &buffer);
+
+ DISALLOW_EVIL_CONSTRUCTORS(DataURISource);
+};
+
+} // namespace android
+
+#endif // DATA_URI_SOURCE_H_
+
diff --git a/media/libstagefright/include/FileSource.h b/media/libstagefright/include/FileSource.h
new file mode 100644
index 0000000..9f3bb5e
--- /dev/null
+++ b/media/libstagefright/include/FileSource.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2009 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 FILE_SOURCE_H_
+
+#define FILE_SOURCE_H_
+
+#include <stdio.h>
+
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaErrors.h>
+#include <utils/threads.h>
+#include <drm/DrmManagerClient.h>
+
+namespace android {
+
+class FileSource : public DataSource {
+public:
+ FileSource(const char *filename);
+ // FileSource takes ownership and will close the fd
+ FileSource(int fd, int64_t offset, int64_t length);
+
+ virtual status_t initCheck() const;
+
+ virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+
+ virtual status_t getSize(off64_t *size);
+
+ virtual uint32_t flags() {
+ return kIsLocalFileSource;
+ }
+
+ virtual sp<DecryptHandle> DrmInitialization(const char *mime);
+
+ virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
+
+ virtual String8 toString() {
+ return mName;
+ }
+
+protected:
+ virtual ~FileSource();
+
+private:
+ int mFd;
+ int64_t mOffset;
+ int64_t mLength;
+ Mutex mLock;
+ String8 mName;
+
+ /*for DRM*/
+ sp<DecryptHandle> mDecryptHandle;
+ DrmManagerClient *mDrmManagerClient;
+ int64_t mDrmBufOffset;
+ ssize_t mDrmBufSize;
+ unsigned char *mDrmBuf;
+
+ ssize_t readAtDRM(off64_t offset, void *data, size_t size);
+
+ FileSource(const FileSource &);
+ FileSource &operator=(const FileSource &);
+};
+
+} // namespace android
+
+#endif // FILE_SOURCE_H_
+
diff --git a/media/libstagefright/include/FrameRenderTracker.h b/media/libstagefright/include/FrameRenderTracker.h
new file mode 100644
index 0000000..6cbf85d
--- /dev/null
+++ b/media/libstagefright/include/FrameRenderTracker.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2015 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 FRAME_RENDER_TRACKER_H_
+
+#define FRAME_RENDER_TRACKER_H_
+
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+#include <system/window.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AString.h>
+
+#include <list>
+
+namespace android {
+
+class Fence;
+class GraphicBuffer;
+
+// Tracks the render information about a frame. Frames go through several states while
+// the render information is tracked:
+//
+// 1. queued frame: mMediaTime and mGraphicBuffer are set for the frame. mFence is the
+// queue fence (read fence). mIndex is negative, and mRenderTimeNs is invalid.
+// Key characteristics: mFence is not NULL and mIndex is negative.
+//
+// 2. dequeued frame: mFence is updated with the dequeue fence (write fence). mIndex is set.
+// Key characteristics: mFence is not NULL and mIndex is non-negative. mRenderTime is still
+// invalid.
+//
+// 3. rendered frame or frame: mFence is cleared, mRenderTimeNs is set.
+// Key characteristics: mFence is NULL.
+//
+struct RenderedFrameInfo {
+ // set by client during onFrameQueued or onFrameRendered
+ int64_t getMediaTimeUs() const { return mMediaTimeUs; }
+
+ // -1 if frame is not yet rendered
+ nsecs_t getRenderTimeNs() const { return mRenderTimeNs; }
+
+ // set by client during updateRenderInfoForDequeuedBuffer; -1 otherwise
+ ssize_t getIndex() const { return mIndex; }
+
+ // creates information for a queued frame
+ RenderedFrameInfo(int64_t mediaTimeUs, const sp<GraphicBuffer> &graphicBuffer,
+ const sp<Fence> &fence)
+ : mMediaTimeUs(mediaTimeUs),
+ mRenderTimeNs(-1),
+ mIndex(-1),
+ mGraphicBuffer(graphicBuffer),
+ mFence(fence) {
+ }
+
+ // creates information for a frame rendered on a tunneled surface
+ RenderedFrameInfo(int64_t mediaTimeUs, nsecs_t renderTimeNs)
+ : mMediaTimeUs(mediaTimeUs),
+ mRenderTimeNs(renderTimeNs),
+ mIndex(-1),
+ mGraphicBuffer(NULL),
+ mFence(NULL) {
+ }
+
+private:
+ int64_t mMediaTimeUs;
+ nsecs_t mRenderTimeNs;
+ ssize_t mIndex; // to be used by client
+ sp<GraphicBuffer> mGraphicBuffer;
+ sp<Fence> mFence;
+
+ friend struct FrameRenderTracker;
+};
+
+struct FrameRenderTracker {
+ typedef RenderedFrameInfo Info;
+
+ FrameRenderTracker();
+
+ void setComponentName(const AString &componentName);
+
+ // clears all tracked frames, and resets last render time
+ void clear(nsecs_t lastRenderTimeNs);
+
+ // called when |graphicBuffer| corresponding to |mediaTimeUs| is
+ // queued to the output surface using |fence|.
+ void onFrameQueued(
+ int64_t mediaTimeUs, const sp<GraphicBuffer> &graphicBuffer, const sp<Fence> &fence);
+
+ // Called when we have dequeued a buffer |buf| from the native window to track render info.
+ // |fenceFd| is the dequeue fence, and |index| is a positive buffer ID to be usable by the
+ // client to track this render info among the dequeued buffers.
+ // Returns pointer to the tracked info, or NULL if buffer is not tracked or if |index|
+ // is negative.
+ Info *updateInfoForDequeuedBuffer(ANativeWindowBuffer *buf, int fenceFd, int index);
+
+ // called when tunneled codec signals frame rendered event
+ // returns BAD_VALUE if systemNano is not monotonic. Otherwise, returns OK.
+ status_t onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
+
+ // Checks to see if any frames have rendered up until |until|. If |until| is NULL or not a
+ // tracked info, this method searches the entire render queue.
+ // Returns list of rendered frames up-until the frame pointed to by |until| or the first
+ // unrendered frame, as well as any dropped frames (those with invalid fence) up-until |until|.
+ // These frames are removed from the render queue.
+ // If |dropIncomplete| is true, unrendered frames up-until |until| will also be dropped from the
+ // queue, allowing all rendered framed up till then to be notified of.
+ // (This will effectively clear the render queue up-until (and including) |until|.)
+ std::list<Info> checkFencesAndGetRenderedFrames(const Info *until, bool dropIncomplete);
+
+ // Stop tracking a queued frame (e.g. if the frame has been discarded). If |info| is NULL or is
+ // not tracked, this method is a no-op. If |index| is specified, all indices larger that |index|
+ // are decremented. This is useful if the untracked frame is deleted from the frame vector.
+ void untrackFrame(const Info *info, ssize_t index = SSIZE_MAX);
+
+ void dumpRenderQueue() const;
+
+ virtual ~FrameRenderTracker();
+
+private:
+
+ // Render information for buffers. Regular surface buffers are queued in the order of
+ // rendering. Tunneled buffers are queued in the order of receipt.
+ std::list<Info> mRenderQueue;
+ nsecs_t mLastRenderTimeNs;
+ AString mComponentName;
+
+ DISALLOW_EVIL_CONSTRUCTORS(FrameRenderTracker);
+};
+
+} // namespace android
+
+#endif // FRAME_RENDER_TRACKER_H_
diff --git a/media/libstagefright/include/JPEGSource.h b/media/libstagefright/include/JPEGSource.h
new file mode 100644
index 0000000..1b7e91b
--- /dev/null
+++ b/media/libstagefright/include/JPEGSource.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 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 JPEG_SOURCE_H_
+
+#define JPEG_SOURCE_H_
+
+#include <media/stagefright/MediaSource.h>
+
+namespace android {
+
+class DataSource;
+class MediaBufferGroup;
+
+struct JPEGSource : public MediaSource {
+ JPEGSource(const sp<DataSource> &source);
+
+ virtual status_t start(MetaData *params = NULL);
+ virtual status_t stop();
+ virtual sp<MetaData> getFormat();
+
+ virtual status_t read(
+ MediaBuffer **buffer, const ReadOptions *options = NULL);
+
+protected:
+ virtual ~JPEGSource();
+
+private:
+ sp<DataSource> mSource;
+ MediaBufferGroup *mGroup;
+ bool mStarted;
+ off64_t mSize;
+ int32_t mWidth, mHeight;
+ off64_t mOffset;
+
+ status_t parseJPEG();
+
+ JPEGSource(const JPEGSource &);
+ JPEGSource &operator=(const JPEGSource &);
+};
+
+} // namespace android
+
+#endif // JPEG_SOURCE_H_
+
diff --git a/media/libstagefright/include/MPEG2TSWriter.h b/media/libstagefright/include/MPEG2TSWriter.h
new file mode 100644
index 0000000..4516fb6
--- /dev/null
+++ b/media/libstagefright/include/MPEG2TSWriter.h
@@ -0,0 +1,92 @@
+/*
+ * 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 MPEG2TS_WRITER_H_
+
+#define MPEG2TS_WRITER_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AHandlerReflector.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/MediaWriter.h>
+
+namespace android {
+
+struct ABuffer;
+
+struct MPEG2TSWriter : public MediaWriter {
+ MPEG2TSWriter(int fd);
+
+ MPEG2TSWriter(
+ void *cookie,
+ ssize_t (*write)(void *cookie, const void *data, size_t size));
+
+ virtual status_t addSource(const sp<IMediaSource> &source);
+ virtual status_t start(MetaData *param = NULL);
+ virtual status_t stop() { return reset(); }
+ virtual status_t pause();
+ virtual bool reachedEOS();
+ virtual status_t dump(int fd, const Vector<String16>& args);
+
+ void onMessageReceived(const sp<AMessage> &msg);
+
+protected:
+ virtual ~MPEG2TSWriter();
+
+private:
+ enum {
+ kWhatSourceNotify = 'noti'
+ };
+
+ struct SourceInfo;
+
+ FILE *mFile;
+
+ void *mWriteCookie;
+ ssize_t (*mWriteFunc)(void *cookie, const void *data, size_t size);
+
+ sp<ALooper> mLooper;
+ sp<AHandlerReflector<MPEG2TSWriter> > mReflector;
+
+ bool mStarted;
+
+ Vector<sp<SourceInfo> > mSources;
+ size_t mNumSourcesDone;
+
+ int64_t mNumTSPacketsWritten;
+ int64_t mNumTSPacketsBeforeMeta;
+ int mPATContinuityCounter;
+ int mPMTContinuityCounter;
+ uint32_t mCrcTable[256];
+
+ void init();
+
+ void writeTS();
+ void writeProgramAssociationTable();
+ void writeProgramMap();
+ void writeAccessUnit(int32_t sourceIndex, const sp<ABuffer> &buffer);
+ void initCrcTable();
+ uint32_t crc32(const uint8_t *start, size_t length);
+
+ ssize_t internalWrite(const void *data, size_t size);
+ status_t reset();
+
+ DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSWriter);
+};
+
+} // namespace android
+
+#endif // MPEG2TS_WRITER_H_
diff --git a/media/libstagefright/include/MPEG4Writer.h b/media/libstagefright/include/MPEG4Writer.h
new file mode 100644
index 0000000..39e7d01
--- /dev/null
+++ b/media/libstagefright/include/MPEG4Writer.h
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2009 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 MPEG4_WRITER_H_
+
+#define MPEG4_WRITER_H_
+
+#include <stdio.h>
+
+#include <media/IMediaSource.h>
+#include <media/stagefright/MediaWriter.h>
+#include <utils/List.h>
+#include <utils/threads.h>
+#include <media/stagefright/foundation/AHandlerReflector.h>
+#include <media/stagefright/foundation/ALooper.h>
+
+namespace android {
+
+class AMessage;
+class MediaBuffer;
+class MetaData;
+
+class MPEG4Writer : public MediaWriter {
+public:
+ MPEG4Writer(int fd);
+
+ // Limitations
+ // No more than one video and/or one audio source can be added, but
+ // multiple metadata sources can be added.
+ virtual status_t addSource(const sp<IMediaSource> &source);
+
+ // Returns INVALID_OPERATION if there is no source or track.
+ virtual status_t start(MetaData *param = NULL);
+ virtual status_t stop() { return reset(); }
+ virtual status_t pause();
+ virtual bool reachedEOS();
+ virtual status_t dump(int fd, const Vector<String16>& args);
+
+ void beginBox(const char *fourcc);
+ void beginBox(uint32_t id);
+ void writeInt8(int8_t x);
+ void writeInt16(int16_t x);
+ void writeInt32(int32_t x);
+ void writeInt64(int64_t x);
+ void writeCString(const char *s);
+ void writeFourcc(const char *fourcc);
+ void write(const void *data, size_t size);
+ inline size_t write(const void *ptr, size_t size, size_t nmemb);
+ void endBox();
+ uint32_t interleaveDuration() const { return mInterleaveDurationUs; }
+ status_t setInterleaveDuration(uint32_t duration);
+ int32_t getTimeScale() const { return mTimeScale; }
+
+ status_t setGeoData(int latitudex10000, int longitudex10000);
+ status_t setCaptureRate(float captureFps);
+ status_t setTemporalLayerCount(uint32_t layerCount);
+ void notifyApproachingLimit();
+ virtual void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
+ virtual int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }
+ virtual status_t setNextFd(int fd);
+
+protected:
+ virtual ~MPEG4Writer();
+
+private:
+ class Track;
+ friend struct AHandlerReflector<MPEG4Writer>;
+
+ enum {
+ kWhatSwitch = 'swch',
+ };
+
+ int mFd;
+ int mNextFd;
+ sp<MetaData> mStartMeta;
+ status_t mInitCheck;
+ bool mIsRealTimeRecording;
+ bool mUse4ByteNalLength;
+ bool mUse32BitOffset;
+ bool mIsFileSizeLimitExplicitlyRequested;
+ bool mPaused;
+ bool mStarted; // Writer thread + track threads started successfully
+ bool mWriterThreadStarted; // Only writer thread started successfully
+ bool mSendNotify;
+ off64_t mOffset;
+ off_t mMdatOffset;
+ uint8_t *mMoovBoxBuffer;
+ off64_t mMoovBoxBufferOffset;
+ bool mWriteMoovBoxToMemory;
+ off64_t mFreeBoxOffset;
+ bool mStreamableFile;
+ off64_t mEstimatedMoovBoxSize;
+ off64_t mMoovExtraSize;
+ uint32_t mInterleaveDurationUs;
+ int32_t mTimeScale;
+ int64_t mStartTimestampUs;
+ int mLatitudex10000;
+ int mLongitudex10000;
+ bool mAreGeoTagsAvailable;
+ int32_t mStartTimeOffsetMs;
+ bool mSwitchPending;
+
+ sp<ALooper> mLooper;
+ sp<AHandlerReflector<MPEG4Writer> > mReflector;
+
+ Mutex mLock;
+
+ List<Track *> mTracks;
+
+ List<off64_t> mBoxes;
+
+ sp<AMessage> mMetaKeys;
+
+ void setStartTimestampUs(int64_t timeUs);
+ int64_t getStartTimestampUs(); // Not const
+ status_t startTracks(MetaData *params);
+ size_t numTracks();
+ int64_t estimateMoovBoxSize(int32_t bitRate);
+
+ struct Chunk {
+ Track *mTrack; // Owner
+ int64_t mTimeStampUs; // Timestamp of the 1st sample
+ List<MediaBuffer *> mSamples; // Sample data
+
+ // Convenient constructor
+ Chunk(): mTrack(NULL), mTimeStampUs(0) {}
+
+ Chunk(Track *track, int64_t timeUs, List<MediaBuffer *> samples)
+ : mTrack(track), mTimeStampUs(timeUs), mSamples(samples) {
+ }
+
+ };
+ struct ChunkInfo {
+ Track *mTrack; // Owner
+ List<Chunk> mChunks; // Remaining chunks to be written
+
+ // Previous chunk timestamp that has been written
+ int64_t mPrevChunkTimestampUs;
+
+ // Max time interval between neighboring chunks
+ int64_t mMaxInterChunkDurUs;
+
+ };
+
+ bool mIsFirstChunk;
+ volatile bool mDone; // Writer thread is done?
+ pthread_t mThread; // Thread id for the writer
+ List<ChunkInfo> mChunkInfos; // Chunk infos
+ Condition mChunkReadyCondition; // Signal that chunks are available
+
+ // Writer thread handling
+ status_t startWriterThread();
+ void stopWriterThread();
+ static void *ThreadWrapper(void *me);
+ void threadFunc();
+
+ // Buffer a single chunk to be written out later.
+ void bufferChunk(const Chunk& chunk);
+
+ // Write all buffered chunks from all tracks
+ void writeAllChunks();
+
+ // Retrieve the proper chunk to write if there is one
+ // Return true if a chunk is found; otherwise, return false.
+ bool findChunkToWrite(Chunk *chunk);
+
+ // Actually write the given chunk to the file.
+ void writeChunkToFile(Chunk* chunk);
+
+ // Adjust other track media clock (presumably wall clock)
+ // based on audio track media clock with the drift time.
+ int64_t mDriftTimeUs;
+ void setDriftTimeUs(int64_t driftTimeUs);
+ int64_t getDriftTimeUs();
+
+ // Return whether the nal length is 4 bytes or 2 bytes
+ // Only makes sense for H.264/AVC
+ bool useNalLengthFour();
+
+ // Return whether the writer is used for real time recording.
+ // In real time recording mode, new samples will be allowed to buffered into
+ // chunks in higher priority thread, even though the file writer has not
+ // drained the chunks yet.
+ // By default, real time recording is on.
+ bool isRealTimeRecording() const;
+
+ void lock();
+ void unlock();
+
+ void initInternal(int fd);
+
+ // Acquire lock before calling these methods
+ off64_t addSample_l(MediaBuffer *buffer);
+ off64_t addLengthPrefixedSample_l(MediaBuffer *buffer);
+ off64_t addMultipleLengthPrefixedSamples_l(MediaBuffer *buffer);
+
+ bool exceedsFileSizeLimit();
+ bool use32BitFileOffset() const;
+ bool exceedsFileDurationLimit();
+ bool approachingFileSizeLimit();
+ bool isFileStreamable() const;
+ void trackProgressStatus(size_t trackId, int64_t timeUs, status_t err = OK);
+ void writeCompositionMatrix(int32_t degrees);
+ void writeMvhdBox(int64_t durationUs);
+ void writeMoovBox(int64_t durationUs);
+ void writeFtypBox(MetaData *param);
+ void writeUdtaBox();
+ void writeGeoDataBox();
+ void writeLatitude(int degreex10000);
+ void writeLongitude(int degreex10000);
+ void finishCurrentSession();
+
+ void addDeviceMeta();
+ void writeHdlr();
+ void writeKeys();
+ void writeIlst();
+ void writeMetaBox();
+ void sendSessionSummary();
+ void release();
+ status_t switchFd();
+ status_t reset(bool stopSource = true);
+
+ static uint32_t getMpeg4Time();
+
+ void onMessageReceived(const sp<AMessage> &msg);
+
+ MPEG4Writer(const MPEG4Writer &);
+ MPEG4Writer &operator=(const MPEG4Writer &);
+};
+
+} // namespace android
+
+#endif // MPEG4_WRITER_H_
diff --git a/media/libstagefright/include/MediaAdapter.h b/media/libstagefright/include/MediaAdapter.h
new file mode 100644
index 0000000..369fce6
--- /dev/null
+++ b/media/libstagefright/include/MediaAdapter.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013 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 MEDIA_ADAPTER_H
+#define MEDIA_ADAPTER_H
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MetaData.h>
+#include <utils/threads.h>
+
+namespace android {
+
+// Convert the MediaMuxer's push model into MPEG4Writer's pull model.
+// Used only by the MediaMuxer for now.
+struct MediaAdapter : public MediaSource, public MediaBufferObserver {
+public:
+ // MetaData is used to set the format and returned at getFormat.
+ MediaAdapter(const sp<MetaData> &meta);
+ virtual ~MediaAdapter();
+ /////////////////////////////////////////////////
+ // Inherited functions from MediaSource
+ /////////////////////////////////////////////////
+
+ virtual status_t start(MetaData *params = NULL);
+ virtual status_t stop();
+ virtual sp<MetaData> getFormat();
+ virtual status_t read(
+ MediaBuffer **buffer, const ReadOptions *options = NULL);
+
+ /////////////////////////////////////////////////
+ // Inherited functions from MediaBufferObserver
+ /////////////////////////////////////////////////
+
+ virtual void signalBufferReturned(MediaBuffer *buffer);
+
+ /////////////////////////////////////////////////
+ // Non-inherited functions:
+ /////////////////////////////////////////////////
+
+ // pushBuffer() will wait for the read() finish, and read() will have a
+ // deep copy, such that after pushBuffer return, the buffer can be re-used.
+ status_t pushBuffer(MediaBuffer *buffer);
+
+private:
+ Mutex mAdapterLock;
+ // Make sure the read() wait for the incoming buffer.
+ Condition mBufferReadCond;
+ // Make sure the pushBuffer() wait for the current buffer consumed.
+ Condition mBufferReturnedCond;
+
+ MediaBuffer *mCurrentMediaBuffer;
+
+ bool mStarted;
+ sp<MetaData> mOutputFormat;
+
+ DISALLOW_EVIL_CONSTRUCTORS(MediaAdapter);
+};
+
+} // namespace android
+
+#endif // MEDIA_ADAPTER_H
diff --git a/media/libstagefright/include/MediaBuffer.h b/media/libstagefright/include/MediaBuffer.h
new file mode 100644
index 0000000..2c0ebe7
--- /dev/null
+++ b/media/libstagefright/include/MediaBuffer.h
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2009 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 MEDIA_BUFFER_H_
+
+#define MEDIA_BUFFER_H_
+
+#include <atomic>
+#include <list>
+#include <media/stagefright/foundation/MediaBufferBase.h>
+
+#include <pthread.h>
+
+#include <binder/MemoryDealer.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct ABuffer;
+class GraphicBuffer;
+class MediaBuffer;
+class MediaBufferObserver;
+class MetaData;
+
+class MediaBufferObserver {
+public:
+ MediaBufferObserver() {}
+ virtual ~MediaBufferObserver() {}
+
+ virtual void signalBufferReturned(MediaBuffer *buffer) = 0;
+
+private:
+ MediaBufferObserver(const MediaBufferObserver &);
+ MediaBufferObserver &operator=(const MediaBufferObserver &);
+};
+
+class MediaBuffer : public MediaBufferBase {
+public:
+ // allocations larger than or equal to this will use shared memory.
+ static const size_t kSharedMemThreshold = 64 * 1024;
+
+ // The underlying data remains the responsibility of the caller!
+ MediaBuffer(void *data, size_t size);
+
+ explicit MediaBuffer(size_t size);
+
+ explicit MediaBuffer(const sp<GraphicBuffer>& graphicBuffer);
+
+ explicit MediaBuffer(const sp<ABuffer> &buffer);
+
+ MediaBuffer(const sp<IMemory> &mem) :
+ MediaBuffer((uint8_t *)mem->pointer() + sizeof(SharedControl), mem->size()) {
+ // delegate and override mMemory
+ mMemory = mem;
+ }
+
+ // If MediaBufferGroup is set, decrement the local reference count;
+ // if the local reference count drops to 0, return the buffer to the
+ // associated MediaBufferGroup.
+ //
+ // If no MediaBufferGroup is set, the local reference count must be zero
+ // when called, whereupon the MediaBuffer is deleted.
+ virtual void release();
+
+ // Increments the local reference count.
+ // Use only when MediaBufferGroup is set.
+ virtual void add_ref();
+
+ void *data() const;
+ size_t size() const;
+
+ size_t range_offset() const;
+ size_t range_length() const;
+
+ void set_range(size_t offset, size_t length);
+
+ sp<GraphicBuffer> graphicBuffer() const;
+
+ sp<MetaData> meta_data();
+
+ // Clears meta data and resets the range to the full extent.
+ void reset();
+
+ void setObserver(MediaBufferObserver *group);
+
+ // Returns a clone of this MediaBuffer increasing its reference count.
+ // The clone references the same data but has its own range and
+ // MetaData.
+ MediaBuffer *clone();
+
+ // sum of localRefcount() and remoteRefcount()
+ int refcount() const {
+ return localRefcount() + remoteRefcount();
+ }
+
+ int localRefcount() const {
+ return mRefCount;
+ }
+
+ int remoteRefcount() const {
+ if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
+ int32_t remoteRefcount =
+ reinterpret_cast<SharedControl *>(mMemory->pointer())->getRemoteRefcount();
+ // Sanity check so that remoteRefCount() is non-negative.
+ return remoteRefcount >= 0 ? remoteRefcount : 0; // do not allow corrupted data.
+ }
+
+ // returns old value
+ int addRemoteRefcount(int32_t value) {
+ if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
+ return reinterpret_cast<SharedControl *>(mMemory->pointer())->addRemoteRefcount(value);
+ }
+
+ bool isDeadObject() const {
+ return isDeadObject(mMemory);
+ }
+
+ static bool isDeadObject(const sp<IMemory> &memory) {
+ if (memory.get() == nullptr || memory->pointer() == nullptr) return false;
+ return reinterpret_cast<SharedControl *>(memory->pointer())->isDeadObject();
+ }
+
+ // Sticky on enabling of shared memory MediaBuffers. By default we don't use
+ // shared memory for MediaBuffers, but we enable this for those processes
+ // that export MediaBuffers.
+ static void useSharedMemory() {
+ std::atomic_store_explicit(
+ &mUseSharedMemory, (int_least32_t)1, std::memory_order_seq_cst);
+ }
+
+protected:
+ // true if MediaBuffer is observed (part of a MediaBufferGroup).
+ inline bool isObserved() const {
+ return mObserver != nullptr;
+ }
+
+ virtual ~MediaBuffer();
+
+ sp<IMemory> mMemory;
+
+private:
+ friend class MediaBufferGroup;
+ friend class OMXDecoder;
+ friend class BnMediaSource;
+ friend class BpMediaSource;
+
+ // For use by OMXDecoder, reference count must be 1, drop reference
+ // count to 0 without signalling the observer.
+ void claim();
+
+ MediaBufferObserver *mObserver;
+ int mRefCount;
+
+ void *mData;
+ size_t mSize, mRangeOffset, mRangeLength;
+ sp<GraphicBuffer> mGraphicBuffer;
+ sp<ABuffer> mBuffer;
+
+ bool mOwnsData;
+
+ sp<MetaData> mMetaData;
+
+ MediaBuffer *mOriginal;
+
+ static std::atomic_int_least32_t mUseSharedMemory;
+
+ MediaBuffer(const MediaBuffer &);
+ MediaBuffer &operator=(const MediaBuffer &);
+
+ // SharedControl block at the start of IMemory.
+ struct SharedControl {
+ enum {
+ FLAG_DEAD_OBJECT = (1 << 0),
+ };
+
+ // returns old value
+ inline int32_t addRemoteRefcount(int32_t value) {
+ return std::atomic_fetch_add_explicit(
+ &mRemoteRefcount, (int_least32_t)value, std::memory_order_seq_cst);
+ }
+
+ inline int32_t getRemoteRefcount() const {
+ return std::atomic_load_explicit(&mRemoteRefcount, std::memory_order_seq_cst);
+ }
+
+ inline void setRemoteRefcount(int32_t value) {
+ std::atomic_store_explicit(
+ &mRemoteRefcount, (int_least32_t)value, std::memory_order_seq_cst);
+ }
+
+ inline bool isDeadObject() const {
+ return (std::atomic_load_explicit(
+ &mFlags, std::memory_order_seq_cst) & FLAG_DEAD_OBJECT) != 0;
+ }
+
+ inline void setDeadObject() {
+ (void)std::atomic_fetch_or_explicit(
+ &mFlags, (int_least32_t)FLAG_DEAD_OBJECT, std::memory_order_seq_cst);
+ }
+
+ inline void clear() {
+ std::atomic_store_explicit(
+ &mFlags, (int_least32_t)0, std::memory_order_seq_cst);
+ std::atomic_store_explicit(
+ &mRemoteRefcount, (int_least32_t)0, std::memory_order_seq_cst);
+ }
+
+ private:
+ // Caution: atomic_int_fast32_t is 64 bits on LP64.
+ std::atomic_int_least32_t mFlags;
+ std::atomic_int_least32_t mRemoteRefcount;
+ int32_t unused[6]; // additional buffer space
+ };
+
+ inline SharedControl *getSharedControl() const {
+ return reinterpret_cast<SharedControl *>(mMemory->pointer());
+ }
+};
+
+} // namespace android
+
+#endif // MEDIA_BUFFER_H_
diff --git a/media/libstagefright/include/MediaBufferGroup.h b/media/libstagefright/include/MediaBufferGroup.h
new file mode 100644
index 0000000..3051406
--- /dev/null
+++ b/media/libstagefright/include/MediaBufferGroup.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2009 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 MEDIA_BUFFER_GROUP_H_
+
+#define MEDIA_BUFFER_GROUP_H_
+
+#include <media/stagefright/MediaBuffer.h>
+#include <utils/Errors.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class MediaBuffer;
+class MetaData;
+
+class MediaBufferGroup : public MediaBufferObserver {
+public:
+ MediaBufferGroup(size_t growthLimit = 0);
+
+ // create a media buffer group with preallocated buffers
+ MediaBufferGroup(size_t buffers, size_t buffer_size, size_t growthLimit = 0);
+
+ ~MediaBufferGroup();
+
+ void add_buffer(MediaBuffer *buffer);
+
+ bool has_buffers();
+
+ // If nonBlocking is false, it blocks until a buffer is available and
+ // passes it to the caller in *buffer, while returning OK.
+ // The returned buffer will have a reference count of 1.
+ // If nonBlocking is true and a buffer is not immediately available,
+ // buffer is set to NULL and it returns WOULD_BLOCK.
+ // If requestedSize is 0, any free MediaBuffer will be returned.
+ // If requestedSize is > 0, the returned MediaBuffer should have buffer
+ // size of at least requstedSize.
+ status_t acquire_buffer(
+ MediaBuffer **buffer, bool nonBlocking = false, size_t requestedSize = 0);
+
+ size_t buffers() const { return mBuffers.size(); }
+
+ // If buffer is nullptr, have acquire_buffer() check for remote release.
+ virtual void signalBufferReturned(MediaBuffer *buffer);
+
+private:
+ friend class MediaBuffer;
+
+ Mutex mLock;
+ Condition mCondition;
+ size_t mGrowthLimit; // Do not automatically grow group larger than this.
+ std::list<MediaBuffer *> mBuffers;
+
+ MediaBufferGroup(const MediaBufferGroup &);
+ MediaBufferGroup &operator=(const MediaBufferGroup &);
+};
+
+} // namespace android
+
+#endif // MEDIA_BUFFER_GROUP_H_
diff --git a/media/libstagefright/include/MediaClock.h b/media/libstagefright/include/MediaClock.h
new file mode 100644
index 0000000..dd1a809
--- /dev/null
+++ b/media/libstagefright/include/MediaClock.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 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 MEDIA_CLOCK_H_
+
+#define MEDIA_CLOCK_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/Mutex.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct AMessage;
+
+struct MediaClock : public RefBase {
+ MediaClock();
+
+ void setStartingTimeMedia(int64_t startingTimeMediaUs);
+
+ void clearAnchor();
+ // It's required to use timestamp of just rendered frame as
+ // anchor time in paused state.
+ void updateAnchor(
+ int64_t anchorTimeMediaUs,
+ int64_t anchorTimeRealUs,
+ int64_t maxTimeMediaUs = INT64_MAX);
+
+ void updateMaxTimeMedia(int64_t maxTimeMediaUs);
+
+ void setPlaybackRate(float rate);
+ float getPlaybackRate() const;
+
+ // query media time corresponding to real time |realUs|, and save the
+ // result in |outMediaUs|.
+ status_t getMediaTime(
+ int64_t realUs,
+ int64_t *outMediaUs,
+ bool allowPastMaxTime = false) const;
+ // query real time corresponding to media time |targetMediaUs|.
+ // The result is saved in |outRealUs|.
+ status_t getRealTimeFor(int64_t targetMediaUs, int64_t *outRealUs) const;
+
+protected:
+ virtual ~MediaClock();
+
+private:
+ status_t getMediaTime_l(
+ int64_t realUs,
+ int64_t *outMediaUs,
+ bool allowPastMaxTime) const;
+
+ mutable Mutex mLock;
+
+ int64_t mAnchorTimeMediaUs;
+ int64_t mAnchorTimeRealUs;
+ int64_t mMaxTimeMediaUs;
+ int64_t mStartingTimeMediaUs;
+
+ float mPlaybackRate;
+
+ DISALLOW_EVIL_CONSTRUCTORS(MediaClock);
+};
+
+} // namespace android
+
+#endif // MEDIA_CLOCK_H_
diff --git a/media/libstagefright/include/MediaCodec.h b/media/libstagefright/include/MediaCodec.h
new file mode 100644
index 0000000..fd3ff26
--- /dev/null
+++ b/media/libstagefright/include/MediaCodec.h
@@ -0,0 +1,442 @@
+/*
+ * Copyright 2012, 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 MEDIA_CODEC_H_
+
+#define MEDIA_CODEC_H_
+
+#include <memory>
+#include <vector>
+
+#include <gui/IGraphicBufferProducer.h>
+#include <media/hardware/CryptoAPI.h>
+#include <media/MediaCodecInfo.h>
+#include <media/MediaResource.h>
+#include <media/MediaAnalyticsItem.h>
+#include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/FrameRenderTracker.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct ABuffer;
+struct AMessage;
+struct AReplyToken;
+struct AString;
+class BufferChannelBase;
+struct CodecBase;
+class IBatteryStats;
+struct ICrypto;
+class MediaCodecBuffer;
+class IMemory;
+class IResourceManagerClient;
+class IResourceManagerService;
+struct PersistentSurface;
+class SoftwareRenderer;
+class Surface;
+namespace media {
+class IDescrambler;
+};
+using namespace media;
+
+struct MediaCodec : public AHandler {
+ enum ConfigureFlags {
+ CONFIGURE_FLAG_ENCODE = 1,
+ };
+
+ enum BufferFlags {
+ BUFFER_FLAG_SYNCFRAME = 1,
+ BUFFER_FLAG_CODECCONFIG = 2,
+ BUFFER_FLAG_EOS = 4,
+ };
+
+ enum {
+ CB_INPUT_AVAILABLE = 1,
+ CB_OUTPUT_AVAILABLE = 2,
+ CB_ERROR = 3,
+ CB_OUTPUT_FORMAT_CHANGED = 4,
+ CB_RESOURCE_RECLAIMED = 5,
+ };
+
+ static const pid_t kNoPid = -1;
+ static const uid_t kNoUid = -1;
+
+ static sp<MediaCodec> CreateByType(
+ const sp<ALooper> &looper, const AString &mime, bool encoder, status_t *err = NULL,
+ pid_t pid = kNoPid, uid_t uid = kNoUid);
+
+ static sp<MediaCodec> CreateByComponentName(
+ const sp<ALooper> &looper, const AString &name, status_t *err = NULL,
+ pid_t pid = kNoPid, uid_t uid = kNoUid);
+
+ static sp<PersistentSurface> CreatePersistentInputSurface();
+
+ // utility method to query capabilities
+ static status_t QueryCapabilities(
+ const AString &name, const AString &mime, bool isEncoder,
+ sp<MediaCodecInfo::Capabilities> *caps /* nonnull */);
+
+ status_t configure(
+ const sp<AMessage> &format,
+ const sp<Surface> &nativeWindow,
+ const sp<ICrypto> &crypto,
+ uint32_t flags);
+
+ status_t configure(
+ const sp<AMessage> &format,
+ const sp<Surface> &nativeWindow,
+ const sp<ICrypto> &crypto,
+ const sp<IDescrambler> &descrambler,
+ uint32_t flags);
+
+ status_t releaseCrypto();
+
+ status_t setCallback(const sp<AMessage> &callback);
+
+ status_t setOnFrameRenderedNotification(const sp<AMessage> ¬ify);
+
+ status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer);
+
+ status_t setInputSurface(const sp<PersistentSurface> &surface);
+
+ status_t start();
+
+ // Returns to a state in which the component remains allocated but
+ // unconfigured.
+ status_t stop();
+
+ // Resets the codec to the INITIALIZED state. Can be called after an error
+ // has occured to make the codec usable.
+ status_t reset();
+
+ // Client MUST call release before releasing final reference to this
+ // object.
+ status_t release();
+
+ status_t flush();
+
+ status_t queueInputBuffer(
+ size_t index,
+ size_t offset,
+ size_t size,
+ int64_t presentationTimeUs,
+ uint32_t flags,
+ AString *errorDetailMsg = NULL);
+
+ status_t queueSecureInputBuffer(
+ size_t index,
+ size_t offset,
+ const CryptoPlugin::SubSample *subSamples,
+ size_t numSubSamples,
+ const uint8_t key[16],
+ const uint8_t iv[16],
+ CryptoPlugin::Mode mode,
+ const CryptoPlugin::Pattern &pattern,
+ int64_t presentationTimeUs,
+ uint32_t flags,
+ AString *errorDetailMsg = NULL);
+
+ status_t dequeueInputBuffer(size_t *index, int64_t timeoutUs = 0ll);
+
+ status_t dequeueOutputBuffer(
+ size_t *index,
+ size_t *offset,
+ size_t *size,
+ int64_t *presentationTimeUs,
+ uint32_t *flags,
+ int64_t timeoutUs = 0ll);
+
+ status_t renderOutputBufferAndRelease(size_t index, int64_t timestampNs);
+ status_t renderOutputBufferAndRelease(size_t index);
+ status_t releaseOutputBuffer(size_t index);
+
+ status_t signalEndOfInputStream();
+
+ status_t getOutputFormat(sp<AMessage> *format) const;
+ status_t getInputFormat(sp<AMessage> *format) const;
+
+ status_t getInputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const;
+ status_t getOutputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const;
+
+ status_t getOutputBuffer(size_t index, sp<MediaCodecBuffer> *buffer);
+ status_t getOutputFormat(size_t index, sp<AMessage> *format);
+ status_t getInputBuffer(size_t index, sp<MediaCodecBuffer> *buffer);
+
+ status_t setSurface(const sp<Surface> &nativeWindow);
+
+ status_t requestIDRFrame();
+
+ // Notification will be posted once there "is something to do", i.e.
+ // an input/output buffer has become available, a format change is
+ // pending, an error is pending.
+ void requestActivityNotification(const sp<AMessage> ¬ify);
+
+ status_t getName(AString *componentName) const;
+
+ status_t getMetrics(Parcel *reply);
+
+ status_t setParameters(const sp<AMessage> ¶ms);
+
+ // Create a MediaCodec notification message from a list of rendered or dropped render infos
+ // by adding rendered frame information to a base notification message. Returns the number
+ // of frames that were rendered.
+ static size_t CreateFramesRenderedMessage(
+ const std::list<FrameRenderTracker::Info> &done, sp<AMessage> &msg);
+
+protected:
+ virtual ~MediaCodec();
+ virtual void onMessageReceived(const sp<AMessage> &msg);
+
+private:
+ // used by ResourceManagerClient
+ status_t reclaim(bool force = false);
+ friend struct ResourceManagerClient;
+
+private:
+ enum State {
+ UNINITIALIZED,
+ INITIALIZING,
+ INITIALIZED,
+ CONFIGURING,
+ CONFIGURED,
+ STARTING,
+ STARTED,
+ FLUSHING,
+ FLUSHED,
+ STOPPING,
+ RELEASING,
+ };
+
+ enum {
+ kPortIndexInput = 0,
+ kPortIndexOutput = 1,
+ };
+
+ enum {
+ kWhatInit = 'init',
+ kWhatConfigure = 'conf',
+ kWhatSetSurface = 'sSur',
+ kWhatCreateInputSurface = 'cisf',
+ kWhatSetInputSurface = 'sisf',
+ kWhatStart = 'strt',
+ kWhatStop = 'stop',
+ kWhatRelease = 'rele',
+ kWhatDequeueInputBuffer = 'deqI',
+ kWhatQueueInputBuffer = 'queI',
+ kWhatDequeueOutputBuffer = 'deqO',
+ kWhatReleaseOutputBuffer = 'relO',
+ kWhatSignalEndOfInputStream = 'eois',
+ kWhatGetBuffers = 'getB',
+ kWhatFlush = 'flus',
+ kWhatGetOutputFormat = 'getO',
+ kWhatGetInputFormat = 'getI',
+ kWhatDequeueInputTimedOut = 'dITO',
+ kWhatDequeueOutputTimedOut = 'dOTO',
+ kWhatCodecNotify = 'codc',
+ kWhatRequestIDRFrame = 'ridr',
+ kWhatRequestActivityNotification = 'racN',
+ kWhatGetName = 'getN',
+ kWhatSetParameters = 'setP',
+ kWhatSetCallback = 'setC',
+ kWhatSetNotification = 'setN',
+ kWhatDrmReleaseCrypto = 'rDrm',
+ };
+
+ enum {
+ kFlagUsesSoftwareRenderer = 1,
+ kFlagOutputFormatChanged = 2,
+ kFlagOutputBuffersChanged = 4,
+ kFlagStickyError = 8,
+ kFlagDequeueInputPending = 16,
+ kFlagDequeueOutputPending = 32,
+ kFlagIsSecure = 64,
+ kFlagSawMediaServerDie = 128,
+ kFlagIsEncoder = 256,
+ // 512 skipped
+ kFlagIsAsync = 1024,
+ kFlagIsComponentAllocated = 2048,
+ kFlagPushBlankBuffersOnShutdown = 4096,
+ };
+
+ struct BufferInfo {
+ BufferInfo();
+
+ sp<MediaCodecBuffer> mData;
+ bool mOwnedByClient;
+ };
+
+ struct ResourceManagerServiceProxy : public IBinder::DeathRecipient {
+ ResourceManagerServiceProxy(pid_t pid);
+ ~ResourceManagerServiceProxy();
+
+ void init();
+
+ // implements DeathRecipient
+ virtual void binderDied(const wp<IBinder>& /*who*/);
+
+ void addResource(
+ int64_t clientId,
+ const sp<IResourceManagerClient> &client,
+ const Vector<MediaResource> &resources);
+
+ void removeResource(int64_t clientId);
+
+ bool reclaimResource(const Vector<MediaResource> &resources);
+
+ private:
+ Mutex mLock;
+ sp<IResourceManagerService> mService;
+ pid_t mPid;
+ };
+
+ State mState;
+ uid_t mUid;
+ bool mReleasedByResourceManager;
+ sp<ALooper> mLooper;
+ sp<ALooper> mCodecLooper;
+ sp<CodecBase> mCodec;
+ AString mComponentName;
+ sp<AReplyToken> mReplyID;
+ uint32_t mFlags;
+ status_t mStickyError;
+ sp<Surface> mSurface;
+ SoftwareRenderer *mSoftRenderer;
+
+ MediaAnalyticsItem *mAnalyticsItem;
+
+ sp<AMessage> mOutputFormat;
+ sp<AMessage> mInputFormat;
+ sp<AMessage> mCallback;
+ sp<AMessage> mOnFrameRenderedNotification;
+
+ sp<IResourceManagerClient> mResourceManagerClient;
+ sp<ResourceManagerServiceProxy> mResourceManagerService;
+
+ bool mBatteryStatNotified;
+ bool mIsVideo;
+ int32_t mVideoWidth;
+ int32_t mVideoHeight;
+ int32_t mRotationDegrees;
+
+ // initial create parameters
+ AString mInitName;
+ bool mInitNameIsType;
+ bool mInitIsEncoder;
+
+ // configure parameter
+ sp<AMessage> mConfigureMsg;
+
+ // Used only to synchronize asynchronous getBufferAndFormat
+ // across all the other (synchronous) buffer state change
+ // operations, such as de/queueIn/OutputBuffer, start and
+ // stop/flush/reset/release.
+ Mutex mBufferLock;
+
+ List<size_t> mAvailPortBuffers[2];
+ std::vector<BufferInfo> mPortBuffers[2];
+
+ int32_t mDequeueInputTimeoutGeneration;
+ sp<AReplyToken> mDequeueInputReplyID;
+
+ int32_t mDequeueOutputTimeoutGeneration;
+ sp<AReplyToken> mDequeueOutputReplyID;
+
+ sp<ICrypto> mCrypto;
+
+ sp<IDescrambler> mDescrambler;
+
+ List<sp<ABuffer> > mCSD;
+
+ sp<AMessage> mActivityNotify;
+
+ bool mHaveInputSurface;
+ bool mHavePendingInputBuffers;
+
+ std::shared_ptr<BufferChannelBase> mBufferChannel;
+
+ MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid);
+
+ static sp<CodecBase> GetCodecBase(const AString &name, bool nameIsType = false);
+
+ static status_t PostAndAwaitResponse(
+ const sp<AMessage> &msg, sp<AMessage> *response);
+
+ void PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err);
+
+ status_t init(const AString &name, bool nameIsType, bool encoder);
+
+ void setState(State newState);
+ void returnBuffersToCodec(bool isReclaim = false);
+ void returnBuffersToCodecOnPort(int32_t portIndex, bool isReclaim = false);
+ size_t updateBuffers(int32_t portIndex, const sp<AMessage> &msg);
+ status_t onQueueInputBuffer(const sp<AMessage> &msg);
+ status_t onReleaseOutputBuffer(const sp<AMessage> &msg);
+ ssize_t dequeuePortBuffer(int32_t portIndex);
+
+ status_t getBufferAndFormat(
+ size_t portIndex, size_t index,
+ sp<MediaCodecBuffer> *buffer, sp<AMessage> *format);
+
+ bool handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false);
+ bool handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false);
+ void cancelPendingDequeueOperations();
+
+ void extractCSD(const sp<AMessage> &format);
+ status_t queueCSDInputBuffer(size_t bufferIndex);
+
+ status_t handleSetSurface(const sp<Surface> &surface);
+ status_t connectToSurface(const sp<Surface> &surface);
+ status_t disconnectFromSurface();
+
+ void postActivityNotificationIfPossible();
+
+ void onInputBufferAvailable();
+ void onOutputBufferAvailable();
+ void onError(status_t err, int32_t actionCode, const char *detail = NULL);
+ void onOutputFormatChanged();
+
+ status_t onSetParameters(const sp<AMessage> ¶ms);
+
+ status_t amendOutputFormatWithCodecSpecificData(const sp<MediaCodecBuffer> &buffer);
+ void updateBatteryStat();
+ bool isExecuting() const;
+
+ uint64_t getGraphicBufferSize();
+ void addResource(MediaResource::Type type, MediaResource::SubType subtype, uint64_t value);
+
+ bool hasPendingBuffer(int portIndex);
+ bool hasPendingBuffer();
+
+ /* called to get the last codec error when the sticky flag is set.
+ * if no such codec error is found, returns UNKNOWN_ERROR.
+ */
+ inline status_t getStickyError() const {
+ return mStickyError != 0 ? mStickyError : UNKNOWN_ERROR;
+ }
+
+ inline void setStickyError(status_t err) {
+ mFlags |= kFlagStickyError;
+ mStickyError = err;
+ }
+
+ void onReleaseCrypto(const sp<AMessage>& msg);
+
+ DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
+};
+
+} // namespace android
+
+#endif // MEDIA_CODEC_H_
diff --git a/media/libstagefright/include/MediaCodecList.h b/media/libstagefright/include/MediaCodecList.h
new file mode 100644
index 0000000..430bc16
--- /dev/null
+++ b/media/libstagefright/include/MediaCodecList.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2012, 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 MEDIA_CODEC_LIST_H_
+
+#define MEDIA_CODEC_LIST_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AString.h>
+#include <media/IMediaCodecList.h>
+#include <media/IOMX.h>
+#include <media/MediaCodecInfo.h>
+
+#include <sys/types.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/Vector.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+extern const char *kMaxEncoderInputBuffers;
+
+struct AMessage;
+
+struct MediaCodecList : public BnMediaCodecList {
+ static sp<IMediaCodecList> getInstance();
+
+ virtual ssize_t findCodecByType(
+ const char *type, bool encoder, size_t startIndex = 0) const;
+
+ virtual ssize_t findCodecByName(const char *name) const;
+
+ virtual size_t countCodecs() const;
+
+ virtual sp<MediaCodecInfo> getCodecInfo(size_t index) const {
+ if (index >= mCodecInfos.size()) {
+ ALOGE("b/24445127");
+ return NULL;
+ }
+ return mCodecInfos.itemAt(index);
+ }
+
+ virtual const sp<AMessage> getGlobalSettings() const;
+
+ // to be used by MediaPlayerService alone
+ static sp<IMediaCodecList> getLocalInstance();
+
+ // only to be used by getLocalInstance
+ static void *profilerThreadWrapper(void * /*arg*/);
+
+ // only to be used by MediaPlayerService
+ void parseTopLevelXMLFile(const char *path, bool ignore_errors = false);
+
+ enum Flags {
+ kPreferSoftwareCodecs = 1,
+ kHardwareCodecsOnly = 2,
+ };
+
+ static void findMatchingCodecs(
+ const char *mime,
+ bool createEncoder,
+ uint32_t flags,
+ Vector<AString> *matching);
+
+ static uint32_t getQuirksFor(const char *mComponentName);
+
+ static bool isSoftwareCodec(const AString &componentName);
+
+
+private:
+ class BinderDeathObserver : public IBinder::DeathRecipient {
+ void binderDied(const wp<IBinder> &the_late_who __unused);
+ };
+
+ static sp<BinderDeathObserver> sBinderDeathObserver;
+
+ enum Section {
+ SECTION_TOPLEVEL,
+ SECTION_SETTINGS,
+ SECTION_DECODERS,
+ SECTION_DECODER,
+ SECTION_DECODER_TYPE,
+ SECTION_ENCODERS,
+ SECTION_ENCODER,
+ SECTION_ENCODER_TYPE,
+ SECTION_INCLUDE,
+ };
+
+ static sp<IMediaCodecList> sCodecList;
+ static sp<IMediaCodecList> sRemoteList;
+
+ status_t mInitCheck;
+ Section mCurrentSection;
+ bool mUpdate;
+ Vector<Section> mPastSections;
+ int32_t mDepth;
+ AString mHrefBase;
+
+ sp<AMessage> mGlobalSettings;
+ KeyedVector<AString, CodecSettings> mOverrides;
+
+ Vector<sp<MediaCodecInfo> > mCodecInfos;
+ sp<MediaCodecInfo> mCurrentInfo;
+
+ MediaCodecList();
+ ~MediaCodecList();
+
+ status_t initCheck() const;
+ void parseXMLFile(const char *path);
+
+ static void StartElementHandlerWrapper(
+ void *me, const char *name, const char **attrs);
+
+ static void EndElementHandlerWrapper(void *me, const char *name);
+
+ void startElementHandler(const char *name, const char **attrs);
+ void endElementHandler(const char *name);
+
+ status_t includeXMLFile(const char **attrs);
+ status_t addSettingFromAttributes(const char **attrs);
+ status_t addMediaCodecFromAttributes(bool encoder, const char **attrs);
+ void addMediaCodec(bool encoder, const char *name, const char *type = NULL);
+
+ void setCurrentCodecInfo(bool encoder, const char *name, const char *type);
+
+ status_t addQuirk(const char **attrs);
+ status_t addTypeFromAttributes(const char **attrs);
+ status_t addLimit(const char **attrs);
+ status_t addFeature(const char **attrs);
+ void addType(const char *name);
+
+ status_t initializeCapabilities(const char *type);
+
+ DISALLOW_EVIL_CONSTRUCTORS(MediaCodecList);
+};
+
+} // namespace android
+
+#endif // MEDIA_CODEC_LIST_H_
+
diff --git a/media/libstagefright/include/MediaCodecSource.h b/media/libstagefright/include/MediaCodecSource.h
new file mode 100644
index 0000000..5e99b78
--- /dev/null
+++ b/media/libstagefright/include/MediaCodecSource.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MediaCodecSource_H_
+#define MediaCodecSource_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AHandlerReflector.h>
+#include <media/stagefright/foundation/Mutexed.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/PersistentSurface.h>
+
+namespace android {
+
+struct ALooper;
+struct AMessage;
+struct AReplyToken;
+class IGraphicBufferProducer;
+struct MediaCodec;
+class MetaData;
+
+struct MediaCodecSource : public MediaSource,
+ public MediaBufferObserver {
+ enum FlagBits {
+ FLAG_USE_SURFACE_INPUT = 1,
+ FLAG_PREFER_SOFTWARE_CODEC = 4, // used for testing only
+ };
+
+ static sp<MediaCodecSource> Create(
+ const sp<ALooper> &looper,
+ const sp<AMessage> &format,
+ const sp<MediaSource> &source,
+ const sp<PersistentSurface> &persistentSurface = NULL,
+ uint32_t flags = 0);
+
+ bool isVideo() const { return mIsVideo; }
+ sp<IGraphicBufferProducer> getGraphicBufferProducer();
+ status_t setInputBufferTimeOffset(int64_t timeOffsetUs);
+ int64_t getFirstSampleSystemTimeUs();
+
+ // MediaSource
+ virtual status_t start(MetaData *params = NULL);
+ virtual status_t stop();
+ virtual status_t pause(MetaData *params = NULL);
+ virtual sp<MetaData> getFormat();
+ virtual status_t read(
+ MediaBuffer **buffer,
+ const ReadOptions *options = NULL);
+
+ // MediaBufferObserver
+ virtual void signalBufferReturned(MediaBuffer *buffer);
+
+ // for AHandlerReflector
+ void onMessageReceived(const sp<AMessage> &msg);
+
+ // Set GraphicBufferSource stop time. GraphicBufferSource will stop
+ // after receiving a buffer with timestamp larger or equal than stopTimeUs.
+ // All the buffers with timestamp larger or equal to stopTimeUs will be
+ // discarded. stopTimeUs uses SYSTEM_TIME_MONOTONIC time base.
+ status_t setStopStimeUs(int64_t stopTimeUs);
+
+protected:
+ virtual ~MediaCodecSource();
+
+private:
+ struct Puller;
+
+ enum {
+ kWhatPullerNotify,
+ kWhatEncoderActivity,
+ kWhatStart,
+ kWhatStop,
+ kWhatPause,
+ kWhatSetInputBufferTimeOffset,
+ kWhatSetStopTimeOffset,
+ kWhatGetFirstSampleSystemTimeUs,
+ kWhatStopStalled,
+ };
+
+ MediaCodecSource(
+ const sp<ALooper> &looper,
+ const sp<AMessage> &outputFormat,
+ const sp<MediaSource> &source,
+ const sp<PersistentSurface> &persistentSurface,
+ uint32_t flags = 0);
+
+ status_t onStart(MetaData *params);
+
+ // Pause the source at pauseStartTimeUs. For non-surface input,
+ // buffers will be dropped immediately. For surface input, buffers
+ // with timestamp smaller than pauseStartTimeUs will still be encoded.
+ // Buffers with timestamp larger or queal to pauseStartTimeUs will be
+ // dropped. pauseStartTimeUs uses SYSTEM_TIME_MONOTONIC time base.
+ void onPause(int64_t pauseStartTimeUs);
+
+ status_t init();
+ status_t initEncoder();
+ void releaseEncoder();
+ status_t feedEncoderInputBuffers();
+ // Resume GraphicBufferSource at resumeStartTimeUs. Buffers
+ // from GraphicBufferSource with timestamp larger or equal to
+ // resumeStartTimeUs will be encoded. resumeStartTimeUs uses
+ // SYSTEM_TIME_MONOTONIC time base.
+ void resume(int64_t resumeStartTimeUs = -1ll);
+ void signalEOS(status_t err = ERROR_END_OF_STREAM);
+ bool reachedEOS();
+ status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg);
+
+ sp<ALooper> mLooper;
+ sp<ALooper> mCodecLooper;
+ sp<AHandlerReflector<MediaCodecSource> > mReflector;
+ sp<AMessage> mOutputFormat;
+ Mutexed<sp<MetaData>> mMeta;
+ sp<Puller> mPuller;
+ sp<MediaCodec> mEncoder;
+ uint32_t mFlags;
+ List<sp<AReplyToken>> mStopReplyIDQueue;
+ bool mIsVideo;
+ bool mStarted;
+ bool mStopping;
+ bool mDoMoreWorkPending;
+ bool mSetEncoderFormat;
+ int32_t mEncoderFormat;
+ int32_t mEncoderDataSpace;
+ sp<AMessage> mEncoderActivityNotify;
+ sp<IGraphicBufferProducer> mGraphicBufferProducer;
+ sp<PersistentSurface> mPersistentSurface;
+ List<MediaBuffer *> mInputBufferQueue;
+ List<size_t> mAvailEncoderInputIndices;
+ List<int64_t> mDecodingTimeQueue; // decoding time (us) for video
+ int64_t mInputBufferTimeOffsetUs;
+ int64_t mFirstSampleSystemTimeUs;
+ bool mPausePending;
+
+ // audio drift time
+ int64_t mFirstSampleTimeUs;
+ List<int64_t> mDriftTimeQueue;
+
+ struct Output {
+ Output();
+ List<MediaBuffer*> mBufferQueue;
+ bool mEncoderReachedEOS;
+ status_t mErrorCode;
+ Condition mCond;
+ };
+ Mutexed<Output> mOutput;
+
+ int32_t mGeneration;
+
+ DISALLOW_EVIL_CONSTRUCTORS(MediaCodecSource);
+};
+
+} // namespace android
+
+#endif /* MediaCodecSource_H_ */
diff --git a/media/libstagefright/include/MediaDefs.h b/media/libstagefright/include/MediaDefs.h
new file mode 100644
index 0000000..359fb69
--- /dev/null
+++ b/media/libstagefright/include/MediaDefs.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 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 STAGEFRIGHT_MEDIA_DEFS_H_
+#define STAGEFRIGHT_MEDIA_DEFS_H_
+
+/*
+ * Please, DO NOT USE!
+ *
+ * This file is here only for legacy reasons. Instead, include directly
+ * the header below.
+ *
+ */
+
+#include <media/MediaDefs.h>
+
+#endif // STAGEFRIGHT_MEDIA_DEFS_H_
diff --git a/media/libstagefright/include/MediaErrors.h b/media/libstagefright/include/MediaErrors.h
new file mode 100644
index 0000000..2e663ec
--- /dev/null
+++ b/media/libstagefright/include/MediaErrors.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2009 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 MEDIA_ERRORS_H_
+
+#define MEDIA_ERRORS_H_
+
+#include <utils/Errors.h>
+
+namespace android {
+
+enum {
+ // status_t map for errors in the media framework
+ // OK or NO_ERROR or 0 represents no error.
+
+ // See system/core/include/utils/Errors.h
+ // System standard errors from -1 through (possibly) -133
+ //
+ // Errors with special meanings and side effects.
+ // INVALID_OPERATION: Operation attempted in an illegal state (will try to signal to app).
+ // DEAD_OBJECT: Signal from CodecBase to MediaCodec that MediaServer has died.
+ // NAME_NOT_FOUND: Signal from CodecBase to MediaCodec that the component was not found.
+
+ // Media errors
+ MEDIA_ERROR_BASE = -1000,
+
+ ERROR_ALREADY_CONNECTED = MEDIA_ERROR_BASE,
+ ERROR_NOT_CONNECTED = MEDIA_ERROR_BASE - 1,
+ ERROR_UNKNOWN_HOST = MEDIA_ERROR_BASE - 2,
+ ERROR_CANNOT_CONNECT = MEDIA_ERROR_BASE - 3,
+ ERROR_IO = MEDIA_ERROR_BASE - 4,
+ ERROR_CONNECTION_LOST = MEDIA_ERROR_BASE - 5,
+ ERROR_MALFORMED = MEDIA_ERROR_BASE - 7,
+ ERROR_OUT_OF_RANGE = MEDIA_ERROR_BASE - 8,
+ ERROR_BUFFER_TOO_SMALL = MEDIA_ERROR_BASE - 9,
+ ERROR_UNSUPPORTED = MEDIA_ERROR_BASE - 10,
+ ERROR_END_OF_STREAM = MEDIA_ERROR_BASE - 11,
+
+ // Not technically an error.
+ INFO_FORMAT_CHANGED = MEDIA_ERROR_BASE - 12,
+ INFO_DISCONTINUITY = MEDIA_ERROR_BASE - 13,
+ INFO_OUTPUT_BUFFERS_CHANGED = MEDIA_ERROR_BASE - 14,
+
+ // The following constant values should be in sync with
+ // drm/drm_framework_common.h
+ DRM_ERROR_BASE = -2000,
+
+ ERROR_DRM_UNKNOWN = DRM_ERROR_BASE,
+ ERROR_DRM_NO_LICENSE = DRM_ERROR_BASE - 1,
+ ERROR_DRM_LICENSE_EXPIRED = DRM_ERROR_BASE - 2,
+ ERROR_DRM_SESSION_NOT_OPENED = DRM_ERROR_BASE - 3,
+ ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED = DRM_ERROR_BASE - 4,
+ ERROR_DRM_DECRYPT = DRM_ERROR_BASE - 5,
+ ERROR_DRM_CANNOT_HANDLE = DRM_ERROR_BASE - 6,
+ ERROR_DRM_TAMPER_DETECTED = DRM_ERROR_BASE - 7,
+ ERROR_DRM_NOT_PROVISIONED = DRM_ERROR_BASE - 8,
+ ERROR_DRM_DEVICE_REVOKED = DRM_ERROR_BASE - 9,
+ ERROR_DRM_RESOURCE_BUSY = DRM_ERROR_BASE - 10,
+ ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = DRM_ERROR_BASE - 11,
+ ERROR_DRM_LAST_USED_ERRORCODE = DRM_ERROR_BASE - 11,
+
+ ERROR_DRM_VENDOR_MAX = DRM_ERROR_BASE - 500,
+ ERROR_DRM_VENDOR_MIN = DRM_ERROR_BASE - 999,
+
+ // Heartbeat Error Codes
+ HEARTBEAT_ERROR_BASE = -3000,
+ ERROR_HEARTBEAT_TERMINATE_REQUESTED = HEARTBEAT_ERROR_BASE,
+
+ // NDK Error codes
+ // frameworks/av/include/ndk/NdkMediaError.h
+ // from -10000 (0xFFFFD8F0 - 0xFFFFD8EC)
+ // from -20000 (0xFFFFB1E0 - 0xFFFFB1D7)
+
+ // Codec errors are permitted from 0x80001000 through 0x9000FFFF
+ ERROR_CODEC_MAX = (signed)0x9000FFFF,
+ ERROR_CODEC_MIN = (signed)0x80001000,
+
+ // System unknown errors from 0x80000000 - 0x80000007 (INT32_MIN + 7)
+ // See system/core/include/utils/Errors.h
+};
+
+// action codes for MediaCodecs that tell the upper layer and application
+// the severity of any error.
+enum ActionCode {
+ ACTION_CODE_FATAL,
+ ACTION_CODE_TRANSIENT,
+ ACTION_CODE_RECOVERABLE,
+};
+
+// returns true if err is a recognized DRM error code
+static inline bool isCryptoError(status_t err) {
+ return (ERROR_DRM_LAST_USED_ERRORCODE <= err && err <= ERROR_DRM_UNKNOWN)
+ || (ERROR_DRM_VENDOR_MIN <= err && err <= ERROR_DRM_VENDOR_MAX);
+}
+
+} // namespace android
+
+#endif // MEDIA_ERRORS_H_
diff --git a/media/libstagefright/include/MediaExtractor.h b/media/libstagefright/include/MediaExtractor.h
new file mode 100644
index 0000000..073391f
--- /dev/null
+++ b/media/libstagefright/include/MediaExtractor.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2009 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 MEDIA_EXTRACTOR_H_
+
+#define MEDIA_EXTRACTOR_H_
+
+#include <media/IMediaExtractor.h>
+#include <media/IMediaSource.h>
+#include <media/MediaAnalyticsItem.h>
+
+namespace android {
+namespace media {
+class ICas;
+};
+using namespace media;
+class DataSource;
+struct MediaSource;
+class MetaData;
+
+class MediaExtractor : public BnMediaExtractor {
+public:
+ static sp<IMediaExtractor> Create(
+ const sp<DataSource> &source, const char *mime = NULL);
+ static sp<MediaExtractor> CreateFromService(
+ const sp<DataSource> &source, const char *mime = NULL);
+
+ virtual size_t countTracks() = 0;
+ virtual sp<IMediaSource> getTrack(size_t index) = 0;
+
+ enum GetTrackMetaDataFlags {
+ kIncludeExtensiveMetaData = 1
+ };
+ virtual sp<MetaData> getTrackMetaData(
+ size_t index, uint32_t flags = 0) = 0;
+
+ // Return container specific meta-data. The default implementation
+ // returns an empty metadata object.
+ virtual sp<MetaData> getMetaData();
+
+ status_t getMetrics(Parcel *reply);
+
+ enum Flags {
+ CAN_SEEK_BACKWARD = 1, // the "seek 10secs back button"
+ CAN_SEEK_FORWARD = 2, // the "seek 10secs forward button"
+ CAN_PAUSE = 4,
+ CAN_SEEK = 8, // the "seek bar"
+ };
+
+ // If subclasses do _not_ override this, the default is
+ // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
+ virtual uint32_t flags() const;
+
+ // for DRM
+ virtual char* getDrmTrackInfo(size_t /*trackID*/, int * /*len*/) {
+ return NULL;
+ }
+ virtual void setUID(uid_t /*uid*/) {
+ }
+ virtual status_t setMediaCas(const sp<ICas> &cas) override {
+ return INVALID_OPERATION;
+ }
+
+ virtual const char * name() { return "<unspecified>"; }
+
+protected:
+ MediaExtractor();
+ virtual ~MediaExtractor();
+
+ MediaAnalyticsItem *mAnalyticsItem;
+
+ virtual void populateMetrics();
+
+private:
+
+ typedef bool (*SnifferFunc)(
+ const sp<DataSource> &source, String8 *mimeType,
+ float *confidence, sp<AMessage> *meta);
+
+ static Mutex gSnifferMutex;
+ static List<SnifferFunc> gSniffers;
+ static bool gSniffersRegistered;
+
+ // The sniffer can optionally fill in "meta" with an AMessage containing
+ // a dictionary of values that helps the corresponding extractor initialize
+ // its state without duplicating effort already exerted by the sniffer.
+ static void RegisterSniffer_l(SnifferFunc func);
+
+ static bool sniff(const sp<DataSource> &source,
+ String8 *mimeType, float *confidence, sp<AMessage> *meta);
+
+ static void RegisterDefaultSniffers();
+
+ MediaExtractor(const MediaExtractor &);
+ MediaExtractor &operator=(const MediaExtractor &);
+};
+
+} // namespace android
+
+#endif // MEDIA_EXTRACTOR_H_
diff --git a/media/libstagefright/include/MediaFilter.h b/media/libstagefright/include/MediaFilter.h
new file mode 100644
index 0000000..0c10d11
--- /dev/null
+++ b/media/libstagefright/include/MediaFilter.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_FILTER_H_
+#define MEDIA_FILTER_H_
+
+#include <media/stagefright/CodecBase.h>
+
+namespace android {
+
+class ACodecBufferChannel;
+struct GraphicBufferListener;
+class MemoryDealer;
+struct SimpleFilter;
+
+struct MediaFilter : public CodecBase {
+ MediaFilter();
+
+ virtual std::shared_ptr<BufferChannelBase> getBufferChannel() override;
+ virtual void initiateAllocateComponent(const sp<AMessage> &msg);
+ virtual void initiateConfigureComponent(const sp<AMessage> &msg);
+ virtual void initiateCreateInputSurface();
+ virtual void initiateSetInputSurface(const sp<PersistentSurface> &surface);
+
+ virtual void initiateStart();
+ virtual void initiateShutdown(bool keepComponentAllocated = false);
+
+ virtual void signalFlush();
+ virtual void signalResume();
+
+ virtual void signalRequestIDRFrame();
+ virtual void signalSetParameters(const sp<AMessage> &msg);
+ virtual void signalEndOfInputStream();
+
+ virtual void onMessageReceived(const sp<AMessage> &msg);
+
+protected:
+ virtual ~MediaFilter();
+
+private:
+ struct BufferInfo {
+ enum Status {
+ OWNED_BY_US,
+ OWNED_BY_UPSTREAM,
+ };
+
+ IOMX::buffer_id mBufferID;
+ int32_t mGeneration;
+ int32_t mOutputFlags;
+ Status mStatus;
+
+ sp<MediaCodecBuffer> mData;
+ };
+
+ enum State {
+ UNINITIALIZED,
+ INITIALIZED,
+ CONFIGURED,
+ STARTED,
+ };
+
+ enum {
+ kWhatInputBufferFilled = 'inpF',
+ kWhatOutputBufferDrained = 'outD',
+ kWhatShutdown = 'shut',
+ kWhatFlush = 'flus',
+ kWhatResume = 'resm',
+ kWhatAllocateComponent = 'allo',
+ kWhatConfigureComponent = 'conf',
+ kWhatCreateInputSurface = 'cisf',
+ kWhatSignalEndOfInputStream = 'eois',
+ kWhatStart = 'star',
+ kWhatSetParameters = 'setP',
+ kWhatProcessBuffers = 'proc',
+ };
+
+ enum {
+ kPortIndexInput = 0,
+ kPortIndexOutput = 1
+ };
+
+ // member variables
+ AString mComponentName;
+ State mState;
+ status_t mInputEOSResult;
+ int32_t mWidth, mHeight;
+ int32_t mStride, mSliceHeight;
+ int32_t mColorFormatIn, mColorFormatOut;
+ size_t mMaxInputSize, mMaxOutputSize;
+ int32_t mGeneration;
+ sp<AMessage> mInputFormat;
+ sp<AMessage> mOutputFormat;
+
+ sp<MemoryDealer> mDealer[2];
+ Vector<BufferInfo> mBuffers[2];
+ Vector<BufferInfo*> mAvailableInputBuffers;
+ Vector<BufferInfo*> mAvailableOutputBuffers;
+ bool mPortEOS[2];
+
+ sp<SimpleFilter> mFilter;
+ sp<GraphicBufferListener> mGraphicBufferListener;
+
+ std::shared_ptr<ACodecBufferChannel> mBufferChannel;
+
+ // helper functions
+ void signalProcessBuffers();
+ void signalError(status_t error);
+
+ status_t allocateBuffersOnPort(OMX_U32 portIndex);
+ BufferInfo *findBufferByID(
+ uint32_t portIndex, IOMX::buffer_id bufferID,
+ ssize_t *index = NULL);
+ void postFillThisBuffer(BufferInfo *info);
+ void postDrainThisBuffer(BufferInfo *info);
+ void postEOS();
+ void requestFillEmptyInput();
+ void processBuffers();
+
+ void onAllocateComponent(const sp<AMessage> &msg);
+ void onConfigureComponent(const sp<AMessage> &msg);
+ void onStart();
+ void onInputBufferFilled(const sp<AMessage> &msg);
+ void onOutputBufferDrained(const sp<AMessage> &msg);
+ void onShutdown(const sp<AMessage> &msg);
+ void onFlush();
+ void onSetParameters(const sp<AMessage> &msg);
+ void onCreateInputSurface();
+ void onInputFrameAvailable();
+ void onSignalEndOfInputStream();
+
+ DISALLOW_EVIL_CONSTRUCTORS(MediaFilter);
+};
+
+} // namespace android
+
+#endif // MEDIA_FILTER_H_
diff --git a/media/libstagefright/include/MediaHTTP.h b/media/libstagefright/include/MediaHTTP.h
new file mode 100644
index 0000000..006d8d8
--- /dev/null
+++ b/media/libstagefright/include/MediaHTTP.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 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 MEDIA_HTTP_H_
+
+#define MEDIA_HTTP_H_
+
+#include <media/stagefright/foundation/AString.h>
+
+#include "include/HTTPBase.h"
+
+namespace android {
+
+struct IMediaHTTPConnection;
+
+struct MediaHTTP : public HTTPBase {
+ MediaHTTP(const sp<IMediaHTTPConnection> &conn);
+
+ virtual status_t connect(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers,
+ off64_t offset);
+
+ virtual void disconnect();
+
+ virtual status_t initCheck() const;
+
+ virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+
+ virtual status_t getSize(off64_t *size);
+
+ virtual uint32_t flags();
+
+ virtual status_t reconnectAtOffset(off64_t offset);
+
+protected:
+ virtual ~MediaHTTP();
+
+ virtual sp<DecryptHandle> DrmInitialization(const char* mime);
+ virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
+ virtual String8 getUri();
+ virtual String8 getMIMEType() const;
+
+private:
+ status_t mInitCheck;
+ sp<IMediaHTTPConnection> mHTTPConnection;
+
+ KeyedVector<String8, String8> mLastHeaders;
+ AString mLastURI;
+
+ bool mCachedSizeValid;
+ off64_t mCachedSize;
+
+ sp<DecryptHandle> mDecryptHandle;
+ DrmManagerClient *mDrmManagerClient;
+
+ void clearDRMState_l();
+
+ DISALLOW_EVIL_CONSTRUCTORS(MediaHTTP);
+};
+
+} // namespace android
+
+#endif // MEDIA_HTTP_H_
diff --git a/media/libstagefright/include/MediaMuxer.h b/media/libstagefright/include/MediaMuxer.h
new file mode 100644
index 0000000..63c3ca5
--- /dev/null
+++ b/media/libstagefright/include/MediaMuxer.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2013, 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 MEDIA_MUXER_H_
+#define MEDIA_MUXER_H_
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+
+#include "foundation/ABase.h"
+
+namespace android {
+
+struct ABuffer;
+struct AMessage;
+struct MediaAdapter;
+class MediaBuffer;
+struct MediaSource;
+class MetaData;
+struct MediaWriter;
+
+// MediaMuxer is used to mux multiple tracks into a video. Currently, we only
+// support a mp4 file as the output.
+// The expected calling order of the functions is:
+// Constructor -> addTrack+ -> start -> writeSampleData+ -> stop
+// If muxing operation need to be cancelled, the app is responsible for
+// deleting the output file after stop.
+struct MediaMuxer : public RefBase {
+public:
+ // Please update media/java/android/media/MediaMuxer.java if the
+ // OutputFormat is updated.
+ enum OutputFormat {
+ OUTPUT_FORMAT_MPEG_4 = 0,
+ OUTPUT_FORMAT_WEBM = 1,
+ OUTPUT_FORMAT_THREE_GPP = 2,
+ OUTPUT_FORMAT_LIST_END // must be last - used to validate format type
+ };
+
+ // Construct the muxer with the file descriptor. Note that the MediaMuxer
+ // will close this file at stop().
+ MediaMuxer(int fd, OutputFormat format);
+
+ virtual ~MediaMuxer();
+
+ /**
+ * Add a track with its format information. This should be
+ * called before start().
+ * @param format the track's format.
+ * @return the track's index or negative number if error.
+ */
+ ssize_t addTrack(const sp<AMessage> &format);
+
+ /**
+ * Start muxing. Make sure all the tracks have been added before
+ * calling this.
+ */
+ status_t start();
+
+ /**
+ * Set the orientation hint.
+ * @param degrees The rotation degrees. It has to be either 0,
+ * 90, 180 or 270.
+ * @return OK if no error.
+ */
+ status_t setOrientationHint(int degrees);
+
+ /**
+ * Set the location.
+ * @param latitude The latitude in degree x 1000. Its value must be in the range
+ * [-900000, 900000].
+ * @param longitude The longitude in degree x 1000. Its value must be in the range
+ * [-1800000, 1800000].
+ * @return OK if no error.
+ */
+ status_t setLocation(int latitude, int longitude);
+
+ /**
+ * Stop muxing.
+ * This method is a blocking call. Depending on how
+ * much data is bufferred internally, the time needed for stopping
+ * the muxer may be time consuming. UI thread is
+ * not recommended for launching this call.
+ * @return OK if no error.
+ */
+ status_t stop();
+
+ /**
+ * Send a sample buffer for muxing.
+ * The buffer can be reused once this method returns. Typically,
+ * this function won't be blocked for very long, and thus there
+ * is no need to use a separate thread calling this method to
+ * push a buffer.
+ * @param buffer the incoming sample buffer.
+ * @param trackIndex the buffer's track index number.
+ * @param timeUs the buffer's time stamp.
+ * @param flags the only supported flag for now is
+ * MediaCodec::BUFFER_FLAG_SYNCFRAME.
+ * @return OK if no error.
+ */
+ status_t writeSampleData(const sp<ABuffer> &buffer, size_t trackIndex,
+ int64_t timeUs, uint32_t flags) ;
+
+private:
+ const OutputFormat mFormat;
+ sp<MediaWriter> mWriter;
+ Vector< sp<MediaAdapter> > mTrackList; // Each track has its MediaAdapter.
+ sp<MetaData> mFileMeta; // Metadata for the whole file.
+
+ Mutex mMuxerLock;
+
+ enum State {
+ UNINITIALIZED,
+ INITIALIZED,
+ STARTED,
+ STOPPED
+ };
+ State mState;
+
+ DISALLOW_EVIL_CONSTRUCTORS(MediaMuxer);
+};
+
+} // namespace android
+
+#endif // MEDIA_MUXER_H_
+
diff --git a/media/libstagefright/include/MediaSource.h b/media/libstagefright/include/MediaSource.h
new file mode 100644
index 0000000..1bd3ed0
--- /dev/null
+++ b/media/libstagefright/include/MediaSource.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2009 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 MEDIA_SOURCE_H_
+
+#define MEDIA_SOURCE_H_
+
+#include <sys/types.h>
+
+#include <media/IMediaSource.h>
+#include <media/stagefright/MediaErrors.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class MediaBuffer;
+class MetaData;
+
+struct MediaSource : public BnMediaSource {
+ MediaSource();
+
+ // To be called before any other methods on this object, except
+ // getFormat().
+ virtual status_t start(MetaData *params = NULL) = 0;
+
+ // Any blocking read call returns immediately with a result of NO_INIT.
+ // It is an error to call any methods other than start after this call
+ // returns. Any buffers the object may be holding onto at the time of
+ // the stop() call are released.
+ // Also, it is imperative that any buffers output by this object and
+ // held onto by callers be released before a call to stop() !!!
+ virtual status_t stop() = 0;
+
+ // Returns the format of the data output by this media source.
+ virtual sp<MetaData> getFormat() = 0;
+
+ // Returns a new buffer of data. Call blocks until a
+ // buffer is available, an error is encountered of the end of the stream
+ // is reached.
+ // End of stream is signalled by a result of ERROR_END_OF_STREAM.
+ // A result of INFO_FORMAT_CHANGED indicates that the format of this
+ // MediaSource has changed mid-stream, the client can continue reading
+ // but should be prepared for buffers of the new configuration.
+ virtual status_t read(
+ MediaBuffer **buffer, const ReadOptions *options = NULL) = 0;
+
+ // Causes this source to suspend pulling data from its upstream source
+ // until a subsequent read-with-seek. This is currently not supported
+ // as such by any source. E.g. MediaCodecSource does not suspend its
+ // upstream source, and instead discard upstream data while paused.
+ virtual status_t pause() {
+ return ERROR_UNSUPPORTED;
+ }
+
+ // The consumer of this media source requests that the given buffers
+ // are to be returned exclusively in response to read calls.
+ // This will be called after a successful start() and before the
+ // first read() call.
+ // Callee assumes ownership of the buffers if no error is returned.
+ virtual status_t setBuffers(const Vector<MediaBuffer *> & /* buffers */) {
+ return ERROR_UNSUPPORTED;
+ }
+
+protected:
+ virtual ~MediaSource();
+
+private:
+ MediaSource(const MediaSource &);
+ MediaSource &operator=(const MediaSource &);
+};
+
+} // namespace android
+
+#endif // MEDIA_SOURCE_H_
diff --git a/media/libstagefright/include/MediaSync.h b/media/libstagefright/include/MediaSync.h
new file mode 100644
index 0000000..ef8cb23
--- /dev/null
+++ b/media/libstagefright/include/MediaSync.h
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2015 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 MEDIA_SYNC_H
+#define MEDIA_SYNC_H
+
+#include <gui/IConsumerListener.h>
+#include <gui/IProducerListener.h>
+
+#include <media/AudioResamplerPublic.h>
+#include <media/AVSyncSettings.h>
+#include <media/stagefright/foundation/AHandler.h>
+
+#include <utils/Condition.h>
+#include <utils/KeyedVector.h>
+#include <utils/Mutex.h>
+
+namespace android {
+
+class AudioTrack;
+class BufferItem;
+class Fence;
+class GraphicBuffer;
+class IGraphicBufferConsumer;
+class IGraphicBufferProducer;
+struct MediaClock;
+struct VideoFrameScheduler;
+
+// MediaSync manages media playback and its synchronization to a media clock
+// source. It can be also used for video-only playback.
+//
+// For video playback, it requires an output surface and provides an input
+// surface. It then controls the rendering of input buffers (buffer queued to
+// the input surface) on the output surface to happen at the appropriate time.
+//
+// For audio playback, it requires an audio track and takes updates of
+// information of rendered audio data to maintain media clock when audio track
+// serves as media clock source. (TODO: move audio rendering from JAVA to
+// native code).
+//
+// It can use the audio or video track as media clock source, as well as an
+// external clock. (TODO: actually support external clock as media clock
+// sources; use video track as media clock source for audio-and-video stream).
+//
+// In video-only mode, MediaSync will playback every video frame even though
+// a video frame arrives late based on its timestamp and last frame's.
+//
+// The client needs to configure surface (for output video rendering) and audio
+// track (for querying information of audio rendering) for MediaSync.
+//
+// Then the client needs to obtain a surface from MediaSync and render video
+// frames onto that surface. Internally, the MediaSync will receive those video
+// frames and render them onto the output surface at the appropriate time.
+//
+// The client needs to call updateQueuedAudioData() immediately after it writes
+// audio data to the audio track. Such information will be used to update media
+// clock.
+//
+class MediaSync : public AHandler {
+public:
+ // Create an instance of MediaSync.
+ static sp<MediaSync> create();
+
+ // Called when MediaSync is used to render video. It should be called
+ // before createInputSurface().
+ status_t setSurface(const sp<IGraphicBufferProducer> &output);
+
+ // Called when audio track is used as media clock source. It should be
+ // called before updateQueuedAudioData().
+ status_t setAudioTrack(const sp<AudioTrack> &audioTrack);
+
+ // Create a surface for client to render video frames. This is the surface
+ // on which the client should render video frames. Those video frames will
+ // be internally directed to output surface for rendering at appropriate
+ // time.
+ status_t createInputSurface(sp<IGraphicBufferProducer> *outBufferProducer);
+
+ // Update just-rendered audio data size and the presentation timestamp of
+ // the first frame of that audio data. It should be called immediately
+ // after the client write audio data into AudioTrack.
+ // This function assumes continous audio stream.
+ // TODO: support gap or backwards updates.
+ status_t updateQueuedAudioData(
+ size_t sizeInBytes, int64_t presentationTimeUs);
+
+ // Set the consumer name of the input queue.
+ void setName(const AString &name);
+
+ // Get the media clock used by the MediaSync so that the client can obtain
+ // corresponding media time or real time via
+ // MediaClock::getMediaTime() and MediaClock::getRealTimeFor().
+ sp<const MediaClock> getMediaClock();
+
+ // Flush mediasync
+ void flush();
+
+ // Set the video frame rate hint - this is used by the video FrameScheduler
+ status_t setVideoFrameRateHint(float rate);
+
+ // Get the video frame rate measurement from the FrameScheduler
+ // returns -1 if there is no measurement
+ float getVideoFrameRate();
+
+ // Set the sync settings parameters.
+ status_t setSyncSettings(const AVSyncSettings &syncSettings);
+
+ // Gets the sync settings parameters.
+ void getSyncSettings(AVSyncSettings *syncSettings /* nonnull */);
+
+ // Sets the playback rate using playback settings.
+ // This method can be called any time.
+ status_t setPlaybackSettings(const AudioPlaybackRate &rate);
+
+ // Gets the playback rate (playback settings parameters).
+ void getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */);
+
+ // Get the play time for pending audio frames in audio sink.
+ status_t getPlayTimeForPendingAudioFrames(int64_t *outTimeUs);
+
+protected:
+ virtual void onMessageReceived(const sp<AMessage> &msg);
+
+private:
+ enum {
+ kWhatDrainVideo = 'dVid',
+ };
+
+ // This is a thin wrapper class that lets us listen to
+ // IConsumerListener::onFrameAvailable from mInput.
+ class InputListener : public BnConsumerListener,
+ public IBinder::DeathRecipient {
+ public:
+ InputListener(const sp<MediaSync> &sync);
+ virtual ~InputListener();
+
+ // From IConsumerListener
+ virtual void onFrameAvailable(const BufferItem &item);
+
+ // From IConsumerListener
+ // We don't care about released buffers because we detach each buffer as
+ // soon as we acquire it. See the comment for onBufferReleased below for
+ // some clarifying notes about the name.
+ virtual void onBuffersReleased() {}
+
+ // From IConsumerListener
+ // We don't care about sideband streams, since we won't relay them.
+ virtual void onSidebandStreamChanged();
+
+ // From IBinder::DeathRecipient
+ virtual void binderDied(const wp<IBinder> &who);
+
+ private:
+ sp<MediaSync> mSync;
+ };
+
+ // This is a thin wrapper class that lets us listen to
+ // IProducerListener::onBufferReleased from mOutput.
+ class OutputListener : public BnProducerListener,
+ public IBinder::DeathRecipient {
+ public:
+ OutputListener(const sp<MediaSync> &sync, const sp<IGraphicBufferProducer> &output);
+ virtual ~OutputListener();
+
+ // From IProducerListener
+ virtual void onBufferReleased();
+
+ // From IBinder::DeathRecipient
+ virtual void binderDied(const wp<IBinder> &who);
+
+ private:
+ sp<MediaSync> mSync;
+ sp<IGraphicBufferProducer> mOutput;
+ };
+
+ // mIsAbandoned is set to true when the input or output dies.
+ // Once the MediaSync has been abandoned by one side, it will disconnect
+ // from the other side and not attempt to communicate with it further.
+ bool mIsAbandoned;
+
+ mutable Mutex mMutex;
+ Condition mReleaseCondition;
+ size_t mNumOutstandingBuffers;
+ sp<IGraphicBufferConsumer> mInput;
+ sp<IGraphicBufferProducer> mOutput;
+ int mUsageFlagsFromOutput;
+ uint32_t mMaxAcquiredBufferCount; // max acquired buffer count
+ bool mReturnPendingInputFrame; // set while we are pending before acquiring an input frame
+
+ sp<AudioTrack> mAudioTrack;
+ uint32_t mNativeSampleRateInHz;
+ int64_t mNumFramesWritten;
+ bool mHasAudio;
+
+ int64_t mNextBufferItemMediaUs;
+ List<BufferItem> mBufferItems;
+ sp<VideoFrameScheduler> mFrameScheduler;
+
+ // Keep track of buffers received from |mInput|. This is needed because
+ // it's possible the consumer of |mOutput| could return a different
+ // GraphicBuffer::handle (e.g., due to passing buffers through IPC),
+ // and that could cause problem if the producer of |mInput| only
+ // supports pre-registered buffers.
+ KeyedVector<uint64_t, sp<GraphicBuffer> > mBuffersFromInput;
+
+ // Keep track of buffers sent to |mOutput|. When a new output surface comes
+ // in, those buffers will be returned to input and old output surface will
+ // be disconnected immediately.
+ KeyedVector<uint64_t, sp<GraphicBuffer> > mBuffersSentToOutput;
+
+ sp<ALooper> mLooper;
+ float mPlaybackRate;
+
+ AudioPlaybackRate mPlaybackSettings;
+ AVSyncSettings mSyncSettings;
+
+ sp<MediaClock> mMediaClock;
+
+ MediaSync();
+
+ // Must be accessed through RefBase
+ virtual ~MediaSync();
+
+ int64_t getRealTime(int64_t mediaTimeUs, int64_t nowUs);
+ int64_t getDurationIfPlayedAtNativeSampleRate_l(int64_t numFrames);
+ int64_t getPlayedOutAudioDurationMedia_l(int64_t nowUs);
+
+ void onDrainVideo_l();
+
+ // This implements the onFrameAvailable callback from IConsumerListener.
+ // It gets called from an InputListener.
+ // During this callback, we detach the buffer from the input, and queue
+ // it for rendering on the output. This call can block if there are too
+ // many outstanding buffers. If it blocks, it will resume when
+ // onBufferReleasedByOutput releases a buffer back to the input.
+ void onFrameAvailableFromInput();
+
+ // Send |bufferItem| to the output for rendering.
+ void renderOneBufferItem_l(const BufferItem &bufferItem);
+
+ // This implements the onBufferReleased callback from IProducerListener.
+ // It gets called from an OutputListener.
+ // During this callback, we detach the buffer from the output, and release
+ // it to the input. A blocked onFrameAvailable call will be allowed to proceed.
+ void onBufferReleasedByOutput(sp<IGraphicBufferProducer> &output);
+
+ // Return |buffer| back to the input.
+ void returnBufferToInput_l(const sp<GraphicBuffer> &buffer, const sp<Fence> &fence);
+
+ // When this is called, the MediaSync disconnects from (i.e., abandons) its
+ // input or output, and signals any waiting onFrameAvailable calls to wake
+ // up. This must be called with mMutex locked.
+ void onAbandoned_l(bool isInput);
+
+ // Set the playback in a desired speed.
+ // This method can be called any time.
+ // |rate| is the ratio between desired speed and the normal one, and should
+ // be non-negative. The meaning of rate values:
+ // 1.0 -- normal playback
+ // 0.0 -- stop or pause
+ // larger than 1.0 -- faster than normal speed
+ // between 0.0 and 1.0 -- slower than normal speed
+ void updatePlaybackRate_l(float rate);
+
+ // apply new sync settings
+ void resync_l();
+
+ // apply playback settings only - without resyncing or updating playback rate
+ status_t setPlaybackSettings_l(const AudioPlaybackRate &rate);
+
+ // helper.
+ bool isPlaying() { return mPlaybackRate != 0.0; }
+
+ DISALLOW_EVIL_CONSTRUCTORS(MediaSync);
+};
+
+} // namespace android
+
+#endif
diff --git a/media/libstagefright/include/MediaWriter.h b/media/libstagefright/include/MediaWriter.h
new file mode 100644
index 0000000..9c30ffa
--- /dev/null
+++ b/media/libstagefright/include/MediaWriter.h
@@ -0,0 +1,73 @@
+/*
+ * 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 MEDIA_WRITER_H_
+
+#define MEDIA_WRITER_H_
+
+#include <utils/RefBase.h>
+#include <media/IMediaRecorderClient.h>
+#include <media/IMediaSource.h>
+
+namespace android {
+
+class MetaData;
+
+struct MediaWriter : public RefBase {
+ MediaWriter()
+ : mMaxFileSizeLimitBytes(0),
+ mMaxFileDurationLimitUs(0) {
+ }
+
+ virtual status_t addSource(const sp<IMediaSource> &source) = 0;
+ virtual bool reachedEOS() = 0;
+ virtual status_t start(MetaData *params = NULL) = 0;
+ virtual status_t stop() = 0;
+ virtual status_t pause() = 0;
+
+ virtual void setMaxFileSize(int64_t bytes) { mMaxFileSizeLimitBytes = bytes; }
+ virtual void setMaxFileDuration(int64_t durationUs) { mMaxFileDurationLimitUs = durationUs; }
+ virtual void setListener(const sp<IMediaRecorderClient>& listener) {
+ mListener = listener;
+ }
+
+ virtual status_t dump(int /*fd*/, const Vector<String16>& /*args*/) {
+ return OK;
+ }
+
+ virtual void setStartTimeOffsetMs(int /*ms*/) {}
+ virtual int32_t getStartTimeOffsetMs() const { return 0; }
+ virtual status_t setNextFd(int fd) { return INVALID_OPERATION; }
+
+protected:
+ virtual ~MediaWriter() {}
+ int64_t mMaxFileSizeLimitBytes;
+ int64_t mMaxFileDurationLimitUs;
+ sp<IMediaRecorderClient> 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 &);
+};
+
+} // namespace android
+
+#endif // MEDIA_WRITER_H_
diff --git a/media/libstagefright/include/MetaData.h b/media/libstagefright/include/MetaData.h
new file mode 100644
index 0000000..6ba7b32
--- /dev/null
+++ b/media/libstagefright/include/MetaData.h
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2009 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 META_DATA_H_
+
+#define META_DATA_H_
+
+#include <sys/types.h>
+
+#include <stdint.h>
+
+#include <binder/Parcel.h>
+#include <utils/RefBase.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+namespace android {
+
+// The following keys map to int32_t data unless indicated otherwise.
+enum {
+ kKeyMIMEType = 'mime', // cstring
+ kKeyWidth = 'widt', // int32_t, image pixel
+ kKeyHeight = 'heig', // int32_t, image pixel
+ kKeyDisplayWidth = 'dWid', // int32_t, display/presentation
+ kKeyDisplayHeight = 'dHgt', // int32_t, display/presentation
+ kKeySARWidth = 'sarW', // int32_t, sampleAspectRatio width
+ kKeySARHeight = 'sarH', // int32_t, sampleAspectRatio height
+
+ // a rectangle, if absent assumed to be (0, 0, width - 1, height - 1)
+ kKeyCropRect = 'crop',
+
+ kKeyRotation = 'rotA', // int32_t (angle in degrees)
+ kKeyIFramesInterval = 'ifiv', // int32_t
+ kKeyStride = 'strd', // int32_t
+ kKeySliceHeight = 'slht', // int32_t
+ kKeyChannelCount = '#chn', // int32_t
+ kKeyChannelMask = 'chnm', // int32_t
+ kKeySampleRate = 'srte', // int32_t (audio sampling rate Hz)
+ kKeyPcmEncoding = 'PCMe', // int32_t (audio encoding enum)
+ kKeyFrameRate = 'frmR', // int32_t (video frame rate fps)
+ kKeyBitRate = 'brte', // int32_t (bps)
+ kKeyMaxBitRate = 'mxBr', // int32_t (bps)
+ kKeyStreamHeader = 'stHd', // raw data
+ kKeyESDS = 'esds', // raw data
+ kKeyAACProfile = 'aacp', // int32_t
+ kKeyAVCC = 'avcc', // raw data
+ kKeyHVCC = 'hvcc', // raw data
+ kKeyD263 = 'd263', // raw data
+ kKeyVorbisInfo = 'vinf', // raw data
+ kKeyVorbisBooks = 'vboo', // raw data
+ kKeyOpusHeader = 'ohdr', // raw data
+ kKeyOpusCodecDelay = 'ocod', // uint64_t (codec delay in ns)
+ kKeyOpusSeekPreRoll = 'ospr', // uint64_t (seek preroll in ns)
+ kKeyVp9CodecPrivate = 'vp9p', // raw data (vp9 csd information)
+ kKeyWantsNALFragments = 'NALf',
+ kKeyIsSyncFrame = 'sync', // int32_t (bool)
+ kKeyIsCodecConfig = 'conf', // int32_t (bool)
+ kKeyTime = 'time', // int64_t (usecs)
+ kKeyDecodingTime = 'decT', // int64_t (decoding timestamp in usecs)
+ kKeyNTPTime = 'ntpT', // uint64_t (ntp-timestamp)
+ kKeyTargetTime = 'tarT', // int64_t (usecs)
+ kKeyDriftTime = 'dftT', // int64_t (usecs)
+ kKeyAnchorTime = 'ancT', // int64_t (usecs)
+ kKeyDuration = 'dura', // int64_t (usecs)
+ kKeyPixelFormat = 'pixf', // int32_t
+ kKeyColorFormat = 'colf', // int32_t
+ kKeyColorSpace = 'cols', // int32_t
+ kKeyPlatformPrivate = 'priv', // pointer
+ kKeyDecoderComponent = 'decC', // cstring
+ kKeyBufferID = 'bfID',
+ kKeyMaxInputSize = 'inpS',
+ kKeyMaxWidth = 'maxW',
+ kKeyMaxHeight = 'maxH',
+ kKeyThumbnailTime = 'thbT', // int64_t (usecs)
+ kKeyTrackID = 'trID',
+ kKeyIsDRM = 'idrm', // int32_t (bool)
+ kKeyEncoderDelay = 'encd', // int32_t (frames)
+ kKeyEncoderPadding = 'encp', // int32_t (frames)
+
+ kKeyAlbum = 'albu', // cstring
+ kKeyArtist = 'arti', // cstring
+ kKeyAlbumArtist = 'aart', // cstring
+ kKeyComposer = 'comp', // cstring
+ kKeyGenre = 'genr', // cstring
+ kKeyTitle = 'titl', // cstring
+ kKeyYear = 'year', // cstring
+ kKeyAlbumArt = 'albA', // compressed image data
+ kKeyAlbumArtMIME = 'alAM', // cstring
+ kKeyAuthor = 'auth', // cstring
+ kKeyCDTrackNumber = 'cdtr', // cstring
+ kKeyDiscNumber = 'dnum', // cstring
+ kKeyDate = 'date', // cstring
+ kKeyWriter = 'writ', // cstring
+ kKeyCompilation = 'cpil', // cstring
+ kKeyLocation = 'loc ', // cstring
+ kKeyTimeScale = 'tmsl', // int32_t
+ kKeyCaptureFramerate = 'capF', // float (capture fps)
+
+ // video profile and level
+ kKeyVideoProfile = 'vprf', // int32_t
+ kKeyVideoLevel = 'vlev', // int32_t
+
+ // Set this key to enable authoring files in 64-bit offset
+ kKey64BitFileOffset = 'fobt', // int32_t (bool)
+ kKey2ByteNalLength = '2NAL', // int32_t (bool)
+
+ // Identify the file output format for authoring
+ // Please see <media/mediarecorder.h> for the supported
+ // file output formats.
+ kKeyFileType = 'ftyp', // int32_t
+
+ // Track authoring progress status
+ // kKeyTrackTimeStatus is used to track progress in elapsed time
+ kKeyTrackTimeStatus = 'tktm', // int64_t
+
+ kKeyRealTimeRecording = 'rtrc', // bool (int32_t)
+ kKeyNumBuffers = 'nbbf', // int32_t
+
+ // Ogg files can be tagged to be automatically looping...
+ kKeyAutoLoop = 'autL', // bool (int32_t)
+
+ kKeyValidSamples = 'valD', // int32_t
+
+ kKeyIsUnreadable = 'unre', // bool (int32_t)
+
+ // An indication that a video buffer has been rendered.
+ kKeyRendered = 'rend', // bool (int32_t)
+
+ // The language code for this media
+ kKeyMediaLanguage = 'lang', // cstring
+
+ // To store the timed text format data
+ kKeyTextFormatData = 'text', // raw data
+
+ kKeyRequiresSecureBuffers = 'secu', // bool (int32_t)
+
+ kKeyIsADTS = 'adts', // bool (int32_t)
+ kKeyAACAOT = 'aaot', // int32_t
+
+ // If a MediaBuffer's data represents (at least partially) encrypted
+ // data, the following fields aid in decryption.
+ // The data can be thought of as pairs of plain and encrypted data
+ // fragments, i.e. plain and encrypted data alternate.
+ // The first fragment is by convention plain data (if that's not the
+ // case, simply specify plain fragment size of 0).
+ // kKeyEncryptedSizes and kKeyPlainSizes each map to an array of
+ // size_t values. The sum total of all size_t values of both arrays
+ // must equal the amount of data (i.e. MediaBuffer's range_length()).
+ // If both arrays are present, they must be of the same size.
+ // If only encrypted sizes are present it is assumed that all
+ // plain sizes are 0, i.e. all fragments are encrypted.
+ // To programmatically set these array, use the MetaData::setData API, i.e.
+ // const size_t encSizes[];
+ // meta->setData(
+ // kKeyEncryptedSizes, 0 /* type */, encSizes, sizeof(encSizes));
+ // A plain sizes array by itself makes no sense.
+ kKeyEncryptedSizes = 'encr', // size_t[]
+ kKeyPlainSizes = 'plai', // size_t[]
+ kKeyCryptoKey = 'cryK', // uint8_t[16]
+ kKeyCryptoIV = 'cryI', // uint8_t[16]
+ kKeyCryptoMode = 'cryM', // int32_t
+
+ kKeyCryptoDefaultIVSize = 'cryS', // int32_t
+
+ kKeyPssh = 'pssh', // raw data
+
+ // Please see MediaFormat.KEY_IS_AUTOSELECT.
+ kKeyTrackIsAutoselect = 'auto', // bool (int32_t)
+ // Please see MediaFormat.KEY_IS_DEFAULT.
+ kKeyTrackIsDefault = 'dflt', // bool (int32_t)
+ // Similar to MediaFormat.KEY_IS_FORCED_SUBTITLE but pertains to av tracks as well.
+ kKeyTrackIsForced = 'frcd', // bool (int32_t)
+
+ // H264 supplemental enhancement information offsets/sizes
+ kKeySEI = 'sei ', // raw data
+
+ // MPEG user data offsets
+ kKeyMpegUserData = 'mpud', // size_t[]
+
+ // Size of NALU length in mkv/mp4
+ kKeyNalLengthSize = 'nals', // int32_t
+
+ // HDR related
+ kKeyHdrStaticInfo = 'hdrS', // HDRStaticInfo
+
+ // color aspects
+ kKeyColorRange = 'cRng', // int32_t, color range, value defined by ColorAspects.Range
+ kKeyColorPrimaries = 'cPrm', // int32_t,
+ // color Primaries, value defined by ColorAspects.Primaries
+ kKeyTransferFunction = 'tFun', // int32_t,
+ // transfer Function, value defined by ColorAspects.Transfer.
+ kKeyColorMatrix = 'cMtx', // int32_t,
+ // color Matrix, value defined by ColorAspects.MatrixCoeffs.
+ kKeyTemporalLayerId = 'iLyr', // int32_t, temporal layer-id. 0-based (0 => base layer)
+ kKeyTemporalLayerCount = 'cLyr', // int32_t, number of temporal layers encoded
+};
+
+enum {
+ kTypeESDS = 'esds',
+ kTypeAVCC = 'avcc',
+ kTypeHVCC = 'hvcc',
+ kTypeD263 = 'd263',
+};
+
+class MetaData : public RefBase {
+public:
+ MetaData();
+ MetaData(const MetaData &from);
+
+ enum Type {
+ TYPE_NONE = 'none',
+ TYPE_C_STRING = 'cstr',
+ TYPE_INT32 = 'in32',
+ TYPE_INT64 = 'in64',
+ TYPE_FLOAT = 'floa',
+ TYPE_POINTER = 'ptr ',
+ TYPE_RECT = 'rect',
+ };
+
+ void clear();
+ bool remove(uint32_t key);
+
+ bool setCString(uint32_t key, const char *value);
+ bool setInt32(uint32_t key, int32_t value);
+ bool setInt64(uint32_t key, int64_t value);
+ bool setFloat(uint32_t key, float value);
+ bool setPointer(uint32_t key, void *value);
+
+ bool setRect(
+ uint32_t key,
+ int32_t left, int32_t top,
+ int32_t right, int32_t bottom);
+
+ bool findCString(uint32_t key, const char **value);
+ bool findInt32(uint32_t key, int32_t *value);
+ bool findInt64(uint32_t key, int64_t *value);
+ bool findFloat(uint32_t key, float *value);
+ bool findPointer(uint32_t key, void **value);
+
+ bool findRect(
+ uint32_t key,
+ int32_t *left, int32_t *top,
+ int32_t *right, int32_t *bottom);
+
+ bool setData(uint32_t key, uint32_t type, const void *data, size_t size);
+
+ bool findData(uint32_t key, uint32_t *type,
+ const void **data, size_t *size) const;
+
+ bool hasData(uint32_t key) const;
+
+ String8 toString() const;
+ void dumpToLog() const;
+
+ status_t writeToParcel(Parcel &parcel);
+ status_t updateFromParcel(const Parcel &parcel);
+ static sp<MetaData> createFromParcel(const Parcel &parcel);
+
+protected:
+ virtual ~MetaData();
+
+private:
+ struct typed_data {
+ typed_data();
+ ~typed_data();
+
+ typed_data(const MetaData::typed_data &);
+ typed_data &operator=(const MetaData::typed_data &);
+
+ void clear();
+ void setData(uint32_t type, const void *data, size_t size);
+ void getData(uint32_t *type, const void **data, size_t *size) const;
+ // may include hexdump of binary data if verbose=true
+ String8 asString(bool verbose) const;
+
+ private:
+ uint32_t mType;
+ size_t mSize;
+
+ union {
+ void *ext_data;
+ float reservoir;
+ } u;
+
+ bool usesReservoir() const {
+ return mSize <= sizeof(u.reservoir);
+ }
+
+ void *allocateStorage(size_t size);
+ void freeStorage();
+
+ void *storage() {
+ return usesReservoir() ? &u.reservoir : u.ext_data;
+ }
+
+ const void *storage() const {
+ return usesReservoir() ? &u.reservoir : u.ext_data;
+ }
+ };
+
+ struct Rect {
+ int32_t mLeft, mTop, mRight, mBottom;
+ };
+
+ KeyedVector<uint32_t, typed_data> mItems;
+
+ // MetaData &operator=(const MetaData &);
+};
+
+} // namespace android
+
+#endif // META_DATA_H_
diff --git a/media/libstagefright/include/NuMediaExtractor.h b/media/libstagefright/include/NuMediaExtractor.h
new file mode 100644
index 0000000..3e3cc17
--- /dev/null
+++ b/media/libstagefright/include/NuMediaExtractor.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2012, 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 NU_MEDIA_EXTRACTOR_H_
+#define NU_MEDIA_EXTRACTOR_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/IMediaExtractor.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/threads.h>
+#include <utils/Vector.h>
+
+namespace android {
+namespace media {
+class ICas;
+}
+using namespace media;
+
+struct ABuffer;
+struct AMessage;
+class DataSource;
+struct IMediaHTTPService;
+class MediaBuffer;
+class MediaExtractor;
+struct MediaSource;
+class MetaData;
+
+struct NuMediaExtractor : public RefBase {
+ enum SampleFlags {
+ SAMPLE_FLAG_SYNC = 1,
+ SAMPLE_FLAG_ENCRYPTED = 2,
+ };
+
+ // identical to IMediaExtractor::GetTrackMetaDataFlags
+ enum GetTrackFormatFlags {
+ kIncludeExtensiveMetaData = 1, // reads sample table and possibly stream headers
+ };
+
+ NuMediaExtractor();
+
+ status_t setDataSource(
+ const sp<IMediaHTTPService> &httpService,
+ const char *path,
+ const KeyedVector<String8, String8> *headers = NULL);
+
+ status_t setDataSource(int fd, off64_t offset, off64_t size);
+
+ status_t setDataSource(const sp<DataSource> &datasource);
+
+ status_t setMediaCas(const sp<ICas> &cas);
+
+ size_t countTracks() const;
+ status_t getTrackFormat(size_t index, sp<AMessage> *format, uint32_t flags = 0) const;
+
+ status_t getFileFormat(sp<AMessage> *format) const;
+
+ status_t selectTrack(size_t index);
+ status_t unselectTrack(size_t index);
+
+ status_t seekTo(
+ int64_t timeUs,
+ MediaSource::ReadOptions::SeekMode mode =
+ MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
+
+ status_t advance();
+ status_t readSampleData(const sp<ABuffer> &buffer);
+ status_t getSampleTrackIndex(size_t *trackIndex);
+ status_t getSampleTime(int64_t *sampleTimeUs);
+ status_t getSampleMeta(sp<MetaData> *sampleMeta);
+ status_t getMetrics(Parcel *reply);
+
+ bool getCachedDuration(int64_t *durationUs, bool *eos) const;
+
+protected:
+ virtual ~NuMediaExtractor();
+
+private:
+ enum TrackFlags {
+ kIsVorbis = 1,
+ };
+
+ enum {
+ kMaxTrackCount = 16384,
+ };
+
+ struct TrackInfo {
+ sp<IMediaSource> mSource;
+ size_t mTrackIndex;
+ status_t mFinalResult;
+ MediaBuffer *mSample;
+ int64_t mSampleTimeUs;
+
+ uint32_t mTrackFlags; // bitmask of "TrackFlags"
+ };
+
+ mutable Mutex mLock;
+
+ sp<DataSource> mDataSource;
+
+ sp<IMediaExtractor> mImpl;
+ sp<ICas> mCas;
+
+ Vector<TrackInfo> mSelectedTracks;
+ int64_t mTotalBitrate; // in bits/sec
+ int64_t mDurationUs;
+
+ ssize_t fetchTrackSamples(
+ int64_t seekTimeUs = -1ll,
+ MediaSource::ReadOptions::SeekMode mode =
+ MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
+
+ void releaseTrackSamples();
+
+ bool getTotalBitrate(int64_t *bitRate) const;
+ status_t updateDurationAndBitrate();
+ status_t appendVorbisNumPageSamples(TrackInfo *info, const sp<ABuffer> &buffer);
+
+ DISALLOW_EVIL_CONSTRUCTORS(NuMediaExtractor);
+};
+
+} // namespace android
+
+#endif // NU_MEDIA_EXTRACTOR_H_
+
diff --git a/media/libstagefright/include/OMXClient.h b/media/libstagefright/include/OMXClient.h
new file mode 100644
index 0000000..315f19b
--- /dev/null
+++ b/media/libstagefright/include/OMXClient.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009 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 OMX_CLIENT_H_
+
+#define OMX_CLIENT_H_
+
+namespace android {
+
+class IOMX;
+
+class OMXClient {
+public:
+ OMXClient();
+
+ status_t connect(bool* trebleFlag = nullptr);
+ status_t connectLegacy();
+ status_t connectTreble();
+ void disconnect();
+
+ sp<IOMX> interface() {
+ return mOMX;
+ }
+
+private:
+ sp<IOMX> mOMX;
+
+ OMXClient(const OMXClient &);
+ OMXClient &operator=(const OMXClient &);
+};
+
+} // namespace android
+
+#endif // OMX_CLIENT_H_
diff --git a/media/libstagefright/include/PersistentSurface.h b/media/libstagefright/include/PersistentSurface.h
new file mode 100644
index 0000000..d8b75a2
--- /dev/null
+++ b/media/libstagefright/include/PersistentSurface.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2015 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 PERSISTENT_SURFACE_H_
+
+#define PERSISTENT_SURFACE_H_
+
+#include <gui/IGraphicBufferProducer.h>
+#include <android/IGraphicBufferSource.h>
+#include <media/stagefright/foundation/ABase.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+struct PersistentSurface : public RefBase {
+ PersistentSurface() {}
+
+ PersistentSurface(
+ const sp<IGraphicBufferProducer>& bufferProducer,
+ const sp<IGraphicBufferSource>& bufferSource) :
+ mBufferProducer(bufferProducer),
+ mBufferSource(bufferSource) { }
+
+ sp<IGraphicBufferProducer> getBufferProducer() const {
+ return mBufferProducer;
+ }
+
+ sp<IGraphicBufferSource> getBufferSource() const {
+ return mBufferSource;
+ }
+
+ status_t writeToParcel(Parcel *parcel) const {
+ parcel->writeStrongBinder(IInterface::asBinder(mBufferProducer));
+ parcel->writeStrongBinder(IInterface::asBinder(mBufferSource));
+ return NO_ERROR;
+ }
+
+ status_t readFromParcel(const Parcel *parcel) {
+ mBufferProducer = interface_cast<IGraphicBufferProducer>(
+ parcel->readStrongBinder());
+ mBufferSource = interface_cast<IGraphicBufferSource>(
+ parcel->readStrongBinder());
+ return NO_ERROR;
+ }
+
+private:
+ sp<IGraphicBufferProducer> mBufferProducer;
+ sp<IGraphicBufferSource> mBufferSource;
+
+ DISALLOW_EVIL_CONSTRUCTORS(PersistentSurface);
+};
+
+} // namespace android
+
+#endif // PERSISTENT_SURFACE_H_
diff --git a/media/libstagefright/include/ProcessInfo.h b/media/libstagefright/include/ProcessInfo.h
new file mode 100644
index 0000000..0be1a52
--- /dev/null
+++ b/media/libstagefright/include/ProcessInfo.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 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 PROCESS_INFO_H_
+
+#define PROCESS_INFO_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/ProcessInfoInterface.h>
+
+namespace android {
+
+struct ProcessInfo : public ProcessInfoInterface {
+ ProcessInfo();
+
+ virtual bool getPriority(int pid, int* priority);
+ virtual bool isValidPid(int pid);
+
+protected:
+ virtual ~ProcessInfo();
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(ProcessInfo);
+};
+
+} // namespace android
+
+#endif // PROCESS_INFO_H_
diff --git a/media/libstagefright/include/ProcessInfoInterface.h b/media/libstagefright/include/ProcessInfoInterface.h
new file mode 100644
index 0000000..b39112a
--- /dev/null
+++ b/media/libstagefright/include/ProcessInfoInterface.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 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 PROCESS_INFO_INTERFACE_H_
+#define PROCESS_INFO_INTERFACE_H_
+
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct ProcessInfoInterface : public RefBase {
+ virtual bool getPriority(int pid, int* priority) = 0;
+ virtual bool isValidPid(int pid) = 0;
+
+protected:
+ virtual ~ProcessInfoInterface() {}
+};
+
+} // namespace android
+
+#endif // PROCESS_INFO_INTERFACE_H_
diff --git a/media/libstagefright/include/RenderScriptWrapper.h b/media/libstagefright/include/RenderScriptWrapper.h
new file mode 100644
index 0000000..b42649e
--- /dev/null
+++ b/media/libstagefright/include/RenderScriptWrapper.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RENDERSCRIPT_WRAPPER_H_
+#define RENDERSCRIPT_WRAPPER_H_
+
+#include <RenderScript.h>
+
+namespace android {
+
+struct RenderScriptWrapper : public RefBase {
+public:
+ struct RSFilterCallback : public RefBase {
+ public:
+ // called by RSFilter to process each input buffer
+ virtual status_t processBuffers(
+ RSC::Allocation* inBuffer,
+ RSC::Allocation* outBuffer) = 0;
+
+ virtual status_t handleSetParameters(const sp<AMessage> &msg) = 0;
+ };
+
+ sp<RSFilterCallback> mCallback;
+ RSC::sp<RSC::RS> mContext;
+};
+
+} // namespace android
+
+#endif // RENDERSCRIPT_WRAPPER_H_
diff --git a/media/libstagefright/include/SimpleDecodingSource.h b/media/libstagefright/include/SimpleDecodingSource.h
new file mode 100644
index 0000000..e6aee6a
--- /dev/null
+++ b/media/libstagefright/include/SimpleDecodingSource.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2016, 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 SIMPLE_DECODING_SOURCE_H_
+#define SIMPLE_DECODING_SOURCE_H_
+
+#include <system/window.h>
+
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/foundation/AString.h>
+#include <media/stagefright/foundation/Mutexed.h>
+
+#include <utils/Condition.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+struct ALooper;
+struct AMessage;
+class MediaBuffer;
+struct MediaCodec;
+class MetaData;
+
+class SimpleDecodingSource : public MediaSource {
+public:
+ // Creates a MediaSource that uses MediaCodec to decode a compressed input |source|.
+ // The selected codec can be influenced using |flags|. This source only supports the
+ // kPreferGoogleCodec and kNonGoogleCodecsOnly |flags| - MediaCodecList.
+ // You can pass in a target |nativeWindow| to render video directly onto a surface. In this
+ // case the source will return empty buffers.
+ // This source cannot be restarted (hence the name "Simple"), all reads are blocking, and
+ // does not support secure input or pausing.
+ // if |desiredCodec| is given, use this specific codec.
+ static sp<SimpleDecodingSource> Create(
+ const sp<IMediaSource> &source, uint32_t flags = 0,
+ const sp<ANativeWindow> &nativeWindow = NULL,
+ const char *desiredCodec = NULL);
+
+ virtual ~SimpleDecodingSource();
+
+ // starts this source (and it's underlying source). |params| is ignored.
+ virtual status_t start(MetaData *params = NULL);
+
+ // stops this source (and it's underlying source).
+ virtual status_t stop();
+
+ // returns the output format of this source.
+ virtual sp<MetaData> getFormat();
+
+ // reads from the source. This call always blocks.
+ virtual status_t read(MediaBuffer **buffer, const ReadOptions *options);
+
+ // unsupported methods
+ virtual status_t pause() { return INVALID_OPERATION; }
+ virtual status_t setBuffers(const Vector<MediaBuffer *> &) { return INVALID_OPERATION; }
+
+private:
+ // Construct this using a codec, source and looper.
+ SimpleDecodingSource(
+ const sp<MediaCodec> &codec, const sp<IMediaSource> &source, const sp<ALooper> &looper,
+ bool usingSurface, bool isVorbis, const sp<AMessage> &format);
+
+ sp<MediaCodec> mCodec;
+ sp<IMediaSource> mSource;
+ sp<ALooper> mLooper;
+ bool mUsingSurface;
+ bool mIsVorbis;
+ enum State {
+ INIT,
+ STARTED,
+ STOPPING,
+ STOPPED,
+ ERROR,
+ };
+ AString mComponentName;
+
+ struct ProtectedState {
+ ProtectedState(const sp<AMessage> &format);
+ bool mReading;
+ Condition mReadCondition;
+
+ sp<AMessage> mFormat;
+ State mState;
+ bool mQueuedInputEOS;
+ bool mGotOutputEOS;
+ };
+ Mutexed<ProtectedState> mProtectedState;
+
+ // do the actual reading
+ status_t doRead(
+ Mutexed<ProtectedState>::Locked &me, MediaBuffer **buffer, const ReadOptions *options);
+};
+
+} // namespace android
+
+#endif
diff --git a/media/libstagefright/include/SkipCutBuffer.h b/media/libstagefright/include/SkipCutBuffer.h
new file mode 100644
index 0000000..0fb5690
--- /dev/null
+++ b/media/libstagefright/include/SkipCutBuffer.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 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 SKIP_CUT_BUFFER_H_
+
+#define SKIP_CUT_BUFFER_H_
+
+#include <media/MediaCodecBuffer.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/foundation/ABuffer.h>
+
+namespace android {
+
+/**
+ * utility class to cut the start and end off a stream of data in MediaBuffers
+ *
+ */
+class SkipCutBuffer: public RefBase {
+ public:
+ // 'skip' is the number of frames to skip from the beginning
+ // 'cut' is the number of frames to cut from the end
+ // 'num16BitChannels' is the number of channels, which are assumed to be 16 bit wide each
+ SkipCutBuffer(size_t skip, size_t cut, size_t num16Channels);
+
+ // Submit one MediaBuffer for skipping and cutting. This may consume all or
+ // some of the data in the buffer, or it may add data to it.
+ // After this, the caller should continue processing the buffer as usual.
+ void submit(MediaBuffer *buffer);
+ void submit(const sp<ABuffer>& buffer); // same as above, but with an ABuffer
+ void submit(const sp<MediaCodecBuffer>& buffer); // same as above, but with an ABuffer
+ void clear();
+ size_t size(); // how many bytes are currently stored in the buffer
+
+ protected:
+ virtual ~SkipCutBuffer();
+
+ private:
+ void write(const char *src, size_t num);
+ size_t read(char *dst, size_t num);
+ template <typename T>
+ void submitInternal(const sp<T>& buffer);
+ int32_t mSkip;
+ int32_t mFrontPadding;
+ int32_t mBackPadding;
+ int32_t mWriteHead;
+ int32_t mReadHead;
+ int32_t mCapacity;
+ char* mCutBuffer;
+ DISALLOW_EVIL_CONSTRUCTORS(SkipCutBuffer);
+};
+
+} // namespace android
+
+#endif // OMX_CODEC_H_
diff --git a/media/libstagefright/include/StagefrightMediaScanner.h b/media/libstagefright/include/StagefrightMediaScanner.h
new file mode 100644
index 0000000..eb3accc
--- /dev/null
+++ b/media/libstagefright/include/StagefrightMediaScanner.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009 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 STAGEFRIGHT_MEDIA_SCANNER_H_
+
+#define STAGEFRIGHT_MEDIA_SCANNER_H_
+
+#include <media/mediascanner.h>
+
+namespace android {
+
+struct StagefrightMediaScanner : public MediaScanner {
+ StagefrightMediaScanner();
+ virtual ~StagefrightMediaScanner();
+
+ virtual MediaScanResult processFile(
+ const char *path, const char *mimeType,
+ MediaScannerClient &client);
+
+ virtual MediaAlbumArt *extractAlbumArt(int fd);
+
+private:
+ StagefrightMediaScanner(const StagefrightMediaScanner &);
+ StagefrightMediaScanner &operator=(const StagefrightMediaScanner &);
+
+ MediaScanResult processFileInternal(
+ const char *path, const char *mimeType,
+ MediaScannerClient &client);
+};
+
+} // namespace android
+
+#endif // STAGEFRIGHT_MEDIA_SCANNER_H_
diff --git a/media/libstagefright/include/SurfaceMediaSource.h b/media/libstagefright/include/SurfaceMediaSource.h
new file mode 100644
index 0000000..ca3a3bf
--- /dev/null
+++ b/media/libstagefright/include/SurfaceMediaSource.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2011 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_GUI_SURFACEMEDIASOURCE_H
+#define ANDROID_GUI_SURFACEMEDIASOURCE_H
+
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/BufferQueue.h>
+
+#include <utils/threads.h>
+#include <utils/Vector.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MediaBuffer.h>
+
+#include <MetadataBufferType.h>
+
+#include "foundation/ABase.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class IGraphicBufferAlloc;
+class String8;
+class GraphicBuffer;
+
+// ASSUMPTIONS
+// 1. SurfaceMediaSource is initialized with width*height which
+// can never change. However, deqeueue buffer does not currently
+// enforce this as in BufferQueue, dequeue can be used by Surface
+// which can modify the default width and heght. Also neither the width
+// nor height can be 0.
+// 2. setSynchronousMode is never used (basically no one should call
+// setSynchronousMode(false)
+// 3. setCrop, setTransform, setScalingMode should never be used
+// 4. queueBuffer returns a filled buffer to the SurfaceMediaSource. In addition, a
+// timestamp must be provided for the buffer. The timestamp is in
+// nanoseconds, and must be monotonically increasing. Its other semantics
+// (zero point, etc) are client-dependent and should be documented by the
+// client.
+// 5. Once disconnected, SurfaceMediaSource can be reused (can not
+// connect again)
+// 6. Stop is a hard stop, the last few frames held by the encoder
+// may be dropped. It is possible to wait for the buffers to be
+// returned (but not implemented)
+
+#define DEBUG_PENDING_BUFFERS 0
+
+class SurfaceMediaSource : public MediaSource,
+ public MediaBufferObserver,
+ protected ConsumerListener {
+public:
+ enum { MIN_UNDEQUEUED_BUFFERS = 4};
+
+ struct FrameAvailableListener : public virtual RefBase {
+ // onFrameAvailable() is called from queueBuffer() is the FIFO is
+ // empty. You can use SurfaceMediaSource::getQueuedCount() to
+ // figure out if there are more frames waiting.
+ // This is called without any lock held can be called concurrently by
+ // multiple threads.
+ virtual void onFrameAvailable() = 0;
+ };
+
+ SurfaceMediaSource(uint32_t bufferWidth, uint32_t bufferHeight);
+
+ virtual ~SurfaceMediaSource();
+
+ // For the MediaSource interface for use by StageFrightRecorder:
+ virtual status_t start(MetaData *params = NULL);
+ virtual status_t stop();
+ virtual status_t read(MediaBuffer **buffer,
+ const ReadOptions *options = NULL);
+ virtual sp<MetaData> getFormat();
+
+ // Get / Set the frame rate used for encoding. Default fps = 30
+ status_t setFrameRate(int32_t fps) ;
+ int32_t getFrameRate( ) const;
+
+ // The call for the StageFrightRecorder to tell us that
+ // it is done using the MediaBuffer data so that its state
+ // can be set to FREE for dequeuing
+ virtual void signalBufferReturned(MediaBuffer* buffer);
+ // end of MediaSource interface
+
+ // getTimestamp retrieves the timestamp associated with the image
+ // set by the most recent call to read()
+ //
+ // The timestamp is in nanoseconds, and is monotonically increasing. Its
+ // other semantics (zero point, etc) are source-dependent and should be
+ // documented by the source.
+ int64_t getTimestamp();
+
+ // setFrameAvailableListener sets the listener object that will be notified
+ // when a new frame becomes available.
+ void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
+
+ // dump our state in a String
+ void dump(String8& result) const;
+ void dump(String8& result, const char* prefix, char* buffer,
+ size_t SIZE) const;
+
+ // metaDataStoredInVideoBuffers tells the encoder what kind of metadata
+ // is passed through the buffers. Currently, it is set to ANWBuffer
+ MetadataBufferType metaDataStoredInVideoBuffers() const;
+
+ sp<IGraphicBufferProducer> getProducer() const { return mProducer; }
+
+ // To be called before start()
+ status_t setMaxAcquiredBufferCount(size_t count);
+
+ // To be called before start()
+ status_t setUseAbsoluteTimestamps();
+
+protected:
+
+ // Implementation of the BufferQueue::ConsumerListener interface. These
+ // calls are used to notify the Surface of asynchronous events in the
+ // BufferQueue.
+ virtual void onFrameAvailable(const BufferItem& item);
+
+ // Used as a hook to BufferQueue::disconnect()
+ // This is called by the client side when it is done
+ // TODO: Currently, this also sets mStopped to true which
+ // is needed for unblocking the encoder which might be
+ // waiting to read more frames. So if on the client side,
+ // the same thread supplies the frames and also calls stop
+ // on the encoder, the client has to call disconnect before
+ // it calls stop.
+ // In the case of the camera,
+ // that need not be required since the thread supplying the
+ // frames is separate than the one calling stop.
+ virtual void onBuffersReleased();
+
+ // SurfaceMediaSource can't handle sideband streams, so this is not expected
+ // to ever be called. Does nothing.
+ virtual void onSidebandStreamChanged();
+
+ static bool isExternalFormat(uint32_t format);
+
+private:
+ // A BufferQueue, represented by these interfaces, is the exchange point
+ // between the producer and this consumer
+ sp<IGraphicBufferProducer> mProducer;
+ sp<IGraphicBufferConsumer> mConsumer;
+
+ struct SlotData {
+ sp<GraphicBuffer> mGraphicBuffer;
+ uint64_t mFrameNumber;
+ };
+
+ // mSlots caches GraphicBuffers and frameNumbers from the buffer queue
+ SlotData mSlots[BufferQueue::NUM_BUFFER_SLOTS];
+
+ // The permenent width and height of SMS buffers
+ int mWidth;
+ int mHeight;
+
+ // mCurrentSlot is the buffer slot index of the buffer that is currently
+ // being used by buffer consumer
+ // (e.g. StageFrightRecorder in the case of SurfaceMediaSource or GLTexture
+ // in the case of Surface).
+ // It is initialized to INVALID_BUFFER_SLOT,
+ // indicating that no buffer slot is currently bound to the texture. Note,
+ // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
+ // that no buffer is bound to the texture. A call to setBufferCount will
+ // reset mCurrentTexture to INVALID_BUFFER_SLOT.
+ int mCurrentSlot;
+
+ // mCurrentBuffers is a list of the graphic buffers that are being used by
+ // buffer consumer (i.e. the video encoder). It's possible that these
+ // buffers are not associated with any buffer slots, so we must track them
+ // separately. Buffers are added to this list in read, and removed from
+ // this list in signalBufferReturned
+ Vector<sp<GraphicBuffer> > mCurrentBuffers;
+
+ size_t mNumPendingBuffers;
+
+#if DEBUG_PENDING_BUFFERS
+ Vector<MediaBuffer *> mPendingBuffers;
+#endif
+
+ // mCurrentTimestamp is the timestamp for the current texture. It
+ // gets set to mLastQueuedTimestamp each time updateTexImage is called.
+ int64_t mCurrentTimestamp;
+
+ // mFrameAvailableListener is the listener object that will be called when a
+ // new frame becomes available. If it is not NULL it will be called from
+ // queueBuffer.
+ sp<FrameAvailableListener> mFrameAvailableListener;
+
+ // mMutex is the mutex used to prevent concurrent access to the member
+ // variables of SurfaceMediaSource objects. It must be locked whenever the
+ // member variables are accessed.
+ mutable Mutex mMutex;
+
+ ////////////////////////// For MediaSource
+ // Set to a default of 30 fps if not specified by the client side
+ int32_t mFrameRate;
+
+ // mStarted is a flag to check if the recording is going on
+ bool mStarted;
+
+ // mNumFramesReceived indicates the number of frames recieved from
+ // the client side
+ int mNumFramesReceived;
+ // mNumFramesEncoded indicates the number of frames passed on to the
+ // encoder
+ int mNumFramesEncoded;
+
+ // mFirstFrameTimestamp is the timestamp of the first received frame.
+ // It is used to offset the output timestamps so recording starts at time 0.
+ int64_t mFirstFrameTimestamp;
+ // mStartTimeNs is the start time passed into the source at start, used to
+ // offset timestamps.
+ int64_t mStartTimeNs;
+
+ size_t mMaxAcquiredBufferCount;
+
+ bool mUseAbsoluteTimestamps;
+
+ // mFrameAvailableCondition condition used to indicate whether there
+ // is a frame available for dequeuing
+ Condition mFrameAvailableCondition;
+
+ Condition mMediaBuffersAvailableCondition;
+
+ // Allocate and return a new MediaBuffer and pass the ANW buffer as metadata into it.
+ void passMetadataBuffer_l(MediaBuffer **buffer, ANativeWindowBuffer *bufferHandle) const;
+
+ // Avoid copying and equating and default constructor
+ DISALLOW_EVIL_CONSTRUCTORS(SurfaceMediaSource);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_SURFACEMEDIASOURCE_H
diff --git a/media/libstagefright/include/SurfaceUtils.h b/media/libstagefright/include/SurfaceUtils.h
new file mode 100644
index 0000000..a7747c7
--- /dev/null
+++ b/media/libstagefright/include/SurfaceUtils.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2015 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 SURFACE_UTILS_H_
+
+#define SURFACE_UTILS_H_
+
+#include <utils/Errors.h>
+
+struct ANativeWindow;
+
+namespace android {
+
+/**
+ * Configures |nativeWindow| for given |width|x|height|, pixel |format|, |rotation| and |usage|.
+ * If |reconnect| is true, reconnects to the native window before hand.
+ * @return first error encountered, or NO_ERROR on success.
+ */
+status_t setNativeWindowSizeFormatAndUsage(
+ ANativeWindow *nativeWindow /* nonnull */,
+ int width, int height, int format, int rotation, int usage, bool reconnect);
+status_t pushBlankBuffersToNativeWindow(ANativeWindow *nativeWindow /* nonnull */);
+status_t nativeWindowConnect(ANativeWindow *surface, const char *reason);
+status_t nativeWindowDisconnect(ANativeWindow *surface, const char *reason);
+
+} // namespace android
+
+#endif // SURFACE_UTILS_H_
diff --git a/media/libstagefright/include/Utils.h b/media/libstagefright/include/Utils.h
new file mode 100644
index 0000000..88a416a
--- /dev/null
+++ b/media/libstagefright/include/Utils.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2009 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 UTILS_H_
+
+#define UTILS_H_
+
+#include <media/stagefright/foundation/AString.h>
+#include <stdint.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <system/audio.h>
+#include <media/BufferingSettings.h>
+#include <media/MediaPlayerInterface.h>
+
+namespace android {
+
+#define FOURCC(c1, c2, c3, c4) \
+ ((c1) << 24 | (c2) << 16 | (c3) << 8 | (c4))
+
+uint16_t U16_AT(const uint8_t *ptr);
+uint32_t U32_AT(const uint8_t *ptr);
+uint64_t U64_AT(const uint8_t *ptr);
+
+uint16_t U16LE_AT(const uint8_t *ptr);
+uint32_t U32LE_AT(const uint8_t *ptr);
+uint64_t U64LE_AT(const uint8_t *ptr);
+
+uint64_t ntoh64(uint64_t x);
+uint64_t hton64(uint64_t x);
+
+class MetaData;
+struct AMessage;
+status_t convertMetaDataToMessage(
+ const sp<MetaData> &meta, sp<AMessage> *format);
+void convertMessageToMetaData(
+ const sp<AMessage> &format, sp<MetaData> &meta);
+
+// Returns a pointer to the next NAL start code in buffer of size |length| starting at |data|, or
+// a pointer to the end of the buffer if the start code is not found.
+// TODO: combine this with avc_utils::getNextNALUnit
+const uint8_t *findNextNalStartCode(const uint8_t *data, size_t length);
+
+AString MakeUserAgent();
+
+// Convert a MIME type to a AudioSystem::audio_format
+status_t mapMimeToAudioFormat(audio_format_t& format, const char* mime);
+
+// Convert a aac profile to a AudioSystem::audio_format
+void mapAACProfileToAudioFormat(audio_format_t& format, uint64_t eAacProfile);
+
+// Send information from MetaData to the HAL via AudioSink
+status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink, const sp<MetaData>& meta);
+
+// Check whether the stream defined by meta can be offloaded to hardware
+bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
+ bool isStreaming, audio_stream_type_t streamType);
+
+AString uriDebugString(const AString &uri, bool incognito = false);
+
+struct HLSTime {
+ int32_t mSeq;
+ int64_t mTimeUs;
+ sp<AMessage> mMeta;
+
+ explicit HLSTime(const sp<AMessage> &meta = NULL);
+ int64_t getSegmentTimeUs() const;
+};
+
+bool operator <(const HLSTime &t0, const HLSTime &t1);
+
+// read and write various object to/from AMessage
+
+void writeToAMessage(const sp<AMessage> &msg, const AudioPlaybackRate &rate);
+void readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */);
+
+void writeToAMessage(const sp<AMessage> &msg, const AVSyncSettings &sync, float videoFpsHint);
+void readFromAMessage(
+ const sp<AMessage> &msg, AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */);
+
+void writeToAMessage(const sp<AMessage> &msg, const BufferingSettings &buffering);
+void readFromAMessage(const sp<AMessage> &msg, BufferingSettings *buffering /* nonnull */);
+
+AString nameForFd(int fd);
+
+} // namespace android
+
+#endif // UTILS_H_
diff --git a/media/libstagefright/include/VideoFrameScheduler.h b/media/libstagefright/include/VideoFrameScheduler.h
new file mode 100644
index 0000000..9d97dfd
--- /dev/null
+++ b/media/libstagefright/include/VideoFrameScheduler.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VIDEO_FRAME_SCHEDULER_H_
+#define VIDEO_FRAME_SCHEDULER_H_
+
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+class ISurfaceComposer;
+
+struct VideoFrameScheduler : public RefBase {
+ VideoFrameScheduler();
+
+ // (re)initialize scheduler
+ void init(float videoFps = -1);
+ // use in case of video render-time discontinuity, e.g. seek
+ void restart();
+ // get adjusted nanotime for a video frame render at renderTime
+ nsecs_t schedule(nsecs_t renderTime);
+
+ // returns the vsync period for the main display
+ nsecs_t getVsyncPeriod();
+
+ // returns the current frames-per-second, or 0.f if not primed
+ float getFrameRate();
+
+ void release();
+
+ static const size_t kHistorySize = 8;
+
+protected:
+ virtual ~VideoFrameScheduler();
+
+private:
+ struct PLL {
+ PLL();
+
+ // reset PLL to new PLL
+ void reset(float fps = -1);
+ // keep current estimate, but restart phase
+ void restart();
+ // returns period or 0 if not yet primed
+ nsecs_t addSample(nsecs_t time);
+ nsecs_t getPeriod() const;
+
+ private:
+ nsecs_t mPeriod;
+ nsecs_t mPhase;
+
+ bool mPrimed; // have an estimate for the period
+ size_t mSamplesUsedForPriming;
+
+ nsecs_t mLastTime; // last input time
+ nsecs_t mRefitAt; // next input time to fit at
+
+ size_t mNumSamples; // can go past kHistorySize
+ nsecs_t mTimes[kHistorySize];
+
+ void test();
+ // returns whether fit was successful
+ bool fit(nsecs_t phase, nsecs_t period, size_t numSamples,
+ int64_t *a, int64_t *b, int64_t *err);
+ void prime(size_t numSamples);
+ };
+
+ void updateVsync();
+
+ nsecs_t mVsyncTime; // vsync timing from display
+ nsecs_t mVsyncPeriod;
+ nsecs_t mVsyncRefreshAt; // next time to refresh timing info
+
+ nsecs_t mLastVsyncTime; // estimated vsync time for last frame
+ nsecs_t mTimeCorrection; // running adjustment
+
+ PLL mPll; // PLL for video frame rate based on render time
+
+ sp<ISurfaceComposer> mComposer;
+
+ DISALLOW_EVIL_CONSTRUCTORS(VideoFrameScheduler);
+};
+
+} // namespace android
+
+#endif // VIDEO_FRAME_SCHEDULER_H_
+
diff --git a/media/libstagefright/include/YUVCanvas.h b/media/libstagefright/include/YUVCanvas.h
new file mode 100644
index 0000000..ff70923
--- /dev/null
+++ b/media/libstagefright/include/YUVCanvas.h
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+// YUVCanvas holds a reference to a YUVImage on which it can do various
+// drawing operations. It provides various utility functions for filling,
+// cropping, etc.
+
+
+#ifndef YUV_CANVAS_H_
+
+#define YUV_CANVAS_H_
+
+#include <stdint.h>
+
+namespace android {
+
+class YUVImage;
+class Rect;
+
+class YUVCanvas {
+public:
+
+ // Constructor takes in reference to a yuvImage on which it can do
+ // various drawing opreations.
+ YUVCanvas(YUVImage &yuvImage);
+ ~YUVCanvas();
+
+ // Fills the entire image with the given YUV values.
+ void FillYUV(uint8_t yValue, uint8_t uValue, uint8_t vValue);
+
+ // Fills the rectangular region [startX,endX]x[startY,endY] with the given YUV values.
+ void FillYUVRectangle(const Rect& rect,
+ uint8_t yValue, uint8_t uValue, uint8_t vValue);
+
+ // Copies the region [startX,endX]x[startY,endY] from srcImage into the
+ // canvas' target image (mYUVImage) starting at
+ // (destinationStartX,destinationStartY).
+ // Note that undefined behavior may occur if srcImage is same as the canvas'
+ // target image.
+ void CopyImageRect(
+ const Rect& srcRect,
+ int32_t destStartX, int32_t destStartY,
+ const YUVImage &srcImage);
+
+ // Downsamples the srcImage into the canvas' target image (mYUVImage)
+ // The downsampling copies pixels from the source image starting at
+ // (srcOffsetX, srcOffsetY) to the target image, starting at (0, 0).
+ // For each X increment in the target image, skipX pixels are skipped
+ // in the source image.
+ // Similarly for each Y increment in the target image, skipY pixels
+ // are skipped in the source image.
+ void downsample(
+ int32_t srcOffsetX, int32_t srcOffsetY,
+ int32_t skipX, int32_t skipY,
+ const YUVImage &srcImage);
+
+private:
+ YUVImage& mYUVImage;
+
+ YUVCanvas(const YUVCanvas &);
+ YUVCanvas &operator=(const YUVCanvas &);
+};
+
+} // namespace android
+
+#endif // YUV_CANVAS_H_
diff --git a/media/libstagefright/include/YUVImage.h b/media/libstagefright/include/YUVImage.h
new file mode 100644
index 0000000..4e98618
--- /dev/null
+++ b/media/libstagefright/include/YUVImage.h
@@ -0,0 +1,178 @@
+/*
+ * 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.
+ */
+
+// A container class to hold YUV data and provide various utilities,
+// e.g. to set/get pixel values.
+// Supported formats:
+// - YUV420 Planar
+// - YUV420 Semi Planar
+//
+// Currently does not support variable strides.
+//
+// Implementation: Two simple abstractions are done to simplify access
+// to YUV channels for different formats:
+// - initializeYUVPointers() sets up pointers (mYdata, mUdata, mVdata) to
+// point to the right start locations of the different channel data depending
+// on the format.
+// - getOffsets() returns the correct offset for the different channels
+// depending on the format.
+// Location of any pixel's YUV channels can then be easily computed using these.
+//
+
+#ifndef YUV_IMAGE_H_
+
+#define YUV_IMAGE_H_
+
+#include <stdint.h>
+#include <cstring>
+
+namespace android {
+
+class Rect;
+
+class YUVImage {
+public:
+ // Supported YUV formats
+ enum YUVFormat {
+ YUV420Planar,
+ YUV420SemiPlanar
+ };
+
+ // Constructs an image with the given size, format. Also allocates and owns
+ // the required memory.
+ YUVImage(YUVFormat yuvFormat, int32_t width, int32_t height);
+
+ // Constructs an image with the given size, format. The memory is provided
+ // by the caller and we don't own it.
+ YUVImage(YUVFormat yuvFormat, int32_t width, int32_t height, uint8_t *buffer);
+
+ // Destructor to delete the memory if it owns it.
+ ~YUVImage();
+
+ // Returns the size of the buffer required to store the YUV data for the given
+ // format and geometry. Useful when the caller wants to allocate the requisite
+ // memory.
+ static size_t bufferSize(YUVFormat yuvFormat, int32_t width, int32_t height);
+
+ int32_t width() const {return mWidth;}
+ int32_t height() const {return mHeight;}
+
+ // Returns true if pixel is the range [0, width-1] x [0, height-1]
+ // and false otherwise.
+ bool validPixel(int32_t x, int32_t y) const;
+
+ // Get the pixel YUV value at pixel (x,y).
+ // Note that the range of x is [0, width-1] and the range of y is [0, height-1].
+ // Returns true if get was successful and false otherwise.
+ bool getPixelValue(int32_t x, int32_t y,
+ uint8_t *yPtr, uint8_t *uPtr, uint8_t *vPtr) const;
+
+ // Set the pixel YUV value at pixel (x,y).
+ // Note that the range of x is [0, width-1] and the range of y is [0, height-1].
+ // Returns true if set was successful and false otherwise.
+ bool setPixelValue(int32_t x, int32_t y,
+ uint8_t yValue, uint8_t uValue, uint8_t vValue);
+
+ // Uses memcpy to copy an entire row of data
+ static void fastCopyRectangle420Planar(
+ const Rect& srcRect,
+ int32_t destStartX, int32_t destStartY,
+ const YUVImage &srcImage, YUVImage &destImage);
+
+ // Uses memcpy to copy an entire row of data
+ static void fastCopyRectangle420SemiPlanar(
+ const Rect& srcRect,
+ int32_t destStartX, int32_t destStartY,
+ const YUVImage &srcImage, YUVImage &destImage);
+
+ // Tries to use memcopy to copy entire rows of data.
+ // Returns false if fast copy is not possible for the passed image formats.
+ static bool fastCopyRectangle(
+ const Rect& srcRect,
+ int32_t destStartX, int32_t destStartY,
+ const YUVImage &srcImage, YUVImage &destImage);
+
+ // Convert the given YUV value to RGB.
+ void yuv2rgb(uint8_t yValue, uint8_t uValue, uint8_t vValue,
+ uint8_t *r, uint8_t *g, uint8_t *b) const;
+
+ // Write the image to a human readable PPM file.
+ // Returns true if write was succesful and false otherwise.
+ bool writeToPPM(const char *filename) const;
+
+private:
+ // YUV Format of the image.
+ YUVFormat mYUVFormat;
+
+ int32_t mWidth;
+ int32_t mHeight;
+
+ // Pointer to the memory buffer.
+ uint8_t *mBuffer;
+
+ // Boolean telling whether we own the memory buffer.
+ bool mOwnBuffer;
+
+ // Pointer to start of the Y data plane.
+ uint8_t *mYdata;
+
+ // Pointer to start of the U data plane. Note that in case of interleaved formats like
+ // YUV420 semiplanar, mUdata points to the start of the U data in the UV plane.
+ uint8_t *mUdata;
+
+ // Pointer to start of the V data plane. Note that in case of interleaved formats like
+ // YUV420 semiplanar, mVdata points to the start of the V data in the UV plane.
+ uint8_t *mVdata;
+
+ // Initialize the pointers mYdata, mUdata, mVdata to point to the right locations for
+ // the given format and geometry.
+ // Returns true if initialize was succesful and false otherwise.
+ bool initializeYUVPointers();
+
+ // For the given pixel location, this returns the offset of the location of y, u and v
+ // data from the corresponding base pointers -- mYdata, mUdata, mVdata.
+ // Note that the range of x is [0, width-1] and the range of y is [0, height-1].
+ // Returns true if getting offsets was succesful and false otherwise.
+ bool getOffsets(int32_t x, int32_t y,
+ int32_t *yOffset, int32_t *uOffset, int32_t *vOffset) const;
+
+ // Returns the offset increments incurred in going from one data row to the next data row
+ // for the YUV channels. Note that this corresponds to data rows and not pixel rows.
+ // E.g. depending on formats, U/V channels may have only one data row corresponding
+ // to two pixel rows.
+ bool getOffsetIncrementsPerDataRow(
+ int32_t *yDataOffsetIncrement,
+ int32_t *uDataOffsetIncrement,
+ int32_t *vDataOffsetIncrement) const;
+
+ // Given the offset return the address of the corresponding channel's data.
+ uint8_t* getYAddress(int32_t offset) const;
+ uint8_t* getUAddress(int32_t offset) const;
+ uint8_t* getVAddress(int32_t offset) const;
+
+ // Given the pixel location, returns the address of the corresponding channel's data.
+ // Note that the range of x is [0, width-1] and the range of y is [0, height-1].
+ bool getYUVAddresses(int32_t x, int32_t y,
+ uint8_t **yAddr, uint8_t **uAddr, uint8_t **vAddr) const;
+
+ // Disallow implicit casting and copying.
+ YUVImage(const YUVImage &);
+ YUVImage &operator=(const YUVImage &);
+};
+
+} // namespace android
+
+#endif // YUV_IMAGE_H_
diff --git a/media/libstagefright/include/foundation/AAtomizer.h b/media/libstagefright/include/foundation/AAtomizer.h
new file mode 100644
index 0000000..5f3a678
--- /dev/null
+++ b/media/libstagefright/include/foundation/AAtomizer.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 A_ATOMIZER_H_
+
+#define A_ATOMIZER_H_
+
+#include <stdint.h>
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AString.h>
+#include <utils/List.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+
+namespace android {
+
+struct AAtomizer {
+ static const char *Atomize(const char *name);
+
+private:
+ static AAtomizer gAtomizer;
+
+ Mutex mLock;
+ Vector<List<AString> > mAtoms;
+
+ AAtomizer();
+
+ const char *atomize(const char *name);
+
+ static uint32_t Hash(const char *s);
+
+ DISALLOW_EVIL_CONSTRUCTORS(AAtomizer);
+};
+
+} // namespace android
+
+#endif // A_ATOMIZER_H_
diff --git a/media/libstagefright/include/foundation/ABase.h b/media/libstagefright/include/foundation/ABase.h
new file mode 100644
index 0000000..76a787e
--- /dev/null
+++ b/media/libstagefright/include/foundation/ABase.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 A_BASE_H_
+
+#define A_BASE_H_
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
+#endif
+
+#define DISALLOW_EVIL_CONSTRUCTORS(name) \
+ name(const name &); \
+ name &operator=(const name &) /* NOLINT */
+
+/* Returns true if the size parameter is safe for new array allocation (32-bit)
+ *
+ * Example usage:
+ *
+ * if (!isSafeArraySize<uint32_t>(arraySize)) {
+ * return BAD_VALUE;
+ * }
+ * ...
+ * uint32_t *myArray = new uint32_t[arraySize];
+ *
+ * There is a bug in gcc versions earlier than 4.8 where the new[] array allocation
+ * will overflow in the internal 32 bit heap allocation, resulting in an
+ * underallocated array. This is a security issue that allows potential overwriting
+ * of other heap data.
+ *
+ * An alternative to checking is to create a safe new array template function which
+ * either throws a std::bad_alloc exception or returns NULL/nullptr_t; NULL considered
+ * safe since normal access of NULL throws an exception.
+ *
+ * https://securityblog.redhat.com/2012/10/31/array-allocation-in-cxx/
+ */
+template <typename T, typename S>
+bool isSafeArraySize(S size) {
+ return size >= 0 // in case S is signed, ignored if not.
+ && size <= 0xffffffff / sizeof(T); // max-unsigned-32-bit-int / element-size.
+}
+
+#endif // A_BASE_H_
diff --git a/media/libstagefright/include/foundation/ABitReader.h b/media/libstagefright/include/foundation/ABitReader.h
new file mode 100644
index 0000000..a30dd2e
--- /dev/null
+++ b/media/libstagefright/include/foundation/ABitReader.h
@@ -0,0 +1,91 @@
+/*
+ * 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 A_BIT_READER_H_
+
+#define A_BIT_READER_H_
+
+#include <media/stagefright/foundation/ABase.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+
+namespace android {
+
+class ABitReader {
+public:
+ ABitReader(const uint8_t *data, size_t size);
+ virtual ~ABitReader();
+
+ // Tries to get |n| bits. If not successful, returns |fallback|. Otherwise, returns result.
+ // Reading 0 bits will always succeed and return 0.
+ uint32_t getBitsWithFallback(size_t n, uint32_t fallback);
+
+ // Tries to get |n| bits. If not successful, returns false. Otherwise, stores result in |out|
+ // and returns true. Use !overRead() to determine if this call was successful. Reading 0 bits
+ // will always succeed and write 0 in |out|.
+ bool getBitsGraceful(size_t n, uint32_t *out);
+
+ // Gets |n| bits and returns result. ABORTS if unsuccessful. Reading 0 bits will always
+ // succeed.
+ uint32_t getBits(size_t n);
+
+ // Tries to skip |n| bits. Returns true iff successful. Skipping 0 bits will always succeed.
+ bool skipBits(size_t n);
+
+ // "Puts" |n| bits with the value |x| back virtually into the bit stream. The put-back bits
+ // are not actually written into the data, but are tracked in a separate buffer that can
+ // store at most 32 bits. This is a no-op if the stream has already been over-read.
+ void putBits(uint32_t x, size_t n);
+
+ size_t numBitsLeft() const;
+
+ const uint8_t *data() const;
+
+ // Returns true iff the stream was over-read (e.g. any getBits operation has been unsuccessful
+ // due to overread (and not trying to read >32 bits).)
+ bool overRead() const { return mOverRead; }
+
+protected:
+ const uint8_t *mData;
+ size_t mSize;
+
+ uint32_t mReservoir; // left-aligned bits
+ size_t mNumBitsLeft;
+ bool mOverRead;
+
+ virtual bool fillReservoir();
+
+ DISALLOW_EVIL_CONSTRUCTORS(ABitReader);
+};
+
+class NALBitReader : public ABitReader {
+public:
+ NALBitReader(const uint8_t *data, size_t size);
+
+ bool atLeastNumBitsLeft(size_t n) const;
+
+private:
+ int32_t mNumZeros;
+
+ virtual bool fillReservoir();
+
+ DISALLOW_EVIL_CONSTRUCTORS(NALBitReader);
+};
+
+} // namespace android
+
+#endif // A_BIT_READER_H_
diff --git a/media/libstagefright/include/foundation/ABuffer.h b/media/libstagefright/include/foundation/ABuffer.h
new file mode 100644
index 0000000..ef11434
--- /dev/null
+++ b/media/libstagefright/include/foundation/ABuffer.h
@@ -0,0 +1,77 @@
+/*
+ * 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 A_BUFFER_H_
+
+#define A_BUFFER_H_
+
+#include <sys/types.h>
+#include <stdint.h>
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct AMessage;
+class MediaBufferBase;
+
+struct ABuffer : public RefBase {
+ explicit ABuffer(size_t capacity);
+ ABuffer(void *data, size_t capacity);
+
+ uint8_t *base() { return (uint8_t *)mData; }
+ uint8_t *data() { return (uint8_t *)mData + mRangeOffset; }
+ size_t capacity() const { return mCapacity; }
+ size_t size() const { return mRangeLength; }
+ size_t offset() const { return mRangeOffset; }
+
+ void setRange(size_t offset, size_t size);
+
+ // create buffer from dup of some memory block
+ static sp<ABuffer> CreateAsCopy(const void *data, size_t capacity);
+
+ void setInt32Data(int32_t data) { mInt32Data = data; }
+ int32_t int32Data() const { return mInt32Data; }
+
+ sp<AMessage> meta();
+
+ MediaBufferBase *getMediaBufferBase();
+ void setMediaBufferBase(MediaBufferBase *mediaBuffer);
+
+protected:
+ virtual ~ABuffer();
+
+private:
+ sp<AMessage> mMeta;
+
+ MediaBufferBase *mMediaBufferBase;
+
+ void *mData;
+ size_t mCapacity;
+ size_t mRangeOffset;
+ size_t mRangeLength;
+
+ int32_t mInt32Data;
+
+ bool mOwnsData;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ABuffer);
+};
+
+} // namespace android
+
+#endif // A_BUFFER_H_
diff --git a/media/libstagefright/include/foundation/AData.h b/media/libstagefright/include/foundation/AData.h
new file mode 100644
index 0000000..49aa0dc
--- /dev/null
+++ b/media/libstagefright/include/foundation/AData.h
@@ -0,0 +1,843 @@
+/*
+ * Copyright (C) 2016 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 STAGEFRIGHT_FOUNDATION_A_DATA_H_
+#define STAGEFRIGHT_FOUNDATION_A_DATA_H_
+
+#include <memory> // for std::shared_ptr, weak_ptr and unique_ptr
+#include <type_traits> // for std::aligned_union
+
+#include <utils/StrongPointer.h> // for android::sp and wp
+
+#include <media/stagefright/foundation/TypeTraits.h>
+#include <media/stagefright/foundation/Flagged.h>
+
+namespace android {
+
+/**
+ * AData is a flexible union type that supports non-POD members. It supports arbitrary types as long
+ * as they are either moveable or copyable.
+ *
+ * Internally, AData is using AUnion - a structure providing the union support. AUnion should not
+ * be used by generic code as it is very unsafe - it opens type aliasing errors where an object of
+ * one type can be easily accessed as an object of another type. AData prevents this.
+ *
+ * AData allows a custom type flagger to be used for future extensions (e.g. allowing automatic
+ * type conversion). A strict and a relaxed flagger are provided as internal types.
+ *
+ * Use as follows:
+ *
+ * AData<int, float>::Basic data; // strict type support
+ * int i = 1;
+ * float f = 7.0f;
+ *
+ * data.set(5);
+ * EXPECT_TRUE(data.find(&i));
+ * EXPECT_FALSE(data.find(&f));
+ * EXPECT_EQ(i, 5);
+ *
+ * data.set(6.0f);
+ * EXPECT_FALSE(data.find(&i));
+ * EXPECT_TRUE(data.find(&f));
+ * EXPECT_EQ(f, 6.0f);
+ *
+ * AData<int, sp<RefBase>>::RelaxedBasic objdata; // relaxed type support
+ * sp<ABuffer> buf = new ABuffer(16), buf2;
+ * sp<RefBase> obj;
+ *
+ * objdata.set(buf);
+ * EXPECT_TRUE(objdata.find(&buf2));
+ * EXPECT_EQ(buf, buf2);
+ * EXPECT_FALSE(objdata.find(&i));
+ * EXPECT_TRUE(objdata.find(&obj));
+ * EXPECT_TRUE(obj == buf);
+ *
+ * obj = buf;
+ * objdata.set(obj); // storing as sp<RefBase>
+ * EXPECT_FALSE(objdata.find(&buf2)); // not stored as ABuffer(!)
+ * EXPECT_TRUE(objdata.find(&obj));
+ */
+
+/// \cond Internal
+
+/**
+ * Helper class to call constructor and destructor for a specific type in AUnion.
+ * This class is needed as member function specialization is not allowed for a
+ * templated class.
+ */
+struct _AUnion_impl {
+ /**
+ * Calls placement constuctor for type T with arbitrary arguments for a storage at an address.
+ * Storage MUST be large enough to contain T.
+ * Also clears the slack space after type T. \todo This is not technically needed, so we may
+ * choose to do this just for debugging.
+ *
+ * \param totalSize size of the storage
+ * \param addr pointer to where object T should be constructed
+ * \param args arbitrary arguments for constructor
+ */
+ template<typename T, typename ...Args>
+ inline static void emplace(size_t totalSize, T *addr, Args&&... args) {
+ new(addr)T(std::forward<Args>(args)...);
+ // clear slack space - this is not technically required
+ constexpr size_t size = sizeof(T);
+ memset(reinterpret_cast<uint8_t*>(addr) + size, 0, totalSize - size);
+ }
+
+ /**
+ * Calls destuctor for an object of type T located at a specific address.
+ *
+ * \note we do not clear the storage in this case as the storage should not be used
+ * until another object is placed there, at which case the storage will be cleared.
+ *
+ * \param addr pointer to where object T is stored
+ */
+ template<typename T>
+ inline static void del(T *addr) {
+ addr->~T();
+ }
+};
+
+/** Constructor specialization for void type */
+template<>
+inline void _AUnion_impl::emplace<void>(size_t totalSize, void *addr) {
+ memset(addr, 0, totalSize);
+}
+
+/** Destructor specialization for void type */
+template<>
+inline void _AUnion_impl::del<void>(void *) {
+}
+
+/// \endcond
+
+/**
+ * A templated union class that can contain specific types of data, and provides
+ * constructors, destructor and access methods strictly for those types.
+ *
+ * \note This class is VERY UNSAFE compared to a union, but it allows non-POD unions.
+ * In particular care must be taken that methods are called in a careful order to
+ * prevent accessing objects of one type as another type. This class provides no
+ * facilities to help with this ordering. This is meant to be wrapped by safer
+ * utility classes that do that.
+ *
+ * \param Ts types stored in this union.
+ */
+template<typename ...Ts>
+struct AUnion {
+private:
+ using _type = typename std::aligned_union<0, Ts...>::type; ///< storage type
+ _type mValue; ///< storage
+
+public:
+ /**
+ * Constructs an object of type T with arbitrary arguments in this union. After this call,
+ * this union will contain this object.
+ *
+ * This method MUST be called only when either 1) no object or 2) a void object (equivalent to
+ * no object) is contained in this union.
+ *
+ * \param T type of object to be constructed. This must be one of the template parameters of
+ * the union class with the same cv-qualification, or void.
+ * \param args arbitrary arguments for the constructor
+ */
+ template<
+ typename T, typename ...Args,
+ typename=typename std::enable_if<is_one_of<T, void, Ts...>::value>::type>
+ inline void emplace(Args&&... args) {
+ _AUnion_impl::emplace(
+ sizeof(_type), reinterpret_cast<T*>(&mValue), std::forward<Args>(args)...);
+ }
+
+ /**
+ * Destructs an object of type T in this union. After this call, this union will contain no
+ * object.
+ *
+ * This method MUST be called only when this union contains an object of type T.
+ *
+ * \param T type of object to be destructed. This must be one of the template parameters of
+ * the union class with the same cv-qualification, or void.
+ */
+ template<
+ typename T,
+ typename=typename std::enable_if<is_one_of<T, void, Ts...>::value>::type>
+ inline void del() {
+ _AUnion_impl::del(reinterpret_cast<T*>(&mValue));
+ }
+
+ /**
+ * Returns a const reference to the object of type T in this union.
+ *
+ * This method MUST be called only when this union contains an object of type T.
+ *
+ * \param T type of object to be returned. This must be one of the template parameters of
+ * the union class with the same cv-qualification.
+ */
+ template<
+ typename T,
+ typename=typename std::enable_if<is_one_of<T, Ts...>::value>::type>
+ inline const T &get() const {
+ return *reinterpret_cast<const T*>(&mValue);
+ }
+
+ /**
+ * Returns a reference to the object of type T in this union.
+ *
+ * This method MUST be called only when this union contains an object of type T.
+ *
+ * \param T type of object to be returned. This must be one of the template parameters of
+ * the union class with the same cv-qualification.
+ */
+ template<typename T>
+ inline T &get() {
+ return *reinterpret_cast<T*>(&mValue);
+ }
+};
+
+/**
+ * Helper utility class that copies an object of type T to a destination.
+ *
+ * T must be copy assignable or copy constructible.
+ *
+ * It provides:
+ *
+ * void assign(T*, const U&) // for copiable types - this leaves the source unchanged, hence const.
+ *
+ * \param T type of object to assign to
+ */
+template<
+ typename T,
+ bool=std::is_copy_assignable<T>::value>
+struct _AData_copier {
+ static_assert(std::is_copy_assignable<T>::value, "T must be copy assignable here");
+
+ /**
+ * Copies src to data without modifying data.
+ *
+ * \param data pointer to destination
+ * \param src source object
+ */
+ inline static void assign(T *data, const T &src) {
+ *data = src;
+ }
+
+ template<typename U>
+ using enable_if_T_is_same_as = typename std::enable_if<std::is_same<U, T>::value>::type;
+
+ /**
+ * Downcast specializations for sp<>, shared_ptr<> and weak_ptr<>
+ */
+ template<typename Tp, typename U, typename=enable_if_T_is_same_as<sp<Tp>>>
+ inline static void assign(sp<Tp> *data, const sp<U> &src) {
+ *data = static_cast<Tp*>(src.get());
+ }
+
+ template<typename Tp, typename U, typename=enable_if_T_is_same_as<wp<Tp>>>
+ inline static void assign(wp<Tp> *data, const wp<U> &src) {
+ sp<U> __tmp = src.promote();
+ *data = static_cast<Tp*>(__tmp.get());
+ }
+
+ template<typename Tp, typename U, typename=enable_if_T_is_same_as<sp<Tp>>>
+ inline static void assign(sp<Tp> *data, sp<U> &&src) {
+ sp<U> __tmp = std::move(src); // move src out as get cannot
+ *data = static_cast<Tp*>(__tmp.get());
+ }
+
+ template<typename Tp, typename U, typename=enable_if_T_is_same_as<std::shared_ptr<Tp>>>
+ inline static void assign(std::shared_ptr<Tp> *data, const std::shared_ptr<U> &src) {
+ *data = std::static_pointer_cast<Tp>(src);
+ }
+
+ template<typename Tp, typename U, typename=enable_if_T_is_same_as<std::shared_ptr<Tp>>>
+ inline static void assign(std::shared_ptr<Tp> *data, std::shared_ptr<U> &&src) {
+ std::shared_ptr<U> __tmp = std::move(src); // move src out as static_pointer_cast cannot
+ *data = std::static_pointer_cast<Tp>(__tmp);
+ }
+
+ template<typename Tp, typename U, typename=enable_if_T_is_same_as<std::weak_ptr<Tp>>>
+ inline static void assign(std::weak_ptr<Tp> *data, const std::weak_ptr<U> &src) {
+ *data = std::static_pointer_cast<Tp>(src.lock());
+ }
+
+ // shared_ptrs are implicitly convertible to weak_ptrs but not vice versa, but picking the
+ // first compatible type in Ts requires having shared_ptr types before weak_ptr types, so that
+ // they are stored as shared_ptrs.
+ /**
+ * Provide sensible error message if encountering shared_ptr/weak_ptr ambiguity. This method
+ * is not enough to detect this, only if someone is trying to find the shared_ptr.
+ */
+ template<typename Tp, typename U>
+ inline static void assign(std::shared_ptr<Tp> *, const std::weak_ptr<U> &) {
+ static_assert(std::is_same<Tp, void>::value,
+ "shared/weak pointer ambiguity. move shared ptr types before weak_ptrs");
+ }
+};
+
+/**
+ * Template specialization for non copy assignable, but copy constructible types.
+ *
+ * \todo Test this. No basic classes are copy constructible but not assignable.
+ *
+ */
+template<typename T>
+struct _AData_copier<T, false> {
+ static_assert(!std::is_copy_assignable<T>::value, "T must not be copy assignable here");
+ static_assert(std::is_copy_constructible<T>::value, "T must be copy constructible here");
+
+ inline static void copy(T *data, const T &src) {
+ data->~T();
+ new(data)T(src);
+ }
+};
+
+/**
+ * Helper utility class that moves an object of type T to a destination.
+ *
+ * T must be move assignable or move constructible.
+ *
+ * It provides multiple methods:
+ *
+ * void assign(T*, T&&)
+ *
+ * \param T type of object to assign
+ */
+template<
+ typename T,
+ bool=std::is_move_assignable<T>::value>
+struct _AData_mover {
+ static_assert(std::is_move_assignable<T>::value, "T must be move assignable here");
+
+ /**
+ * Moves src to data while likely modifying it.
+ *
+ * \param data pointer to destination
+ * \param src source object
+ */
+ inline static void assign(T *data, T &&src) {
+ *data = std::move(src);
+ }
+
+ template<typename U>
+ using enable_if_T_is_same_as = typename std::enable_if<std::is_same<U, T>::value>::type;
+
+ /**
+ * Downcast specializations for sp<>, shared_ptr<> and weak_ptr<>
+ */
+ template<typename Tp, typename U, typename=enable_if_T_is_same_as<sp<Tp>>>
+ inline static void assign(sp<Tp> *data, sp<U> &&src) {
+ sp<U> __tmp = std::move(src); // move src out as get cannot
+ *data = static_cast<Tp*>(__tmp.get());
+ }
+
+ template<typename Tp, typename U, typename=enable_if_T_is_same_as<std::shared_ptr<Tp>>>
+ inline static void assign(std::shared_ptr<Tp> *data, std::shared_ptr<U> &&src) {
+ std::shared_ptr<U> __tmp = std::move(src); // move src out as static_pointer_cast cannot
+ *data = std::static_pointer_cast<Tp>(__tmp);
+ }
+
+ template<typename Tp, typename Td, typename U, typename Ud,
+ typename=enable_if_T_is_same_as<std::unique_ptr<Tp, Td>>>
+ inline static void assign(std::unique_ptr<Tp, Td> *data, std::unique_ptr<U, Ud> &&src) {
+ *data = std::unique_ptr<Tp, Td>(static_cast<Tp*>(src.release()));
+ }
+
+ // shared_ptrs are implicitly convertible to weak_ptrs but not vice versa, but picking the
+ // first compatible type in Ts requires having shared_ptr types before weak_ptr types, so that
+ // they are stored as shared_ptrs.
+ /**
+ * Provide sensible error message if encountering shared_ptr/weak_ptr ambiguity. This method
+ * is not enough to detect this, only if someone is trying to remove the shared_ptr.
+ */
+ template<typename Tp, typename U>
+ inline static void assign(std::shared_ptr<Tp> *, std::weak_ptr<U> &&) {
+ static_assert(std::is_same<Tp, void>::value,
+ "shared/weak pointer ambiguity. move shared ptr types before weak_ptrs");
+ }
+
+ // unique_ptrs are implicitly convertible to shared_ptrs but not vice versa, but picking the
+ // first compatible type in Ts requires having unique_ptrs types before shared_ptrs types, so
+ // that they are stored as unique_ptrs.
+ /**
+ * Provide sensible error message if encountering shared_ptr/unique_ptr ambiguity. This method
+ * is not enough to detect this, only if someone is trying to remove the unique_ptr.
+ */
+ template<typename Tp, typename U>
+ inline static void assign(std::unique_ptr<Tp> *, std::shared_ptr<U> &&) {
+ static_assert(std::is_same<Tp, void>::value,
+ "unique/shared pointer ambiguity. move unique ptr types before shared_ptrs");
+ }
+};
+
+/**
+ * Template specialization for non move assignable, but move constructible types.
+ *
+ * \todo Test this. No basic classes are move constructible but not assignable.
+ *
+ */
+template<typename T>
+struct _AData_mover<T, false> {
+ static_assert(!std::is_move_assignable<T>::value, "T must not be move assignable here");
+ static_assert(std::is_move_constructible<T>::value, "T must be move constructible here");
+
+ inline static void assign(T *data, T &&src) {
+ data->~T();
+ new(data)T(std::move(src));
+ }
+};
+
+/**
+ * Helper template that deletes an object of a specific type (member) in an AUnion.
+ *
+ * \param Flagger type flagger class (see AData)
+ * \param U AUnion object in which the member should be deleted
+ * \param Ts types to consider for the member
+ */
+template<typename Flagger, typename U, typename ...Ts>
+struct _AData_deleter;
+
+/**
+ * Template specialization when there are still types to consider (T and rest)
+ */
+template<typename Flagger, typename U, typename T, typename ...Ts>
+struct _AData_deleter<Flagger, U, T, Ts...> {
+ static bool del(typename Flagger::type flags, U &data) {
+ if (Flagger::canDeleteAs(flags, Flagger::flagFor((T*)0))) {
+ data.template del<T>();
+ return true;
+ }
+ return _AData_deleter<Flagger, U, Ts...>::del(flags, data);
+ }
+};
+
+/**
+ * Template specialization when there are no more types to consider.
+ */
+template<typename Flagger, typename U>
+struct _AData_deleter<Flagger, U> {
+ inline static bool del(typename Flagger::type, U &) {
+ return false;
+ }
+};
+
+/**
+ * Container that can store an arbitrary object of a set of specified types.
+ *
+ * This struct is an outer class that contains various inner classes based on desired type
+ * strictness. The following inner classes are supported:
+ *
+ * AData<types...>::Basic - strict type support using uint32_t flag.
+ *
+ * AData<types...>::Strict<Flag> - strict type support using custom flag.
+ * AData<types...>::Relaxed<Flag, MaxSize, Align>
+ * - relaxed type support with compatible (usually derived) class support
+ * for pointer types with added size checking for minimal additional
+ * safety.
+ *
+ * AData<types...>::RelaxedBasic - strict type support using uint32_t flag.
+ *
+ * AData<types...>::Custom<flagger> - custom type support (flaggers determine the supported types
+ * and the base type to use for each)
+ *
+ */
+template<typename ...Ts>
+struct AData {
+private:
+ static_assert(are_unique<Ts...>::value, "types must be unique");
+
+ static constexpr size_t num_types = sizeof...(Ts); ///< number of types to support
+
+public:
+ /**
+ * Default (strict) type flagger provided.
+ *
+ * The default flagger simply returns the index of the type within Ts, or 0 for void.
+ *
+ * Type flaggers return a flag for a supported type.
+ *
+ * They must provide:
+ *
+ * - a flagFor(T*) method for supported types _and_ for T=void. T=void is used to mark that no
+ * object is stored in the container. For this, an arbitrary unique value may be returned.
+ * - a mask field that contains the flag mask.
+ * - a canDeleteAs(Flag, Flag) flag comparison method that checks if a type of a flag can be
+ * deleted as another type.
+ *
+ * \param Flag the underlying unsigned integral to use for the flags.
+ */
+ template<typename Flag>
+ struct flagger {
+ private:
+ static_assert(std::is_unsigned<Flag>::value, "Flag must be unsigned");
+ static_assert(std::is_integral<Flag>::value, "Flag must be an integral type");
+
+ static constexpr Flag count = num_types + 1;
+
+ public:
+ typedef Flag type; ///< flag type
+
+ static constexpr Flag mask = _Flagged_helper::minMask<Flag>(count); ///< flag mask
+
+ /**
+ * Return the stored type for T. This is itself.
+ */
+ template<typename T>
+ struct store {
+ typedef T as_type; ///< the base type that T is stored as
+ };
+
+ /**
+ * Constexpr method that returns if two flags are compatible for deletion.
+ *
+ * \param objectFlag flag for object to be deleted
+ * \param deleteFlag flag for type that object is to be deleted as
+ */
+ static constexpr bool canDeleteAs(Flag objectFlag, Flag deleteFlag) {
+ // default flagger requires strict type equality
+ return objectFlag == deleteFlag;
+ }
+
+ /**
+ * Constexpr method that returns the flag to use for a given type.
+ *
+ * Function overload for void*.
+ */
+ static constexpr Flag flagFor(void*) {
+ return 0u;
+ }
+
+ /**
+ * Constexpr method that returns the flag to use for a given supported type (T).
+ */
+ template<typename T, typename=typename std::enable_if<is_one_of<T, Ts...>::value>::type>
+ static constexpr Flag flagFor(T*) {
+ return find_first<T, Ts...>::index;
+ }
+ };
+
+ /**
+ * Relaxed flagger returns the index of the type within Ts. However, for pointers T* it returns
+ * the first type in Ts that T* can be converted into (this is normally a base type, but also
+ * works for sp<>, shared_ptr<> or unique_ptr<>). For a bit more strictness, the flag also
+ * contains the size of the class to avoid finding objects that were stored as a different
+ * derived class of the same base class.
+ *
+ * Flag is basically the index of the (base) type in Ts multiplied by the max size stored plus
+ * the size of the type (divided by alignment) for derived pointer types.
+ *
+ * \param MaxSize max supported size for derived class pointers
+ * \param Align alignment to assume for derived class pointers
+ */
+ template<typename Flag, size_t MaxSize=1024, size_t Align=4>
+ struct relaxed_flagger {
+ private:
+ static_assert(std::is_unsigned<Flag>::value, "Flag must be unsigned");
+ static_assert(std::is_integral<Flag>::value, "Flag must be an integral type");
+
+ static constexpr Flag count = num_types + 1;
+ static_assert(std::numeric_limits<Flag>::max() / count > (MaxSize / Align),
+ "not enough bits to fit into flag");
+
+ static constexpr Flag max_size_stored = MaxSize / Align + 1;
+
+ // T can be converted if it's size is <= MaxSize and it can be converted to one of the Ts
+ template<typename T, size_t size>
+ using enable_if_can_be_converted = typename std::enable_if<
+ (size / Align < max_size_stored
+ && find_first_convertible_to<T, Ts...>::index)>::type;
+
+
+ template<typename W, typename T, typename=enable_if_can_be_converted<W, sizeof(T)>>
+ static constexpr Flag relaxedFlagFor(W*, T*) {
+ return find_first_convertible_to<W, Ts...>::index * max_size_stored
+ + (is_one_of<W, Ts...>::value ? 0 : (sizeof(T) / Align));
+ }
+
+ public:
+ typedef Flag type; ///< flag type
+
+ static constexpr Flag mask =
+ _Flagged_helper::minMask<Flag>(count * max_size_stored); ///< flag mask
+
+ /**
+ * Constexpr method that returns if two flags are compatible for deletion.
+ *
+ * \param objectFlag flag for object to be deleted
+ * \param deleteFlag flag for type that object is to be deleted as
+ */
+ static constexpr bool canDeleteAs(Flag objectFlag, Flag deleteFlag) {
+ // can delete if objects have the same base type
+ return
+ objectFlag / max_size_stored == deleteFlag / max_size_stored &&
+ (deleteFlag % max_size_stored) == 0;
+ }
+
+ /**
+ * Constexpr method that returns the flag to use for a given type.
+ *
+ * Function overload for void*.
+ */
+ static constexpr Flag flagFor(void*) {
+ return 0u;
+ }
+
+ /**
+ * Constexpr method that returns the flag to use for a given supported type (T).
+ *
+ * This is a member method to enable both overloading as well as template specialization.
+ */
+ template<typename T, typename=typename std::enable_if<is_one_of<T, Ts...>::value>::type>
+ static constexpr Flag flagFor(T*) {
+ return find_first<T, Ts...>::index * max_size_stored;
+ }
+
+ /**
+ * For precaution, we only consider converting pointers to their base classes.
+ */
+
+ /**
+ * Template specialization for derived class pointers and managed pointers.
+ */
+ template<typename T>
+ static constexpr Flag flagFor(T**p) { return relaxedFlagFor(p, (T*)0); }
+ template<typename T>
+ static constexpr Flag flagFor(std::shared_ptr<T>*p) { return relaxedFlagFor(p, (T*)0); }
+ template<typename T>
+ static constexpr Flag flagFor(std::unique_ptr<T>*p) { return relaxedFlagFor(p, (T*)0); }
+ template<typename T>
+ static constexpr Flag flagFor(std::weak_ptr<T>*p) { return relaxedFlagFor(p, (T*)0); }
+ template<typename T>
+ static constexpr Flag flagFor(sp<T>*p) { return relaxedFlagFor(p, (T*)0); }
+ template<typename T>
+ static constexpr Flag flagFor(wp<T>*p) { return relaxedFlagFor(p, (T*)0); }
+
+ /**
+ * Type support template that provodes the stored type for T.
+ * This is itself if it is one of Ts, or the first type in Ts that T is convertible to.
+ *
+ * NOTE: This template may provide a base class for an unsupported type. Support is
+ * determined by flagFor().
+ */
+ template<typename T>
+ struct store {
+ typedef typename std::conditional<
+ is_one_of<T, Ts...>::value,
+ T,
+ typename find_first_convertible_to<T, Ts...>::type>::type as_type;
+ };
+ };
+
+ /**
+ * Implementation of AData.
+ */
+ template<typename Flagger>
+ struct Custom : protected Flagged<AUnion<Ts...>, typename Flagger::type, Flagger::mask> {
+ using data_t = AUnion<Ts...>;
+ using base_t = Flagged<AUnion<Ts...>, typename Flagger::type, Flagger::mask>;
+
+ /**
+ * Constructor. Initializes this to a container that does not contain any object.
+ */
+ Custom() : base_t(Flagger::flagFor((void*)0)) { }
+
+ /**
+ * Removes the contained object, if any.
+ */
+ ~Custom() {
+ if (!this->clear()) {
+ __builtin_trap();
+ // std::cerr << "could not delete data of type " << this->flags() << std::endl;
+ }
+ }
+
+ /**
+ * Returns whether there is any object contained.
+ */
+ inline bool used() const {
+ return this->flags() != Flagger::flagFor((void*)0);
+ }
+
+ /**
+ * Removes the contained object, if any. Returns true if there are no objects contained,
+ * or false on any error (this is highly unexpected).
+ */
+ bool clear() {
+ if (this->used()) {
+ if (_AData_deleter<Flagger, data_t, Ts...>::del(this->flags(), this->get())) {
+ this->setFlags(Flagger::flagFor((void*)0));
+ return true;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ template<typename T>
+ using is_supported_by_flagger =
+ typename std::enable_if<Flagger::flagFor((T*)0) != Flagger::flagFor((void*)0)>::type;
+
+ /**
+ * Checks if there is a copiable object of type T in this container. If there is, it copies
+ * that object into the provided address and returns true. Otherwise, it does nothing and
+ * returns false.
+ *
+ * This method normally requires a flag equality between the stored and retrieved types.
+ * However, it also allows retrieving the stored object as the stored type
+ * (usually base type).
+ *
+ * \param T type of object to sought
+ * \param data address at which the object should be retrieved
+ *
+ * \return true if the object was retrieved. false if it was not.
+ */
+ template<
+ typename T,
+ typename=is_supported_by_flagger<T>>
+ bool find(T *data) const {
+ using B = typename Flagger::template store<T>::as_type;
+ if (this->flags() == Flagger::flagFor((T*)0) ||
+ Flagger::canDeleteAs(this->flags(), Flagger::flagFor((T*)0))) {
+ _AData_copier<T>::assign(data, this->get().template get<B>());
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Checks if there is an object of type T in this container. If there is, it moves that
+ * object into the provided address and returns true. Otherwise, it does nothing and returns
+ * false.
+ *
+ * This method normally requires a flag equality between the stored and retrieved types.
+ * However, it also allows retrieving the stored object as the stored type
+ * (usually base type).
+ *
+ * \param T type of object to sought
+ * \param data address at which the object should be retrieved.
+ *
+ * \return true if the object was retrieved. false if it was not.
+ */
+ template<
+ typename T,
+ typename=is_supported_by_flagger<T>>
+ bool remove(T *data) {
+ using B = typename Flagger::template store<T>::as_type;
+ if (this->flags() == Flagger::flagFor((T*)0) ||
+ Flagger::canDeleteAs(this->flags(), Flagger::flagFor((T*)0))) {
+ _AData_mover<T>::assign(data, std::move(this->get().template get<B>()));
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Stores an object into this container by copying. If it was successful, returns true.
+ * Otherwise, (e.g. it could not destroy the already stored object) it returns false. This
+ * latter would be highly unexpected.
+ *
+ * \param T type of object to store
+ * \param data object to store
+ *
+ * \return true if the object was stored. false if it was not.
+ */
+ template<
+ typename T,
+ typename=is_supported_by_flagger<T>,
+ typename=typename std::enable_if<
+ std::is_copy_constructible<T>::value ||
+ (std::is_default_constructible<T>::value &&
+ std::is_copy_assignable<T>::value)>::type>
+ bool set(const T &data) {
+ using B = typename Flagger::template store<T>::as_type;
+
+ // if already contains an object of this type, simply assign
+ if (this->flags() == Flagger::flagFor((T*)0) && std::is_same<T, B>::value) {
+ _AData_copier<B>::assign(&this->get().template get<B>(), data);
+ return true;
+ } else if (this->used()) {
+ // destroy previous object
+ if (!this->clear()) {
+ return false;
+ }
+ }
+ this->get().template emplace<B>(data);
+ this->setFlags(Flagger::flagFor((T *)0));
+ return true;
+ }
+
+ /**
+ * Moves an object into this container. If it was successful, returns true. Otherwise,
+ * (e.g. it could not destroy the already stored object) it returns false. This latter
+ * would be highly unexpected.
+ *
+ * \param T type of object to store
+ * \param data object to store
+ *
+ * \return true if the object was stored. false if it was not.
+ */
+ template<
+ typename T,
+ typename=is_supported_by_flagger<T>>
+ bool set(T &&data) {
+ using B = typename Flagger::template store<T>::as_type;
+
+ // if already contains an object of this type, simply assign
+ if (this->flags() == Flagger::flagFor((T*)0) && std::is_same<T, B>::value) {
+ _AData_mover<B>::assign(&this->get().template get<B>(), std::forward<T&&>(data));
+ return true;
+ } else if (this->used()) {
+ // destroy previous object
+ if (!this->clear()) {
+ return false;
+ }
+ }
+ this->get().template emplace<B>(std::forward<T&&>(data));
+ this->setFlags(Flagger::flagFor((T *)0));
+ return true;
+ }
+ };
+
+ /**
+ * Basic AData using the default type flagger and requested flag type.
+ *
+ * \param Flag desired flag type to use. Must be an unsigned and std::integral type.
+ */
+ template<typename Flag>
+ using Strict = Custom<flagger<Flag>>;
+
+ /**
+ * Basic AData using the default type flagger and uint32_t flag.
+ */
+ using Basic = Strict<uint32_t>;
+
+ /**
+ * AData using the relaxed type flagger for max size and requested flag type.
+ *
+ * \param Flag desired flag type to use. Must be an unsigned and std::integral type.
+ */
+ template<typename Flag, size_t MaxSize = 1024, size_t Align = 4>
+ using Relaxed = Custom<relaxed_flagger<Flag, MaxSize, Align>>;
+
+ /**
+ * Basic AData using the relaxed type flagger and uint32_t flag.
+ */
+ using RelaxedBasic = Relaxed<uint32_t>;
+};
+
+} // namespace android
+
+#endif // STAGEFRIGHT_FOUNDATION_A_DATA_H_
+
diff --git a/media/libstagefright/include/foundation/ADebug.h b/media/libstagefright/include/foundation/ADebug.h
new file mode 100644
index 0000000..564b3f7
--- /dev/null
+++ b/media/libstagefright/include/foundation/ADebug.h
@@ -0,0 +1,164 @@
+/*
+ * 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 A_DEBUG_H_
+
+#define A_DEBUG_H_
+
+#include <string.h>
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AString.h>
+#include <utils/Log.h>
+
+namespace android {
+
+inline static const char *asString(status_t i, const char *def = "??") {
+ switch (i) {
+ case NO_ERROR: return "NO_ERROR";
+ case UNKNOWN_ERROR: return "UNKNOWN_ERROR";
+ case NO_MEMORY: return "NO_MEMORY";
+ case INVALID_OPERATION: return "INVALID_OPERATION";
+ case BAD_VALUE: return "BAD_VALUE";
+ case BAD_TYPE: return "BAD_TYPE";
+ case NAME_NOT_FOUND: return "NAME_NOT_FOUND";
+ case PERMISSION_DENIED: return "PERMISSION_DENIED";
+ case NO_INIT: return "NO_INIT";
+ case ALREADY_EXISTS: return "ALREADY_EXISTS";
+ case DEAD_OBJECT: return "DEAD_OBJECT";
+ case FAILED_TRANSACTION: return "FAILED_TRANSACTION";
+ case BAD_INDEX: return "BAD_INDEX";
+ case NOT_ENOUGH_DATA: return "NOT_ENOUGH_DATA";
+ case WOULD_BLOCK: return "WOULD_BLOCK";
+ case TIMED_OUT: return "TIMED_OUT";
+ case UNKNOWN_TRANSACTION: return "UNKNOWN_TRANSACTION";
+ case FDS_NOT_ALLOWED: return "FDS_NOT_ALLOWED";
+ default: return def;
+ }
+}
+
+#define LITERAL_TO_STRING_INTERNAL(x) #x
+#define LITERAL_TO_STRING(x) LITERAL_TO_STRING_INTERNAL(x)
+
+#define CHECK(condition) \
+ LOG_ALWAYS_FATAL_IF( \
+ !(condition), \
+ "%s", \
+ __FILE__ ":" LITERAL_TO_STRING(__LINE__) \
+ " CHECK(" #condition ") failed.")
+
+#define MAKE_COMPARATOR(suffix,op) \
+ template<class A, class B> \
+ AString Compare_##suffix(const A &a, const B &b) { \
+ AString res; \
+ if (!(a op b)) { \
+ res.append(a); \
+ res.append(" vs. "); \
+ res.append(b); \
+ } \
+ return res; \
+ }
+
+MAKE_COMPARATOR(EQ,==)
+MAKE_COMPARATOR(NE,!=)
+MAKE_COMPARATOR(LE,<=)
+MAKE_COMPARATOR(GE,>=)
+MAKE_COMPARATOR(LT,<)
+MAKE_COMPARATOR(GT,>)
+
+#define CHECK_OP(x,y,suffix,op) \
+ do { \
+ AString ___res = Compare_##suffix(x, y); \
+ if (!___res.empty()) { \
+ AString ___full = \
+ __FILE__ ":" LITERAL_TO_STRING(__LINE__) \
+ " CHECK_" #suffix "( " #x "," #y ") failed: "; \
+ ___full.append(___res); \
+ \
+ LOG_ALWAYS_FATAL("%s", ___full.c_str()); \
+ } \
+ } while (false)
+
+#define CHECK_EQ(x,y) CHECK_OP(x,y,EQ,==)
+#define CHECK_NE(x,y) CHECK_OP(x,y,NE,!=)
+#define CHECK_LE(x,y) CHECK_OP(x,y,LE,<=)
+#define CHECK_LT(x,y) CHECK_OP(x,y,LT,<)
+#define CHECK_GE(x,y) CHECK_OP(x,y,GE,>=)
+#define CHECK_GT(x,y) CHECK_OP(x,y,GT,>)
+
+#define TRESPASS() \
+ LOG_ALWAYS_FATAL( \
+ __FILE__ ":" LITERAL_TO_STRING(__LINE__) \
+ " Should not be here.");
+
+struct ADebug {
+ enum Level {
+ kDebugNone, // no debug
+ kDebugLifeCycle, // lifecycle events: creation/deletion
+ kDebugState, // commands and events
+ kDebugConfig, // configuration
+ kDebugInternalState, // internal state changes
+ kDebugAll, // all
+ kDebugMax = kDebugAll,
+
+ };
+
+ // parse the property or string to get a long-type level for a component name
+ // string format is:
+ // <level>[:<glob>][,<level>[:<glob>]...]
+ // - <level> is 0-5 corresponding to ADebug::Level
+ // - <glob> is used to match component name case insensitively, if omitted, it
+ // matches all components
+ // - string is read left-to-right, and the last matching level is returned, or
+ // the def if no terms matched
+ static long GetLevelFromSettingsString(
+ const char *name, const char *value, long def);
+ static long GetLevelFromProperty(
+ const char *name, const char *value, long def);
+
+ // same for ADebug::Level - performs clamping to valid debug ranges
+ static Level GetDebugLevelFromProperty(
+ const char *name, const char *propertyName, Level def = kDebugNone);
+
+ // remove redundant segments of a codec name, and return a newly allocated
+ // string suitable for debugging
+ static char *GetDebugName(const char *name);
+
+ inline static bool isExperimentEnabled(
+ const char *name __unused /* nonnull */, bool allow __unused = true) {
+#ifdef ENABLE_STAGEFRIGHT_EXPERIMENTS
+ if (!strcmp(name, "legacy-adaptive")) {
+ return getExperimentFlag(allow, name, 2, 1); // every other day
+ } else if (!strcmp(name, "legacy-setsurface")) {
+ return getExperimentFlag(allow, name, 3, 1); // every third day
+ } else {
+ ALOGE("unknown experiment '%s' (disabled)", name);
+ }
+#endif
+ return false;
+ }
+
+private:
+ // pass in allow, so we can print in the log if the experiment is disabled
+ static bool getExperimentFlag(
+ bool allow, const char *name, uint64_t modulo, uint64_t limit,
+ uint64_t plus = 0, uint64_t timeDivisor = 24 * 60 * 60 /* 1 day */);
+};
+
+} // namespace android
+
+#endif // A_DEBUG_H_
+
diff --git a/media/libstagefright/include/foundation/AHandler.h b/media/libstagefright/include/foundation/AHandler.h
new file mode 100644
index 0000000..53d8a9b
--- /dev/null
+++ b/media/libstagefright/include/foundation/AHandler.h
@@ -0,0 +1,79 @@
+/*
+ * 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 A_HANDLER_H_
+
+#define A_HANDLER_H_
+
+#include <media/stagefright/foundation/ALooper.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct AMessage;
+
+struct AHandler : public RefBase {
+ AHandler()
+ : mID(0),
+ mVerboseStats(false),
+ mMessageCounter(0) {
+ }
+
+ ALooper::handler_id id() const {
+ return mID;
+ }
+
+ sp<ALooper> looper() const {
+ return mLooper.promote();
+ }
+
+ wp<ALooper> getLooper() const {
+ return mLooper;
+ }
+
+ wp<AHandler> getHandler() const {
+ // allow getting a weak reference to a const handler
+ return const_cast<AHandler *>(this);
+ }
+
+protected:
+ virtual void onMessageReceived(const sp<AMessage> &msg) = 0;
+
+private:
+ friend struct AMessage; // deliverMessage()
+ friend struct ALooperRoster; // setID()
+
+ ALooper::handler_id mID;
+ wp<ALooper> mLooper;
+
+ inline void setID(ALooper::handler_id id, const wp<ALooper> &looper) {
+ mID = id;
+ mLooper = looper;
+ }
+
+ bool mVerboseStats;
+ uint32_t mMessageCounter;
+ KeyedVector<uint32_t, uint32_t> mMessages;
+
+ void deliverMessage(const sp<AMessage> &msg);
+
+ DISALLOW_EVIL_CONSTRUCTORS(AHandler);
+};
+
+} // namespace android
+
+#endif // A_HANDLER_H_
diff --git a/media/libstagefright/include/foundation/AHandlerReflector.h b/media/libstagefright/include/foundation/AHandlerReflector.h
new file mode 100644
index 0000000..9d201b5
--- /dev/null
+++ b/media/libstagefright/include/foundation/AHandlerReflector.h
@@ -0,0 +1,48 @@
+/*
+ * 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 A_HANDLER_REFLECTOR_H_
+
+#define A_HANDLER_REFLECTOR_H_
+
+#include <media/stagefright/foundation/AHandler.h>
+
+namespace android {
+
+template<class T>
+struct AHandlerReflector : public AHandler {
+ AHandlerReflector(T *target)
+ : mTarget(target) {
+ }
+
+protected:
+ virtual void onMessageReceived(const sp<AMessage> &msg) {
+ sp<T> target = mTarget.promote();
+ if (target != NULL) {
+ target->onMessageReceived(msg);
+ }
+ }
+
+private:
+ wp<T> mTarget;
+
+ AHandlerReflector(const AHandlerReflector<T> &);
+ AHandlerReflector<T> &operator=(const AHandlerReflector<T> &);
+};
+
+} // namespace android
+
+#endif // A_HANDLER_REFLECTOR_H_
diff --git a/media/libstagefright/include/foundation/AHierarchicalStateMachine.h b/media/libstagefright/include/foundation/AHierarchicalStateMachine.h
new file mode 100644
index 0000000..3bb7d75
--- /dev/null
+++ b/media/libstagefright/include/foundation/AHierarchicalStateMachine.h
@@ -0,0 +1,65 @@
+/*
+ * 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 A_HIERARCHICAL_STATE_MACHINE_H_
+
+#define A_HIERARCHICAL_STATE_MACHINE_H_
+
+#include <media/stagefright/foundation/AHandler.h>
+
+namespace android {
+
+struct AState : public RefBase {
+ AState(const sp<AState> &parentState = NULL);
+
+ sp<AState> parentState();
+
+protected:
+ virtual ~AState();
+
+ virtual void stateEntered();
+ virtual void stateExited();
+
+ virtual bool onMessageReceived(const sp<AMessage> &msg) = 0;
+
+private:
+ friend struct AHierarchicalStateMachine;
+
+ sp<AState> mParentState;
+
+ DISALLOW_EVIL_CONSTRUCTORS(AState);
+};
+
+struct AHierarchicalStateMachine {
+ AHierarchicalStateMachine();
+
+protected:
+ virtual ~AHierarchicalStateMachine();
+
+ virtual void handleMessage(const sp<AMessage> &msg);
+
+ // Only to be called in response to a message.
+ void changeState(const sp<AState> &state);
+
+private:
+ sp<AState> mState;
+
+ DISALLOW_EVIL_CONSTRUCTORS(AHierarchicalStateMachine);
+};
+
+} // namespace android
+
+#endif // A_HIERARCHICAL_STATE_MACHINE_H_
diff --git a/media/libstagefright/include/foundation/ALookup.h b/media/libstagefright/include/foundation/ALookup.h
new file mode 100644
index 0000000..5a68806
--- /dev/null
+++ b/media/libstagefright/include/foundation/ALookup.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_LOOKUP_H_
+
+#define A_LOOKUP_H_
+
+#include <utility>
+#include <vector>
+
+namespace android {
+
+template<typename T, typename U>
+struct ALookup {
+ ALookup(std::initializer_list<std::pair<T, U>> list);
+
+ bool lookup(const T& from, U *to) const;
+ bool rlookup(const U& from, T *to) const;
+
+ template<typename V, typename = typename std::enable_if<!std::is_same<T, V>::value>::type>
+ inline bool map(const T& from, V *to) const { return lookup(from, to); }
+
+ template<typename V, typename = typename std::enable_if<!std::is_same<T, V>::value>::type>
+ inline bool map(const V& from, T *to) const { return rlookup(from, to); }
+
+private:
+ std::vector<std::pair<T, U>> mTable;
+};
+
+template<typename T, typename U>
+ALookup<T, U>::ALookup(std::initializer_list<std::pair<T, U>> list)
+ : mTable(list) {
+}
+
+template<typename T, typename U>
+bool ALookup<T, U>::lookup(const T& from, U *to) const {
+ for (auto elem : mTable) {
+ if (elem.first == from) {
+ *to = elem.second;
+ return true;
+ }
+ }
+ return false;
+}
+
+template<typename T, typename U>
+bool ALookup<T, U>::rlookup(const U& from, T *to) const {
+ for (auto elem : mTable) {
+ if (elem.second == from) {
+ *to = elem.first;
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace android
+
+#endif // A_UTILS_H_
diff --git a/media/libstagefright/include/foundation/ALooper.h b/media/libstagefright/include/foundation/ALooper.h
new file mode 100644
index 0000000..09c469b
--- /dev/null
+++ b/media/libstagefright/include/foundation/ALooper.h
@@ -0,0 +1,111 @@
+/*
+ * 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 A_LOOPER_H_
+
+#define A_LOOPER_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AString.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/List.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+
+namespace android {
+
+struct AHandler;
+struct AMessage;
+struct AReplyToken;
+
+struct ALooper : public RefBase {
+ typedef int32_t event_id;
+ typedef int32_t handler_id;
+
+ ALooper();
+
+ // Takes effect in a subsequent call to start().
+ void setName(const char *name);
+
+ handler_id registerHandler(const sp<AHandler> &handler);
+ void unregisterHandler(handler_id handlerID);
+
+ status_t start(
+ bool runOnCallingThread = false,
+ bool canCallJava = false,
+ int32_t priority = PRIORITY_DEFAULT
+ );
+
+ status_t stop();
+
+ static int64_t GetNowUs();
+
+ const char *getName() const {
+ return mName.c_str();
+ }
+
+protected:
+ virtual ~ALooper();
+
+private:
+ friend struct AMessage; // post()
+
+ struct Event {
+ int64_t mWhenUs;
+ sp<AMessage> mMessage;
+ };
+
+ Mutex mLock;
+ Condition mQueueChangedCondition;
+
+ AString mName;
+
+ List<Event> mEventQueue;
+
+ struct LooperThread;
+ sp<LooperThread> mThread;
+ bool mRunningLocally;
+
+ // use a separate lock for reply handling, as it is always on another thread
+ // use a central lock, however, to avoid creating a mutex for each reply
+ Mutex mRepliesLock;
+ Condition mRepliesCondition;
+
+ // START --- methods used only by AMessage
+
+ // posts a message on this looper with the given timeout
+ void post(const sp<AMessage> &msg, int64_t delayUs);
+
+ // creates a reply token to be used with this looper
+ sp<AReplyToken> createReplyToken();
+ // waits for a response for the reply token. If status is OK, the response
+ // is stored into the supplied variable. Otherwise, it is unchanged.
+ status_t awaitResponse(const sp<AReplyToken> &replyToken, sp<AMessage> *response);
+ // posts a reply for a reply token. If the reply could be successfully posted,
+ // it returns OK. Otherwise, it returns an error value.
+ status_t postReply(const sp<AReplyToken> &replyToken, const sp<AMessage> &msg);
+
+ // END --- methods used only by AMessage
+
+ bool loop();
+
+ DISALLOW_EVIL_CONSTRUCTORS(ALooper);
+};
+
+} // namespace android
+
+#endif // A_LOOPER_H_
diff --git a/media/libstagefright/include/foundation/ALooperRoster.h b/media/libstagefright/include/foundation/ALooperRoster.h
new file mode 100644
index 0000000..5873e68
--- /dev/null
+++ b/media/libstagefright/include/foundation/ALooperRoster.h
@@ -0,0 +1,53 @@
+/*
+ * 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 A_LOOPER_ROSTER_H_
+
+#define A_LOOPER_ROSTER_H_
+
+#include <media/stagefright/foundation/ALooper.h>
+#include <utils/KeyedVector.h>
+#include <utils/String16.h>
+
+namespace android {
+
+struct ALooperRoster {
+ ALooperRoster();
+
+ ALooper::handler_id registerHandler(
+ const sp<ALooper> &looper, const sp<AHandler> &handler);
+
+ void unregisterHandler(ALooper::handler_id handlerID);
+ void unregisterStaleHandlers();
+
+ void dump(int fd, const Vector<String16>& args);
+
+private:
+ struct HandlerInfo {
+ wp<ALooper> mLooper;
+ wp<AHandler> mHandler;
+ };
+
+ Mutex mLock;
+ KeyedVector<ALooper::handler_id, HandlerInfo> mHandlers;
+ ALooper::handler_id mNextHandlerID;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ALooperRoster);
+};
+
+} // namespace android
+
+#endif // A_LOOPER_ROSTER_H_
diff --git a/media/libstagefright/include/foundation/AMessage.h b/media/libstagefright/include/foundation/AMessage.h
new file mode 100644
index 0000000..782f8e6
--- /dev/null
+++ b/media/libstagefright/include/foundation/AMessage.h
@@ -0,0 +1,241 @@
+/*
+ * 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 A_MESSAGE_H_
+
+#define A_MESSAGE_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct ABuffer;
+struct AHandler;
+struct AString;
+class Parcel;
+
+struct AReplyToken : public RefBase {
+ explicit AReplyToken(const sp<ALooper> &looper)
+ : mLooper(looper),
+ mReplied(false) {
+ }
+
+private:
+ friend struct AMessage;
+ friend struct ALooper;
+ wp<ALooper> mLooper;
+ sp<AMessage> mReply;
+ bool mReplied;
+
+ sp<ALooper> getLooper() const {
+ return mLooper.promote();
+ }
+ // if reply is not set, returns false; otherwise, it retrieves the reply and returns true
+ bool retrieveReply(sp<AMessage> *reply) {
+ if (mReplied) {
+ *reply = mReply;
+ mReply.clear();
+ }
+ return mReplied;
+ }
+ // sets the reply for this token. returns OK or error
+ status_t setReply(const sp<AMessage> &reply);
+};
+
+struct AMessage : public RefBase {
+ AMessage();
+ AMessage(uint32_t what, const sp<const AHandler> &handler);
+
+ // Construct an AMessage from a parcel.
+ // nestingAllowed determines how many levels AMessage can be nested inside
+ // AMessage. The default value here is arbitrarily set to 255.
+ // FromParcel() returns NULL on error, which occurs when the input parcel
+ // contains
+ // - an AMessage nested deeper than maxNestingLevel; or
+ // - an item whose type is not recognized by this function.
+ // Types currently recognized by this function are:
+ // Item types set/find function suffixes
+ // ==========================================
+ // int32_t Int32
+ // int64_t Int64
+ // size_t Size
+ // float Float
+ // double Double
+ // AString String
+ // AMessage Message
+ static sp<AMessage> FromParcel(const Parcel &parcel,
+ size_t maxNestingLevel = 255);
+
+ // Write this AMessage to a parcel.
+ // All items in the AMessage must have types that are recognized by
+ // FromParcel(); otherwise, TRESPASS error will occur.
+ void writeToParcel(Parcel *parcel) const;
+
+ void setWhat(uint32_t what);
+ uint32_t what() const;
+
+ void setTarget(const sp<const AHandler> &handler);
+
+ void clear();
+
+ void setInt32(const char *name, int32_t value);
+ void setInt64(const char *name, int64_t value);
+ void setSize(const char *name, size_t value);
+ void setFloat(const char *name, float value);
+ void setDouble(const char *name, double value);
+ void setPointer(const char *name, void *value);
+ void setString(const char *name, const char *s, ssize_t len = -1);
+ void setString(const char *name, const AString &s);
+ void setObject(const char *name, const sp<RefBase> &obj);
+ void setBuffer(const char *name, const sp<ABuffer> &buffer);
+ void setMessage(const char *name, const sp<AMessage> &obj);
+
+ void setRect(
+ const char *name,
+ int32_t left, int32_t top, int32_t right, int32_t bottom);
+
+ bool contains(const char *name) const;
+
+ bool findInt32(const char *name, int32_t *value) const;
+ bool findInt64(const char *name, int64_t *value) const;
+ bool findSize(const char *name, size_t *value) const;
+ bool findFloat(const char *name, float *value) const;
+ bool findDouble(const char *name, double *value) const;
+ bool findPointer(const char *name, void **value) const;
+ bool findString(const char *name, AString *value) const;
+ bool findObject(const char *name, sp<RefBase> *obj) const;
+ bool findBuffer(const char *name, sp<ABuffer> *buffer) const;
+ bool findMessage(const char *name, sp<AMessage> *obj) const;
+
+ // finds any numeric type cast to a float
+ bool findAsFloat(const char *name, float *value) const;
+
+ bool findRect(
+ const char *name,
+ int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) const;
+
+ status_t post(int64_t delayUs = 0);
+
+ // Posts the message to its target and waits for a response (or error)
+ // before returning.
+ status_t postAndAwaitResponse(sp<AMessage> *response);
+
+ // If this returns true, the sender of this message is synchronously
+ // awaiting a response and the reply token is consumed from the message
+ // and stored into replyID. The reply token must be used to send the response
+ // using "postReply" below.
+ bool senderAwaitsResponse(sp<AReplyToken> *replyID);
+
+ // Posts the message as a response to a reply token. A reply token can
+ // only be used once. Returns OK if the response could be posted; otherwise,
+ // an error.
+ status_t postReply(const sp<AReplyToken> &replyID);
+
+ // Performs a deep-copy of "this", contained messages are in turn "dup'ed".
+ // Warning: RefBase items, i.e. "objects" are _not_ copied but only have
+ // their refcount incremented.
+ sp<AMessage> dup() const;
+
+ // Performs a shallow or deep comparison of |this| and |other| and returns
+ // an AMessage with the differences.
+ // Warning: RefBase items, i.e. "objects" are _not_ copied but only have
+ // their refcount incremented.
+ // This is true for AMessages that have no corresponding AMessage equivalent in |other|.
+ // (E.g. there is no such key or the type is different.) On the other hand, changes in
+ // the AMessage (or AMessages if deep is |false|) are returned in new objects.
+ sp<AMessage> changesFrom(const sp<const AMessage> &other, bool deep = false) const;
+
+ AString debugString(int32_t indent = 0) const;
+
+ enum Type {
+ kTypeInt32,
+ kTypeInt64,
+ kTypeSize,
+ kTypeFloat,
+ kTypeDouble,
+ kTypePointer,
+ kTypeString,
+ kTypeObject,
+ kTypeMessage,
+ kTypeRect,
+ kTypeBuffer,
+ };
+
+ size_t countEntries() const;
+ const char *getEntryNameAt(size_t index, Type *type) const;
+
+protected:
+ virtual ~AMessage();
+
+private:
+ friend struct ALooper; // deliver()
+
+ uint32_t mWhat;
+
+ // used only for debugging
+ ALooper::handler_id mTarget;
+
+ wp<AHandler> mHandler;
+ wp<ALooper> mLooper;
+
+ struct Rect {
+ int32_t mLeft, mTop, mRight, mBottom;
+ };
+
+ struct Item {
+ union {
+ int32_t int32Value;
+ int64_t int64Value;
+ size_t sizeValue;
+ float floatValue;
+ double doubleValue;
+ void *ptrValue;
+ RefBase *refValue;
+ AString *stringValue;
+ Rect rectValue;
+ } u;
+ const char *mName;
+ size_t mNameLength;
+ Type mType;
+ void setName(const char *name, size_t len);
+ };
+
+ enum {
+ kMaxNumItems = 64
+ };
+ Item mItems[kMaxNumItems];
+ size_t mNumItems;
+
+ Item *allocateItem(const char *name);
+ void freeItemValue(Item *item);
+ const Item *findItem(const char *name, Type type) const;
+
+ void setObjectInternal(
+ const char *name, const sp<RefBase> &obj, Type type);
+
+ size_t findItemIndex(const char *name, size_t len) const;
+
+ void deliver();
+
+ DISALLOW_EVIL_CONSTRUCTORS(AMessage);
+};
+
+} // namespace android
+
+#endif // A_MESSAGE_H_
diff --git a/media/libstagefright/include/foundation/ANetworkSession.h b/media/libstagefright/include/foundation/ANetworkSession.h
new file mode 100644
index 0000000..fd3ebaa
--- /dev/null
+++ b/media/libstagefright/include/foundation/ANetworkSession.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_NETWORK_SESSION_H_
+
+#define A_NETWORK_SESSION_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+#include <utils/Thread.h>
+
+#include <netinet/in.h>
+
+namespace android {
+
+struct AMessage;
+
+// Helper class to manage a number of live sockets (datagram and stream-based)
+// on a single thread. Clients are notified about activity through AMessages.
+struct ANetworkSession : public RefBase {
+ ANetworkSession();
+
+ status_t start();
+ status_t stop();
+
+ status_t createRTSPClient(
+ const char *host, unsigned port, const sp<AMessage> ¬ify,
+ int32_t *sessionID);
+
+ status_t createRTSPServer(
+ const struct in_addr &addr, unsigned port,
+ const sp<AMessage> ¬ify, int32_t *sessionID);
+
+ status_t createUDPSession(
+ unsigned localPort, const sp<AMessage> ¬ify, int32_t *sessionID);
+
+ status_t createUDPSession(
+ unsigned localPort,
+ const char *remoteHost,
+ unsigned remotePort,
+ const sp<AMessage> ¬ify,
+ int32_t *sessionID);
+
+ status_t connectUDPSession(
+ int32_t sessionID, const char *remoteHost, unsigned remotePort);
+
+ // passive
+ status_t createTCPDatagramSession(
+ const struct in_addr &addr, unsigned port,
+ const sp<AMessage> ¬ify, int32_t *sessionID);
+
+ // active
+ status_t createTCPDatagramSession(
+ unsigned localPort,
+ const char *remoteHost,
+ unsigned remotePort,
+ const sp<AMessage> ¬ify,
+ int32_t *sessionID);
+
+ status_t destroySession(int32_t sessionID);
+
+ status_t sendRequest(
+ int32_t sessionID, const void *data, ssize_t size = -1,
+ bool timeValid = false, int64_t timeUs = -1ll);
+
+ status_t switchToWebSocketMode(int32_t sessionID);
+
+ enum NotificationReason {
+ kWhatError,
+ kWhatConnected,
+ kWhatClientConnected,
+ kWhatData,
+ kWhatDatagram,
+ kWhatBinaryData,
+ kWhatWebSocketMessage,
+ kWhatNetworkStall,
+ };
+
+protected:
+ virtual ~ANetworkSession();
+
+private:
+ struct NetworkThread;
+ struct Session;
+
+ Mutex mLock;
+ sp<Thread> mThread;
+
+ int32_t mNextSessionID;
+
+ int mPipeFd[2];
+
+ KeyedVector<int32_t, sp<Session> > mSessions;
+
+ enum Mode {
+ kModeCreateUDPSession,
+ kModeCreateTCPDatagramSessionPassive,
+ kModeCreateTCPDatagramSessionActive,
+ kModeCreateRTSPServer,
+ kModeCreateRTSPClient,
+ };
+ status_t createClientOrServer(
+ Mode mode,
+ const struct in_addr *addr,
+ unsigned port,
+ const char *remoteHost,
+ unsigned remotePort,
+ const sp<AMessage> ¬ify,
+ int32_t *sessionID);
+
+ void threadLoop();
+ void interrupt();
+
+ static status_t MakeSocketNonBlocking(int s);
+
+ DISALLOW_EVIL_CONSTRUCTORS(ANetworkSession);
+};
+
+} // namespace android
+
+#endif // A_NETWORK_SESSION_H_
diff --git a/media/libstagefright/include/foundation/AString.h b/media/libstagefright/include/foundation/AString.h
new file mode 100644
index 0000000..ff086b3
--- /dev/null
+++ b/media/libstagefright/include/foundation/AString.h
@@ -0,0 +1,110 @@
+/*
+ * 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 A_STRING_H_
+
+#define A_STRING_H_
+
+#include <utils/Errors.h>
+#include <sys/types.h>
+
+namespace android {
+
+class String8;
+class Parcel;
+
+struct AString {
+ AString();
+ AString(const char *s); // NOLINT, implicit conversion
+ AString(const char *s, size_t size);
+ AString(const String8 &from); // NOLINT, implicit conversion
+ AString(const AString &from);
+ AString(const AString &from, size_t offset, size_t n);
+ ~AString();
+
+ AString &operator=(const AString &from);
+ void setTo(const char *s);
+ void setTo(const char *s, size_t size);
+ void setTo(const AString &from, size_t offset, size_t n);
+
+ size_t size() const;
+ const char *c_str() const;
+
+ bool empty() const;
+
+ void clear();
+ void trim();
+ void erase(size_t start, size_t n);
+
+ void append(char c) { append(&c, 1); }
+ void append(const char *s);
+ void append(const char *s, size_t size);
+ void append(const AString &from);
+ void append(const AString &from, size_t offset, size_t n);
+ void append(int x);
+ void append(unsigned x);
+ void append(long x);
+ void append(unsigned long x);
+ void append(long long x);
+ void append(unsigned long long x);
+ void append(float x);
+ void append(double x);
+ void append(void *x);
+
+ void insert(const AString &from, size_t insertionPos);
+ void insert(const char *from, size_t size, size_t insertionPos);
+
+ ssize_t find(const char *substring, size_t start = 0) const;
+
+ size_t hash() const;
+
+ bool operator==(const AString &other) const;
+ bool operator!=(const AString &other) const {
+ return !operator==(other);
+ }
+ bool operator<(const AString &other) const;
+ bool operator>(const AString &other) const;
+
+ int compare(const AString &other) const;
+ int compareIgnoreCase(const AString &other) const;
+
+ bool equalsIgnoreCase(const AString &other) const;
+ bool startsWith(const char *prefix) const;
+ bool endsWith(const char *suffix) const;
+ bool startsWithIgnoreCase(const char *prefix) const;
+ bool endsWithIgnoreCase(const char *suffix) const;
+
+ void tolower();
+
+ static AString FromParcel(const Parcel &parcel);
+ status_t writeToParcel(Parcel *parcel) const;
+
+private:
+ static const char *kEmptyString;
+
+ char *mData;
+ size_t mSize;
+ size_t mAllocSize;
+
+ void makeMutable();
+};
+
+AString AStringPrintf(const char *format, ...);
+
+} // namespace android
+
+#endif // A_STRING_H_
+
diff --git a/media/libstagefright/include/foundation/AStringUtils.h b/media/libstagefright/include/foundation/AStringUtils.h
new file mode 100644
index 0000000..76a7791
--- /dev/null
+++ b/media/libstagefright/include/foundation/AStringUtils.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_STRING_UTILS_H_
+#define A_STRING_UTILS_H_
+
+#include <stdlib.h>
+
+namespace android {
+
+struct AStringUtils {
+ // similar to strncmp or strcasecmp, but case sensitivity is parametric
+ static int Compare(const char *a, const char *b, size_t len, bool ignoreCase);
+
+ // matches a string (str) to a glob pattern that supports:
+ // * - matches any number of characters
+ static bool MatchesGlob(
+ const char *glob, size_t globLen, const char *str, size_t strLen, bool ignoreCase);
+};
+
+} // namespace android
+
+#endif // A_STRING_UTILS_H_
diff --git a/media/libstagefright/include/foundation/AUtils.h b/media/libstagefright/include/foundation/AUtils.h
new file mode 100644
index 0000000..255a0f4
--- /dev/null
+++ b/media/libstagefright/include/foundation/AUtils.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_UTILS_H_
+
+#define A_UTILS_H_
+
+/* ============================ math templates ============================ */
+
+/* T must be integer type, den must not be 0 */
+template<class T>
+inline static const T divRound(const T &nom, const T &den) {
+ if ((nom >= 0) ^ (den >= 0)) {
+ return (nom - den / 2) / den;
+ } else {
+ return (nom + den / 2) / den;
+ }
+}
+
+/* == ceil(nom / den). T must be integer type, den must not be 0 */
+template<class T>
+inline static const T divUp(const T &nom, const T &den) {
+ if (den < 0) {
+ return (nom < 0 ? nom + den + 1 : nom) / den;
+ } else {
+ return (nom < 0 ? nom : nom + den - 1) / den;
+ }
+}
+
+/* == ceil(nom / den) * den. T must be integer type, alignment must be positive power of 2 */
+template<class T, class U>
+inline static const T align(const T &nom, const U &den) {
+ return (nom + (T)(den - 1)) & (T)~(den - 1);
+}
+
+template<class T>
+inline static T abs(const T &a) {
+ return a < 0 ? -a : a;
+}
+
+template<class T>
+inline static const T &min(const T &a, const T &b) {
+ return a < b ? a : b;
+}
+
+template<class T>
+inline static const T &max(const T &a, const T &b) {
+ return a > b ? a : b;
+}
+
+template<class T>
+void ENSURE_UNSIGNED_TYPE() {
+ T TYPE_MUST_BE_UNSIGNED[(T)-1 < 0 ? -1 : 0] __unused;
+}
+
+// needle is in range [hayStart, hayStart + haySize)
+template<class T, class U>
+__attribute__((no_sanitize("integer")))
+inline static bool isInRange(const T &hayStart, const U &haySize, const T &needle) {
+ ENSURE_UNSIGNED_TYPE<U>();
+ return (T)(hayStart + haySize) >= hayStart && needle >= hayStart && (U)(needle - hayStart) < haySize;
+}
+
+// [needleStart, needleStart + needleSize) is in range [hayStart, hayStart + haySize)
+template<class T, class U>
+__attribute__((no_sanitize("integer")))
+inline static bool isInRange(
+ const T &hayStart, const U &haySize, const T &needleStart, const U &needleSize) {
+ ENSURE_UNSIGNED_TYPE<U>();
+ return isInRange(hayStart, haySize, needleStart)
+ && (T)(needleStart + needleSize) >= needleStart
+ && (U)(needleStart + needleSize - hayStart) <= haySize;
+}
+
+/* T must be integer type, period must be positive */
+template<class T>
+inline static T periodicError(const T &val, const T &period) {
+ T err = abs(val) % period;
+ return (err < (period / 2)) ? err : (period - err);
+}
+
+#endif // A_UTILS_H_
diff --git a/media/libstagefright/include/foundation/AWakeLock.h b/media/libstagefright/include/foundation/AWakeLock.h
new file mode 100644
index 0000000..323e7d7
--- /dev/null
+++ b/media/libstagefright/include/foundation/AWakeLock.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_WAKELOCK_H_
+#define A_WAKELOCK_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <powermanager/IPowerManager.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+class AWakeLock : public RefBase {
+
+public:
+ AWakeLock();
+
+ // NOTE: acquire and release are not thread safe
+
+ // returns true if wakelock was acquired
+ bool acquire();
+ void release(bool force = false);
+
+ virtual ~AWakeLock();
+
+private:
+ sp<IPowerManager> mPowerManager;
+ sp<IBinder> mWakeLockToken;
+ uint32_t mWakeLockCount;
+
+ class PMDeathRecipient : public IBinder::DeathRecipient {
+ public:
+ explicit PMDeathRecipient(AWakeLock *wakeLock) : mWakeLock(wakeLock) {}
+ virtual ~PMDeathRecipient() {}
+
+ // IBinder::DeathRecipient
+ virtual void binderDied(const wp<IBinder> &who);
+
+ private:
+ PMDeathRecipient(const PMDeathRecipient&);
+ PMDeathRecipient& operator= (const PMDeathRecipient&);
+
+ AWakeLock *mWakeLock;
+ };
+
+ const sp<PMDeathRecipient> mDeathRecipient;
+
+ void clearPowerManager();
+
+ DISALLOW_EVIL_CONSTRUCTORS(AWakeLock);
+};
+
+} // namespace android
+
+#endif // A_WAKELOCK_H_
diff --git a/media/libstagefright/include/foundation/ColorUtils.h b/media/libstagefright/include/foundation/ColorUtils.h
new file mode 100644
index 0000000..b889a02
--- /dev/null
+++ b/media/libstagefright/include/foundation/ColorUtils.h
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2016 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 COLOR_UTILS_H_
+
+#define COLOR_UTILS_H_
+
+#include <stdint.h>
+
+#define STRINGIFY_ENUMS
+
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <media/hardware/VideoAPI.h>
+#include <system/graphics.h>
+
+namespace android {
+
+struct ColorUtils {
+ /*
+ * Media-platform color constants. MediaCodec uses (an extended version of) platform-defined
+ * constants that are derived from HAL_DATASPACE, since these are directly exposed to the user.
+ * We extend the values to maintain the richer set of information defined inside media
+ * containers and bitstreams that are not supported by the platform. We also expect vendors
+ * to extend some of these values with vendor-specific values. These are separated into a
+ * vendor-extension section so they won't collide with future platform values.
+ */
+
+#define GET_HAL_ENUM(class, name) HAL_DATASPACE_##class##name
+#define GET_HAL_BITFIELD(class, name) (GET_HAL_ENUM(class, _##name) >> GET_HAL_ENUM(class, _SHIFT))
+
+ enum ColorStandard : uint32_t {
+ kColorStandardUnspecified = GET_HAL_BITFIELD(STANDARD, UNSPECIFIED),
+ kColorStandardBT709 = GET_HAL_BITFIELD(STANDARD, BT709),
+ kColorStandardBT601_625 = GET_HAL_BITFIELD(STANDARD, BT601_625),
+ kColorStandardBT601_625_Unadjusted = GET_HAL_BITFIELD(STANDARD, BT601_625_UNADJUSTED),
+ kColorStandardBT601_525 = GET_HAL_BITFIELD(STANDARD, BT601_525),
+ kColorStandardBT601_525_Unadjusted = GET_HAL_BITFIELD(STANDARD, BT601_525_UNADJUSTED),
+ kColorStandardBT2020 = GET_HAL_BITFIELD(STANDARD, BT2020),
+ kColorStandardBT2020Constant = GET_HAL_BITFIELD(STANDARD, BT2020_CONSTANT_LUMINANCE),
+ kColorStandardBT470M = GET_HAL_BITFIELD(STANDARD, BT470M),
+ kColorStandardFilm = GET_HAL_BITFIELD(STANDARD, FILM),
+ kColorStandardMax = GET_HAL_BITFIELD(STANDARD, MASK),
+
+ /* This marks a section of color-standard values that are not supported by graphics HAL,
+ but track defined color primaries-matrix coefficient combinations in media.
+ These are stable for a given release. */
+ kColorStandardExtendedStart = kColorStandardMax + 1,
+
+ /* This marks a section of color-standard values that are not supported by graphics HAL
+ nor using media defined color primaries or matrix coefficients. These may differ per
+ device. */
+ kColorStandardVendorStart = 0x10000,
+ };
+
+ enum ColorTransfer : uint32_t {
+ kColorTransferUnspecified = GET_HAL_BITFIELD(TRANSFER, UNSPECIFIED),
+ kColorTransferLinear = GET_HAL_BITFIELD(TRANSFER, LINEAR),
+ kColorTransferSRGB = GET_HAL_BITFIELD(TRANSFER, SRGB),
+ kColorTransferSMPTE_170M = GET_HAL_BITFIELD(TRANSFER, SMPTE_170M),
+ kColorTransferGamma22 = GET_HAL_BITFIELD(TRANSFER, GAMMA2_2),
+ kColorTransferGamma28 = GET_HAL_BITFIELD(TRANSFER, GAMMA2_8),
+ kColorTransferST2084 = GET_HAL_BITFIELD(TRANSFER, ST2084),
+ kColorTransferHLG = GET_HAL_BITFIELD(TRANSFER, HLG),
+ kColorTransferMax = GET_HAL_BITFIELD(TRANSFER, MASK),
+
+ /* This marks a section of color-transfer values that are not supported by graphics HAL,
+ but track media-defined color-transfer. These are stable for a given release. */
+ kColorTransferExtendedStart = kColorTransferMax + 1,
+
+ /* This marks a section of color-transfer values that are not supported by graphics HAL
+ nor defined by media. These may differ per device. */
+ kColorTransferVendorStart = 0x10000,
+ };
+
+ enum ColorRange : uint32_t {
+ kColorRangeUnspecified = GET_HAL_BITFIELD(RANGE, UNSPECIFIED),
+ kColorRangeFull = GET_HAL_BITFIELD(RANGE, FULL),
+ kColorRangeLimited = GET_HAL_BITFIELD(RANGE, LIMITED),
+ kColorRangeMax = GET_HAL_BITFIELD(RANGE, MASK),
+
+ /* This marks a section of color-transfer values that are not supported by graphics HAL,
+ but track media-defined color-transfer. These are stable for a given release. */
+ kColorRangeExtendedStart = kColorRangeMax + 1,
+
+ /* This marks a section of color-transfer values that are not supported by graphics HAL
+ nor defined by media. These may differ per device. */
+ kColorRangeVendorStart = 0x10000,
+ };
+
+#undef GET_HAL_BITFIELD
+#undef GET_HAL_ENUM
+
+ /*
+ * Static utilities for codec support
+ */
+
+ // using int32_t for media range/standard/transfers to denote extended ranges
+ // wrap methods change invalid aspects to the Unspecified value
+ static int32_t wrapColorAspectsIntoColorStandard(
+ ColorAspects::Primaries primaries, ColorAspects::MatrixCoeffs coeffs);
+ static int32_t wrapColorAspectsIntoColorRange(ColorAspects::Range range);
+ static int32_t wrapColorAspectsIntoColorTransfer(ColorAspects::Transfer transfer);
+
+ // unwrap methods change invalid aspects to the Other value
+ static status_t unwrapColorAspectsFromColorRange(
+ int32_t range, ColorAspects::Range *aspect);
+ static status_t unwrapColorAspectsFromColorTransfer(
+ int32_t transfer, ColorAspects::Transfer *aspect);
+ static status_t unwrapColorAspectsFromColorStandard(
+ int32_t standard,
+ ColorAspects::Primaries *primaries, ColorAspects::MatrixCoeffs *coeffs);
+
+ static status_t convertPlatformColorAspectsToCodecAspects(
+ int32_t range, int32_t standard, int32_t transfer, ColorAspects &aspects);
+ static status_t convertCodecColorAspectsToPlatformAspects(
+ const ColorAspects &aspects, int32_t *range, int32_t *standard, int32_t *transfer);
+
+ // converts Other values to Unspecified
+ static void convertCodecColorAspectsToIsoAspects(
+ const ColorAspects &aspects,
+ int32_t *primaries, int32_t *transfer, int32_t *coeffs, bool *fullRange);
+ // converts unsupported values to Other
+ static void convertIsoColorAspectsToCodecAspects(
+ int32_t primaries, int32_t transfer, int32_t coeffs, bool fullRange,
+ ColorAspects &aspects);
+
+ // unpack a uint32_t to a full ColorAspects struct
+ static ColorAspects unpackToColorAspects(uint32_t packed);
+
+ // pack a full ColorAspects struct into a uint32_t
+ static uint32_t packToU32(const ColorAspects &aspects);
+
+ // updates Unspecified color aspects to their defaults based on the video size
+ static void setDefaultCodecColorAspectsIfNeeded(
+ ColorAspects &aspects, int32_t width, int32_t height);
+
+ // it returns the closest dataSpace for given color |aspects|. if |mayExpand| is true, it allows
+ // returning a larger dataSpace that contains the color space given by |aspects|, and is better
+ // suited to blending. This requires implicit color space conversion on part of the device.
+ static android_dataspace getDataSpaceForColorAspects(ColorAspects &aspects, bool mayExpand);
+
+ // converts |dataSpace| to a V0 enum, and returns true if dataSpace is an aspect-only value
+ static bool convertDataSpaceToV0(android_dataspace &dataSpace);
+
+ // compares |aspect| to |orig|. Returns |true| if any aspects have changed, except if they
+ // changed to Unspecified value. It also sets the changed values to Unspecified in |aspect|.
+ static bool checkIfAspectsChangedAndUnspecifyThem(
+ ColorAspects &aspects, const ColorAspects &orig, bool usePlatformAspects = false);
+
+ // finds color config in format, defaulting them to 0.
+ static void getColorConfigFromFormat(
+ const sp<AMessage> &format, int *range, int *standard, int *transfer);
+
+ // copies existing color config from |source| to |target|.
+ static void copyColorConfig(const sp<AMessage> &source, sp<AMessage> &target);
+
+ // finds color config in format as ColorAspects, defaulting them to 0.
+ static void getColorAspectsFromFormat(const sp<AMessage> &format, ColorAspects &aspects);
+
+ // writes |aspects| into format. iff |force| is false, Unspecified values are not
+ // written.
+ static void setColorAspectsIntoFormat(
+ const ColorAspects &aspects, sp<AMessage> &format, bool force = false);
+
+ // finds HDR metadata in format as HDRStaticInfo, defaulting them to 0.
+ // Return |true| if could find HDR metadata in format. Otherwise, return |false|.
+ static bool getHDRStaticInfoFromFormat(const sp<AMessage> &format, HDRStaticInfo *info);
+
+ // writes |info| into format.
+ static void setHDRStaticInfoIntoFormat(const HDRStaticInfo &info, sp<AMessage> &format);
+};
+
+inline static const char *asString(android::ColorUtils::ColorStandard i, const char *def = "??") {
+ using namespace android;
+ switch (i) {
+ case ColorUtils::kColorStandardUnspecified: return "Unspecified";
+ case ColorUtils::kColorStandardBT709: return "BT709";
+ case ColorUtils::kColorStandardBT601_625: return "BT601_625";
+ case ColorUtils::kColorStandardBT601_625_Unadjusted: return "BT601_625_Unadjusted";
+ case ColorUtils::kColorStandardBT601_525: return "BT601_525";
+ case ColorUtils::kColorStandardBT601_525_Unadjusted: return "BT601_525_Unadjusted";
+ case ColorUtils::kColorStandardBT2020: return "BT2020";
+ case ColorUtils::kColorStandardBT2020Constant: return "BT2020Constant";
+ case ColorUtils::kColorStandardBT470M: return "BT470M";
+ case ColorUtils::kColorStandardFilm: return "Film";
+ default: return def;
+ }
+}
+
+inline static const char *asString(android::ColorUtils::ColorTransfer i, const char *def = "??") {
+ using namespace android;
+ switch (i) {
+ case ColorUtils::kColorTransferUnspecified: return "Unspecified";
+ case ColorUtils::kColorTransferLinear: return "Linear";
+ case ColorUtils::kColorTransferSRGB: return "SRGB";
+ case ColorUtils::kColorTransferSMPTE_170M: return "SMPTE_170M";
+ case ColorUtils::kColorTransferGamma22: return "Gamma22";
+ case ColorUtils::kColorTransferGamma28: return "Gamma28";
+ case ColorUtils::kColorTransferST2084: return "ST2084";
+ case ColorUtils::kColorTransferHLG: return "HLG";
+ default: return def;
+ }
+}
+
+inline static const char *asString(android::ColorUtils::ColorRange i, const char *def = "??") {
+ using namespace android;
+ switch (i) {
+ case ColorUtils::kColorRangeUnspecified: return "Unspecified";
+ case ColorUtils::kColorRangeFull: return "Full";
+ case ColorUtils::kColorRangeLimited: return "Limited";
+ default: return def;
+ }
+}
+
+} // namespace android
+
+#endif // COLOR_UTILS_H_
+
diff --git a/media/libstagefright/include/foundation/Flagged.h b/media/libstagefright/include/foundation/Flagged.h
new file mode 100644
index 0000000..bf0afbf
--- /dev/null
+++ b/media/libstagefright/include/foundation/Flagged.h
@@ -0,0 +1,513 @@
+/*
+ * Copyright (C) 2016 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 STAGEFRIGHT_FOUNDATION_FLAGGED_H_
+#define STAGEFRIGHT_FOUNDATION_FLAGGED_H_
+
+#include <media/stagefright/foundation/TypeTraits.h>
+
+namespace android {
+
+/**
+ * Flagged<T, Flag> is basically a specialized std::pair<Flag, T> that automatically optimizes out
+ * the flag if the wrapped type T is already flagged and we can combine the outer and inner flags.
+ *
+ * Flags can be queried/manipulated via flags() an setFlags(Flags). The wrapped value can be
+ * accessed via get(). This template is meant to be inherited by other utility/wrapper classes
+ * that need to store integral information along with the value.
+ *
+ * Users must specify the used bits (MASK) in the flags. Flag getters and setters will enforce this
+ * mask. _Flagged_helper::minMask<Flag> is provided to easily calculate a mask for a max value.
+ *
+ * E.g. adding a safe flag can be achieved like this:
+ *
+ *
+ * enum SafeFlags : uint32_t {
+ * kUnsafe,
+ * kSafe,
+ * kSafeMask = _Flagged_helper::minMask(kSafe),
+ * };
+ * typedef Flagged<int32_t, SafeFlags, kSafeMask> safeInt32;
+ *
+ * safeInt32 a;
+ * a.setFlags(kSafe);
+ * a.get() = 15;
+ * EXPECT_EQ(a.flags(), kSafe);
+ * EXPECT_EQ(a.get(), 15);
+ *
+ *
+ * Flagged also supports lazy or calculated wrapping of already flagged types. Lazy wrapping is
+ * provided automatically (flags are automatically shared if possible, e.g. mask is shifted
+ * automatically to not overlap with used bits of the wrapped type's flags, and fall back to
+ * unshared version of the template.):
+ *
+ * enum OriginFlags : uint32_t {
+ * kUnknown,
+ * kConst,
+ * kCalculated,
+ * kComponent,
+ * kApplication,
+ * kFile,
+ * kBinder,
+ * kOriginMask = _Flagged_helper::minMask(kBinder),
+ * };
+ * typedef Flagged<safeInt32, OriginFlags, kOriginMask>
+ * trackedSafeInt32;
+ *
+ * static_assert(sizeof(trackedSafeInt32) == sizeof(safeInt32), "");
+ *
+ * trackedSafeInt32 b(kConst, kSafe, 1);
+ * EXPECT_EQ(b.flags(), kConst);
+ * EXPECT_EQ(b.get().flags(), kSafe);
+ * EXPECT_EQ(b.get().get(), 1);
+ * b.setFlags(kCalculated);
+ * b.get().setFlags(overflow ? kUnsafe : kSafe);
+ *
+ * One can also choose to share some flag-bits with the wrapped class:
+ *
+ * enum ValidatedFlags : uint32_t {
+ * kUnsafeV = kUnsafe,
+ * kSafeV = kSafe,
+ * kValidated = kSafe | 2,
+ * kSharedMaskV = kSafeMask,
+ * kValidatedMask = _Flagged_helper::minMask(kValidated),
+ * };
+ * typedef Flagged<safeInt32, ValidatedFlags, kValidatedMask, kSharedMaskV> validatedInt32;
+ *
+ * validatedInt32 v(kUnsafeV, kSafe, 10);
+ * EXPECT_EQ(v.flags(), kUnsafeV);
+ * EXPECT_EQ(v.get().flags(), kUnsafe); // !kUnsafeV overrides kSafe
+ * EXPECT_EQ(v.get().get(), 10);
+ * v.setFlags(kValidated);
+ * EXPECT_EQ(v.flags(), kValidated);
+ * EXPECT_EQ(v.get().flags(), kSafe);
+ * v.get().setFlags(kUnsafe);
+ * EXPECT_EQ(v.flags(), 2); // NOTE: sharing masks with enums allows strange situations to occur
+ */
+
+/**
+ * Helper class for Flagged support. Encapsulates common utilities used by all
+ * templated classes.
+ */
+struct _Flagged_helper {
+ /**
+ * Calculates the value with a given number of top-most bits set.
+ *
+ * This method may be called with a signed flag.
+ *
+ * \param num number of bits to set. This must be between 0 and the number of bits in Flag.
+ *
+ * \return the value where only the given number of top-most bits are set.
+ */
+ template<typename Flag>
+ static constexpr Flag topBits(int num) {
+ return Flag(num > 0 ?
+ ~((Flag(1) << (sizeof(Flag) * 8 - is_signed_integral<Flag>::value - num)) - 1) :
+ 0);
+ }
+
+ /**
+ * Calculates the minimum mask required to cover a value. Used with the maximum enum value for
+ * an unsigned flag.
+ *
+ * \param maxValue maximum value to cover
+ * \param shift DO NO USE. used internally
+ *
+ * \return mask that can be used that covers the maximum value.
+ */
+ template<typename Flag>
+ static constexpr Flag minMask(Flag maxValue, int shift=sizeof(Flag) * 4) {
+ static_assert(is_unsigned_integral<Flag>::value,
+ "this method only makes sense for unsigned flags");
+ return shift ? minMask<Flag>(Flag(maxValue | (maxValue >> shift)), shift >> 1) : maxValue;
+ }
+
+ /**
+ * Returns a value left-shifted by an argument as a potential constexpr.
+ *
+ * This method helps around the C-language limitation, when left-shift of a negative value with
+ * even 0 cannot be a constexpr.
+ *
+ * \param value value to shift
+ * \param shift amount of shift
+ * \returns the shifted value as an integral type
+ */
+ template<typename Flag, typename IntFlag = typename underlying_integral_type<Flag>::type>
+ static constexpr IntFlag lshift(Flag value, int shift) {
+ return shift ? value << shift : value;
+ }
+
+private:
+
+ /**
+ * Determines whether mask can be combined with base-mask for a given left shift.
+ *
+ * \param mask desired mask
+ * \param baseMask mask used by T or 0 if T is not flagged by Flag
+ * \param sharedMask desired shared mask (if this is non-0, this must be mask & baseMask)
+ * \param shift desired left shift to be used for mask
+ * \param baseShift left shift used by T or 0 if T is not flagged by Flag
+ * \param effectiveMask effective mask used by T or 0 if T is not flagged by Flag
+ *
+ * \return bool whether mask can be combined with baseMask using the desired values.
+ */
+ template<typename Flag, typename IntFlag=typename underlying_integral_type<Flag>::type>
+ static constexpr bool canCombine(
+ Flag mask, IntFlag baseMask, Flag sharedMask, int shift,
+ int baseShift, IntFlag effectiveMask) {
+ return
+ // verify that shift is valid and mask can be shifted
+ shift >= 0 && (mask & topBits<Flag>(shift)) == 0 &&
+
+ // verify that base mask is part of effective mask (sanity check on arguments)
+ (baseMask & ~(effectiveMask >> baseShift)) == 0 &&
+
+ // if sharing masks, shift must be the base's shift.
+ // verify that shared mask is the overlap of base mask and mask
+ (sharedMask ?
+ ((sharedMask ^ (baseMask & mask)) == 0 &&
+ shift == baseShift) :
+
+
+ // otherwise, verify that there is no overlap between mask and base's effective mask
+ (mask & (effectiveMask >> shift)) == 0);
+ }
+
+
+ /**
+ * Calculates the minimum (left) shift required to combine a mask with the mask of an
+ * underlying type (T, also flagged by Flag).
+ *
+ * \param mask desired mask
+ * \param baseMask mask used by T or 0 if T is not flagged by Flag
+ * \param sharedMask desired shared mask (if this is non-0, this must be mask & baseMask)
+ * \param baseShift left shift used by T
+ * \param effectiveMask effective mask used by T
+ *
+ * \return a non-negative minimum left shift value if mask can be combined with baseMask,
+ * or -1 if the masks cannot be combined. -2 if the input is invalid.
+ */
+ template<typename Flag,
+ typename IntFlag = typename underlying_integral_type<Flag>::type>
+ static constexpr int getShift(
+ Flag mask, IntFlag baseMask, Flag sharedMask, int baseShift, IntFlag effectiveMask) {
+ return
+ // baseMask must be part of the effective mask
+ (baseMask & ~(effectiveMask >> baseShift)) ? -2 :
+
+ // if sharing masks, shift must be base's shift. verify that shared mask is part of
+ // base mask and mask, and that desired mask still fits with base's shift value
+ sharedMask ?
+ (canCombine(mask, baseMask, sharedMask, baseShift /* shift */,
+ baseShift, effectiveMask) ? baseShift : -1) :
+
+ // otherwise, see if 0-shift works
+ ((mask & effectiveMask) == 0) ? 0 :
+
+ // otherwise, verify that mask can be shifted up
+ ((mask & topBits<Flag>(1)) || (mask < 0)) ? -1 :
+
+ incShift(getShift(Flag(mask << 1), baseMask /* unused */, sharedMask /* 0 */,
+ baseShift /* unused */, effectiveMask));
+ }
+
+ /**
+ * Helper method that increments a non-negative (shift) value.
+ *
+ * This method is used to make it easier to create a constexpr for getShift.
+ *
+ * \param shift (shift) value to increment
+ *
+ * \return original shift if it was negative; otherwise, the shift incremented by one.
+ */
+ static constexpr int incShift(int shift) {
+ return shift + (shift >= 0);
+ }
+
+#ifdef FRIEND_TEST
+ FRIEND_TEST(FlaggedTest, _Flagged_helper_Test);
+#endif
+
+public:
+ /**
+ * Base class for all Flagged<T, Flag> classes.
+ *
+ * \note flagged types do not have a member variable for the mask used by the type. As such,
+ * they should be be cast to this base class.
+ *
+ * \todo can we replace this base class check with a static member check to remove possibility
+ * of cast?
+ */
+ template<typename Flag>
+ struct base {};
+
+ /**
+ * Type support utility that retrieves the mask of a class (T) if it is a type flagged by
+ * Flag (e.g. Flagged<T, Flag>).
+ *
+ * \note This retrieves 0 if T is a flagged class, that is not flagged by Flag or an equivalent
+ * underlying type.
+ *
+ * Generic implementation for a non-flagged class.
+ */
+ template<
+ typename T, typename Flag,
+ bool=std::is_base_of<base<typename underlying_integral_type<Flag>::type>, T>::value>
+ struct mask_of {
+ using IntFlag = typename underlying_integral_type<Flag>::type;
+ static constexpr IntFlag value = Flag(0); ///< mask of a potentially flagged class
+ static constexpr int shift = 0; ///<left shift of flags in a potentially flagged class
+ static constexpr IntFlag effective_value = IntFlag(0); ///<effective mask of flagged class
+ };
+
+ /**
+ * Type support utility that calculates the minimum (left) shift required to combine a mask
+ * with the mask of an underlying type T also flagged by Flag.
+ *
+ * \note if T is not flagged, not flagged by Flag, or the masks cannot be combined due to
+ * incorrect sharing or the flags not having enough bits, the minimum is -1.
+ *
+ * \param MASK desired mask
+ * \param SHARED_MASK desired shared mask (if this is non-0, T must be an type flagged by
+ * Flag with a mask that has exactly these bits common with MASK)
+ */
+ template<typename T, typename Flag, Flag MASK, Flag SHARED_MASK>
+ struct min_shift {
+ /// minimum (left) shift required, or -1 if masks cannot be combined
+ static constexpr int value =
+ getShift(MASK, mask_of<T, Flag>::value, SHARED_MASK,
+ mask_of<T, Flag>::shift, mask_of<T, Flag>::effective_value);
+ };
+
+ /**
+ * Type support utility that calculates whether the flags of T can be combined with MASK.
+ *
+ * \param MASK desired mask
+ * \param SHARED_MASK desired shared mask (if this is non-0, T MUST be an type flagged by
+ * Flag with a mask that has exactly these bits common with MASK)
+ */
+ template<
+ typename T, typename Flag, Flag MASK,
+ Flag SHARED_MASK=Flag(0),
+ int SHIFT=min_shift<T, Flag, MASK, SHARED_MASK>::value>
+ struct can_combine {
+ using IntFlag = typename underlying_integral_type<Flag>::type;
+ /// true if this mask can be combined with T's existing flag. false otherwise.
+ static constexpr bool value =
+ std::is_base_of<base<IntFlag>, T>::value
+ && canCombine(MASK, mask_of<T, Flag>::value, SHARED_MASK, SHIFT,
+ mask_of<T, Flag>::shift, mask_of<T, Flag>::effective_value);
+ };
+};
+
+/**
+ * Template specialization for the case when T is flagged by Flag or a compatible type.
+ */
+template<typename T, typename Flag>
+struct _Flagged_helper::mask_of<T, Flag, true> {
+ using IntType = typename underlying_integral_type<Flag>::type;
+ static constexpr IntType value = T::sFlagMask;
+ static constexpr int shift = T::sFlagShift;
+ static constexpr IntType effective_value = T::sEffectiveMask;
+};
+
+/**
+ * Main Flagged template that adds flags to an object of another type (in essence, creates a pair)
+ *
+ * Flag must be an integral type (enums are allowed).
+ *
+ * \note We could make SHARED_MASK be a boolean as it must be either 0 or MASK & base's mask, but we
+ * want it to be spelled out for safety.
+ *
+ * \param T type of object wrapped
+ * \param Flag type of flag
+ * \param MASK mask for the bits used in flag (before any shift)
+ * \param SHARED_MASK optional mask to be shared with T (if this is not zero, SHIFT must be 0, and
+ * it must equal to MASK & T's mask)
+ * \param SHIFT optional left shift for MASK to combine with T's mask (or -1, if masks should not
+ * be combined.)
+ */
+template<
+ typename T, typename Flag, Flag MASK, Flag SHARED_MASK=(Flag)0,
+ int SHIFT=_Flagged_helper::min_shift<T, Flag, MASK, SHARED_MASK>::value,
+ typename IntFlag=typename underlying_integral_type<Flag>::type,
+ bool=_Flagged_helper::can_combine<T, IntFlag, MASK, SHARED_MASK, SHIFT>::value>
+class Flagged : public _Flagged_helper::base<IntFlag> {
+ static_assert(SHARED_MASK == 0,
+ "shared mask can only be used with common flag types "
+ "and must be part of mask and mask of base type");
+ static_assert((_Flagged_helper::topBits<Flag>(SHIFT) & MASK) == 0, "SHIFT overflows MASK");
+
+ static constexpr Flag sFlagMask = MASK; ///< the mask
+ static constexpr int sFlagShift = SHIFT > 0 ? SHIFT : 0; ///< the left shift applied to flags
+
+ friend struct _Flagged_helper;
+#ifdef FRIEND_TEST
+ static constexpr bool sFlagCombined = false;
+ FRIEND_TEST(FlaggedTest, _Flagged_helper_Test);
+#endif
+
+ T mValue; ///< wrapped value
+ IntFlag mFlags; ///< flags
+
+protected:
+ /// The effective combined mask used by this class and any wrapped classes if the flags are
+ /// combined.
+ static constexpr IntFlag sEffectiveMask = _Flagged_helper::lshift(MASK, sFlagShift);
+
+ /**
+ * Helper method used by subsequent flagged wrappers to query flags. Returns the
+ * flags for a particular mask and left shift.
+ *
+ * \param mask bitmask to use
+ * \param shift left shifts to use
+ *
+ * \return the requested flags
+ */
+ inline constexpr IntFlag getFlagsHelper(IntFlag mask, int shift) const {
+ return (mFlags >> shift) & mask;
+ }
+
+ /**
+ * Helper method used by subsequent flagged wrappers to apply combined flags. Sets the flags
+ * in the bitmask using a particulare left shift.
+ *
+ * \param mask bitmask to use
+ * \param shift left shifts to use
+ * \param flags flags to update (any flags within the bitmask are updated to their value in this
+ * argument)
+ */
+ inline void setFlagsHelper(IntFlag mask, int shift, IntFlag flags) {
+ mFlags = Flag((mFlags & ~(mask << shift)) | ((flags & mask) << shift));
+ }
+
+public:
+ /**
+ * Wrapper around base class constructor. These take the flags as their first
+ * argument and pass the rest of the arguments to the base class constructor.
+ *
+ * \param flags initial flags
+ */
+ template<typename ...Args>
+ constexpr Flagged(Flag flags, Args... args)
+ : mValue(std::forward<Args>(args)...),
+ mFlags(Flag(_Flagged_helper::lshift(flags & sFlagMask, sFlagShift))) { }
+
+ /** Gets the wrapped value as const. */
+ inline constexpr const T &get() const { return mValue; }
+
+ /** Gets the wrapped value. */
+ inline T &get() { return mValue; }
+
+ /** Gets the flags. */
+ constexpr Flag flags() const {
+ return Flag(getFlagsHelper(sFlagMask, sFlagShift));
+ }
+
+ /** Sets the flags. */
+ void setFlags(Flag flags) {
+ setFlagsHelper(sFlagMask, sFlagShift, flags);
+ }
+};
+
+/*
+ * TRICKY: we cannot implement the specialization as:
+ *
+ * class Flagged : base<Flag> {
+ * T value;
+ * };
+ *
+ * Because T also inherits from base<Flag> and this runs into a compiler bug where
+ * sizeof(Flagged) > sizeof(T).
+ *
+ * Instead, we must inherit directly from the wrapped class
+ *
+ */
+#if 0
+template<
+ typename T, typename Flag, Flag MASK, Flag SHARED_MASK, int SHIFT>
+class Flagged<T, Flag, MASK, SHARED_MASK, SHIFT, true> : public _Flagged_helper::base<Flag> {
+private:
+ T mValue;
+};
+#else
+/**
+ * Specialization for the case when T is derived from Flagged<U, Flag> and flags can be combined.
+ */
+template<
+ typename T, typename Flag, Flag MASK, Flag SHARED_MASK, int SHIFT, typename IntFlag>
+class Flagged<T, Flag, MASK, SHARED_MASK, SHIFT, IntFlag, true> : private T {
+ static_assert(is_integral_or_enum<Flag>::value, "flag must be integer or enum");
+
+ static_assert(SHARED_MASK == 0 || SHIFT == 0, "cannot overlap masks when using SHIFT");
+ static_assert((SHARED_MASK & ~MASK) == 0, "shared mask must be part of the mask");
+ static_assert((SHARED_MASK & ~T::sEffectiveMask) == 0,
+ "shared mask must be part of the base mask");
+ static_assert(SHARED_MASK == 0 || (~SHARED_MASK & (MASK & T::sEffectiveMask)) == 0,
+ "mask and base mask can only overlap in shared mask");
+
+ static constexpr Flag sFlagMask = MASK; ///< the mask
+ static constexpr int sFlagShift = SHIFT; ///< the left shift applied to the flags
+
+#ifdef FRIEND_TEST
+ const static bool sFlagCombined = true;
+ FRIEND_TEST(FlaggedTest, _Flagged_helper_Test);
+#endif
+
+protected:
+ /// The effective combined mask used by this class and any wrapped classes if the flags are
+ /// combined.
+ static constexpr IntFlag sEffectiveMask = Flag((MASK << SHIFT) | T::sEffectiveMask);
+ friend struct _Flagged_helper;
+
+public:
+ /**
+ * Wrapper around base class constructor. These take the flags as their first
+ * argument and pass the rest of the arguments to the base class constructor.
+ *
+ * \param flags initial flags
+ */
+ template<typename ...Args>
+ constexpr Flagged(Flag flags, Args... args)
+ : T(std::forward<Args>(args)...) {
+ // we construct the base class first and apply the flags afterwards as
+ // base class may not have a constructor that takes flags even if it is derived from
+ // Flagged<U, Flag>
+ setFlags(flags);
+ }
+
+ /** Gets the wrapped value as const. */
+ inline constexpr T &get() const { return *this; }
+
+ /** Gets the wrapped value. */
+ inline T &get() { return *this; }
+
+ /** Gets the flags. */
+ Flag constexpr flags() const {
+ return Flag(this->getFlagsHelper(sFlagMask, sFlagShift));
+ }
+
+ /** Sets the flags. */
+ void setFlags(Flag flags) {
+ this->setFlagsHelper(sFlagMask, sFlagShift, flags);
+ }
+};
+#endif
+
+} // namespace android
+
+#endif // STAGEFRIGHT_FOUNDATION_FLAGGED_H_
+
diff --git a/media/libstagefright/include/foundation/MediaBufferBase.h b/media/libstagefright/include/foundation/MediaBufferBase.h
new file mode 100644
index 0000000..99418fb
--- /dev/null
+++ b/media/libstagefright/include/foundation/MediaBufferBase.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_BUFFER_BASE_H_
+
+#define MEDIA_BUFFER_BASE_H_
+
+namespace android {
+
+class MediaBufferBase {
+public:
+ MediaBufferBase() {}
+
+ virtual void release() = 0;
+ virtual void add_ref() = 0;
+
+protected:
+ virtual ~MediaBufferBase() {}
+
+private:
+ MediaBufferBase(const MediaBufferBase &);
+ MediaBufferBase &operator=(const MediaBufferBase &);
+};
+
+} // namespace android
+
+#endif // MEDIA_BUFFER_BASE_H_
diff --git a/media/libstagefright/include/foundation/Mutexed.h b/media/libstagefright/include/foundation/Mutexed.h
new file mode 100644
index 0000000..143b140
--- /dev/null
+++ b/media/libstagefright/include/foundation/Mutexed.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2016, 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 STAGEFRIGHT_FOUNDATION_MUTEXED_H_
+#define STAGEFRIGHT_FOUNDATION_MUTEXED_H_
+
+#include <utils/Mutex.h>
+#include <utils/Condition.h>
+
+namespace android {
+
+/*
+ * Wrapper class to programmatically protect a structure using a mutex.
+ *
+ * Mutexed<> objects contain a built-in mutex. Protection is enforced because the structure can
+ * only be accessed by locking the mutex first.
+ *
+ * Usage:
+ *
+ * struct DataToProtect {
+ * State(int var1) : mVar1(var1), mVar2(0) { }
+ * int mVar1;
+ * int mVar2;
+ * Condition mCondition1;
+ * };
+ *
+ * Mutexed<DataToProtect> mProtectedData;
+ *
+ * // members are inaccessible via mProtectedData directly
+ *
+ * void someFunction() {
+ * Mutexed<DataToProtect>::Locked data(mProtectedData); // access the protected data
+ *
+ * // the mutex is locked here, so accessing the data is safe
+ *
+ * if (data->mVar1 < 5) {
+ * ++data->mVar2;
+ * }
+ *
+ * // if you need to temporarily unlock the mutex, you can use unlock/relock mutex locally
+ * // using the accessor object.
+ *
+ * data.unlock();
+ *
+ * // data is inaccessible here
+ *
+ * doSomeLongOperation();
+ *
+ * data.lock();
+ *
+ * // data is now accessible again. Note: it may have changed since unlock().
+ *
+ * // you can use the integral mutex to wait for a condition
+ *
+ * data.waitForCondition(data->mCondition1);
+ *
+ * helper(&data);
+ * }
+ *
+ * void trigger() {
+ * Mutexed<DataToProtect>::Locked data(mProtectedData);
+ * data->mCondition1.signal();
+ * }
+ *
+ * void helper(const Mutexed<DataToProtect>::Locked &data) {
+ * data->mVar1 = 3;
+ * }
+ *
+ */
+
+template<typename T>
+class Mutexed {
+public:
+ /*
+ * Accessor-guard of the mutex-protected structure. This can be dereferenced to
+ * access the structure (using -> or * operators).
+ *
+ * Upon creation, the mutex is locked. You can use lock()/unlock() methods to
+ * temporarily lock/unlock the mutex. Using any references to the underlying
+ * structure or its members defeats the protection of this class, so don't do
+ * it.
+ *
+ * Note: The accessor-guard itself is not thread-safe. E.g. you should not call
+ * unlock() or lock() from different threads; they must be called from the thread
+ * that locked the original wrapper.
+ *
+ * Also note: Recursive locking/unlocking is not supported by the accessor. This
+ * is as intended, as it allows lenient locking/unlocking via multiple code paths.
+ */
+ class Locked {
+ public:
+ inline Locked(Mutexed<T> &mParent);
+ inline Locked(Locked &&from) :
+ mLock(from.mLock),
+ mTreasure(from.mTreasure),
+ mLocked(from.mLocked) {}
+ inline ~Locked();
+
+ // dereference the protected structure. This returns nullptr if the
+ // mutex is not locked by this accessor-guard.
+ inline T* operator->() const { return mLocked ? &mTreasure : nullptr; }
+ inline T& operator*() const { return mLocked ? mTreasure : *(T*)nullptr; }
+
+ // same as *
+ inline T& get() const { return mLocked ? mTreasure : *(T*)nullptr; }
+ // sets structure. this will abort if mLocked is false.
+ inline void set(T& o) const { get() = o; }
+
+ // Wait on the condition variable using lock. Must be locked.
+ inline status_t waitForCondition(Condition &cond) { return cond.wait(mLock); }
+
+ // same with relative timeout
+ inline status_t waitForConditionRelative(Condition &cond, nsecs_t reltime) {
+ return cond.waitRelative(mLock, reltime);
+ }
+
+ // unlocks the integral mutex. No-op if the mutex was already unlocked.
+ inline void unlock();
+
+ // locks the integral mutex. No-op if the mutex was already locked.
+ inline void lock();
+
+ private:
+ Mutex &mLock;
+ T &mTreasure;
+ bool mLocked;
+
+ // disable copy constructors
+ Locked(const Locked&) = delete;
+ void operator=(const Locked&) = delete;
+ };
+
+ // Wrap all constructors of the underlying structure
+ template<typename ...Args>
+ Mutexed(Args... args) : mTreasure(args...) { }
+
+ ~Mutexed() { }
+
+ // Lock the mutex, and create an accessor-guard (a Locked object) to access the underlying
+ // structure. This returns an object that dereferences to the wrapped structure when the mutex
+ // is locked by it, or otherwise to "null".
+ // This is just a shorthand for Locked() constructor to avoid specifying the template type.
+ inline Locked lock() {
+ return Locked(*this);
+ }
+
+private:
+ friend class Locked;
+ Mutex mLock;
+ T mTreasure;
+
+ // disable copy constructors
+ Mutexed(const Mutexed<T>&) = delete;
+ void operator=(const Mutexed<T>&) = delete;
+};
+
+template<typename T>
+inline Mutexed<T>::Locked::Locked(Mutexed<T> &mParent)
+ : mLock(mParent.mLock),
+ mTreasure(mParent.mTreasure),
+ mLocked(true) {
+ mLock.lock();
+}
+
+template<typename T>
+inline Mutexed<T>::Locked::~Locked() {
+ if (mLocked) {
+ mLock.unlock();
+ }
+}
+
+template<typename T>
+inline void Mutexed<T>::Locked::unlock() {
+ if (mLocked) {
+ mLocked = false;
+ mLock.unlock();
+ }
+}
+
+template<typename T>
+inline void Mutexed<T>::Locked::lock() {
+ if (!mLocked) {
+ mLock.lock();
+ mLocked = true;
+ }
+}
+
+} // namespace android
+
+#endif
diff --git a/media/libstagefright/include/foundation/ParsedMessage.h b/media/libstagefright/include/foundation/ParsedMessage.h
new file mode 100644
index 0000000..9d43a93
--- /dev/null
+++ b/media/libstagefright/include/foundation/ParsedMessage.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AString.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+// Encapsulates an "HTTP/RTSP style" response, i.e. a status line,
+// key/value pairs making up the headers and an optional body/content.
+struct ParsedMessage : public RefBase {
+ static sp<ParsedMessage> Parse(
+ const char *data, size_t size, bool noMoreData, size_t *length);
+
+ bool findString(const char *name, AString *value) const;
+ bool findInt32(const char *name, int32_t *value) const;
+
+ const char *getContent() const;
+
+ bool getRequestField(size_t index, AString *field) const;
+ bool getStatusCode(int32_t *statusCode) const;
+
+ AString debugString() const;
+
+ static bool GetAttribute(const char *s, const char *key, AString *value);
+
+ static bool GetInt32Attribute(
+ const char *s, const char *key, int32_t *value);
+
+
+protected:
+ virtual ~ParsedMessage();
+
+private:
+ KeyedVector<AString, AString> mDict;
+ AString mContent;
+
+ ParsedMessage();
+
+ ssize_t parse(const char *data, size_t size, bool noMoreData);
+
+ DISALLOW_EVIL_CONSTRUCTORS(ParsedMessage);
+};
+
+} // namespace android
diff --git a/media/libstagefright/include/foundation/TypeTraits.h b/media/libstagefright/include/foundation/TypeTraits.h
new file mode 100644
index 0000000..1250e9b
--- /dev/null
+++ b/media/libstagefright/include/foundation/TypeTraits.h
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2016 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 STAGEFRIGHT_FOUNDATION_TYPE_TRAITS_H_
+#define STAGEFRIGHT_FOUNDATION_TYPE_TRAITS_H_
+
+#include <type_traits>
+
+namespace android {
+
+/**
+ * std::is_signed, is_unsigned and is_integral does not consider enums even though the standard
+ * considers them integral. Create modified versions of these here. Also create a wrapper around
+ * std::underlying_type that does not require checking if the type is an enum.
+ */
+
+/**
+ * Type support utility class to check if a type is an integral type or an enum.
+ */
+template<typename T>
+struct is_integral_or_enum
+ : std::integral_constant<bool, std::is_integral<T>::value || std::is_enum<T>::value> { };
+
+/**
+ * Type support utility class to get the underlying std::is_integral supported type for a type.
+ * This returns the underlying type for enums, and the same type for types covered by
+ * std::is_integral.
+ *
+ * This is also used as a conditional to return an alternate type if the template param is not
+ * an integral or enum type (as in underlying_integral_type<T, TypeIfNotEnumOrIntegral>::type).
+ */
+template<typename T,
+ typename U=typename std::enable_if<is_integral_or_enum<T>::value>::type,
+ bool=std::is_enum<T>::value,
+ bool=std::is_integral<T>::value>
+struct underlying_integral_type {
+ static_assert(!std::is_enum<T>::value, "T should not be enum here");
+ static_assert(!std::is_integral<T>::value, "T should not be integral here");
+ typedef U type;
+};
+
+/** Specialization for enums. */
+template<typename T, typename U>
+struct underlying_integral_type<T, U, true, false> {
+ static_assert(std::is_enum<T>::value, "T should be enum here");
+ static_assert(!std::is_integral<T>::value, "T should not be integral here");
+ typedef typename std::underlying_type<T>::type type;
+};
+
+/** Specialization for non-enum std-integral types. */
+template<typename T, typename U>
+struct underlying_integral_type<T, U, false, true> {
+ static_assert(!std::is_enum<T>::value, "T should not be enum here");
+ static_assert(std::is_integral<T>::value, "T should be integral here");
+ typedef T type;
+};
+
+/**
+ * Type support utility class to check if the underlying integral type is signed.
+ */
+template<typename T>
+struct is_signed_integral
+ : std::integral_constant<bool, std::is_signed<
+ typename underlying_integral_type<T, unsigned>::type>::value> { };
+
+/**
+ * Type support utility class to check if the underlying integral type is unsigned.
+ */
+template<typename T>
+struct is_unsigned_integral
+ : std::integral_constant<bool, std::is_unsigned<
+ typename underlying_integral_type<T, signed>::type>::value> {
+};
+
+/**
+ * Type support relationship query template.
+ *
+ * If T occurs as one of the types in Us with the same const-volatile qualifications, provides the
+ * member constant |value| equal to true. Otherwise value is false.
+ */
+template<typename T, typename ...Us>
+struct is_one_of;
+
+/// \if 0
+/**
+ * Template specialization when first type matches the searched type.
+ */
+template<typename T, typename ...Us>
+struct is_one_of<T, T, Us...> : std::true_type {};
+
+/**
+ * Template specialization when first type does not match the searched type.
+ */
+template<typename T, typename U, typename ...Us>
+struct is_one_of<T, U, Us...> : is_one_of<T, Us...> {};
+
+/**
+ * Template specialization when there are no types to search.
+ */
+template<typename T>
+struct is_one_of<T> : std::false_type {};
+/// \endif
+
+/**
+ * Type support relationship query template.
+ *
+ * If all types in Us are unique, provides the member constant |value| equal to true.
+ * Otherwise value is false.
+ */
+template<typename ...Us>
+struct are_unique;
+
+/// \if 0
+/**
+ * Template specialization when there are no types.
+ */
+template<>
+struct are_unique<> : std::true_type {};
+
+/**
+ * Template specialization when there is at least one type to check.
+ */
+template<typename T, typename ...Us>
+struct are_unique<T, Us...>
+ : std::integral_constant<bool, are_unique<Us...>::value && !is_one_of<T, Us...>::value> {};
+/// \endif
+
+/// \if 0
+template<size_t Base, typename T, typename ...Us>
+struct _find_first_impl;
+
+/**
+ * Template specialization when there are no types to search.
+ */
+template<size_t Base, typename T>
+struct _find_first_impl<Base, T> : std::integral_constant<size_t, 0> {};
+
+/**
+ * Template specialization when T is the first type in Us.
+ */
+template<size_t Base, typename T, typename ...Us>
+struct _find_first_impl<Base, T, T, Us...> : std::integral_constant<size_t, Base> {};
+
+/**
+ * Template specialization when T is not the first type in Us.
+ */
+template<size_t Base, typename T, typename U, typename ...Us>
+struct _find_first_impl<Base, T, U, Us...>
+ : std::integral_constant<size_t, _find_first_impl<Base + 1, T, Us...>::value> {};
+
+/// \endif
+
+/**
+ * Type support relationship query template.
+ *
+ * If T occurs in Us, index is the 1-based left-most index of T in Us. Otherwise, index is 0.
+ */
+template<typename T, typename ...Us>
+struct find_first {
+ static constexpr size_t index = _find_first_impl<1, T, Us...>::value;
+};
+
+/// \if 0
+/**
+ * Helper class for find_first_convertible_to template.
+ *
+ * Adds a base index.
+ */
+template<size_t Base, typename T, typename ...Us>
+struct _find_first_convertible_to_helper;
+
+/**
+ * Template specialization for when there are more types to consider
+ */
+template<size_t Base, typename T, typename U, typename ...Us>
+struct _find_first_convertible_to_helper<Base, T, U, Us...> {
+ static constexpr size_t index =
+ std::is_convertible<T, U>::value ? Base :
+ _find_first_convertible_to_helper<Base + 1, T, Us...>::index;
+ typedef typename std::conditional<
+ std::is_convertible<T, U>::value, U,
+ typename _find_first_convertible_to_helper<Base + 1, T, Us...>::type>::type type;
+};
+
+/**
+ * Template specialization for when there are no more types to consider
+ */
+template<size_t Base, typename T>
+struct _find_first_convertible_to_helper<Base, T> {
+ static constexpr size_t index = 0;
+ typedef void type;
+};
+
+/// \endif
+
+/**
+ * Type support template that returns the type that T can be implicitly converted into, and its
+ * index, from a list of other types (Us).
+ *
+ * Returns index of 0 and type of void if there are no convertible types.
+ *
+ * \param T type that is converted
+ * \param Us types into which the conversion is considered
+ */
+template<typename T, typename ...Us>
+struct find_first_convertible_to : public _find_first_convertible_to_helper<1, T, Us...> { };
+
+} // namespace android
+
+#endif // STAGEFRIGHT_FOUNDATION_TYPE_TRAITS_H_
+
diff --git a/media/libstagefright/include/foundation/base64.h b/media/libstagefright/include/foundation/base64.h
new file mode 100644
index 0000000..e340b89
--- /dev/null
+++ b/media/libstagefright/include/foundation/base64.h
@@ -0,0 +1,33 @@
+/*
+ * 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 BASE_64_H_
+
+#define BASE_64_H_
+
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct ABuffer;
+struct AString;
+
+sp<ABuffer> decodeBase64(const AString &s);
+void encodeBase64(const void *data, size_t size, AString *out);
+
+} // namespace android
+
+#endif // BASE_64_H_
diff --git a/media/libstagefright/include/foundation/hexdump.h b/media/libstagefright/include/foundation/hexdump.h
new file mode 100644
index 0000000..8360c5a
--- /dev/null
+++ b/media/libstagefright/include/foundation/hexdump.h
@@ -0,0 +1,33 @@
+/*
+ * 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 HEXDUMP_H_
+
+#define HEXDUMP_H_
+
+#include <sys/types.h>
+
+namespace android {
+
+struct AString;
+
+void hexdump(
+ const void *_data, size_t size,
+ size_t indent = 0, AString *appendTo = NULL);
+
+} // namespace android
+
+#endif // HEXDUMP_H_