diff options
Diffstat (limited to 'include/media')
58 files changed, 3527 insertions, 164 deletions
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index 13e51ee..008468c 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -26,8 +26,8 @@ #include <utils/RefBase.h> #include <utils/Errors.h> -#include <utils/IInterface.h> -#include <utils/IMemory.h> +#include <binder/IInterface.h> +#include <binder/IMemory.h> #include <utils/threads.h> @@ -39,21 +39,10 @@ class AudioRecord { public: - // input sources values must always be defined in the range - // [AudioRecord::DEFAULT_INPUT, AudioRecord::NUM_INPUT_SOURCES[ - enum input_source { - DEFAULT_INPUT =-1, - MIC_INPUT = 0, - VOICE_UPLINK_INPUT = 1, - VOICE_DOWNLINK_INPUT = 2, - VOICE_CALL_INPUT = 3, - NUM_INPUT_SOURCES - }; - static const int DEFAULT_SAMPLE_RATE = 8000; /* Events used by AudioRecord callback function (callback_t). - * + * * to keep in sync with frameworks/base/media/java/android/media/AudioRecord.java */ enum event_type { @@ -61,7 +50,7 @@ public: EVENT_OVERRUN = 1, // PCM buffer overrun occured. EVENT_MARKER = 2, // Record head is at the specified marker position // (See setMarkerPosition()). - EVENT_NEW_POS = 3, // Record head is at a new position + EVENT_NEW_POS = 3, // Record head is at a new position // (See setPositionUpdatePeriod()). }; @@ -123,11 +112,11 @@ public: * * Parameters: * - * inputSource: Select the audio input to record to (e.g. AudioRecord::MIC_INPUT). + * inputSource: Select the audio input to record to (e.g. AUDIO_SOURCE_DEFAULT). * sampleRate: Track sampling rate in Hz. - * format: PCM sample format (e.g AudioSystem::PCM_16_BIT for signed + * format: Audio format (e.g AudioSystem::PCM_16_BIT for signed * 16 bits per sample). - * channelCount: Number of PCM channels (e.g 2 for stereo). + * channels: Channel mask: see AudioSystem::audio_channels. * frameCount: Total size of track PCM buffer in frames. This defines the * latency of the track. * flags: A bitmask of acoustic values from enum record_flags. It enables @@ -148,7 +137,7 @@ public: AudioRecord(int inputSource, uint32_t sampleRate = 0, int format = 0, - int channelCount = 0, + uint32_t channels = AudioSystem::CHANNEL_IN_MONO, int frameCount = 0, uint32_t flags = 0, callback_t cbf = 0, @@ -166,14 +155,14 @@ public: * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful intialization * - INVALID_OPERATION: AudioRecord is already intitialized or record device is already in use - * - BAD_VALUE: invalid parameter (channelCount, format, sampleRate...) + * - BAD_VALUE: invalid parameter (channels, format, sampleRate...) * - NO_INIT: audio server or audio hardware not initialized * - PERMISSION_DENIED: recording is not allowed for the requesting process * */ status_t set(int inputSource = 0, uint32_t sampleRate = 0, int format = 0, - int channelCount = 0, + uint32_t channels = AudioSystem::CHANNEL_IN_MONO, int frameCount = 0, uint32_t flags = 0, callback_t cbf = 0, @@ -199,6 +188,7 @@ public: int format() const; int channelCount() const; + int channels() const; uint32_t frameCount() const; int frameSize() const; int inputSource() const; @@ -222,8 +212,8 @@ public: /* 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. - * If the AudioRecord has been opened with no callback function associated, + * with marker == 0 cancels marker notification callback. + * If the AudioRecord has been opened with no callback function associated, * the operation will fail. * * Parameters: @@ -238,10 +228,10 @@ public: status_t getMarkerPosition(uint32_t *marker); - /* Sets position update period. Every time the number of frames specified has been recorded, - * a callback with event type EVENT_NEW_POS is called. - * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification - * callback. + /* Sets position update period. Every time the number of frames specified has been recorded, + * a callback with event type EVENT_NEW_POS is called. + * Calling setPositionUpdatePeriod with updatePeriod == 0 cancels new position notification + * callback. * If the AudioRecord has been opened with no callback function associated, * the operation will fail. * @@ -257,8 +247,8 @@ public: status_t getPositionUpdatePeriod(uint32_t *updatePeriod); - /* Gets record head position. The position is the total number of frames - * recorded since record start. + /* Gets record head position. The position is the total number of frames + * recorded since record start. * * Parameters: * @@ -270,8 +260,16 @@ public: */ status_t getPosition(uint32_t *position); - - + /* returns a handle on the audio input used by this AudioRecord. + * + * Parameters: + * none. + * + * Returned value: + * handle on audio hardware input + */ + audio_io_handle_t getInput() { return mInput; } + /* obtains a buffer of "frameCount" frames. The buffer must be * filled entirely. If the track is stopped, obtainBuffer() returns * STOPPED instead of NO_ERROR as long as there are buffers availlable, @@ -316,6 +314,11 @@ private: }; bool processAudioBuffer(const sp<ClientRecordThread>& thread); + status_t openRecord(uint32_t sampleRate, + int format, + int channelCount, + int frameCount, + uint32_t flags); sp<IAudioRecord> mAudioRecord; sp<IMemory> mCblkMemory; @@ -342,6 +345,8 @@ private: bool mMarkerReached; uint32_t mNewPosition; uint32_t mUpdatePeriod; + audio_io_handle_t mInput; + uint32_t mFlags; }; }; // namespace android diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index 3a3a714..e066177 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -24,36 +24,130 @@ namespace android { typedef void (*audio_error_callback)(status_t err); +typedef int audio_io_handle_t; + +class IAudioPolicyService; +class String8; class AudioSystem { public: enum stream_type { - DEFAULT =-1, - VOICE_CALL = 0, - SYSTEM = 1, - RING = 2, - MUSIC = 3, - ALARM = 4, - NOTIFICATION = 5, - BLUETOOTH_SCO = 6, + DEFAULT =-1, + VOICE_CALL = 0, + SYSTEM = 1, + RING = 2, + MUSIC = 3, + ALARM = 4, + NOTIFICATION = 5, + BLUETOOTH_SCO = 6, ENFORCED_AUDIBLE = 7, // Sounds that cannot be muted by user and must be routed to speaker + DTMF = 8, + TTS = 9, NUM_STREAM_TYPES }; - enum audio_output_type { - AUDIO_OUTPUT_DEFAULT =-1, - AUDIO_OUTPUT_HARDWARE = 0, - AUDIO_OUTPUT_A2DP = 1, - NUM_AUDIO_OUTPUT_TYPES + // Audio sub formats (see AudioSystem::audio_format). + enum pcm_sub_format { + PCM_SUB_16_BIT = 0x1, // must be 1 for backward compatibility + PCM_SUB_8_BIT = 0x2, // must be 2 for backward compatibility + }; + + // MP3 sub format field definition : can use 11 LSBs in the same way as MP3 frame header to specify + // bit rate, stereo mode, version... + enum mp3_sub_format { + //TODO + }; + + // AMR NB/WB sub format field definition: specify frame block interleaving, bandwidth efficient or octet aligned, + // encoding mode for recording... + enum amr_sub_format { + //TODO + }; + + // AAC sub format field definition: specify profile or bitrate for recording... + enum aac_sub_format { + //TODO }; + // VORBIS sub format field definition: specify quality for recording... + enum vorbis_sub_format { + //TODO + }; + + // Audio format consists in a main format field (upper 8 bits) and a sub format field (lower 24 bits). + // The main format indicates the main codec type. The sub format field indicates options and parameters + // for each format. The sub format is mainly used for record to indicate for instance the requested bitrate + // or profile. It can also be used for certain formats to give informations not present in the encoded + // audio stream (e.g. octet alignement for AMR). enum audio_format { - FORMAT_DEFAULT = 0, - PCM_16_BIT, - PCM_8_BIT, - INVALID_FORMAT + INVALID_FORMAT = -1, + FORMAT_DEFAULT = 0, + PCM = 0x00000000, // must be 0 for backward compatibility + MP3 = 0x01000000, + AMR_NB = 0x02000000, + AMR_WB = 0x03000000, + AAC = 0x04000000, + HE_AAC_V1 = 0x05000000, + HE_AAC_V2 = 0x06000000, + VORBIS = 0x07000000, + MAIN_FORMAT_MASK = 0xFF000000, + SUB_FORMAT_MASK = 0x00FFFFFF, + // Aliases + PCM_16_BIT = (PCM|PCM_SUB_16_BIT), + PCM_8_BIT = (PCM|PCM_SUB_8_BIT) + }; + + + // Channel mask definitions must be kept in sync with JAVA values in /media/java/android/media/AudioFormat.java + enum audio_channels { + // output channels + CHANNEL_OUT_FRONT_LEFT = 0x4, + CHANNEL_OUT_FRONT_RIGHT = 0x8, + CHANNEL_OUT_FRONT_CENTER = 0x10, + CHANNEL_OUT_LOW_FREQUENCY = 0x20, + CHANNEL_OUT_BACK_LEFT = 0x40, + CHANNEL_OUT_BACK_RIGHT = 0x80, + CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x100, + CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x200, + CHANNEL_OUT_BACK_CENTER = 0x400, + CHANNEL_OUT_MONO = CHANNEL_OUT_FRONT_LEFT, + CHANNEL_OUT_STEREO = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT), + CHANNEL_OUT_QUAD = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT), + CHANNEL_OUT_SURROUND = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_CENTER), + CHANNEL_OUT_5POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT), + CHANNEL_OUT_7POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT | + CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER), + CHANNEL_OUT_ALL = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT | + CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER | CHANNEL_OUT_BACK_CENTER), + + // input channels + CHANNEL_IN_LEFT = 0x4, + CHANNEL_IN_RIGHT = 0x8, + CHANNEL_IN_FRONT = 0x10, + CHANNEL_IN_BACK = 0x20, + CHANNEL_IN_LEFT_PROCESSED = 0x40, + CHANNEL_IN_RIGHT_PROCESSED = 0x80, + CHANNEL_IN_FRONT_PROCESSED = 0x100, + CHANNEL_IN_BACK_PROCESSED = 0x200, + CHANNEL_IN_PRESSURE = 0x400, + CHANNEL_IN_X_AXIS = 0x800, + CHANNEL_IN_Y_AXIS = 0x1000, + CHANNEL_IN_Z_AXIS = 0x2000, + CHANNEL_IN_VOICE_UPLINK = 0x4000, + CHANNEL_IN_VOICE_DNLINK = 0x8000, + CHANNEL_IN_MONO = CHANNEL_IN_FRONT, + CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT), + CHANNEL_IN_ALL = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT | CHANNEL_IN_FRONT | CHANNEL_IN_BACK| + CHANNEL_IN_LEFT_PROCESSED | CHANNEL_IN_RIGHT_PROCESSED | CHANNEL_IN_FRONT_PROCESSED | CHANNEL_IN_BACK_PROCESSED| + CHANNEL_IN_PRESSURE | CHANNEL_IN_X_AXIS | CHANNEL_IN_Y_AXIS | CHANNEL_IN_Z_AXIS | + CHANNEL_IN_VOICE_UPLINK | CHANNEL_IN_VOICE_DNLINK) }; enum audio_mode { @@ -65,15 +159,6 @@ public: NUM_MODES // not a valid entry, denotes end-of-list }; - enum audio_routes { - ROUTE_EARPIECE = (1 << 0), - ROUTE_SPEAKER = (1 << 1), - ROUTE_BLUETOOTH_SCO = (1 << 2), - ROUTE_HEADSET = (1 << 3), - ROUTE_BLUETOOTH_A2DP = (1 << 4), - ROUTE_ALL = -1UL, - }; - enum audio_in_acoustics { AGC_ENABLE = 0x0001, AGC_DISABLE = 0, @@ -87,36 +172,37 @@ public: * only privileged processes can have access to them */ - // routing helper functions - static status_t speakerphone(bool state); - static status_t isSpeakerphoneOn(bool* state); - static status_t bluetoothSco(bool state); - static status_t isBluetoothScoOn(bool* state); + // mute/unmute microphone static status_t muteMicrophone(bool state); static status_t isMicrophoneMuted(bool *state); + // set/get master volume static status_t setMasterVolume(float value); - static status_t setMasterMute(bool mute); static status_t getMasterVolume(float* volume); + // mute/unmute audio outputs + static status_t setMasterMute(bool mute); static status_t getMasterMute(bool* mute); - static status_t setStreamVolume(int stream, float value); + // set/get stream volume on specified output + static status_t setStreamVolume(int stream, float value, int output); + static status_t getStreamVolume(int stream, float* volume, int output); + + // mute/unmute stream static status_t setStreamMute(int stream, bool mute); - static status_t getStreamVolume(int stream, float* volume); static status_t getStreamMute(int stream, bool* mute); + // set audio mode in audio hardware (see AudioSystem::audio_mode) static status_t setMode(int mode); - static status_t getMode(int* mode); - - static status_t setRouting(int mode, uint32_t routes, uint32_t mask); - static status_t getRouting(int mode, uint32_t* routes); + // returns true if tracks are active on AudioSystem::MUSIC stream static status_t isMusicActive(bool *state); - // Temporary interface, do not use - // TODO: Replace with a more generic key:value get/set mechanism - static status_t setParameter(const char* key, const char* value); - + // 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). + static status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs); + static String8 getParameters(audio_io_handle_t ioHandle, const String8& keys); + static void setErrorCallback(audio_error_callback cb); // helper function to obtain AudioFlinger service handle @@ -130,47 +216,250 @@ public: static status_t getOutputLatency(uint32_t* latency, int stream = DEFAULT); static bool routedToA2dpOutput(int streamType); - - static status_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount, + + static status_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount, size_t* buffSize); + static status_t setVoiceVolume(float volume); + + // + // AudioPolicyService interface + // + + enum audio_devices { + // output devices + DEVICE_OUT_EARPIECE = 0x1, + DEVICE_OUT_SPEAKER = 0x2, + DEVICE_OUT_WIRED_HEADSET = 0x4, + DEVICE_OUT_WIRED_HEADPHONE = 0x8, + DEVICE_OUT_BLUETOOTH_SCO = 0x10, + DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20, + DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40, + DEVICE_OUT_BLUETOOTH_A2DP = 0x80, + DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100, + DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200, + DEVICE_OUT_AUX_DIGITAL = 0x400, + DEVICE_OUT_FM_HEADPHONE = 0x800, + DEVICE_OUT_FM_SPEAKER = 0x1000, + DEVICE_OUT_TTY = 0x2000, + DEVICE_OUT_DEFAULT = 0x8000, + DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE | DEVICE_OUT_SPEAKER | DEVICE_OUT_WIRED_HEADSET | + DEVICE_OUT_WIRED_HEADPHONE | DEVICE_OUT_BLUETOOTH_SCO | DEVICE_OUT_BLUETOOTH_SCO_HEADSET | + DEVICE_OUT_BLUETOOTH_SCO_CARKIT | DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | + DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | DEVICE_OUT_AUX_DIGITAL | DEVICE_OUT_FM_HEADPHONE | + DEVICE_OUT_FM_SPEAKER | DEVICE_OUT_TTY | DEVICE_OUT_DEFAULT), + + // input devices + DEVICE_IN_COMMUNICATION = 0x10000, + DEVICE_IN_AMBIENT = 0x20000, + DEVICE_IN_BUILTIN_MIC = 0x40000, + DEVICE_IN_BLUETOOTH_SCO_HEADSET = 0x80000, + DEVICE_IN_WIRED_HEADSET = 0x100000, + DEVICE_IN_AUX_DIGITAL = 0x200000, + DEVICE_IN_VOICE_CALL = 0x400000, + DEVICE_IN_BACK_MIC = 0x800000, + DEVICE_IN_DEFAULT = 0x80000000, + + DEVICE_IN_ALL = (DEVICE_IN_COMMUNICATION | DEVICE_IN_AMBIENT | DEVICE_IN_BUILTIN_MIC | + DEVICE_IN_BLUETOOTH_SCO_HEADSET | DEVICE_IN_WIRED_HEADSET | DEVICE_IN_AUX_DIGITAL | + DEVICE_IN_VOICE_CALL | DEVICE_IN_BACK_MIC | DEVICE_IN_DEFAULT) + }; + + // device connection states used for setDeviceConnectionState() + enum device_connection_state { + DEVICE_STATE_UNAVAILABLE, + DEVICE_STATE_AVAILABLE, + NUM_DEVICE_STATES + }; + + // request to open a direct output with getOutput() (by opposition to sharing an output with other AudioTracks) + enum output_flags { + OUTPUT_FLAG_INDIRECT = 0x0, + OUTPUT_FLAG_DIRECT = 0x1 + }; + + // device categories used for setForceUse() + enum forced_config { + FORCE_NONE, + FORCE_SPEAKER, + FORCE_HEADPHONES, + FORCE_BT_SCO, + FORCE_BT_A2DP, + FORCE_WIRED_ACCESSORY, + NUM_FORCE_CONFIG, + FORCE_DEFAULT = FORCE_NONE + }; + + // usages used for setForceUse() + enum force_use { + FOR_COMMUNICATION, + FOR_MEDIA, + FOR_RECORD, + NUM_FORCE_USE + }; + + // types of io configuration change events received with ioConfigChanged() + enum io_config_event { + OUTPUT_OPENED, + OUTPUT_CLOSED, + OUTPUT_CONFIG_CHANGED, + INPUT_OPENED, + INPUT_CLOSED, + INPUT_CONFIG_CHANGED, + STREAM_CONFIG_CHANGED, + NUM_CONFIG_EVENTS + }; + + // audio output descritor used to cache output configurations in client process to avoid frequent calls + // through IAudioFlinger + class OutputDescriptor { + public: + OutputDescriptor() + : samplingRate(0), format(0), channels(0), frameCount(0), latency(0) {} + + uint32_t samplingRate; + int32_t format; + int32_t channels; + size_t frameCount; + uint32_t latency; + }; + + // + // IAudioPolicyService interface (see AudioPolicyInterface for method descriptions) + // + static status_t setDeviceConnectionState(audio_devices device, device_connection_state state, const char *device_address); + static device_connection_state getDeviceConnectionState(audio_devices device, const char *device_address); + static status_t setPhoneState(int state); + static status_t setRingerMode(uint32_t mode, uint32_t mask); + static status_t setForceUse(force_use usage, forced_config config); + static forced_config getForceUse(force_use usage); + static audio_io_handle_t getOutput(stream_type stream, + uint32_t samplingRate = 0, + uint32_t format = FORMAT_DEFAULT, + uint32_t channels = CHANNEL_OUT_STEREO, + output_flags flags = OUTPUT_FLAG_INDIRECT); + static status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream); + static status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream); + static void releaseOutput(audio_io_handle_t output); + static audio_io_handle_t getInput(int inputSource, + uint32_t samplingRate = 0, + uint32_t format = FORMAT_DEFAULT, + uint32_t channels = CHANNEL_IN_MONO, + audio_in_acoustics acoustics = (audio_in_acoustics)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); + static status_t initStreamVolume(stream_type stream, + int indexMin, + int indexMax); + static status_t setStreamVolumeIndex(stream_type stream, int index); + static status_t getStreamVolumeIndex(stream_type stream, int *index); + + static const sp<IAudioPolicyService>& get_audio_policy_service(); + // ---------------------------------------------------------------------------- + static uint32_t popCount(uint32_t u); + static bool isOutputDevice(audio_devices device); + static bool isInputDevice(audio_devices device); + static bool isA2dpDevice(audio_devices device); + static bool isBluetoothScoDevice(audio_devices device); + static bool isLowVisibility(stream_type stream); + static bool isOutputChannel(uint32_t channel); + static bool isInputChannel(uint32_t channel); + static bool isValidFormat(uint32_t format); + static bool isLinearPCM(uint32_t format); + private: class AudioFlingerClient: public IBinder::DeathRecipient, public BnAudioFlingerClient { public: - AudioFlingerClient() { + AudioFlingerClient() { } - + // DeathRecipient virtual void binderDied(const wp<IBinder>& who); - + // IAudioFlingerClient - virtual void a2dpEnabledChanged(bool enabled); - + + // indicate a change in the configuration of an output or input: keeps the cached + // values for output/input parameters upto date in client process + virtual void ioConfigChanged(int event, int ioHandle, void *param2); }; - static int getOutput(int streamType); - static sp<AudioFlingerClient> gAudioFlingerClient; + class AudioPolicyServiceClient: public IBinder::DeathRecipient + { + public: + AudioPolicyServiceClient() { + } + // DeathRecipient + virtual void binderDied(const wp<IBinder>& who); + }; + + static sp<AudioFlingerClient> gAudioFlingerClient; + static sp<AudioPolicyServiceClient> gAudioPolicyServiceClient; friend class AudioFlingerClient; + friend class AudioPolicyServiceClient; static Mutex gLock; static sp<IAudioFlinger> gAudioFlinger; static audio_error_callback gAudioErrorCallback; - static int gOutSamplingRate[NUM_AUDIO_OUTPUT_TYPES]; - static int gOutFrameCount[NUM_AUDIO_OUTPUT_TYPES]; - static uint32_t gOutLatency[NUM_AUDIO_OUTPUT_TYPES]; - static bool gA2dpEnabled; - + static size_t gInBuffSize; // previous parameters for recording buffer size queries static uint32_t gPrevInSamplingRate; static int gPrevInFormat; static int gPrevInChannelCount; + static sp<IAudioPolicyService> gAudioPolicyService; + + // mapping between stream types and outputs + static DefaultKeyedVector<int, audio_io_handle_t> gStreamOutputMap; + // list of output descritor containing cached parameters (sampling rate, framecount, channel count...) + static DefaultKeyedVector<audio_io_handle_t, OutputDescriptor *> gOutputs; +}; + +class AudioParameter { + +public: + AudioParameter() {} + AudioParameter(const String8& keyValuePairs); + virtual ~AudioParameter(); + + // reserved parameter keys for changeing standard parameters with setParameters() function. + // Using these keys is mandatory for AudioFlinger to properly monitor audio output/input + // configuration changes and act accordingly. + // keyRouting: to change audio routing, value is an int in AudioSystem::audio_devices + // keySamplingRate: to change sampling rate routing, value is an int + // keyFormat: to change audio format, value is an int in AudioSystem::audio_format + // keyChannels: to change audio channel configuration, value is an int in AudioSystem::audio_channels + // keyFrameCount: to change audio output frame count, value is an int + static const char *keyRouting; + static const char *keySamplingRate; + static const char *keyFormat; + static const char *keyChannels; + static const char *keyFrameCount; + + String8 toString(); + + status_t add(const String8& key, const String8& value); + status_t addInt(const String8& key, const int value); + status_t addFloat(const String8& key, const float value); + + status_t remove(const String8& key); + + status_t get(const String8& key, String8& value); + status_t getInt(const String8& key, int& value); + status_t getFloat(const String8& key, float& value); + status_t getAt(size_t index, String8& key, String8& value); + + size_t size() { return mParameters.size(); } + +private: + String8 mKeyValuePairs; + KeyedVector <String8, String8> mParameters; }; }; // namespace android diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index 7c86a65..14b30ae 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -26,8 +26,8 @@ #include <utils/RefBase.h> #include <utils/Errors.h> -#include <utils/IInterface.h> -#include <utils/IMemory.h> +#include <binder/IInterface.h> +#include <binder/IMemory.h> #include <utils/threads.h> @@ -117,9 +117,9 @@ public: * streamType: Select the type of audio stream this track is attached to * (e.g. AudioSystem::MUSIC). * sampleRate: Track sampling rate in Hz. - * format: PCM sample format (e.g AudioSystem::PCM_16_BIT for signed + * format: Audio format (e.g AudioSystem::PCM_16_BIT for signed * 16 bits per sample). - * channelCount: Number of PCM channels (e.g 2 for stereo). + * channels: Channel mask: see AudioSystem::audio_channels. * frameCount: Total size of track PCM buffer in frames. This defines the * latency of the track. * flags: Reserved for future use. @@ -133,7 +133,7 @@ public: AudioTrack( int streamType, uint32_t sampleRate = 0, int format = 0, - int channelCount = 0, + int channels = 0, int frameCount = 0, uint32_t flags = 0, callback_t cbf = 0, @@ -152,7 +152,7 @@ public: AudioTrack( int streamType, uint32_t sampleRate = 0, int format = 0, - int channelCount = 0, + int channels = 0, const sp<IMemory>& sharedBuffer = 0, uint32_t flags = 0, callback_t cbf = 0, @@ -169,13 +169,13 @@ public: * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful intialization * - INVALID_OPERATION: AudioTrack is already intitialized - * - BAD_VALUE: invalid parameter (channelCount, format, sampleRate...) + * - BAD_VALUE: invalid parameter (channels, format, sampleRate...) * - NO_INIT: audio server or audio hardware not initialized * */ status_t set(int streamType =-1, uint32_t sampleRate = 0, int format = 0, - int channelCount = 0, + int channels = 0, int frameCount = 0, uint32_t flags = 0, callback_t cbf = 0, @@ -330,6 +330,16 @@ public: */ status_t reload(); + /* returns a handle on the audio output used by this AudioTrack. + * + * Parameters: + * none. + * + * Returned value: + * handle on audio hardware output + */ + audio_io_handle_t getOutput(); + /* obtains a buffer of "frameCount" frames. The buffer must be * filled entirely. If the track is stopped, obtainBuffer() returns * STOPPED instead of NO_ERROR as long as there are buffers availlable, @@ -381,13 +391,20 @@ private: }; bool processAudioBuffer(const sp<AudioTrackThread>& thread); + status_t createTrack(int streamType, + uint32_t sampleRate, + int format, + int channelCount, + int frameCount, + uint32_t flags, + const sp<IMemory>& sharedBuffer, + audio_io_handle_t output); sp<IAudioTrack> mAudioTrack; sp<IMemory> mCblkMemory; sp<AudioTrackThread> mAudioTrackThread; float mVolume[2]; - uint32_t mSampleRate; uint32_t mFrameCount; audio_track_cblk_t* mCblk; @@ -395,6 +412,7 @@ private: uint8_t mFormat; uint8_t mChannelCount; uint8_t mMuted; + uint32_t mChannels; status_t mStatus; uint32_t mLatency; @@ -410,6 +428,7 @@ private: bool mMarkerReached; uint32_t mNewPosition; uint32_t mUpdatePeriod; + uint32_t mFlags; }; diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index 3e59d85..a46c727 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -23,11 +23,11 @@ #include <utils/RefBase.h> #include <utils/Errors.h> -#include <utils/IInterface.h> +#include <binder/IInterface.h> #include <media/IAudioTrack.h> #include <media/IAudioRecord.h> #include <media/IAudioFlingerClient.h> - +#include <utils/String8.h> namespace android { @@ -50,11 +50,12 @@ public: int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, + int output, status_t *status) = 0; virtual sp<IAudioRecord> openRecord( pid_t pid, - int inputSource, + int input, uint32_t sampleRate, int format, int channelCount, @@ -83,19 +84,14 @@ public: /* set/get stream type state. This will probably be used by * the preference panel, mostly. */ - virtual status_t setStreamVolume(int stream, float value) = 0; + virtual status_t setStreamVolume(int stream, float value, int output) = 0; virtual status_t setStreamMute(int stream, bool muted) = 0; - virtual float streamVolume(int stream) const = 0; + virtual float streamVolume(int stream, int output) const = 0; virtual bool streamMute(int stream) const = 0; - // set/get audio routing - virtual status_t setRouting(int mode, uint32_t routes, uint32_t mask) = 0; - virtual uint32_t getRouting(int mode) const = 0; - - // set/get audio mode + // set audio mode virtual status_t setMode(int mode) = 0; - virtual int getMode() const = 0; // mic mute/state virtual status_t setMicMute(bool state) = 0; @@ -104,22 +100,36 @@ public: // is a music stream active? virtual bool isMusicActive() const = 0; - // pass a generic configuration parameter to libaudio - // Temporary interface, do not use - // TODO: Replace with a more generic key:value get/set mechanism - virtual status_t setParameter(const char* key, const char* value) = 0; - + virtual status_t setParameters(int ioHandle, const String8& keyValuePairs) = 0; + virtual String8 getParameters(int ioHandle, const String8& keys) = 0; + // register a current process for audio output change notifications virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0; - + // retrieve the audio recording buffer size virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount) = 0; - - // force AudioFlinger thread out of standby - virtual void wakeUp() = 0; - // is A2DP output enabled - virtual bool isA2dpEnabled() const = 0; + virtual int openOutput(uint32_t *pDevices, + uint32_t *pSamplingRate, + uint32_t *pFormat, + uint32_t *pChannels, + uint32_t *pLatencyMs, + uint32_t flags) = 0; + virtual int openDuplicateOutput(int output1, int output2) = 0; + virtual status_t closeOutput(int output) = 0; + virtual status_t suspendOutput(int output) = 0; + virtual status_t restoreOutput(int output) = 0; + + virtual int openInput(uint32_t *pDevices, + uint32_t *pSamplingRate, + uint32_t *pFormat, + uint32_t *pChannels, + uint32_t acoustics) = 0; + virtual status_t closeInput(int input) = 0; + + virtual status_t setStreamOutput(uint32_t stream, int output) = 0; + + virtual status_t setVoiceVolume(float volume) = 0; }; diff --git a/include/media/IAudioFlingerClient.h b/include/media/IAudioFlingerClient.h index c3deb0b..aa0cdcf 100644 --- a/include/media/IAudioFlingerClient.h +++ b/include/media/IAudioFlingerClient.h @@ -19,8 +19,8 @@ #include <utils/RefBase.h> -#include <utils/IInterface.h> - +#include <binder/IInterface.h> +#include <utils/KeyedVector.h> namespace android { @@ -31,8 +31,8 @@ class IAudioFlingerClient : public IInterface public: DECLARE_META_INTERFACE(AudioFlingerClient); - // Notifies a change of audio output from/to hardware to/from A2DP. - virtual void a2dpEnabledChanged(bool enabled) = 0; + // Notifies a change of audio input/output configuration. + virtual void ioConfigChanged(int event, int ioHandle, void *param2) = 0; }; diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h new file mode 100644 index 0000000..4804bbd --- /dev/null +++ b/include/media/IAudioPolicyService.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IAUDIOPOLICYSERVICE_H +#define ANDROID_IAUDIOPOLICYSERVICE_H + +#include <stdint.h> +#include <sys/types.h> +#include <unistd.h> + +#include <utils/RefBase.h> +#include <utils/Errors.h> +#include <binder/IInterface.h> +#include <media/AudioSystem.h> + + +namespace android { + +// ---------------------------------------------------------------------------- + +class IAudioPolicyService : public IInterface +{ +public: + DECLARE_META_INTERFACE(AudioPolicyService); + + // + // IAudioPolicyService interface (see AudioPolicyInterface for method descriptions) + // + virtual status_t setDeviceConnectionState(AudioSystem::audio_devices device, + AudioSystem::device_connection_state state, + const char *device_address) = 0; + virtual AudioSystem::device_connection_state getDeviceConnectionState(AudioSystem::audio_devices device, + const char *device_address) = 0; + virtual status_t setPhoneState(int state) = 0; + virtual status_t setRingerMode(uint32_t mode, uint32_t mask) = 0; + virtual status_t setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) = 0; + virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage) = 0; + virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream, + uint32_t samplingRate = 0, + uint32_t format = AudioSystem::FORMAT_DEFAULT, + uint32_t channels = 0, + AudioSystem::output_flags flags = AudioSystem::OUTPUT_FLAG_INDIRECT) = 0; + virtual status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream) = 0; + virtual status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream) = 0; + virtual void releaseOutput(audio_io_handle_t output) = 0; + virtual audio_io_handle_t getInput(int inputSource, + uint32_t samplingRate = 0, + uint32_t format = AudioSystem::FORMAT_DEFAULT, + uint32_t channels = 0, + AudioSystem::audio_in_acoustics acoustics = (AudioSystem::audio_in_acoustics)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; + virtual status_t initStreamVolume(AudioSystem::stream_type stream, + int indexMin, + int indexMax) = 0; + virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index) = 0; + virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index) = 0; +}; + + +// ---------------------------------------------------------------------------- + +class BnAudioPolicyService : public BnInterface<IAudioPolicyService> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IAUDIOPOLICYSERVICE_H diff --git a/include/media/IAudioRecord.h b/include/media/IAudioRecord.h index 9d45d2d..46735de 100644 --- a/include/media/IAudioRecord.h +++ b/include/media/IAudioRecord.h @@ -22,8 +22,8 @@ #include <utils/RefBase.h> #include <utils/Errors.h> -#include <utils/IInterface.h> -#include <utils/IMemory.h> +#include <binder/IInterface.h> +#include <binder/IMemory.h> namespace android { diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h index 12f2111..de6426a 100644 --- a/include/media/IAudioTrack.h +++ b/include/media/IAudioTrack.h @@ -22,8 +22,8 @@ #include <utils/RefBase.h> #include <utils/Errors.h> -#include <utils/IInterface.h> -#include <utils/IMemory.h> +#include <binder/IInterface.h> +#include <binder/IMemory.h> namespace android { diff --git a/include/media/IMediaMetadataRetriever.h b/include/media/IMediaMetadataRetriever.h index c677e83..9baba8e 100644 --- a/include/media/IMediaMetadataRetriever.h +++ b/include/media/IMediaMetadataRetriever.h @@ -19,9 +19,9 @@ #define ANDROID_IMEDIAMETADATARETRIEVER_H #include <utils/RefBase.h> -#include <utils/IInterface.h> -#include <utils/Parcel.h> -#include <utils/IMemory.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> +#include <binder/IMemory.h> namespace android { diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h index a683e74..b6f654f 100644 --- a/include/media/IMediaPlayer.h +++ b/include/media/IMediaPlayer.h @@ -18,11 +18,12 @@ #define ANDROID_IMEDIAPLAYER_H #include <utils/RefBase.h> -#include <utils/IInterface.h> -#include <utils/Parcel.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> namespace android { +class Parcel; class ISurface; class IMediaPlayer: public IInterface @@ -45,6 +46,36 @@ public: virtual status_t setAudioStreamType(int type) = 0; virtual status_t setLooping(int loop) = 0; virtual status_t setVolume(float leftVolume, float rightVolume) = 0; + + // Invoke a generic method on the player by using opaque parcels + // for the request and reply. + // @param request Parcel that must start with the media player + // interface token. + // @param[out] reply Parcel to hold the reply data. Cannot be null. + // @return OK if the invocation was made successfully. + virtual status_t invoke(const Parcel& request, Parcel *reply) = 0; + + // Set a new metadata filter. + // @param filter A set of allow and drop rules serialized in a Parcel. + // @return OK if the invocation was made successfully. + virtual status_t setMetadataFilter(const Parcel& filter) = 0; + + // Retrieve a set of metadata. + // @param update_only Include only the metadata that have changed + // since the last invocation of getMetadata. + // The set is built using the unfiltered + // notifications the native player sent to the + // MediaPlayerService during that period of + // time. If false, all the metadatas are considered. + // @param apply_filter If true, once the metadata set has been built based + // on the value update_only, the current filter is + // applied. + // @param[out] metadata On exit contains a set (possibly empty) of metadata. + // Valid only if the call returned OK. + // @return OK if the invocation was made successfully. + virtual status_t getMetadata(bool update_only, + bool apply_filter, + Parcel *metadata) = 0; }; // ---------------------------------------------------------------------------- @@ -61,4 +92,3 @@ public: }; // namespace android #endif // ANDROID_IMEDIAPLAYER_H - diff --git a/include/media/IMediaPlayerClient.h b/include/media/IMediaPlayerClient.h index 5d32811..eee6c97 100644 --- a/include/media/IMediaPlayerClient.h +++ b/include/media/IMediaPlayerClient.h @@ -18,8 +18,8 @@ #define ANDROID_IMEDIAPLAYERCLIENT_H #include <utils/RefBase.h> -#include <utils/IInterface.h> -#include <utils/Parcel.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> namespace android { diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h index d1d96b1..d5c1594 100644 --- a/include/media/IMediaPlayerService.h +++ b/include/media/IMediaPlayerService.h @@ -17,9 +17,10 @@ #ifndef ANDROID_IMEDIAPLAYERSERVICE_H #define ANDROID_IMEDIAPLAYERSERVICE_H +#include <utils/Errors.h> // for status_t #include <utils/RefBase.h> -#include <utils/IInterface.h> -#include <utils/Parcel.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> #include <media/IMediaPlayerClient.h> #include <media/IMediaPlayer.h> @@ -28,6 +29,7 @@ namespace android { class IMediaRecorder; +class IOMX; class IMediaPlayerService: public IInterface { @@ -36,11 +38,15 @@ public: virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid) = 0; virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid) = 0; - virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url) = 0; virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length) = 0; virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0; virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0; + virtual sp<IOMX> getOMX() = 0; + + // Take a peek at currently playing audio, for visualization purposes. + // This returns a buffer of 16 bit mono PCM data, or NULL if no visualization buffer is currently available. + virtual sp<IMemory> snoop() = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h index 64d3a40..24ac82b 100644 --- a/include/media/IMediaRecorder.h +++ b/include/media/IMediaRecorder.h @@ -18,7 +18,7 @@ #ifndef ANDROID_IMEDIARECORDER_H #define ANDROID_IMEDIARECORDER_H -#include <utils/IInterface.h> +#include <binder/IInterface.h> namespace android { diff --git a/include/media/IOMX.h b/include/media/IOMX.h new file mode 100644 index 0000000..6f3ba1c --- /dev/null +++ b/include/media/IOMX.h @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IOMX_H_ + +#define ANDROID_IOMX_H_ + +#include <binder/IInterface.h> +#include <utils/List.h> +#include <utils/String8.h> + +#include <OMX_Core.h> +#include <OMX_Video.h> + +#include "jni.h" + +namespace android { + +class IMemory; +class IOMXObserver; +class IOMXRenderer; +class ISurface; +class Surface; + +class IOMX : public IInterface { +public: + DECLARE_META_INTERFACE(OMX); + + typedef void *buffer_id; + typedef void *node_id; + + virtual status_t listNodes(List<String8> *list) = 0; + + virtual status_t allocateNode( + const char *name, const sp<IOMXObserver> &observer, + node_id *node) = 0; + + virtual status_t freeNode(node_id node) = 0; + + virtual status_t sendCommand( + node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) = 0; + + virtual status_t getParameter( + node_id node, OMX_INDEXTYPE index, + void *params, size_t size) = 0; + + virtual status_t setParameter( + node_id node, OMX_INDEXTYPE index, + const void *params, size_t size) = 0; + + virtual status_t getConfig( + node_id node, OMX_INDEXTYPE index, + void *params, size_t size) = 0; + + virtual status_t setConfig( + node_id node, OMX_INDEXTYPE index, + const void *params, size_t size) = 0; + + virtual status_t useBuffer( + node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, + buffer_id *buffer) = 0; + + virtual status_t allocateBuffer( + node_id node, OMX_U32 port_index, size_t size, + buffer_id *buffer) = 0; + + virtual status_t allocateBufferWithBackup( + node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, + buffer_id *buffer) = 0; + + virtual status_t freeBuffer( + node_id node, OMX_U32 port_index, buffer_id buffer) = 0; + + virtual status_t fillBuffer(node_id node, buffer_id buffer) = 0; + + virtual status_t emptyBuffer( + node_id node, + buffer_id buffer, + OMX_U32 range_offset, OMX_U32 range_length, + OMX_U32 flags, OMX_TICKS timestamp) = 0; + + virtual status_t getExtensionIndex( + node_id node, + const char *parameter_name, + OMX_INDEXTYPE *index) = 0; + + virtual sp<IOMXRenderer> createRenderer( + const sp<ISurface> &surface, + const char *componentName, + OMX_COLOR_FORMATTYPE colorFormat, + size_t encodedWidth, size_t encodedHeight, + size_t displayWidth, size_t displayHeight) = 0; + + // Note: These methods are _not_ virtual, it exists as a wrapper around + // the virtual "createRenderer" method above facilitating extraction + // of the ISurface from a regular Surface or a java Surface object. + sp<IOMXRenderer> createRenderer( + const sp<Surface> &surface, + const char *componentName, + OMX_COLOR_FORMATTYPE colorFormat, + size_t encodedWidth, size_t encodedHeight, + size_t displayWidth, size_t displayHeight); + + sp<IOMXRenderer> createRendererFromJavaSurface( + JNIEnv *env, jobject javaSurface, + const char *componentName, + OMX_COLOR_FORMATTYPE colorFormat, + size_t encodedWidth, size_t encodedHeight, + size_t displayWidth, size_t displayHeight); +}; + +struct omx_message { + enum { + EVENT, + EMPTY_BUFFER_DONE, + FILL_BUFFER_DONE, + + } type; + + IOMX::node_id node; + + union { + // if type == EVENT + struct { + OMX_EVENTTYPE event; + OMX_U32 data1; + OMX_U32 data2; + } event_data; + + // if type == EMPTY_BUFFER_DONE + struct { + IOMX::buffer_id buffer; + } buffer_data; + + // if type == FILL_BUFFER_DONE + struct { + IOMX::buffer_id buffer; + OMX_U32 range_offset; + OMX_U32 range_length; + OMX_U32 flags; + OMX_TICKS timestamp; + OMX_PTR platform_private; + } extended_buffer_data; + + } u; +}; + +class IOMXObserver : public IInterface { +public: + DECLARE_META_INTERFACE(OMXObserver); + + virtual void onMessage(const omx_message &msg) = 0; +}; + +class IOMXRenderer : public IInterface { +public: + DECLARE_META_INTERFACE(OMXRenderer); + + virtual void render(IOMX::buffer_id buffer) = 0; +}; + +//////////////////////////////////////////////////////////////////////////////// + +class BnOMX : public BnInterface<IOMX> { +public: + virtual status_t onTransact( + uint32_t code, const Parcel &data, Parcel *reply, + uint32_t flags = 0); +}; + +class BnOMXObserver : public BnInterface<IOMXObserver> { +public: + virtual status_t onTransact( + uint32_t code, const Parcel &data, Parcel *reply, + uint32_t flags = 0); +}; + +class BnOMXRenderer : public BnInterface<IOMXRenderer> { +public: + virtual status_t onTransact( + uint32_t code, const Parcel &data, Parcel *reply, + uint32_t flags = 0); +}; + +} // namespace android + +#endif // ANDROID_IOMX_H_ diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h index b178836..e228357 100644 --- a/include/media/MediaMetadataRetrieverInterface.h +++ b/include/media/MediaMetadataRetrieverInterface.h @@ -44,6 +44,28 @@ class MediaMetadataRetrieverInterface : public MediaMetadataRetrieverBase { public: virtual ~MediaMetadataRetrieverInterface() {} + + // @param mode The intended mode of operations: + // can be any of the following: + // METADATA_MODE_NOOP: Experimental - just add and remove data source. + // METADATA_MODE_FRAME_CAPTURE_ONLY: For capture frame/thumbnail only. + // METADATA_MODE_METADATA_RETRIEVAL_ONLY: For meta data retrieval only. + // METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL: For both frame + // capture and meta data retrieval. + virtual status_t setMode(int mode) { + if (mode < METADATA_MODE_NOOP || + mode > METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL) { + return BAD_VALUE; + } + return NO_ERROR; + } + + virtual status_t getMode(int* mode) const { *mode = mMode; return NO_ERROR; } + virtual VideoFrame* captureFrame() { return NULL; } + virtual MediaAlbumArt* extractAlbumArt() { return NULL; } + virtual const char* extractMetadata(int keyCode) { return NULL; } + + uint32_t mMode; }; }; // namespace android diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index 7bf555a..f723cfd 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -19,20 +19,32 @@ #ifdef __cplusplus +#include <sys/types.h> #include <ui/ISurface.h> #include <utils/RefBase.h> +#include <utils/Errors.h> #include <media/mediaplayer.h> #include <media/AudioSystem.h> +#include <media/Metadata.h> namespace android { +class Parcel; +template<typename T> class SortedVector; + enum player_type { PV_PLAYER = 1, SONIVOX_PLAYER = 2, - VORBIS_PLAYER = 3 + VORBIS_PLAYER = 3, + STAGEFRIGHT_PLAYER = 4, + // Test players are available only in the 'test' and 'eng' builds. + // The shared library with the test player is passed passed as an + // argument to the 'test:' url in the setDataSource call. + TEST_PLAYER = 5, }; + #define DEFAULT_AUDIOSINK_BUFFERCOUNT 4 #define DEFAULT_AUDIOSINK_BUFFERSIZE 1200 #define DEFAULT_AUDIOSINK_SAMPLERATE 44100 @@ -45,10 +57,12 @@ typedef void (*notify_callback_f)(void* cookie, int msg, int ext1, int ext2); class MediaPlayerBase : public RefBase { public: - // AudioSink: abstraction layer for audio output class AudioSink : public RefBase { public: + typedef void (*AudioCallback)( + AudioSink *audioSink, void *buffer, size_t size, void *cookie); + virtual ~AudioSink() {} virtual bool ready() const = 0; // audio output is open and ready virtual bool realtime() const = 0; // audio output is real-time output @@ -58,7 +72,17 @@ public: virtual ssize_t frameSize() const = 0; virtual uint32_t latency() const = 0; virtual float msecsPerFrame() const = 0; - virtual status_t open(uint32_t sampleRate, int channelCount, int format=AudioSystem::PCM_16_BIT, int bufferCount=DEFAULT_AUDIOSINK_BUFFERCOUNT) = 0; + + // If no callback is specified, use the "write" API below to submit + // audio data. Otherwise return a full buffer of audio data on each + // callback. + virtual status_t open( + uint32_t sampleRate, int channelCount, + int format=AudioSystem::PCM_16_BIT, + int bufferCount=DEFAULT_AUDIOSINK_BUFFERCOUNT, + AudioCallback cb = NULL, + void *cookie = NULL) = 0; + virtual void start() = 0; virtual ssize_t write(const void* buffer, size_t size) = 0; virtual void stop() = 0; @@ -88,6 +112,26 @@ public: virtual player_type playerType() = 0; virtual void setNotifyCallback(void* cookie, notify_callback_f notifyFunc) { mCookie = cookie; mNotify = notifyFunc; } + // Invoke a generic method on the player by using opaque parcels + // for the request and reply. + // + // @param request Parcel that is positioned at the start of the + // data sent by the java layer. + // @param[out] reply Parcel to hold the reply data. Cannot be null. + // @return OK if the call was successful. + virtual status_t invoke(const Parcel& request, Parcel *reply) = 0; + + // The Client in the MetadataPlayerService calls this method on + // the native player to retrieve all or a subset of metadata. + // + // @param ids SortedList of metadata ID to be fetch. If empty, all + // the known metadata should be returned. + // @param[inout] records Parcel where the player appends its metadata. + // @return OK if the call was successful. + virtual status_t getMetadata(const media::Metadata::Filter& ids, + Parcel *records) { + return INVALID_OPERATION; + }; protected: virtual void sendEvent(int msg, int ext1=0, int ext2=0) { if (mNotify) mNotify(mCookie, msg, ext1, ext2); } diff --git a/include/media/Metadata.h b/include/media/Metadata.h new file mode 100644 index 0000000..241868a --- /dev/null +++ b/include/media/Metadata.h @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_MEDIA_METADATA_H__ +#define ANDROID_MEDIA_METADATA_H__ + +#include <sys/types.h> +#include <utils/Errors.h> +#include <utils/RefBase.h> +#include <utils/SortedVector.h> + +namespace android { +class Parcel; + +namespace media { + +// Metadata is a class to build/serialize a set of metadata in a Parcel. +// +// This class should be kept in sync with android/media/Metadata.java. +// It provides all the metadata ids available and methods to build the +// header, add records and adjust the set size header field. +// +// Typical Usage: +// ============== +// Parcel p; +// media::Metadata data(&p); +// +// data.appendHeader(); +// data.appendBool(Metadata::kPauseAvailable, true); +// ... more append ... +// data.updateLength(); +// + +class Metadata { + public: + typedef int32_t Type; + typedef SortedVector<Type> Filter; + + static const Type kAny = 0; + + // Keep in sync with android/media/Metadata.java + static const Type kTitle = 1; // String + static const Type kComment = 2; // String + static const Type kCopyright = 3; // String + static const Type kAlbum = 4; // String + static const Type kArtist = 5; // String + static const Type kAuthor = 6; // String + static const Type kComposer = 7; // String + static const Type kGenre = 8; // String + static const Type kDate = 9; // Date + static const Type kDuration = 10; // Integer(millisec) + static const Type kCdTrackNum = 11; // Integer 1-based + static const Type kCdTrackMax = 12; // Integer + static const Type kRating = 13; // String + static const Type kAlbumArt = 14; // byte[] + static const Type kVideoFrame = 15; // Bitmap + static const Type kCaption = 16; // TimedText + + static const Type kBitRate = 17; // Integer, Aggregate rate of + // all the streams in bps. + + static const Type kAudioBitRate = 18; // Integer, bps + static const Type kVideoBitRate = 19; // Integer, bps + static const Type kAudioSampleRate = 20; // Integer, Hz + static const Type kVideoframeRate = 21; // Integer, Hz + + // See RFC2046 and RFC4281. + static const Type kMimeType = 22; // String + static const Type kAudioCodec = 23; // String + static const Type kVideoCodec = 24; // String + + static const Type kVideoHeight = 25; // Integer + static const Type kVideoWidth = 26; // Integer + static const Type kNumTracks = 27; // Integer + static const Type kDrmCrippled = 28; // Boolean + + // Playback capabilities. + static const Type kPauseAvailable = 29; // Boolean + static const Type kSeekBackwardAvailable = 30; // Boolean + static const Type kSeekForwardAvailable = 31; // Boolean + + // @param p[inout] The parcel to append the metadata records + // to. The global metadata header should have been set already. + explicit Metadata(Parcel *p); + ~Metadata(); + + // Rewind the underlying parcel, undoing all the changes. + void resetParcel(); + + // Append the size and 'META' marker. + bool appendHeader(); + + // Once all the records have been added, call this to update the + // lenght field in the header. + void updateLength(); + + // append* are methods to append metadata. + // @param key Is the metadata Id. + // @param val Is the value of the metadata. + // @return true if successful, false otherwise. + // TODO: add more as needed to handle other types. + bool appendBool(Type key, bool val); + bool appendInt32(Type key, int32_t val); + + private: + Metadata(const Metadata&); + Metadata& operator=(const Metadata&); + + + // Checks the key is valid and not already present. + bool checkKey(Type key); + + Parcel *mData; + size_t mBegin; +}; + +} // namespace android::media +} // namespace android + +#endif // ANDROID_MEDIA_METADATA_H__ diff --git a/include/media/PVPlayer.h b/include/media/PVPlayer.h index 8122df6..8a66152 100644 --- a/include/media/PVPlayer.h +++ b/include/media/PVPlayer.h @@ -19,6 +19,7 @@ #include <utils/Errors.h> #include <media/MediaPlayerInterface.h> +#include <media/Metadata.h> #define MAX_OPENCORE_INSTANCES 25 @@ -52,6 +53,10 @@ public: virtual status_t reset(); virtual status_t setLooping(int loop); virtual player_type playerType() { return PV_PLAYER; } + virtual status_t invoke(const Parcel& request, Parcel *reply); + virtual status_t getMetadata( + const SortedVector<media::Metadata::Type>& ids, + Parcel *records); // make available to PlayerDriver void sendEvent(int msg, int ext1=0, int ext2=0) { MediaPlayerBase::sendEvent(msg, ext1, ext2); } @@ -62,6 +67,7 @@ private: static void run_set_video_surface(status_t s, void *cookie, bool cancelled); static void run_set_audio_output(status_t s, void *cookie, bool cancelled); static void run_prepare(status_t s, void *cookie, bool cancelled); + static void check_for_live_streaming(status_t s, void *cookie, bool cancelled); PlayerDriver* mPlayerDriver; char * mDataSourcePath; diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h index eafa661..1ad1f26 100644 --- a/include/media/ToneGenerator.h +++ b/include/media/ToneGenerator.h @@ -151,10 +151,10 @@ public: NUM_SUP_TONES = LAST_SUP_TONE-FIRST_SUP_TONE+1 }; - ToneGenerator(int streamType, float volume); + ToneGenerator(int streamType, float volume, bool threadCanCallJava = false); ~ToneGenerator(); - bool startTone(int toneType); + bool startTone(int toneType, int durationMs = -1); void stopTone(); bool isInited() { return (mState == TONE_IDLE)?false:true;} @@ -167,7 +167,8 @@ private: TONE_STARTING, // ToneGenerator is starting playing TONE_PLAYING, // ToneGenerator is playing TONE_STOPPING, // ToneGenerator is stoping - TONE_RESTARTING // + TONE_STOPPED, // ToneGenerator is stopped: the AudioTrack will be stopped + TONE_RESTARTING // A start request was received in active state (playing or stopping) }; @@ -241,11 +242,14 @@ private: static const ToneDescriptor sToneDescriptors[]; + bool mThreadCanCallJava; unsigned int mTotalSmp; // Total number of audio samples played (gives current time) unsigned int mNextSegSmp; // Position of next segment transition expressed in samples // NOTE: because mTotalSmp, mNextSegSmp are stored on 32 bit, current design will operate properly // only if tone duration is less than about 27 Hours(@44100Hz sampling rate). If this time is exceeded, // no crash will occur but tone sequence will show a glitch. + unsigned int mMaxSmp; // Maximum number of audio samples played (maximun tone duration) + int mDurationMs; // Maximum tone duration in ms unsigned short mCurSegment; // Current segment index in ToneDescriptor segments[] unsigned short mCurCount; // Current sequence repeat count diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h index f2719d3..cfc205c 100644 --- a/include/media/mediametadataretriever.h +++ b/include/media/mediametadataretriever.h @@ -20,7 +20,7 @@ #include <utils/Errors.h> // for status_t #include <utils/threads.h> -#include <utils/IMemory.h> +#include <binder/IMemory.h> #include <media/IMediaMetadataRetriever.h> namespace android { @@ -52,9 +52,22 @@ enum { METADATA_KEY_VIDEO_FORMAT = 18, METADATA_KEY_VIDEO_HEIGHT = 19, METADATA_KEY_VIDEO_WIDTH = 20, + METADATA_KEY_WRITER = 21, // Add more here... }; +// The intended mode of operations:$ +// METADATA_MODE_NOOP: Experimental - just add and remove data source.$ +// METADATA_MODE_FRAME_CAPTURE_ONLY: For capture frame/thumbnail only.$ +// METADATA_MODE_METADATA_RETRIEVAL_ONLY: For meta data retrieval only.$ +// METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL: For both frame capture +// and meta data retrieval.$ +enum { + METADATA_MODE_NOOP = 0x00, + METADATA_MODE_FRAME_CAPTURE_ONLY = 0x01, + METADATA_MODE_METADATA_RETRIEVAL_ONLY = 0x02, + METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL = 0x03 +}; class MediaMetadataRetriever: public RefBase { diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h index 513ffe1..b91b47e 100644 --- a/include/media/mediaplayer.h +++ b/include/media/mediaplayer.h @@ -17,7 +17,7 @@ #ifndef ANDROID_MEDIAPLAYER_H #define ANDROID_MEDIAPLAYER_H -#include <utils/IMemory.h> +#include <binder/IMemory.h> #include <ui/Surface.h> #include <media/IMediaPlayerClient.h> #include <media/IMediaPlayer.h> @@ -97,6 +97,8 @@ enum media_info_type { MEDIA_INFO_BAD_INTERLEAVING = 800, // The media is not seekable (e.g live stream). MEDIA_INFO_NOT_SEEKABLE = 801, + // New media metadata is available. + MEDIA_INFO_METADATA_UPDATE = 802, }; @@ -151,7 +153,10 @@ public: void notify(int msg, int ext1, int ext2); static sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat); static sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat); - + static int snoop(short *data, int len, int kind); + status_t invoke(const Parcel& request, Parcel *reply); + status_t setMetadataFilter(const Parcel& filter); + status_t getMetadata(bool update_only, bool apply_filter, Parcel *metadata); private: void clear_l(); status_t seekTo_l(int msec); diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h index 9b54ca9..8c7392b 100644 --- a/include/media/mediarecorder.h +++ b/include/media/mediarecorder.h @@ -18,7 +18,10 @@ #ifndef ANDROID_MEDIARECORDER_H #define ANDROID_MEDIARECORDER_H -#include <utils.h> +#include <utils/Log.h> +#include <utils/threads.h> +#include <utils/List.h> +#include <utils/Errors.h> #include <media/IMediaPlayerClient.h> namespace android { @@ -38,7 +41,9 @@ enum audio_source { AUDIO_SOURCE_VOICE_UPLINK = 2, AUDIO_SOURCE_VOICE_DOWNLINK = 3, AUDIO_SOURCE_VOICE_CALL = 4, - AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_CALL, + AUDIO_SOURCE_CAMCORDER = 5, + AUDIO_SOURCE_VOICE_RECOGNITION = 6, + AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_RECOGNITION, AUDIO_SOURCE_LIST_END // must be last - used to validate audio source type }; @@ -90,10 +95,6 @@ enum video_encoder { VIDEO_ENCODER_LIST_END // must be the last - used to validate the video encoder type }; - -// Maximum frames per second is 24 -#define MEDIA_RECORDER_MAX_FRAME_RATE 24 - /* * The state machine of the media_recorder uses a set of different state names. * The mapping between the media_recorder and the pvauthorengine is shown below: diff --git a/include/media/mediascanner.h b/include/media/mediascanner.h index fbef1db..cd0b86e 100644 --- a/include/media/mediascanner.h +++ b/include/media/mediascanner.h @@ -17,7 +17,10 @@ #ifndef MEDIASCANNER_H #define MEDIASCANNER_H -#include <utils.h> +#include <utils/Log.h> +#include <utils/threads.h> +#include <utils/List.h> +#include <utils/Errors.h> #include <pthread.h> namespace android { @@ -56,16 +59,17 @@ private: class MediaScannerClient { public: - MediaScannerClient(); - virtual ~MediaScannerClient(); - void setLocale(const char* locale); - void beginFile(); - bool addStringTag(const char* name, const char* value); - void endFile(); - - virtual bool scanFile(const char* path, long long lastModified, long long fileSize) = 0; - virtual bool handleStringTag(const char* name, const char* value) = 0; - virtual bool setMimeType(const char* mimeType) = 0; + MediaScannerClient(); + virtual ~MediaScannerClient(); + void setLocale(const char* locale); + void beginFile(); + bool addStringTag(const char* name, const char* value); + void endFile(); + + virtual bool scanFile(const char* path, long long lastModified, long long fileSize) = 0; + virtual bool handleStringTag(const char* name, const char* value) = 0; + virtual bool setMimeType(const char* mimeType) = 0; + virtual bool addNoMediaFolder(const char* path) = 0; protected: void convertValues(uint32_t encoding); diff --git a/include/media/stagefright/AMRExtractor.h b/include/media/stagefright/AMRExtractor.h new file mode 100644 index 0000000..c8710d3 --- /dev/null +++ b/include/media/stagefright/AMRExtractor.h @@ -0,0 +1,54 @@ +/* + * 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 AMR_EXTRACTOR_H_ + +#define AMR_EXTRACTOR_H_ + +#include <media/stagefright/MediaExtractor.h> + +namespace android { + +class String8; + +class AMRExtractor : public MediaExtractor { +public: + AMRExtractor(const sp<DataSource> &source); + + virtual size_t countTracks(); + virtual sp<MediaSource> getTrack(size_t index); + virtual sp<MetaData> getTrackMetaData(size_t index); + + static sp<MetaData> makeAMRFormat(bool isWide); + +protected: + virtual ~AMRExtractor(); + +private: + sp<DataSource> mDataSource; + status_t mInitCheck; + bool mIsWide; + + AMRExtractor(const AMRExtractor &); + AMRExtractor &operator=(const AMRExtractor &); +}; + +bool SniffAMR( + const sp<DataSource> &source, String8 *mimeType, float *confidence); + +} // namespace android + +#endif // AMR_EXTRACTOR_H_ diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h new file mode 100644 index 0000000..960eda3 --- /dev/null +++ b/include/media/stagefright/AudioPlayer.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUDIO_PLAYER_H_ + +#define AUDIO_PLAYER_H_ + +#include <media/MediaPlayerInterface.h> +#include <media/stagefright/MediaBuffer.h> +#include <media/stagefright/TimeSource.h> +#include <utils/threads.h> + +namespace android { + +class MediaSource; +class AudioTrack; + +class AudioPlayer : public TimeSource { +public: + AudioPlayer(const sp<MediaPlayerBase::AudioSink> &audioSink); + virtual ~AudioPlayer(); + + // Caller retains ownership of "source". + void setSource(const sp<MediaSource> &source); + + // Return time in us. + virtual int64_t getRealTimeUs(); + + void start(); + + void pause(); + void resume(); + + void stop(); + + // Returns the timestamp of the last buffer played (in us). + int64_t getMediaTimeUs(); + + // Returns true iff a mapping is established, i.e. the AudioPlayer + // has played at least one frame of audio. + bool getMediaTimeMapping(int64_t *realtime_us, int64_t *mediatime_us); + + status_t seekTo(int64_t time_us); + +private: + sp<MediaSource> mSource; + AudioTrack *mAudioTrack; + + MediaBuffer *mInputBuffer; + + int mSampleRate; + int64_t mLatencyUs; + size_t mFrameSize; + + Mutex mLock; + int64_t mNumFramesPlayed; + + int64_t mPositionTimeMediaUs; + int64_t mPositionTimeRealUs; + + bool mSeeking; + int64_t mSeekTimeUs; + + bool mStarted; + + sp<MediaPlayerBase::AudioSink> mAudioSink; + + static void AudioCallback(int event, void *user, void *info); + void AudioCallback(int event, void *info); + + static void AudioSinkCallback( + MediaPlayerBase::AudioSink *audioSink, + void *data, size_t size, void *me); + + void fillBuffer(void *data, size_t size); + + int64_t getRealTimeUsLocked() const; + + AudioPlayer(const AudioPlayer &); + AudioPlayer &operator=(const AudioPlayer &); +}; + +} // namespace android + +#endif // AUDIO_PLAYER_H_ diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h new file mode 100644 index 0000000..e129958 --- /dev/null +++ b/include/media/stagefright/AudioSource.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUDIO_SOURCE_H_ + +#define AUDIO_SOURCE_H_ + +#include <media/stagefright/MediaSource.h> + +namespace android { + +class AudioRecord; + +class AudioSource { +public: + AudioSource(int inputSource); + virtual ~AudioSource(); + + status_t initCheck() const; + + virtual status_t start(MetaData *params = NULL); + virtual status_t stop(); + virtual sp<MetaData> getFormat(); + + virtual status_t read( + MediaBuffer **buffer, const ReadOptions *options = NULL); + +private: + AudioRecord *mRecord; + status_t mInitCheck; + + AudioSource(const AudioSource &); + AudioSource &operator=(const AudioSource &); +}; + +} // namespace android + +#endif // AUDIO_SOURCE_H_ diff --git a/include/media/stagefright/CachingDataSource.h b/include/media/stagefright/CachingDataSource.h new file mode 100644 index 0000000..e35e19e --- /dev/null +++ b/include/media/stagefright/CachingDataSource.h @@ -0,0 +1,62 @@ +/* + * 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 CACHING_DATASOURCE_H_ + +#define CACHING_DATASOURCE_H_ + +#include <media/stagefright/DataSource.h> +#include <media/stagefright/MediaErrors.h> +#include <utils/threads.h> + +namespace android { + +class CachingDataSource : public DataSource { +public: + CachingDataSource( + const sp<DataSource> &source, size_t pageSize, int numPages); + + status_t InitCheck() const; + + virtual ssize_t read_at(off_t offset, void *data, size_t size); + +protected: + virtual ~CachingDataSource(); + +private: + struct Page { + Page *mPrev, *mNext; + off_t mOffset; + size_t mLength; + void *mData; + }; + + sp<DataSource> mSource; + void *mData; + size_t mPageSize; + Page *mFirst, *mLast; + + Page *allocate_page(); + + Mutex mLock; + + CachingDataSource(const CachingDataSource &); + CachingDataSource &operator=(const CachingDataSource &); +}; + +} // namespace android + +#endif // CACHING_DATASOURCE_H_ diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h new file mode 100644 index 0000000..7042e1a --- /dev/null +++ b/include/media/stagefright/CameraSource.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CAMERA_SOURCE_H_ + +#define CAMERA_SOURCE_H_ + +#include <media/stagefright/MediaBuffer.h> +#include <media/stagefright/MediaSource.h> +#include <utils/List.h> +#include <utils/RefBase.h> +#include <utils/threads.h> + +namespace android { + +class ICamera; +class ICameraClient; +class IMemory; + +class CameraSource : public MediaSource, + public MediaBufferObserver { +public: + static CameraSource *Create(); + + virtual ~CameraSource(); + + virtual status_t start(MetaData *params = NULL); + virtual status_t stop(); + + virtual sp<MetaData> getFormat(); + + virtual status_t read( + MediaBuffer **buffer, const ReadOptions *options = NULL); + + virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2); + virtual void dataCallback(int32_t msgType, const sp<IMemory>& data); + + virtual void signalBufferReturned(MediaBuffer *buffer); + +private: + CameraSource(const sp<ICamera> &camera, const sp<ICameraClient> &client); + + sp<ICamera> mCamera; + sp<ICameraClient> mCameraClient; + + Mutex mLock; + Condition mFrameAvailableCondition; + List<sp<IMemory> > mFrames; + + int mNumFrames; + bool mStarted; + + CameraSource(const CameraSource &); + CameraSource &operator=(const CameraSource &); +}; + +} // namespace android + +#endif // CAMERA_SOURCE_H_ diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h new file mode 100644 index 0000000..f46f0af --- /dev/null +++ b/include/media/stagefright/DataSource.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATA_SOURCE_H_ + +#define DATA_SOURCE_H_ + +#include <sys/types.h> + +#include <utils/Errors.h> +#include <utils/List.h> +#include <utils/RefBase.h> +#include <utils/threads.h> + +namespace android { + +class String8; + +class DataSource : public RefBase { +public: + DataSource() {} + + virtual ssize_t read_at(off_t offset, void *data, size_t size) = 0; + + // Convenience methods: + bool getUInt16(off_t offset, uint16_t *x); + + // May return ERROR_UNSUPPORTED. + virtual status_t getSize(off_t *size); + + //////////////////////////////////////////////////////////////////////////// + + bool sniff(String8 *mimeType, float *confidence); + + typedef bool (*SnifferFunc)( + const sp<DataSource> &source, String8 *mimeType, float *confidence); + + static void RegisterSniffer(SnifferFunc func); + static void RegisterDefaultSniffers(); + +protected: + virtual ~DataSource() {} + +private: + static Mutex gSnifferMutex; + static List<SnifferFunc> gSniffers; + + DataSource(const DataSource &); + DataSource &operator=(const DataSource &); +}; + +} // namespace android + +#endif // DATA_SOURCE_H_ diff --git a/include/media/stagefright/ESDS.h b/include/media/stagefright/ESDS.h new file mode 100644 index 0000000..01bcd18 --- /dev/null +++ b/include/media/stagefright/ESDS.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ESDS_H_ + +#define ESDS_H_ + +#include <stdint.h> + +#include <media/stagefright/MediaErrors.h> + +namespace android { + +class ESDS { +public: + ESDS(const void *data, size_t size); + ~ESDS(); + + status_t InitCheck() const; + + status_t getCodecSpecificInfo(const void **data, size_t *size) const; + +private: + enum { + kTag_ESDescriptor = 0x03, + kTag_DecoderConfigDescriptor = 0x04, + kTag_DecoderSpecificInfo = 0x05 + }; + + uint8_t *mData; + size_t mSize; + + status_t mInitCheck; + + size_t mDecoderSpecificOffset; + size_t mDecoderSpecificLength; + + status_t skipDescriptorHeader( + size_t offset, size_t size, + uint8_t *tag, size_t *data_offset, size_t *data_size) const; + + status_t parse(); + status_t parseESDescriptor(size_t offset, size_t size); + status_t parseDecoderConfigDescriptor(size_t offset, size_t size); + + ESDS(const ESDS &); + ESDS &operator=(const ESDS &); +}; + +} // namespace android +#endif // ESDS_H_ diff --git a/include/media/stagefright/FileSource.h b/include/media/stagefright/FileSource.h new file mode 100644 index 0000000..ccbe0ef --- /dev/null +++ b/include/media/stagefright/FileSource.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILE_SOURCE_H_ + +#define FILE_SOURCE_H_ + +#include <stdio.h> + +#include <media/stagefright/DataSource.h> +#include <media/stagefright/MediaErrors.h> +#include <utils/threads.h> + +namespace android { + +class FileSource : public DataSource { +public: + FileSource(const char *filename); + virtual ~FileSource(); + + status_t InitCheck() const; + + virtual ssize_t read_at(off_t offset, void *data, size_t size); + +private: + FILE *mFile; + Mutex mLock; + + FileSource(const FileSource &); + FileSource &operator=(const FileSource &); +}; + +} // namespace android + +#endif // FILE_SOURCE_H_ + diff --git a/include/media/stagefright/HTTPDataSource.h b/include/media/stagefright/HTTPDataSource.h new file mode 100644 index 0000000..0587c7c --- /dev/null +++ b/include/media/stagefright/HTTPDataSource.h @@ -0,0 +1,59 @@ +/* + * 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 HTTP_DATASOURCE_H_ + +#define HTTP_DATASOURCE_H_ + +#include <media/stagefright/DataSource.h> +#include <media/stagefright/HTTPStream.h> + +namespace android { + +class HTTPDataSource : public DataSource { +public: + HTTPDataSource(const char *host, int port, const char *path); + HTTPDataSource(const char *uri); + + virtual ~HTTPDataSource(); + + // XXXandih + status_t InitCheck() const { return OK; } + + virtual ssize_t read_at(off_t offset, void *data, size_t size); + +private: + enum { + kBufferSize = 64 * 1024 + }; + + HTTPStream mHttp; + char *mHost; + int mPort; + char *mPath; + + void *mBuffer; + size_t mBufferLength; + off_t mBufferOffset; + + HTTPDataSource(const HTTPDataSource &); + HTTPDataSource &operator=(const HTTPDataSource &); +}; + +} // namespace android + +#endif // HTTP_DATASOURCE_H_ + diff --git a/include/media/stagefright/HTTPStream.h b/include/media/stagefright/HTTPStream.h new file mode 100644 index 0000000..72e796c --- /dev/null +++ b/include/media/stagefright/HTTPStream.h @@ -0,0 +1,74 @@ +/* + * 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 HTTP_STREAM_H_ + +#define HTTP_STREAM_H_ + +#include <sys/types.h> + +#include <media/stagefright/MediaErrors.h> +#include <media/stagefright/stagefright_string.h> +#include <utils/KeyedVector.h> + +namespace android { + +class HTTPStream { +public: + HTTPStream(); + ~HTTPStream(); + + status_t connect(const char *server, int port = 80); + status_t disconnect(); + + status_t send(const char *data, size_t size); + + // Assumes data is a '\0' terminated string. + status_t send(const char *data); + + // Receive up to "size" bytes of data. + ssize_t receive(void *data, size_t size); + + status_t receive_header(int *http_status); + + // The header key used to retrieve the status line. + static const char *kStatusKey; + + bool find_header_value( + const string &key, string *value) const; + +private: + enum State { + READY, + CONNECTED + }; + + State mState; + int mSocket; + + KeyedVector<string, string> mHeaders; + + // Receive a line of data terminated by CRLF, line will be '\0' terminated + // _excluding_ the termianting CRLF. + status_t receive_line(char *line, size_t size); + + HTTPStream(const HTTPStream &); + HTTPStream &operator=(const HTTPStream &); +}; + +} // namespace android + +#endif // HTTP_STREAM_H_ diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h new file mode 100644 index 0000000..7e1f08d --- /dev/null +++ b/include/media/stagefright/HardwareAPI.h @@ -0,0 +1,35 @@ +/* + * 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 HARDWARE_API_H_ + +#define HARDWARE_API_H_ + +#include <media/stagefright/VideoRenderer.h> +#include <ui/ISurface.h> +#include <utils/RefBase.h> + +#include <OMX_Component.h> + +extern android::VideoRenderer *createRenderer( + const android::sp<android::ISurface> &surface, + const char *componentName, + OMX_COLOR_FORMATTYPE colorFormat, + size_t displayWidth, size_t displayHeight, + size_t decodedWidth, size_t decodedHeight); + +#endif // HARDWARE_API_H_ + diff --git a/include/media/stagefright/JPEGSource.h b/include/media/stagefright/JPEGSource.h new file mode 100644 index 0000000..9d0a700 --- /dev/null +++ b/include/media/stagefright/JPEGSource.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JPEG_SOURCE_H_ + +#define JPEG_SOURCE_H_ + +#include <media/stagefright/MediaSource.h> + +namespace android { + +class DataSource; +class MediaBufferGroup; + +struct JPEGSource : public MediaSource { + JPEGSource(const sp<DataSource> &source); + + virtual status_t start(MetaData *params = NULL); + virtual status_t stop(); + virtual sp<MetaData> getFormat(); + + virtual status_t read( + MediaBuffer **buffer, const ReadOptions *options = NULL); + +protected: + virtual ~JPEGSource(); + +private: + sp<DataSource> mSource; + MediaBufferGroup *mGroup; + bool mStarted; + off_t mSize; + int32_t mWidth, mHeight; + off_t mOffset; + + status_t parseJPEG(); + + JPEGSource(const JPEGSource &); + JPEGSource &operator=(const JPEGSource &); +}; + +} // namespace android + +#endif // JPEG_SOURCE_H_ + diff --git a/include/media/stagefright/MP3Extractor.h b/include/media/stagefright/MP3Extractor.h new file mode 100644 index 0000000..11ba01d --- /dev/null +++ b/include/media/stagefright/MP3Extractor.h @@ -0,0 +1,55 @@ +/* + * 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 MP3_EXTRACTOR_H_ + +#define MP3_EXTRACTOR_H_ + +#include <media/stagefright/MediaExtractor.h> + +namespace android { + +class DataSource; +class String8; + +class MP3Extractor : public MediaExtractor { +public: + // Extractor assumes ownership of "source". + MP3Extractor(const sp<DataSource> &source); + + virtual size_t countTracks(); + virtual sp<MediaSource> getTrack(size_t index); + virtual sp<MetaData> getTrackMetaData(size_t index); + +protected: + virtual ~MP3Extractor(); + +private: + sp<DataSource> mDataSource; + off_t mFirstFramePos; + sp<MetaData> mMeta; + uint32_t mFixedHeader; + + MP3Extractor(const MP3Extractor &); + MP3Extractor &operator=(const MP3Extractor &); +}; + +bool SniffMP3( + const sp<DataSource> &source, String8 *mimeType, float *confidence); + +} // namespace android + +#endif // MP3_EXTRACTOR_H_ diff --git a/include/media/stagefright/MPEG4Extractor.h b/include/media/stagefright/MPEG4Extractor.h new file mode 100644 index 0000000..932e30f --- /dev/null +++ b/include/media/stagefright/MPEG4Extractor.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MPEG4_EXTRACTOR_H_ + +#define MPEG4_EXTRACTOR_H_ + +#include <media/stagefright/MediaExtractor.h> + +namespace android { + +class DataSource; +class SampleTable; +class String8; + +class MPEG4Extractor : public MediaExtractor { +public: + // Extractor assumes ownership of "source". + MPEG4Extractor(const sp<DataSource> &source); + + size_t countTracks(); + sp<MediaSource> getTrack(size_t index); + sp<MetaData> getTrackMetaData(size_t index); + +protected: + virtual ~MPEG4Extractor(); + +private: + struct Track { + Track *next; + sp<MetaData> meta; + uint32_t timescale; + sp<SampleTable> sampleTable; + }; + + sp<DataSource> mDataSource; + bool mHaveMetadata; + + Track *mFirstTrack, *mLastTrack; + + uint32_t mHandlerType; + + status_t readMetaData(); + status_t parseChunk(off_t *offset, int depth); + + MPEG4Extractor(const MPEG4Extractor &); + MPEG4Extractor &operator=(const MPEG4Extractor &); +}; + +bool SniffMPEG4( + const sp<DataSource> &source, String8 *mimeType, float *confidence); + +} // namespace android + +#endif // MPEG4_EXTRACTOR_H_ diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h new file mode 100644 index 0000000..6b0399f --- /dev/null +++ b/include/media/stagefright/MPEG4Writer.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MPEG4_WRITER_H_ + +#define MPEG4_WRITER_H_ + +#include <stdio.h> + +#include <utils/List.h> +#include <utils/RefBase.h> +#include <utils/threads.h> + +namespace android { + +class MediaBuffer; +class MediaSource; +class MetaData; + +class MPEG4Writer : public RefBase { +public: + MPEG4Writer(const char *filename); + + void addSource(const sp<MediaSource> &source); + status_t start(); + bool reachedEOS(); + void stop(); + + void beginBox(const char *fourcc); + void writeInt8(int8_t x); + void writeInt16(int16_t x); + void writeInt32(int32_t x); + void writeInt64(int64_t x); + void writeCString(const char *s); + void writeFourcc(const char *fourcc); + void write(const void *data, size_t size); + void endBox(); + +protected: + virtual ~MPEG4Writer(); + +private: + class Track; + + FILE *mFile; + off_t mOffset; + off_t mMdatOffset; + Mutex mLock; + + List<Track *> mTracks; + + List<off_t> mBoxes; + + off_t addSample(MediaBuffer *buffer); + + MPEG4Writer(const MPEG4Writer &); + MPEG4Writer &operator=(const MPEG4Writer &); +}; + +} // namespace android + +#endif // MPEG4_WRITER_H_ diff --git a/include/media/stagefright/MediaBuffer.h b/include/media/stagefright/MediaBuffer.h new file mode 100644 index 0000000..339e6fb --- /dev/null +++ b/include/media/stagefright/MediaBuffer.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_BUFFER_H_ + +#define MEDIA_BUFFER_H_ + +#include <pthread.h> + +#include <utils/Errors.h> +#include <utils/RefBase.h> + +namespace android { + +class MediaBuffer; +class MediaBufferObserver; +class MetaData; + +class MediaBufferObserver { +public: + MediaBufferObserver() {} + virtual ~MediaBufferObserver() {} + + virtual void signalBufferReturned(MediaBuffer *buffer) = 0; + +private: + MediaBufferObserver(const MediaBufferObserver &); + MediaBufferObserver &operator=(const MediaBufferObserver &); +}; + +class MediaBuffer { +public: + // The underlying data remains the responsibility of the caller! + MediaBuffer(void *data, size_t size); + + MediaBuffer(size_t size); + + // Decrements the reference count and returns the buffer to its + // associated MediaBufferGroup if the reference count drops to 0. + void release(); + + // Increments the reference count. + void add_ref(); + + void *data() const; + size_t size() const; + + size_t range_offset() const; + size_t range_length() const; + + void set_range(size_t offset, size_t length); + + sp<MetaData> meta_data(); + + // Clears meta data and resets the range to the full extent. + void reset(); + + void setObserver(MediaBufferObserver *group); + + // Returns a clone of this MediaBuffer increasing its reference count. + // The clone references the same data but has its own range and + // MetaData. + MediaBuffer *clone(); + + int refcount() const; + +protected: + virtual ~MediaBuffer(); + +private: + friend class MediaBufferGroup; + friend class OMXDecoder; + + // For use by OMXDecoder, reference count must be 1, drop reference + // count to 0 without signalling the observer. + void claim(); + + MediaBufferObserver *mObserver; + MediaBuffer *mNextBuffer; + int mRefCount; + + void *mData; + size_t mSize, mRangeOffset, mRangeLength; + + bool mOwnsData; + + sp<MetaData> mMetaData; + + MediaBuffer *mOriginal; + + void setNextBuffer(MediaBuffer *buffer); + MediaBuffer *nextBuffer(); + + MediaBuffer(const MediaBuffer &); + MediaBuffer &operator=(const MediaBuffer &); +}; + +} // namespace android + +#endif // MEDIA_BUFFER_H_ diff --git a/include/media/stagefright/MediaBufferGroup.h b/include/media/stagefright/MediaBufferGroup.h new file mode 100644 index 0000000..0488292 --- /dev/null +++ b/include/media/stagefright/MediaBufferGroup.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_BUFFER_GROUP_H_ + +#define MEDIA_BUFFER_GROUP_H_ + +#include <media/stagefright/MediaBuffer.h> +#include <utils/Errors.h> +#include <utils/threads.h> + +namespace android { + +class MediaBuffer; +class MetaData; + +class MediaBufferGroup : public MediaBufferObserver { +public: + MediaBufferGroup(); + ~MediaBufferGroup(); + + 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); + +protected: + virtual void signalBufferReturned(MediaBuffer *buffer); + +private: + friend class MediaBuffer; + + Mutex mLock; + Condition mCondition; + + MediaBuffer *mFirstBuffer, *mLastBuffer; + + MediaBufferGroup(const MediaBufferGroup &); + MediaBufferGroup &operator=(const MediaBufferGroup &); +}; + +} // namespace android + +#endif // MEDIA_BUFFER_GROUP_H_ diff --git a/include/media/stagefright/MediaDebug.h b/include/media/stagefright/MediaDebug.h new file mode 100644 index 0000000..c8a8f00 --- /dev/null +++ b/include/media/stagefright/MediaDebug.h @@ -0,0 +1,20 @@ +#ifndef MEDIA_DEBUG_H_ + +#define MEDIA_DEBUG_H_ + +#include <cutils/log.h> + +#define LITERAL_TO_STRING_INTERNAL(x) #x +#define LITERAL_TO_STRING(x) LITERAL_TO_STRING_INTERNAL(x) + +#define CHECK_EQ(x,y) \ + LOG_ALWAYS_FATAL_IF( \ + (x) != (y), \ + __FILE__ ":" LITERAL_TO_STRING(__LINE__) " " #x " != " #y) + +#define CHECK(x) \ + LOG_ALWAYS_FATAL_IF( \ + !(x), \ + __FILE__ ":" LITERAL_TO_STRING(__LINE__) " " #x) + +#endif // MEDIA_DEBUG_H_ diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h new file mode 100644 index 0000000..feb66e3 --- /dev/null +++ b/include/media/stagefright/MediaDefs.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_DEFS_H_ + +#define MEDIA_DEFS_H_ + +namespace android { + +extern const char *MEDIA_MIMETYPE_IMAGE_JPEG; + +extern const char *MEDIA_MIMETYPE_VIDEO_AVC; +extern const char *MEDIA_MIMETYPE_VIDEO_MPEG4; +extern const char *MEDIA_MIMETYPE_VIDEO_H263; +extern const char *MEDIA_MIMETYPE_VIDEO_RAW; + +extern const char *MEDIA_MIMETYPE_AUDIO_AMR_NB; +extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB; +extern const char *MEDIA_MIMETYPE_AUDIO_MPEG; +extern const char *MEDIA_MIMETYPE_AUDIO_AAC; +extern const char *MEDIA_MIMETYPE_AUDIO_RAW; + +extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4; + +} // namespace android + +#endif // MEDIA_DEFS_H_ diff --git a/include/media/stagefright/MediaErrors.h b/include/media/stagefright/MediaErrors.h new file mode 100644 index 0000000..2bb0ed6 --- /dev/null +++ b/include/media/stagefright/MediaErrors.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_ERRORS_H_ + +#define MEDIA_ERRORS_H_ + +#include <utils/Errors.h> + +namespace android { + +enum { + MEDIA_ERROR_BASE = -1000, + + ERROR_ALREADY_CONNECTED = MEDIA_ERROR_BASE, + ERROR_NOT_CONNECTED = MEDIA_ERROR_BASE - 1, + ERROR_UNKNOWN_HOST = MEDIA_ERROR_BASE - 2, + ERROR_CANNOT_CONNECT = MEDIA_ERROR_BASE - 3, + ERROR_IO = MEDIA_ERROR_BASE - 4, + ERROR_CONNECTION_LOST = MEDIA_ERROR_BASE - 5, + ERROR_MALFORMED = MEDIA_ERROR_BASE - 7, + ERROR_OUT_OF_RANGE = MEDIA_ERROR_BASE - 8, + ERROR_BUFFER_TOO_SMALL = MEDIA_ERROR_BASE - 9, + ERROR_UNSUPPORTED = MEDIA_ERROR_BASE - 10, + ERROR_END_OF_STREAM = MEDIA_ERROR_BASE - 11, +}; + +} // namespace android + +#endif // MEDIA_ERRORS_H_ diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h new file mode 100644 index 0000000..67e45bd --- /dev/null +++ b/include/media/stagefright/MediaExtractor.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_EXTRACTOR_H_ + +#define MEDIA_EXTRACTOR_H_ + +#include <utils/RefBase.h> + +namespace android { + +class DataSource; +class MediaSource; +class MetaData; + +class MediaExtractor : public RefBase { +public: + static sp<MediaExtractor> Create( + const sp<DataSource> &source, const char *mime = NULL); + + virtual size_t countTracks() = 0; + virtual sp<MediaSource> getTrack(size_t index) = 0; + virtual sp<MetaData> getTrackMetaData(size_t index) = 0; + +protected: + MediaExtractor() {} + virtual ~MediaExtractor() {} + +private: + MediaExtractor(const MediaExtractor &); + MediaExtractor &operator=(const MediaExtractor &); +}; + +} // namespace android + +#endif // MEDIA_EXTRACTOR_H_ diff --git a/include/media/stagefright/MediaPlayerImpl.h b/include/media/stagefright/MediaPlayerImpl.h new file mode 100644 index 0000000..53a2088 --- /dev/null +++ b/include/media/stagefright/MediaPlayerImpl.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_PLAYER_IMPL_H_ + +#define MEDIA_PLAYER_IMPL_H_ + +#include <pthread.h> + +#include <media/MediaPlayerInterface.h> +#include <media/stagefright/OMXClient.h> +#include <utils/RefBase.h> +#include <utils/threads.h> + +namespace android { + +class AudioPlayer; +class IOMXRenderer; +class ISurface; +class MediaExtractor; +class MediaBuffer; +class MediaSource; +class MemoryHeapPmem; +class MetaData; +class Surface; +class TimeSource; + +class MediaPlayerImpl { +public: + MediaPlayerImpl(const char *uri); + + status_t initCheck() const; + + // Assumes ownership of "fd". + MediaPlayerImpl(int fd, int64_t offset, int64_t length); + + ~MediaPlayerImpl(); + + void play(); + void pause(); + bool isPlaying() const; + + void setSurface(const sp<Surface> &surface); + void setISurface(const sp<ISurface> &isurface); + + void setAudioSink(const sp<MediaPlayerBase::AudioSink> &audioSink); + + int32_t getWidth() const { return mVideoWidth; } + int32_t getHeight() const { return mVideoHeight; } + + int64_t getDuration(); + int64_t getPosition(); + status_t seekTo(int64_t time); + +private: + status_t mInitCheck; + + OMXClient mClient; + + sp<MediaExtractor> mExtractor; + + TimeSource *mTimeSource; + + sp<MediaSource> mAudioSource; + sp<MediaSource> mAudioDecoder; + AudioPlayer *mAudioPlayer; + + sp<MediaSource> mVideoSource; + sp<MediaSource> mVideoDecoder; + int32_t mVideoWidth, mVideoHeight; + int64_t mVideoPosition; + + int64_t mDuration; + + bool mPlaying; + bool mPaused; + + int64_t mTimeSourceDeltaUs; + + sp<Surface> mSurface; + sp<ISurface> mISurface; + sp<IOMXRenderer> mVideoRenderer; + + sp<MediaPlayerBase::AudioSink> mAudioSink; + + Mutex mLock; + pthread_t mVideoThread; + + bool mSeeking; + int64_t mSeekTimeUs; + + void init(); + + static void *VideoWrapper(void *me); + void videoEntry(); + + void setAudioSource(const sp<MediaSource> &source); + void setVideoSource(const sp<MediaSource> &source); + + MediaSource *makeShoutcastSource(const char *path); + + void displayOrDiscardFrame(MediaBuffer *buffer, int64_t pts_us); + void populateISurface(); + void depopulateISurface(); + void sendFrameToISurface(MediaBuffer *buffer); + + void stop(); + + MediaPlayerImpl(const MediaPlayerImpl &); + MediaPlayerImpl &operator=(const MediaPlayerImpl &); +}; + +} // namespace android + +#endif // MEDIA_PLAYER_IMPL_H_ diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h new file mode 100644 index 0000000..d1fa114 --- /dev/null +++ b/include/media/stagefright/MediaSource.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_SOURCE_H_ + +#define MEDIA_SOURCE_H_ + +#include <sys/types.h> + +#include <utils/RefBase.h> + +namespace android { + +class MediaBuffer; +class MetaData; + +struct MediaSource : public RefBase { + MediaSource(); + + // To be called before any other methods on this object, except + // getFormat(). + virtual status_t start(MetaData *params = NULL) = 0; + + // Any blocking read call returns immediately with a result of NO_INIT. + // It is an error to call any methods other than start after this call + // returns. Any buffers the object may be holding onto at the time of + // the stop() call are released. + // Also, it is imperative that any buffers output by this object and + // held onto by callers be released before a call to stop() !!! + virtual status_t stop() = 0; + + // Returns the format of the data output by this media source. + virtual sp<MetaData> getFormat() = 0; + + struct ReadOptions; + + // Returns a new buffer of data. Call blocks until a + // buffer is available, an error is encountered of the end of the stream + // is reached. + // End of stream is signalled by a result of ERROR_END_OF_STREAM. + virtual status_t read( + MediaBuffer **buffer, const ReadOptions *options = NULL) = 0; + + // Options that modify read() behaviour. The default is to + // a) not request a seek + // b) not be late, i.e. lateness_us = 0 + struct ReadOptions { + ReadOptions(); + + // Reset everything back to defaults. + void reset(); + + void setSeekTo(int64_t time_us); + void clearSeekTo(); + bool getSeekTo(int64_t *time_us) const; + + void setLateBy(int64_t lateness_us); + int64_t getLateBy() const; + + private: + enum Options { + kSeekTo_Option = 1, + }; + + uint32_t mOptions; + int64_t mSeekTimeUs; + int64_t mLatenessUs; + }; + +protected: + virtual ~MediaSource(); + +private: + MediaSource(const MediaSource &); + MediaSource &operator=(const MediaSource &); +}; + +} // namespace android + +#endif // MEDIA_SOURCE_H_ diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h new file mode 100644 index 0000000..abb45a9 --- /dev/null +++ b/include/media/stagefright/MetaData.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef META_DATA_H_ + +#define META_DATA_H_ + +#include <sys/types.h> + +#include <stdint.h> + +#include <utils/RefBase.h> +#include <utils/KeyedVector.h> + +namespace android { + +enum { + kKeyMIMEType = 'mime', + kKeyWidth = 'widt', + kKeyHeight = 'heig', + kKeyChannelCount = '#chn', + kKeySampleRate = 'srte', + kKeyBitRate = 'brte', + kKeyESDS = 'esds', + kKeyAVCC = 'avcc', + kKeyTimeUnits = '#tim', + kKeyTimeScale = 'scal', + kKeyWantsNALFragments = 'NALf', + kKeyIsSyncFrame = 'sync', + kKeyDuration = 'dura', + kKeyColorFormat = 'colf', + kKeyPlatformPrivate = 'priv', + kKeyDecoderComponent = 'decC', + kKeyBufferID = 'bfID', + kKeyMaxInputSize = 'inpS', +}; + +enum { + kTypeESDS = 'esds', + kTypeAVCC = 'avcc', +}; + +class MetaData : public RefBase { +public: + MetaData(); + MetaData(const MetaData &from); + + enum Type { + TYPE_NONE = 'none', + TYPE_C_STRING = 'cstr', + TYPE_INT32 = 'in32', + TYPE_FLOAT = 'floa', + TYPE_POINTER = 'ptr ', + }; + + void clear(); + bool remove(uint32_t key); + + bool setCString(uint32_t key, const char *value); + bool setInt32(uint32_t key, int32_t value); + bool setFloat(uint32_t key, float value); + bool setPointer(uint32_t key, void *value); + + bool findCString(uint32_t key, const char **value); + bool findInt32(uint32_t key, int32_t *value); + bool findFloat(uint32_t key, float *value); + bool findPointer(uint32_t key, void **value); + + bool setData(uint32_t key, uint32_t type, const void *data, size_t size); + + bool findData(uint32_t key, uint32_t *type, + const void **data, size_t *size) const; + +protected: + virtual ~MetaData(); + +private: + struct typed_data { + typed_data(); + ~typed_data(); + + typed_data(const MetaData::typed_data &); + typed_data &operator=(const MetaData::typed_data &); + + void clear(); + void setData(uint32_t type, const void *data, size_t size); + void getData(uint32_t *type, const void **data, size_t *size) const; + + private: + uint32_t mType; + size_t mSize; + + union { + void *ext_data; + float reservoir; + } u; + + bool usesReservoir() const { + return mSize <= sizeof(u.reservoir); + } + + void allocateStorage(size_t size); + void freeStorage(); + + void *storage() { + return usesReservoir() ? &u.reservoir : u.ext_data; + } + + const void *storage() const { + return usesReservoir() ? &u.reservoir : u.ext_data; + } + }; + + KeyedVector<uint32_t, typed_data> mItems; + + // MetaData &operator=(const MetaData &); +}; + +} // namespace android + +#endif // META_DATA_H_ diff --git a/include/media/stagefright/MmapSource.h b/include/media/stagefright/MmapSource.h new file mode 100644 index 0000000..a8bd57f --- /dev/null +++ b/include/media/stagefright/MmapSource.h @@ -0,0 +1,52 @@ +/* + * 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 MMAP_SOURCE_H_ + +#define MMAP_SOURCE_H_ + +#include <media/stagefright/DataSource.h> +#include <media/stagefright/MediaErrors.h> + +namespace android { + +class MmapSource : public DataSource { +public: + MmapSource(const char *filename); + + // Assumes ownership of "fd". + MmapSource(int fd, int64_t offset, int64_t length); + + virtual ~MmapSource(); + + status_t InitCheck() const; + + virtual ssize_t read_at(off_t offset, void *data, size_t size); + virtual status_t getSize(off_t *size); + +private: + int mFd; + void *mBase; + size_t mSize; + + MmapSource(const MmapSource &); + MmapSource &operator=(const MmapSource &); +}; + +} // namespace android + +#endif // MMAP_SOURCE_H_ + diff --git a/include/media/stagefright/OMXClient.h b/include/media/stagefright/OMXClient.h new file mode 100644 index 0000000..2f14d06 --- /dev/null +++ b/include/media/stagefright/OMXClient.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OMX_CLIENT_H_ + +#define OMX_CLIENT_H_ + +#include <media/IOMX.h> + +namespace android { + +class OMXClient { +public: + OMXClient(); + + status_t connect(); + void disconnect(); + + sp<IOMX> interface() { + return mOMX; + } + +private: + sp<IOMX> mOMX; + + OMXClient(const OMXClient &); + OMXClient &operator=(const OMXClient &); +}; + +} // namespace android + +#endif // OMX_CLIENT_H_ diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h new file mode 100644 index 0000000..3f3dcf9 --- /dev/null +++ b/include/media/stagefright/OMXCodec.h @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OMX_CODEC_H_ + +#define OMX_CODEC_H_ + +#include <media/IOMX.h> +#include <media/stagefright/MediaBuffer.h> +#include <media/stagefright/MediaSource.h> +#include <utils/threads.h> + +namespace android { + +class MemoryDealer; +struct OMXCodecObserver; + +struct OMXCodec : public MediaSource, + public MediaBufferObserver { + static sp<OMXCodec> Create( + const sp<IOMX> &omx, + const sp<MetaData> &meta, bool createEncoder, + const sp<MediaSource> &source, + const char *matchComponentName = NULL); + + static void setComponentRole( + const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder, + const char *mime); + + virtual status_t start(MetaData *params = NULL); + virtual status_t stop(); + + virtual sp<MetaData> getFormat(); + + virtual status_t read( + MediaBuffer **buffer, const ReadOptions *options = NULL); + + void on_message(const omx_message &msg); + + // from MediaBufferObserver + virtual void signalBufferReturned(MediaBuffer *buffer); + +protected: + virtual ~OMXCodec(); + +private: + enum State { + DEAD, + LOADED, + LOADED_TO_IDLE, + IDLE_TO_EXECUTING, + EXECUTING, + EXECUTING_TO_IDLE, + IDLE_TO_LOADED, + RECONFIGURING, + ERROR + }; + + enum { + kPortIndexInput = 0, + kPortIndexOutput = 1 + }; + + enum PortStatus { + ENABLED, + DISABLING, + DISABLED, + ENABLING, + SHUTTING_DOWN, + }; + + enum Quirks { + kNeedsFlushBeforeDisable = 1, + kWantsNALFragments = 2, + kRequiresLoadedToIdleAfterAllocation = 4, + kRequiresAllocateBufferOnInputPorts = 8, + kRequiresFlushCompleteEmulation = 16, + kRequiresAllocateBufferOnOutputPorts = 32, + kRequiresFlushBeforeShutdown = 64, + kOutputDimensionsAre16Aligned = 128, + }; + + struct BufferInfo { + IOMX::buffer_id mBuffer; + bool mOwnedByComponent; + sp<IMemory> mMem; + MediaBuffer *mMediaBuffer; + }; + + struct CodecSpecificData { + size_t mSize; + uint8_t mData[1]; + }; + + sp<IOMX> mOMX; + IOMX::node_id mNode; + sp<OMXCodecObserver> mObserver; + uint32_t mQuirks; + bool mIsEncoder; + char *mMIME; + char *mComponentName; + sp<MetaData> mOutputFormat; + sp<MediaSource> mSource; + Vector<CodecSpecificData *> mCodecSpecificData; + size_t mCodecSpecificDataIndex; + + sp<MemoryDealer> mDealer[2]; + + State mState; + Vector<BufferInfo> mPortBuffers[2]; + PortStatus mPortStatus[2]; + bool mInitialBufferSubmit; + bool mSignalledEOS; + bool mNoMoreOutputData; + int64_t mSeekTimeUs; + + Mutex mLock; + Condition mAsyncCompletion; + + // A list of indices into mPortStatus[kPortIndexOutput] filled with data. + List<size_t> mFilledBuffers; + Condition mBufferFilled; + + OMXCodec(const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks, + bool isEncoder, const char *mime, const char *componentName, + const sp<MediaSource> &source); + + void addCodecSpecificData(const void *data, size_t size); + void clearCodecSpecificData(); + + void setComponentRole(); + + void setAMRFormat(); + void setAMRWBFormat(); + void setAACFormat(int32_t numChannels, int32_t sampleRate); + + status_t setVideoPortFormatType( + OMX_U32 portIndex, + OMX_VIDEO_CODINGTYPE compressionFormat, + OMX_COLOR_FORMATTYPE colorFormat); + + void setVideoInputFormat( + const char *mime, OMX_U32 width, OMX_U32 height); + + void setVideoOutputFormat( + const char *mime, OMX_U32 width, OMX_U32 height); + + void setImageOutputFormat( + OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height); + + void setJPEGInputFormat( + OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize); + + void setMinBufferSize(OMX_U32 portIndex, OMX_U32 size); + + void setRawAudioFormat( + OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels); + + status_t allocateBuffers(); + status_t allocateBuffersOnPort(OMX_U32 portIndex); + + status_t freeBuffersOnPort( + OMX_U32 portIndex, bool onlyThoseWeOwn = false); + + void drainInputBuffer(IOMX::buffer_id buffer); + void fillOutputBuffer(IOMX::buffer_id buffer); + void drainInputBuffer(BufferInfo *info); + void fillOutputBuffer(BufferInfo *info); + + void drainInputBuffers(); + void fillOutputBuffers(); + + // Returns true iff a flush was initiated and a completion event is + // upcoming, false otherwise (A flush was not necessary as we own all + // the buffers on that port). + // This method will ONLY ever return false for a component with quirk + // "kRequiresFlushCompleteEmulation". + bool flushPortAsync(OMX_U32 portIndex); + + void disablePortAsync(OMX_U32 portIndex); + void enablePortAsync(OMX_U32 portIndex); + + static size_t countBuffersWeOwn(const Vector<BufferInfo> &buffers); + static bool isIntermediateState(State state); + + void onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); + void onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data); + void onStateChange(OMX_STATETYPE newState); + void onPortSettingsChanged(OMX_U32 portIndex); + + void setState(State newState); + + status_t init(); + void initOutputFormat(const sp<MetaData> &inputFormat); + + void dumpPortStatus(OMX_U32 portIndex); + + OMXCodec(const OMXCodec &); + OMXCodec &operator=(const OMXCodec &); +}; + +struct CodecProfileLevel { + OMX_U32 mProfile; + OMX_U32 mLevel; +}; + +struct CodecCapabilities { + String8 mComponentName; + Vector<CodecProfileLevel> mProfileLevels; +}; + +// Return a vector of componentNames with supported profile/level pairs +// supporting the given mime type, if queryDecoders==true, returns components +// that decode content of the given type, otherwise returns components +// that encode content of the given type. +// profile and level indications only make sense for h.263, mpeg4 and avc +// video. +// The profile/level values correspond to +// OMX_VIDEO_H263PROFILETYPE, OMX_VIDEO_MPEG4PROFILETYPE, +// OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263LEVELTYPE, OMX_VIDEO_MPEG4LEVELTYPE +// and OMX_VIDEO_AVCLEVELTYPE respectively. + +status_t QueryCodecs( + const sp<IOMX> &omx, + const char *mimeType, bool queryDecoders, + Vector<CodecCapabilities> *results); + +} // namespace android + +#endif // OMX_CODEC_H_ diff --git a/include/media/stagefright/SampleTable.h b/include/media/stagefright/SampleTable.h new file mode 100644 index 0000000..808d142 --- /dev/null +++ b/include/media/stagefright/SampleTable.h @@ -0,0 +1,109 @@ +/* + * 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 SAMPLE_TABLE_H_ + +#define SAMPLE_TABLE_H_ + +#include <sys/types.h> +#include <stdint.h> + +#include <media/stagefright/MediaErrors.h> +#include <utils/RefBase.h> +#include <utils/threads.h> + +namespace android { + +class DataSource; + +class SampleTable : public RefBase { +public: + SampleTable(const sp<DataSource> &source); + + // type can be 'stco' or 'co64'. + status_t setChunkOffsetParams( + uint32_t type, off_t data_offset, off_t data_size); + + status_t setSampleToChunkParams(off_t data_offset, off_t data_size); + + // type can be 'stsz' or 'stz2'. + status_t setSampleSizeParams( + uint32_t type, off_t data_offset, off_t data_size); + + status_t setTimeToSampleParams(off_t data_offset, off_t data_size); + + status_t setSyncSampleParams(off_t data_offset, off_t data_size); + + //////////////////////////////////////////////////////////////////////////// + + uint32_t countChunkOffsets() const; + status_t getChunkOffset(uint32_t chunk_index, off_t *offset); + + status_t getChunkForSample( + uint32_t sample_index, uint32_t *chunk_index, + uint32_t *chunk_relative_sample_index, uint32_t *desc_index); + + uint32_t countSamples() const; + status_t getSampleSize(uint32_t sample_index, size_t *sample_size); + + status_t getSampleOffsetAndSize( + uint32_t sample_index, off_t *offset, size_t *size); + + status_t getMaxSampleSize(size_t *size); + + status_t getDecodingTime(uint32_t sample_index, uint32_t *time); + + enum { + kSyncSample_Flag = 1 + }; + status_t findClosestSample( + uint32_t req_time, uint32_t *sample_index, uint32_t flags); + + status_t findClosestSyncSample( + uint32_t start_sample_index, uint32_t *sample_index); + +protected: + ~SampleTable(); + +private: + sp<DataSource> mDataSource; + Mutex mLock; + + off_t mChunkOffsetOffset; + uint32_t mChunkOffsetType; + uint32_t mNumChunkOffsets; + + off_t mSampleToChunkOffset; + uint32_t mNumSampleToChunkOffsets; + + off_t mSampleSizeOffset; + uint32_t mSampleSizeFieldSize; + uint32_t mDefaultSampleSize; + uint32_t mNumSampleSizes; + + uint32_t mTimeToSampleCount; + uint32_t *mTimeToSample; + + off_t mSyncSampleOffset; + uint32_t mNumSyncSamples; + + SampleTable(const SampleTable &); + SampleTable &operator=(const SampleTable &); +}; + +} // namespace android + +#endif // SAMPLE_TABLE_H_ diff --git a/include/media/stagefright/ShoutcastSource.h b/include/media/stagefright/ShoutcastSource.h new file mode 100644 index 0000000..352857a --- /dev/null +++ b/include/media/stagefright/ShoutcastSource.h @@ -0,0 +1,59 @@ +/* + * 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 SHOUTCAST_SOURCE_H_ + +#define SHOUTCAST_SOURCE_H_ + +#include <sys/types.h> + +#include <media/stagefright/MediaSource.h> + +namespace android { + +class HTTPStream; +class MediaBufferGroup; + +class ShoutcastSource : public MediaSource { +public: + // Assumes ownership of "http". + ShoutcastSource(HTTPStream *http); + virtual ~ShoutcastSource(); + + virtual status_t start(MetaData *params = NULL); + virtual status_t stop(); + + virtual sp<MetaData> getFormat(); + + virtual status_t read( + MediaBuffer **buffer, const ReadOptions *options = NULL); + +private: + HTTPStream *mHttp; + size_t mMetaDataOffset; + size_t mBytesUntilMetaData; + + MediaBufferGroup *mGroup; + bool mStarted; + + ShoutcastSource(const ShoutcastSource &); + ShoutcastSource &operator= (const ShoutcastSource &); +}; + +} // namespace android + +#endif // SHOUTCAST_SOURCE_H_ + diff --git a/include/media/stagefright/SoftwareRenderer.h b/include/media/stagefright/SoftwareRenderer.h new file mode 100644 index 0000000..1545493 --- /dev/null +++ b/include/media/stagefright/SoftwareRenderer.h @@ -0,0 +1,66 @@ +/* + * 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 SOFTWARE_RENDERER_H_ + +#define SOFTWARE_RENDERER_H_ + +#include <OMX_Video.h> +#include <media/stagefright/VideoRenderer.h> +#include <utils/RefBase.h> + +namespace android { + +class ISurface; +class MemoryHeapBase; + +class SoftwareRenderer : public VideoRenderer { +public: + SoftwareRenderer( + OMX_COLOR_FORMATTYPE colorFormat, + const sp<ISurface> &surface, + size_t displayWidth, size_t displayHeight, + size_t decodedWidth, size_t decodedHeight); + + virtual ~SoftwareRenderer(); + + virtual void render( + const void *data, size_t size, void *platformPrivate); + +private: + uint8_t *initClip(); + + void renderCbYCrY(const void *data, size_t size); + void renderYUV420Planar(const void *data, size_t size); + void renderQCOMYUV420SemiPlanar(const void *data, size_t size); + + OMX_COLOR_FORMATTYPE mColorFormat; + sp<ISurface> mISurface; + size_t mDisplayWidth, mDisplayHeight; + size_t mDecodedWidth, mDecodedHeight; + size_t mFrameSize; + sp<MemoryHeapBase> mMemoryHeap; + int mIndex; + + uint8_t *mClip; + + SoftwareRenderer(const SoftwareRenderer &); + SoftwareRenderer &operator=(const SoftwareRenderer &); +}; + +} // namespace android + +#endif // SOFTWARE_RENDERER_H_ diff --git a/include/media/stagefright/TimeSource.h b/include/media/stagefright/TimeSource.h new file mode 100644 index 0000000..443673d --- /dev/null +++ b/include/media/stagefright/TimeSource.h @@ -0,0 +1,51 @@ +/* + * 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 TIME_SOURCE_H_ + +#define TIME_SOURCE_H_ + +#include <stdint.h> + +namespace android { + +class TimeSource { +public: + TimeSource() {} + virtual ~TimeSource() {} + + virtual int64_t getRealTimeUs() = 0; + +private: + TimeSource(const TimeSource &); + TimeSource &operator=(const TimeSource &); +}; + +class SystemTimeSource : public TimeSource { +public: + SystemTimeSource(); + + virtual int64_t getRealTimeUs(); + +private: + static int64_t GetSystemTimeUs(); + + int64_t mStartTimeUs; +}; + +} // namespace android + +#endif // TIME_SOURCE_H_ diff --git a/include/media/stagefright/TimedEventQueue.h b/include/media/stagefright/TimedEventQueue.h new file mode 100644 index 0000000..a264421 --- /dev/null +++ b/include/media/stagefright/TimedEventQueue.h @@ -0,0 +1,106 @@ +/* + * 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 TIMED_EVENT_QUEUE_H_ + +#define TIMED_EVENT_QUEUE_H_ + +#include <pthread.h> + +#include <utils/List.h> +#include <utils/RefBase.h> +#include <utils/threads.h> + +namespace android { + +struct TimedEventQueue { + + struct Event : public RefBase { + Event() {} + virtual ~Event() {} + + protected: + virtual void fire(TimedEventQueue *queue, int64_t now_us) = 0; + + private: + friend class TimedEventQueue; + + Event(const Event &); + Event &operator=(const Event &); + }; + + TimedEventQueue(); + ~TimedEventQueue(); + + // Start executing the event loop. + void start(); + + // Stop executing the event loop, if flush is false, any pending + // events are discarded, otherwise the queue will stop (and this call + // return) once all pending events have been handled. + void stop(bool flush = false); + + // Posts an event to the front of the queue (after all events that + // have previously been posted to the front but before timed events). + void postEvent(const sp<Event> &event); + + void postEventToBack(const sp<Event> &event); + + // It is an error to post an event with a negative delay. + void postEventWithDelay(const sp<Event> &event, int64_t delay_us); + + // If the event is to be posted at a time that has already passed, + // it will fire as soon as possible. + void postTimedEvent(const sp<Event> &event, int64_t realtime_us); + + // Returns true iff event is currently in the queue and has been + // successfully cancelled. In this case the event will have been + // removed from the queue and won't fire. + bool cancelEvent(const sp<Event> &event); + + static int64_t getRealTimeUs(); + +private: + struct QueueItem { + sp<Event> event; + int64_t realtime_us; + }; + + struct StopEvent : public TimedEventQueue::Event { + virtual void fire(TimedEventQueue *queue, int64_t now_us) { + queue->mStopped = true; + } + }; + + pthread_t mThread; + List<QueueItem> mQueue; + Mutex mLock; + Condition mQueueNotEmptyCondition; + Condition mQueueHeadChangedCondition; + + bool mRunning; + bool mStopped; + + static void *ThreadWrapper(void *me); + void threadEntry(); + + TimedEventQueue(const TimedEventQueue &); + TimedEventQueue &operator=(const TimedEventQueue &); +}; + +} // namespace android + +#endif // TIMED_EVENT_QUEUE_H_ diff --git a/include/media/stagefright/Utils.h b/include/media/stagefright/Utils.h new file mode 100644 index 0000000..30c7f11 --- /dev/null +++ b/include/media/stagefright/Utils.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_H_ + +#define UTILS_H_ + +#include <stdint.h> + +namespace android { + +#define FOURCC(c1, c2, c3, c4) \ + (c1 << 24 | c2 << 16 | c3 << 8 | c4) + +uint16_t U16_AT(const uint8_t *ptr); +uint32_t U32_AT(const uint8_t *ptr); +uint64_t U64_AT(const uint8_t *ptr); + +uint64_t ntoh64(uint64_t x); +uint64_t hton64(uint64_t x); + +} // namespace android + +#endif // UTILS_H_ diff --git a/include/media/stagefright/VideoRenderer.h b/include/media/stagefright/VideoRenderer.h new file mode 100644 index 0000000..f80b277 --- /dev/null +++ b/include/media/stagefright/VideoRenderer.h @@ -0,0 +1,41 @@ +/* + * 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 VIDEO_RENDERER_H_ + +#define VIDEO_RENDERER_H_ + +#include <sys/types.h> + +namespace android { + +class VideoRenderer { +public: + virtual ~VideoRenderer() {} + + virtual void render( + const void *data, size_t size, void *platformPrivate) = 0; + +protected: + VideoRenderer() {} + + VideoRenderer(const VideoRenderer &); + VideoRenderer &operator=(const VideoRenderer &); +}; + +} // namespace android + +#endif // VIDEO_RENDERER_H_ diff --git a/include/media/stagefright/stagefright_string.h b/include/media/stagefright/stagefright_string.h new file mode 100644 index 0000000..1ed4c86 --- /dev/null +++ b/include/media/stagefright/stagefright_string.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef STAGEFRIGHT_STRING_H_ + +#define STAGEFRIGHT_STRING_H_ + +#include <utils/String8.h> + +namespace android { + +class string { +public: + typedef size_t size_type; + static size_type npos; + + string(); + string(const char *s); + string(const char *s, size_t length); + string(const string &from, size_type start, size_type length = npos); + + const char *c_str() const; + size_type size() const; + + void clear(); + void erase(size_type from, size_type length); + + size_type find(char c) const; + + bool operator<(const string &other) const; + bool operator==(const string &other) const; + + string &operator+=(char c); + +private: + String8 mString; +}; + +} // namespace android + +#endif // STAGEFRIGHT_STRING_H_ |