diff options
Diffstat (limited to 'include/media')
70 files changed, 1777 insertions, 326 deletions
diff --git a/include/media/AudioBufferProvider.h b/include/media/AudioBufferProvider.h index ef392f0..7be449c 100644 --- a/include/media/AudioBufferProvider.h +++ b/include/media/AudioBufferProvider.h @@ -61,6 +61,17 @@ public: // buffer->frameCount 0 virtual status_t getNextBuffer(Buffer* buffer, int64_t pts = kInvalidPTS) = 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; }; diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h index 05d834d..f98002d 100644 --- a/include/media/AudioEffect.h +++ b/include/media/AudioEffect.h @@ -36,7 +36,7 @@ namespace android { // ---------------------------------------------------------------------------- -class effect_param_cblk_t; +struct effect_param_cblk_t; // ---------------------------------------------------------------------------- @@ -217,8 +217,9 @@ public: * 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 0, the effect will be global to - * the output mix. If not 0, the effect will be applied to all players + * 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. @@ -229,8 +230,8 @@ public: int32_t priority = 0, effect_callback_t cbf = NULL, void* user = NULL, - int sessionId = 0, - audio_io_handle_t io = 0 + int sessionId = AUDIO_SESSION_OUTPUT_MIX, + audio_io_handle_t io = AUDIO_IO_HANDLE_NONE ); /* Constructor. @@ -241,8 +242,8 @@ public: int32_t priority = 0, effect_callback_t cbf = NULL, void* user = NULL, - int sessionId = 0, - audio_io_handle_t io = 0 + int sessionId = AUDIO_SESSION_OUTPUT_MIX, + audio_io_handle_t io = AUDIO_IO_HANDLE_NONE ); /* Terminates the AudioEffect and unregisters it from AudioFlinger. @@ -263,8 +264,8 @@ public: int32_t priority = 0, effect_callback_t cbf = NULL, void* user = NULL, - int sessionId = 0, - audio_io_handle_t io = 0 + int sessionId = AUDIO_SESSION_OUTPUT_MIX, + audio_io_handle_t io = AUDIO_IO_HANDLE_NONE ); /* Result of constructing the AudioEffect. This must be checked diff --git a/include/media/AudioPolicyHelper.h b/include/media/AudioPolicyHelper.h new file mode 100644 index 0000000..f4afd45 --- /dev/null +++ b/include/media/AudioPolicyHelper.h @@ -0,0 +1,64 @@ +/* + * 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> + +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_ACCESSIBILITY: + case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: + return AUDIO_STREAM_MUSIC; + 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; + } +} + +#endif //AUDIO_POLICY_HELPER_H_ diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index 052064d..4edc1bf 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -26,7 +26,7 @@ namespace android { // ---------------------------------------------------------------------------- -class audio_track_cblk_t; +struct audio_track_cblk_t; class AudioRecordClientProxy; // ---------------------------------------------------------------------------- @@ -39,8 +39,12 @@ public: * Keep in sync with frameworks/base/media/java/android/media/AudioRecord.java NATIVE_EVENT_*. */ enum event_type { - EVENT_MORE_DATA = 0, // Request to read more data from PCM buffer. - EVENT_OVERRUN = 1, // PCM buffer overrun occurred. + 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 @@ -60,9 +64,10 @@ public: size_t frameCount; // number of sample frames corresponding to size; // on input it is the number of frames available, // on output is the number of frames actually drained - // (currently ignored, but will make the primary field in future) + // (currently ignored but will make the primary field in future) size_t size; // input/output in bytes == frameCount * frameSize + // on output is the number of bytes actually drained // FIXME this is redundant with respect to frameCount, // and TRANSFER_OBTAIN mode is broken for 8-bit data // since we don't define the frame format @@ -76,7 +81,7 @@ public: /* 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 ready or various conditions occur. + * invokes the callback when a new buffer becomes available or various conditions occur. * Parameters: * * event: type of event notified (see enum AudioRecord::event_type). @@ -99,6 +104,8 @@ public: * - 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. */ static status_t getMinFrameCount(size_t* frameCount, @@ -109,7 +116,7 @@ public: /* How data is transferred from AudioRecord */ enum transfer_type { - TRANSFER_DEFAULT, // not specified explicitly; determine from other parameters + TRANSFER_DEFAULT, // not specified explicitly; determine from the other parameters TRANSFER_CALLBACK, // callback EVENT_MORE_DATA TRANSFER_OBTAIN, // FIXME deprecated: call obtainBuffer() and releaseBuffer() TRANSFER_SYNC, // synchronous read() @@ -137,7 +144,7 @@ public: * 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 PCM data and inform of marker, position updates, etc. + * to consume new data 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. @@ -151,11 +158,11 @@ public: uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, - int frameCount = 0, + size_t frameCount = 0, callback_t cbf = NULL, void* user = NULL, - int notificationFrames = 0, - int sessionId = 0, + uint32_t notificationFrames = 0, + int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE); @@ -171,9 +178,10 @@ public: * 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 (channels, format, sampleRate...) + * - 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: * @@ -183,16 +191,16 @@ public: uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, - int frameCount = 0, + size_t frameCount = 0, callback_t cbf = NULL, void* user = NULL, - int notificationFrames = 0, + uint32_t notificationFrames = 0, bool threadCanCallJava = false, - int sessionId = 0, + int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE); - /* Result of constructing the AudioRecord. This must be checked + /* 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. @@ -221,7 +229,7 @@ public: status_t start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE, int triggerSession = 0); - /* Stop a track. If set, the callback will cease being called. Note that obtainBuffer() still + /* 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(); @@ -232,11 +240,16 @@ public: */ uint32_t getSampleRate() const { return mSampleRate; } + /* Return the notification frame count. + * This is approximately how often the callback is invoked, for transfer type TRANSFER_CALLBACK. + */ + size_t notificationFrames() const { return mNotificationFramesAct; } + /* 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 the set the marker at a nearby position such as ~0 or 1. + * 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. * @@ -378,8 +391,10 @@ public: * 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. */ - unsigned int getInputFramesLost() const; + uint32_t getInputFramesLost() const; private: /* copying audio record objects is not allowed */ @@ -412,6 +427,7 @@ 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; // whether to ignore next mPausedInt request }; // body of AudioRecordThread::threadLoop() @@ -422,9 +438,10 @@ private: // 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(const sp<AudioRecordThread>& thread); + nsecs_t processAudioBuffer(); // caller must hold lock on mLock for all _l methods + status_t openRecord_l(size_t epoch); // FIXME enum is faster than strcmp() for parameter 'from' @@ -444,14 +461,16 @@ private: // 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 next 2 + 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() - int mObservedSequence; // last observed value of mSequence + uint32_t mObservedSequence; // last observed value of mSequence uint32_t mMarkerPosition; // in wrapping (overflow) frame units bool mMarkerReached; @@ -460,9 +479,13 @@ private: status_t mStatus; + 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 + // constant after constructor or set() uint32_t mSampleRate; - size_t mFrameCount; audio_format_t mFormat; uint32_t mChannelCount; size_t mFrameSize; // app-level frame size == AudioFlinger frame size @@ -473,12 +496,13 @@ private: int mSessionId; transfer_type mTransfer; - audio_io_handle_t mInput; // returned by AudioSystem::getInput() - - // may be changed if IAudioRecord object is re-created + // 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; diff --git a/include/media/AudioResamplerPublic.h b/include/media/AudioResamplerPublic.h new file mode 100644 index 0000000..97847a0 --- /dev/null +++ b/include/media/AudioResamplerPublic.h @@ -0,0 +1,29 @@ +/* + * 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 + +// 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 + +#endif // ANDROID_AUDIO_RESAMPLER_PUBLIC_H diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index 4c22412..dd63a23 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -19,6 +19,7 @@ #include <hardware/audio_effect.h> #include <media/IAudioFlingerClient.h> +#include <media/IAudioPolicyServiceClient.h> #include <system/audio.h> #include <system/audio_policy.h> #include <utils/Errors.h> @@ -67,20 +68,24 @@ public: // 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 = 0); + 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 = 0); + 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); @@ -90,36 +95,37 @@ public: 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 static status_t getOutputSamplingRate(uint32_t* samplingRate, - audio_stream_type_t stream = AUDIO_STREAM_DEFAULT); + audio_stream_type_t stream); + static status_t getOutputSamplingRateForAttr(uint32_t* samplingRate, + const audio_attributes_t *attr); static status_t getOutputFrameCount(size_t* frameCount, - audio_stream_type_t stream = AUDIO_STREAM_DEFAULT); + audio_stream_type_t stream); static status_t getOutputLatency(uint32_t* latency, - audio_stream_type_t stream = AUDIO_STREAM_DEFAULT); + audio_stream_type_t stream); static status_t getSamplingRate(audio_io_handle_t output, - audio_stream_type_t streamType, uint32_t* samplingRate); // returns the number of frames per audio HAL write buffer. Corresponds to - // audio_stream->get_buffer_size()/audio_stream_frame_size() + // audio_stream->get_buffer_size()/audio_stream_out_frame_size() static status_t getFrameCount(audio_io_handle_t output, - audio_stream_type_t stream, size_t* frameCount); // returns the audio output stream latency in ms. Corresponds to // audio_stream_out->get_latency() static status_t getLatency(audio_io_handle_t output, - audio_stream_type_t stream, uint32_t* latency); static bool routedToA2dpOutput(audio_stream_type_t streamType); + // return status NO_ERROR implies *buffSize > 0 static status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, size_t* buffSize); 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 output on which the specified stream is playing - // has exited standby. + // audio dsp to DAC since the specified output I/O handle 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 @@ -128,15 +134,25 @@ public: // 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, - audio_stream_type_t stream = AUDIO_STREAM_DEFAULT); + uint32_t *dspFrames); // return the number of input frames lost by HAL implementation, or 0 if the handle is invalid - static size_t getInputFramesLost(audio_io_handle_t ioHandle); + 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 AUDIO_UNIQUE_ID_ALLOCATE + // or an unspecified existing unique ID. + static audio_unique_id_t newAudioUniqueId(); - static int newAudioSessionId(); - static void acquireAudioSessionId(int audioSession); - static void releaseAudioSessionId(int audioSession); + static void acquireAudioSessionId(int audioSession, pid_t pid); + static void releaseAudioSessionId(int 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); // types of io configuration change events received with ioConfigChanged() enum io_config_event { @@ -155,7 +171,8 @@ public: class OutputDescriptor { public: OutputDescriptor() - : samplingRate(0), format(AUDIO_FORMAT_DEFAULT), channelMask(0), frameCount(0), latency(0) {} + : samplingRate(0), format(AUDIO_FORMAT_DEFAULT), channelMask(0), frameCount(0), latency(0) + {} uint32_t samplingRate; audio_format_t format; @@ -193,27 +210,44 @@ public: 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 audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr, + 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 startOutput(audio_io_handle_t output, audio_stream_type_t stream, - int session = 0); + int session); static status_t stopOutput(audio_io_handle_t output, audio_stream_type_t stream, - int session = 0); + int session); static void releaseOutput(audio_io_handle_t output); + + // Client must successfully hand off the handle reference to AudioFlinger via openRecord(), + // or release it with releaseInput(). static audio_io_handle_t getInput(audio_source_t inputSource, - uint32_t samplingRate = 0, - audio_format_t format = AUDIO_FORMAT_DEFAULT, - audio_channel_mask_t channelMask = AUDIO_CHANNEL_IN_MONO, - int sessionId = 0); - static status_t startInput(audio_io_handle_t input); - static status_t stopInput(audio_io_handle_t input); - static void releaseInput(audio_io_handle_t input); + uint32_t samplingRate, + audio_format_t format, + audio_channel_mask_t channelMask, + int sessionId, + audio_input_flags_t); + + 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); @@ -255,8 +289,54 @@ public: // 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); + // ---------------------------------------------------------------------------- + class AudioPortCallback : public RefBase + { + public: + + AudioPortCallback() {} + virtual ~AudioPortCallback() {} + + virtual void onAudioPortListUpdate() = 0; + virtual void onAudioPatchListUpdate() = 0; + virtual void onServiceDied() = 0; + + }; + + static void setAudioPortCallback(sp<AudioPortCallback> callBack); + private: class AudioFlingerClient: public IBinder::DeathRecipient, public BnAudioFlingerClient @@ -275,7 +355,8 @@ private: virtual void ioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2); }; - class AudioPolicyServiceClient: public IBinder::DeathRecipient + class AudioPolicyServiceClient: public IBinder::DeathRecipient, + public BnAudioPolicyServiceClient { public: AudioPolicyServiceClient() { @@ -283,6 +364,10 @@ private: // DeathRecipient virtual void binderDied(const wp<IBinder>& who); + + // IAudioPolicyServiceClient + virtual void onAudioPortListUpdate(); + virtual void onAudioPatchListUpdate(); }; static sp<AudioFlingerClient> gAudioFlingerClient; @@ -302,11 +387,11 @@ private: static sp<IAudioPolicyService> gAudioPolicyService; - // mapping between stream types and outputs - static DefaultKeyedVector<audio_stream_type_t, audio_io_handle_t> gStreamOutputMap; // list of output descriptors containing cached parameters // (sampling rate, framecount, channel count...) static DefaultKeyedVector<audio_io_handle_t, OutputDescriptor *> gOutputs; + + static sp<AudioPortCallback> gAudioPortCallback; }; }; // namespace android diff --git a/include/media/AudioTimestamp.h b/include/media/AudioTimestamp.h index c29c7e5..99e9c3e 100644 --- a/include/media/AudioTimestamp.h +++ b/include/media/AudioTimestamp.h @@ -19,6 +19,8 @@ #include <time.h> +namespace android { + class AudioTimestamp { public: AudioTimestamp() : mPosition(0) { @@ -30,4 +32,6 @@ public: struct timespec mTime; // corresponding CLOCK_MONOTONIC when frame is expected to present }; +} // namespace + #endif // ANDROID_AUDIO_TIMESTAMP_H diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index 4736369..a3cc396 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -27,7 +27,7 @@ namespace android { // ---------------------------------------------------------------------------- -class audio_track_cblk_t; +struct audio_track_cblk_t; class AudioTrackClientProxy; class StaticAudioTrackClientProxy; @@ -36,11 +36,6 @@ class StaticAudioTrackClientProxy; class AudioTrack : public RefBase { public: - enum channel_index { - MONO = 0, - LEFT = 0, - RIGHT = 1 - }; /* Events used by AudioTrack callback function (callback_t). * Keep in sync with frameworks/base/media/java/android/media/AudioTrack.java NATIVE_EVENT_*. @@ -82,6 +77,7 @@ public: // (currently ignored, but will make the primary field in future) size_t size; // input/output in bytes == frameCount * frameSize + // on input it is unused // on output is the number of bytes actually filled // FIXME this is redundant with respect to frameCount, // and TRANSFER_OBTAIN mode is broken for 8-bit data @@ -91,7 +87,7 @@ public: void* raw; short* i16; // signed 16-bit int8_t* i8; // unsigned 8-bit, offset by 0x80 - }; + }; // input: unused, output: pointer to buffer }; /* As a convenience, if a callback is supplied, a handler thread @@ -123,6 +119,8 @@ public: * - 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. */ static status_t getMinFrameCount(size_t* frameCount, @@ -156,9 +154,10 @@ public: * streamType: Select the type of audio stream this track is attached to * (e.g. AUDIO_STREAM_MUSIC). * sampleRate: Data source sampling rate in Hz. - * format: Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed - * 16 bits per sample). - * channelMask: Channel mask. + * format: Audio format. For mixed tracks, any PCM format supported by server is OK + * or AUDIO_FORMAT_PCM_8_BIT which is handled on client side. 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 @@ -180,15 +179,17 @@ public: uint32_t sampleRate, audio_format_t format, audio_channel_mask_t, - int frameCount = 0, + size_t frameCount = 0, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, callback_t cbf = NULL, void* user = NULL, - int notificationFrames = 0, - int sessionId = 0, + uint32_t notificationFrames = 0, + int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, const audio_offload_info_t *offloadInfo = NULL, - int uid = -1); + int uid = -1, + pid_t pid = -1, + const audio_attributes_t* pAttributes = NULL); /* Creates an audio track and registers it with AudioFlinger. * With this constructor, the track is configured for static buffer mode. @@ -209,11 +210,13 @@ public: audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, callback_t cbf = NULL, void* user = NULL, - int notificationFrames = 0, - int sessionId = 0, + uint32_t notificationFrames = 0, + int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, const audio_offload_info_t *offloadInfo = NULL, - int uid = -1); + int uid = -1, + pid_t pid = -1, + const audio_attributes_t* pAttributes = NULL); /* Terminates the AudioTrack and unregisters it from AudioFlinger. * Also destroys all resources associated with the AudioTrack. @@ -241,17 +244,19 @@ public: uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, - int frameCount = 0, + size_t frameCount = 0, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, callback_t cbf = NULL, void* user = NULL, - int notificationFrames = 0, + uint32_t notificationFrames = 0, const sp<IMemory>& sharedBuffer = 0, bool threadCanCallJava = false, - int sessionId = 0, + int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, const audio_offload_info_t *offloadInfo = NULL, - int uid = -1); + int uid = -1, + pid_t pid = -1, + const audio_attributes_t* pAttributes = NULL); /* Result of constructing the AudioTrack. This must be checked for successful initialization * before using any AudioTrack API (except for set()), because using @@ -279,7 +284,7 @@ public: size_t frameSize() const { return mFrameSize; } uint32_t channelCount() const { return mChannelCount; } - uint32_t frameCount() const { return mFrameCount; } + size_t frameCount() const { return mFrameCount; } /* Return the static buffer specified in constructor or set(), or 0 for streaming mode */ sp<IMemory> sharedBuffer() const { return mSharedBuffer; } @@ -336,7 +341,7 @@ public: */ status_t setSampleRate(uint32_t sampleRate); - /* Return current source sample rate in Hz, or 0 if unknown */ + /* Return current source sample rate in Hz */ uint32_t getSampleRate() const; /* Enables looping and sets the start and end points of looping. @@ -361,7 +366,7 @@ public: /* 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 the set the marker at a nearby position such as ~0 or 1. + * 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. * @@ -450,9 +455,10 @@ public: * none. * * Returned value: - * handle on audio hardware output + * handle on audio hardware output, or AUDIO_IO_HANDLE_NONE if the + * track needed to be re-created but that failed */ - audio_io_handle_t getOutput(); + audio_io_handle_t getOutput() const; /* Returns the unique session ID associated with this track. * @@ -528,15 +534,6 @@ private: struct timespec *elapsed = NULL, size_t *nonContig = NULL); public: -//EL_FIXME to be reconciled with new obtainBuffer() return codes and control block proxy -// enum { -// NO_MORE_BUFFERS = 0x80000001, // same name in AudioFlinger.h, ok to be different value -// TEAR_DOWN = 0x80000002, -// STOPPED = 1, -// STREAM_END_WAIT, -// STREAM_END -// }; - /* Release a filled buffer of "audioBuffer->frameCount" frames for AudioFlinger to process. */ // FIXME make private when obtainBuffer() for TRANSFER_OBTAIN is removed void releaseBuffer(Buffer* audioBuffer); @@ -551,8 +548,11 @@ public: * WOULD_BLOCK when obtainBuffer() returns same, or * AudioTrack was stopped during the write * or any other error code returned by IAudioTrack::start() or restoreTrack_l(). + * Default behavior is to only return until 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); + ssize_t write(const void* buffer, size_t size, bool blocking = true); /* * Dumps the state of an audio track. @@ -566,7 +566,7 @@ public: uint32_t getUnderrunFrames() const; /* Get the flags */ - audio_output_flags_t getFlags() const { return mFlags; } + 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); @@ -589,6 +589,11 @@ protected: AudioTrack(const AudioTrack& other); AudioTrack& operator = (const AudioTrack& other); + void setAttributesFromStreamType(audio_stream_type_t streamType); + void setStreamTypeFromAttributes(audio_attributes_t& aa); + /* paa is guaranteed non-NULL */ + bool isValidAttributes(const audio_attributes_t *paa); + /* a small internal class to handle the callback */ class AudioTrackThread : public Thread { @@ -626,53 +631,60 @@ protected: // 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(const sp<AudioTrackThread>& thread); - status_t processStreamEnd(int32_t waitCount); + nsecs_t processAudioBuffer(); + bool isOffloaded() const; + bool isDirect() const; + bool isOffloadedOrDirect() const; // caller must hold lock on mLock for all _l methods - status_t createTrack_l(audio_stream_type_t streamType, - uint32_t sampleRate, - audio_format_t format, - size_t frameCount, - audio_output_flags_t flags, - const sp<IMemory>& sharedBuffer, - audio_io_handle_t output, - size_t epoch); + status_t createTrack_l(size_t epoch); // can only be called when mState != STATE_ACTIVE void flush_l(); void setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount); - audio_io_handle_t getOutput_l(); // FIXME enum is faster than strcmp() for parameter 'from' status_t restoreTrack_l(const char *from); - bool isOffloaded() const + bool isOffloaded_l() const { return (mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0; } - // Next 3 fields may be changed if IAudioTrack is re-created, but always != 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; } + + // 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; + float mVolume[2]; float mSendLevel; mutable uint32_t mSampleRate; // mutable because getSampleRate() can update it. - size_t mFrameCount; // corresponds to current IAudioTrack - size_t mReqFrameCount; // frame count to request the next time a new - // IAudioTrack is needed - + size_t mFrameCount; // corresponds to current IAudioTrack, value is + // reported back by AudioFlinger to the client + size_t mReqFrameCount; // frame count to request the first or next time + // a new IAudioTrack is needed, non-decreasing // constant after constructor or set() audio_format_t mFormat; // as requested by client, not forced to 16-bit audio_stream_type_t mStreamType; 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; // mFrameSize is equal to mFrameSizeAF for non-PCM or 16-bit PCM data. For 8-bit PCM data, it's // twice as large as mFrameSize because data is expanded to 16-bit before it's stored in buffer. @@ -705,21 +717,25 @@ protected: uint32_t mNotificationFramesAct; // actual number of frames between each // notification callback, // at initial source sample rate - bool mRefreshRemaining; // processAudioBuffer() should refresh next 2 + 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 - sp<IMemory> mSharedBuffer; uint32_t mLoopPeriod; // in frames, zero means looping is disabled + uint32_t mMarkerPosition; // in wrapping (overflow) frame units bool mMarkerReached; uint32_t mNewPosition; // in frames uint32_t mUpdatePeriod; // in frames, zero means no EVENT_NEW_POS audio_output_flags_t mFlags; + // const after set(), except for bits AUDIO_OUTPUT_FLAG_FAST and AUDIO_OUTPUT_FLAG_OFFLOAD. + // mLock must be held to read or write those bits reliably. + int mSessionId; int mAuxEffectId; @@ -739,7 +755,6 @@ protected: sp<AudioTrackClientProxy> mProxy; // primary owner of the memory bool mInUnderrun; // whether track is currently in underrun state - String8 mName; // server's name for this IAudioTrack uint32_t mPausedPosition; private: @@ -754,8 +769,8 @@ private: sp<DeathNotifier> mDeathNotifier; uint32_t mSequence; // incremented for each new IAudioTrack attempt - audio_io_handle_t mOutput; // cached output io handle int mClientUid; + pid_t mClientPid; }; class TimedAudioTrack : public AudioTrack diff --git a/include/media/CharacterEncodingDetector.h b/include/media/CharacterEncodingDetector.h new file mode 100644 index 0000000..deaa377 --- /dev/null +++ b/include/media/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/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index 282f275..31a14f0 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -50,6 +50,7 @@ public: TRACK_TIMED = 1, // client requests a TimedAudioTrack TRACK_FAST = 2, // client requests a fast AudioTrack or AudioRecord TRACK_OFFLOAD = 4, // client requests offload to hw codec + TRACK_DIRECT = 8, // client requests a direct output }; typedef uint32_t track_flags_t; @@ -64,37 +65,39 @@ public: uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, - size_t frameCount, + size_t *pFrameCount, track_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 tid, // -1 means unused, otherwise must be valid non-0 int *sessionId, - // input: ignored - // output: server's description of IAudioTrack for display in logs. - // Don't attempt to parse, as the format could change. - String8& name, int clientUid, status_t *status) = 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, - size_t frameCount, + size_t *pFrameCount, track_flags_t *flags, pid_t tid, // -1 means unused, otherwise must be valid non-0 int *sessionId, + size_t *notificationFrames, + sp<IMemory>& cblk, + sp<IMemory>& buffers, // return value 0 means it follows cblk status_t *status) = 0; /* query the audio hardware state. This state never changes, * and therefore can be cached. */ virtual uint32_t sampleRate(audio_io_handle_t output) const = 0; -#if 0 - virtual int channelCount(audio_io_handle_t output) const = 0; -#endif virtual audio_format_t format(audio_io_handle_t output) const = 0; virtual size_t frameCount(audio_io_handle_t output) const = 0; @@ -142,28 +145,29 @@ public: virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask) const = 0; - virtual audio_io_handle_t openOutput(audio_module_handle_t module, - audio_devices_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - audio_channel_mask_t *pChannelMask, - uint32_t *pLatencyMs, - audio_output_flags_t flags, - const audio_offload_info_t *offloadInfo = NULL) = 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 audio_io_handle_t openInput(audio_module_handle_t module, - audio_devices_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - audio_channel_mask_t *pChannelMask) = 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 setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output) = 0; + virtual status_t invalidateStream(audio_stream_type_t stream) = 0; virtual status_t setVoiceVolume(float volume) = 0; @@ -172,10 +176,10 @@ public: virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const = 0; - virtual int newAudioSessionId() = 0; + virtual audio_unique_id_t newAudioUniqueId() = 0; - virtual void acquireAudioSessionId(int audioSession) = 0; - virtual void releaseAudioSessionId(int audioSession) = 0; + virtual void acquireAudioSessionId(int audioSession, pid_t pid) = 0; + virtual void releaseAudioSessionId(int audioSession, pid_t pid) = 0; virtual status_t queryNumberEffects(uint32_t *numEffects) const = 0; @@ -188,6 +192,7 @@ public: 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, int sessionId, status_t *status, @@ -209,6 +214,29 @@ public: // 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; }; diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h index 09b9ea6..c251439 100644 --- a/include/media/IAudioPolicyService.h +++ b/include/media/IAudioPolicyService.h @@ -25,6 +25,7 @@ #include <utils/Errors.h> #include <binder/IInterface.h> #include <media/AudioSystem.h> +#include <media/IAudioPolicyServiceClient.h> #include <system/audio_policy.h> @@ -55,6 +56,12 @@ public: audio_channel_mask_t channelMask = 0, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, const audio_offload_info_t *offloadInfo = NULL) = 0; + virtual audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr, + 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 startOutput(audio_io_handle_t output, audio_stream_type_t stream, int session = 0) = 0; @@ -63,13 +70,17 @@ public: int session = 0) = 0; virtual void releaseOutput(audio_io_handle_t output) = 0; virtual audio_io_handle_t getInput(audio_source_t inputSource, - uint32_t samplingRate = 0, - audio_format_t format = AUDIO_FORMAT_DEFAULT, - audio_channel_mask_t channelMask = 0, - int audioSession = 0) = 0; - virtual status_t startInput(audio_io_handle_t input) = 0; - virtual status_t stopInput(audio_io_handle_t input) = 0; - virtual void releaseInput(audio_io_handle_t input) = 0; + uint32_t samplingRate, + audio_format_t format, + audio_channel_mask_t channelMask, + int audioSession, + audio_input_flags_t flags) = 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; @@ -99,6 +110,38 @@ public: // 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 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; }; diff --git a/include/media/IAudioPolicyServiceClient.h b/include/media/IAudioPolicyServiceClient.h new file mode 100644 index 0000000..59df046 --- /dev/null +++ b/include/media/IAudioPolicyServiceClient.h @@ -0,0 +1,56 @@ +/* + * 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; +}; + + +// ---------------------------------------------------------------------------- + +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/include/media/IAudioRecord.h b/include/media/IAudioRecord.h index eccc2ca..2003985 100644 --- a/include/media/IAudioRecord.h +++ b/include/media/IAudioRecord.h @@ -34,9 +34,6 @@ class IAudioRecord : public IInterface public: DECLARE_META_INTERFACE(AudioRecord); - /* get this tracks control block */ - virtual sp<IMemory> getCblk() const = 0; - /* After it's created the track is not active. Call start() to * make it active. */ diff --git a/include/media/IDrm.h b/include/media/IDrm.h index 5ef26af..68de87a 100644 --- a/include/media/IDrm.h +++ b/include/media/IDrm.h @@ -61,10 +61,16 @@ struct IDrm : public IInterface { virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId, KeyedVector<String8, String8> &infoMap) const = 0; - virtual status_t getProvisionRequest(Vector<uint8_t> &request, + 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) = 0; + virtual status_t provideProvisionResponse(Vector<uint8_t> const &response, + Vector<uint8_t> &certificate, + Vector<uint8_t> &wrappedKey) = 0; + + virtual status_t unprovisionDevice() = 0; virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0; @@ -107,6 +113,12 @@ struct IDrm : public IInterface { 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: diff --git a/include/media/IMediaCodecList.h b/include/media/IMediaCodecList.h new file mode 100644 index 0000000..e93ea8b --- /dev/null +++ b/include/media/IMediaCodecList.h @@ -0,0 +1,55 @@ +/* + * 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> + +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 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/include/media/IMediaHTTPConnection.h b/include/media/IMediaHTTPConnection.h new file mode 100644 index 0000000..2a63eb7 --- /dev/null +++ b/include/media/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/include/media/IMediaHTTPService.h b/include/media/IMediaHTTPService.h new file mode 100644 index 0000000..f66d6c8 --- /dev/null +++ b/include/media/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/include/media/IMediaMetadataRetriever.h b/include/media/IMediaMetadataRetriever.h index 6dbb2d7..2529800 100644 --- a/include/media/IMediaMetadataRetriever.h +++ b/include/media/IMediaMetadataRetriever.h @@ -26,6 +26,8 @@ namespace android { +struct IMediaHTTPService; + class IMediaMetadataRetriever: public IInterface { public: @@ -33,6 +35,7 @@ public: virtual void disconnect() = 0; virtual status_t setDataSource( + const sp<IMediaHTTPService> &httpService, const char *srcUrl, const KeyedVector<String8, String8> *headers = NULL) = 0; diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h index 0cbd269..db62cd5 100644 --- a/include/media/IMediaPlayer.h +++ b/include/media/IMediaPlayer.h @@ -33,6 +33,7 @@ class Parcel; class Surface; class IStreamSource; class IGraphicBufferProducer; +struct IMediaHTTPService; class IMediaPlayer: public IInterface { @@ -41,8 +42,11 @@ public: virtual void disconnect() = 0; - virtual status_t setDataSource(const char *url, - const KeyedVector<String8, String8>* headers) = 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 setVideoSurfaceTexture( diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h index 2998b37..d7e584a 100644 --- a/include/media/IMediaPlayerService.h +++ b/include/media/IMediaPlayerService.h @@ -34,6 +34,8 @@ namespace android { struct ICrypto; struct IDrm; struct IHDCP; +struct IMediaCodecList; +struct IMediaHTTPService; class IMediaRecorder; class IOMX; class IRemoteDisplay; @@ -49,9 +51,14 @@ public: virtual sp<IMediaMetadataRetriever> createMetadataRetriever() = 0; virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client, int audioSessionId = 0) = 0; - virtual status_t decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, - audio_format_t* pFormat, - const sp<IMemoryHeap>& heap, size_t *pSize) = 0; + virtual status_t decode( + const sp<IMediaHTTPService> &httpService, + const char* url, + uint32_t *pSampleRate, + int* pNumChannels, + audio_format_t* pFormat, + const sp<IMemoryHeap>& heap, size_t *pSize) = 0; + virtual status_t decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat, const sp<IMemoryHeap>& heap, size_t *pSize) = 0; @@ -59,6 +66,7 @@ public: virtual sp<ICrypto> makeCrypto() = 0; virtual sp<IDrm> makeDrm() = 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 @@ -93,9 +101,6 @@ public: virtual void addBatteryData(uint32_t params) = 0; virtual status_t pullBatteryData(Parcel* reply) = 0; - - virtual status_t updateProxyConfig( - const char *host, int32_t port, const char *exclusionList) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/media/IOMX.h b/include/media/IOMX.h index b74a2c7..627f23b 100644 --- a/include/media/IOMX.h +++ b/include/media/IOMX.h @@ -87,6 +87,10 @@ public: node_id node, OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) = 0; + virtual status_t configureVideoTunnelMode( + node_id node, OMX_U32 portIndex, OMX_BOOL tunneled, + OMX_U32 audioHwSync, native_handle_t **sidebandHandle) = 0; + virtual status_t enableGraphicBuffers( node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0; @@ -143,6 +147,8 @@ public: INTERNAL_OPTION_SUSPEND, // data is a bool INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY, // data is an int64_t INTERNAL_OPTION_MAX_TIMESTAMP_GAP, // data is int64_t + INTERNAL_OPTION_START_TIME, // data is an int64_t + INTERNAL_OPTION_TIME_LAPSE, // data is an int64_t[2] }; virtual status_t setInternalOption( node_id node, @@ -182,8 +188,6 @@ struct omx_message { OMX_U32 range_length; OMX_U32 flags; OMX_TICKS timestamp; - OMX_PTR platform_private; - OMX_PTR data_ptr; } extended_buffer_data; } u; diff --git a/include/media/MediaCodecInfo.h b/include/media/MediaCodecInfo.h new file mode 100644 index 0000000..cd56adb --- /dev/null +++ b/include/media/MediaCodecInfo.h @@ -0,0 +1,123 @@ +/* + * 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; +struct Parcel; +struct CodecCapabilities; + +struct MediaCodecInfo : public RefBase { + struct ProfileLevel { + uint32_t mProfile; + uint32_t mLevel; + }; + + struct Capabilities : public RefBase { + void getSupportedProfileLevels(Vector<ProfileLevel> *profileLevels) const; + void getSupportedColorFormats(Vector<uint32_t> *colorFormats) const; + uint32_t getFlags() const; + const sp<AMessage> getDetails() const; + + private: + Vector<ProfileLevel> mProfileLevels; + Vector<uint32_t> mColorFormats; + uint32_t mFlags; + sp<AMessage> mDetails; + + Capabilities(); + + // 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 class MediaCodecInfo; + }; + + 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 initializeCapabilities(const CodecCapabilities &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 class MediaCodecList; +}; + +} // namespace android + +#endif // MEDIA_CODEC_INFO_H_ + + diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h index cd5bf88..38dbb20 100644 --- a/include/media/MediaMetadataRetrieverInterface.h +++ b/include/media/MediaMetadataRetrieverInterface.h @@ -25,6 +25,8 @@ namespace android { +struct IMediaHTTPService; + // Abstract base class class MediaMetadataRetrieverBase : public RefBase { @@ -33,6 +35,7 @@ public: virtual ~MediaMetadataRetrieverBase() {} virtual status_t setDataSource( + const sp<IMediaHTTPService> &httpService, const char *url, const KeyedVector<String8, String8> *headers = NULL) = 0; diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index 26d8729..87717da 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -137,6 +137,7 @@ public: } virtual status_t setDataSource( + const sp<IMediaHTTPService> &httpService, const char *url, const KeyedVector<String8, String8> *headers = NULL) = 0; @@ -213,11 +214,6 @@ public: return INVALID_OPERATION; } - virtual status_t updateProxyConfig( - const char *host, int32_t port, const char *exclusionList) { - return INVALID_OPERATION; - } - private: friend class MediaPlayerService; diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h index 9fc962c..f061d22 100644 --- a/include/media/MediaProfiles.h +++ b/include/media/MediaProfiles.h @@ -33,7 +33,8 @@ enum camcorder_quality { CAMCORDER_QUALITY_720P = 5, CAMCORDER_QUALITY_1080P = 6, CAMCORDER_QUALITY_QVGA = 7, - CAMCORDER_QUALITY_LIST_END = 7, + CAMCORDER_QUALITY_2160P = 8, + CAMCORDER_QUALITY_LIST_END = 8, CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000, CAMCORDER_QUALITY_TIME_LAPSE_LOW = 1000, @@ -44,7 +45,17 @@ enum camcorder_quality { CAMCORDER_QUALITY_TIME_LAPSE_720P = 1005, CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006, CAMCORDER_QUALITY_TIME_LAPSE_QVGA = 1007, - CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 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, }; /** diff --git a/include/media/SoundPool.h b/include/media/SoundPool.h index 2dd78cc..5830475 100644 --- a/include/media/SoundPool.h +++ b/include/media/SoundPool.h @@ -167,7 +167,7 @@ class SoundPool { friend class SoundPoolThread; friend class SoundChannel; public: - SoundPool(int maxChannels, audio_stream_type_t streamType, int srcQuality); + SoundPool(int maxChannels, const audio_attributes_t* pAttributes); ~SoundPool(); int load(const char* url, int priority); int load(int fd, int64_t offset, int64_t length, int priority); @@ -183,8 +183,7 @@ public: void setPriority(int channelID, int priority); void setLoop(int channelID, int loop); void setRate(int channelID, float rate); - audio_stream_type_t streamType() const { return mStreamType; } - int srcQuality() const { return mSrcQuality; } + const audio_attributes_t* attributes() { return &mAttributes; } // called from SoundPoolThread void sampleLoaded(int sampleID); @@ -225,8 +224,7 @@ private: List<SoundChannel*> mStop; DefaultKeyedVector< int, sp<Sample> > mSamples; int mMaxChannels; - audio_stream_type_t mStreamType; - int mSrcQuality; + audio_attributes_t mAttributes; int mAllocated; int mNextSampleID; int mNextChannelID; diff --git a/include/media/StringArray.h b/include/media/StringArray.h new file mode 100644 index 0000000..ae47085 --- /dev/null +++ b/include/media/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/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h index 0df77c1..b35cf32 100644 --- a/include/media/mediametadataretriever.h +++ b/include/media/mediametadataretriever.h @@ -25,6 +25,7 @@ namespace android { +struct IMediaHTTPService; class IMediaPlayerService; class IMediaMetadataRetriever; @@ -68,6 +69,7 @@ public: void disconnect(); status_t setDataSource( + const sp<IMediaHTTPService> &httpService, const char *dataSourceUrl, const KeyedVector<String8, String8> *headers = NULL); diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h index 4c05fc3..9cc208e 100644 --- a/include/media/mediaplayer.h +++ b/include/media/mediaplayer.h @@ -160,6 +160,9 @@ enum media_parameter_keys { // 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. @@ -170,6 +173,7 @@ enum media_player_invoke_ids { 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. @@ -189,6 +193,8 @@ public: virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) = 0; }; +struct IMediaHTTPService; + class MediaPlayer : public BnMediaPlayerClient, public virtual IMediaDeathNotifier { @@ -199,6 +205,7 @@ public: void disconnect(); status_t setDataSource( + const sp<IMediaHTTPService> &httpService, const char *url, const KeyedVector<String8, String8> *headers); @@ -220,13 +227,19 @@ public: 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); - static status_t decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, - audio_format_t* pFormat, - const sp<IMemoryHeap>& heap, size_t *pSize); + static status_t decode( + const sp<IMediaHTTPService> &httpService, + const char* url, + uint32_t *pSampleRate, + int* pNumChannels, + audio_format_t* pFormat, + const sp<IMemoryHeap>& heap, + size_t *pSize); static status_t decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat, const sp<IMemoryHeap>& heap, size_t *pSize); @@ -242,9 +255,6 @@ public: status_t setRetransmitEndpoint(const char* addrString, uint16_t port); status_t setNextMediaPlayer(const sp<MediaPlayer>& player); - status_t updateProxyConfig( - const char *host, int32_t port, const char *exclusionList); - private: void clear_l(); status_t seekTo_l(int msec); @@ -253,6 +263,7 @@ private: 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; @@ -267,6 +278,7 @@ private: bool mPrepareSync; status_t mPrepareStatus; audio_stream_type_t mStreamType; + Parcel* mAudioAttributesParcel; bool mLoop; float mLeftVolume; float mRightVolume; diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h index 88a42a0..b0a62a7 100644 --- a/include/media/mediarecorder.h +++ b/include/media/mediarecorder.h @@ -39,7 +39,7 @@ typedef void (*media_completion_f)(status_t status, void *cookie); enum video_source { VIDEO_SOURCE_DEFAULT = 0, VIDEO_SOURCE_CAMERA = 1, - VIDEO_SOURCE_GRALLOC_BUFFER = 2, + VIDEO_SOURCE_SURFACE = 2, VIDEO_SOURCE_LIST_END // must be last - used to validate audio source type }; @@ -61,12 +61,18 @@ enum output_format { 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 }; @@ -77,6 +83,7 @@ enum audio_encoder { 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 }; @@ -86,6 +93,7 @@ enum video_encoder { VIDEO_ENCODER_H263 = 1, VIDEO_ENCODER_H264 = 2, VIDEO_ENCODER_MPEG_4_SP = 3, + VIDEO_ENCODER_VP8 = 4, VIDEO_ENCODER_LIST_END // must be the last - used to validate the video encoder type }; diff --git a/include/media/mediascanner.h b/include/media/mediascanner.h index 37a83c6..d555279 100644 --- a/include/media/mediascanner.h +++ b/include/media/mediascanner.h @@ -21,6 +21,7 @@ #include <utils/threads.h> #include <utils/List.h> #include <utils/Errors.h> +#include <utils/String8.h> #include <pthread.h> struct dirent; @@ -29,6 +30,7 @@ namespace android { class MediaScannerClient; class StringArray; +class CharacterEncodingDetector; enum MediaScanResult { // This file or directory was scanned successfully. @@ -118,15 +120,8 @@ public: virtual status_t setMimeType(const char* mimeType) = 0; protected: - void convertValues(uint32_t encoding); - -protected: - // cached name and value strings, for native encoding support. - StringArray* mNames; - StringArray* mValues; - - // default encoding based on MediaScanner::mLocale string - uint32_t mLocaleEncoding; + // default encoding from MediaScanner::mLocale + String8 mLocale; }; }; // namespace android diff --git a/include/media/nbaio/AudioBufferProviderSource.h b/include/media/nbaio/AudioBufferProviderSource.h index 2c4aaff..b16e20a 100644 --- a/include/media/nbaio/AudioBufferProviderSource.h +++ b/include/media/nbaio/AudioBufferProviderSource.h @@ -27,7 +27,7 @@ namespace android { class AudioBufferProviderSource : public NBAIO_Source { public: - AudioBufferProviderSource(AudioBufferProvider *provider, NBAIO_Format format); + AudioBufferProviderSource(AudioBufferProvider *provider, const NBAIO_Format& format); virtual ~AudioBufferProviderSource(); // NBAIO_Port interface diff --git a/include/media/nbaio/AudioStreamInSource.h b/include/media/nbaio/AudioStreamInSource.h index 07d8c89..5169f1e 100644 --- a/include/media/nbaio/AudioStreamInSource.h +++ b/include/media/nbaio/AudioStreamInSource.h @@ -43,9 +43,9 @@ public: // 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 >> mBitShift; } + virtual ssize_t availableToRead() { return mStreamBufferSizeBytes / mFrameSize; } - virtual ssize_t read(void *buffer, size_t count); + virtual ssize_t read(void *buffer, size_t count, int64_t readPTS); // NBAIO_Sink end diff --git a/include/media/nbaio/AudioStreamOutSink.h b/include/media/nbaio/AudioStreamOutSink.h index 7948d40..9949b88 100644 --- a/include/media/nbaio/AudioStreamOutSink.h +++ b/include/media/nbaio/AudioStreamOutSink.h @@ -43,7 +43,7 @@ public: // 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() const { return mStreamBufferSizeBytes >> mBitShift; } + virtual ssize_t availableToWrite() const { return mStreamBufferSizeBytes / mFrameSize; } virtual ssize_t write(const void *buffer, size_t count); diff --git a/include/media/nbaio/MonoPipe.h b/include/media/nbaio/MonoPipe.h index d3802fe..b09b35f 100644 --- a/include/media/nbaio/MonoPipe.h +++ b/include/media/nbaio/MonoPipe.h @@ -41,7 +41,7 @@ public: // 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, NBAIO_Format format, bool writeCanBlock = false); + MonoPipe(size_t reqFrames, const NBAIO_Format& format, bool writeCanBlock = false); virtual ~MonoPipe(); // NBAIO_Port interface diff --git a/include/media/nbaio/NBAIO.h b/include/media/nbaio/NBAIO.h index 1da0c73..be0c15b 100644 --- a/include/media/nbaio/NBAIO.h +++ b/include/media/nbaio/NBAIO.h @@ -29,6 +29,7 @@ #include <utils/Errors.h> #include <utils/RefBase.h> #include <media/AudioTimestamp.h> +#include <system/audio.h> namespace android { @@ -52,31 +53,41 @@ enum { // 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. -typedef unsigned NBAIO_Format; -enum { - Format_Invalid +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; }; -// Return the frame size of an NBAIO_Format in bytes -size_t Format_frameSize(NBAIO_Format format); +extern const NBAIO_Format Format_Invalid; -// Return the frame size of an NBAIO_Format as a bit shift -size_t Format_frameBitShift(NBAIO_Format format); +// 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 -NBAIO_Format Format_from_SR_C(unsigned sampleRate, unsigned channelCount); +// 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(NBAIO_Format format); +unsigned Format_sampleRate(const NBAIO_Format& format); // Return the channel count of an NBAIO_Format -unsigned Format_channelCount(NBAIO_Format 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, int64_t readPTS); +// 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 { @@ -115,15 +126,15 @@ public: virtual NBAIO_Format format() const { return mNegotiated ? mFormat : Format_Invalid; } protected: - NBAIO_Port(NBAIO_Format format) : mNegotiated(false), mFormat(format), - mBitShift(Format_frameBitShift(format)) { } + 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 mBitShift; // assign in parallel with any assignment to mFormat + 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. @@ -220,7 +231,7 @@ public: virtual status_t getTimestamp(AudioTimestamp& timestamp) { return INVALID_OPERATION; } protected: - NBAIO_Sink(NBAIO_Format format = Format_Invalid) : NBAIO_Port(format), mFramesWritten(0) { } + 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 @@ -311,7 +322,7 @@ public: virtual void onTimestamp(const AudioTimestamp& timestamp) { } protected: - NBAIO_Source(NBAIO_Format format = Format_Invalid) : NBAIO_Port(format), mFramesRead(0) { } + 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 diff --git a/include/media/nbaio/Pipe.h b/include/media/nbaio/Pipe.h index 79a4eee..eba37bc 100644 --- a/include/media/nbaio/Pipe.h +++ b/include/media/nbaio/Pipe.h @@ -30,7 +30,11 @@ class Pipe : public NBAIO_Sink { public: // maxFrames will be rounded up to a power of 2, and all slots are available. Must be >= 2. - Pipe(size_t maxFrames, NBAIO_Format format); + // 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 @@ -57,6 +61,7 @@ private: void * const mBuffer; volatile int32_t mRear; // written by android_atomic_release_store volatile int32_t mReaders; // number of PipeReader clients currently attached to this Pipe + const bool mFreeBufferInDestructor; }; } // namespace android diff --git a/include/media/nbaio/SourceAudioBufferProvider.h b/include/media/nbaio/SourceAudioBufferProvider.h index cdfb6fe..daf6bc3 100644 --- a/include/media/nbaio/SourceAudioBufferProvider.h +++ b/include/media/nbaio/SourceAudioBufferProvider.h @@ -41,7 +41,7 @@ public: private: const sp<NBAIO_Source> mSource; // the wrapped source - /*const*/ size_t mFrameBitShift; // log2(frame size in bytes) + /*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 diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index 46c62dc..da4c20c 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -22,6 +22,7 @@ #include <android/native_window.h> #include <media/IOMX.h> #include <media/stagefright/foundation/AHierarchicalStateMachine.h> +#include <media/stagefright/CodecBase.h> #include <media/stagefright/SkipCutBuffer.h> #include <OMX_Audio.h> @@ -31,45 +32,34 @@ namespace android { struct ABuffer; struct MemoryDealer; +struct DescribeColorFormatParams; -struct ACodec : public AHierarchicalStateMachine { - enum { - kWhatFillThisBuffer = 'fill', - kWhatDrainThisBuffer = 'drai', - kWhatEOS = 'eos ', - kWhatShutdownCompleted = 'scom', - kWhatFlushCompleted = 'fcom', - kWhatOutputFormatChanged = 'outC', - kWhatError = 'erro', - kWhatComponentAllocated = 'cAll', - kWhatComponentConfigured = 'cCon', - kWhatInputSurfaceCreated = 'isfc', - kWhatSignaledInputEOS = 'seos', - kWhatBuffersAllocated = 'allc', - kWhatOMXDied = 'OMXd', - }; - +struct ACodec : public AHierarchicalStateMachine, public CodecBase { ACodec(); - void setNotificationMessage(const sp<AMessage> &msg); + virtual void setNotificationMessage(const sp<AMessage> &msg); + void initiateSetup(const sp<AMessage> &msg); - void signalFlush(); - void signalResume(); - void initiateShutdown(bool keepComponentAllocated = false); - void signalSetParameters(const sp<AMessage> &msg); - void signalEndOfInputStream(); + virtual void initiateAllocateComponent(const sp<AMessage> &msg); + virtual void initiateConfigureComponent(const sp<AMessage> &msg); + virtual void initiateCreateInputSurface(); + virtual void initiateStart(); + virtual void initiateShutdown(bool keepComponentAllocated = false); - void initiateAllocateComponent(const sp<AMessage> &msg); - void initiateConfigureComponent(const sp<AMessage> &msg); - void initiateCreateInputSurface(); - void initiateStart(); + virtual void signalFlush(); + virtual void signalResume(); - void signalRequestIDRFrame(); + virtual void signalSetParameters(const sp<AMessage> &msg); + virtual void signalEndOfInputStream(); + virtual void signalRequestIDRFrame(); - bool isConfiguredForAdaptivePlayback() { return mIsConfiguredForAdaptivePlayback; } + // AHierarchicalStateMachine implements the message handling + virtual void onMessageReceived(const sp<AMessage> &msg) { + handleMessage(msg); + } - struct PortDescription : public RefBase { + struct PortDescription : public CodecBase::PortDescription { size_t countBuffers(); IOMX::buffer_id bufferIDAt(size_t index) const; sp<ABuffer> bufferAt(size_t index) const; @@ -86,6 +76,10 @@ struct ACodec : public AHierarchicalStateMachine { DISALLOW_EVIL_CONSTRUCTORS(PortDescription); }; + static bool isFlexibleColorFormat( + const sp<IOMX> &omx, IOMX::node_id node, + uint32_t colorFormat, OMX_U32 *flexibleEquivalent); + protected: virtual ~ACodec(); @@ -119,6 +113,7 @@ private: kWhatRequestIDRFrame = 'ridr', kWhatSetParameters = 'setP', kWhatSubmitOutputMetaDataBufferIfEOS = 'subm', + kWhatOMXDied = 'OMXd', }; enum { @@ -178,6 +173,8 @@ private: sp<MemoryDealer> mDealer[2]; sp<ANativeWindow> mNativeWindow; + sp<AMessage> mInputFormat; + sp<AMessage> mOutputFormat; Vector<BufferInfo> mBuffers[2]; bool mPortEOS[2]; @@ -189,7 +186,7 @@ private: bool mIsEncoder; bool mUseMetadataOnEncoderOutput; bool mShutdownInProgress; - bool mIsConfiguredForAdaptivePlayback; + bool mExplicitShutdown; // If "mKeepComponentAllocated" we only transition back to Loaded state // and do not release the component instance. @@ -197,6 +194,7 @@ private: int32_t mEncoderDelay; int32_t mEncoderPadding; + int32_t mRotationDegrees; bool mChannelMaskPresent; int32_t mChannelMask; @@ -208,6 +206,11 @@ private: int64_t mRepeatFrameDelayUs; int64_t mMaxPtsGapUs; + int64_t mTimePerFrameUs; + int64_t mTimePerCaptureUs; + + bool mCreateInputBuffersSuspended; + status_t setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode); status_t allocateBuffersOnPort(OMX_U32 portIndex); status_t freeBuffersOnPort(OMX_U32 portIndex); @@ -231,6 +234,9 @@ private: 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, @@ -239,7 +245,7 @@ private: status_t setSupportedOutputFormat(); status_t setupVideoDecoder( - const char *mime, int32_t width, int32_t height); + const char *mime, const sp<AMessage> &msg); status_t setupVideoEncoder( const char *mime, const sp<AMessage> &msg); @@ -249,10 +255,21 @@ private: int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat); + 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 aacProfile, bool isADTS, int32_t sbrMode, + int32_t maxOutputChannelCount, const drcParams_t& drc); + + status_t setupAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate); status_t selectAudioPortFormat( OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat); @@ -271,6 +288,7 @@ private: 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); status_t verifySupportForProfileAndLevel(int32_t profile, int32_t level); @@ -299,11 +317,17 @@ private: void processDeferredMessages(); void sendFormatChange(const sp<AMessage> &reply); + status_t getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify); void signalError( OMX_ERRORTYPE error = OMX_ErrorUndefined, status_t internalError = UNKNOWN_ERROR); + static bool describeDefaultColorFormat(DescribeColorFormatParams &describeParams); + static bool describeColorFormat( + const sp<IOMX> &omx, IOMX::node_id node, + DescribeColorFormatParams &describeParams); + status_t requestIDRFrame(); status_t setParameters(const sp<AMessage> ¶ms); diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h index a829916..dd0a106 100644 --- a/include/media/stagefright/CameraSource.h +++ b/include/media/stagefright/CameraSource.h @@ -172,7 +172,7 @@ protected: const sp<IGraphicBufferProducer>& surface, bool storeMetaDataInVideoBuffers); - virtual void startCameraRecording(); + virtual status_t startCameraRecording(); virtual void releaseRecordingFrame(const sp<IMemory>& frame); // Returns true if need to skip the current frame. @@ -185,6 +185,8 @@ protected: virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType, const sp<IMemory> &data); + void releaseCamera(); + private: friend class CameraSourceListener; @@ -233,7 +235,6 @@ private: int32_t frameRate); void stopCameraRecording(); - void releaseCamera(); status_t reset(); CameraSource(const CameraSource &); diff --git a/include/media/stagefright/CodecBase.h b/include/media/stagefright/CodecBase.h new file mode 100644 index 0000000..1bf27a6 --- /dev/null +++ b/include/media/stagefright/CodecBase.h @@ -0,0 +1,88 @@ +/* + * 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 <stdint.h> +#include <media/IOMX.h> + +#include <media/stagefright/foundation/AHandler.h> + +namespace android { + +struct ABuffer; + +struct CodecBase : public AHandler { + enum { + kWhatFillThisBuffer = 'fill', + kWhatDrainThisBuffer = 'drai', + kWhatEOS = 'eos ', + kWhatShutdownCompleted = 'scom', + kWhatFlushCompleted = 'fcom', + kWhatOutputFormatChanged = 'outC', + kWhatError = 'erro', + kWhatComponentAllocated = 'cAll', + kWhatComponentConfigured = 'cCon', + kWhatInputSurfaceCreated = 'isfc', + kWhatSignaledInputEOS = 'seos', + kWhatBuffersAllocated = 'allc', + }; + + virtual void setNotificationMessage(const sp<AMessage> &msg) = 0; + + virtual void initiateAllocateComponent(const sp<AMessage> &msg) = 0; + virtual void initiateConfigureComponent(const sp<AMessage> &msg) = 0; + virtual void initiateCreateInputSurface() = 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 void signalFlush() = 0; + virtual void signalResume() = 0; + + virtual void signalRequestIDRFrame() = 0; + virtual void signalSetParameters(const sp<AMessage> &msg) = 0; + virtual void signalEndOfInputStream() = 0; + + struct PortDescription : public RefBase { + virtual size_t countBuffers() = 0; + virtual IOMX::buffer_id bufferIDAt(size_t index) const = 0; + virtual sp<ABuffer> bufferAt(size_t index) const = 0; + + protected: + PortDescription(); + virtual ~PortDescription(); + + private: + DISALLOW_EVIL_CONSTRUCTORS(PortDescription); + }; + +protected: + CodecBase(); + virtual ~CodecBase(); + +private: + DISALLOW_EVIL_CONSTRUCTORS(CodecBase); +}; + +} // namespace android + +#endif // CODEC_BASE_H_ + diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h index 157b1aa..8000e84 100644 --- a/include/media/stagefright/DataSource.h +++ b/include/media/stagefright/DataSource.h @@ -31,6 +31,8 @@ namespace android { struct AMessage; +struct AString; +struct IMediaHTTPService; class String8; class DataSource : public RefBase { @@ -43,8 +45,10 @@ public: }; static sp<DataSource> CreateFromURI( + const sp<IMediaHTTPService> &httpService, const char *uri, - const KeyedVector<String8, String8> *headers = NULL); + const KeyedVector<String8, String8> *headers = NULL, + String8 *contentType = NULL); DataSource() {} diff --git a/include/media/stagefright/DataURISource.h b/include/media/stagefright/DataURISource.h new file mode 100644 index 0000000..693562e --- /dev/null +++ b/include/media/stagefright/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/include/media/stagefright/FileSource.h b/include/media/stagefright/FileSource.h index be152e7..a981d1c 100644 --- a/include/media/stagefright/FileSource.h +++ b/include/media/stagefright/FileSource.h @@ -30,6 +30,7 @@ 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; diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h index 3ef6b9a..26ce5f9 100644 --- a/include/media/stagefright/MPEG4Writer.h +++ b/include/media/stagefright/MPEG4Writer.h @@ -63,8 +63,8 @@ public: int32_t getTimeScale() const { return mTimeScale; } status_t setGeoData(int latitudex10000, int longitudex10000); - void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; } - int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; } + virtual void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; } + virtual int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; } protected: virtual ~MPEG4Writer(); diff --git a/include/media/stagefright/MediaBufferGroup.h b/include/media/stagefright/MediaBufferGroup.h index 0488292..a006f7f 100644 --- a/include/media/stagefright/MediaBufferGroup.h +++ b/include/media/stagefright/MediaBufferGroup.h @@ -34,9 +34,12 @@ public: void add_buffer(MediaBuffer *buffer); - // Blocks until a buffer is available and returns it to the caller, - // the returned buffer will have a reference count of 1. - status_t acquire_buffer(MediaBuffer **buffer); + // 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. + status_t acquire_buffer(MediaBuffer **buffer, bool nonBlocking = false); protected: virtual void signalBufferReturned(MediaBuffer *buffer); diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h index 1f17efe..b87a09e 100644 --- a/include/media/stagefright/MediaCodec.h +++ b/include/media/stagefright/MediaCodec.h @@ -26,10 +26,11 @@ namespace android { struct ABuffer; -struct ACodec; struct AMessage; struct AString; +struct CodecBase; struct ICrypto; +struct IBatteryStats; struct SoftwareRenderer; struct Surface; @@ -44,11 +45,20 @@ struct MediaCodec : public AHandler { BUFFER_FLAG_EOS = 4, }; + enum { + CB_INPUT_AVAILABLE = 1, + CB_OUTPUT_AVAILABLE = 2, + CB_ERROR = 3, + CB_OUTPUT_FORMAT_CHANGED = 4, + }; + + struct BatteryNotifier; + static sp<MediaCodec> CreateByType( - const sp<ALooper> &looper, const char *mime, bool encoder); + const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err = NULL); static sp<MediaCodec> CreateByComponentName( - const sp<ALooper> &looper, const char *name); + const sp<ALooper> &looper, const char *name, status_t *err = NULL); status_t configure( const sp<AMessage> &format, @@ -56,6 +66,8 @@ struct MediaCodec : public AHandler { const sp<ICrypto> &crypto, uint32_t flags); + status_t setCallback(const sp<AMessage> &callback); + status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer); status_t start(); @@ -64,6 +76,10 @@ struct MediaCodec : public AHandler { // 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(); @@ -100,16 +116,22 @@ struct MediaCodec : public AHandler { 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<ABuffer> > *buffers) const; status_t getOutputBuffers(Vector<sp<ABuffer> > *buffers) const; + status_t getOutputBuffer(size_t index, sp<ABuffer> *buffer); + status_t getOutputFormat(size_t index, sp<AMessage> *format); + status_t getInputBuffer(size_t index, sp<ABuffer> *buffer); + status_t requestIDRFrame(); // Notification will be posted once there "is something to do", i.e. @@ -135,6 +157,7 @@ private: STARTING, STARTED, FLUSHING, + FLUSHED, STOPPING, RELEASING, }; @@ -159,6 +182,7 @@ private: kWhatGetBuffers = 'getB', kWhatFlush = 'flus', kWhatGetOutputFormat = 'getO', + kWhatGetInputFormat = 'getI', kWhatDequeueInputTimedOut = 'dITO', kWhatDequeueOutputTimedOut = 'dOTO', kWhatCodecNotify = 'codc', @@ -166,6 +190,7 @@ private: kWhatRequestActivityNotification = 'racN', kWhatGetName = 'getN', kWhatSetParameters = 'setP', + kWhatSetCallback = 'setC', }; enum { @@ -179,6 +204,7 @@ private: kFlagSawMediaServerDie = 128, kFlagIsEncoder = 256, kFlagGatherCodecSpecificData = 512, + kFlagIsAsync = 1024, }; struct BufferInfo { @@ -186,19 +212,37 @@ private: sp<ABuffer> mData; sp<ABuffer> mEncryptedData; sp<AMessage> mNotify; + sp<AMessage> mFormat; bool mOwnedByClient; }; State mState; sp<ALooper> mLooper; sp<ALooper> mCodecLooper; - sp<ACodec> mCodec; + sp<CodecBase> mCodec; AString mComponentName; uint32_t mReplyID; uint32_t mFlags; + status_t mStickyError; sp<Surface> mNativeWindow; SoftwareRenderer *mSoftRenderer; sp<AMessage> mOutputFormat; + sp<AMessage> mInputFormat; + sp<AMessage> mCallback; + + bool mBatteryStatNotified; + bool mIsVideo; + + // initial create parameters + AString mInitName; + bool mInitNameIsType; + bool mInitIsEncoder; + + // 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]; Vector<BufferInfo> mPortBuffers[2]; @@ -222,6 +266,8 @@ private: static status_t PostAndAwaitResponse( const sp<AMessage> &msg, sp<AMessage> *response); + static void PostReplyWithError(int32_t replyID, int32_t err); + status_t init(const char *name, bool nameIsType, bool encoder); void setState(State newState); @@ -232,6 +278,10 @@ private: status_t onReleaseOutputBuffer(const sp<AMessage> &msg); ssize_t dequeuePortBuffer(int32_t portIndex); + status_t getBufferAndFormat( + size_t portIndex, size_t index, + sp<ABuffer> *buffer, sp<AMessage> *format); + bool handleDequeueInputBuffer(uint32_t replyID, bool newRequest = false); bool handleDequeueOutputBuffer(uint32_t replyID, bool newRequest = false); void cancelPendingDequeueOperations(); @@ -244,9 +294,28 @@ private: 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<ABuffer> &buffer); + void updateBatteryStat(); + bool isExecuting() const; + + /* 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; + } DISALLOW_EVIL_CONSTRUCTORS(MediaCodec); }; diff --git a/include/media/stagefright/MediaCodecList.h b/include/media/stagefright/MediaCodecList.h index 590623b..8605d99 100644 --- a/include/media/stagefright/MediaCodecList.h +++ b/include/media/stagefright/MediaCodecList.h @@ -20,70 +20,68 @@ #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 { -struct MediaCodecList { - static const MediaCodecList *getInstance(); +struct AMessage; - ssize_t findCodecByType( +struct MediaCodecList : public BnMediaCodecList { + static sp<IMediaCodecList> getInstance(); + + virtual ssize_t findCodecByType( const char *type, bool encoder, size_t startIndex = 0) const; - ssize_t findCodecByName(const char *name) const; + virtual ssize_t findCodecByName(const char *name) const; - size_t countCodecs() const; - const char *getCodecName(size_t index) const; - bool isEncoder(size_t index) const; - bool codecHasQuirk(size_t index, const char *quirkName) const; + virtual size_t countCodecs() const; - status_t getSupportedTypes(size_t index, Vector<AString> *types) const; + virtual sp<MediaCodecInfo> getCodecInfo(size_t index) const { + return mCodecInfos.itemAt(index); + } - struct ProfileLevel { - uint32_t mProfile; - uint32_t mLevel; - }; - status_t getCodecCapabilities( - size_t index, const char *type, - Vector<ProfileLevel> *profileLevels, - Vector<uint32_t> *colorFormats, - uint32_t *flags) const; + // to be used by MediaPlayerService alone + static sp<IMediaCodecList> getLocalInstance(); private: enum Section { SECTION_TOPLEVEL, SECTION_DECODERS, SECTION_DECODER, + SECTION_DECODER_TYPE, SECTION_ENCODERS, SECTION_ENCODER, + SECTION_ENCODER_TYPE, + SECTION_INCLUDE, }; - struct CodecInfo { - AString mName; - bool mIsEncoder; - uint32_t mTypes; - uint32_t mQuirks; - }; - - static MediaCodecList *sCodecList; + static sp<IMediaCodecList> sCodecList; + static sp<IMediaCodecList> sRemoteList; status_t mInitCheck; Section mCurrentSection; + Vector<Section> mPastSections; int32_t mDepth; + AString mHrefBase; - Vector<CodecInfo> mCodecInfos; - KeyedVector<AString, size_t> mCodecQuirks; - KeyedVector<AString, size_t> mTypes; + Vector<sp<MediaCodecInfo> > mCodecInfos; + sp<MediaCodecInfo> mCurrentInfo; + sp<IOMX> mOMX; MediaCodecList(); ~MediaCodecList(); status_t initCheck() const; - void parseXMLFile(FILE *file); + void parseXMLFile(const char *path); + void parseTopLevelXMLFile(const char *path); static void StartElementHandlerWrapper( void *me, const char *name, const char **attrs); @@ -93,13 +91,18 @@ private: void startElementHandler(const char *name, const char **attrs); void endElementHandler(const char *name); + status_t includeXMLFile(const char **attrs); status_t addMediaCodecFromAttributes(bool encoder, const char **attrs); void addMediaCodec(bool encoder, const char *name, const char *type = NULL); 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); }; diff --git a/include/media/stagefright/MediaCodecSource.h b/include/media/stagefright/MediaCodecSource.h new file mode 100644 index 0000000..e1b2830 --- /dev/null +++ b/include/media/stagefright/MediaCodecSource.h @@ -0,0 +1,133 @@ +/* + * 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/MediaSource.h> + +namespace android { + +class ALooper; +class AMessage; +class IGraphicBufferProducer; +class MediaCodec; +class MetaData; + +struct MediaCodecSource : public MediaSource, + public MediaBufferObserver { + enum FlagBits { + FLAG_USE_SURFACE_INPUT = 1, + FLAG_USE_METADATA_INPUT = 2, + }; + + static sp<MediaCodecSource> Create( + const sp<ALooper> &looper, + const sp<AMessage> &format, + const sp<MediaSource> &source, + uint32_t flags = 0); + + bool isVideo() const { return mIsVideo; } + sp<IGraphicBufferProducer> getGraphicBufferProducer(); + + // MediaSource + virtual status_t start(MetaData *params = NULL); + virtual status_t stop(); + virtual status_t pause(); + virtual sp<MetaData> getFormat() { return mMeta; } + virtual status_t read( + MediaBuffer **buffer, + const ReadOptions *options = NULL); + + // MediaBufferObserver + virtual void signalBufferReturned(MediaBuffer *buffer); + + // for AHandlerReflector + void onMessageReceived(const sp<AMessage> &msg); + +protected: + virtual ~MediaCodecSource(); + +private: + struct Puller; + + enum { + kWhatPullerNotify, + kWhatEncoderActivity, + kWhatStart, + kWhatStop, + kWhatPause, + }; + + MediaCodecSource( + const sp<ALooper> &looper, + const sp<AMessage> &outputFormat, + const sp<MediaSource> &source, + uint32_t flags = 0); + + status_t onStart(MetaData *params); + status_t init(); + status_t initEncoder(); + void releaseEncoder(); + status_t feedEncoderInputBuffers(); + void scheduleDoMoreWork(); + status_t doMoreWork(); + void suspend(); + void resume(int64_t skipFramesBeforeUs = -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; + sp<MetaData> mMeta; + sp<Puller> mPuller; + sp<MediaCodec> mEncoder; + uint32_t mFlags; + List<uint32_t> mStopReplyIDQueue; + bool mIsVideo; + bool mStarted; + bool mStopping; + bool mDoMoreWorkPending; + sp<AMessage> mEncoderActivityNotify; + sp<IGraphicBufferProducer> mGraphicBufferProducer; + Vector<sp<ABuffer> > mEncoderInputBuffers; + Vector<sp<ABuffer> > mEncoderOutputBuffers; + List<MediaBuffer *> mInputBufferQueue; + List<size_t> mAvailEncoderInputIndices; + List<int64_t> mDecodingTimeQueue; // decoding time (us) for video + + // audio drift time + int64_t mFirstSampleTimeUs; + List<int64_t> mDriftTimeQueue; + + // following variables are protected by mOutputBufferLock + Mutex mOutputBufferLock; + Condition mOutputBufferCond; + List<MediaBuffer*> mOutputBufferQueue; + bool mEncoderReachedEOS; + status_t mErrorCode; + + DISALLOW_EVIL_CONSTRUCTORS(MediaCodecSource); +}; + +} // namespace android + +#endif /* MediaCodecSource_H_ */ diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h index 85693d4..e67d4d5 100644 --- a/include/media/stagefright/MediaDefs.h +++ b/include/media/stagefright/MediaDefs.h @@ -25,6 +25,7 @@ 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; @@ -38,12 +39,14 @@ extern const char *MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II; 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_CONTAINER_MPEG4; extern const char *MEDIA_MIMETYPE_CONTAINER_WAV; @@ -57,6 +60,8 @@ extern const char *MEDIA_MIMETYPE_CONTAINER_WVM; 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; } // namespace android diff --git a/include/media/stagefright/MediaErrors.h b/include/media/stagefright/MediaErrors.h index 686f286..2e663ec 100644 --- a/include/media/stagefright/MediaErrors.h +++ b/include/media/stagefright/MediaErrors.h @@ -23,6 +23,18 @@ 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, @@ -46,26 +58,54 @@ enum { // 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_VENDOR_MAX = DRM_ERROR_BASE - 500, - ERROR_DRM_VENDOR_MIN = DRM_ERROR_BASE - 999, + 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/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h index 3076a96..183933a 100644 --- a/include/media/stagefright/MediaExtractor.h +++ b/include/media/stagefright/MediaExtractor.h @@ -65,6 +65,8 @@ public: virtual char* getDrmTrackInfo(size_t trackID, int *len) { return NULL; } + virtual void setUID(uid_t uid) { + } protected: MediaExtractor() : mIsDrm(false) {} diff --git a/include/media/stagefright/MediaHTTP.h b/include/media/stagefright/MediaHTTP.h new file mode 100644 index 0000000..006d8d8 --- /dev/null +++ b/include/media/stagefright/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/include/media/stagefright/MediaMuxer.h b/include/media/stagefright/MediaMuxer.h index ff6a66e..bbe4303 100644 --- a/include/media/stagefright/MediaMuxer.h +++ b/include/media/stagefright/MediaMuxer.h @@ -30,7 +30,7 @@ struct MediaAdapter; struct MediaBuffer; struct MediaSource; struct MetaData; -struct MPEG4Writer; +struct MediaWriter; // MediaMuxer is used to mux multiple tracks into a video. Currently, we only // support a mp4 file as the output. @@ -44,6 +44,7 @@ public: // OutputFormat is updated. enum OutputFormat { OUTPUT_FORMAT_MPEG_4 = 0, + OUTPUT_FORMAT_WEBM = 1, OUTPUT_FORMAT_LIST_END // must be last - used to validate format type }; @@ -115,7 +116,8 @@ public: int64_t timeUs, uint32_t flags) ; private: - sp<MPEG4Writer> mWriter; + const OutputFormat mFormat; + sp<MediaWriter> mWriter; Vector< sp<MediaAdapter> > mTrackList; // Each track has its MediaAdapter. sp<MetaData> mFileMeta; // Metadata for the whole file. diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h index 204d1c6..a653db9 100644 --- a/include/media/stagefright/MediaSource.h +++ b/include/media/stagefright/MediaSource.h @@ -82,6 +82,10 @@ struct MediaSource : public virtual RefBase { void setLateBy(int64_t lateness_us); int64_t getLateBy() const; + void setNonBlocking(); + void clearNonBlocking(); + bool getNonBlocking() const; + private: enum Options { kSeekTo_Option = 1, @@ -91,6 +95,7 @@ struct MediaSource : public virtual RefBase { int64_t mSeekTimeUs; SeekMode mSeekMode; int64_t mLatenessUs; + bool mNonBlocking; }; // Causes this source to suspend pulling data from its upstream source diff --git a/include/media/stagefright/MediaWriter.h b/include/media/stagefright/MediaWriter.h index 5cc8dcf..e27ea1d 100644 --- a/include/media/stagefright/MediaWriter.h +++ b/include/media/stagefright/MediaWriter.h @@ -48,6 +48,9 @@ struct MediaWriter : public RefBase { return OK; } + virtual void setStartTimeOffsetMs(int ms) {} + virtual int32_t getStartTimeOffsetMs() const { return 0; } + protected: virtual ~MediaWriter() {} int64_t mMaxFileSizeLimitBytes; diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h index db8216b..087d016 100644 --- a/include/media/stagefright/MetaData.h +++ b/include/media/stagefright/MetaData.h @@ -53,9 +53,13 @@ enum { 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) kKeyWantsNALFragments = 'NALf', kKeyIsSyncFrame = 'sync', // int32_t (bool) kKeyIsCodecConfig = 'conf', // int32_t (bool) @@ -162,11 +166,19 @@ enum { 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) }; enum { kTypeESDS = 'esds', kTypeAVCC = 'avcc', + kTypeHVCC = 'hvcc', kTypeD263 = 'd263', }; diff --git a/include/media/stagefright/NuMediaExtractor.h b/include/media/stagefright/NuMediaExtractor.h index 5ae6f6b..402e7f8 100644 --- a/include/media/stagefright/NuMediaExtractor.h +++ b/include/media/stagefright/NuMediaExtractor.h @@ -31,6 +31,7 @@ namespace android { struct ABuffer; struct AMessage; struct DataSource; +struct IMediaHTTPService; struct MediaBuffer; struct MediaExtractor; struct MediaSource; @@ -45,6 +46,7 @@ struct NuMediaExtractor : public RefBase { NuMediaExtractor(); status_t setDataSource( + const sp<IMediaHTTPService> &httpService, const char *path, const KeyedVector<String8, String8> *headers = NULL); diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index daaf20f..e341160 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -28,7 +28,7 @@ namespace android { -struct MediaCodecList; +struct MediaCodecInfo; class MemoryDealer; struct OMXCodecObserver; struct CodecProfileLevel; @@ -115,7 +115,7 @@ struct OMXCodec : public MediaSource, Vector<CodecNameAndQuirks> *matchingCodecNamesAndQuirks); static uint32_t getComponentQuirks( - const MediaCodecList *list, size_t index); + const sp<MediaCodecInfo> &list); static bool findCodecQuirks(const char *componentName, uint32_t *quirks); @@ -248,6 +248,8 @@ private: int32_t numChannels, int32_t sampleRate, int32_t bitRate, int32_t aacProfile, bool isADTS); + status_t setAC3Format(int32_t numChannels, int32_t sampleRate); + void setG711Format(int32_t numChannels); status_t setVideoPortFormatType( @@ -350,6 +352,9 @@ private: int64_t getDecodingTimeUs(); + status_t parseHEVCCodecSpecificData( + const void *data, size_t size, + unsigned *profile, unsigned *level); status_t parseAVCCodecSpecificData( const void *data, size_t size, unsigned *profile, unsigned *level); diff --git a/include/media/stagefright/SkipCutBuffer.h b/include/media/stagefright/SkipCutBuffer.h index 2653b53..098aa69 100644 --- a/include/media/stagefright/SkipCutBuffer.h +++ b/include/media/stagefright/SkipCutBuffer.h @@ -47,6 +47,7 @@ class SkipCutBuffer: public RefBase { private: void write(const char *src, size_t num); size_t read(char *dst, size_t num); + int32_t mSkip; int32_t mFrontPadding; int32_t mBackPadding; int32_t mWriteHead; diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h index db5f947..43b75fd 100644 --- a/include/media/stagefright/SurfaceMediaSource.h +++ b/include/media/stagefright/SurfaceMediaSource.h @@ -111,7 +111,7 @@ public: // pass metadata through the buffers. Currently, it is force set to true bool isMetaDataStoredInVideoBuffers() const; - sp<BufferQueue> getBufferQueue() const { return mBufferQueue; } + sp<IGraphicBufferProducer> getProducer() const { return mProducer; } // To be called before start() status_t setMaxAcquiredBufferCount(size_t count); @@ -139,12 +139,17 @@ protected: // 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: - // mBufferQueue is the exchange point between the producer and - // this consumer - sp<BufferQueue> mBufferQueue; + // 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; diff --git a/include/media/stagefright/Utils.h b/include/media/stagefright/Utils.h index bbad271..a795c80 100644 --- a/include/media/stagefright/Utils.h +++ b/include/media/stagefright/Utils.h @@ -53,6 +53,9 @@ 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); @@ -60,6 +63,8 @@ status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink, const sp<MetaDa bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, bool isStreaming, audio_stream_type_t streamType); +AString uriDebugString(const AString &uri, bool incognito = false); + } // namespace android #endif // UTILS_H_ diff --git a/include/media/stagefright/foundation/ABase.h b/include/media/stagefright/foundation/ABase.h index 9eceea3..72e3d87 100644 --- a/include/media/stagefright/foundation/ABase.h +++ b/include/media/stagefright/foundation/ABase.h @@ -18,8 +18,37 @@ #define A_BASE_H_ +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) + #define DISALLOW_EVIL_CONSTRUCTORS(name) \ name(const name &); \ name &operator=(const name &) +/* 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/include/media/stagefright/foundation/ABitReader.h b/include/media/stagefright/foundation/ABitReader.h index 5510b12..c3bf0ff 100644 --- a/include/media/stagefright/foundation/ABitReader.h +++ b/include/media/stagefright/foundation/ABitReader.h @@ -25,8 +25,10 @@ namespace android { -struct ABitReader { +class ABitReader { +public: ABitReader(const uint8_t *data, size_t size); + virtual ~ABitReader(); uint32_t getBits(size_t n); void skipBits(size_t n); @@ -37,18 +39,32 @@ struct ABitReader { const uint8_t *data() const; -private: +protected: const uint8_t *mData; size_t mSize; uint32_t mReservoir; // left-aligned bits size_t mNumBitsLeft; - void fillReservoir(); + virtual void 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 void fillReservoir(); + + DISALLOW_EVIL_CONSTRUCTORS(NALBitReader); +}; + } // namespace android #endif // A_BIT_READER_H_ diff --git a/include/media/stagefright/foundation/ABuffer.h b/include/media/stagefright/foundation/ABuffer.h index 28f0aed..602f7ab 100644 --- a/include/media/stagefright/foundation/ABuffer.h +++ b/include/media/stagefright/foundation/ABuffer.h @@ -42,6 +42,9 @@ struct ABuffer : public RefBase { 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; } diff --git a/include/media/stagefright/foundation/AHierarchicalStateMachine.h b/include/media/stagefright/foundation/AHierarchicalStateMachine.h index d2e6b28..3bb7d75 100644 --- a/include/media/stagefright/foundation/AHierarchicalStateMachine.h +++ b/include/media/stagefright/foundation/AHierarchicalStateMachine.h @@ -43,13 +43,13 @@ private: DISALLOW_EVIL_CONSTRUCTORS(AState); }; -struct AHierarchicalStateMachine : public AHandler { +struct AHierarchicalStateMachine { AHierarchicalStateMachine(); protected: virtual ~AHierarchicalStateMachine(); - virtual void onMessageReceived(const sp<AMessage> &msg); + virtual void handleMessage(const sp<AMessage> &msg); // Only to be called in response to a message. void changeState(const sp<AState> &state); diff --git a/include/media/stagefright/foundation/ALooperRoster.h b/include/media/stagefright/foundation/ALooperRoster.h index 940fc55..4d76b64 100644 --- a/include/media/stagefright/foundation/ALooperRoster.h +++ b/include/media/stagefright/foundation/ALooperRoster.h @@ -56,8 +56,6 @@ private: KeyedVector<uint32_t, sp<AMessage> > mReplies; - status_t postMessage_l(const sp<AMessage> &msg, int64_t delayUs); - DISALLOW_EVIL_CONSTRUCTORS(ALooperRoster); }; diff --git a/include/media/stagefright/foundation/AMessage.h b/include/media/stagefright/foundation/AMessage.h index 7e823eb..a9e235b 100644 --- a/include/media/stagefright/foundation/AMessage.h +++ b/include/media/stagefright/foundation/AMessage.h @@ -50,6 +50,7 @@ struct AMessage : public RefBase { 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); @@ -58,6 +59,8 @@ struct AMessage : public RefBase { 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; @@ -134,7 +137,9 @@ private: Rect rectValue; } u; const char *mName; + size_t mNameLength; Type mType; + void setName(const char *name, size_t len); }; enum { @@ -144,12 +149,14 @@ private: size_t mNumItems; Item *allocateItem(const char *name); - void freeItem(Item *item); + 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; + DISALLOW_EVIL_CONSTRUCTORS(AMessage); }; diff --git a/include/media/stagefright/foundation/AString.h b/include/media/stagefright/foundation/AString.h index 0f8f1e1..7c98699 100644 --- a/include/media/stagefright/foundation/AString.h +++ b/include/media/stagefright/foundation/AString.h @@ -18,14 +18,19 @@ #define A_STRING_H_ +#include <utils/Errors.h> #include <sys/types.h> namespace android { +struct String8; +struct Parcel; + struct AString { AString(); AString(const char *s); AString(const char *s, size_t size); + AString(const String8 &from); AString(const AString &from); AString(const AString &from, size_t offset, size_t n); ~AString(); @@ -67,16 +72,26 @@ struct AString { 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; diff --git a/include/media/stagefright/timedtext/TimedTextDriver.h b/include/media/stagefright/timedtext/TimedTextDriver.h index f23c337..37ef674 100644 --- a/include/media/stagefright/timedtext/TimedTextDriver.h +++ b/include/media/stagefright/timedtext/TimedTextDriver.h @@ -25,6 +25,7 @@ namespace android { class ALooper; +struct IMediaHTTPService; class MediaPlayerBase; class MediaSource; class Parcel; @@ -34,7 +35,9 @@ class DataSource; class TimedTextDriver { public: - TimedTextDriver(const wp<MediaPlayerBase> &listener); + TimedTextDriver( + const wp<MediaPlayerBase> &listener, + const sp<IMediaHTTPService> &httpService); ~TimedTextDriver(); @@ -77,6 +80,7 @@ private: sp<ALooper> mLooper; sp<TimedTextPlayer> mPlayer; wp<MediaPlayerBase> mListener; + sp<IMediaHTTPService> mHTTPService; // Variables to be guarded by mLock. State mState; |