diff options
Diffstat (limited to 'include')
94 files changed, 3800 insertions, 366 deletions
diff --git a/include/camera/Camera.h b/include/camera/Camera.h index 79682b8..2b60842 100644 --- a/include/camera/Camera.h +++ b/include/camera/Camera.h @@ -74,6 +74,10 @@ public: const String16& clientPackageName, int clientUid); + static status_t connectLegacy(int cameraId, int halVersion, + const String16& clientPackageName, + int clientUid, sp<Camera>& camera); + virtual ~Camera(); status_t reconnect(); diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h index d521543..c6074fc 100644 --- a/include/camera/CameraParameters.h +++ b/include/camera/CameraParameters.h @@ -102,6 +102,12 @@ public: void dump() const; status_t dump(int fd, const Vector<String16>& args) const; + /** + * Returns a Vector containing the supported preview formats + * as enums given in graphics.h. + */ + void getSupportedPreviewFormats(Vector<int>& formats) const; + // Parameter keys to communicate between camera application and driver. // The access (read/write, read only, or write only) is viewed from the // perspective of applications, not driver. @@ -674,6 +680,13 @@ public: // High-dynamic range mode static const char LIGHTFX_HDR[]; + /** + * Returns the the supported preview formats as an enum given in graphics.h + * corrsponding to the format given in the input string or -1 if no such + * conversion exists. + */ + static int previewFormatToEnum(const char* format); + private: DefaultKeyedVector<String8,String8> mMap; }; diff --git a/include/camera/CameraUtils.h b/include/camera/CameraUtils.h new file mode 100644 index 0000000..c06f05d --- /dev/null +++ b/include/camera/CameraUtils.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_CAMERA_CLIENT_CAMERAUTILS_H +#define ANDROID_CAMERA_CLIENT_CAMERAUTILS_H + +#include <camera/CameraMetadata.h> +#include <utils/Errors.h> + +#include <stdint.h> + +namespace android { + +/** + * CameraUtils contains utility methods that are shared between the native + * camera client, and the camera service. + */ +class CameraUtils { + public: + /** + * Calculate the ANativeWindow transform from the static camera + * metadata. This is based on the sensor orientation and lens facing + * attributes of the camera device. + * + * Returns OK on success, or a negative error code. + */ + static status_t getRotationTransform(const CameraMetadata& staticInfo, + /*out*/int32_t* transform); + private: + CameraUtils(); +}; + +} /* namespace android */ + +#endif /* ANDROID_CAMERA_CLIENT_CAMERAUTILS_H */ + diff --git a/include/camera/CaptureResult.h b/include/camera/CaptureResult.h new file mode 100644 index 0000000..0be7d6f --- /dev/null +++ b/include/camera/CaptureResult.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_CAPTURERESULT_H +#define ANDROID_HARDWARE_CAPTURERESULT_H + +#include <utils/RefBase.h> +#include <camera/CameraMetadata.h> + +namespace android { + +/** + * CaptureResultExtras is a structure to encapsulate various indices for a capture result. + * These indices are framework-internal and not sent to the HAL. + */ +struct CaptureResultExtras { + /** + * An integer to index the request sequence that this result belongs to. + */ + int32_t requestId; + + /** + * An integer to index this result inside a request sequence, starting from 0. + */ + int32_t burstId; + + /** + * TODO: Add documentation for this field. + */ + int32_t afTriggerId; + + /** + * TODO: Add documentation for this field. + */ + int32_t precaptureTriggerId; + + /** + * A 64bit integer to index the frame number associated with this result. + */ + int64_t frameNumber; + + /** + * The partial result count (index) for this capture result. + */ + int32_t partialResultCount; + + /** + * Constructor initializes object as invalid by setting requestId to be -1. + */ + CaptureResultExtras() + : requestId(-1), + burstId(0), + afTriggerId(0), + precaptureTriggerId(0), + frameNumber(0), + partialResultCount(0) { + } + + /** + * This function returns true if it's a valid CaptureResultExtras object. + * Otherwise, returns false. It is valid only when requestId is non-negative. + */ + bool isValid(); + + status_t readFromParcel(Parcel* parcel); + status_t writeToParcel(Parcel* parcel) const; +}; + +struct CaptureResult : public virtual LightRefBase<CaptureResult> { + CameraMetadata mMetadata; + CaptureResultExtras mResultExtras; + + CaptureResult(); + + CaptureResult(const CaptureResult& otherResult); + + status_t readFromParcel(Parcel* parcel); + status_t writeToParcel(Parcel* parcel) const; +}; + +} + +#endif /* ANDROID_HARDWARE_CAPTURERESULT_H */ diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h index f342122..f7f06bb 100644 --- a/include/camera/ICameraService.h +++ b/include/camera/ICameraService.h @@ -31,6 +31,8 @@ class ICameraServiceListener; class ICameraDeviceUser; class ICameraDeviceCallbacks; class CameraMetadata; +class VendorTagDescriptor; +class String16; class ICameraService : public IInterface { @@ -47,21 +49,40 @@ public: ADD_LISTENER, REMOVE_LISTENER, GET_CAMERA_CHARACTERISTICS, + GET_CAMERA_VENDOR_TAG_DESCRIPTOR, + GET_LEGACY_PARAMETERS, + SUPPORTS_CAMERA_API, + CONNECT_LEGACY, }; enum { USE_CALLING_UID = -1 }; + enum { + API_VERSION_1 = 1, + API_VERSION_2 = 2, + }; + + enum { + CAMERA_HAL_API_VERSION_UNSPECIFIED = -1 + }; + public: DECLARE_META_INTERFACE(CameraService); virtual int32_t getNumberOfCameras() = 0; virtual status_t getCameraInfo(int cameraId, - struct CameraInfo* cameraInfo) = 0; + /*out*/ + struct CameraInfo* cameraInfo) = 0; virtual status_t getCameraCharacteristics(int cameraId, - CameraMetadata* cameraInfo) = 0; + /*out*/ + CameraMetadata* cameraInfo) = 0; + + virtual status_t getCameraVendorTagDescriptor( + /*out*/ + sp<VendorTagDescriptor>& desc) = 0; // Returns 'OK' if operation succeeded // - Errors: ALREADY_EXISTS if the listener was already added @@ -97,6 +118,30 @@ public: int clientUid, /*out*/ sp<ICameraDeviceUser>& device) = 0; + + virtual status_t getLegacyParameters( + int cameraId, + /*out*/ + String16* parameters) = 0; + + /** + * Returns OK if device supports camera2 api, + * returns -EOPNOTSUPP if it doesn't. + */ + virtual status_t supportsCameraApi( + int cameraId, int apiVersion) = 0; + + /** + * Connect the device as a legacy device for a given HAL version. + * For halVersion, use CAMERA_API_DEVICE_VERSION_* for a particular + * version, or CAMERA_HAL_API_VERSION_UNSPECIFIED for a service-selected version. + */ + virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, + int cameraId, int halVersion, + const String16& clientPackageName, + int clientUid, + /*out*/ + sp<ICamera>& device) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/camera/VendorTagDescriptor.h b/include/camera/VendorTagDescriptor.h new file mode 100644 index 0000000..1758acf --- /dev/null +++ b/include/camera/VendorTagDescriptor.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef VENDOR_TAG_DESCRIPTOR_H + +#include <utils/Vector.h> +#include <utils/KeyedVector.h> +#include <utils/String8.h> +#include <utils/RefBase.h> +#include <system/camera_vendor_tags.h> + +#include <stdint.h> + +namespace android { + +class Parcel; + +/** + * VendorTagDescriptor objects are parcelable containers for the vendor tag + * definitions provided, and are typically used to pass the vendor tag + * information enumerated by the HAL to clients of the camera service. + */ +class VendorTagDescriptor + : public LightRefBase<VendorTagDescriptor> { + public: + virtual ~VendorTagDescriptor(); + + /** + * The following 'get*' methods implement the corresponding + * functions defined in + * system/media/camera/include/system/camera_vendor_tags.h + */ + + // Returns the number of vendor tags defined. + int getTagCount() const; + + // Returns an array containing the id's of vendor tags defined. + void getTagArray(uint32_t* tagArray) const; + + // Returns the section name string for a given vendor tag id. + const char* getSectionName(uint32_t tag) const; + + // Returns the tag name string for a given vendor tag id. + const char* getTagName(uint32_t tag) const; + + // Returns the tag type for a given vendor tag id. + int getTagType(uint32_t tag) const; + + /** + * Write the VendorTagDescriptor object into the given parcel. + * + * Returns OK on success, or a negative error code. + */ + status_t writeToParcel( + /*out*/ + Parcel* parcel) const; + + /** + * Convenience method to get a vector containing all vendor tag + * sections, or an empty vector if none are defined. + */ + SortedVector<String8> getAllSectionNames() const; + + /** + * Lookup the tag id for a given tag name and section. + * + * Returns OK on success, or a negative error code. + */ + status_t lookupTag(String8 name, String8 section, /*out*/uint32_t* tag) const; + + /** + * Dump the currently configured vendor tags to a file descriptor. + */ + void dump(int fd, int verbosity, int indentation) const; + + // Static methods: + + /** + * Create a VendorTagDescriptor object from the given parcel. + * + * Returns OK on success, or a negative error code. + */ + static status_t createFromParcel(const Parcel* parcel, + /*out*/ + sp<VendorTagDescriptor>& descriptor); + + /** + * Create a VendorTagDescriptor object from the given vendor_tag_ops_t + * struct. + * + * Returns OK on success, or a negative error code. + */ + static status_t createDescriptorFromOps(const vendor_tag_ops_t* vOps, + /*out*/ + sp<VendorTagDescriptor>& descriptor); + + /** + * Sets the global vendor tag descriptor to use for this process. + * Camera metadata operations that access vendor tags will use the + * vendor tag definitions set this way. + * + * Returns OK on success, or a negative error code. + */ + static status_t setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc); + + /** + * Clears the global vendor tag descriptor used by this process. + */ + static void clearGlobalVendorTagDescriptor(); + + /** + * Returns the global vendor tag descriptor used by this process. + * This will contain NULL if no vendor tags are defined. + */ + static sp<VendorTagDescriptor> getGlobalVendorTagDescriptor(); + protected: + VendorTagDescriptor(); + KeyedVector<String8, KeyedVector<String8, uint32_t>*> mReverseMapping; + KeyedVector<uint32_t, String8> mTagToNameMap; + KeyedVector<uint32_t, uint32_t> mTagToSectionMap; // Value is offset in mSections + KeyedVector<uint32_t, int32_t> mTagToTypeMap; + SortedVector<String8> mSections; + // must be int32_t to be compatible with Parcel::writeInt32 + int32_t mTagCount; + private: + vendor_tag_ops mVendorOps; +}; + +} /* namespace android */ + +#define VENDOR_TAG_DESCRIPTOR_H +#endif /* VENDOR_TAG_DESCRIPTOR_H */ diff --git a/include/camera/camera2/ICameraDeviceCallbacks.h b/include/camera/camera2/ICameraDeviceCallbacks.h index 8dac4f2..670480b 100644 --- a/include/camera/camera2/ICameraDeviceCallbacks.h +++ b/include/camera/camera2/ICameraDeviceCallbacks.h @@ -24,9 +24,12 @@ #include <utils/Timers.h> #include <system/camera.h> +#include <camera/CaptureResult.h> + namespace android { class CameraMetadata; + class ICameraDeviceCallbacks : public IInterface { /** @@ -39,24 +42,29 @@ public: * Error codes for CAMERA_MSG_ERROR */ enum CameraErrorCode { + ERROR_CAMERA_INVALID_ERROR = -1, // To indicate all invalid error codes ERROR_CAMERA_DISCONNECTED = 0, ERROR_CAMERA_DEVICE = 1, - ERROR_CAMERA_SERVICE = 2 + ERROR_CAMERA_SERVICE = 2, + ERROR_CAMERA_REQUEST = 3, + ERROR_CAMERA_RESULT = 4, + ERROR_CAMERA_BUFFER = 5, }; // One way - virtual void onDeviceError(CameraErrorCode errorCode) = 0; + virtual void onDeviceError(CameraErrorCode errorCode, + const CaptureResultExtras& resultExtras) = 0; // One way virtual void onDeviceIdle() = 0; // One way - virtual void onCaptureStarted(int32_t requestId, + virtual void onCaptureStarted(const CaptureResultExtras& resultExtras, int64_t timestamp) = 0; // One way - virtual void onResultReceived(int32_t requestId, - const CameraMetadata& result) = 0; + virtual void onResultReceived(const CameraMetadata& metadata, + const CaptureResultExtras& resultExtras) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/camera/camera2/ICameraDeviceUser.h b/include/camera/camera2/ICameraDeviceUser.h index f71f302..35488bb 100644 --- a/include/camera/camera2/ICameraDeviceUser.h +++ b/include/camera/camera2/ICameraDeviceUser.h @@ -19,6 +19,7 @@ #include <binder/IInterface.h> #include <binder/Parcel.h> +#include <utils/List.h> struct camera_metadata; @@ -30,6 +31,10 @@ class Surface; class CaptureRequest; class CameraMetadata; +enum { + NO_IN_FLIGHT_REPEATING_FRAMES = -1, +}; + class ICameraDeviceUser : public IInterface { /** @@ -44,9 +49,55 @@ public: * Request Handling **/ + /** + * For streaming requests, output lastFrameNumber is the last frame number + * of the previous repeating request. + * For non-streaming requests, output lastFrameNumber is the expected last + * frame number of the current request. + */ virtual int submitRequest(sp<CaptureRequest> request, - bool streaming = false) = 0; - virtual status_t cancelRequest(int requestId) = 0; + bool streaming = false, + /*out*/ + int64_t* lastFrameNumber = NULL) = 0; + + /** + * For streaming requests, output lastFrameNumber is the last frame number + * of the previous repeating request. + * For non-streaming requests, output lastFrameNumber is the expected last + * frame number of the current request. + */ + virtual int submitRequestList(List<sp<CaptureRequest> > requestList, + bool streaming = false, + /*out*/ + int64_t* lastFrameNumber = NULL) = 0; + + /** + * Output lastFrameNumber is the last frame number of the previous repeating request. + */ + virtual status_t cancelRequest(int requestId, + /*out*/ + int64_t* lastFrameNumber = NULL) = 0; + + /** + * Begin the device configuration. + * + * <p> + * beginConfigure must be called before any call to deleteStream, createStream, + * or endConfigure. It is not valid to call this when the device is not idle. + * <p> + */ + virtual status_t beginConfigure() = 0; + + /** + * End the device configuration. + * + * <p> + * endConfigure must be called after stream configuration is complete (i.e. after + * a call to beginConfigure and subsequent createStream/deleteStream calls). This + * must be called before any requests can be submitted. + * <p> + */ + virtual status_t endConfigure() = 0; virtual status_t deleteStream(int streamId) = 0; virtual status_t createStream( @@ -64,8 +115,12 @@ public: // Wait until all the submitted requests have finished processing virtual status_t waitUntilIdle() = 0; - // Flush all pending and in-progress work as quickly as possible. - virtual status_t flush() = 0; + /** + * Flush all pending and in-progress work as quickly as possible. + * Output lastFrameNumber is the last frame number of the previous repeating request. + */ + virtual status_t flush(/*out*/ + int64_t* lastFrameNumber = NULL) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/media/AudioBufferProvider.h b/include/media/AudioBufferProvider.h index ef392f0..7be449c 100644 --- a/include/media/AudioBufferProvider.h +++ b/include/media/AudioBufferProvider.h @@ -61,6 +61,17 @@ public: // buffer->frameCount 0 virtual status_t getNextBuffer(Buffer* buffer, int64_t pts = kInvalidPTS) = 0; + // Release (a portion of) the buffer previously obtained by getNextBuffer(). + // It is permissible to call releaseBuffer() multiple times per getNextBuffer(). + // On entry: + // buffer->frameCount number of frames to release, must be <= number of frames + // obtained but not yet released + // buffer->raw unused + // On return: + // buffer->frameCount 0; implementation MUST set to zero + // buffer->raw undefined; implementation is PERMITTED to set to any value, + // so if caller needs to continue using this buffer it must + // keep track of the pointer itself virtual void releaseBuffer(Buffer* buffer) = 0; }; diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h index 05d834d..4932d40 100644 --- a/include/media/AudioEffect.h +++ b/include/media/AudioEffect.h @@ -36,7 +36,7 @@ namespace android { // ---------------------------------------------------------------------------- -class effect_param_cblk_t; +struct effect_param_cblk_t; // ---------------------------------------------------------------------------- @@ -217,8 +217,9 @@ public: * higher priorities, 0 being the normal priority. * cbf: optional callback function (see effect_callback_t) * user: pointer to context for use by the callback receiver. - * sessionID: audio session this effect is associated to. If 0, the effect will be global to - * the output mix. If not 0, the effect will be applied to all players + * sessionID: audio session this effect is associated to. + * If equal to AUDIO_SESSION_OUTPUT_MIX, the effect will be global to + * the output mix. Otherwise, the effect will be applied to all players * (AudioTrack or MediaPLayer) within the same audio session. * io: HAL audio output or input stream to which this effect must be attached. Leave at 0 for * automatic output selection by AudioFlinger. @@ -229,8 +230,8 @@ public: int32_t priority = 0, effect_callback_t cbf = NULL, void* user = NULL, - int sessionId = 0, - audio_io_handle_t io = 0 + int sessionId = AUDIO_SESSION_OUTPUT_MIX, + audio_io_handle_t io = AUDIO_IO_HANDLE_NONE ); /* Constructor. @@ -241,8 +242,8 @@ public: int32_t priority = 0, effect_callback_t cbf = NULL, void* user = NULL, - int sessionId = 0, - audio_io_handle_t io = 0 + int sessionId = AUDIO_SESSION_OUTPUT_MIX, + audio_io_handle_t io = AUDIO_IO_HANDLE_NONE ); /* Terminates the AudioEffect and unregisters it from AudioFlinger. @@ -263,8 +264,8 @@ public: int32_t priority = 0, effect_callback_t cbf = NULL, void* user = NULL, - int sessionId = 0, - audio_io_handle_t io = 0 + int sessionId = AUDIO_SESSION_OUTPUT_MIX, + audio_io_handle_t io = AUDIO_IO_HANDLE_NONE ); /* Result of constructing the AudioEffect. This must be checked @@ -448,6 +449,7 @@ private: sp<EffectClient> mIEffectClient; // IEffectClient implementation sp<IMemory> mCblkMemory; // shared memory for deferred parameter setting effect_param_cblk_t* mCblk; // control block for deferred parameter setting + pid_t mClientPid; }; diff --git a/include/media/AudioPolicyHelper.h b/include/media/AudioPolicyHelper.h new file mode 100644 index 0000000..f4afd45 --- /dev/null +++ b/include/media/AudioPolicyHelper.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef AUDIO_POLICY_HELPER_H_ +#define AUDIO_POLICY_HELPER_H_ + +#include <system/audio.h> + +audio_stream_type_t audio_attributes_to_stream_type(const audio_attributes_t *attr) +{ + // flags to stream type mapping + if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) { + return AUDIO_STREAM_ENFORCED_AUDIBLE; + } + if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) { + return AUDIO_STREAM_BLUETOOTH_SCO; + } + + // usage to stream type mapping + switch (attr->usage) { + case AUDIO_USAGE_MEDIA: + case AUDIO_USAGE_GAME: + case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: + case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: + return AUDIO_STREAM_MUSIC; + case AUDIO_USAGE_ASSISTANCE_SONIFICATION: + return AUDIO_STREAM_SYSTEM; + case AUDIO_USAGE_VOICE_COMMUNICATION: + return AUDIO_STREAM_VOICE_CALL; + + case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: + return AUDIO_STREAM_DTMF; + + case AUDIO_USAGE_ALARM: + return AUDIO_STREAM_ALARM; + case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: + return AUDIO_STREAM_RING; + + case AUDIO_USAGE_NOTIFICATION: + case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: + case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: + case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: + case AUDIO_USAGE_NOTIFICATION_EVENT: + return AUDIO_STREAM_NOTIFICATION; + + case AUDIO_USAGE_UNKNOWN: + default: + return AUDIO_STREAM_MUSIC; + } +} + +#endif //AUDIO_POLICY_HELPER_H_ diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index 052064d..4edc1bf 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -26,7 +26,7 @@ namespace android { // ---------------------------------------------------------------------------- -class audio_track_cblk_t; +struct audio_track_cblk_t; class AudioRecordClientProxy; // ---------------------------------------------------------------------------- @@ -39,8 +39,12 @@ public: * Keep in sync with frameworks/base/media/java/android/media/AudioRecord.java NATIVE_EVENT_*. */ enum event_type { - EVENT_MORE_DATA = 0, // Request to read more data from PCM buffer. - EVENT_OVERRUN = 1, // PCM buffer overrun occurred. + EVENT_MORE_DATA = 0, // Request to read available data from buffer. + // If this event is delivered but the callback handler + // does not want to read the available data, the handler must + // explicitly + // ignore the event by setting frameCount to zero. + EVENT_OVERRUN = 1, // Buffer overrun occurred. EVENT_MARKER = 2, // Record head is at the specified marker position // (See setMarkerPosition()). EVENT_NEW_POS = 3, // Record head is at a new position @@ -60,9 +64,10 @@ public: size_t frameCount; // number of sample frames corresponding to size; // on input it is the number of frames available, // on output is the number of frames actually drained - // (currently ignored, but will make the primary field in future) + // (currently ignored but will make the primary field in future) size_t size; // input/output in bytes == frameCount * frameSize + // on output is the number of bytes actually drained // FIXME this is redundant with respect to frameCount, // and TRANSFER_OBTAIN mode is broken for 8-bit data // since we don't define the frame format @@ -76,7 +81,7 @@ public: /* As a convenience, if a callback is supplied, a handler thread * is automatically created with the appropriate priority. This thread - * invokes the callback when a new buffer becomes ready or various conditions occur. + * invokes the callback when a new buffer becomes available or various conditions occur. * Parameters: * * event: type of event notified (see enum AudioRecord::event_type). @@ -99,6 +104,8 @@ public: * - NO_ERROR: successful operation * - NO_INIT: audio server or audio hardware not initialized * - BAD_VALUE: unsupported configuration + * frameCount is guaranteed to be non-zero if status is NO_ERROR, + * and is undefined otherwise. */ static status_t getMinFrameCount(size_t* frameCount, @@ -109,7 +116,7 @@ public: /* How data is transferred from AudioRecord */ enum transfer_type { - TRANSFER_DEFAULT, // not specified explicitly; determine from other parameters + TRANSFER_DEFAULT, // not specified explicitly; determine from the other parameters TRANSFER_CALLBACK, // callback EVENT_MORE_DATA TRANSFER_OBTAIN, // FIXME deprecated: call obtainBuffer() and releaseBuffer() TRANSFER_SYNC, // synchronous read() @@ -137,7 +144,7 @@ public: * be larger if the requested size is not compatible with current audio HAL * latency. Zero means to use a default value. * cbf: Callback function. If not null, this function is called periodically - * to consume new PCM data and inform of marker, position updates, etc. + * to consume new data and inform of marker, position updates, etc. * user: Context for use by the callback receiver. * notificationFrames: The callback function is called each time notificationFrames PCM * frames are ready in record track output buffer. @@ -151,11 +158,11 @@ public: uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, - int frameCount = 0, + size_t frameCount = 0, callback_t cbf = NULL, void* user = NULL, - int notificationFrames = 0, - int sessionId = 0, + uint32_t notificationFrames = 0, + int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE); @@ -171,9 +178,10 @@ public: * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful intialization * - INVALID_OPERATION: AudioRecord is already initialized or record device is already in use - * - BAD_VALUE: invalid parameter (channels, format, sampleRate...) + * - BAD_VALUE: invalid parameter (channelMask, format, sampleRate...) * - NO_INIT: audio server or audio hardware not initialized * - PERMISSION_DENIED: recording is not allowed for the requesting process + * If status is not equal to NO_ERROR, don't call any other APIs on this AudioRecord. * * Parameters not listed in the AudioRecord constructors above: * @@ -183,16 +191,16 @@ public: uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, - int frameCount = 0, + size_t frameCount = 0, callback_t cbf = NULL, void* user = NULL, - int notificationFrames = 0, + uint32_t notificationFrames = 0, bool threadCanCallJava = false, - int sessionId = 0, + int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE); - /* Result of constructing the AudioRecord. This must be checked + /* Result of constructing the AudioRecord. This must be checked for successful initialization * before using any AudioRecord API (except for set()), because using * an uninitialized AudioRecord produces undefined results. * See set() method above for possible return codes. @@ -221,7 +229,7 @@ public: status_t start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE, int triggerSession = 0); - /* Stop a track. If set, the callback will cease being called. Note that obtainBuffer() still + /* Stop a track. The callback will cease being called. Note that obtainBuffer() still * works and will drain buffers until the pool is exhausted, and then will return WOULD_BLOCK. */ void stop(); @@ -232,11 +240,16 @@ public: */ uint32_t getSampleRate() const { return mSampleRate; } + /* Return the notification frame count. + * This is approximately how often the callback is invoked, for transfer type TRANSFER_CALLBACK. + */ + size_t notificationFrames() const { return mNotificationFramesAct; } + /* Sets marker position. When record reaches the number of frames specified, * a callback with event type EVENT_MARKER is called. Calling setMarkerPosition * with marker == 0 cancels marker notification callback. * To set a marker at a position which would compute as 0, - * a workaround is to the set the marker at a nearby position such as ~0 or 1. + * a workaround is to set the marker at a nearby position such as ~0 or 1. * If the AudioRecord has been opened with no callback function associated, * the operation will fail. * @@ -378,8 +391,10 @@ public: * returning the current value by this function call. Such loss typically occurs when the * user space process is blocked longer than the capacity of audio driver buffers. * Units: the number of input audio frames. + * FIXME The side-effect of resetting the counter may be incompatible with multi-client. + * Consider making it more like AudioTrack::getUnderrunFrames which doesn't have side effects. */ - unsigned int getInputFramesLost() const; + uint32_t getInputFramesLost() const; private: /* copying audio record objects is not allowed */ @@ -412,6 +427,7 @@ private: bool mPaused; // whether thread is requested to pause at next loop entry bool mPausedInt; // whether thread internally requests pause nsecs_t mPausedNs; // if mPausedInt then associated timeout, otherwise ignored + bool mIgnoreNextPausedInt; // whether to ignore next mPausedInt request }; // body of AudioRecordThread::threadLoop() @@ -422,9 +438,10 @@ private: // NS_INACTIVE inactive so don't run again until re-started // NS_NEVER never again static const nsecs_t NS_WHENEVER = -1, NS_INACTIVE = -2, NS_NEVER = -3; - nsecs_t processAudioBuffer(const sp<AudioRecordThread>& thread); + nsecs_t processAudioBuffer(); // caller must hold lock on mLock for all _l methods + status_t openRecord_l(size_t epoch); // FIXME enum is faster than strcmp() for parameter 'from' @@ -444,14 +461,16 @@ private: // for notification APIs uint32_t mNotificationFramesReq; // requested number of frames between each // notification callback + // as specified in constructor or set() uint32_t mNotificationFramesAct; // actual number of frames between each // notification callback - bool mRefreshRemaining; // processAudioBuffer() should refresh next 2 + bool mRefreshRemaining; // processAudioBuffer() should refresh + // mRemainingFrames and mRetryOnPartialBuffer // These are private to processAudioBuffer(), and are not protected by a lock uint32_t mRemainingFrames; // number of frames to request in obtainBuffer() bool mRetryOnPartialBuffer; // sleep and retry after partial obtainBuffer() - int mObservedSequence; // last observed value of mSequence + uint32_t mObservedSequence; // last observed value of mSequence uint32_t mMarkerPosition; // in wrapping (overflow) frame units bool mMarkerReached; @@ -460,9 +479,13 @@ private: status_t mStatus; + size_t mFrameCount; // corresponds to current IAudioRecord, value is + // reported back by AudioFlinger to the client + size_t mReqFrameCount; // frame count to request the first or next time + // a new IAudioRecord is needed, non-decreasing + // constant after constructor or set() uint32_t mSampleRate; - size_t mFrameCount; audio_format_t mFormat; uint32_t mChannelCount; size_t mFrameSize; // app-level frame size == AudioFlinger frame size @@ -473,12 +496,13 @@ private: int mSessionId; transfer_type mTransfer; - audio_io_handle_t mInput; // returned by AudioSystem::getInput() - - // may be changed if IAudioRecord object is re-created + // Next 5 fields may be changed if IAudioRecord is re-created, but always != 0 + // provided the initial set() was successful sp<IAudioRecord> mAudioRecord; sp<IMemory> mCblkMemory; audio_track_cblk_t* mCblk; // re-load after mLock.unlock() + sp<IMemory> mBufferMemory; + audio_io_handle_t mInput; // returned by AudioSystem::getInput() int mPreviousPriority; // before start() SchedPolicy mPreviousSchedulingGroup; diff --git a/include/media/AudioResamplerPublic.h b/include/media/AudioResamplerPublic.h new file mode 100644 index 0000000..97847a0 --- /dev/null +++ b/include/media/AudioResamplerPublic.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_AUDIO_RESAMPLER_PUBLIC_H +#define ANDROID_AUDIO_RESAMPLER_PUBLIC_H + +// AUDIO_RESAMPLER_DOWN_RATIO_MAX is the maximum ratio between the original +// audio sample rate and the target rate when downsampling, +// as permitted in the audio framework, e.g. AudioTrack and AudioFlinger. +// In practice, it is not recommended to downsample more than 6:1 +// for best audio quality, even though the audio framework permits a larger +// downsampling ratio. +// TODO: replace with an API +#define AUDIO_RESAMPLER_DOWN_RATIO_MAX 256 + +#endif // ANDROID_AUDIO_RESAMPLER_PUBLIC_H diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index 4c22412..dd63a23 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -19,6 +19,7 @@ #include <hardware/audio_effect.h> #include <media/IAudioFlingerClient.h> +#include <media/IAudioPolicyServiceClient.h> #include <system/audio.h> #include <system/audio_policy.h> #include <utils/Errors.h> @@ -67,20 +68,24 @@ public: // returns true in *state if tracks are active on the specified stream or have been active // in the past inPastMs milliseconds - static status_t isStreamActive(audio_stream_type_t stream, bool *state, uint32_t inPastMs = 0); + static status_t isStreamActive(audio_stream_type_t stream, bool *state, uint32_t inPastMs); // returns true in *state if tracks are active for what qualifies as remote playback // on the specified stream or have been active in the past inPastMs milliseconds. Remote // playback isn't mutually exclusive with local playback. static status_t isStreamActiveRemotely(audio_stream_type_t stream, bool *state, - uint32_t inPastMs = 0); + uint32_t inPastMs); // returns true in *state if a recorder is currently recording with the specified source static status_t isSourceActive(audio_source_t source, bool *state); // set/get audio hardware parameters. The function accepts a list of parameters // key value pairs in the form: key1=value1;key2=value2;... // Some keys are reserved for standard parameters (See AudioParameter class). + // The versions with audio_io_handle_t are intended for internal media framework use only. static status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs); static String8 getParameters(audio_io_handle_t ioHandle, const String8& keys); + // The versions without audio_io_handle_t are intended for JNI. + static status_t setParameters(const String8& keyValuePairs); + static String8 getParameters(const String8& keys); static void setErrorCallback(audio_error_callback cb); @@ -90,36 +95,37 @@ public: static float linearToLog(int volume); static int logToLinear(float volume); + // Returned samplingRate and frameCount output values are guaranteed + // to be non-zero if status == NO_ERROR static status_t getOutputSamplingRate(uint32_t* samplingRate, - audio_stream_type_t stream = AUDIO_STREAM_DEFAULT); + audio_stream_type_t stream); + static status_t getOutputSamplingRateForAttr(uint32_t* samplingRate, + const audio_attributes_t *attr); static status_t getOutputFrameCount(size_t* frameCount, - audio_stream_type_t stream = AUDIO_STREAM_DEFAULT); + audio_stream_type_t stream); static status_t getOutputLatency(uint32_t* latency, - audio_stream_type_t stream = AUDIO_STREAM_DEFAULT); + audio_stream_type_t stream); static status_t getSamplingRate(audio_io_handle_t output, - audio_stream_type_t streamType, uint32_t* samplingRate); // returns the number of frames per audio HAL write buffer. Corresponds to - // audio_stream->get_buffer_size()/audio_stream_frame_size() + // audio_stream->get_buffer_size()/audio_stream_out_frame_size() static status_t getFrameCount(audio_io_handle_t output, - audio_stream_type_t stream, size_t* frameCount); // returns the audio output stream latency in ms. Corresponds to // audio_stream_out->get_latency() static status_t getLatency(audio_io_handle_t output, - audio_stream_type_t stream, uint32_t* latency); static bool routedToA2dpOutput(audio_stream_type_t streamType); + // return status NO_ERROR implies *buffSize > 0 static status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, size_t* buffSize); static status_t setVoiceVolume(float volume); // return the number of audio frames written by AudioFlinger to audio HAL and - // audio dsp to DAC since the output on which the specified stream is playing - // has exited standby. + // audio dsp to DAC since the specified output I/O handle has exited standby. // returned status (from utils/Errors.h) can be: // - NO_ERROR: successful operation, halFrames and dspFrames point to valid data // - INVALID_OPERATION: Not supported on current hardware platform @@ -128,15 +134,25 @@ public: // necessary to check returned status before using the returned values. static status_t getRenderPosition(audio_io_handle_t output, uint32_t *halFrames, - uint32_t *dspFrames, - audio_stream_type_t stream = AUDIO_STREAM_DEFAULT); + uint32_t *dspFrames); // return the number of input frames lost by HAL implementation, or 0 if the handle is invalid - static size_t getInputFramesLost(audio_io_handle_t ioHandle); + static uint32_t getInputFramesLost(audio_io_handle_t ioHandle); + + // Allocate a new unique ID for use as an audio session ID or I/O handle. + // If unable to contact AudioFlinger, returns AUDIO_UNIQUE_ID_ALLOCATE instead. + // FIXME If AudioFlinger were to ever exhaust the unique ID namespace, + // this method could fail by returning either AUDIO_UNIQUE_ID_ALLOCATE + // or an unspecified existing unique ID. + static audio_unique_id_t newAudioUniqueId(); - static int newAudioSessionId(); - static void acquireAudioSessionId(int audioSession); - static void releaseAudioSessionId(int audioSession); + static void acquireAudioSessionId(int audioSession, pid_t pid); + static void releaseAudioSessionId(int audioSession, pid_t pid); + + // Get the HW synchronization source used for an audio session. + // Return a valid source or AUDIO_HW_SYNC_INVALID if an error occurs + // or no HW sync source is used. + static audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId); // types of io configuration change events received with ioConfigChanged() enum io_config_event { @@ -155,7 +171,8 @@ public: class OutputDescriptor { public: OutputDescriptor() - : samplingRate(0), format(AUDIO_FORMAT_DEFAULT), channelMask(0), frameCount(0), latency(0) {} + : samplingRate(0), format(AUDIO_FORMAT_DEFAULT), channelMask(0), frameCount(0), latency(0) + {} uint32_t samplingRate; audio_format_t format; @@ -193,27 +210,44 @@ public: static status_t setPhoneState(audio_mode_t state); static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config); static audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage); + + // Client must successfully hand off the handle reference to AudioFlinger via createTrack(), + // or release it with releaseOutput(). static audio_io_handle_t getOutput(audio_stream_type_t stream, uint32_t samplingRate = 0, audio_format_t format = AUDIO_FORMAT_DEFAULT, audio_channel_mask_t channelMask = AUDIO_CHANNEL_OUT_STEREO, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, const audio_offload_info_t *offloadInfo = NULL); + static audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr, + uint32_t samplingRate = 0, + audio_format_t format = AUDIO_FORMAT_DEFAULT, + audio_channel_mask_t channelMask = AUDIO_CHANNEL_OUT_STEREO, + audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, + const audio_offload_info_t *offloadInfo = NULL); static status_t startOutput(audio_io_handle_t output, audio_stream_type_t stream, - int session = 0); + int session); static status_t stopOutput(audio_io_handle_t output, audio_stream_type_t stream, - int session = 0); + int session); static void releaseOutput(audio_io_handle_t output); + + // Client must successfully hand off the handle reference to AudioFlinger via openRecord(), + // or release it with releaseInput(). static audio_io_handle_t getInput(audio_source_t inputSource, - uint32_t samplingRate = 0, - audio_format_t format = AUDIO_FORMAT_DEFAULT, - audio_channel_mask_t channelMask = AUDIO_CHANNEL_IN_MONO, - int sessionId = 0); - static status_t startInput(audio_io_handle_t input); - static status_t stopInput(audio_io_handle_t input); - static void releaseInput(audio_io_handle_t input); + uint32_t samplingRate, + audio_format_t format, + audio_channel_mask_t channelMask, + int sessionId, + audio_input_flags_t); + + static status_t startInput(audio_io_handle_t input, + audio_session_t session); + static status_t stopInput(audio_io_handle_t input, + audio_session_t session); + static void releaseInput(audio_io_handle_t input, + audio_session_t session); static status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax); @@ -255,8 +289,54 @@ public: // check presence of audio flinger service. // returns NO_ERROR if binding to service succeeds, DEAD_OBJECT otherwise static status_t checkAudioFlinger(); + + /* List available audio ports and their attributes */ + static status_t listAudioPorts(audio_port_role_t role, + audio_port_type_t type, + unsigned int *num_ports, + struct audio_port *ports, + unsigned int *generation); + + /* Get attributes for a given audio port */ + static status_t getAudioPort(struct audio_port *port); + + /* Create an audio patch between several source and sink ports */ + static status_t createAudioPatch(const struct audio_patch *patch, + audio_patch_handle_t *handle); + + /* Release an audio patch */ + static status_t releaseAudioPatch(audio_patch_handle_t handle); + + /* List existing audio patches */ + static status_t listAudioPatches(unsigned int *num_patches, + struct audio_patch *patches, + unsigned int *generation); + /* Set audio port configuration */ + static status_t setAudioPortConfig(const struct audio_port_config *config); + + + static status_t acquireSoundTriggerSession(audio_session_t *session, + audio_io_handle_t *ioHandle, + audio_devices_t *device); + static status_t releaseSoundTriggerSession(audio_session_t session); + // ---------------------------------------------------------------------------- + class AudioPortCallback : public RefBase + { + public: + + AudioPortCallback() {} + virtual ~AudioPortCallback() {} + + virtual void onAudioPortListUpdate() = 0; + virtual void onAudioPatchListUpdate() = 0; + virtual void onServiceDied() = 0; + + }; + + static void setAudioPortCallback(sp<AudioPortCallback> callBack); + private: class AudioFlingerClient: public IBinder::DeathRecipient, public BnAudioFlingerClient @@ -275,7 +355,8 @@ private: virtual void ioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2); }; - class AudioPolicyServiceClient: public IBinder::DeathRecipient + class AudioPolicyServiceClient: public IBinder::DeathRecipient, + public BnAudioPolicyServiceClient { public: AudioPolicyServiceClient() { @@ -283,6 +364,10 @@ private: // DeathRecipient virtual void binderDied(const wp<IBinder>& who); + + // IAudioPolicyServiceClient + virtual void onAudioPortListUpdate(); + virtual void onAudioPatchListUpdate(); }; static sp<AudioFlingerClient> gAudioFlingerClient; @@ -302,11 +387,11 @@ private: static sp<IAudioPolicyService> gAudioPolicyService; - // mapping between stream types and outputs - static DefaultKeyedVector<audio_stream_type_t, audio_io_handle_t> gStreamOutputMap; // list of output descriptors containing cached parameters // (sampling rate, framecount, channel count...) static DefaultKeyedVector<audio_io_handle_t, OutputDescriptor *> gOutputs; + + static sp<AudioPortCallback> gAudioPortCallback; }; }; // namespace android diff --git a/include/media/AudioTimestamp.h b/include/media/AudioTimestamp.h index c29c7e5..99e9c3e 100644 --- a/include/media/AudioTimestamp.h +++ b/include/media/AudioTimestamp.h @@ -19,6 +19,8 @@ #include <time.h> +namespace android { + class AudioTimestamp { public: AudioTimestamp() : mPosition(0) { @@ -30,4 +32,6 @@ public: struct timespec mTime; // corresponding CLOCK_MONOTONIC when frame is expected to present }; +} // namespace + #endif // ANDROID_AUDIO_TIMESTAMP_H diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index 4736369..b5256f0 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -27,7 +27,7 @@ namespace android { // ---------------------------------------------------------------------------- -class audio_track_cblk_t; +struct audio_track_cblk_t; class AudioTrackClientProxy; class StaticAudioTrackClientProxy; @@ -36,11 +36,6 @@ class StaticAudioTrackClientProxy; class AudioTrack : public RefBase { public: - enum channel_index { - MONO = 0, - LEFT = 0, - RIGHT = 1 - }; /* Events used by AudioTrack callback function (callback_t). * Keep in sync with frameworks/base/media/java/android/media/AudioTrack.java NATIVE_EVENT_*. @@ -82,6 +77,7 @@ public: // (currently ignored, but will make the primary field in future) size_t size; // input/output in bytes == frameCount * frameSize + // on input it is unused // on output is the number of bytes actually filled // FIXME this is redundant with respect to frameCount, // and TRANSFER_OBTAIN mode is broken for 8-bit data @@ -91,7 +87,7 @@ public: void* raw; short* i16; // signed 16-bit int8_t* i8; // unsigned 8-bit, offset by 0x80 - }; + }; // input: unused, output: pointer to buffer }; /* As a convenience, if a callback is supplied, a handler thread @@ -123,6 +119,8 @@ public: * - NO_ERROR: successful operation * - NO_INIT: audio server or audio hardware not initialized * - BAD_VALUE: unsupported configuration + * frameCount is guaranteed to be non-zero if status is NO_ERROR, + * and is undefined otherwise. */ static status_t getMinFrameCount(size_t* frameCount, @@ -156,9 +154,10 @@ public: * streamType: Select the type of audio stream this track is attached to * (e.g. AUDIO_STREAM_MUSIC). * sampleRate: Data source sampling rate in Hz. - * format: Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed - * 16 bits per sample). - * channelMask: Channel mask. + * format: Audio format. For mixed tracks, any PCM format supported by server is OK + * or AUDIO_FORMAT_PCM_8_BIT which is handled on client side. For direct + * and offloaded tracks, the possible format(s) depends on the output sink. + * channelMask: Channel mask, such that audio_is_output_channel(channelMask) is true. * frameCount: Minimum size of track PCM buffer in frames. This defines the * application's contribution to the * latency of the track. The actual size selected by the AudioTrack could be @@ -180,15 +179,17 @@ public: uint32_t sampleRate, audio_format_t format, audio_channel_mask_t, - int frameCount = 0, + size_t frameCount = 0, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, callback_t cbf = NULL, void* user = NULL, - int notificationFrames = 0, - int sessionId = 0, + uint32_t notificationFrames = 0, + int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, const audio_offload_info_t *offloadInfo = NULL, - int uid = -1); + int uid = -1, + pid_t pid = -1, + const audio_attributes_t* pAttributes = NULL); /* Creates an audio track and registers it with AudioFlinger. * With this constructor, the track is configured for static buffer mode. @@ -209,11 +210,13 @@ public: audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, callback_t cbf = NULL, void* user = NULL, - int notificationFrames = 0, - int sessionId = 0, + uint32_t notificationFrames = 0, + int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, const audio_offload_info_t *offloadInfo = NULL, - int uid = -1); + int uid = -1, + pid_t pid = -1, + const audio_attributes_t* pAttributes = NULL); /* Terminates the AudioTrack and unregisters it from AudioFlinger. * Also destroys all resources associated with the AudioTrack. @@ -241,17 +244,19 @@ public: uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, - int frameCount = 0, + size_t frameCount = 0, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, callback_t cbf = NULL, void* user = NULL, - int notificationFrames = 0, + uint32_t notificationFrames = 0, const sp<IMemory>& sharedBuffer = 0, bool threadCanCallJava = false, - int sessionId = 0, + int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, const audio_offload_info_t *offloadInfo = NULL, - int uid = -1); + int uid = -1, + pid_t pid = -1, + const audio_attributes_t* pAttributes = NULL); /* Result of constructing the AudioTrack. This must be checked for successful initialization * before using any AudioTrack API (except for set()), because using @@ -279,7 +284,7 @@ public: size_t frameSize() const { return mFrameSize; } uint32_t channelCount() const { return mChannelCount; } - uint32_t frameCount() const { return mFrameCount; } + size_t frameCount() const { return mFrameCount; } /* Return the static buffer specified in constructor or set(), or 0 for streaming mode */ sp<IMemory> sharedBuffer() const { return mSharedBuffer; } @@ -336,7 +341,7 @@ public: */ status_t setSampleRate(uint32_t sampleRate); - /* Return current source sample rate in Hz, or 0 if unknown */ + /* Return current source sample rate in Hz */ uint32_t getSampleRate() const; /* Enables looping and sets the start and end points of looping. @@ -361,7 +366,7 @@ public: /* Sets marker position. When playback reaches the number of frames specified, a callback with * event type EVENT_MARKER is called. Calling setMarkerPosition with marker == 0 cancels marker * notification callback. To set a marker at a position which would compute as 0, - * a workaround is to the set the marker at a nearby position such as ~0 or 1. + * a workaround is to set the marker at a nearby position such as ~0 or 1. * If the AudioTrack has been opened with no callback function associated, the operation will * fail. * @@ -425,7 +430,7 @@ public: * - NO_ERROR: successful operation * - BAD_VALUE: position is NULL */ - status_t getPosition(uint32_t *position) const; + status_t getPosition(uint32_t *position); /* For static buffer mode only, this returns the current playback position in frames * relative to start of buffer. It is analogous to the position units used by @@ -450,9 +455,10 @@ public: * none. * * Returned value: - * handle on audio hardware output + * handle on audio hardware output, or AUDIO_IO_HANDLE_NONE if the + * track needed to be re-created but that failed */ - audio_io_handle_t getOutput(); + audio_io_handle_t getOutput() const; /* Returns the unique session ID associated with this track. * @@ -528,15 +534,6 @@ private: struct timespec *elapsed = NULL, size_t *nonContig = NULL); public: -//EL_FIXME to be reconciled with new obtainBuffer() return codes and control block proxy -// enum { -// NO_MORE_BUFFERS = 0x80000001, // same name in AudioFlinger.h, ok to be different value -// TEAR_DOWN = 0x80000002, -// STOPPED = 1, -// STREAM_END_WAIT, -// STREAM_END -// }; - /* Release a filled buffer of "audioBuffer->frameCount" frames for AudioFlinger to process. */ // FIXME make private when obtainBuffer() for TRANSFER_OBTAIN is removed void releaseBuffer(Buffer* audioBuffer); @@ -551,8 +548,11 @@ public: * WOULD_BLOCK when obtainBuffer() returns same, or * AudioTrack was stopped during the write * or any other error code returned by IAudioTrack::start() or restoreTrack_l(). + * Default behavior is to only return until all data has been transferred. Set 'blocking' to + * false for the method to return immediately without waiting to try multiple times to write + * the full content of the buffer. */ - ssize_t write(const void* buffer, size_t size); + ssize_t write(const void* buffer, size_t size, bool blocking = true); /* * Dumps the state of an audio track. @@ -566,7 +566,7 @@ public: uint32_t getUnderrunFrames() const; /* Get the flags */ - audio_output_flags_t getFlags() const { return mFlags; } + audio_output_flags_t getFlags() const { AutoMutex _l(mLock); return mFlags; } /* Set parameters - only possible when using direct output */ status_t setParameters(const String8& keyValuePairs); @@ -580,7 +580,15 @@ public: * Caution: calling this method too often may be inefficient; * if you need a high resolution mapping between frame position and presentation time, * consider implementing that at application level, based on the low resolution timestamps. - * Returns NO_ERROR if timestamp is valid. + * Returns NO_ERROR if timestamp is valid. + * WOULD_BLOCK if called in STOPPED or FLUSHED state, or if called immediately after + * start/ACTIVE, when the number of frames consumed is less than the + * overall hardware latency to physical output. In WOULD_BLOCK cases, + * one might poll again, or use getPosition(), or use 0 position and + * current time for the timestamp. + * INVALID_OPERATION if called on a FastTrack, wrong state, or some other error. + * + * The timestamp parameter is undefined on return, if status is not NO_ERROR. */ status_t getTimestamp(AudioTimestamp& timestamp); @@ -589,6 +597,11 @@ protected: AudioTrack(const AudioTrack& other); AudioTrack& operator = (const AudioTrack& other); + void setAttributesFromStreamType(audio_stream_type_t streamType); + void setStreamTypeFromAttributes(audio_attributes_t& aa); + /* paa is guaranteed non-NULL */ + bool isValidAttributes(const audio_attributes_t *paa); + /* a small internal class to handle the callback */ class AudioTrackThread : public Thread { @@ -626,53 +639,63 @@ protected: // NS_INACTIVE inactive so don't run again until re-started // NS_NEVER never again static const nsecs_t NS_WHENEVER = -1, NS_INACTIVE = -2, NS_NEVER = -3; - nsecs_t processAudioBuffer(const sp<AudioTrackThread>& thread); - status_t processStreamEnd(int32_t waitCount); + nsecs_t processAudioBuffer(); + bool isOffloaded() const; + bool isDirect() const; + bool isOffloadedOrDirect() const; // caller must hold lock on mLock for all _l methods - status_t createTrack_l(audio_stream_type_t streamType, - uint32_t sampleRate, - audio_format_t format, - size_t frameCount, - audio_output_flags_t flags, - const sp<IMemory>& sharedBuffer, - audio_io_handle_t output, - size_t epoch); + status_t createTrack_l(); // can only be called when mState != STATE_ACTIVE void flush_l(); void setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount); - audio_io_handle_t getOutput_l(); // FIXME enum is faster than strcmp() for parameter 'from' status_t restoreTrack_l(const char *from); - bool isOffloaded() const + bool isOffloaded_l() const { return (mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0; } - // Next 3 fields may be changed if IAudioTrack is re-created, but always != 0 + bool isOffloadedOrDirect_l() const + { return (mFlags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD| + AUDIO_OUTPUT_FLAG_DIRECT)) != 0; } + + bool isDirect_l() const + { return (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0; } + + // increment mPosition by the delta of mServer, and return new value of mPosition + uint32_t updateAndGetPosition_l(); + + // Next 4 fields may be changed if IAudioTrack is re-created, but always != 0 sp<IAudioTrack> mAudioTrack; sp<IMemory> mCblkMemory; audio_track_cblk_t* mCblk; // re-load after mLock.unlock() + audio_io_handle_t mOutput; // returned by AudioSystem::getOutput() sp<AudioTrackThread> mAudioTrackThread; + float mVolume[2]; float mSendLevel; mutable uint32_t mSampleRate; // mutable because getSampleRate() can update it. - size_t mFrameCount; // corresponds to current IAudioTrack - size_t mReqFrameCount; // frame count to request the next time a new - // IAudioTrack is needed - + size_t mFrameCount; // corresponds to current IAudioTrack, value is + // reported back by AudioFlinger to the client + size_t mReqFrameCount; // frame count to request the first or next time + // a new IAudioTrack is needed, non-decreasing // constant after constructor or set() audio_format_t mFormat; // as requested by client, not forced to 16-bit audio_stream_type_t mStreamType; uint32_t mChannelCount; audio_channel_mask_t mChannelMask; + sp<IMemory> mSharedBuffer; transfer_type mTransfer; + audio_offload_info_t mOffloadInfoCopy; + const audio_offload_info_t* mOffloadInfo; + audio_attributes_t mAttributes; // mFrameSize is equal to mFrameSizeAF for non-PCM or 16-bit PCM data. For 8-bit PCM data, it's // twice as large as mFrameSize because data is expanded to 16-bit before it's stored in buffer. @@ -705,21 +728,39 @@ protected: uint32_t mNotificationFramesAct; // actual number of frames between each // notification callback, // at initial source sample rate - bool mRefreshRemaining; // processAudioBuffer() should refresh next 2 + bool mRefreshRemaining; // processAudioBuffer() should refresh + // mRemainingFrames and mRetryOnPartialBuffer // These are private to processAudioBuffer(), and are not protected by a lock uint32_t mRemainingFrames; // number of frames to request in obtainBuffer() bool mRetryOnPartialBuffer; // sleep and retry after partial obtainBuffer() uint32_t mObservedSequence; // last observed value of mSequence - sp<IMemory> mSharedBuffer; uint32_t mLoopPeriod; // in frames, zero means looping is disabled + uint32_t mMarkerPosition; // in wrapping (overflow) frame units bool mMarkerReached; uint32_t mNewPosition; // in frames uint32_t mUpdatePeriod; // in frames, zero means no EVENT_NEW_POS + uint32_t mServer; // in frames, last known mProxy->getPosition() + // which is count of frames consumed by server, + // reset by new IAudioTrack, + // whether it is reset by stop() is TBD + uint32_t mPosition; // in frames, like mServer except continues + // monotonically after new IAudioTrack, + // and could be easily widened to uint64_t + uint32_t mReleased; // in frames, count of frames released to server + // but not necessarily consumed by server, + // reset by stop() but continues monotonically + // after new IAudioTrack to restore mPosition, + // and could be easily widened to uint64_t + int64_t mStartUs; // the start time after flush or stop. + // only used for offloaded and direct tracks. audio_output_flags_t mFlags; + // const after set(), except for bits AUDIO_OUTPUT_FLAG_FAST and AUDIO_OUTPUT_FLAG_OFFLOAD. + // mLock must be held to read or write those bits reliably. + int mSessionId; int mAuxEffectId; @@ -739,7 +780,6 @@ protected: sp<AudioTrackClientProxy> mProxy; // primary owner of the memory bool mInUnderrun; // whether track is currently in underrun state - String8 mName; // server's name for this IAudioTrack uint32_t mPausedPosition; private: @@ -754,8 +794,8 @@ private: sp<DeathNotifier> mDeathNotifier; uint32_t mSequence; // incremented for each new IAudioTrack attempt - audio_io_handle_t mOutput; // cached output io handle int mClientUid; + pid_t mClientPid; }; class TimedAudioTrack : public AudioTrack diff --git a/include/media/CharacterEncodingDetector.h b/include/media/CharacterEncodingDetector.h new file mode 100644 index 0000000..deaa377 --- /dev/null +++ b/include/media/CharacterEncodingDetector.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _CHARACTER_ENCODING_DETECTOR_H +#define _CHARACTER_ENCODING_DETECTOR_H + +#include <media/mediascanner.h> + +#include "StringArray.h" + +#include "unicode/ucnv.h" +#include "unicode/ucsdet.h" +#include "unicode/ustring.h" + +namespace android { + +class CharacterEncodingDetector { + + public: + CharacterEncodingDetector(); + ~CharacterEncodingDetector(); + + void addTag(const char *name, const char *value); + size_t size(); + + void detectAndConvert(); + status_t getTag(int index, const char **name, const char**value); + + private: + const UCharsetMatch *getPreferred( + const char *input, size_t len, + const UCharsetMatch** ucma, size_t matches, + bool *goodmatch, int *highestmatch); + + bool isFrequent(const uint16_t *values, uint32_t c); + + // cached name and value strings, for native encoding support. + // TODO: replace these with byte blob arrays that don't require the data to be + // singlenullbyte-terminated + StringArray mNames; + StringArray mValues; + + UConverter* mUtf8Conv; +}; + + + +}; // namespace android + +#endif diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index 282f275..31a14f0 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -50,6 +50,7 @@ public: TRACK_TIMED = 1, // client requests a TimedAudioTrack TRACK_FAST = 2, // client requests a fast AudioTrack or AudioRecord TRACK_OFFLOAD = 4, // client requests offload to hw codec + TRACK_DIRECT = 8, // client requests a direct output }; typedef uint32_t track_flags_t; @@ -64,37 +65,39 @@ public: uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, - size_t frameCount, + size_t *pFrameCount, track_flags_t *flags, const sp<IMemory>& sharedBuffer, + // On successful return, AudioFlinger takes over the handle + // reference and will release it when the track is destroyed. + // However on failure, the client is responsible for release. audio_io_handle_t output, pid_t tid, // -1 means unused, otherwise must be valid non-0 int *sessionId, - // input: ignored - // output: server's description of IAudioTrack for display in logs. - // Don't attempt to parse, as the format could change. - String8& name, int clientUid, status_t *status) = 0; virtual sp<IAudioRecord> openRecord( + // On successful return, AudioFlinger takes over the handle + // reference and will release it when the track is destroyed. + // However on failure, the client is responsible for release. audio_io_handle_t input, uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, - size_t frameCount, + size_t *pFrameCount, track_flags_t *flags, pid_t tid, // -1 means unused, otherwise must be valid non-0 int *sessionId, + size_t *notificationFrames, + sp<IMemory>& cblk, + sp<IMemory>& buffers, // return value 0 means it follows cblk status_t *status) = 0; /* query the audio hardware state. This state never changes, * and therefore can be cached. */ virtual uint32_t sampleRate(audio_io_handle_t output) const = 0; -#if 0 - virtual int channelCount(audio_io_handle_t output) const = 0; -#endif virtual audio_format_t format(audio_io_handle_t output) const = 0; virtual size_t frameCount(audio_io_handle_t output) const = 0; @@ -142,28 +145,29 @@ public: virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask) const = 0; - virtual audio_io_handle_t openOutput(audio_module_handle_t module, - audio_devices_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - audio_channel_mask_t *pChannelMask, - uint32_t *pLatencyMs, - audio_output_flags_t flags, - const audio_offload_info_t *offloadInfo = NULL) = 0; + virtual status_t openOutput(audio_module_handle_t module, + audio_io_handle_t *output, + audio_config_t *config, + audio_devices_t *devices, + const String8& address, + uint32_t *latencyMs, + audio_output_flags_t flags) = 0; virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2) = 0; virtual status_t closeOutput(audio_io_handle_t output) = 0; virtual status_t suspendOutput(audio_io_handle_t output) = 0; virtual status_t restoreOutput(audio_io_handle_t output) = 0; - virtual audio_io_handle_t openInput(audio_module_handle_t module, - audio_devices_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - audio_channel_mask_t *pChannelMask) = 0; + virtual status_t openInput(audio_module_handle_t module, + audio_io_handle_t *input, + audio_config_t *config, + audio_devices_t *device, + const String8& address, + audio_source_t source, + audio_input_flags_t flags) = 0; virtual status_t closeInput(audio_io_handle_t input) = 0; - virtual status_t setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output) = 0; + virtual status_t invalidateStream(audio_stream_type_t stream) = 0; virtual status_t setVoiceVolume(float volume) = 0; @@ -172,10 +176,10 @@ public: virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const = 0; - virtual int newAudioSessionId() = 0; + virtual audio_unique_id_t newAudioUniqueId() = 0; - virtual void acquireAudioSessionId(int audioSession) = 0; - virtual void releaseAudioSessionId(int audioSession) = 0; + virtual void acquireAudioSessionId(int audioSession, pid_t pid) = 0; + virtual void releaseAudioSessionId(int audioSession, pid_t pid) = 0; virtual status_t queryNumberEffects(uint32_t *numEffects) const = 0; @@ -188,6 +192,7 @@ public: effect_descriptor_t *pDesc, const sp<IEffectClient>& client, int32_t priority, + // AudioFlinger doesn't take over handle reference from client audio_io_handle_t output, int sessionId, status_t *status, @@ -209,6 +214,29 @@ public: // and should be called at most once. For a definition of what "low RAM" means, see // android.app.ActivityManager.isLowRamDevice(). virtual status_t setLowRamDevice(bool isLowRamDevice) = 0; + + /* List available audio ports and their attributes */ + virtual status_t listAudioPorts(unsigned int *num_ports, + struct audio_port *ports) = 0; + + /* Get attributes for a given audio port */ + virtual status_t getAudioPort(struct audio_port *port) = 0; + + /* Create an audio patch between several source and sink ports */ + virtual status_t createAudioPatch(const struct audio_patch *patch, + audio_patch_handle_t *handle) = 0; + + /* Release an audio patch */ + virtual status_t releaseAudioPatch(audio_patch_handle_t handle) = 0; + + /* List existing audio patches */ + virtual status_t listAudioPatches(unsigned int *num_patches, + struct audio_patch *patches) = 0; + /* Set audio port configuration */ + virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0; + + /* Get the HW synchronization source used for an audio session */ + virtual audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId) = 0; }; diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h index 09b9ea6..c251439 100644 --- a/include/media/IAudioPolicyService.h +++ b/include/media/IAudioPolicyService.h @@ -25,6 +25,7 @@ #include <utils/Errors.h> #include <binder/IInterface.h> #include <media/AudioSystem.h> +#include <media/IAudioPolicyServiceClient.h> #include <system/audio_policy.h> @@ -55,6 +56,12 @@ public: audio_channel_mask_t channelMask = 0, audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, const audio_offload_info_t *offloadInfo = NULL) = 0; + virtual audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr, + uint32_t samplingRate = 0, + audio_format_t format = AUDIO_FORMAT_DEFAULT, + audio_channel_mask_t channelMask = 0, + audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, + const audio_offload_info_t *offloadInfo = NULL) = 0; virtual status_t startOutput(audio_io_handle_t output, audio_stream_type_t stream, int session = 0) = 0; @@ -63,13 +70,17 @@ public: int session = 0) = 0; virtual void releaseOutput(audio_io_handle_t output) = 0; virtual audio_io_handle_t getInput(audio_source_t inputSource, - uint32_t samplingRate = 0, - audio_format_t format = AUDIO_FORMAT_DEFAULT, - audio_channel_mask_t channelMask = 0, - int audioSession = 0) = 0; - virtual status_t startInput(audio_io_handle_t input) = 0; - virtual status_t stopInput(audio_io_handle_t input) = 0; - virtual void releaseInput(audio_io_handle_t input) = 0; + uint32_t samplingRate, + audio_format_t format, + audio_channel_mask_t channelMask, + int audioSession, + audio_input_flags_t flags) = 0; + virtual status_t startInput(audio_io_handle_t input, + audio_session_t session) = 0; + virtual status_t stopInput(audio_io_handle_t input, + audio_session_t session) = 0; + virtual void releaseInput(audio_io_handle_t input, + audio_session_t session) = 0; virtual status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax) = 0; @@ -99,6 +110,38 @@ public: // Check if offload is possible for given format, stream type, sample rate, // bit rate, duration, video and streaming or offload property is enabled virtual bool isOffloadSupported(const audio_offload_info_t& info) = 0; + + /* List available audio ports and their attributes */ + virtual status_t listAudioPorts(audio_port_role_t role, + audio_port_type_t type, + unsigned int *num_ports, + struct audio_port *ports, + unsigned int *generation) = 0; + + /* Get attributes for a given audio port */ + virtual status_t getAudioPort(struct audio_port *port) = 0; + + /* Create an audio patch between several source and sink ports */ + virtual status_t createAudioPatch(const struct audio_patch *patch, + audio_patch_handle_t *handle) = 0; + + /* Release an audio patch */ + virtual status_t releaseAudioPatch(audio_patch_handle_t handle) = 0; + + /* List existing audio patches */ + virtual status_t listAudioPatches(unsigned int *num_patches, + struct audio_patch *patches, + unsigned int *generation) = 0; + /* Set audio port configuration */ + virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0; + + virtual void registerClient(const sp<IAudioPolicyServiceClient>& client) = 0; + + virtual status_t acquireSoundTriggerSession(audio_session_t *session, + audio_io_handle_t *ioHandle, + audio_devices_t *device) = 0; + + virtual status_t releaseSoundTriggerSession(audio_session_t session) = 0; }; diff --git a/include/media/IAudioPolicyServiceClient.h b/include/media/IAudioPolicyServiceClient.h new file mode 100644 index 0000000..59df046 --- /dev/null +++ b/include/media/IAudioPolicyServiceClient.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IAUDIOPOLICYSERVICECLIENT_H +#define ANDROID_IAUDIOPOLICYSERVICECLIENT_H + + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <system/audio.h> + +namespace android { + +// ---------------------------------------------------------------------------- + +class IAudioPolicyServiceClient : public IInterface +{ +public: + DECLARE_META_INTERFACE(AudioPolicyServiceClient); + + // Notifies a change of audio port configuration. + virtual void onAudioPortListUpdate() = 0; + // Notifies a change of audio patch configuration. + virtual void onAudioPatchListUpdate() = 0; +}; + + +// ---------------------------------------------------------------------------- + +class BnAudioPolicyServiceClient : public BnInterface<IAudioPolicyServiceClient> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IAUDIOPOLICYSERVICECLIENT_H diff --git a/include/media/IAudioRecord.h b/include/media/IAudioRecord.h index eccc2ca..2003985 100644 --- a/include/media/IAudioRecord.h +++ b/include/media/IAudioRecord.h @@ -34,9 +34,6 @@ class IAudioRecord : public IInterface public: DECLARE_META_INTERFACE(AudioRecord); - /* get this tracks control block */ - virtual sp<IMemory> getCblk() const = 0; - /* After it's created the track is not active. Call start() to * make it active. */ diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h index 5c8a484..619ac78 100644 --- a/include/media/IAudioTrack.h +++ b/include/media/IAudioTrack.h @@ -88,7 +88,7 @@ public: /* Send parameters to the audio hardware */ virtual status_t setParameters(const String8& keyValuePairs) = 0; - /* Return NO_ERROR if timestamp is valid */ + /* Return NO_ERROR if timestamp is valid. timestamp is undefined otherwise. */ virtual status_t getTimestamp(AudioTimestamp& timestamp) = 0; /* Signal the playback thread for a change in control block */ diff --git a/include/media/IDrm.h b/include/media/IDrm.h index 5ef26af..68de87a 100644 --- a/include/media/IDrm.h +++ b/include/media/IDrm.h @@ -61,10 +61,16 @@ struct IDrm : public IInterface { virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId, KeyedVector<String8, String8> &infoMap) const = 0; - virtual status_t getProvisionRequest(Vector<uint8_t> &request, + virtual status_t getProvisionRequest(String8 const &certType, + String8 const &certAuthority, + Vector<uint8_t> &request, String8 &defaulUrl) = 0; - virtual status_t provideProvisionResponse(Vector<uint8_t> const &response) = 0; + virtual status_t provideProvisionResponse(Vector<uint8_t> const &response, + Vector<uint8_t> &certificate, + Vector<uint8_t> &wrappedKey) = 0; + + virtual status_t unprovisionDevice() = 0; virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0; @@ -107,6 +113,12 @@ struct IDrm : public IInterface { Vector<uint8_t> const &signature, bool &match) = 0; + virtual status_t signRSA(Vector<uint8_t> const &sessionId, + String8 const &algorithm, + Vector<uint8_t> const &message, + Vector<uint8_t> const &wrappedKey, + Vector<uint8_t> &signature) = 0; + virtual status_t setListener(const sp<IDrmClient>& listener) = 0; private: diff --git a/include/media/IMediaCodecList.h b/include/media/IMediaCodecList.h new file mode 100644 index 0000000..e93ea8b --- /dev/null +++ b/include/media/IMediaCodecList.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IMEDIACODECLIST_H +#define ANDROID_IMEDIACODECLIST_H + +#include <utils/Errors.h> // for status_t +#include <binder/IInterface.h> +#include <binder/Parcel.h> + +namespace android { + +struct MediaCodecInfo; + +class IMediaCodecList: public IInterface +{ +public: + DECLARE_META_INTERFACE(MediaCodecList); + + virtual size_t countCodecs() const = 0; + virtual sp<MediaCodecInfo> getCodecInfo(size_t index) const = 0; + + virtual ssize_t findCodecByType( + const char *type, bool encoder, size_t startIndex = 0) const = 0; + + virtual ssize_t findCodecByName(const char *name) const = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnMediaCodecList: public BnInterface<IMediaCodecList> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif // ANDROID_IMEDIACODECLIST_H diff --git a/include/media/IMediaHTTPConnection.h b/include/media/IMediaHTTPConnection.h new file mode 100644 index 0000000..2a63eb7 --- /dev/null +++ b/include/media/IMediaHTTPConnection.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_MEDIA_HTTP_CONNECTION_H_ + +#define I_MEDIA_HTTP_CONNECTION_H_ + +#include <binder/IInterface.h> +#include <media/stagefright/foundation/ABase.h> +#include <utils/KeyedVector.h> + +namespace android { + +struct IMediaHTTPConnection; + +/** MUST stay in sync with IMediaHTTPConnection.aidl */ + +struct IMediaHTTPConnection : public IInterface { + DECLARE_META_INTERFACE(MediaHTTPConnection); + + virtual bool connect( + const char *uri, const KeyedVector<String8, String8> *headers) = 0; + + virtual void disconnect() = 0; + virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0; + virtual off64_t getSize() = 0; + virtual status_t getMIMEType(String8 *mimeType) = 0; + virtual status_t getUri(String8 *uri) = 0; + +private: + DISALLOW_EVIL_CONSTRUCTORS(IMediaHTTPConnection); +}; + +} // namespace android + +#endif // I_MEDIA_HTTP_CONNECTION_H_ diff --git a/include/media/IMediaHTTPService.h b/include/media/IMediaHTTPService.h new file mode 100644 index 0000000..f66d6c8 --- /dev/null +++ b/include/media/IMediaHTTPService.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_MEDIA_HTTP_SERVICE_H_ + +#define I_MEDIA_HTTP_SERVICE_H_ + +#include <binder/IInterface.h> +#include <media/stagefright/foundation/ABase.h> + +namespace android { + +struct IMediaHTTPConnection; + +/** MUST stay in sync with IMediaHTTPService.aidl */ + +struct IMediaHTTPService : public IInterface { + DECLARE_META_INTERFACE(MediaHTTPService); + + virtual sp<IMediaHTTPConnection> makeHTTPConnection() = 0; + +private: + DISALLOW_EVIL_CONSTRUCTORS(IMediaHTTPService); +}; + +} // namespace android + +#endif // I_MEDIA_HTTP_SERVICE_H_ diff --git a/include/media/IMediaMetadataRetriever.h b/include/media/IMediaMetadataRetriever.h index 6dbb2d7..2529800 100644 --- a/include/media/IMediaMetadataRetriever.h +++ b/include/media/IMediaMetadataRetriever.h @@ -26,6 +26,8 @@ namespace android { +struct IMediaHTTPService; + class IMediaMetadataRetriever: public IInterface { public: @@ -33,6 +35,7 @@ public: virtual void disconnect() = 0; virtual status_t setDataSource( + const sp<IMediaHTTPService> &httpService, const char *srcUrl, const KeyedVector<String8, String8> *headers = NULL) = 0; diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h index 0cbd269..db62cd5 100644 --- a/include/media/IMediaPlayer.h +++ b/include/media/IMediaPlayer.h @@ -33,6 +33,7 @@ class Parcel; class Surface; class IStreamSource; class IGraphicBufferProducer; +struct IMediaHTTPService; class IMediaPlayer: public IInterface { @@ -41,8 +42,11 @@ public: virtual void disconnect() = 0; - virtual status_t setDataSource(const char *url, - const KeyedVector<String8, String8>* headers) = 0; + virtual status_t setDataSource( + const sp<IMediaHTTPService> &httpService, + const char *url, + const KeyedVector<String8, String8>* headers) = 0; + virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0; virtual status_t setDataSource(const sp<IStreamSource>& source) = 0; virtual status_t setVideoSurfaceTexture( diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h index 2998b37..d7e584a 100644 --- a/include/media/IMediaPlayerService.h +++ b/include/media/IMediaPlayerService.h @@ -34,6 +34,8 @@ namespace android { struct ICrypto; struct IDrm; struct IHDCP; +struct IMediaCodecList; +struct IMediaHTTPService; class IMediaRecorder; class IOMX; class IRemoteDisplay; @@ -49,9 +51,14 @@ public: virtual sp<IMediaMetadataRetriever> createMetadataRetriever() = 0; virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client, int audioSessionId = 0) = 0; - virtual status_t decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, - audio_format_t* pFormat, - const sp<IMemoryHeap>& heap, size_t *pSize) = 0; + virtual status_t decode( + const sp<IMediaHTTPService> &httpService, + const char* url, + uint32_t *pSampleRate, + int* pNumChannels, + audio_format_t* pFormat, + const sp<IMemoryHeap>& heap, size_t *pSize) = 0; + virtual status_t decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat, const sp<IMemoryHeap>& heap, size_t *pSize) = 0; @@ -59,6 +66,7 @@ public: virtual sp<ICrypto> makeCrypto() = 0; virtual sp<IDrm> makeDrm() = 0; virtual sp<IHDCP> makeHDCP(bool createEncryptionModule) = 0; + virtual sp<IMediaCodecList> getCodecList() const = 0; // Connects to a remote display. // 'iface' specifies the address of the local interface on which to listen for @@ -93,9 +101,6 @@ public: virtual void addBatteryData(uint32_t params) = 0; virtual status_t pullBatteryData(Parcel* reply) = 0; - - virtual status_t updateProxyConfig( - const char *host, int32_t port, const char *exclusionList) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/media/IOMX.h b/include/media/IOMX.h index b74a2c7..627f23b 100644 --- a/include/media/IOMX.h +++ b/include/media/IOMX.h @@ -87,6 +87,10 @@ public: node_id node, OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) = 0; + virtual status_t configureVideoTunnelMode( + node_id node, OMX_U32 portIndex, OMX_BOOL tunneled, + OMX_U32 audioHwSync, native_handle_t **sidebandHandle) = 0; + virtual status_t enableGraphicBuffers( node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0; @@ -143,6 +147,8 @@ public: INTERNAL_OPTION_SUSPEND, // data is a bool INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY, // data is an int64_t INTERNAL_OPTION_MAX_TIMESTAMP_GAP, // data is int64_t + INTERNAL_OPTION_START_TIME, // data is an int64_t + INTERNAL_OPTION_TIME_LAPSE, // data is an int64_t[2] }; virtual status_t setInternalOption( node_id node, @@ -182,8 +188,6 @@ struct omx_message { OMX_U32 range_length; OMX_U32 flags; OMX_TICKS timestamp; - OMX_PTR platform_private; - OMX_PTR data_ptr; } extended_buffer_data; } u; diff --git a/include/media/MediaCodecInfo.h b/include/media/MediaCodecInfo.h new file mode 100644 index 0000000..cd56adb --- /dev/null +++ b/include/media/MediaCodecInfo.h @@ -0,0 +1,123 @@ +/* + * Copyright 2014, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_CODEC_INFO_H_ + +#define MEDIA_CODEC_INFO_H_ + +#include <binder/Parcel.h> +#include <media/stagefright/foundation/ABase.h> +#include <media/stagefright/foundation/AString.h> + +#include <sys/types.h> +#include <utils/Errors.h> +#include <utils/KeyedVector.h> +#include <utils/RefBase.h> +#include <utils/Vector.h> +#include <utils/StrongPointer.h> + +namespace android { + +struct AMessage; +struct Parcel; +struct CodecCapabilities; + +struct MediaCodecInfo : public RefBase { + struct ProfileLevel { + uint32_t mProfile; + uint32_t mLevel; + }; + + struct Capabilities : public RefBase { + void getSupportedProfileLevels(Vector<ProfileLevel> *profileLevels) const; + void getSupportedColorFormats(Vector<uint32_t> *colorFormats) const; + uint32_t getFlags() const; + const sp<AMessage> getDetails() const; + + private: + Vector<ProfileLevel> mProfileLevels; + Vector<uint32_t> mColorFormats; + uint32_t mFlags; + sp<AMessage> mDetails; + + Capabilities(); + + // read object from parcel even if object creation fails + static sp<Capabilities> FromParcel(const Parcel &parcel); + status_t writeToParcel(Parcel *parcel) const; + + DISALLOW_EVIL_CONSTRUCTORS(Capabilities); + + friend class MediaCodecInfo; + }; + + bool isEncoder() const; + bool hasQuirk(const char *name) const; + void getSupportedMimes(Vector<AString> *mimes) const; + const sp<Capabilities> getCapabilitiesFor(const char *mime) const; + const char *getCodecName() const; + + /** + * Serialization over Binder + */ + static sp<MediaCodecInfo> FromParcel(const Parcel &parcel); + status_t writeToParcel(Parcel *parcel) const; + +private: + // variable set only in constructor - these are accessed by MediaCodecList + // to avoid duplication of same variables + AString mName; + bool mIsEncoder; + bool mHasSoleMime; // was initialized with mime + + Vector<AString> mQuirks; + KeyedVector<AString, sp<Capabilities> > mCaps; + + sp<Capabilities> mCurrentCaps; // currently initalized capabilities + + ssize_t getCapabilityIndex(const char *mime) const; + + /* Methods used by MediaCodecList to construct the info + * object from XML. + * + * After info object is created: + * - additional quirks can be added + * - additional mimes can be added + * - OMX codec capabilities can be set for the current mime-type + * - a capability detail can be set for the current mime-type + * - a feature can be set for the current mime-type + * - info object can be completed when parsing of a mime-type is done + */ + MediaCodecInfo(AString name, bool encoder, const char *mime); + void addQuirk(const char *name); + status_t addMime(const char *mime); + status_t initializeCapabilities(const CodecCapabilities &caps); + void addDetail(const AString &key, const AString &value); + void addFeature(const AString &key, int32_t value); + void addFeature(const AString &key, const char *value); + void removeMime(const char *mime); + void complete(); + + DISALLOW_EVIL_CONSTRUCTORS(MediaCodecInfo); + + friend class MediaCodecList; +}; + +} // namespace android + +#endif // MEDIA_CODEC_INFO_H_ + + diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h index cd5bf88..38dbb20 100644 --- a/include/media/MediaMetadataRetrieverInterface.h +++ b/include/media/MediaMetadataRetrieverInterface.h @@ -25,6 +25,8 @@ namespace android { +struct IMediaHTTPService; + // Abstract base class class MediaMetadataRetrieverBase : public RefBase { @@ -33,6 +35,7 @@ public: virtual ~MediaMetadataRetrieverBase() {} virtual status_t setDataSource( + const sp<IMediaHTTPService> &httpService, const char *url, const KeyedVector<String8, String8> *headers = NULL) = 0; diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index 26d8729..cf18a45 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -27,6 +27,7 @@ #include <media/mediaplayer.h> #include <media/AudioSystem.h> +#include <media/AudioTimestamp.h> #include <media/Metadata.h> // Fwd decl to make sure everyone agrees that the scope of struct sockaddr_in is @@ -97,6 +98,7 @@ public: virtual uint32_t latency() const = 0; virtual float msecsPerFrame() const = 0; virtual status_t getPosition(uint32_t *position) const = 0; + virtual status_t getTimestamp(AudioTimestamp &ts) const = 0; virtual status_t getFramesWritten(uint32_t *frameswritten) const = 0; virtual int getSessionId() const = 0; virtual audio_stream_type_t getAudioStreamType() const = 0; @@ -137,6 +139,7 @@ public: } virtual status_t setDataSource( + const sp<IMediaHTTPService> &httpService, const char *url, const KeyedVector<String8, String8> *headers = NULL) = 0; @@ -213,11 +216,6 @@ public: return INVALID_OPERATION; } - virtual status_t updateProxyConfig( - const char *host, int32_t port, const char *exclusionList) { - return INVALID_OPERATION; - } - private: friend class MediaPlayerService; diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h index 9fc962c..f061d22 100644 --- a/include/media/MediaProfiles.h +++ b/include/media/MediaProfiles.h @@ -33,7 +33,8 @@ enum camcorder_quality { CAMCORDER_QUALITY_720P = 5, CAMCORDER_QUALITY_1080P = 6, CAMCORDER_QUALITY_QVGA = 7, - CAMCORDER_QUALITY_LIST_END = 7, + CAMCORDER_QUALITY_2160P = 8, + CAMCORDER_QUALITY_LIST_END = 8, CAMCORDER_QUALITY_TIME_LAPSE_LIST_START = 1000, CAMCORDER_QUALITY_TIME_LAPSE_LOW = 1000, @@ -44,7 +45,17 @@ enum camcorder_quality { CAMCORDER_QUALITY_TIME_LAPSE_720P = 1005, CAMCORDER_QUALITY_TIME_LAPSE_1080P = 1006, CAMCORDER_QUALITY_TIME_LAPSE_QVGA = 1007, - CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1007, + CAMCORDER_QUALITY_TIME_LAPSE_2160P = 1008, + CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1008, + + CAMCORDER_QUALITY_HIGH_SPEED_LIST_START = 2000, + CAMCORDER_QUALITY_HIGH_SPEED_LOW = 2000, + CAMCORDER_QUALITY_HIGH_SPEED_HIGH = 2001, + CAMCORDER_QUALITY_HIGH_SPEED_480P = 2002, + CAMCORDER_QUALITY_HIGH_SPEED_720P = 2003, + CAMCORDER_QUALITY_HIGH_SPEED_1080P = 2004, + CAMCORDER_QUALITY_HIGH_SPEED_2160P = 2005, + CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2005, }; /** diff --git a/include/media/SoundPool.h b/include/media/SoundPool.h index 2dd78cc..5830475 100644 --- a/include/media/SoundPool.h +++ b/include/media/SoundPool.h @@ -167,7 +167,7 @@ class SoundPool { friend class SoundPoolThread; friend class SoundChannel; public: - SoundPool(int maxChannels, audio_stream_type_t streamType, int srcQuality); + SoundPool(int maxChannels, const audio_attributes_t* pAttributes); ~SoundPool(); int load(const char* url, int priority); int load(int fd, int64_t offset, int64_t length, int priority); @@ -183,8 +183,7 @@ public: void setPriority(int channelID, int priority); void setLoop(int channelID, int loop); void setRate(int channelID, float rate); - audio_stream_type_t streamType() const { return mStreamType; } - int srcQuality() const { return mSrcQuality; } + const audio_attributes_t* attributes() { return &mAttributes; } // called from SoundPoolThread void sampleLoaded(int sampleID); @@ -225,8 +224,7 @@ private: List<SoundChannel*> mStop; DefaultKeyedVector< int, sp<Sample> > mSamples; int mMaxChannels; - audio_stream_type_t mStreamType; - int mSrcQuality; + audio_attributes_t mAttributes; int mAllocated; int mNextSampleID; int mNextChannelID; diff --git a/include/media/StringArray.h b/include/media/StringArray.h new file mode 100644 index 0000000..ae47085 --- /dev/null +++ b/include/media/StringArray.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Sortable array of strings. STL-ish, but STL-free. +// +#ifndef _LIBS_MEDIA_STRING_ARRAY_H +#define _LIBS_MEDIA_STRING_ARRAY_H + +#include <stdlib.h> +#include <string.h> + +namespace android { + +// +// An expanding array of strings. Add, get, sort, delete. +// +class StringArray { +public: + StringArray(); + virtual ~StringArray(); + + // + // Add a string. A copy of the string is made. + // + bool push_back(const char* str); + + // + // Delete an entry. + // + void erase(int idx); + + // + // Sort the array. + // + void sort(int (*compare)(const void*, const void*)); + + // + // Pass this to the sort routine to do an ascending alphabetical sort. + // + static int cmpAscendingAlpha(const void* pstr1, const void* pstr2); + + // + // Get the #of items in the array. + // + inline int size(void) const { return mCurrent; } + + // + // Return entry N. + // [should use operator[] here] + // + const char* getEntry(int idx) const { + return (unsigned(idx) >= unsigned(mCurrent)) ? NULL : mArray[idx]; + } + + // + // Set entry N to specified string. + // [should use operator[] here] + // + void setEntry(int idx, const char* str); + +private: + int mMax; + int mCurrent; + char** mArray; +}; + +}; // namespace android + +#endif // _LIBS_MEDIA_STRING_ARRAY_H diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h index 0df77c1..b35cf32 100644 --- a/include/media/mediametadataretriever.h +++ b/include/media/mediametadataretriever.h @@ -25,6 +25,7 @@ namespace android { +struct IMediaHTTPService; class IMediaPlayerService; class IMediaMetadataRetriever; @@ -68,6 +69,7 @@ public: void disconnect(); status_t setDataSource( + const sp<IMediaHTTPService> &httpService, const char *dataSourceUrl, const KeyedVector<String8, String8> *headers = NULL); diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h index 4c05fc3..9cc208e 100644 --- a/include/media/mediaplayer.h +++ b/include/media/mediaplayer.h @@ -160,6 +160,9 @@ enum media_parameter_keys { // Playback rate expressed in permille (1000 is normal speed), saved as int32_t, with negative // values used for rewinding or reverse playback. KEY_PARAMETER_PLAYBACK_RATE_PERMILLE = 1300, // set only + + // Set a Parcel containing the value of a parcelled Java AudioAttribute instance + KEY_PARAMETER_AUDIO_ATTRIBUTES = 1400 // set only }; // Keep INVOKE_ID_* in sync with MediaPlayer.java. @@ -170,6 +173,7 @@ enum media_player_invoke_ids { INVOKE_ID_SELECT_TRACK = 4, INVOKE_ID_UNSELECT_TRACK = 5, INVOKE_ID_SET_VIDEO_SCALING_MODE = 6, + INVOKE_ID_GET_SELECTED_TRACK = 7 }; // Keep MEDIA_TRACK_TYPE_* in sync with MediaPlayer.java. @@ -189,6 +193,8 @@ public: virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) = 0; }; +struct IMediaHTTPService; + class MediaPlayer : public BnMediaPlayerClient, public virtual IMediaDeathNotifier { @@ -199,6 +205,7 @@ public: void disconnect(); status_t setDataSource( + const sp<IMediaHTTPService> &httpService, const char *url, const KeyedVector<String8, String8> *headers); @@ -220,13 +227,19 @@ public: status_t getDuration(int *msec); status_t reset(); status_t setAudioStreamType(audio_stream_type_t type); + status_t getAudioStreamType(audio_stream_type_t *type); status_t setLooping(int loop); bool isLooping(); status_t setVolume(float leftVolume, float rightVolume); void notify(int msg, int ext1, int ext2, const Parcel *obj = NULL); - static status_t decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, - audio_format_t* pFormat, - const sp<IMemoryHeap>& heap, size_t *pSize); + static status_t decode( + const sp<IMediaHTTPService> &httpService, + const char* url, + uint32_t *pSampleRate, + int* pNumChannels, + audio_format_t* pFormat, + const sp<IMemoryHeap>& heap, + size_t *pSize); static status_t decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat, const sp<IMemoryHeap>& heap, size_t *pSize); @@ -242,9 +255,6 @@ public: status_t setRetransmitEndpoint(const char* addrString, uint16_t port); status_t setNextMediaPlayer(const sp<MediaPlayer>& player); - status_t updateProxyConfig( - const char *host, int32_t port, const char *exclusionList); - private: void clear_l(); status_t seekTo_l(int msec); @@ -253,6 +263,7 @@ private: status_t attachNewPlayer(const sp<IMediaPlayer>& player); status_t reset_l(); status_t doSetRetransmitEndpoint(const sp<IMediaPlayer>& player); + status_t checkStateForKeySet_l(int key); sp<IMediaPlayer> mPlayer; thread_id_t mLockThreadId; @@ -267,6 +278,7 @@ private: bool mPrepareSync; status_t mPrepareStatus; audio_stream_type_t mStreamType; + Parcel* mAudioAttributesParcel; bool mLoop; float mLeftVolume; float mRightVolume; diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h index 88a42a0..b0a62a7 100644 --- a/include/media/mediarecorder.h +++ b/include/media/mediarecorder.h @@ -39,7 +39,7 @@ typedef void (*media_completion_f)(status_t status, void *cookie); enum video_source { VIDEO_SOURCE_DEFAULT = 0, VIDEO_SOURCE_CAMERA = 1, - VIDEO_SOURCE_GRALLOC_BUFFER = 2, + VIDEO_SOURCE_SURFACE = 2, VIDEO_SOURCE_LIST_END // must be last - used to validate audio source type }; @@ -61,12 +61,18 @@ enum output_format { OUTPUT_FORMAT_AAC_ADIF = 5, OUTPUT_FORMAT_AAC_ADTS = 6, + OUTPUT_FORMAT_AUDIO_ONLY_END = 7, // Used in validating the output format. Should be the + // at the end of the audio only output formats. + /* Stream over a socket, limited to a single stream */ OUTPUT_FORMAT_RTP_AVP = 7, /* H.264/AAC data encapsulated in MPEG2/TS */ OUTPUT_FORMAT_MPEG2TS = 8, + /* VP8/VORBIS data in a WEBM container */ + OUTPUT_FORMAT_WEBM = 9, + OUTPUT_FORMAT_LIST_END // must be last - used to validate format type }; @@ -77,6 +83,7 @@ enum audio_encoder { AUDIO_ENCODER_AAC = 3, AUDIO_ENCODER_HE_AAC = 4, AUDIO_ENCODER_AAC_ELD = 5, + AUDIO_ENCODER_VORBIS = 6, AUDIO_ENCODER_LIST_END // must be the last - used to validate the audio encoder type }; @@ -86,6 +93,7 @@ enum video_encoder { VIDEO_ENCODER_H263 = 1, VIDEO_ENCODER_H264 = 2, VIDEO_ENCODER_MPEG_4_SP = 3, + VIDEO_ENCODER_VP8 = 4, VIDEO_ENCODER_LIST_END // must be the last - used to validate the video encoder type }; diff --git a/include/media/mediascanner.h b/include/media/mediascanner.h index 37a83c6..d555279 100644 --- a/include/media/mediascanner.h +++ b/include/media/mediascanner.h @@ -21,6 +21,7 @@ #include <utils/threads.h> #include <utils/List.h> #include <utils/Errors.h> +#include <utils/String8.h> #include <pthread.h> struct dirent; @@ -29,6 +30,7 @@ namespace android { class MediaScannerClient; class StringArray; +class CharacterEncodingDetector; enum MediaScanResult { // This file or directory was scanned successfully. @@ -118,15 +120,8 @@ public: virtual status_t setMimeType(const char* mimeType) = 0; protected: - void convertValues(uint32_t encoding); - -protected: - // cached name and value strings, for native encoding support. - StringArray* mNames; - StringArray* mValues; - - // default encoding based on MediaScanner::mLocale string - uint32_t mLocaleEncoding; + // default encoding from MediaScanner::mLocale + String8 mLocale; }; }; // namespace android diff --git a/include/media/nbaio/AudioBufferProviderSource.h b/include/media/nbaio/AudioBufferProviderSource.h index 2c4aaff..b16e20a 100644 --- a/include/media/nbaio/AudioBufferProviderSource.h +++ b/include/media/nbaio/AudioBufferProviderSource.h @@ -27,7 +27,7 @@ namespace android { class AudioBufferProviderSource : public NBAIO_Source { public: - AudioBufferProviderSource(AudioBufferProvider *provider, NBAIO_Format format); + AudioBufferProviderSource(AudioBufferProvider *provider, const NBAIO_Format& format); virtual ~AudioBufferProviderSource(); // NBAIO_Port interface diff --git a/include/media/nbaio/AudioStreamInSource.h b/include/media/nbaio/AudioStreamInSource.h index 07d8c89..5169f1e 100644 --- a/include/media/nbaio/AudioStreamInSource.h +++ b/include/media/nbaio/AudioStreamInSource.h @@ -43,9 +43,9 @@ public: // This is an over-estimate, and could dupe the caller into making a blocking read() // FIXME Use an audio HAL API to query the buffer filling status when it's available. - virtual ssize_t availableToRead() { return mStreamBufferSizeBytes >> mBitShift; } + virtual ssize_t availableToRead() { return mStreamBufferSizeBytes / mFrameSize; } - virtual ssize_t read(void *buffer, size_t count); + virtual ssize_t read(void *buffer, size_t count, int64_t readPTS); // NBAIO_Sink end diff --git a/include/media/nbaio/AudioStreamOutSink.h b/include/media/nbaio/AudioStreamOutSink.h index 7948d40..9949b88 100644 --- a/include/media/nbaio/AudioStreamOutSink.h +++ b/include/media/nbaio/AudioStreamOutSink.h @@ -43,7 +43,7 @@ public: // This is an over-estimate, and could dupe the caller into making a blocking write() // FIXME Use an audio HAL API to query the buffer emptying status when it's available. - virtual ssize_t availableToWrite() const { return mStreamBufferSizeBytes >> mBitShift; } + virtual ssize_t availableToWrite() const { return mStreamBufferSizeBytes / mFrameSize; } virtual ssize_t write(const void *buffer, size_t count); diff --git a/include/media/nbaio/MonoPipe.h b/include/media/nbaio/MonoPipe.h index d3802fe..b09b35f 100644 --- a/include/media/nbaio/MonoPipe.h +++ b/include/media/nbaio/MonoPipe.h @@ -41,7 +41,7 @@ public: // Note: whatever shares this object with another thread needs to do so in an SMP-safe way (like // creating it the object before creating the other thread, or storing the object with a // release_store). Otherwise the other thread could see a partially-constructed object. - MonoPipe(size_t reqFrames, NBAIO_Format format, bool writeCanBlock = false); + MonoPipe(size_t reqFrames, const NBAIO_Format& format, bool writeCanBlock = false); virtual ~MonoPipe(); // NBAIO_Port interface diff --git a/include/media/nbaio/NBAIO.h b/include/media/nbaio/NBAIO.h index 1da0c73..d422576 100644 --- a/include/media/nbaio/NBAIO.h +++ b/include/media/nbaio/NBAIO.h @@ -29,6 +29,7 @@ #include <utils/Errors.h> #include <utils/RefBase.h> #include <media/AudioTimestamp.h> +#include <system/audio.h> namespace android { @@ -52,31 +53,41 @@ enum { // the combinations that are actually needed within AudioFlinger. If the list of combinations grows // too large, then this decision should be re-visited. // Sample rate and channel count are explicit, PCM interleaved 16-bit is assumed. -typedef unsigned NBAIO_Format; -enum { - Format_Invalid +struct NBAIO_Format { +// FIXME make this a class, and change Format_... global methods to class methods +//private: + unsigned mSampleRate; + unsigned mChannelCount; + audio_format_t mFormat; + size_t mFrameSize; }; -// Return the frame size of an NBAIO_Format in bytes -size_t Format_frameSize(NBAIO_Format format); +extern const NBAIO_Format Format_Invalid; -// Return the frame size of an NBAIO_Format as a bit shift -size_t Format_frameBitShift(NBAIO_Format format); +// Return the frame size of an NBAIO_Format in bytes +size_t Format_frameSize(const NBAIO_Format& format); // Convert a sample rate in Hz and channel count to an NBAIO_Format -NBAIO_Format Format_from_SR_C(unsigned sampleRate, unsigned channelCount); +// FIXME rename +NBAIO_Format Format_from_SR_C(unsigned sampleRate, unsigned channelCount, audio_format_t format); // Return the sample rate in Hz of an NBAIO_Format -unsigned Format_sampleRate(NBAIO_Format format); +unsigned Format_sampleRate(const NBAIO_Format& format); // Return the channel count of an NBAIO_Format -unsigned Format_channelCount(NBAIO_Format format); +unsigned Format_channelCount(const NBAIO_Format& format); // Callbacks used by NBAIO_Sink::writeVia() and NBAIO_Source::readVia() below. typedef ssize_t (*writeVia_t)(void *user, void *buffer, size_t count); typedef ssize_t (*readVia_t)(void *user, const void *buffer, size_t count, int64_t readPTS); +// Check whether an NBAIO_Format is valid +bool Format_isValid(const NBAIO_Format& format); + +// Compare two NBAIO_Format values +bool Format_isEqual(const NBAIO_Format& format1, const NBAIO_Format& format2); + // Abstract class (interface) representing a data port. class NBAIO_Port : public RefBase { @@ -115,15 +126,15 @@ public: virtual NBAIO_Format format() const { return mNegotiated ? mFormat : Format_Invalid; } protected: - NBAIO_Port(NBAIO_Format format) : mNegotiated(false), mFormat(format), - mBitShift(Format_frameBitShift(format)) { } + NBAIO_Port(const NBAIO_Format& format) : mNegotiated(false), mFormat(format), + mFrameSize(Format_frameSize(format)) { } virtual ~NBAIO_Port() { } // Implementations are free to ignore these if they don't need them bool mNegotiated; // mNegotiated implies (mFormat != Format_Invalid) NBAIO_Format mFormat; // (mFormat != Format_Invalid) does not imply mNegotiated - size_t mBitShift; // assign in parallel with any assignment to mFormat + size_t mFrameSize; // assign in parallel with any assignment to mFormat }; // Abstract class (interface) representing a non-blocking data sink, for use by a data provider. @@ -216,11 +227,11 @@ public: // Returns NO_ERROR if a timestamp is available. The timestamp includes the total number // of frames presented to an external observer, together with the value of CLOCK_MONOTONIC - // as of this presentation count. + // as of this presentation count. The timestamp parameter is undefined if error is returned. virtual status_t getTimestamp(AudioTimestamp& timestamp) { return INVALID_OPERATION; } protected: - NBAIO_Sink(NBAIO_Format format = Format_Invalid) : NBAIO_Port(format), mFramesWritten(0) { } + NBAIO_Sink(const NBAIO_Format& format = Format_Invalid) : NBAIO_Port(format), mFramesWritten(0) { } virtual ~NBAIO_Sink() { } // Implementations are free to ignore these if they don't need them @@ -311,7 +322,7 @@ public: virtual void onTimestamp(const AudioTimestamp& timestamp) { } protected: - NBAIO_Source(NBAIO_Format format = Format_Invalid) : NBAIO_Port(format), mFramesRead(0) { } + NBAIO_Source(const NBAIO_Format& format = Format_Invalid) : NBAIO_Port(format), mFramesRead(0) { } virtual ~NBAIO_Source() { } // Implementations are free to ignore these if they don't need them diff --git a/include/media/nbaio/Pipe.h b/include/media/nbaio/Pipe.h index 79a4eee..eba37bc 100644 --- a/include/media/nbaio/Pipe.h +++ b/include/media/nbaio/Pipe.h @@ -30,7 +30,11 @@ class Pipe : public NBAIO_Sink { public: // maxFrames will be rounded up to a power of 2, and all slots are available. Must be >= 2. - Pipe(size_t maxFrames, NBAIO_Format format); + // buffer is an optional parameter specifying the virtual address of the pipe buffer, + // which must be of size roundup(maxFrames) * Format_frameSize(format) bytes. + Pipe(size_t maxFrames, const NBAIO_Format& format, void *buffer = NULL); + + // If a buffer was specified in the constructor, it is not automatically freed by destructor. virtual ~Pipe(); // NBAIO_Port interface @@ -57,6 +61,7 @@ private: void * const mBuffer; volatile int32_t mRear; // written by android_atomic_release_store volatile int32_t mReaders; // number of PipeReader clients currently attached to this Pipe + const bool mFreeBufferInDestructor; }; } // namespace android diff --git a/include/media/nbaio/SourceAudioBufferProvider.h b/include/media/nbaio/SourceAudioBufferProvider.h index cdfb6fe..daf6bc3 100644 --- a/include/media/nbaio/SourceAudioBufferProvider.h +++ b/include/media/nbaio/SourceAudioBufferProvider.h @@ -41,7 +41,7 @@ public: private: const sp<NBAIO_Source> mSource; // the wrapped source - /*const*/ size_t mFrameBitShift; // log2(frame size in bytes) + /*const*/ size_t mFrameSize; // frame size in bytes void* mAllocated; // pointer to base of allocated memory size_t mSize; // size of mAllocated in frames size_t mOffset; // frame offset within mAllocated of valid data diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index 46c62dc..da4c20c 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -22,6 +22,7 @@ #include <android/native_window.h> #include <media/IOMX.h> #include <media/stagefright/foundation/AHierarchicalStateMachine.h> +#include <media/stagefright/CodecBase.h> #include <media/stagefright/SkipCutBuffer.h> #include <OMX_Audio.h> @@ -31,45 +32,34 @@ namespace android { struct ABuffer; struct MemoryDealer; +struct DescribeColorFormatParams; -struct ACodec : public AHierarchicalStateMachine { - enum { - kWhatFillThisBuffer = 'fill', - kWhatDrainThisBuffer = 'drai', - kWhatEOS = 'eos ', - kWhatShutdownCompleted = 'scom', - kWhatFlushCompleted = 'fcom', - kWhatOutputFormatChanged = 'outC', - kWhatError = 'erro', - kWhatComponentAllocated = 'cAll', - kWhatComponentConfigured = 'cCon', - kWhatInputSurfaceCreated = 'isfc', - kWhatSignaledInputEOS = 'seos', - kWhatBuffersAllocated = 'allc', - kWhatOMXDied = 'OMXd', - }; - +struct ACodec : public AHierarchicalStateMachine, public CodecBase { ACodec(); - void setNotificationMessage(const sp<AMessage> &msg); + virtual void setNotificationMessage(const sp<AMessage> &msg); + void initiateSetup(const sp<AMessage> &msg); - void signalFlush(); - void signalResume(); - void initiateShutdown(bool keepComponentAllocated = false); - void signalSetParameters(const sp<AMessage> &msg); - void signalEndOfInputStream(); + virtual void initiateAllocateComponent(const sp<AMessage> &msg); + virtual void initiateConfigureComponent(const sp<AMessage> &msg); + virtual void initiateCreateInputSurface(); + virtual void initiateStart(); + virtual void initiateShutdown(bool keepComponentAllocated = false); - void initiateAllocateComponent(const sp<AMessage> &msg); - void initiateConfigureComponent(const sp<AMessage> &msg); - void initiateCreateInputSurface(); - void initiateStart(); + virtual void signalFlush(); + virtual void signalResume(); - void signalRequestIDRFrame(); + virtual void signalSetParameters(const sp<AMessage> &msg); + virtual void signalEndOfInputStream(); + virtual void signalRequestIDRFrame(); - bool isConfiguredForAdaptivePlayback() { return mIsConfiguredForAdaptivePlayback; } + // AHierarchicalStateMachine implements the message handling + virtual void onMessageReceived(const sp<AMessage> &msg) { + handleMessage(msg); + } - struct PortDescription : public RefBase { + struct PortDescription : public CodecBase::PortDescription { size_t countBuffers(); IOMX::buffer_id bufferIDAt(size_t index) const; sp<ABuffer> bufferAt(size_t index) const; @@ -86,6 +76,10 @@ struct ACodec : public AHierarchicalStateMachine { DISALLOW_EVIL_CONSTRUCTORS(PortDescription); }; + static bool isFlexibleColorFormat( + const sp<IOMX> &omx, IOMX::node_id node, + uint32_t colorFormat, OMX_U32 *flexibleEquivalent); + protected: virtual ~ACodec(); @@ -119,6 +113,7 @@ private: kWhatRequestIDRFrame = 'ridr', kWhatSetParameters = 'setP', kWhatSubmitOutputMetaDataBufferIfEOS = 'subm', + kWhatOMXDied = 'OMXd', }; enum { @@ -178,6 +173,8 @@ private: sp<MemoryDealer> mDealer[2]; sp<ANativeWindow> mNativeWindow; + sp<AMessage> mInputFormat; + sp<AMessage> mOutputFormat; Vector<BufferInfo> mBuffers[2]; bool mPortEOS[2]; @@ -189,7 +186,7 @@ private: bool mIsEncoder; bool mUseMetadataOnEncoderOutput; bool mShutdownInProgress; - bool mIsConfiguredForAdaptivePlayback; + bool mExplicitShutdown; // If "mKeepComponentAllocated" we only transition back to Loaded state // and do not release the component instance. @@ -197,6 +194,7 @@ private: int32_t mEncoderDelay; int32_t mEncoderPadding; + int32_t mRotationDegrees; bool mChannelMaskPresent; int32_t mChannelMask; @@ -208,6 +206,11 @@ private: int64_t mRepeatFrameDelayUs; int64_t mMaxPtsGapUs; + int64_t mTimePerFrameUs; + int64_t mTimePerCaptureUs; + + bool mCreateInputBuffersSuspended; + status_t setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode); status_t allocateBuffersOnPort(OMX_U32 portIndex); status_t freeBuffersOnPort(OMX_U32 portIndex); @@ -231,6 +234,9 @@ private: status_t setComponentRole(bool isEncoder, const char *mime); status_t configureCodec(const char *mime, const sp<AMessage> &msg); + status_t configureTunneledVideoPlayback(int32_t audioHwSync, + const sp<ANativeWindow> &nativeWindow); + status_t setVideoPortFormatType( OMX_U32 portIndex, OMX_VIDEO_CODINGTYPE compressionFormat, @@ -239,7 +245,7 @@ private: status_t setSupportedOutputFormat(); status_t setupVideoDecoder( - const char *mime, int32_t width, int32_t height); + const char *mime, const sp<AMessage> &msg); status_t setupVideoEncoder( const char *mime, const sp<AMessage> &msg); @@ -249,10 +255,21 @@ private: int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat); + typedef struct drcParams { + int32_t drcCut; + int32_t drcBoost; + int32_t heavyCompression; + int32_t targetRefLevel; + int32_t encodedTargetLevel; + } drcParams_t; + status_t setupAACCodec( bool encoder, int32_t numChannels, int32_t sampleRate, int32_t bitRate, - int32_t aacProfile, bool isADTS); + int32_t aacProfile, bool isADTS, int32_t sbrMode, + int32_t maxOutputChannelCount, const drcParams_t& drc); + + status_t setupAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate); status_t selectAudioPortFormat( OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat); @@ -271,6 +288,7 @@ private: status_t setupMPEG4EncoderParameters(const sp<AMessage> &msg); status_t setupH263EncoderParameters(const sp<AMessage> &msg); status_t setupAVCEncoderParameters(const sp<AMessage> &msg); + status_t setupHEVCEncoderParameters(const sp<AMessage> &msg); status_t setupVPXEncoderParameters(const sp<AMessage> &msg); status_t verifySupportForProfileAndLevel(int32_t profile, int32_t level); @@ -299,11 +317,17 @@ private: void processDeferredMessages(); void sendFormatChange(const sp<AMessage> &reply); + status_t getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify); void signalError( OMX_ERRORTYPE error = OMX_ErrorUndefined, status_t internalError = UNKNOWN_ERROR); + static bool describeDefaultColorFormat(DescribeColorFormatParams &describeParams); + static bool describeColorFormat( + const sp<IOMX> &omx, IOMX::node_id node, + DescribeColorFormatParams &describeParams); + status_t requestIDRFrame(); status_t setParameters(const sp<AMessage> ¶ms); diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h index a829916..dd0a106 100644 --- a/include/media/stagefright/CameraSource.h +++ b/include/media/stagefright/CameraSource.h @@ -172,7 +172,7 @@ protected: const sp<IGraphicBufferProducer>& surface, bool storeMetaDataInVideoBuffers); - virtual void startCameraRecording(); + virtual status_t startCameraRecording(); virtual void releaseRecordingFrame(const sp<IMemory>& frame); // Returns true if need to skip the current frame. @@ -185,6 +185,8 @@ protected: virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType, const sp<IMemory> &data); + void releaseCamera(); + private: friend class CameraSourceListener; @@ -233,7 +235,6 @@ private: int32_t frameRate); void stopCameraRecording(); - void releaseCamera(); status_t reset(); CameraSource(const CameraSource &); diff --git a/include/media/stagefright/CodecBase.h b/include/media/stagefright/CodecBase.h new file mode 100644 index 0000000..1bf27a6 --- /dev/null +++ b/include/media/stagefright/CodecBase.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CODEC_BASE_H_ + +#define CODEC_BASE_H_ + +#include <stdint.h> +#include <media/IOMX.h> + +#include <media/stagefright/foundation/AHandler.h> + +namespace android { + +struct ABuffer; + +struct CodecBase : public AHandler { + enum { + kWhatFillThisBuffer = 'fill', + kWhatDrainThisBuffer = 'drai', + kWhatEOS = 'eos ', + kWhatShutdownCompleted = 'scom', + kWhatFlushCompleted = 'fcom', + kWhatOutputFormatChanged = 'outC', + kWhatError = 'erro', + kWhatComponentAllocated = 'cAll', + kWhatComponentConfigured = 'cCon', + kWhatInputSurfaceCreated = 'isfc', + kWhatSignaledInputEOS = 'seos', + kWhatBuffersAllocated = 'allc', + }; + + virtual void setNotificationMessage(const sp<AMessage> &msg) = 0; + + virtual void initiateAllocateComponent(const sp<AMessage> &msg) = 0; + virtual void initiateConfigureComponent(const sp<AMessage> &msg) = 0; + virtual void initiateCreateInputSurface() = 0; + virtual void initiateStart() = 0; + virtual void initiateShutdown(bool keepComponentAllocated = false) = 0; + + // require an explicit message handler + virtual void onMessageReceived(const sp<AMessage> &msg) = 0; + + virtual void signalFlush() = 0; + virtual void signalResume() = 0; + + virtual void signalRequestIDRFrame() = 0; + virtual void signalSetParameters(const sp<AMessage> &msg) = 0; + virtual void signalEndOfInputStream() = 0; + + struct PortDescription : public RefBase { + virtual size_t countBuffers() = 0; + virtual IOMX::buffer_id bufferIDAt(size_t index) const = 0; + virtual sp<ABuffer> bufferAt(size_t index) const = 0; + + protected: + PortDescription(); + virtual ~PortDescription(); + + private: + DISALLOW_EVIL_CONSTRUCTORS(PortDescription); + }; + +protected: + CodecBase(); + virtual ~CodecBase(); + +private: + DISALLOW_EVIL_CONSTRUCTORS(CodecBase); +}; + +} // namespace android + +#endif // CODEC_BASE_H_ + diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h index 157b1aa..8000e84 100644 --- a/include/media/stagefright/DataSource.h +++ b/include/media/stagefright/DataSource.h @@ -31,6 +31,8 @@ namespace android { struct AMessage; +struct AString; +struct IMediaHTTPService; class String8; class DataSource : public RefBase { @@ -43,8 +45,10 @@ public: }; static sp<DataSource> CreateFromURI( + const sp<IMediaHTTPService> &httpService, const char *uri, - const KeyedVector<String8, String8> *headers = NULL); + const KeyedVector<String8, String8> *headers = NULL, + String8 *contentType = NULL); DataSource() {} diff --git a/include/media/stagefright/DataURISource.h b/include/media/stagefright/DataURISource.h new file mode 100644 index 0000000..693562e --- /dev/null +++ b/include/media/stagefright/DataURISource.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATA_URI_SOURCE_H_ + +#define DATA_URI_SOURCE_H_ + +#include <media/stagefright/DataSource.h> +#include <media/stagefright/foundation/ABase.h> + +namespace android { + +struct ABuffer; + +struct DataURISource : public DataSource { + static sp<DataURISource> Create(const char *uri); + + virtual status_t initCheck() const; + virtual ssize_t readAt(off64_t offset, void *data, size_t size); + virtual status_t getSize(off64_t *size); + +protected: + virtual ~DataURISource(); + +private: + sp<ABuffer> mBuffer; + + DataURISource(const sp<ABuffer> &buffer); + + DISALLOW_EVIL_CONSTRUCTORS(DataURISource); +}; + +} // namespace android + +#endif // DATA_URI_SOURCE_H_ + diff --git a/include/media/stagefright/FileSource.h b/include/media/stagefright/FileSource.h index be152e7..a981d1c 100644 --- a/include/media/stagefright/FileSource.h +++ b/include/media/stagefright/FileSource.h @@ -30,6 +30,7 @@ namespace android { class FileSource : public DataSource { public: FileSource(const char *filename); + // FileSource takes ownership and will close the fd FileSource(int fd, int64_t offset, int64_t length); virtual status_t initCheck() const; diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h index 3ef6b9a..26ce5f9 100644 --- a/include/media/stagefright/MPEG4Writer.h +++ b/include/media/stagefright/MPEG4Writer.h @@ -63,8 +63,8 @@ public: int32_t getTimeScale() const { return mTimeScale; } status_t setGeoData(int latitudex10000, int longitudex10000); - void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; } - int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; } + virtual void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; } + virtual int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; } protected: virtual ~MPEG4Writer(); diff --git a/include/media/stagefright/MediaBuffer.h b/include/media/stagefright/MediaBuffer.h index 3d79596..c8a50e8 100644 --- a/include/media/stagefright/MediaBuffer.h +++ b/include/media/stagefright/MediaBuffer.h @@ -18,6 +18,8 @@ #define MEDIA_BUFFER_H_ +#include <media/stagefright/foundation/MediaBufferBase.h> + #include <pthread.h> #include <utils/Errors.h> @@ -43,7 +45,7 @@ private: MediaBufferObserver &operator=(const MediaBufferObserver &); }; -class MediaBuffer { +class MediaBuffer : public MediaBufferBase { public: // The underlying data remains the responsibility of the caller! MediaBuffer(void *data, size_t size); @@ -56,10 +58,10 @@ public: // Decrements the reference count and returns the buffer to its // associated MediaBufferGroup if the reference count drops to 0. - void release(); + virtual void release(); // Increments the reference count. - void add_ref(); + virtual void add_ref(); void *data() const; size_t size() const; diff --git a/include/media/stagefright/MediaBufferGroup.h b/include/media/stagefright/MediaBufferGroup.h index 0488292..a006f7f 100644 --- a/include/media/stagefright/MediaBufferGroup.h +++ b/include/media/stagefright/MediaBufferGroup.h @@ -34,9 +34,12 @@ public: void add_buffer(MediaBuffer *buffer); - // Blocks until a buffer is available and returns it to the caller, - // the returned buffer will have a reference count of 1. - status_t acquire_buffer(MediaBuffer **buffer); + // If nonBlocking is false, it blocks until a buffer is available and + // passes it to the caller in *buffer, while returning OK. + // The returned buffer will have a reference count of 1. + // If nonBlocking is true and a buffer is not immediately available, + // buffer is set to NULL and it returns WOULD_BLOCK. + status_t acquire_buffer(MediaBuffer **buffer, bool nonBlocking = false); protected: virtual void signalBufferReturned(MediaBuffer *buffer); diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h index 1f17efe..bca78b9 100644 --- a/include/media/stagefright/MediaCodec.h +++ b/include/media/stagefright/MediaCodec.h @@ -26,10 +26,11 @@ namespace android { struct ABuffer; -struct ACodec; struct AMessage; struct AString; +struct CodecBase; struct ICrypto; +struct IBatteryStats; struct SoftwareRenderer; struct Surface; @@ -44,11 +45,20 @@ struct MediaCodec : public AHandler { BUFFER_FLAG_EOS = 4, }; + enum { + CB_INPUT_AVAILABLE = 1, + CB_OUTPUT_AVAILABLE = 2, + CB_ERROR = 3, + CB_OUTPUT_FORMAT_CHANGED = 4, + }; + + struct BatteryNotifier; + static sp<MediaCodec> CreateByType( - const sp<ALooper> &looper, const char *mime, bool encoder); + const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err = NULL); static sp<MediaCodec> CreateByComponentName( - const sp<ALooper> &looper, const char *name); + const sp<ALooper> &looper, const char *name, status_t *err = NULL); status_t configure( const sp<AMessage> &format, @@ -56,6 +66,8 @@ struct MediaCodec : public AHandler { const sp<ICrypto> &crypto, uint32_t flags); + status_t setCallback(const sp<AMessage> &callback); + status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer); status_t start(); @@ -64,6 +76,10 @@ struct MediaCodec : public AHandler { // unconfigured. status_t stop(); + // Resets the codec to the INITIALIZED state. Can be called after an error + // has occured to make the codec usable. + status_t reset(); + // Client MUST call release before releasing final reference to this // object. status_t release(); @@ -100,16 +116,22 @@ struct MediaCodec : public AHandler { uint32_t *flags, int64_t timeoutUs = 0ll); + status_t renderOutputBufferAndRelease(size_t index, int64_t timestampNs); status_t renderOutputBufferAndRelease(size_t index); status_t releaseOutputBuffer(size_t index); status_t signalEndOfInputStream(); status_t getOutputFormat(sp<AMessage> *format) const; + status_t getInputFormat(sp<AMessage> *format) const; status_t getInputBuffers(Vector<sp<ABuffer> > *buffers) const; status_t getOutputBuffers(Vector<sp<ABuffer> > *buffers) const; + status_t getOutputBuffer(size_t index, sp<ABuffer> *buffer); + status_t getOutputFormat(size_t index, sp<AMessage> *format); + status_t getInputBuffer(size_t index, sp<ABuffer> *buffer); + status_t requestIDRFrame(); // Notification will be posted once there "is something to do", i.e. @@ -135,6 +157,7 @@ private: STARTING, STARTED, FLUSHING, + FLUSHED, STOPPING, RELEASING, }; @@ -159,6 +182,7 @@ private: kWhatGetBuffers = 'getB', kWhatFlush = 'flus', kWhatGetOutputFormat = 'getO', + kWhatGetInputFormat = 'getI', kWhatDequeueInputTimedOut = 'dITO', kWhatDequeueOutputTimedOut = 'dOTO', kWhatCodecNotify = 'codc', @@ -166,6 +190,7 @@ private: kWhatRequestActivityNotification = 'racN', kWhatGetName = 'getN', kWhatSetParameters = 'setP', + kWhatSetCallback = 'setC', }; enum { @@ -179,6 +204,7 @@ private: kFlagSawMediaServerDie = 128, kFlagIsEncoder = 256, kFlagGatherCodecSpecificData = 512, + kFlagIsAsync = 1024, }; struct BufferInfo { @@ -186,19 +212,37 @@ private: sp<ABuffer> mData; sp<ABuffer> mEncryptedData; sp<AMessage> mNotify; + sp<AMessage> mFormat; bool mOwnedByClient; }; State mState; sp<ALooper> mLooper; sp<ALooper> mCodecLooper; - sp<ACodec> mCodec; + sp<CodecBase> mCodec; AString mComponentName; uint32_t mReplyID; uint32_t mFlags; + status_t mStickyError; sp<Surface> mNativeWindow; SoftwareRenderer *mSoftRenderer; sp<AMessage> mOutputFormat; + sp<AMessage> mInputFormat; + sp<AMessage> mCallback; + + bool mBatteryStatNotified; + bool mIsVideo; + + // initial create parameters + AString mInitName; + bool mInitNameIsType; + bool mInitIsEncoder; + + // Used only to synchronize asynchronous getBufferAndFormat + // across all the other (synchronous) buffer state change + // operations, such as de/queueIn/OutputBuffer, start and + // stop/flush/reset/release. + Mutex mBufferLock; List<size_t> mAvailPortBuffers[2]; Vector<BufferInfo> mPortBuffers[2]; @@ -222,7 +266,9 @@ private: static status_t PostAndAwaitResponse( const sp<AMessage> &msg, sp<AMessage> *response); - status_t init(const char *name, bool nameIsType, bool encoder); + static void PostReplyWithError(int32_t replyID, int32_t err); + + status_t init(const AString &name, bool nameIsType, bool encoder); void setState(State newState); void returnBuffersToCodec(); @@ -232,6 +278,10 @@ private: status_t onReleaseOutputBuffer(const sp<AMessage> &msg); ssize_t dequeuePortBuffer(int32_t portIndex); + status_t getBufferAndFormat( + size_t portIndex, size_t index, + sp<ABuffer> *buffer, sp<AMessage> *format); + bool handleDequeueInputBuffer(uint32_t replyID, bool newRequest = false); bool handleDequeueOutputBuffer(uint32_t replyID, bool newRequest = false); void cancelPendingDequeueOperations(); @@ -244,9 +294,28 @@ private: void postActivityNotificationIfPossible(); + void onInputBufferAvailable(); + void onOutputBufferAvailable(); + void onError(status_t err, int32_t actionCode, const char *detail = NULL); + void onOutputFormatChanged(); + status_t onSetParameters(const sp<AMessage> ¶ms); status_t amendOutputFormatWithCodecSpecificData(const sp<ABuffer> &buffer); + void updateBatteryStat(); + bool isExecuting() const; + + /* called to get the last codec error when the sticky flag is set. + * if no such codec error is found, returns UNKNOWN_ERROR. + */ + inline status_t getStickyError() const { + return mStickyError != 0 ? mStickyError : UNKNOWN_ERROR; + } + + inline void setStickyError(status_t err) { + mFlags |= kFlagStickyError; + mStickyError = err; + } DISALLOW_EVIL_CONSTRUCTORS(MediaCodec); }; diff --git a/include/media/stagefright/MediaCodecList.h b/include/media/stagefright/MediaCodecList.h index 590623b..8605d99 100644 --- a/include/media/stagefright/MediaCodecList.h +++ b/include/media/stagefright/MediaCodecList.h @@ -20,70 +20,68 @@ #include <media/stagefright/foundation/ABase.h> #include <media/stagefright/foundation/AString.h> +#include <media/IMediaCodecList.h> +#include <media/IOMX.h> +#include <media/MediaCodecInfo.h> #include <sys/types.h> #include <utils/Errors.h> #include <utils/KeyedVector.h> #include <utils/Vector.h> +#include <utils/StrongPointer.h> namespace android { -struct MediaCodecList { - static const MediaCodecList *getInstance(); +struct AMessage; - ssize_t findCodecByType( +struct MediaCodecList : public BnMediaCodecList { + static sp<IMediaCodecList> getInstance(); + + virtual ssize_t findCodecByType( const char *type, bool encoder, size_t startIndex = 0) const; - ssize_t findCodecByName(const char *name) const; + virtual ssize_t findCodecByName(const char *name) const; - size_t countCodecs() const; - const char *getCodecName(size_t index) const; - bool isEncoder(size_t index) const; - bool codecHasQuirk(size_t index, const char *quirkName) const; + virtual size_t countCodecs() const; - status_t getSupportedTypes(size_t index, Vector<AString> *types) const; + virtual sp<MediaCodecInfo> getCodecInfo(size_t index) const { + return mCodecInfos.itemAt(index); + } - struct ProfileLevel { - uint32_t mProfile; - uint32_t mLevel; - }; - status_t getCodecCapabilities( - size_t index, const char *type, - Vector<ProfileLevel> *profileLevels, - Vector<uint32_t> *colorFormats, - uint32_t *flags) const; + // to be used by MediaPlayerService alone + static sp<IMediaCodecList> getLocalInstance(); private: enum Section { SECTION_TOPLEVEL, SECTION_DECODERS, SECTION_DECODER, + SECTION_DECODER_TYPE, SECTION_ENCODERS, SECTION_ENCODER, + SECTION_ENCODER_TYPE, + SECTION_INCLUDE, }; - struct CodecInfo { - AString mName; - bool mIsEncoder; - uint32_t mTypes; - uint32_t mQuirks; - }; - - static MediaCodecList *sCodecList; + static sp<IMediaCodecList> sCodecList; + static sp<IMediaCodecList> sRemoteList; status_t mInitCheck; Section mCurrentSection; + Vector<Section> mPastSections; int32_t mDepth; + AString mHrefBase; - Vector<CodecInfo> mCodecInfos; - KeyedVector<AString, size_t> mCodecQuirks; - KeyedVector<AString, size_t> mTypes; + Vector<sp<MediaCodecInfo> > mCodecInfos; + sp<MediaCodecInfo> mCurrentInfo; + sp<IOMX> mOMX; MediaCodecList(); ~MediaCodecList(); status_t initCheck() const; - void parseXMLFile(FILE *file); + void parseXMLFile(const char *path); + void parseTopLevelXMLFile(const char *path); static void StartElementHandlerWrapper( void *me, const char *name, const char **attrs); @@ -93,13 +91,18 @@ private: void startElementHandler(const char *name, const char **attrs); void endElementHandler(const char *name); + status_t includeXMLFile(const char **attrs); status_t addMediaCodecFromAttributes(bool encoder, const char **attrs); void addMediaCodec(bool encoder, const char *name, const char *type = NULL); status_t addQuirk(const char **attrs); status_t addTypeFromAttributes(const char **attrs); + status_t addLimit(const char **attrs); + status_t addFeature(const char **attrs); void addType(const char *name); + status_t initializeCapabilities(const char *type); + DISALLOW_EVIL_CONSTRUCTORS(MediaCodecList); }; diff --git a/include/media/stagefright/MediaCodecSource.h b/include/media/stagefright/MediaCodecSource.h new file mode 100644 index 0000000..e1b2830 --- /dev/null +++ b/include/media/stagefright/MediaCodecSource.h @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MediaCodecSource_H_ +#define MediaCodecSource_H_ + +#include <media/stagefright/foundation/ABase.h> +#include <media/stagefright/foundation/AHandlerReflector.h> +#include <media/stagefright/MediaSource.h> + +namespace android { + +class ALooper; +class AMessage; +class IGraphicBufferProducer; +class MediaCodec; +class MetaData; + +struct MediaCodecSource : public MediaSource, + public MediaBufferObserver { + enum FlagBits { + FLAG_USE_SURFACE_INPUT = 1, + FLAG_USE_METADATA_INPUT = 2, + }; + + static sp<MediaCodecSource> Create( + const sp<ALooper> &looper, + const sp<AMessage> &format, + const sp<MediaSource> &source, + uint32_t flags = 0); + + bool isVideo() const { return mIsVideo; } + sp<IGraphicBufferProducer> getGraphicBufferProducer(); + + // MediaSource + virtual status_t start(MetaData *params = NULL); + virtual status_t stop(); + virtual status_t pause(); + virtual sp<MetaData> getFormat() { return mMeta; } + virtual status_t read( + MediaBuffer **buffer, + const ReadOptions *options = NULL); + + // MediaBufferObserver + virtual void signalBufferReturned(MediaBuffer *buffer); + + // for AHandlerReflector + void onMessageReceived(const sp<AMessage> &msg); + +protected: + virtual ~MediaCodecSource(); + +private: + struct Puller; + + enum { + kWhatPullerNotify, + kWhatEncoderActivity, + kWhatStart, + kWhatStop, + kWhatPause, + }; + + MediaCodecSource( + const sp<ALooper> &looper, + const sp<AMessage> &outputFormat, + const sp<MediaSource> &source, + uint32_t flags = 0); + + status_t onStart(MetaData *params); + status_t init(); + status_t initEncoder(); + void releaseEncoder(); + status_t feedEncoderInputBuffers(); + void scheduleDoMoreWork(); + status_t doMoreWork(); + void suspend(); + void resume(int64_t skipFramesBeforeUs = -1ll); + void signalEOS(status_t err = ERROR_END_OF_STREAM); + bool reachedEOS(); + status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg); + + sp<ALooper> mLooper; + sp<ALooper> mCodecLooper; + sp<AHandlerReflector<MediaCodecSource> > mReflector; + sp<AMessage> mOutputFormat; + sp<MetaData> mMeta; + sp<Puller> mPuller; + sp<MediaCodec> mEncoder; + uint32_t mFlags; + List<uint32_t> mStopReplyIDQueue; + bool mIsVideo; + bool mStarted; + bool mStopping; + bool mDoMoreWorkPending; + sp<AMessage> mEncoderActivityNotify; + sp<IGraphicBufferProducer> mGraphicBufferProducer; + Vector<sp<ABuffer> > mEncoderInputBuffers; + Vector<sp<ABuffer> > mEncoderOutputBuffers; + List<MediaBuffer *> mInputBufferQueue; + List<size_t> mAvailEncoderInputIndices; + List<int64_t> mDecodingTimeQueue; // decoding time (us) for video + + // audio drift time + int64_t mFirstSampleTimeUs; + List<int64_t> mDriftTimeQueue; + + // following variables are protected by mOutputBufferLock + Mutex mOutputBufferLock; + Condition mOutputBufferCond; + List<MediaBuffer*> mOutputBufferQueue; + bool mEncoderReachedEOS; + status_t mErrorCode; + + DISALLOW_EVIL_CONSTRUCTORS(MediaCodecSource); +}; + +} // namespace android + +#endif /* MediaCodecSource_H_ */ diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h index 85693d4..e67d4d5 100644 --- a/include/media/stagefright/MediaDefs.h +++ b/include/media/stagefright/MediaDefs.h @@ -25,6 +25,7 @@ extern const char *MEDIA_MIMETYPE_IMAGE_JPEG; extern const char *MEDIA_MIMETYPE_VIDEO_VP8; extern const char *MEDIA_MIMETYPE_VIDEO_VP9; extern const char *MEDIA_MIMETYPE_VIDEO_AVC; +extern const char *MEDIA_MIMETYPE_VIDEO_HEVC; extern const char *MEDIA_MIMETYPE_VIDEO_MPEG4; extern const char *MEDIA_MIMETYPE_VIDEO_H263; extern const char *MEDIA_MIMETYPE_VIDEO_MPEG2; @@ -38,12 +39,14 @@ extern const char *MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II; extern const char *MEDIA_MIMETYPE_AUDIO_AAC; extern const char *MEDIA_MIMETYPE_AUDIO_QCELP; extern const char *MEDIA_MIMETYPE_AUDIO_VORBIS; +extern const char *MEDIA_MIMETYPE_AUDIO_OPUS; extern const char *MEDIA_MIMETYPE_AUDIO_G711_ALAW; extern const char *MEDIA_MIMETYPE_AUDIO_G711_MLAW; extern const char *MEDIA_MIMETYPE_AUDIO_RAW; extern const char *MEDIA_MIMETYPE_AUDIO_FLAC; extern const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS; extern const char *MEDIA_MIMETYPE_AUDIO_MSGSM; +extern const char *MEDIA_MIMETYPE_AUDIO_AC3; extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4; extern const char *MEDIA_MIMETYPE_CONTAINER_WAV; @@ -57,6 +60,8 @@ extern const char *MEDIA_MIMETYPE_CONTAINER_WVM; extern const char *MEDIA_MIMETYPE_TEXT_3GPP; extern const char *MEDIA_MIMETYPE_TEXT_SUBRIP; +extern const char *MEDIA_MIMETYPE_TEXT_VTT; +extern const char *MEDIA_MIMETYPE_TEXT_CEA_608; } // namespace android diff --git a/include/media/stagefright/MediaErrors.h b/include/media/stagefright/MediaErrors.h index 686f286..2e663ec 100644 --- a/include/media/stagefright/MediaErrors.h +++ b/include/media/stagefright/MediaErrors.h @@ -23,6 +23,18 @@ namespace android { enum { + // status_t map for errors in the media framework + // OK or NO_ERROR or 0 represents no error. + + // See system/core/include/utils/Errors.h + // System standard errors from -1 through (possibly) -133 + // + // Errors with special meanings and side effects. + // INVALID_OPERATION: Operation attempted in an illegal state (will try to signal to app). + // DEAD_OBJECT: Signal from CodecBase to MediaCodec that MediaServer has died. + // NAME_NOT_FOUND: Signal from CodecBase to MediaCodec that the component was not found. + + // Media errors MEDIA_ERROR_BASE = -1000, ERROR_ALREADY_CONNECTED = MEDIA_ERROR_BASE, @@ -46,26 +58,54 @@ enum { // drm/drm_framework_common.h DRM_ERROR_BASE = -2000, - ERROR_DRM_UNKNOWN = DRM_ERROR_BASE, - ERROR_DRM_NO_LICENSE = DRM_ERROR_BASE - 1, - ERROR_DRM_LICENSE_EXPIRED = DRM_ERROR_BASE - 2, - ERROR_DRM_SESSION_NOT_OPENED = DRM_ERROR_BASE - 3, - ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED = DRM_ERROR_BASE - 4, - ERROR_DRM_DECRYPT = DRM_ERROR_BASE - 5, - ERROR_DRM_CANNOT_HANDLE = DRM_ERROR_BASE - 6, - ERROR_DRM_TAMPER_DETECTED = DRM_ERROR_BASE - 7, - ERROR_DRM_NOT_PROVISIONED = DRM_ERROR_BASE - 8, - ERROR_DRM_DEVICE_REVOKED = DRM_ERROR_BASE - 9, - ERROR_DRM_RESOURCE_BUSY = DRM_ERROR_BASE - 10, - - ERROR_DRM_VENDOR_MAX = DRM_ERROR_BASE - 500, - ERROR_DRM_VENDOR_MIN = DRM_ERROR_BASE - 999, + ERROR_DRM_UNKNOWN = DRM_ERROR_BASE, + ERROR_DRM_NO_LICENSE = DRM_ERROR_BASE - 1, + ERROR_DRM_LICENSE_EXPIRED = DRM_ERROR_BASE - 2, + ERROR_DRM_SESSION_NOT_OPENED = DRM_ERROR_BASE - 3, + ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED = DRM_ERROR_BASE - 4, + ERROR_DRM_DECRYPT = DRM_ERROR_BASE - 5, + ERROR_DRM_CANNOT_HANDLE = DRM_ERROR_BASE - 6, + ERROR_DRM_TAMPER_DETECTED = DRM_ERROR_BASE - 7, + ERROR_DRM_NOT_PROVISIONED = DRM_ERROR_BASE - 8, + ERROR_DRM_DEVICE_REVOKED = DRM_ERROR_BASE - 9, + ERROR_DRM_RESOURCE_BUSY = DRM_ERROR_BASE - 10, + ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = DRM_ERROR_BASE - 11, + ERROR_DRM_LAST_USED_ERRORCODE = DRM_ERROR_BASE - 11, + + ERROR_DRM_VENDOR_MAX = DRM_ERROR_BASE - 500, + ERROR_DRM_VENDOR_MIN = DRM_ERROR_BASE - 999, // Heartbeat Error Codes HEARTBEAT_ERROR_BASE = -3000, ERROR_HEARTBEAT_TERMINATE_REQUESTED = HEARTBEAT_ERROR_BASE, + + // NDK Error codes + // frameworks/av/include/ndk/NdkMediaError.h + // from -10000 (0xFFFFD8F0 - 0xFFFFD8EC) + // from -20000 (0xFFFFB1E0 - 0xFFFFB1D7) + + // Codec errors are permitted from 0x80001000 through 0x9000FFFF + ERROR_CODEC_MAX = (signed)0x9000FFFF, + ERROR_CODEC_MIN = (signed)0x80001000, + + // System unknown errors from 0x80000000 - 0x80000007 (INT32_MIN + 7) + // See system/core/include/utils/Errors.h +}; + +// action codes for MediaCodecs that tell the upper layer and application +// the severity of any error. +enum ActionCode { + ACTION_CODE_FATAL, + ACTION_CODE_TRANSIENT, + ACTION_CODE_RECOVERABLE, }; +// returns true if err is a recognized DRM error code +static inline bool isCryptoError(status_t err) { + return (ERROR_DRM_LAST_USED_ERRORCODE <= err && err <= ERROR_DRM_UNKNOWN) + || (ERROR_DRM_VENDOR_MIN <= err && err <= ERROR_DRM_VENDOR_MAX); +} + } // namespace android #endif // MEDIA_ERRORS_H_ diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h index 3076a96..183933a 100644 --- a/include/media/stagefright/MediaExtractor.h +++ b/include/media/stagefright/MediaExtractor.h @@ -65,6 +65,8 @@ public: virtual char* getDrmTrackInfo(size_t trackID, int *len) { return NULL; } + virtual void setUID(uid_t uid) { + } protected: MediaExtractor() : mIsDrm(false) {} diff --git a/include/media/stagefright/MediaHTTP.h b/include/media/stagefright/MediaHTTP.h new file mode 100644 index 0000000..006d8d8 --- /dev/null +++ b/include/media/stagefright/MediaHTTP.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_HTTP_H_ + +#define MEDIA_HTTP_H_ + +#include <media/stagefright/foundation/AString.h> + +#include "include/HTTPBase.h" + +namespace android { + +struct IMediaHTTPConnection; + +struct MediaHTTP : public HTTPBase { + MediaHTTP(const sp<IMediaHTTPConnection> &conn); + + virtual status_t connect( + const char *uri, + const KeyedVector<String8, String8> *headers, + off64_t offset); + + virtual void disconnect(); + + virtual status_t initCheck() const; + + virtual ssize_t readAt(off64_t offset, void *data, size_t size); + + virtual status_t getSize(off64_t *size); + + virtual uint32_t flags(); + + virtual status_t reconnectAtOffset(off64_t offset); + +protected: + virtual ~MediaHTTP(); + + virtual sp<DecryptHandle> DrmInitialization(const char* mime); + virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client); + virtual String8 getUri(); + virtual String8 getMIMEType() const; + +private: + status_t mInitCheck; + sp<IMediaHTTPConnection> mHTTPConnection; + + KeyedVector<String8, String8> mLastHeaders; + AString mLastURI; + + bool mCachedSizeValid; + off64_t mCachedSize; + + sp<DecryptHandle> mDecryptHandle; + DrmManagerClient *mDrmManagerClient; + + void clearDRMState_l(); + + DISALLOW_EVIL_CONSTRUCTORS(MediaHTTP); +}; + +} // namespace android + +#endif // MEDIA_HTTP_H_ diff --git a/include/media/stagefright/MediaMuxer.h b/include/media/stagefright/MediaMuxer.h index ff6a66e..bbe4303 100644 --- a/include/media/stagefright/MediaMuxer.h +++ b/include/media/stagefright/MediaMuxer.h @@ -30,7 +30,7 @@ struct MediaAdapter; struct MediaBuffer; struct MediaSource; struct MetaData; -struct MPEG4Writer; +struct MediaWriter; // MediaMuxer is used to mux multiple tracks into a video. Currently, we only // support a mp4 file as the output. @@ -44,6 +44,7 @@ public: // OutputFormat is updated. enum OutputFormat { OUTPUT_FORMAT_MPEG_4 = 0, + OUTPUT_FORMAT_WEBM = 1, OUTPUT_FORMAT_LIST_END // must be last - used to validate format type }; @@ -115,7 +116,8 @@ public: int64_t timeUs, uint32_t flags) ; private: - sp<MPEG4Writer> mWriter; + const OutputFormat mFormat; + sp<MediaWriter> mWriter; Vector< sp<MediaAdapter> > mTrackList; // Each track has its MediaAdapter. sp<MetaData> mFileMeta; // Metadata for the whole file. diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h index 204d1c6..a653db9 100644 --- a/include/media/stagefright/MediaSource.h +++ b/include/media/stagefright/MediaSource.h @@ -82,6 +82,10 @@ struct MediaSource : public virtual RefBase { void setLateBy(int64_t lateness_us); int64_t getLateBy() const; + void setNonBlocking(); + void clearNonBlocking(); + bool getNonBlocking() const; + private: enum Options { kSeekTo_Option = 1, @@ -91,6 +95,7 @@ struct MediaSource : public virtual RefBase { int64_t mSeekTimeUs; SeekMode mSeekMode; int64_t mLatenessUs; + bool mNonBlocking; }; // Causes this source to suspend pulling data from its upstream source diff --git a/include/media/stagefright/MediaWriter.h b/include/media/stagefright/MediaWriter.h index 5cc8dcf..e27ea1d 100644 --- a/include/media/stagefright/MediaWriter.h +++ b/include/media/stagefright/MediaWriter.h @@ -48,6 +48,9 @@ struct MediaWriter : public RefBase { return OK; } + virtual void setStartTimeOffsetMs(int ms) {} + virtual int32_t getStartTimeOffsetMs() const { return 0; } + protected: virtual ~MediaWriter() {} int64_t mMaxFileSizeLimitBytes; diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h index db8216b..087d016 100644 --- a/include/media/stagefright/MetaData.h +++ b/include/media/stagefright/MetaData.h @@ -53,9 +53,13 @@ enum { kKeyESDS = 'esds', // raw data kKeyAACProfile = 'aacp', // int32_t kKeyAVCC = 'avcc', // raw data + kKeyHVCC = 'hvcc', // raw data kKeyD263 = 'd263', // raw data kKeyVorbisInfo = 'vinf', // raw data kKeyVorbisBooks = 'vboo', // raw data + kKeyOpusHeader = 'ohdr', // raw data + kKeyOpusCodecDelay = 'ocod', // uint64_t (codec delay in ns) + kKeyOpusSeekPreRoll = 'ospr', // uint64_t (seek preroll in ns) kKeyWantsNALFragments = 'NALf', kKeyIsSyncFrame = 'sync', // int32_t (bool) kKeyIsCodecConfig = 'conf', // int32_t (bool) @@ -162,11 +166,19 @@ enum { kKeyCryptoDefaultIVSize = 'cryS', // int32_t kKeyPssh = 'pssh', // raw data + + // Please see MediaFormat.KEY_IS_AUTOSELECT. + kKeyTrackIsAutoselect = 'auto', // bool (int32_t) + // Please see MediaFormat.KEY_IS_DEFAULT. + kKeyTrackIsDefault = 'dflt', // bool (int32_t) + // Similar to MediaFormat.KEY_IS_FORCED_SUBTITLE but pertains to av tracks as well. + kKeyTrackIsForced = 'frcd', // bool (int32_t) }; enum { kTypeESDS = 'esds', kTypeAVCC = 'avcc', + kTypeHVCC = 'hvcc', kTypeD263 = 'd263', }; diff --git a/include/media/stagefright/NuMediaExtractor.h b/include/media/stagefright/NuMediaExtractor.h index 5ae6f6b..402e7f8 100644 --- a/include/media/stagefright/NuMediaExtractor.h +++ b/include/media/stagefright/NuMediaExtractor.h @@ -31,6 +31,7 @@ namespace android { struct ABuffer; struct AMessage; struct DataSource; +struct IMediaHTTPService; struct MediaBuffer; struct MediaExtractor; struct MediaSource; @@ -45,6 +46,7 @@ struct NuMediaExtractor : public RefBase { NuMediaExtractor(); status_t setDataSource( + const sp<IMediaHTTPService> &httpService, const char *path, const KeyedVector<String8, String8> *headers = NULL); diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index daaf20f..e341160 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -28,7 +28,7 @@ namespace android { -struct MediaCodecList; +struct MediaCodecInfo; class MemoryDealer; struct OMXCodecObserver; struct CodecProfileLevel; @@ -115,7 +115,7 @@ struct OMXCodec : public MediaSource, Vector<CodecNameAndQuirks> *matchingCodecNamesAndQuirks); static uint32_t getComponentQuirks( - const MediaCodecList *list, size_t index); + const sp<MediaCodecInfo> &list); static bool findCodecQuirks(const char *componentName, uint32_t *quirks); @@ -248,6 +248,8 @@ private: int32_t numChannels, int32_t sampleRate, int32_t bitRate, int32_t aacProfile, bool isADTS); + status_t setAC3Format(int32_t numChannels, int32_t sampleRate); + void setG711Format(int32_t numChannels); status_t setVideoPortFormatType( @@ -350,6 +352,9 @@ private: int64_t getDecodingTimeUs(); + status_t parseHEVCCodecSpecificData( + const void *data, size_t size, + unsigned *profile, unsigned *level); status_t parseAVCCodecSpecificData( const void *data, size_t size, unsigned *profile, unsigned *level); diff --git a/include/media/stagefright/SkipCutBuffer.h b/include/media/stagefright/SkipCutBuffer.h index 2653b53..098aa69 100644 --- a/include/media/stagefright/SkipCutBuffer.h +++ b/include/media/stagefright/SkipCutBuffer.h @@ -47,6 +47,7 @@ class SkipCutBuffer: public RefBase { private: void write(const char *src, size_t num); size_t read(char *dst, size_t num); + int32_t mSkip; int32_t mFrontPadding; int32_t mBackPadding; int32_t mWriteHead; diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h index db5f947..43b75fd 100644 --- a/include/media/stagefright/SurfaceMediaSource.h +++ b/include/media/stagefright/SurfaceMediaSource.h @@ -111,7 +111,7 @@ public: // pass metadata through the buffers. Currently, it is force set to true bool isMetaDataStoredInVideoBuffers() const; - sp<BufferQueue> getBufferQueue() const { return mBufferQueue; } + sp<IGraphicBufferProducer> getProducer() const { return mProducer; } // To be called before start() status_t setMaxAcquiredBufferCount(size_t count); @@ -139,12 +139,17 @@ protected: // frames is separate than the one calling stop. virtual void onBuffersReleased(); + // SurfaceMediaSource can't handle sideband streams, so this is not expected + // to ever be called. Does nothing. + virtual void onSidebandStreamChanged(); + static bool isExternalFormat(uint32_t format); private: - // mBufferQueue is the exchange point between the producer and - // this consumer - sp<BufferQueue> mBufferQueue; + // A BufferQueue, represented by these interfaces, is the exchange point + // between the producer and this consumer + sp<IGraphicBufferProducer> mProducer; + sp<IGraphicBufferConsumer> mConsumer; struct SlotData { sp<GraphicBuffer> mGraphicBuffer; diff --git a/include/media/stagefright/Utils.h b/include/media/stagefright/Utils.h index bbad271..a795c80 100644 --- a/include/media/stagefright/Utils.h +++ b/include/media/stagefright/Utils.h @@ -53,6 +53,9 @@ AString MakeUserAgent(); // Convert a MIME type to a AudioSystem::audio_format status_t mapMimeToAudioFormat(audio_format_t& format, const char* mime); +// Convert a aac profile to a AudioSystem::audio_format +void mapAACProfileToAudioFormat(audio_format_t& format, uint64_t eAacProfile); + // Send information from MetaData to the HAL via AudioSink status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink, const sp<MetaData>& meta); @@ -60,6 +63,8 @@ status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink, const sp<MetaDa bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, bool isStreaming, audio_stream_type_t streamType); +AString uriDebugString(const AString &uri, bool incognito = false); + } // namespace android #endif // UTILS_H_ diff --git a/include/media/stagefright/foundation/ABase.h b/include/media/stagefright/foundation/ABase.h index 9eceea3..72e3d87 100644 --- a/include/media/stagefright/foundation/ABase.h +++ b/include/media/stagefright/foundation/ABase.h @@ -18,8 +18,37 @@ #define A_BASE_H_ +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) + #define DISALLOW_EVIL_CONSTRUCTORS(name) \ name(const name &); \ name &operator=(const name &) +/* Returns true if the size parameter is safe for new array allocation (32-bit) + * + * Example usage: + * + * if (!isSafeArraySize<uint32_t>(arraySize)) { + * return BAD_VALUE; + * } + * ... + * uint32_t *myArray = new uint32_t[arraySize]; + * + * There is a bug in gcc versions earlier than 4.8 where the new[] array allocation + * will overflow in the internal 32 bit heap allocation, resulting in an + * underallocated array. This is a security issue that allows potential overwriting + * of other heap data. + * + * An alternative to checking is to create a safe new array template function which + * either throws a std::bad_alloc exception or returns NULL/nullptr_t; NULL considered + * safe since normal access of NULL throws an exception. + * + * https://securityblog.redhat.com/2012/10/31/array-allocation-in-cxx/ + */ +template <typename T, typename S> +bool isSafeArraySize(S size) { + return size >= 0 // in case S is signed, ignored if not. + && size <= 0xffffffff / sizeof(T); // max-unsigned-32-bit-int / element-size. +} + #endif // A_BASE_H_ diff --git a/include/media/stagefright/foundation/ABitReader.h b/include/media/stagefright/foundation/ABitReader.h index 5510b12..c3bf0ff 100644 --- a/include/media/stagefright/foundation/ABitReader.h +++ b/include/media/stagefright/foundation/ABitReader.h @@ -25,8 +25,10 @@ namespace android { -struct ABitReader { +class ABitReader { +public: ABitReader(const uint8_t *data, size_t size); + virtual ~ABitReader(); uint32_t getBits(size_t n); void skipBits(size_t n); @@ -37,18 +39,32 @@ struct ABitReader { const uint8_t *data() const; -private: +protected: const uint8_t *mData; size_t mSize; uint32_t mReservoir; // left-aligned bits size_t mNumBitsLeft; - void fillReservoir(); + virtual void fillReservoir(); DISALLOW_EVIL_CONSTRUCTORS(ABitReader); }; +class NALBitReader : public ABitReader { +public: + NALBitReader(const uint8_t *data, size_t size); + + bool atLeastNumBitsLeft(size_t n) const; + +private: + int32_t mNumZeros; + + virtual void fillReservoir(); + + DISALLOW_EVIL_CONSTRUCTORS(NALBitReader); +}; + } // namespace android #endif // A_BIT_READER_H_ diff --git a/include/media/stagefright/foundation/ABuffer.h b/include/media/stagefright/foundation/ABuffer.h index 28f0aed..6294ee7 100644 --- a/include/media/stagefright/foundation/ABuffer.h +++ b/include/media/stagefright/foundation/ABuffer.h @@ -27,6 +27,7 @@ namespace android { struct AMessage; +class MediaBufferBase; struct ABuffer : public RefBase { ABuffer(size_t capacity); @@ -42,11 +43,17 @@ struct ABuffer : public RefBase { void setRange(size_t offset, size_t size); + // create buffer from dup of some memory block + static sp<ABuffer> CreateAsCopy(const void *data, size_t capacity); + void setInt32Data(int32_t data) { mInt32Data = data; } int32_t int32Data() const { return mInt32Data; } sp<AMessage> meta(); + MediaBufferBase *getMediaBufferBase(); + void setMediaBufferBase(MediaBufferBase *mediaBuffer); + protected: virtual ~ABuffer(); @@ -54,6 +61,8 @@ private: sp<AMessage> mFarewell; sp<AMessage> mMeta; + MediaBufferBase *mMediaBufferBase; + void *mData; size_t mCapacity; size_t mRangeOffset; diff --git a/include/media/stagefright/foundation/AHierarchicalStateMachine.h b/include/media/stagefright/foundation/AHierarchicalStateMachine.h index d2e6b28..3bb7d75 100644 --- a/include/media/stagefright/foundation/AHierarchicalStateMachine.h +++ b/include/media/stagefright/foundation/AHierarchicalStateMachine.h @@ -43,13 +43,13 @@ private: DISALLOW_EVIL_CONSTRUCTORS(AState); }; -struct AHierarchicalStateMachine : public AHandler { +struct AHierarchicalStateMachine { AHierarchicalStateMachine(); protected: virtual ~AHierarchicalStateMachine(); - virtual void onMessageReceived(const sp<AMessage> &msg); + virtual void handleMessage(const sp<AMessage> &msg); // Only to be called in response to a message. void changeState(const sp<AState> &state); diff --git a/include/media/stagefright/foundation/ALooperRoster.h b/include/media/stagefright/foundation/ALooperRoster.h index 940fc55..4d76b64 100644 --- a/include/media/stagefright/foundation/ALooperRoster.h +++ b/include/media/stagefright/foundation/ALooperRoster.h @@ -56,8 +56,6 @@ private: KeyedVector<uint32_t, sp<AMessage> > mReplies; - status_t postMessage_l(const sp<AMessage> &msg, int64_t delayUs); - DISALLOW_EVIL_CONSTRUCTORS(ALooperRoster); }; diff --git a/include/media/stagefright/foundation/AMessage.h b/include/media/stagefright/foundation/AMessage.h index 7e823eb..a9e235b 100644 --- a/include/media/stagefright/foundation/AMessage.h +++ b/include/media/stagefright/foundation/AMessage.h @@ -50,6 +50,7 @@ struct AMessage : public RefBase { void setDouble(const char *name, double value); void setPointer(const char *name, void *value); void setString(const char *name, const char *s, ssize_t len = -1); + void setString(const char *name, const AString &s); void setObject(const char *name, const sp<RefBase> &obj); void setBuffer(const char *name, const sp<ABuffer> &buffer); void setMessage(const char *name, const sp<AMessage> &obj); @@ -58,6 +59,8 @@ struct AMessage : public RefBase { const char *name, int32_t left, int32_t top, int32_t right, int32_t bottom); + bool contains(const char *name) const; + bool findInt32(const char *name, int32_t *value) const; bool findInt64(const char *name, int64_t *value) const; bool findSize(const char *name, size_t *value) const; @@ -134,7 +137,9 @@ private: Rect rectValue; } u; const char *mName; + size_t mNameLength; Type mType; + void setName(const char *name, size_t len); }; enum { @@ -144,12 +149,14 @@ private: size_t mNumItems; Item *allocateItem(const char *name); - void freeItem(Item *item); + void freeItemValue(Item *item); const Item *findItem(const char *name, Type type) const; void setObjectInternal( const char *name, const sp<RefBase> &obj, Type type); + size_t findItemIndex(const char *name, size_t len) const; + DISALLOW_EVIL_CONSTRUCTORS(AMessage); }; diff --git a/include/media/stagefright/foundation/AString.h b/include/media/stagefright/foundation/AString.h index 0f8f1e1..7c98699 100644 --- a/include/media/stagefright/foundation/AString.h +++ b/include/media/stagefright/foundation/AString.h @@ -18,14 +18,19 @@ #define A_STRING_H_ +#include <utils/Errors.h> #include <sys/types.h> namespace android { +struct String8; +struct Parcel; + struct AString { AString(); AString(const char *s); AString(const char *s, size_t size); + AString(const String8 &from); AString(const AString &from); AString(const AString &from, size_t offset, size_t n); ~AString(); @@ -67,16 +72,26 @@ struct AString { size_t hash() const; bool operator==(const AString &other) const; + bool operator!=(const AString &other) const { + return !operator==(other); + } bool operator<(const AString &other) const; bool operator>(const AString &other) const; int compare(const AString &other) const; + int compareIgnoreCase(const AString &other) const; + bool equalsIgnoreCase(const AString &other) const; bool startsWith(const char *prefix) const; bool endsWith(const char *suffix) const; + bool startsWithIgnoreCase(const char *prefix) const; + bool endsWithIgnoreCase(const char *suffix) const; void tolower(); + static AString FromParcel(const Parcel &parcel); + status_t writeToParcel(Parcel *parcel) const; + private: static const char *kEmptyString; diff --git a/include/media/stagefright/foundation/MediaBufferBase.h b/include/media/stagefright/foundation/MediaBufferBase.h new file mode 100644 index 0000000..99418fb --- /dev/null +++ b/include/media/stagefright/foundation/MediaBufferBase.h @@ -0,0 +1,40 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_BUFFER_BASE_H_ + +#define MEDIA_BUFFER_BASE_H_ + +namespace android { + +class MediaBufferBase { +public: + MediaBufferBase() {} + + virtual void release() = 0; + virtual void add_ref() = 0; + +protected: + virtual ~MediaBufferBase() {} + +private: + MediaBufferBase(const MediaBufferBase &); + MediaBufferBase &operator=(const MediaBufferBase &); +}; + +} // namespace android + +#endif // MEDIA_BUFFER_BASE_H_ diff --git a/include/media/stagefright/timedtext/TimedTextDriver.h b/include/media/stagefright/timedtext/TimedTextDriver.h index f23c337..37ef674 100644 --- a/include/media/stagefright/timedtext/TimedTextDriver.h +++ b/include/media/stagefright/timedtext/TimedTextDriver.h @@ -25,6 +25,7 @@ namespace android { class ALooper; +struct IMediaHTTPService; class MediaPlayerBase; class MediaSource; class Parcel; @@ -34,7 +35,9 @@ class DataSource; class TimedTextDriver { public: - TimedTextDriver(const wp<MediaPlayerBase> &listener); + TimedTextDriver( + const wp<MediaPlayerBase> &listener, + const sp<IMediaHTTPService> &httpService); ~TimedTextDriver(); @@ -77,6 +80,7 @@ private: sp<ALooper> mLooper; sp<TimedTextPlayer> mPlayer; wp<MediaPlayerBase> mListener; + sp<IMediaHTTPService> mHTTPService; // Variables to be guarded by mLock. State mState; diff --git a/include/ndk/NdkMediaCodec.h b/include/ndk/NdkMediaCodec.h new file mode 100644 index 0000000..c07f4c9 --- /dev/null +++ b/include/ndk/NdkMediaCodec.h @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file defines an NDK API. + * Do not remove methods. + * Do not change method signatures. + * Do not change the value of constants. + * Do not change the size of any of the classes defined in here. + * Do not reference types that are not part of the NDK. + * Do not #include files that aren't part of the NDK. + */ + +#ifndef _NDK_MEDIA_CODEC_H +#define _NDK_MEDIA_CODEC_H + +#include <android/native_window.h> + +#include "NdkMediaCrypto.h" +#include "NdkMediaError.h" +#include "NdkMediaFormat.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +struct AMediaCodec; +typedef struct AMediaCodec AMediaCodec; + +struct AMediaCodecBufferInfo { + int32_t offset; + int32_t size; + int64_t presentationTimeUs; + uint32_t flags; +}; +typedef struct AMediaCodecBufferInfo AMediaCodecBufferInfo; +typedef struct AMediaCodecCryptoInfo AMediaCodecCryptoInfo; + +enum { + AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM = 4, + AMEDIACODEC_CONFIGURE_FLAG_ENCODE = 1, + AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED = -3, + AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED = -2, + AMEDIACODEC_INFO_TRY_AGAIN_LATER = -1 +}; + +/** + * Create codec by name. Use this if you know the exact codec you want to use. + * When configuring, you will need to specify whether to use the codec as an + * encoder or decoder. + */ +AMediaCodec* AMediaCodec_createCodecByName(const char *name); + +/** + * Create codec by mime type. Most applications will use this, specifying a + * mime type obtained from media extractor. + */ +AMediaCodec* AMediaCodec_createDecoderByType(const char *mime_type); + +/** + * Create encoder by name. + */ +AMediaCodec* AMediaCodec_createEncoderByType(const char *mime_type); + +/** + * delete the codec and free its resources + */ +media_status_t AMediaCodec_delete(AMediaCodec*); + +/** + * Configure the codec. For decoding you would typically get the format from an extractor. + */ +media_status_t AMediaCodec_configure( + AMediaCodec*, + const AMediaFormat* format, + ANativeWindow* surface, + AMediaCrypto *crypto, + uint32_t flags); + +/** + * Start the codec. A codec must be configured before it can be started, and must be started + * before buffers can be sent to it. + */ +media_status_t AMediaCodec_start(AMediaCodec*); + +/** + * Stop the codec. + */ +media_status_t AMediaCodec_stop(AMediaCodec*); + +/* + * Flush the codec's input and output. All indices previously returned from calls to + * AMediaCodec_dequeueInputBuffer and AMediaCodec_dequeueOutputBuffer become invalid. + */ +media_status_t AMediaCodec_flush(AMediaCodec*); + +/** + * Get an input buffer. The specified buffer index must have been previously obtained from + * dequeueInputBuffer, and not yet queued. + */ +uint8_t* AMediaCodec_getInputBuffer(AMediaCodec*, size_t idx, size_t *out_size); + +/** + * Get an output buffer. The specified buffer index must have been previously obtained from + * dequeueOutputBuffer, and not yet queued. + */ +uint8_t* AMediaCodec_getOutputBuffer(AMediaCodec*, size_t idx, size_t *out_size); + +/** + * Get the index of the next available input buffer. An app will typically use this with + * getInputBuffer() to get a pointer to the buffer, then copy the data to be encoded or decoded + * into the buffer before passing it to the codec. + */ +ssize_t AMediaCodec_dequeueInputBuffer(AMediaCodec*, int64_t timeoutUs); + +/** + * Send the specified buffer to the codec for processing. + */ +media_status_t AMediaCodec_queueInputBuffer(AMediaCodec*, + size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags); + +/** + * Send the specified buffer to the codec for processing. + */ +media_status_t AMediaCodec_queueSecureInputBuffer(AMediaCodec*, + size_t idx, off_t offset, AMediaCodecCryptoInfo*, uint64_t time, uint32_t flags); + +/** + * Get the index of the next available buffer of processed data. + */ +ssize_t AMediaCodec_dequeueOutputBuffer(AMediaCodec*, AMediaCodecBufferInfo *info, int64_t timeoutUs); +AMediaFormat* AMediaCodec_getOutputFormat(AMediaCodec*); + +/** + * If you are done with a buffer, use this call to return the buffer to + * the codec. If you previously specified a surface when configuring this + * video decoder you can optionally render the buffer. + */ +media_status_t AMediaCodec_releaseOutputBuffer(AMediaCodec*, size_t idx, bool render); + +/** + * If you are done with a buffer, use this call to update its surface timestamp + * and return it to the codec to render it on the output surface. If you + * have not specified an output surface when configuring this video codec, + * this call will simply return the buffer to the codec. + * + * For more details, see the Java documentation for MediaCodec.releaseOutputBuffer. + */ +media_status_t AMediaCodec_releaseOutputBufferAtTime( + AMediaCodec *mData, size_t idx, int64_t timestampNs); + + +typedef enum { + AMEDIACODECRYPTOINFO_MODE_CLEAR = 0, + AMEDIACODECRYPTOINFO_MODE_AES_CTR = 1 +} cryptoinfo_mode_t; + +/** + * Create an AMediaCodecCryptoInfo from scratch. Use this if you need to use custom + * crypto info, rather than one obtained from AMediaExtractor. + * + * AMediaCodecCryptoInfo describes the structure of an (at least + * partially) encrypted input sample. + * A buffer's data is considered to be partitioned into "subsamples", + * each subsample starts with a (potentially empty) run of plain, + * unencrypted bytes followed by a (also potentially empty) run of + * encrypted bytes. + * numBytesOfClearData can be null to indicate that all data is encrypted. + * This information encapsulates per-sample metadata as outlined in + * ISO/IEC FDIS 23001-7:2011 "Common encryption in ISO base media file format files". + */ +AMediaCodecCryptoInfo *AMediaCodecCryptoInfo_new( + int numsubsamples, + uint8_t key[16], + uint8_t iv[16], + cryptoinfo_mode_t mode, + size_t *clearbytes, + size_t *encryptedbytes); + +/** + * delete an AMediaCodecCryptoInfo created previously with AMediaCodecCryptoInfo_new, or + * obtained from AMediaExtractor + */ +media_status_t AMediaCodecCryptoInfo_delete(AMediaCodecCryptoInfo*); + +/** + * The number of subsamples that make up the buffer's contents. + */ +size_t AMediaCodecCryptoInfo_getNumSubSamples(AMediaCodecCryptoInfo*); + +/** + * A 16-byte opaque key + */ +media_status_t AMediaCodecCryptoInfo_getKey(AMediaCodecCryptoInfo*, uint8_t *dst); + +/** + * A 16-byte initialization vector + */ +media_status_t AMediaCodecCryptoInfo_getIV(AMediaCodecCryptoInfo*, uint8_t *dst); + +/** + * The type of encryption that has been applied, + * one of AMEDIACODECRYPTOINFO_MODE_CLEAR or AMEDIACODECRYPTOINFO_MODE_AES_CTR. + */ +cryptoinfo_mode_t AMediaCodecCryptoInfo_getMode(AMediaCodecCryptoInfo*); + +/** + * The number of leading unencrypted bytes in each subsample. + */ +media_status_t AMediaCodecCryptoInfo_getClearBytes(AMediaCodecCryptoInfo*, size_t *dst); + +/** + * The number of trailing encrypted bytes in each subsample. + */ +media_status_t AMediaCodecCryptoInfo_getEncryptedBytes(AMediaCodecCryptoInfo*, size_t *dst); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif //_NDK_MEDIA_CODEC_H diff --git a/include/ndk/NdkMediaCrypto.h b/include/ndk/NdkMediaCrypto.h new file mode 100644 index 0000000..90374c5 --- /dev/null +++ b/include/ndk/NdkMediaCrypto.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/* + * This file defines an NDK API. + * Do not remove methods. + * Do not change method signatures. + * Do not change the value of constants. + * Do not change the size of any of the classes defined in here. + * Do not reference types that are not part of the NDK. + * Do not #include files that aren't part of the NDK. + */ + +#ifndef _NDK_MEDIA_CRYPTO_H +#define _NDK_MEDIA_CRYPTO_H + +#include <sys/types.h> +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct AMediaCrypto; +typedef struct AMediaCrypto AMediaCrypto; + +typedef uint8_t AMediaUUID[16]; + +bool AMediaCrypto_isCryptoSchemeSupported(const AMediaUUID uuid); + +bool AMediaCrypto_requiresSecureDecoderComponent(const char *mime); + +AMediaCrypto* AMediaCrypto_new(const AMediaUUID uuid, const void *initData, size_t initDataSize); + +void AMediaCrypto_delete(AMediaCrypto* crypto); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _NDK_MEDIA_CRYPTO_H diff --git a/include/ndk/NdkMediaDrm.h b/include/ndk/NdkMediaDrm.h new file mode 100644 index 0000000..10afdd9 --- /dev/null +++ b/include/ndk/NdkMediaDrm.h @@ -0,0 +1,455 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file defines an NDK API. + * Do not remove methods. + * Do not change method signatures. + * Do not change the value of constants. + * Do not change the size of any of the classes defined in here. + * Do not reference types that are not part of the NDK. + * Do not #include files that aren't part of the NDK. + */ + +#ifndef _NDK_MEDIA_DRM_H +#define _NDK_MEDIA_DRM_H + +#include "NdkMediaError.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include <stdbool.h> + +struct AMediaDrm; +typedef struct AMediaDrm AMediaDrm; + +typedef struct { + const uint8_t *ptr; + size_t length; +} AMediaDrmByteArray; + +typedef AMediaDrmByteArray AMediaDrmSessionId; +typedef AMediaDrmByteArray AMediaDrmScope; +typedef AMediaDrmByteArray AMediaDrmKeySetId; +typedef AMediaDrmByteArray AMediaDrmSecureStop; + + +typedef enum AMediaDrmEventType { + /** + * This event type indicates that the app needs to request a certificate from + * the provisioning server. The request message data is obtained using + * AMediaDrm_getProvisionRequest. + */ + EVENT_PROVISION_REQUIRED = 1, + + /** + * This event type indicates that the app needs to request keys from a license + * server. The request message data is obtained using AMediaDrm_getKeyRequest. + */ + EVENT_KEY_REQUIRED = 2, + + /** + * This event type indicates that the licensed usage duration for keys in a session + * has expired. The keys are no longer valid. + */ + EVENT_KEY_EXPIRED = 3, + + /** + * This event may indicate some specific vendor-defined condition, see your + * DRM provider documentation for details + */ + EVENT_VENDOR_DEFINED = 4 +} AMediaDrmEventType; + +typedef void (*AMediaDrmEventListener)(AMediaDrm *, const AMediaDrmSessionId *sessionId, + AMediaDrmEventType eventType, int extra, const uint8_t *data, size_t dataSize); + + +/** + * Query if the given scheme identified by its UUID is supported on this device, and + * whether the drm plugin is able to handle the media container format specified by mimeType. + * + * uuid identifies the universal unique ID of the crypto scheme. uuid must be 16 bytes. + * mimeType is the MIME type of the media container, e.g. "video/mp4". If mimeType + * is not known or required, it can be provided as NULL. + */ +bool AMediaDrm_isCryptoSchemeSupported(const uint8_t *uuid, const char *mimeType); + +/** + * Create a MediaDrm instance from a UUID + * uuid identifies the universal unique ID of the crypto scheme. uuid must be 16 bytes. + */ +AMediaDrm* AMediaDrm_createByUUID(const uint8_t *uuid); + +/** + * Release a MediaDrm object + */ +void AMediaDrm_release(AMediaDrm *); + +/** + * Register a callback to be invoked when an event occurs + * + * listener is the callback that will be invoked on event + */ +media_status_t AMediaDrm_setOnEventListener(AMediaDrm *, AMediaDrmEventListener listener); + +/** + * Open a new session with the MediaDrm object. A session ID is returned. + * + * returns MEDIADRM_NOT_PROVISIONED_ERROR if provisioning is needed + * returns MEDIADRM_RESOURCE_BUSY_ERROR if required resources are in use + */ +media_status_t AMediaDrm_openSession(AMediaDrm *, AMediaDrmSessionId *sessionId); + +/** + * Close a session on the MediaDrm object that was previously opened + * with AMediaDrm_openSession. + */ +media_status_t AMediaDrm_closeSession(AMediaDrm *, const AMediaDrmSessionId *sessionId); + +typedef enum AMediaDrmKeyType { + /** + * This key request type species that the keys will be for online use, they will + * not be saved to the device for subsequent use when the device is not connected + * to a network. + */ + KEY_TYPE_STREAMING = 1, + + /** + * This key request type specifies that the keys will be for offline use, they + * will be saved to the device for use when the device is not connected to a network. + */ + KEY_TYPE_OFFLINE = 2, + + /** + * This key request type specifies that previously saved offline keys should be released. + */ + KEY_TYPE_RELEASE = 3 +} AMediaDrmKeyType; + +/** + * Data type containing {key, value} pair + */ +typedef struct AMediaDrmKeyValuePair { + const char *mKey; + const char *mValue; +} AMediaDrmKeyValue; + +/** + * A key request/response exchange occurs between the app and a license server + * to obtain or release keys used to decrypt encrypted content. + * AMediaDrm_getKeyRequest is used to obtain an opaque key request byte array that + * is delivered to the license server. The opaque key request byte array is + * returned in KeyRequest.data. The recommended URL to deliver the key request to + * is returned in KeyRequest.defaultUrl. + * + * After the app has received the key request response from the server, + * it should deliver to the response to the DRM engine plugin using the method + * AMediaDrm_provideKeyResponse. + * + * scope may be a sessionId or a keySetId, depending on the specified keyType. + * When the keyType is KEY_TYPE_STREAMING or KEY_TYPE_OFFLINE, scope should be set + * to the sessionId the keys will be provided to. When the keyType is + * KEY_TYPE_RELEASE, scope should be set to the keySetId of the keys being released. + * Releasing keys from a device invalidates them for all sessions. + * + * init container-specific data, its meaning is interpreted based on the mime type + * provided in the mimeType parameter. It could contain, for example, the content + * ID, key ID or other data obtained from the content metadata that is required in + * generating the key request. init may be null when keyType is KEY_TYPE_RELEASE. + * + * initSize is the number of bytes of initData + * + * mimeType identifies the mime type of the content. + * + * keyType specifes the type of the request. The request may be to acquire keys for + * streaming or offline content, or to release previously acquired keys, which are + * identified by a keySetId. + * + * optionalParameters are included in the key request message to allow a client + * application to provide additional message parameters to the server. + * + * numOptionalParameters indicates the number of optional parameters provided + * by the caller + * + * On exit: + * 1. The keyRequest pointer will reference the opaque key request data. It + * will reside in memory owned by the AMediaDrm object, and will remain + * accessible until the next call to AMediaDrm_getKeyRequest or until the + * MediaDrm object is released. + * 2. keyRequestSize will be set to the size of the request + * + * returns MEDIADRM_NOT_PROVISIONED_ERROR if reprovisioning is needed, due to a + * problem with the device certificate. +*/ +media_status_t AMediaDrm_getKeyRequest(AMediaDrm *, const AMediaDrmScope *scope, + const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType, + const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters, + const uint8_t **keyRequest, size_t *keyRequestSize); + +/** + * A key response is received from the license server by the app, then it is + * provided to the DRM engine plugin using provideKeyResponse. When the + * response is for an offline key request, a keySetId is returned that can be + * used to later restore the keys to a new session with AMediaDrm_restoreKeys. + * When the response is for a streaming or release request, a null keySetId is + * returned. + * + * scope may be a sessionId or keySetId depending on the type of the + * response. Scope should be set to the sessionId when the response is for either + * streaming or offline key requests. Scope should be set to the keySetId when + * the response is for a release request. + * + * response points to the opaque response from the server + * responseSize should be set to the size of the response in bytes + */ + +media_status_t AMediaDrm_provideKeyResponse(AMediaDrm *, const AMediaDrmScope *scope, + const uint8_t *response, size_t responseSize, AMediaDrmKeySetId *keySetId); + +/** + * Restore persisted offline keys into a new session. keySetId identifies the + * keys to load, obtained from a prior call to AMediaDrm_provideKeyResponse. + * + * sessionId is the session ID for the DRM session + * keySetId identifies the saved key set to restore + */ +media_status_t AMediaDrm_restoreKeys(AMediaDrm *, const AMediaDrmSessionId *sessionId, + const AMediaDrmKeySetId *keySetId); + +/** + * Remove the current keys from a session. + * + * keySetId identifies keys to remove + */ +media_status_t AMediaDrm_removeKeys(AMediaDrm *, const AMediaDrmSessionId *keySetId); + +/** + * Request an informative description of the key status for the session. The status is + * in the form of {key, value} pairs. Since DRM license policies vary by vendor, + * the specific status field names are determined by each DRM vendor. Refer to your + * DRM provider documentation for definitions of the field names for a particular + * DRM engine plugin. + * + * On entry, numPairs should be set by the caller to the maximum number of pairs + * that can be returned (the size of the array). On exit, numPairs will be set + * to the number of entries written to the array. If the number of {key, value} pairs + * to be returned is greater than *numPairs, MEDIADRM_SHORT_BUFFER will be returned + * and numPairs will be set to the number of pairs available. + */ +media_status_t AMediaDrm_queryKeyStatus(AMediaDrm *, const AMediaDrmSessionId *sessionId, + AMediaDrmKeyValue *keyValuePairs, size_t *numPairs); + + +/** + * A provision request/response exchange occurs between the app and a provisioning + * server to retrieve a device certificate. If provisionining is required, the + * EVENT_PROVISION_REQUIRED event will be sent to the event handler. + * getProvisionRequest is used to obtain the opaque provision request byte array that + * should be delivered to the provisioning server. + * On exit: + * 1. The provision request data will be referenced by provisionRequest, in + * memory owned by the AMediaDrm object. It will remain accessible until the + * next call to getProvisionRequest. + * 2. provisionRequestSize will be set to the size of the request data. + * 3. serverUrl will reference a NULL terminated string containing the URL + * the provisioning request should be sent to. It will remain accessible until + * the next call to getProvisionRequest. + */ +media_status_t AMediaDrm_getProvisionRequest(AMediaDrm *, const uint8_t **provisionRequest, + size_t *provisionRequestSize, const char **serverUrl); + + +/** + * After a provision response is received by the app, it is provided to the DRM + * engine plugin using this method. + * + * response is the opaque provisioning response byte array to provide to the + * DRM engine plugin. + * responseSize is the length of the provisioning response in bytes. + * + * returns MEDIADRM_DEVICE_REVOKED_ERROR if the response indicates that the + * server rejected the request + */ +media_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *, + const uint8_t *response, size_t responseSize); + + +/** + * A means of enforcing limits on the number of concurrent streams per subscriber + * across devices is provided via SecureStop. This is achieved by securely + * monitoring the lifetime of sessions. + * + * Information from the server related to the current playback session is written + * to persistent storage on the device when each MediaCrypto object is created. + * + * In the normal case, playback will be completed, the session destroyed and the + * Secure Stops will be queried. The app queries secure stops and forwards the + * secure stop message to the server which verifies the signature and notifies the + * server side database that the session destruction has been confirmed. The persisted + * record on the client is only removed after positive confirmation that the server + * received the message using releaseSecureStops(). + * + * numSecureStops is set by the caller to the maximum number of secure stops to + * return. On exit, *numSecureStops will be set to the number actually returned. + * If *numSecureStops is too small for the number of secure stops available, + * MEDIADRM_SHORT_BUFFER will be returned and *numSecureStops will be set to the + * number required. + */ +media_status_t AMediaDrm_getSecureStops(AMediaDrm *, + AMediaDrmSecureStop *secureStops, size_t *numSecureStops); + +/** + * Process the SecureStop server response message ssRelease. After authenticating + * the message, remove the SecureStops identified in the response. + * + * ssRelease is the server response indicating which secure stops to release + */ +media_status_t AMediaDrm_releaseSecureStops(AMediaDrm *, + const AMediaDrmSecureStop *ssRelease); + +/** + * String property name: identifies the maker of the DRM engine plugin + */ +const char *PROPERTY_VENDOR = "vendor"; + +/** + * String property name: identifies the version of the DRM engine plugin + */ +const char *PROPERTY_VERSION = "version"; + +/** + * String property name: describes the DRM engine plugin + */ +const char *PROPERTY_DESCRIPTION = "description"; + +/** + * String property name: a comma-separated list of cipher and mac algorithms + * supported by CryptoSession. The list may be empty if the DRM engine + * plugin does not support CryptoSession operations. + */ +const char *PROPERTY_ALGORITHMS = "algorithms"; + +/** + * Read a DRM engine plugin String property value, given the property name string. + * + * propertyName identifies the property to query + * On return, propertyValue will be set to point to the property value. The + * memory that the value resides in is owned by the NDK MediaDrm API and + * will remain valid until the next call to AMediaDrm_getPropertyString. + */ +media_status_t AMediaDrm_getPropertyString(AMediaDrm *, const char *propertyName, + const char **propertyValue); + +/** + * Byte array property name: the device unique identifier is established during + * device provisioning and provides a means of uniquely identifying each device. + */ +const char *PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId"; + +/** + * Read a DRM engine plugin byte array property value, given the property name string. + * On return, *propertyValue will be set to point to the property value. The + * memory that the value resides in is owned by the NDK MediaDrm API and + * will remain valid until the next call to AMediaDrm_getPropertyByteArray. + */ +media_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *, const char *propertyName, + AMediaDrmByteArray *propertyValue); + +/** + * Set a DRM engine plugin String property value. + */ +media_status_t AMediaDrm_setPropertyString(AMediaDrm *, const char *propertyName, + const char *value); + +/** + * Set a DRM engine plugin byte array property value. + */ +media_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *, const char *propertyName, + const uint8_t *value, size_t valueSize); + +/** + * In addition to supporting decryption of DASH Common Encrypted Media, the + * MediaDrm APIs provide the ability to securely deliver session keys from + * an operator's session key server to a client device, based on the factory-installed + * root of trust, and then perform encrypt, decrypt, sign and verify operations + * with the session key on arbitrary user data. + * + * Operators create session key servers that receive session key requests and provide + * encrypted session keys which can be used for general purpose crypto operations. + * + * Generic encrypt/decrypt/sign/verify methods are based on the established session + * keys. These keys are exchanged using the getKeyRequest/provideKeyResponse methods. + * + * Applications of this capability include securing various types of purchased or + * private content, such as applications, books and other media, photos or media + * delivery protocols. + */ + +/* + * Encrypt the data referenced by input of length dataSize using algorithm specified + * by cipherAlgorithm, and write the encrypted result into output. The caller must + * ensure that the output buffer is large enough to accept dataSize bytes. The key + * to use is identified by the 16 byte keyId. The key must have been loaded into + * the session using provideKeyResponse. + */ +media_status_t AMediaDrm_encrypt(AMediaDrm *, const AMediaDrmSessionId *sessionId, + const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv, + const uint8_t *input, uint8_t *output, size_t dataSize); + +/* + * Decrypt the data referenced by input of length dataSize using algorithm specified + * by cipherAlgorithm, and write the decrypted result into output. The caller must + * ensure that the output buffer is large enough to accept dataSize bytes. The key + * to use is identified by the 16 byte keyId. The key must have been loaded into + * the session using provideKeyResponse. + */ +media_status_t AMediaDrm_decrypt(AMediaDrm *, const AMediaDrmSessionId *sessionId, + const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv, + const uint8_t *input, uint8_t *output, size_t dataSize); + +/* + * Generate a signature using the specified macAlgorithm over the message data + * referenced by message of size messageSize and store the signature in the + * buffer referenced signature of max size *signatureSize. If the buffer is not + * large enough to hold the signature, MEDIADRM_SHORT_BUFFER is returned and + * *signatureSize is set to the buffer size required. The key to use is identified + * by the 16 byte keyId. The key must have been loaded into the session using + * provideKeyResponse. + */ +media_status_t AMediaDrm_sign(AMediaDrm *, const AMediaDrmSessionId *sessionId, + const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize, + uint8_t *signature, size_t *signatureSize); + +/* + * Perform a signature verification using the specified macAlgorithm over the message + * data referenced by the message parameter of size messageSize. Returns MEDIADRM_OK + * if the signature matches, otherwise MEDAIDRM_VERIFY_FAILED is returned. The key to + * use is identified by the 16 byte keyId. The key must have been loaded into the + * session using provideKeyResponse. + */ +media_status_t AMediaDrm_verify(AMediaDrm *, const AMediaDrmSessionId *sessionId, + const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize, + const uint8_t *signature, size_t signatureSize); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif //_NDK_MEDIA_DRM_H diff --git a/include/ndk/NdkMediaError.h b/include/ndk/NdkMediaError.h new file mode 100644 index 0000000..12613eb --- /dev/null +++ b/include/ndk/NdkMediaError.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/* + * This file defines an NDK API. + * Do not remove methods. + * Do not change method signatures. + * Do not change the value of constants. + * Do not change the size of any of the classes defined in here. + * Do not reference types that are not part of the NDK. + * Do not #include files that aren't part of the NDK. + */ + +#ifndef _NDK_MEDIA_ERROR_H +#define _NDK_MEDIA_ERROR_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + AMEDIA_OK = 0, + + AMEDIA_ERROR_BASE = -10000, + AMEDIA_ERROR_UNKNOWN = AMEDIA_ERROR_BASE, + AMEDIA_ERROR_MALFORMED = AMEDIA_ERROR_BASE - 1, + AMEDIA_ERROR_UNSUPPORTED = AMEDIA_ERROR_BASE - 2, + AMEDIA_ERROR_INVALID_OBJECT = AMEDIA_ERROR_BASE - 3, + AMEDIA_ERROR_INVALID_PARAMETER = AMEDIA_ERROR_BASE - 4, + + AMEDIA_DRM_ERROR_BASE = -20000, + AMEDIA_DRM_NOT_PROVISIONED = AMEDIA_DRM_ERROR_BASE - 1, + AMEDIA_DRM_RESOURCE_BUSY = AMEDIA_DRM_ERROR_BASE - 2, + AMEDIA_DRM_DEVICE_REVOKED = AMEDIA_DRM_ERROR_BASE - 3, + AMEDIA_DRM_SHORT_BUFFER = AMEDIA_DRM_ERROR_BASE - 4, + AMEDIA_DRM_SESSION_NOT_OPENED = AMEDIA_DRM_ERROR_BASE - 5, + AMEDIA_DRM_TAMPER_DETECTED = AMEDIA_DRM_ERROR_BASE - 6, + AMEDIA_DRM_VERIFY_FAILED = AMEDIA_DRM_ERROR_BASE - 7, + AMEDIA_DRM_NEED_KEY = AMEDIA_DRM_ERROR_BASE - 8, + AMEDIA_DRM_LICENSE_EXPIRED = AMEDIA_DRM_ERROR_BASE - 9, + +} media_status_t; + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _NDK_MEDIA_ERROR_H diff --git a/include/ndk/NdkMediaExtractor.h b/include/ndk/NdkMediaExtractor.h new file mode 100644 index 0000000..7a4e702 --- /dev/null +++ b/include/ndk/NdkMediaExtractor.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/* + * This file defines an NDK API. + * Do not remove methods. + * Do not change method signatures. + * Do not change the value of constants. + * Do not change the size of any of the classes defined in here. + * Do not reference types that are not part of the NDK. + * Do not #include files that aren't part of the NDK. + */ + +#ifndef _NDK_MEDIA_EXTRACTOR_H +#define _NDK_MEDIA_EXTRACTOR_H + +#include <sys/types.h> + +#include "NdkMediaCodec.h" +#include "NdkMediaFormat.h" +#include "NdkMediaCrypto.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct AMediaExtractor; +typedef struct AMediaExtractor AMediaExtractor; + + +/** + * Create new media extractor + */ +AMediaExtractor* AMediaExtractor_new(); + +/** + * Delete a previously created media extractor + */ +media_status_t AMediaExtractor_delete(AMediaExtractor*); + +/** + * Set the file descriptor from which the extractor will read. + */ +media_status_t AMediaExtractor_setDataSourceFd(AMediaExtractor*, int fd, off64_t offset, off64_t length); + +/** + * Set the URI from which the extractor will read. + */ +media_status_t AMediaExtractor_setDataSource(AMediaExtractor*, const char *location); // TODO support headers + +/** + * Return the number of tracks in the previously specified media file + */ +size_t AMediaExtractor_getTrackCount(AMediaExtractor*); + +/** + * Return the format of the specified track. The caller must free the returned format + */ +AMediaFormat* AMediaExtractor_getTrackFormat(AMediaExtractor*, size_t idx); + +/** + * Select the specified track. Subsequent calls to readSampleData, getSampleTrackIndex and + * getSampleTime only retrieve information for the subset of tracks selected. + * Selecting the same track multiple times has no effect, the track is + * only selected once. + */ +media_status_t AMediaExtractor_selectTrack(AMediaExtractor*, size_t idx); + +/** + * Unselect the specified track. Subsequent calls to readSampleData, getSampleTrackIndex and + * getSampleTime only retrieve information for the subset of tracks selected.. + */ +media_status_t AMediaExtractor_unselectTrack(AMediaExtractor*, size_t idx); + +/** + * Read the current sample. + */ +ssize_t AMediaExtractor_readSampleData(AMediaExtractor*, uint8_t *buffer, size_t capacity); + +/** + * Read the current sample's flags. + */ +uint32_t AMediaExtractor_getSampleFlags(AMediaExtractor*); // see definitions below + +/** + * Returns the track index the current sample originates from (or -1 + * if no more samples are available) + */ +int AMediaExtractor_getSampleTrackIndex(AMediaExtractor*); + +/** + * Returns the current sample's presentation time in microseconds. + * or -1 if no more samples are available. + */ +int64_t AMediaExtractor_getSampleTime(AMediaExtractor*); + +/** + * Advance to the next sample. Returns false if no more sample data + * is available (end of stream). + */ +bool AMediaExtractor_advance(AMediaExtractor*); + +typedef enum { + AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC, + AMEDIAEXTRACTOR_SEEK_NEXT_SYNC, + AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC +} SeekMode; + +/** + * + */ +media_status_t AMediaExtractor_seekTo(AMediaExtractor*, int64_t seekPosUs, SeekMode mode); + +/** + * mapping of crypto scheme uuid to the scheme specific data for that scheme + */ +typedef struct PsshEntry { + AMediaUUID uuid; + size_t datalen; + void *data; +} PsshEntry; + +/** + * list of crypto schemes and their data + */ +typedef struct PsshInfo { + size_t numentries; + PsshEntry entries[0]; +} PsshInfo; + +/** + * Get the PSSH info if present. + */ +PsshInfo* AMediaExtractor_getPsshInfo(AMediaExtractor*); + + +AMediaCodecCryptoInfo *AMediaExtractor_getSampleCryptoInfo(AMediaExtractor *); + + +enum { + AMEDIAEXTRACTOR_SAMPLE_FLAG_SYNC = 1, + AMEDIAEXTRACTOR_SAMPLE_FLAG_ENCRYPTED = 2, +}; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _NDK_MEDIA_EXTRACTOR_H diff --git a/include/ndk/NdkMediaFormat.h b/include/ndk/NdkMediaFormat.h new file mode 100644 index 0000000..ab29791 --- /dev/null +++ b/include/ndk/NdkMediaFormat.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file defines an NDK API. + * Do not remove methods. + * Do not change method signatures. + * Do not change the value of constants. + * Do not change the size of any of the classes defined in here. + * Do not reference types that are not part of the NDK. + * Do not #include files that aren't part of the NDK. + */ + +#ifndef _NDK_MEDIA_FORMAT_H +#define _NDK_MEDIA_FORMAT_H + +#include <sys/types.h> + +#include "NdkMediaError.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct AMediaFormat; +typedef struct AMediaFormat AMediaFormat; + +AMediaFormat *AMediaFormat_new(); +media_status_t AMediaFormat_delete(AMediaFormat*); + +/** + * Human readable representation of the format. The returned string is owned by the format, + * and remains valid until the next call to toString, or until the format is deleted. + */ +const char* AMediaFormat_toString(AMediaFormat*); + +bool AMediaFormat_getInt32(AMediaFormat*, const char *name, int32_t *out); +bool AMediaFormat_getInt64(AMediaFormat*, const char *name, int64_t *out); +bool AMediaFormat_getFloat(AMediaFormat*, const char *name, float *out); +/** + * The returned data is owned by the format and remains valid as long as the named entry + * is part of the format. + */ +bool AMediaFormat_getBuffer(AMediaFormat*, const char *name, void** data, size_t *size); +/** + * The returned string is owned by the format, and remains valid until the next call to getString, + * or until the format is deleted. + */ +bool AMediaFormat_getString(AMediaFormat*, const char *name, const char **out); + + +void AMediaFormat_setInt32(AMediaFormat*, const char* name, int32_t value); +void AMediaFormat_setInt64(AMediaFormat*, const char* name, int64_t value); +void AMediaFormat_setFloat(AMediaFormat*, const char* name, float value); +/** + * The provided string is copied into the format. + */ +void AMediaFormat_setString(AMediaFormat*, const char* name, const char* value); +/** + * The provided data is copied into the format. + */ +void AMediaFormat_setBuffer(AMediaFormat*, const char* name, void* data, size_t size); + + + +/** + * XXX should these be ints/enums that we look up in a table as needed? + */ +extern const char* AMEDIAFORMAT_KEY_AAC_PROFILE; +extern const char* AMEDIAFORMAT_KEY_BIT_RATE; +extern const char* AMEDIAFORMAT_KEY_CHANNEL_COUNT; +extern const char* AMEDIAFORMAT_KEY_CHANNEL_MASK; +extern const char* AMEDIAFORMAT_KEY_COLOR_FORMAT; +extern const char* AMEDIAFORMAT_KEY_DURATION; +extern const char* AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL; +extern const char* AMEDIAFORMAT_KEY_FRAME_RATE; +extern const char* AMEDIAFORMAT_KEY_HEIGHT; +extern const char* AMEDIAFORMAT_KEY_IS_ADTS; +extern const char* AMEDIAFORMAT_KEY_IS_AUTOSELECT; +extern const char* AMEDIAFORMAT_KEY_IS_DEFAULT; +extern const char* AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE; +extern const char* AMEDIAFORMAT_KEY_I_FRAME_INTERVAL; +extern const char* AMEDIAFORMAT_KEY_LANGUAGE; +extern const char* AMEDIAFORMAT_KEY_MAX_HEIGHT; +extern const char* AMEDIAFORMAT_KEY_MAX_INPUT_SIZE; +extern const char* AMEDIAFORMAT_KEY_MAX_WIDTH; +extern const char* AMEDIAFORMAT_KEY_MIME; +extern const char* AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP; +extern const char* AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER; +extern const char* AMEDIAFORMAT_KEY_SAMPLE_RATE; +extern const char* AMEDIAFORMAT_KEY_WIDTH; +extern const char* AMEDIAFORMAT_KEY_STRIDE; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _NDK_MEDIA_FORMAT_H diff --git a/include/ndk/NdkMediaMuxer.h b/include/ndk/NdkMediaMuxer.h new file mode 100644 index 0000000..90d946c --- /dev/null +++ b/include/ndk/NdkMediaMuxer.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/* + * This file defines an NDK API. + * Do not remove methods. + * Do not change method signatures. + * Do not change the value of constants. + * Do not change the size of any of the classes defined in here. + * Do not reference types that are not part of the NDK. + * Do not #include files that aren't part of the NDK. + */ + +#ifndef _NDK_MEDIA_MUXER_H +#define _NDK_MEDIA_MUXER_H + +#include <sys/types.h> + +#include "NdkMediaCodec.h" +#include "NdkMediaError.h" +#include "NdkMediaFormat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct AMediaMuxer; +typedef struct AMediaMuxer AMediaMuxer; + +typedef enum { + AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4 = 0, + AMEDIAMUXER_OUTPUT_FORMAT_WEBM = 1, +} OutputFormat; + +/** + * Create new media muxer + */ +AMediaMuxer* AMediaMuxer_new(int fd, OutputFormat format); + +/** + * Delete a previously created media muxer + */ +media_status_t AMediaMuxer_delete(AMediaMuxer*); + +/** + * Set and store the geodata (latitude and longitude) in the output file. + * This method should be called before AMediaMuxer_start. The geodata is stored + * in udta box if the output format is AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4, and is + * ignored for other output formats. + * The geodata is stored according to ISO-6709 standard. + * + * Both values are specified in degrees. + * Latitude must be in the range [-90, 90]. + * Longitude must be in the range [-180, 180]. + */ +media_status_t AMediaMuxer_setLocation(AMediaMuxer*, float latitude, float longitude); + +/** + * Sets the orientation hint for output video playback. + * This method should be called before AMediaMuxer_start. Calling this + * method will not rotate the video frame when muxer is generating the file, + * but add a composition matrix containing the rotation angle in the output + * video if the output format is AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4, so that a + * video player can choose the proper orientation for playback. + * Note that some video players may choose to ignore the composition matrix + * during playback. + * The angle is specified in degrees, clockwise. + * The supported angles are 0, 90, 180, and 270 degrees. + */ +media_status_t AMediaMuxer_setOrientationHint(AMediaMuxer*, int degrees); + +/** + * Adds a track with the specified format. + * Returns the index of the new track or a negative value in case of failure, + * which can be interpreted as a media_status_t. + */ +ssize_t AMediaMuxer_addTrack(AMediaMuxer*, const AMediaFormat* format); + +/** + * Start the muxer. Should be called after AMediaMuxer_addTrack and + * before AMediaMuxer_writeSampleData. + */ +media_status_t AMediaMuxer_start(AMediaMuxer*); + +/** + * Stops the muxer. + * Once the muxer stops, it can not be restarted. + */ +media_status_t AMediaMuxer_stop(AMediaMuxer*); + +/** + * Writes an encoded sample into the muxer. + * The application needs to make sure that the samples are written into + * the right tracks. Also, it needs to make sure the samples for each track + * are written in chronological order (e.g. in the order they are provided + * by the encoder.) + */ +media_status_t AMediaMuxer_writeSampleData(AMediaMuxer *muxer, + size_t trackIdx, const uint8_t *data, const AMediaCodecBufferInfo *info); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _NDK_MEDIA_MUXER_H diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h index 2d033e6..fa1b20a 100644 --- a/include/private/media/AudioTrackShared.h +++ b/include/private/media/AudioTrackShared.h @@ -20,6 +20,7 @@ #include <stdint.h> #include <sys/types.h> +#include <audio_utils/minifloat.h> #include <utils/threads.h> #include <utils/Log.h> #include <utils/RefBase.h> @@ -48,7 +49,7 @@ namespace android { #define CBLK_STREAM_END_DONE 0x400 // set by server on render completion, cleared by client //EL_FIXME 20 seconds may not be enough and must be reconciled with new obtainBuffer implementation -#define MAX_RUN_OFFLOADED_TIMEOUT_MS 20000 //assuming upto a maximum of 20 seconds of offloaded +#define MAX_RUN_OFFLOADED_TIMEOUT_MS 20000 // assuming up to a maximum of 20 seconds of offloaded struct AudioTrackSharedStreaming { // similar to NBAIO MonoPipe @@ -98,11 +99,7 @@ struct audio_track_cblk_t // The value should be used "for entertainment purposes only", // which means don't make important decisions based on it. - size_t frameCount_; // used during creation to pass actual track buffer size - // from AudioFlinger to client, and not referenced again - // FIXME remove here and replace by createTrack() in/out - // parameter - // renamed to "_" to detect incorrect use + uint32_t mPad1; // unused volatile int32_t mFutex; // event flag: down (P) by client, // up (V) by server or binderDied() or interrupt() @@ -114,11 +111,8 @@ private: // force to 32-bit. The client and server may have different typedefs for size_t. uint32_t mMinimum; // server wakes up client if available >= mMinimum - // Channel volumes are fixed point U4.12, so 0x1000 means 1.0. - // Left channel is in [0:15], right channel is in [16:31]. - // Always read and write the combined pair atomically. - // For AudioTrack only, not used by AudioRecord. - uint32_t mVolumeLR; + // Stereo gains for AudioTrack only, not used by AudioRecord. + gain_minifloat_packed_t mVolumeLR; uint32_t mSampleRate; // AudioTrack only: client's requested sample rate in Hz // or 0 == default. Write-only client, read-only server. @@ -181,12 +175,11 @@ protected: // Proxy seen by AudioTrack client and AudioRecord client class ClientProxy : public Proxy { -protected: +public: ClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t frameSize, bool isOut, bool clientInServer); virtual ~ClientProxy() { } -public: static const struct timespec kForever; static const struct timespec kNonBlocking; @@ -289,8 +282,8 @@ public: mCblk->mSendLevel = uint16_t(sendLevel * 0x1000); } - // caller must limit to 0 <= volumeLR <= 0x10001000 - void setVolumeLR(uint32_t volumeLR) { + // set stereo gains + void setVolumeLR(gain_minifloat_packed_t volumeLR) { mCblk->mVolumeLR = volumeLR; } @@ -400,8 +393,10 @@ protected: class AudioTrackServerProxy : public ServerProxy { public: AudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, - size_t frameSize, bool clientInServer = false) - : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer) { } + size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0) + : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer) { + mCblk->mSampleRate = sampleRate; + } protected: virtual ~AudioTrackServerProxy() { } @@ -409,7 +404,7 @@ public: // return value of these methods must be validated by the caller uint32_t getSampleRate() const { return mCblk->mSampleRate; } uint16_t getSendLevel_U4_12() const { return mCblk->mSendLevel; } - uint32_t getVolumeLR() const { return mCblk->mVolumeLR; } + gain_minifloat_packed_t getVolumeLR() const { return mCblk->mVolumeLR; } // estimated total number of filled frames available to server to read, // which may include non-contiguous frames @@ -464,9 +459,8 @@ private: class AudioRecordServerProxy : public ServerProxy { public: AudioRecordServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, - size_t frameSize) - : ServerProxy(cblk, buffers, frameCount, frameSize, false /*isOut*/, - false /*clientInServer*/) { } + size_t frameSize, bool clientInServer) + : ServerProxy(cblk, buffers, frameCount, frameSize, false /*isOut*/, clientInServer) { } protected: virtual ~AudioRecordServerProxy() { } }; diff --git a/include/soundtrigger/ISoundTrigger.h b/include/soundtrigger/ISoundTrigger.h new file mode 100644 index 0000000..5fd8eb2 --- /dev/null +++ b/include/soundtrigger/ISoundTrigger.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_ISOUNDTRIGGER_H +#define ANDROID_HARDWARE_ISOUNDTRIGGER_H + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> +#include <binder/IMemory.h> +#include <system/sound_trigger.h> + +namespace android { + +class ISoundTrigger : public IInterface +{ +public: + DECLARE_META_INTERFACE(SoundTrigger); + + virtual void detach() = 0; + + virtual status_t loadSoundModel(const sp<IMemory>& modelMemory, + sound_model_handle_t *handle) = 0; + + virtual status_t unloadSoundModel(sound_model_handle_t handle) = 0; + + virtual status_t startRecognition(sound_model_handle_t handle, + const sp<IMemory>& dataMemory) = 0; + virtual status_t stopRecognition(sound_model_handle_t handle) = 0; + +}; + +// ---------------------------------------------------------------------------- + +class BnSoundTrigger: public BnInterface<ISoundTrigger> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif //ANDROID_HARDWARE_ISOUNDTRIGGER_H diff --git a/include/soundtrigger/ISoundTriggerClient.h b/include/soundtrigger/ISoundTriggerClient.h new file mode 100644 index 0000000..480429a --- /dev/null +++ b/include/soundtrigger/ISoundTriggerClient.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_ISOUNDTRIGGER_CLIENT_H +#define ANDROID_HARDWARE_ISOUNDTRIGGER_CLIENT_H + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> + +namespace android { + +class ISoundTriggerClient : public IInterface +{ +public: + + DECLARE_META_INTERFACE(SoundTriggerClient); + + virtual void onRecognitionEvent(const sp<IMemory>& eventMemory) = 0; + + virtual void onSoundModelEvent(const sp<IMemory>& eventMemory) = 0; + + virtual void onServiceStateChange(const sp<IMemory>& eventMemory) = 0; + +}; + +// ---------------------------------------------------------------------------- + +class BnSoundTriggerClient : public BnInterface<ISoundTriggerClient> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif //ANDROID_HARDWARE_ISOUNDTRIGGER_CLIENT_H diff --git a/include/soundtrigger/ISoundTriggerHwService.h b/include/soundtrigger/ISoundTriggerHwService.h new file mode 100644 index 0000000..ae0cb01 --- /dev/null +++ b/include/soundtrigger/ISoundTriggerHwService.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_ISOUNDTRIGGER_SERVICE_H +#define ANDROID_HARDWARE_ISOUNDTRIGGER_SERVICE_H + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> +#include <system/sound_trigger.h> + +namespace android { + +class ISoundTrigger; +class ISoundTriggerClient; + +class ISoundTriggerHwService : public IInterface +{ +public: + + DECLARE_META_INTERFACE(SoundTriggerHwService); + + virtual status_t listModules(struct sound_trigger_module_descriptor *modules, + uint32_t *numModules) = 0; + + virtual status_t attach(const sound_trigger_module_handle_t handle, + const sp<ISoundTriggerClient>& client, + sp<ISoundTrigger>& module) = 0; + + virtual status_t setCaptureState(bool active) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnSoundTriggerHwService: public BnInterface<ISoundTriggerHwService> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +}; // namespace android + +#endif //ANDROID_HARDWARE_ISOUNDTRIGGER_SERVICE_H diff --git a/include/soundtrigger/SoundTrigger.h b/include/soundtrigger/SoundTrigger.h new file mode 100644 index 0000000..bf5e1de --- /dev/null +++ b/include/soundtrigger/SoundTrigger.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_SOUNDTRIGGER_H +#define ANDROID_HARDWARE_SOUNDTRIGGER_H + +#include <binder/IBinder.h> +#include <utils/threads.h> +#include <soundtrigger/SoundTriggerCallback.h> +#include <soundtrigger/ISoundTrigger.h> +#include <soundtrigger/ISoundTriggerHwService.h> +#include <soundtrigger/ISoundTriggerClient.h> +#include <system/sound_trigger.h> + +namespace android { + +class MemoryDealer; + +class SoundTrigger : public BnSoundTriggerClient, + public IBinder::DeathRecipient +{ +public: + + virtual ~SoundTrigger(); + + static status_t listModules(struct sound_trigger_module_descriptor *modules, + uint32_t *numModules); + static sp<SoundTrigger> attach(const sound_trigger_module_handle_t module, + const sp<SoundTriggerCallback>& callback); + + static status_t setCaptureState(bool active); + + void detach(); + + status_t loadSoundModel(const sp<IMemory>& modelMemory, + sound_model_handle_t *handle); + + status_t unloadSoundModel(sound_model_handle_t handle); + + status_t startRecognition(sound_model_handle_t handle, const sp<IMemory>& dataMemory); + status_t stopRecognition(sound_model_handle_t handle); + + // BpSoundTriggerClient + virtual void onRecognitionEvent(const sp<IMemory>& eventMemory); + virtual void onSoundModelEvent(const sp<IMemory>& eventMemory); + virtual void onServiceStateChange(const sp<IMemory>& eventMemory); + + //IBinder::DeathRecipient + virtual void binderDied(const wp<IBinder>& who); + + static status_t stringToGuid(const char *str, sound_trigger_uuid_t *guid); + static status_t guidToString(const sound_trigger_uuid_t *guid, + char *str, size_t maxLen); + +private: + SoundTrigger(sound_trigger_module_handle_t module, + const sp<SoundTriggerCallback>&); + static const sp<ISoundTriggerHwService>& getSoundTriggerHwService(); + + Mutex mLock; + sp<ISoundTrigger> mISoundTrigger; + const sound_trigger_module_handle_t mModule; + sp<SoundTriggerCallback> mCallback; +}; + +}; // namespace android + +#endif //ANDROID_HARDWARE_SOUNDTRIGGER_H diff --git a/include/soundtrigger/SoundTriggerCallback.h b/include/soundtrigger/SoundTriggerCallback.h new file mode 100644 index 0000000..b5277f2 --- /dev/null +++ b/include/soundtrigger/SoundTriggerCallback.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_SOUNDTRIGGER_CALLBACK_H +#define ANDROID_HARDWARE_SOUNDTRIGGER_CALLBACK_H + +#include <utils/RefBase.h> +#include <system/sound_trigger.h> + +namespace android { + +class SoundTriggerCallback : public RefBase +{ +public: + + SoundTriggerCallback() {} + virtual ~SoundTriggerCallback() {} + + virtual void onRecognitionEvent(struct sound_trigger_recognition_event *event) = 0; + + virtual void onSoundModelEvent(struct sound_trigger_model_event *event) = 0; + + virtual void onServiceStateChange(sound_trigger_service_state_t state) = 0; + + virtual void onServiceDied() = 0; + +}; + +}; // namespace android + +#endif //ANDROID_HARDWARE_SOUNDTRIGGER_CALLBACK_H |