diff options
Diffstat (limited to 'include')
102 files changed, 3767 insertions, 1018 deletions
diff --git a/include/camera/CameraMetadata.h b/include/camera/CameraMetadata.h index 1254d3c..953d711 100644 --- a/include/camera/CameraMetadata.h +++ b/include/camera/CameraMetadata.h @@ -56,7 +56,7 @@ class CameraMetadata {       * thread-safety, it simply prevents the camera_metadata_t pointer returned       * here from being accidentally invalidated by CameraMetadata operations.       */ -    const camera_metadata_t* getAndLock(); +    const camera_metadata_t* getAndLock() const;      /**       * Unlock the CameraMetadata for use again. After this unlock, the pointer @@ -208,7 +208,7 @@ class CameraMetadata {    private:      camera_metadata_t *mBuffer; -    bool               mLocked; +    mutable bool       mLocked;      /**       * Check if tag has a given type diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h index c6074fc..ba33ffe 100644 --- a/include/camera/CameraParameters.h +++ b/include/camera/CameraParameters.h @@ -108,6 +108,9 @@ public:       */      void getSupportedPreviewFormats(Vector<int>& formats) const; +    // Returns true if no keys are present +    bool isEmpty() 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. diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h index f7f06bb..5f85635 100644 --- a/include/camera/ICameraService.h +++ b/include/camera/ICameraService.h @@ -25,8 +25,6 @@ namespace android {  class ICamera;  class ICameraClient; -class IProCameraUser; -class IProCameraCallbacks;  class ICameraServiceListener;  class ICameraDeviceUser;  class ICameraDeviceCallbacks; @@ -44,7 +42,6 @@ public:          GET_NUMBER_OF_CAMERAS = IBinder::FIRST_CALL_TRANSACTION,          GET_CAMERA_INFO,          CONNECT, -        CONNECT_PRO,          CONNECT_DEVICE,          ADD_LISTENER,          REMOVE_LISTENER, @@ -53,6 +50,8 @@ public:          GET_LEGACY_PARAMETERS,          SUPPORTS_CAMERA_API,          CONNECT_LEGACY, +        SET_TORCH_MODE, +        NOTIFY_SYSTEM_EVENT,      };      enum { @@ -66,7 +65,18 @@ public:      enum {          CAMERA_HAL_API_VERSION_UNSPECIFIED = -1 -      }; +    }; + +    /** +     * Keep up-to-date with declarations in +     * frameworks/base/services/core/java/com/android/server/camera/CameraService.java +     * +     * These event codes are intended to be used with the notifySystemEvent call. +     */ +    enum { +        NO_EVENT = 0, +        USER_SWITCHED, +    };  public:      DECLARE_META_INTERFACE(CameraService); @@ -104,13 +114,6 @@ public:              /*out*/              sp<ICamera>& device) = 0; -    virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, -            int cameraId, -            const String16& clientPackageName, -            int clientUid, -            /*out*/ -            sp<IProCameraUser>& device) = 0; -      virtual status_t connectDevice(              const sp<ICameraDeviceCallbacks>& cameraCb,              int cameraId, @@ -142,6 +145,26 @@ public:              int clientUid,              /*out*/              sp<ICamera>& device) = 0; + +    /** +     * Turn on or off a camera's torch mode. Torch mode will be turned off by +     * camera service if the lastest client binder that turns it on dies. +     * +     * return values: +     * 0:       on a successful operation. +     * -ENOSYS: the camera device doesn't support this operation. It it returned +     *          if and only if android.flash.into.available is false. +     * -EBUSY:  the camera device is opened. +     * -EINVAL: camera_id is invalid or clientBinder is NULL when enabling a +     *          torch mode. +     */ +    virtual status_t setTorchMode(const String16& cameraId, bool enabled, +            const sp<IBinder>& clientBinder) = 0; + +    /** +     * Notify the camera service of a system event.  Should only be called from system_server. +     */ +    virtual void notifySystemEvent(int32_t eventId, const int32_t* args, size_t length) = 0;  };  // ---------------------------------------------------------------------------- diff --git a/include/camera/ICameraServiceListener.h b/include/camera/ICameraServiceListener.h index 0a0e43a..709ff31 100644 --- a/include/camera/ICameraServiceListener.h +++ b/include/camera/ICameraServiceListener.h @@ -66,9 +66,35 @@ public:          STATUS_UNKNOWN          = 0xFFFFFFFF,      }; +    /** +     * The torch mode status of a camera. +     * +     * Initial status will be transmitted with onTorchStatusChanged immediately +     * after this listener is added to the service listener list. +     * +     * The enums should be set to values matching +     * include/hardware/camera_common.h +     */ +    enum TorchStatus { +        // The camera's torch mode has become not available to use via +        // setTorchMode(). +        TORCH_STATUS_NOT_AVAILABLE  = TORCH_MODE_STATUS_NOT_AVAILABLE, +        // The camera's torch mode is off and available to be turned on via +        // setTorchMode(). +        TORCH_STATUS_AVAILABLE_OFF  = TORCH_MODE_STATUS_AVAILABLE_OFF, +        // The camera's torch mode is on and available to be turned off via +        // setTorchMode(). +        TORCH_STATUS_AVAILABLE_ON   = TORCH_MODE_STATUS_AVAILABLE_ON, + +        // Use to initialize variables only +        TORCH_STATUS_UNKNOWN        = 0xFFFFFFFF, +    }; +      DECLARE_META_INTERFACE(CameraServiceListener);      virtual void onStatusChanged(Status status, int32_t cameraId) = 0; + +    virtual void onTorchStatusChanged(TorchStatus status, const String16& cameraId) = 0;  };  // ---------------------------------------------------------------------------- diff --git a/include/camera/ICameraServiceProxy.h b/include/camera/ICameraServiceProxy.h new file mode 100644 index 0000000..12a555f --- /dev/null +++ b/include/camera/ICameraServiceProxy.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_ICAMERASERVICEPROXY_H +#define ANDROID_HARDWARE_ICAMERASERVICEPROXY_H + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> + +namespace android { + +class ICameraServiceProxy : public IInterface { +public: +    enum { +        PING_FOR_USER_UPDATE = IBinder::FIRST_CALL_TRANSACTION, +    }; + +    DECLARE_META_INTERFACE(CameraServiceProxy); + +    virtual void pingForUserUpdate() = 0; +}; + +class BnCameraServiceProxy: public BnInterface<ICameraServiceProxy> +{ +public: +    virtual status_t    onTransact( uint32_t code, +                                    const Parcel& data, +                                    Parcel* reply, +                                    uint32_t flags = 0); +}; + + + +}; // namespace android + +#endif // ANDROID_HARDWARE_ICAMERASERVICEPROXY_H + + diff --git a/include/camera/IProCameraCallbacks.h b/include/camera/IProCameraCallbacks.h deleted file mode 100644 index e8abb89..0000000 --- a/include/camera/IProCameraCallbacks.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_IPROCAMERA_CALLBACKS_H -#define ANDROID_HARDWARE_IPROCAMERA_CALLBACKS_H - -#include <utils/RefBase.h> -#include <binder/IInterface.h> -#include <binder/Parcel.h> -#include <binder/IMemory.h> -#include <utils/Timers.h> -#include <system/camera.h> - -struct camera_metadata; - -namespace android { - -class IProCameraCallbacks : public IInterface -{ -    /** -     * Keep up-to-date with IProCameraCallbacks.aidl in frameworks/base -     */ -public: -    DECLARE_META_INTERFACE(ProCameraCallbacks); - -    virtual void            notifyCallback(int32_t msgType, -                                           int32_t ext1, -                                           int32_t ext2) = 0; - -    enum LockStatus { -        LOCK_ACQUIRED, -        LOCK_RELEASED, -        LOCK_STOLEN, -    }; - -    virtual void            onLockStatusChanged(LockStatus newLockStatus) = 0; - -    /** Missing by design: implementation is client-side in ProCamera.cpp **/ -    // virtual void onBufferReceived(int streamId, -    //                               const CpuConsumer::LockedBufer& buf); -    virtual void            onResultReceived(int32_t requestId, -                                             camera_metadata* result) = 0; -}; - -// ---------------------------------------------------------------------------- - -class BnProCameraCallbacks : public BnInterface<IProCameraCallbacks> -{ -public: -    virtual status_t    onTransact( uint32_t code, -                                    const Parcel& data, -                                    Parcel* reply, -                                    uint32_t flags = 0); -}; - -}; // namespace android - -#endif diff --git a/include/camera/IProCameraUser.h b/include/camera/IProCameraUser.h deleted file mode 100644 index 2ccc4d2..0000000 --- a/include/camera/IProCameraUser.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_IPROCAMERAUSER_H -#define ANDROID_HARDWARE_IPROCAMERAUSER_H - -#include <utils/RefBase.h> -#include <binder/IInterface.h> -#include <binder/Parcel.h> -#include <binder/IMemory.h> -#include <utils/String8.h> -#include <camera/IProCameraCallbacks.h> - -struct camera_metadata; - -namespace android { - -class IProCameraUserClient; -class IGraphicBufferProducer; -class Surface; - -class IProCameraUser: public IInterface -{ -    /** -     * Keep up-to-date with IProCameraUser.aidl in frameworks/base -     */ -public: -    DECLARE_META_INTERFACE(ProCameraUser); - -    virtual void            disconnect() = 0; - -    // connect to the service, given a callbacks listener -    virtual status_t        connect(const sp<IProCameraCallbacks>& callbacks) -                                                                            = 0; - -    /** -     * Locking -     **/ -    virtual status_t        exclusiveTryLock() = 0; -    virtual status_t        exclusiveLock() = 0; -    virtual status_t        exclusiveUnlock() = 0; - -    virtual bool            hasExclusiveLock() = 0; - -    /** -     * Request Handling -     **/ - -    // Note that the callee gets a copy of the metadata. -    virtual int             submitRequest(struct camera_metadata* metadata, -                                          bool streaming = false) = 0; -    virtual status_t        cancelRequest(int requestId) = 0; - -    virtual status_t        deleteStream(int streamId) = 0; -    virtual status_t        createStream( -                                      int width, int height, int format, -                                      const sp<IGraphicBufferProducer>& bufferProducer, -                                      /*out*/ -                                      int* streamId) = 0; - -    // Create a request object from a template. -    virtual status_t        createDefaultRequest(int templateId, -                                                 /*out*/ -                                                 camera_metadata** request) -                                                                           = 0; - -    // Get static camera metadata -    virtual status_t        getCameraInfo(int cameraId, -                                          /*out*/ -                                          camera_metadata** info) = 0; - -}; - -// ---------------------------------------------------------------------------- - -class BnProCameraUser: public BnInterface<IProCameraUser> -{ -public: -    virtual status_t    onTransact( uint32_t code, -                                    const Parcel& data, -                                    Parcel* reply, -                                    uint32_t flags = 0); -}; - -}; // namespace android - -#endif diff --git a/include/camera/ProCamera.h b/include/camera/ProCamera.h deleted file mode 100644 index e9b687a..0000000 --- a/include/camera/ProCamera.h +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_PRO_CAMERA_H -#define ANDROID_HARDWARE_PRO_CAMERA_H - -#include <utils/Timers.h> -#include <utils/KeyedVector.h> -#include <gui/IGraphicBufferProducer.h> -#include <system/camera.h> -#include <camera/IProCameraCallbacks.h> -#include <camera/IProCameraUser.h> -#include <camera/Camera.h> -#include <camera/CameraMetadata.h> -#include <camera/ICameraService.h> -#include <gui/CpuConsumer.h> - -#include <gui/Surface.h> - -#include <utils/Condition.h> -#include <utils/Mutex.h> - -#include <camera/CameraBase.h> - -struct camera_metadata; - -namespace android { - -// All callbacks on this class are concurrent -// (they come from separate threads) -class ProCameraListener : virtual public RefBase -{ -public: -    virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0; - -    // Lock has been acquired. Write operations now available. -    virtual void onLockAcquired() = 0; -    // Lock has been released with exclusiveUnlock. -    virtual void onLockReleased() = 0; -    // Lock has been stolen by another client. -    virtual void onLockStolen() = 0; - -    // Lock free. -    virtual void onTriggerNotify(int32_t msgType, int32_t ext1, int32_t ext2) -                                                                            = 0; -    // onFrameAvailable and OnResultReceived can come in with any order, -    // use android.sensor.timestamp and LockedBuffer.timestamp to correlate them - -    /** -      * A new metadata buffer has been received. -      * -- Ownership of request passes on to the callee, free with -      *    free_camera_metadata. -      */ -    virtual void onResultReceived(int32_t frameId, camera_metadata* result) = 0; - -    // TODO: make onFrameAvailable pure virtual - -    // A new frame buffer has been received for this stream. -    // -- This callback only fires for createStreamCpu streams -    // -- A buffer may be obtained by calling cpuConsumer->lockNextBuffer -    // -- Use buf.timestamp to correlate with result's android.sensor.timestamp -    // -- The buffer should be accessed with CpuConsumer::lockNextBuffer -    //      and CpuConsumer::unlockBuffer -    virtual void onFrameAvailable(int /*streamId*/, -                                  const sp<CpuConsumer>& /*cpuConsumer*/) { -    } - -}; - -class ProCamera; - -template <> -struct CameraTraits<ProCamera> -{ -    typedef ProCameraListener     TCamListener; -    typedef IProCameraUser        TCamUser; -    typedef IProCameraCallbacks   TCamCallbacks; -    typedef status_t (ICameraService::*TCamConnectService)(const sp<IProCameraCallbacks>&, -                                                           int, const String16&, int, -                                                           /*out*/ -                                                           sp<IProCameraUser>&); -    static TCamConnectService     fnConnectService; -}; - - -class ProCamera : -    public CameraBase<ProCamera>, -    public BnProCameraCallbacks -{ -public: -    /** -     * Connect a shared camera. By default access is restricted to read only -     * (Lock free) operations. To be able to submit custom requests a lock needs -     * to be acquired with exclusive[Try]Lock. -     */ -    static sp<ProCamera> connect(int cameraId); -    virtual ~ProCamera(); - -    /** -     * Exclusive Locks: -     * - We may request exclusive access to a camera if no other -     *   clients are using the camera. This works as a traditional -     *   client, writing/reading any camera state. -     * - An application opening the camera (a regular 'Camera') will -     *   always steal away the exclusive lock from a ProCamera, -     *   this will call onLockReleased. -     * - onLockAcquired will be called again once it is possible -     *   to again exclusively lock the camera. -     * -     */ - -    /** -     * All exclusiveLock/unlock functions are asynchronous. The remote endpoint -     * shall not block while waiting to acquire the lock. Instead the lock -     * notifications will come in asynchronously on the listener. -     */ - -    /** -      * Attempt to acquire the lock instantly (non-blocking) -      * - If this succeeds, you do not need to wait for onLockAcquired -      *   but the event will still be fired -      * -      * Returns -EBUSY if already locked. 0 on success. -      */ -    status_t exclusiveTryLock(); -    // always returns 0. wait for onLockAcquired before lock is acquired. -    status_t exclusiveLock(); -    // release a lock if we have one, or cancel the lock request. -    status_t exclusiveUnlock(); - -    // exclusive lock = do whatever we want. no lock = read only. -    bool hasExclusiveLock(); - -    /** -     * < 0 error, >= 0 the request ID. streaming to have the request repeat -     *    until cancelled. -     * The request queue is flushed when a lock is released or stolen -     *    if not locked will return PERMISSION_DENIED -     */ -    int submitRequest(const struct camera_metadata* metadata, -                                                        bool streaming = false); -    // if not locked will return PERMISSION_DENIED, BAD_VALUE if requestId bad -    status_t cancelRequest(int requestId); - -    /** -     * Ask for a stream to be enabled. -     * Lock free. Service maintains counter of streams. -     */ -    status_t requestStream(int streamId); -// TODO: remove requestStream, its useless. - -    /** -      * Delete a stream. -      * Lock free. -      * -      * NOTE: As a side effect this cancels ALL streaming requests. -      * -      * Errors: BAD_VALUE if unknown stream ID. -      *         PERMISSION_DENIED if the stream wasn't yours -      */ -    status_t deleteStream(int streamId); - -    /** -      * Create a new HW stream, whose sink will be the window. -      * Lock free. Service maintains counter of streams. -      * Errors: -EBUSY if too many streams created -      */ -    status_t createStream(int width, int height, int format, -                          const sp<Surface>& surface, -                          /*out*/ -                          int* streamId); - -    /** -      * Create a new HW stream, whose sink will be the SurfaceTexture. -      * Lock free. Service maintains counter of streams. -      * Errors: -EBUSY if too many streams created -      */ -    status_t createStream(int width, int height, int format, -                          const sp<IGraphicBufferProducer>& bufferProducer, -                          /*out*/ -                          int* streamId); -    status_t createStreamCpu(int width, int height, int format, -                          int heapCount, -                          /*out*/ -                          sp<CpuConsumer>* cpuConsumer, -                          int* streamId); -    status_t createStreamCpu(int width, int height, int format, -                          int heapCount, -                          bool synchronousMode, -                          /*out*/ -                          sp<CpuConsumer>* cpuConsumer, -                          int* streamId); - -    // Create a request object from a template. -    status_t createDefaultRequest(int templateId, -                                 /*out*/ -                                  camera_metadata** request) const; - -    // Get static camera metadata -    camera_metadata* getCameraInfo(int cameraId); - -    // Blocks until a frame is available (CPU streams only) -    // - Obtain the frame data by calling CpuConsumer::lockNextBuffer -    // - Release the frame data after use with CpuConsumer::unlockBuffer -    // Return value: -    // - >0 - number of frames available to be locked -    // - <0 - error (refer to error codes) -    // Error codes: -    // -ETIMEDOUT if it took too long to get a frame -    int waitForFrameBuffer(int streamId); - -    // Blocks until a metadata result is available -    // - Obtain the metadata by calling consumeFrameMetadata() -    // Error codes: -    // -ETIMEDOUT if it took too long to get a frame -    status_t waitForFrameMetadata(); - -    // Get the latest metadata. This is destructive. -    // - Calling this repeatedly will produce empty metadata objects. -    // - Use waitForFrameMetadata to sync until new data is available. -    CameraMetadata consumeFrameMetadata(); - -    // Convenience method to drop frame buffers (CPU streams only) -    // Return values: -    //  >=0 - number of frames dropped (up to count) -    //  <0  - error code -    // Error codes: -    //   BAD_VALUE - invalid streamId or count passed -    int dropFrameBuffer(int streamId, int count); - -protected: -    //////////////////////////////////////////////////////// -    // IProCameraCallbacks implementation -    //////////////////////////////////////////////////////// -    virtual void        notifyCallback(int32_t msgType, -                                       int32_t ext, -                                       int32_t ext2); - -    virtual void        onLockStatusChanged( -                                IProCameraCallbacks::LockStatus newLockStatus); - -    virtual void        onResultReceived(int32_t requestId, -                                         camera_metadata* result); -private: -    ProCamera(int cameraId); - -    class ProFrameListener : public CpuConsumer::FrameAvailableListener { -    public: -        ProFrameListener(wp<ProCamera> camera, int streamID) { -            mCamera = camera; -            mStreamId = streamID; -        } - -    protected: -        virtual void onFrameAvailable(const BufferItem& /* item */) { -            sp<ProCamera> c = mCamera.promote(); -            if (c.get() != NULL) { -                c->onFrameAvailable(mStreamId); -            } -        } - -    private: -        wp<ProCamera> mCamera; -        int mStreamId; -    }; -    friend class ProFrameListener; - -    struct StreamInfo -    { -        StreamInfo(int streamId) { -            this->streamID = streamId; -            cpuStream = false; -            frameReady = 0; -        } - -        StreamInfo() { -            streamID = -1; -            cpuStream = false; -        } - -        int  streamID; -        bool cpuStream; -        sp<CpuConsumer> cpuConsumer; -        bool synchronousMode; -        sp<ProFrameListener> frameAvailableListener; -        sp<Surface> stc; -        int frameReady; -    }; - -    Condition mWaitCondition; -    Mutex     mWaitMutex; -    static const nsecs_t mWaitTimeout = 1000000000; // 1sec -    KeyedVector<int, StreamInfo> mStreams; -    bool mMetadataReady; -    CameraMetadata mLatestMetadata; - -    void onFrameAvailable(int streamId); - -    StreamInfo& getStreamInfo(int streamId); - -    friend class CameraBase; -}; - -}; // namespace android - -#endif diff --git a/include/camera/camera2/CaptureRequest.h b/include/camera/camera2/CaptureRequest.h index e56d61f..eeab217 100644 --- a/include/camera/camera2/CaptureRequest.h +++ b/include/camera/camera2/CaptureRequest.h @@ -30,6 +30,7 @@ public:      CameraMetadata          mMetadata;      Vector<sp<Surface> >    mSurfaceList; +    bool                    mIsReprocess;      /**       * Keep impl up-to-date with CaptureRequest.java in frameworks/base diff --git a/include/camera/camera2/ICameraDeviceCallbacks.h b/include/camera/camera2/ICameraDeviceCallbacks.h index 670480b..c57b39f 100644 --- a/include/camera/camera2/ICameraDeviceCallbacks.h +++ b/include/camera/camera2/ICameraDeviceCallbacks.h @@ -65,6 +65,9 @@ public:      // One way      virtual void            onResultReceived(const CameraMetadata& metadata,                                               const CaptureResultExtras& resultExtras) = 0; + +    // One way +    virtual void            onPrepared(int streamId) = 0;  };  // ---------------------------------------------------------------------------- diff --git a/include/camera/camera2/ICameraDeviceUser.h b/include/camera/camera2/ICameraDeviceUser.h index 35488bb..a7bf8ab 100644 --- a/include/camera/camera2/ICameraDeviceUser.h +++ b/include/camera/camera2/ICameraDeviceUser.h @@ -27,9 +27,9 @@ namespace android {  class ICameraDeviceUserClient;  class IGraphicBufferProducer; -class Surface;  class CaptureRequest;  class CameraMetadata; +class OutputConfiguration;  enum {      NO_IN_FLIGHT_REPEATING_FRAMES = -1, @@ -97,12 +97,24 @@ public:       * must be called before any requests can be submitted.       * <p>       */ -    virtual status_t        endConfigure() = 0; +    virtual status_t        endConfigure(bool isConstrainedHighSpeed = false) = 0;      virtual status_t        deleteStream(int streamId) = 0; -    virtual status_t        createStream( -            int width, int height, int format, -            const sp<IGraphicBufferProducer>& bufferProducer) = 0; + +    virtual status_t        createStream(const OutputConfiguration& outputConfiguration) = 0; + +    /** +     * Create an input stream of width, height, and format (one of +     * HAL_PIXEL_FORMAT_*) +     * +     * Return stream ID if it's a non-negative value. status_t if it's a +     * negative value. +     */ +    virtual status_t        createInputStream(int width, int height, int format) = 0; + +    // get the buffer producer of the input stream +    virtual status_t        getInputBufferProducer( +            sp<IGraphicBufferProducer> *producer) = 0;      // Create a request object from a template.      virtual status_t        createDefaultRequest(int templateId, @@ -121,6 +133,17 @@ public:       */      virtual status_t        flush(/*out*/                                    int64_t* lastFrameNumber = NULL) = 0; + +    /** +     * Preallocate buffers for a given output stream asynchronously. +     */ +    virtual status_t        prepare(int streamId) = 0; + +    /** +     * Free all unused buffers for a given output stream. +     */ +    virtual status_t        tearDown(int streamId) = 0; +  };  // ---------------------------------------------------------------------------- diff --git a/include/camera/camera2/OutputConfiguration.h b/include/camera/camera2/OutputConfiguration.h new file mode 100644 index 0000000..5bcbe15 --- /dev/null +++ b/include/camera/camera2/OutputConfiguration.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_CAMERA2_OUTPUTCONFIGURATION_H +#define ANDROID_HARDWARE_CAMERA2_OUTPUTCONFIGURATION_H + +#include <utils/RefBase.h> +#include <gui/IGraphicBufferProducer.h> + +namespace android { + +class Surface; + +class OutputConfiguration : public virtual RefBase { +public: + +    static const int INVALID_ROTATION; +    sp<IGraphicBufferProducer> getGraphicBufferProducer() const; +    int                        getRotation() const; + +    /** +     * Keep impl up-to-date with OutputConfiguration.java in frameworks/base +     */ +    status_t                   writeToParcel(Parcel& parcel) const; +    // getGraphicBufferProducer will be NULL if error occurred +    // getRotation will be INVALID_ROTATION if error occurred +    OutputConfiguration(const Parcel& parcel); + +    OutputConfiguration(sp<IGraphicBufferProducer>& gbp, int rotation); + +private: +    sp<IGraphicBufferProducer> mGbp; +    int                        mRotation; + +    // helper function +    static String16 readMaybeEmptyString16(const Parcel& parcel); +}; +}; // namespace android + +#endif diff --git a/include/media/AVSyncSettings.h b/include/media/AVSyncSettings.h new file mode 100644 index 0000000..10e3bcc --- /dev/null +++ b/include/media/AVSyncSettings.h @@ -0,0 +1,61 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_AV_SYNC_SETTINGS_H +#define ANDROID_AV_SYNC_SETTINGS_H + +namespace android { + +enum AVSyncSource : unsigned { +    // let the system decide the best sync source +    AVSYNC_SOURCE_DEFAULT = 0, +    // sync to the system clock +    AVSYNC_SOURCE_SYSTEM_CLOCK = 1, +    // sync to the audio track +    AVSYNC_SOURCE_AUDIO = 2, +    // sync to the display vsync +    AVSYNC_SOURCE_VSYNC = 3, +    AVSYNC_SOURCE_MAX, +}; + +enum AVSyncAudioAdjustMode : unsigned { +    // let the system decide the best audio adjust mode +    AVSYNC_AUDIO_ADJUST_MODE_DEFAULT = 0, +    // adjust audio by time stretching +    AVSYNC_AUDIO_ADJUST_MODE_STRETCH = 1, +    // adjust audio by resampling +    AVSYNC_AUDIO_ADJUST_MODE_RESAMPLE = 2, +    AVSYNC_AUDIO_ADJUST_MODE_MAX, +}; + +// max tolerance when adjusting playback speed to desired playback speed +#define AVSYNC_TOLERANCE_MAX 1.0f + +struct AVSyncSettings { +    AVSyncSource mSource; +    AVSyncAudioAdjustMode mAudioAdjustMode; +    float mTolerance; +    AVSyncSettings() +        : mSource(AVSYNC_SOURCE_DEFAULT), +          mAudioAdjustMode(AVSYNC_AUDIO_ADJUST_MODE_DEFAULT), +          mTolerance(.044f) { } +}; + +} // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_AV_SYNC_SETTINGS_H diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h index 583695d..5af6c10 100644 --- a/include/media/AudioEffect.h +++ b/include/media/AudioEffect.h @@ -201,8 +201,12 @@ public:       */      /* Simple Constructor. +     * +     * Parameters: +     * +     * opPackageName:      The package name used for app op checks.       */ -    AudioEffect(); +    AudioEffect(const String16& opPackageName);      /* Constructor. @@ -211,6 +215,7 @@ public:       *       * type:  type of effect created: can be null if uuid is specified. This corresponds to       *        the OpenSL ES interface implemented by this effect. +     * opPackageName:  The package name used for app op checks.       * uuid:  Uuid of effect created: can be null if type is specified. This uuid corresponds to       *        a particular implementation of an effect type.       * priority:    requested priority for effect control: the priority level corresponds to the @@ -227,6 +232,7 @@ public:       */      AudioEffect(const effect_uuid_t *type, +                const String16& opPackageName,                  const effect_uuid_t *uuid = NULL,                    int32_t priority = 0,                    effect_callback_t cbf = NULL, @@ -239,6 +245,7 @@ public:       *      Same as above but with type and uuid specified by character strings       */      AudioEffect(const char *typeStr, +                    const String16& opPackageName,                      const char *uuidStr = NULL,                      int32_t priority = 0,                      effect_callback_t cbf = NULL, @@ -406,7 +413,9 @@ protected:       void*                   mUserData;          // client context for callback function       effect_descriptor_t     mDescriptor;        // effect descriptor       int32_t                 mId;                // system wide unique effect engine instance ID -     Mutex                   mLock;               // Mutex for mEnabled access +     Mutex                   mLock;              // Mutex for mEnabled access + +     String16                mOpPackageName;     // The package name used for app op checks.       // IEffectClient       virtual void controlStatusChanged(bool controlGranted); @@ -420,7 +429,8 @@ protected:  private:       // Implements the IEffectClient interface -    class EffectClient : public android::BnEffectClient,  public android::IBinder::DeathRecipient +    class EffectClient : +        public android::BnEffectClient, public android::IBinder::DeathRecipient      {      public: @@ -428,24 +438,39 @@ private:          // IEffectClient          virtual void controlStatusChanged(bool controlGranted) { -            mEffect->controlStatusChanged(controlGranted); +            sp<AudioEffect> effect = mEffect.promote(); +            if (effect != 0) { +                effect->controlStatusChanged(controlGranted); +            }          }          virtual void enableStatusChanged(bool enabled) { -            mEffect->enableStatusChanged(enabled); +            sp<AudioEffect> effect = mEffect.promote(); +            if (effect != 0) { +                effect->enableStatusChanged(enabled); +            }          }          virtual void commandExecuted(uint32_t cmdCode,                                       uint32_t cmdSize,                                       void *pCmdData,                                       uint32_t replySize,                                       void *pReplyData) { -            mEffect->commandExecuted(cmdCode, cmdSize, pCmdData, replySize, pReplyData); +            sp<AudioEffect> effect = mEffect.promote(); +            if (effect != 0) { +                effect->commandExecuted( +                    cmdCode, cmdSize, pCmdData, replySize, pReplyData); +            }          }          // IBinder::DeathRecipient -        virtual void binderDied(const wp<IBinder>& who) {mEffect->binderDied();} +        virtual void binderDied(const wp<IBinder>& who) { +            sp<AudioEffect> effect = mEffect.promote(); +            if (effect != 0) { +                effect->binderDied(); +            } +        }      private: -        AudioEffect *mEffect; +        wp<AudioEffect> mEffect;      };      void binderDied(); diff --git a/include/media/AudioIoDescriptor.h b/include/media/AudioIoDescriptor.h new file mode 100644 index 0000000..c94b738 --- /dev/null +++ b/include/media/AudioIoDescriptor.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_AUDIO_IO_DESCRIPTOR_H +#define ANDROID_AUDIO_IO_DESCRIPTOR_H + +namespace android { + +enum audio_io_config_event { +    AUDIO_OUTPUT_OPENED, +    AUDIO_OUTPUT_CLOSED, +    AUDIO_OUTPUT_CONFIG_CHANGED, +    AUDIO_INPUT_OPENED, +    AUDIO_INPUT_CLOSED, +    AUDIO_INPUT_CONFIG_CHANGED, +}; + +// audio input/output descriptor used to cache output configurations in client process to avoid +// frequent calls through IAudioFlinger +class AudioIoDescriptor : public RefBase { +public: +    AudioIoDescriptor() : +        mIoHandle(AUDIO_IO_HANDLE_NONE), +        mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(AUDIO_CHANNEL_NONE), +        mFrameCount(0), mLatency(0) +    { +        memset(&mPatch, 0, sizeof(struct audio_patch)); +    } + +    virtual ~AudioIoDescriptor() {} + +    audio_port_handle_t getDeviceId() { +        if (mPatch.num_sources != 0 && mPatch.num_sinks != 0) { +            if (mPatch.sources[0].type == AUDIO_PORT_TYPE_MIX) { +                // this is an output mix +                // FIXME: the API only returns the first device in case of multiple device selection +                return mPatch.sinks[0].id; +            } else { +                // this is an input mix +                return mPatch.sources[0].id; +            } +        } +        return AUDIO_PORT_HANDLE_NONE; +    } + +    audio_io_handle_t mIoHandle; +    struct audio_patch mPatch; +    uint32_t mSamplingRate; +    audio_format_t mFormat; +    audio_channel_mask_t mChannelMask; +    size_t mFrameCount; +    uint32_t mLatency; +}; + + +};  // namespace android + +#endif  /*ANDROID_AUDIO_IO_DESCRIPTOR_H*/ diff --git a/include/media/AudioPolicy.h b/include/media/AudioPolicy.h index a755e1e..feed402 100644 --- a/include/media/AudioPolicy.h +++ b/include/media/AudioPolicy.h @@ -38,8 +38,17 @@ namespace android {  #define MIX_TYPE_PLAYERS 0  #define MIX_TYPE_RECORDERS 1 -#define ROUTE_FLAG_RENDER 0x1 -#define ROUTE_FLAG_LOOP_BACK (0x1 << 1) +// definition of the different events that can be reported on a dynamic policy from +//   AudioSystem's implementation of the AudioPolicyClient interface +// keep in sync with AudioSystem.java +#define DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE 0 + +#define MIX_STATE_DISABLED -1 +#define MIX_STATE_IDLE 0 +#define MIX_STATE_MIXING 1 + +#define MIX_ROUTE_FLAG_RENDER 0x1 +#define MIX_ROUTE_FLAG_LOOP_BACK (0x1 << 1)  #define MAX_MIXES_PER_POLICY 10  #define MAX_CRITERIA_PER_MIX 20 @@ -61,11 +70,15 @@ public:  class AudioMix {  public: +    // flag on an AudioMix indicating the activity on this mix (IDLE, MIXING) +    //   must be reported through the AudioPolicyClient interface +    static const uint32_t kCbFlagNotifyActivity = 0x1; +      AudioMix() {}      AudioMix(Vector<AttributeMatchCriterion> criteria, uint32_t mixType, audio_config_t format, -             uint32_t routeFlags, String8 registrationId) : +             uint32_t routeFlags, String8 registrationId, uint32_t flags) :          mCriteria(criteria), mMixType(mixType), mFormat(format), -        mRouteFlags(routeFlags), mRegistrationId(registrationId) {} +        mRouteFlags(routeFlags), mRegistrationId(registrationId), mCbFlags(flags){}      status_t readFromParcel(Parcel *parcel);      status_t writeToParcel(Parcel *parcel) const; @@ -75,6 +88,7 @@ public:      audio_config_t  mFormat;      uint32_t        mRouteFlags;      String8         mRegistrationId; +    uint32_t        mCbFlags; // flags indicating which callbacks to use, see kCbFlag*  };  }; // namespace android diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index f70d981..c4c7b0e 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -42,8 +42,7 @@ public:          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. +                                    // 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()). @@ -53,7 +52,7 @@ public:                                      // voluntary invalidation by mediaserver, or mediaserver crash.      }; -    /* Client should declare Buffer on the stack and pass address to obtainBuffer() +    /* Client should declare a Buffer and pass address to obtainBuffer()       * and releaseBuffer().  See also callback_t for EVENT_MORE_DATA.       */ @@ -62,20 +61,25 @@ public:      public:          // FIXME use m prefix          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) +                                    // on input to obtainBuffer() it is the number of frames desired +                                    // on output from obtainBuffer() it is the number of available +                                    //    frames to be read +                                    // on input to releaseBuffer() it is currently ignored          size_t      size;           // input/output in bytes == frameCount * frameSize -                                    // on 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 +                                    // on input to obtainBuffer() it is ignored +                                    // on output from obtainBuffer() it is the number of available +                                    //    bytes to be read, which is frameCount * frameSize +                                    // on input to releaseBuffer() it is the number of bytes to +                                    //    release +                                    // FIXME This is redundant with respect to frameCount.  Consider +                                    //    removing size and making frameCount the primary field.          union {              void*       raw;              short*      i16;        // signed 16-bit              int8_t*     i8;         // unsigned 8-bit, offset by 0x80 +                                    // input to obtainBuffer(): unused, output: pointer to buffer          };      }; @@ -88,8 +92,8 @@ public:       * user:    Pointer to context for use by the callback receiver.       * info:    Pointer to optional parameter according to event type:       *          - EVENT_MORE_DATA: pointer to AudioRecord::Buffer struct. The callback must not read -     *            more bytes than indicated by 'size' field and update 'size' if fewer bytes are -     *            consumed. +     *                             more bytes than indicated by 'size' field and update 'size' if +     *                             fewer bytes are consumed.       *          - EVENT_OVERRUN: unused.       *          - EVENT_MARKER: pointer to const uint32_t containing the marker position in frames.       *          - EVENT_NEW_POS: pointer to const uint32_t containing the new position in frames. @@ -106,6 +110,7 @@ public:       *  - BAD_VALUE: unsupported configuration       * frameCount is guaranteed to be non-zero if status is NO_ERROR,       * and is undefined otherwise. +     * FIXME This API assumes a route, and so should be deprecated.       */       static status_t getMinFrameCount(size_t* frameCount, @@ -118,14 +123,18 @@ public:      enum transfer_type {          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_OBTAIN,    // call obtainBuffer() and releaseBuffer()          TRANSFER_SYNC,      // synchronous read()      };      /* Constructs an uninitialized AudioRecord. No connection with       * AudioFlinger takes place.  Use set() after this. +     * +     * Parameters: +     * +     * opPackageName:      The package name used for app ops.       */ -                        AudioRecord(); +                        AudioRecord(const String16& opPackageName);      /* Creates an AudioRecord object and registers it with AudioFlinger.       * Once created, the track needs to be started before it can be used. @@ -138,27 +147,30 @@ public:       * format:             Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed       *                     16 bits per sample).       * channelMask:        Channel mask, such that audio_is_input_channel(channelMask) is true. +     * opPackageName:      The package name used for app ops.       * frameCount:         Minimum size of track PCM buffer in frames. This defines the       *                     application's contribution to the       *                     latency of the track.  The actual size selected by the AudioRecord could       *                     be larger if the requested size is not compatible with current audio HAL       *                     latency.  Zero means to use a default value.       * cbf:                Callback function. If not null, this function is called periodically -     *                     to consume new data and inform of marker, position updates, etc. +     *                     to consume new data in TRANSFER_CALLBACK mode +     *                     and inform of marker, position updates, etc.       * user:               Context for use by the callback receiver.       * notificationFrames: The callback function is called each time notificationFrames PCM       *                     frames are ready in record track output buffer.       * sessionId:          Not yet supported.       * transferType:       How data is transferred from AudioRecord.       * flags:              See comments on audio_input_flags_t in <system/audio.h> +     * pAttributes:        If not NULL, supersedes inputSource for use case selection.       * threadCanCallJava:  Not present in parameter list, and so is fixed at false. -     * pAttributes:        if not NULL, supersedes inputSource for use case selection       */                          AudioRecord(audio_source_t inputSource,                                      uint32_t sampleRate,                                      audio_format_t format,                                      audio_channel_mask_t channelMask, +                                    const String16& opPackageName,                                      size_t frameCount = 0,                                      callback_t cbf = NULL,                                      void* user = NULL, @@ -166,6 +178,8 @@ public:                                      int sessionId = AUDIO_SESSION_ALLOCATE,                                      transfer_type transferType = TRANSFER_DEFAULT,                                      audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE, +                                    int uid = -1, +                                    pid_t pid = -1,                                      const audio_attributes_t* pAttributes = NULL);      /* Terminates the AudioRecord and unregisters it from AudioFlinger. @@ -177,6 +191,7 @@ public:      /* Initialize an AudioRecord that was created using the AudioRecord() constructor.       * Don't call set() more than once, or after an AudioRecord() constructor that takes parameters. +     * set() is not multi-thread safe.       * Returned status (from utils/Errors.h) can be:       *  - NO_ERROR: successful intialization       *  - INVALID_OPERATION: AudioRecord is already initialized or record device is already in use @@ -201,6 +216,8 @@ public:                              int sessionId = AUDIO_SESSION_ALLOCATE,                              transfer_type transferType = TRANSFER_DEFAULT,                              audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE, +                            int uid = -1, +                            pid_t pid = -1,                              const audio_attributes_t* pAttributes = NULL);      /* Result of constructing the AudioRecord. This must be checked for successful initialization @@ -211,7 +228,7 @@ public:              status_t    initCheck() const   { return mStatus; }      /* Returns this track's estimated latency in milliseconds. -     * This includes the latency due to AudioRecord buffer size, +     * This includes the latency due to AudioRecord buffer size, resampling if applicable,       * and audio hardware driver.       */              uint32_t    latency() const     { return mLatency; } @@ -243,11 +260,6 @@ 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. @@ -309,7 +321,12 @@ public:       * Returned value:       *  handle on audio hardware input       */ -            audio_io_handle_t    getInput() const; +// FIXME The only known public caller is frameworks/opt/net/voip/src/jni/rtp/AudioGroup.cpp +            audio_io_handle_t    getInput() const __attribute__((__deprecated__)) +                                                { return getInputPrivate(); } +private: +            audio_io_handle_t    getInputPrivate() const; +public:      /* Returns the audio session ID associated with this AudioRecord.       * @@ -323,10 +340,18 @@ public:       */              int    getSessionId() const { return mSessionId; } -    /* Obtains a buffer of up to "audioBuffer->frameCount" full frames. +    /* Public API for TRANSFER_OBTAIN mode. +     * Obtains a buffer of up to "audioBuffer->frameCount" full frames.       * After draining these frames of data, the caller should release them with releaseBuffer().       * If the track buffer is not empty, obtainBuffer() returns as many contiguous       * full frames as are available immediately. +     * +     * If nonContig is non-NULL, it is an output parameter that will be set to the number of +     * additional non-contiguous frames that are predicted to be available immediately, +     * if the client were to release the first frames and then call obtainBuffer() again. +     * This value is only a prediction, and needs to be confirmed. +     * It will be set to zero for an error return. +     *       * If the track buffer is empty and track is stopped, obtainBuffer() returns WOULD_BLOCK       * regardless of the value of waitCount.       * If the track buffer is empty and track is not stopped, obtainBuffer() blocks with a @@ -336,9 +361,6 @@ public:       * or return WOULD_BLOCK depending on the value of the "waitCount"       * parameter.       * -     * obtainBuffer() and releaseBuffer() are deprecated for direct use by applications, -     * which should use read() or callback EVENT_MORE_DATA instead. -     *       * Interpretation of waitCount:       *  +n  limits wait time to n * WAIT_PERIOD_MS,       *  -1  causes an (almost) infinite wait time, @@ -347,6 +369,8 @@ public:       * Buffer fields       * On entry:       *  frameCount  number of frames requested +     *  size        ignored +     *  raw         ignored       * After error return:       *  frameCount  0       *  size        0 @@ -357,13 +381,58 @@ public:       *  raw         pointer to the buffer       */ -    /* FIXME Deprecated public API for TRANSFER_OBTAIN mode */ -            status_t    obtainBuffer(Buffer* audioBuffer, int32_t waitCount) -                                __attribute__((__deprecated__)); +            status_t    obtainBuffer(Buffer* audioBuffer, int32_t waitCount, +                                size_t *nonContig = NULL); + +            // Explicit Routing +    /** +     * TODO Document this method. +     */ +            status_t setInputDevice(audio_port_handle_t deviceId); + +    /** +     * TODO Document this method. +     */ +            audio_port_handle_t getInputDevice(); + +     /* Returns the ID of the audio device actually used by the input to which this AudioRecord +      * is attached. +      * A value of AUDIO_PORT_HANDLE_NONE indicates the AudioRecord is not attached to any input. +      * +      * Parameters: +      *  none. +      */ +     audio_port_handle_t getRoutedDeviceId(); + +    /* Add an AudioDeviceCallback. The caller will be notified when the audio device +     * to which this AudioRecord is routed is updated. +     * Replaces any previously installed callback. +     * Parameters: +     *  callback:  The callback interface +     * Returns NO_ERROR if successful. +     *         INVALID_OPERATION if the same callback is already installed. +     *         NO_INIT or PREMISSION_DENIED if AudioFlinger service is not reachable +     *         BAD_VALUE if the callback is NULL +     */ +            status_t addAudioDeviceCallback( +                    const sp<AudioSystem::AudioDeviceCallback>& callback); + +    /* remove an AudioDeviceCallback. +     * Parameters: +     *  callback:  The callback interface +     * Returns NO_ERROR if successful. +     *         INVALID_OPERATION if the callback is not installed +     *         BAD_VALUE if the callback is NULL +     */ +            status_t removeAudioDeviceCallback( +                    const sp<AudioSystem::AudioDeviceCallback>& callback);  private:      /* If nonContig is non-NULL, it is an output parameter that will be set to the number of -     * additional non-contiguous frames that are available immediately. +     * additional non-contiguous frames that are predicted to be available immediately, +     * if the client were to release the first frames and then call obtainBuffer() again. +     * This value is only a prediction, and needs to be confirmed. +     * It will be set to zero for an error return.       * FIXME We could pass an array of Buffers instead of only one Buffer to obtainBuffer(),       * in case the requested amount of frames is in two or more non-contiguous regions.       * FIXME requested and elapsed are both relative times.  Consider changing to absolute time. @@ -372,9 +441,15 @@ private:                                       struct timespec *elapsed = NULL, size_t *nonContig = NULL);  public: -    /* Release an emptied buffer of "audioBuffer->frameCount" frames for AudioFlinger to re-fill. */ -    // FIXME make private when obtainBuffer() for TRANSFER_OBTAIN is removed -            void        releaseBuffer(Buffer* audioBuffer); +    /* Public API for TRANSFER_OBTAIN mode. +     * Release an emptied buffer of "audioBuffer->frameCount" frames for AudioFlinger to re-fill. +     * +     * Buffer fields: +     *  frameCount  currently ignored but recommend to set to actual number of frames consumed +     *  size        actual number of bytes consumed, must be multiple of frameSize +     *  raw         ignored +     */ +            void        releaseBuffer(const Buffer* audioBuffer);      /* As a convenience we provide a read() interface to the audio buffer.       * Input parameter 'size' is in byte units. @@ -386,8 +461,11 @@ public:       *      WOULD_BLOCK         when obtainBuffer() returns same, or       *                          AudioRecord was stopped during the read       *      or any other error code returned by IAudioRecord::start() or restoreRecord_l(). +     * Default behavior is to only return when all data has been transferred. Set 'blocking' to +     * false for the method to return immediately without waiting to try multiple times to read +     * the full content of the buffer.       */ -            ssize_t     read(void* buffer, size_t size); +            ssize_t     read(void* buffer, size_t size, bool blocking = true);      /* Return the number of input frames lost in the audio driver since the last call of this       * function.  Audio driver is expected to reset the value to 0 and restart counting upon @@ -416,6 +494,7 @@ private:                  void        pause();    // suspend thread from execution at next loop boundary                  void        resume();   // allow thread to execute, if not requested to exit +                void        wake();     // wake to handle changed notification conditions.      private:                  void        pauseInternal(nsecs_t ns = 0LL); @@ -430,7 +509,9 @@ 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 +        bool                mIgnoreNextPausedInt;   // skip any internal pause and go immediately +                                        // to processAudioBuffer() as state may have changed +                                        // since pause time calculated.      };              // body of AudioRecordThread::threadLoop() @@ -445,7 +526,7 @@ private:              // caller must hold lock on mLock for all _l methods -            status_t openRecord_l(size_t epoch); +            status_t openRecord_l(size_t epoch, const String16& opPackageName);              // FIXME enum is faster than strcmp() for parameter 'from'              status_t restoreRecord_l(const char *from); @@ -458,7 +539,7 @@ private:      bool                    mActive;      // for client callback handler -    callback_t              mCbf;               // callback handler for events, or NULL +    callback_t              mCbf;                   // callback handler for events, or NULL      void*                   mUserData;      // for notification APIs @@ -475,13 +556,15 @@ private:      bool                    mRetryOnPartialBuffer;  // sleep and retry after partial obtainBuffer()      uint32_t                mObservedSequence;      // last observed value of mSequence -    uint32_t                mMarkerPosition;    // in wrapping (overflow) frame units +    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                mNewPosition;           // in frames +    uint32_t                mUpdatePeriod;          // in frames, zero means no EVENT_NEW_POS      status_t                mStatus; +    String16                mOpPackageName;         // The package name used for app ops. +      size_t                  mFrameCount;            // corresponds to current IAudioRecord, value is                                                      // reported back by AudioFlinger to the client      size_t                  mReqFrameCount;         // frame count to request the first or next time @@ -531,7 +614,14 @@ private:      sp<DeathNotifier>       mDeathNotifier;      uint32_t                mSequence;              // incremented for each new IAudioRecord attempt +    int                     mClientUid; +    pid_t                   mClientPid;      audio_attributes_t      mAttributes; + +    // For Device Selection API +    //  a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing. +    audio_port_handle_t    mSelectedDeviceId; +    sp<AudioSystem::AudioDeviceCallback> mDeviceCallback;  };  }; // namespace android diff --git a/include/media/AudioResamplerPublic.h b/include/media/AudioResamplerPublic.h index 97847a0..055f724 100644 --- a/include/media/AudioResamplerPublic.h +++ b/include/media/AudioResamplerPublic.h @@ -17,6 +17,11 @@  #ifndef ANDROID_AUDIO_RESAMPLER_PUBLIC_H  #define ANDROID_AUDIO_RESAMPLER_PUBLIC_H +#include <stdint.h> +#include <math.h> + +namespace android { +  // AUDIO_RESAMPLER_DOWN_RATIO_MAX is the maximum ratio between the original  // audio sample rate and the target rate when downsampling,  // as permitted in the audio framework, e.g. AudioTrack and AudioFlinger. @@ -26,4 +31,147 @@  // TODO: replace with an API  #define AUDIO_RESAMPLER_DOWN_RATIO_MAX 256 +// AUDIO_RESAMPLER_UP_RATIO_MAX is the maximum suggested ratio between the original +// audio sample rate and the target rate when upsampling.  It is loosely enforced by +// the system. One issue with large upsampling ratios is the approximation by +// an int32_t of the phase increments, making the resulting sample rate inexact. +#define AUDIO_RESAMPLER_UP_RATIO_MAX 65536 + +// AUDIO_TIMESTRETCH_SPEED_MIN and AUDIO_TIMESTRETCH_SPEED_MAX define the min and max time stretch +// speeds supported by the system. These are enforced by the system and values outside this range +// will result in a runtime error. +// Depending on the AudioPlaybackRate::mStretchMode, the effective limits might be narrower than +// the ones specified here +// AUDIO_TIMESTRETCH_SPEED_MIN_DELTA is the minimum absolute speed difference that might trigger a +// parameter update +#define AUDIO_TIMESTRETCH_SPEED_MIN    0.01f +#define AUDIO_TIMESTRETCH_SPEED_MAX    20.0f +#define AUDIO_TIMESTRETCH_SPEED_NORMAL 1.0f +#define AUDIO_TIMESTRETCH_SPEED_MIN_DELTA 0.0001f + +// AUDIO_TIMESTRETCH_PITCH_MIN and AUDIO_TIMESTRETCH_PITCH_MAX define the min and max time stretch +// pitch shifting supported by the system. These are not enforced by the system and values +// outside this range might result in a pitch different than the one requested. +// Depending on the AudioPlaybackRate::mStretchMode, the effective limits might be narrower than +// the ones specified here. +// AUDIO_TIMESTRETCH_PITCH_MIN_DELTA is the minimum absolute pitch difference that might trigger a +// parameter update +#define AUDIO_TIMESTRETCH_PITCH_MIN    0.25f +#define AUDIO_TIMESTRETCH_PITCH_MAX    4.0f +#define AUDIO_TIMESTRETCH_PITCH_NORMAL 1.0f +#define AUDIO_TIMESTRETCH_PITCH_MIN_DELTA 0.0001f + + +//Determines the current algorithm used for stretching +enum AudioTimestretchStretchMode : int32_t { +    AUDIO_TIMESTRETCH_STRETCH_DEFAULT            = 0, +    AUDIO_TIMESTRETCH_STRETCH_SPEECH             = 1, +    //TODO: add more stretch modes/algorithms +}; + +//Limits for AUDIO_TIMESTRETCH_STRETCH_SPEECH mode +#define TIMESTRETCH_SONIC_SPEED_MIN 0.1f +#define TIMESTRETCH_SONIC_SPEED_MAX 6.0f + +//Determines behavior of Timestretch if current algorithm can't perform +//with current parameters. +// FALLBACK_CUT_REPEAT: (internal only) for speed <1.0 will truncate frames +//    for speed > 1.0 will repeat frames +// FALLBACK_MUTE: will set all processed frames to zero +// FALLBACK_FAIL:  will stop program execution and log a fatal error +enum AudioTimestretchFallbackMode : int32_t { +    AUDIO_TIMESTRETCH_FALLBACK_CUT_REPEAT     = -1, +    AUDIO_TIMESTRETCH_FALLBACK_DEFAULT        = 0, +    AUDIO_TIMESTRETCH_FALLBACK_MUTE           = 1, +    AUDIO_TIMESTRETCH_FALLBACK_FAIL           = 2, +}; + +struct AudioPlaybackRate { +    float mSpeed; +    float mPitch; +    enum AudioTimestretchStretchMode  mStretchMode; +    enum AudioTimestretchFallbackMode mFallbackMode; +}; + +static const AudioPlaybackRate AUDIO_PLAYBACK_RATE_DEFAULT = { +        AUDIO_TIMESTRETCH_SPEED_NORMAL, +        AUDIO_TIMESTRETCH_PITCH_NORMAL, +        AUDIO_TIMESTRETCH_STRETCH_DEFAULT, +        AUDIO_TIMESTRETCH_FALLBACK_DEFAULT +}; + +static inline bool isAudioPlaybackRateEqual(const AudioPlaybackRate &pr1, +        const AudioPlaybackRate &pr2) { +    return fabs(pr1.mSpeed - pr2.mSpeed) < AUDIO_TIMESTRETCH_SPEED_MIN_DELTA && +           fabs(pr1.mPitch - pr2.mPitch) < AUDIO_TIMESTRETCH_PITCH_MIN_DELTA && +           pr2.mStretchMode == pr2.mStretchMode && +           pr2.mFallbackMode == pr2.mFallbackMode; +} + +static inline bool isAudioPlaybackRateValid(const AudioPlaybackRate &playbackRate) { +    if (playbackRate.mFallbackMode == AUDIO_TIMESTRETCH_FALLBACK_FAIL && +            (playbackRate.mStretchMode == AUDIO_TIMESTRETCH_STRETCH_SPEECH || +                    playbackRate.mStretchMode == AUDIO_TIMESTRETCH_STRETCH_DEFAULT)) { +        //test sonic specific constraints +        return playbackRate.mSpeed >= TIMESTRETCH_SONIC_SPEED_MIN && +                playbackRate.mSpeed <= TIMESTRETCH_SONIC_SPEED_MAX && +                playbackRate.mPitch >= AUDIO_TIMESTRETCH_PITCH_MIN && +                playbackRate.mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX; +    } else { +        return playbackRate.mSpeed >= AUDIO_TIMESTRETCH_SPEED_MIN && +                playbackRate.mSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX && +                playbackRate.mPitch >= AUDIO_TIMESTRETCH_PITCH_MIN && +                playbackRate.mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX; +    } +} + +// TODO: Consider putting these inlines into a class scope + +// Returns the source frames needed to resample to destination frames.  This is not a precise +// value and depends on the resampler (and possibly how it handles rounding internally). +// Nevertheless, this should be an upper bound on the requirements of the resampler. +// If srcSampleRate and dstSampleRate are equal, then it returns destination frames, which +// may not be true if the resampler is asynchronous. +static inline size_t sourceFramesNeeded( +        uint32_t srcSampleRate, size_t dstFramesRequired, uint32_t dstSampleRate) { +    // +1 for rounding - always do this even if matched ratio (resampler may use phases not ratio) +    // +1 for additional sample needed for interpolation +    return srcSampleRate == dstSampleRate ? dstFramesRequired : +            size_t((uint64_t)dstFramesRequired * srcSampleRate / dstSampleRate + 1 + 1); +} + +// An upper bound for the number of destination frames possible from srcFrames +// after sample rate conversion.  This may be used for buffer sizing. +static inline size_t destinationFramesPossible(size_t srcFrames, uint32_t srcSampleRate, +        uint32_t dstSampleRate) { +    if (srcSampleRate == dstSampleRate) { +        return srcFrames; +    } +    uint64_t dstFrames = (uint64_t)srcFrames * dstSampleRate / srcSampleRate; +    return dstFrames > 2 ? dstFrames - 2 : 0; +} + +static inline size_t sourceFramesNeededWithTimestretch( +        uint32_t srcSampleRate, size_t dstFramesRequired, uint32_t dstSampleRate, +        float speed) { +    // required is the number of input frames the resampler needs +    size_t required = sourceFramesNeeded(srcSampleRate, dstFramesRequired, dstSampleRate); +    // to deliver this, the time stretcher requires: +    return required * (double)speed + 1 + 1; // accounting for rounding dependencies +} + +// Identifies sample rates that we associate with music +// and thus eligible for better resampling and fast capture. +// This is somewhat less than 44100 to allow for pitch correction +// involving resampling as well as asynchronous resampling. +#define AUDIO_PROCESSING_MUSIC_RATE 40000 + +static inline bool isMusicRate(uint32_t sampleRate) { +    return sampleRate >= AUDIO_PROCESSING_MUSIC_RATE; +} + +} // namespace android + +// --------------------------------------------------------------------------- +  #endif // ANDROID_AUDIO_RESAMPLER_PUBLIC_H diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index 843a354..06116a5 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -19,6 +19,7 @@  #include <hardware/audio_effect.h>  #include <media/AudioPolicy.h> +#include <media/AudioIoDescriptor.h>  #include <media/IAudioFlingerClient.h>  #include <media/IAudioPolicyServiceClient.h>  #include <system/audio.h> @@ -29,6 +30,7 @@  namespace android {  typedef void (*audio_error_callback)(status_t err); +typedef void (*dynamic_policy_callback)(int event, String8 regId, int val);  class IAudioFlinger;  class IAudioPolicyService; @@ -89,6 +91,7 @@ public:      static String8  getParameters(const String8& keys);      static void setErrorCallback(audio_error_callback cb); +    static void setDynPolicyCallback(dynamic_policy_callback cb);      // helper function to obtain AudioFlinger service handle      static const sp<IAudioFlinger> get_audio_flinger(); @@ -98,10 +101,13 @@ public:      // Returned samplingRate and frameCount output values are guaranteed      // to be non-zero if status == NO_ERROR +    // FIXME This API assumes a route, and so should be deprecated.      static status_t getOutputSamplingRate(uint32_t* samplingRate,              audio_stream_type_t stream); +    // FIXME This API assumes a route, and so should be deprecated.      static status_t getOutputFrameCount(size_t* frameCount,              audio_stream_type_t stream); +    // FIXME This API assumes a route, and so should be deprecated.      static status_t getOutputLatency(uint32_t* latency,              audio_stream_type_t stream);      static status_t getSamplingRate(audio_io_handle_t output, @@ -110,19 +116,20 @@ public:      // audio_stream->get_buffer_size()/audio_stream_out_frame_size()      static status_t getFrameCount(audio_io_handle_t output,                                    size_t* frameCount); -    // returns the audio output stream latency in ms. Corresponds to +    // returns the audio output latency in ms. Corresponds to      // audio_stream_out->get_latency()      static status_t getLatency(audio_io_handle_t output,                                 uint32_t* latency);      // return status NO_ERROR implies *buffSize > 0 +    // FIXME This API assumes a route, and so should deprecated.      static status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,          audio_channel_mask_t channelMask, size_t* buffSize);      static status_t setVoiceVolume(float volume);      // return the number of audio frames written by AudioFlinger to audio HAL and -    // audio dsp to DAC since the specified output I/O handle has exited standby. +    // audio dsp to DAC since the specified output has exited standby.      // returned status (from utils/Errors.h) can be:      // - NO_ERROR: successful operation, halFrames and dspFrames point to valid data      // - INVALID_OPERATION: Not supported on current hardware platform @@ -151,32 +158,8 @@ public:      // 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 { -        OUTPUT_OPENED, -        OUTPUT_CLOSED, -        OUTPUT_CONFIG_CHANGED, -        INPUT_OPENED, -        INPUT_CLOSED, -        INPUT_CONFIG_CHANGED, -        STREAM_CONFIG_CHANGED, -        NUM_CONFIG_EVENTS -    }; - -    // audio output descriptor used to cache output configurations in client process to avoid -    // frequent calls through IAudioFlinger -    class OutputDescriptor { -    public: -        OutputDescriptor() -        : samplingRate(0), format(AUDIO_FORMAT_DEFAULT), channelMask(0), frameCount(0), latency(0) -            {} - -        uint32_t samplingRate; -        audio_format_t format; -        audio_channel_mask_t channelMask; -        size_t frameCount; -        uint32_t latency; -    }; +    // Indicate JAVA services are ready (scheduling, power management ...) +    static status_t systemReady();      // Events used to synchronize actions between audio sessions.      // For instance SYNC_EVENT_PRESENTATION_COMPLETE can be used to delay recording start until @@ -201,7 +184,7 @@ public:      // IAudioPolicyService interface (see AudioPolicyInterface for method descriptions)      //      static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, -                                                const char *device_address); +                                             const char *device_address, const char *device_name);      static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,                                                                  const char *device_address);      static status_t setPhoneState(audio_mode_t state); @@ -217,14 +200,16 @@ public:                                          audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,                                          const audio_offload_info_t *offloadInfo = NULL);      static status_t getOutputForAttr(const audio_attributes_t *attr, -                                        audio_io_handle_t *output, -                                        audio_session_t session, -                                        audio_stream_type_t *stream, -                                        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); +                                     audio_io_handle_t *output, +                                     audio_session_t session, +                                     audio_stream_type_t *stream, +                                     uid_t uid, +                                     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, +                                     audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE, +                                     const audio_offload_info_t *offloadInfo = NULL);      static status_t startOutput(audio_io_handle_t output,                                  audio_stream_type_t stream,                                  audio_session_t session); @@ -240,10 +225,12 @@ public:      static status_t getInputForAttr(const audio_attributes_t *attr,                                      audio_io_handle_t *input,                                      audio_session_t session, +                                    uid_t uid,                                      uint32_t samplingRate,                                      audio_format_t format,                                      audio_channel_mask_t channelMask, -                                    audio_input_flags_t flags); +                                    audio_input_flags_t flags, +                                    audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);      static status_t startInput(audio_io_handle_t input,                                 audio_session_t session); @@ -327,6 +314,12 @@ public:      static status_t registerPolicyMixes(Vector<AudioMix> mixes, bool registration); +    static status_t startAudioSource(const struct audio_port_config *source, +                                      const audio_attributes_t *attributes, +                                      audio_io_handle_t *handle); +    static status_t stopAudioSource(audio_io_handle_t handle); + +      // ----------------------------------------------------------------------------      class AudioPortCallback : public RefBase @@ -342,16 +335,42 @@ public:      }; -    static void setAudioPortCallback(sp<AudioPortCallback> callBack); +    static status_t addAudioPortCallback(const sp<AudioPortCallback>& callback); +    static status_t removeAudioPortCallback(const sp<AudioPortCallback>& callback); + +    class AudioDeviceCallback : public RefBase +    { +    public: + +                AudioDeviceCallback() {} +        virtual ~AudioDeviceCallback() {} + +        virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo, +                                         audio_port_handle_t deviceId) = 0; +    }; + +    static status_t addAudioDeviceCallback(const sp<AudioDeviceCallback>& callback, +                                           audio_io_handle_t audioIo); +    static status_t removeAudioDeviceCallback(const sp<AudioDeviceCallback>& callback, +                                              audio_io_handle_t audioIo); + +    static audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo);  private:      class AudioFlingerClient: public IBinder::DeathRecipient, public BnAudioFlingerClient      {      public: -        AudioFlingerClient() { +        AudioFlingerClient() : +            mInBuffSize(0), mInSamplingRate(0), +            mInFormat(AUDIO_FORMAT_DEFAULT), mInChannelMask(AUDIO_CHANNEL_NONE) {          } +        void clearIoCache(); +        status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, +                                    audio_channel_mask_t channelMask, size_t* buffSize); +        sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle); +          // DeathRecipient          virtual void binderDied(const wp<IBinder>& who); @@ -359,7 +378,27 @@ private:          // indicate a change in the configuration of an output or input: keeps the cached          // values for output/input parameters up-to-date in client process -        virtual void ioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2); +        virtual void ioConfigChanged(audio_io_config_event event, +                                     const sp<AudioIoDescriptor>& ioDesc); + + +        status_t addAudioDeviceCallback(const sp<AudioDeviceCallback>& callback, +                                               audio_io_handle_t audioIo); +        status_t removeAudioDeviceCallback(const sp<AudioDeviceCallback>& callback, +                                           audio_io_handle_t audioIo); + +        audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo); + +    private: +        Mutex                               mLock; +        DefaultKeyedVector<audio_io_handle_t, sp<AudioIoDescriptor> >   mIoDescriptors; +        DefaultKeyedVector<audio_io_handle_t, Vector < sp<AudioDeviceCallback> > > +                                                                        mAudioDeviceCallbacks; +        // cached values for recording getInputBufferSize() queries +        size_t                              mInBuffSize;    // zero indicates cache is invalid +        uint32_t                            mInSamplingRate; +        audio_format_t                      mInFormat; +        audio_channel_mask_t                mInChannelMask;      };      class AudioPolicyServiceClient: public IBinder::DeathRecipient, @@ -369,26 +408,35 @@ private:          AudioPolicyServiceClient() {          } +        int addAudioPortCallback(const sp<AudioPortCallback>& callback); +        int removeAudioPortCallback(const sp<AudioPortCallback>& callback); +          // DeathRecipient          virtual void binderDied(const wp<IBinder>& who);          // IAudioPolicyServiceClient          virtual void onAudioPortListUpdate();          virtual void onAudioPatchListUpdate(); +        virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state); + +    private: +        Mutex                               mLock; +        Vector <sp <AudioPortCallback> >    mAudioPortCallbacks;      }; +    static const sp<AudioFlingerClient> getAudioFlingerClient(); +    static sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle); +      static sp<AudioFlingerClient> gAudioFlingerClient;      static sp<AudioPolicyServiceClient> gAudioPolicyServiceClient;      friend class AudioFlingerClient;      friend class AudioPolicyServiceClient;      static Mutex gLock;      // protects gAudioFlinger and gAudioErrorCallback, -    static Mutex gLockCache; // protects gOutputs, gPrevInSamplingRate, gPrevInFormat, -                             // gPrevInChannelMask and gInBuffSize      static Mutex gLockAPS;   // protects gAudioPolicyService and gAudioPolicyServiceClient -    static Mutex gLockAPC;   // protects gAudioPortCallback      static sp<IAudioFlinger> gAudioFlinger;      static audio_error_callback gAudioErrorCallback; +    static dynamic_policy_callback gDynPolicyCallback;      static size_t gInBuffSize;      // previous parameters for recording buffer size queries @@ -397,12 +445,6 @@ private:      static audio_channel_mask_t gPrevInChannelMask;      static sp<IAudioPolicyService> gAudioPolicyService; - -    // 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/AudioTrack.h b/include/media/AudioTrack.h index fd51b8f..e02f1b7 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -21,6 +21,7 @@  #include <media/AudioSystem.h>  #include <media/AudioTimestamp.h>  #include <media/IAudioTrack.h> +#include <media/AudioResamplerPublic.h>  #include <utils/threads.h>  namespace android { @@ -42,28 +43,38 @@ public:       */      enum event_type {          EVENT_MORE_DATA = 0,        // Request to write more data to buffer. +                                    // This event only occurs for TRANSFER_CALLBACK.                                      // If this event is delivered but the callback handler -                                    // does not want to write more data, the handler must explicitly +                                    // does not want to write more data, the handler must                                      // ignore the event by setting frameCount to zero. -        EVENT_UNDERRUN = 1,         // Buffer underrun occurred. +                                    // This might occur, for example, if the application is +                                    // waiting for source data or is at the end of stream. +                                    // +                                    // For data filling, it is preferred that the callback +                                    // does not block and instead returns a short count on +                                    // the amount of data actually delivered +                                    // (or 0, if no data is currently available). +        EVENT_UNDERRUN = 1,         // Buffer underrun occurred. This will not occur for +                                    // static tracks.          EVENT_LOOP_END = 2,         // Sample loop end was reached; playback restarted from -                                    // loop start if loop count was not 0. +                                    // loop start if loop count was not 0 for a static track.          EVENT_MARKER = 3,           // Playback head is at the specified marker position                                      // (See setMarkerPosition()).          EVENT_NEW_POS = 4,          // Playback head is at a new position                                      // (See setPositionUpdatePeriod()). -        EVENT_BUFFER_END = 5,       // Playback head is at the end of the buffer. -                                    // Not currently used by android.media.AudioTrack. +        EVENT_BUFFER_END = 5,       // Playback has completed for a static track.          EVENT_NEW_IAUDIOTRACK = 6,  // IAudioTrack was re-created, either due to re-routing and                                      // voluntary invalidation by mediaserver, or mediaserver crash.          EVENT_STREAM_END = 7,       // Sent after all the buffers queued in AF and HW are played -                                    // back (after stop is called) +                                    // back (after stop is called) for an offloaded track. +#if 0   // FIXME not yet implemented          EVENT_NEW_TIMESTAMP = 8,    // Delivered periodically and when there's a significant change                                      // in the mapping from frame position to presentation time.                                      // See AudioTimestamp for the information included with event. +#endif      }; -    /* Client should declare Buffer on the stack and pass address to obtainBuffer() +    /* Client should declare a Buffer and pass the address to obtainBuffer()       * and releaseBuffer().  See also callback_t for EVENT_MORE_DATA.       */ @@ -72,22 +83,26 @@ public:      public:          // FIXME use m prefix          size_t      frameCount;   // number of sample frames corresponding to size; -                                  // on input it is the number of frames desired, -                                  // on output is the number of frames actually filled -                                  // (currently ignored, but will make the primary field in future) +                                  // on input to obtainBuffer() it is the number of frames desired, +                                  // on output from obtainBuffer() it is the number of available +                                  //    [empty slots for] frames to be filled +                                  // on input to releaseBuffer() it is currently ignored          size_t      size;         // input/output in bytes == frameCount * frameSize -                                  // on input 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 -                                  // since we don't define the frame format +                                  // on input to obtainBuffer() it is ignored +                                  // on output from obtainBuffer() it is the number of available +                                  //    [empty slots for] bytes to be filled, +                                  //    which is frameCount * frameSize +                                  // on input to releaseBuffer() it is the number of bytes to +                                  //    release +                                  // FIXME This is redundant with respect to frameCount.  Consider +                                  //    removing size and making frameCount the primary field.          union {              void*       raw;              short*      i16;      // signed 16-bit              int8_t*     i8;       // unsigned 8-bit, offset by 0x80 -        };                        // input: unused, output: pointer to buffer +        };                        // input to obtainBuffer(): unused, output: pointer to buffer      };      /* As a convenience, if a callback is supplied, a handler thread @@ -121,6 +136,7 @@ public:       *  - BAD_VALUE: unsupported configuration       * frameCount is guaranteed to be non-zero if status is NO_ERROR,       * and is undefined otherwise. +     * FIXME This API assumes a route, and so should be deprecated.       */      static status_t getMinFrameCount(size_t* frameCount, @@ -132,7 +148,7 @@ public:      enum transfer_type {          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_OBTAIN,    // call obtainBuffer() and releaseBuffer()          TRANSFER_SYNC,      // synchronous write()          TRANSFER_SHARED,    // shared memory      }; @@ -145,18 +161,15 @@ public:      /* Creates an AudioTrack object and registers it with AudioFlinger.       * Once created, the track needs to be started before it can be used.       * Unspecified values are set to appropriate default values. -     * With this constructor, the track is configured for streaming mode. -     * Data to be rendered is supplied by write() or by the callback EVENT_MORE_DATA. -     * Intermixing a combination of write() and non-ignored EVENT_MORE_DATA is not allowed.       *       * Parameters:       *       * streamType:         Select the type of audio stream this track is attached to       *                     (e.g. AUDIO_STREAM_MUSIC).       * sampleRate:         Data source sampling rate in Hz. -     * 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. +     * format:             Audio format. For mixed tracks, any PCM format supported by server is OK. +     *                     For direct and offloaded tracks, the possible format(s) depends on the +     *                     output sink.       * channelMask:        Channel mask, such that audio_is_output_channel(channelMask) is true.       * frameCount:         Minimum size of track PCM buffer in frames. This defines the       *                     application's contribution to the @@ -165,20 +178,32 @@ public:       *                     configuration.  Zero means to use a default value.       * flags:              See comments on audio_output_flags_t in <system/audio.h>.       * cbf:                Callback function. If not null, this function is called periodically -     *                     to provide new data and inform of marker, position updates, etc. +     *                     to provide new data in TRANSFER_CALLBACK mode +     *                     and inform of marker, position updates, etc.       * user:               Context for use by the callback receiver.       * notificationFrames: The callback function is called each time notificationFrames PCM       *                     frames have been consumed from track input buffer.       *                     This is expressed in units of frames at the initial source sample rate.       * sessionId:          Specific session ID, or zero to use default.       * transferType:       How data is transferred to AudioTrack. +     * offloadInfo:        If not NULL, provides offload parameters for +     *                     AudioSystem::getOutputForAttr(). +     * uid:                User ID of the app which initially requested this AudioTrack +     *                     for power management tracking, or -1 for current user ID. +     * pid:                Process ID of the app which initially requested this AudioTrack +     *                     for power management tracking, or -1 for current process ID. +     * pAttributes:        If not NULL, supersedes streamType for use case selection. +     * doNotReconnect:     If set to true, AudioTrack won't automatically recreate the IAudioTrack +                           binder to AudioFlinger. +                           It will return an error instead.  The application will recreate +                           the track based on offloading or different channel configuration, etc.       * threadCanCallJava:  Not present in parameter list, and so is fixed at false.       */                          AudioTrack( audio_stream_type_t streamType,                                      uint32_t sampleRate,                                      audio_format_t format, -                                    audio_channel_mask_t, +                                    audio_channel_mask_t channelMask,                                      size_t frameCount    = 0,                                      audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,                                      callback_t cbf       = NULL, @@ -189,13 +214,15 @@ public:                                      const audio_offload_info_t *offloadInfo = NULL,                                      int uid = -1,                                      pid_t pid = -1, -                                    const audio_attributes_t* pAttributes = NULL); +                                    const audio_attributes_t* pAttributes = NULL, +                                    bool doNotReconnect = false);      /* Creates an audio track and registers it with AudioFlinger.       * With this constructor, the track is configured for static buffer mode. -     * The format must not be 8-bit linear PCM.       * Data to be rendered is passed in a shared memory buffer -     * identified by the argument sharedBuffer, which must be non-0. +     * identified by the argument sharedBuffer, which should be non-0. +     * If sharedBuffer is zero, this constructor is equivalent to the previous constructor +     * but without the ability to specify a non-zero value for the frameCount parameter.       * The memory should be initialized to the desired data before calling start().       * The write() method is not supported in this case.       * It is recommended to pass a callback function to be notified of playback end by an @@ -216,7 +243,8 @@ public:                                      const audio_offload_info_t *offloadInfo = NULL,                                      int uid = -1,                                      pid_t pid = -1, -                                    const audio_attributes_t* pAttributes = NULL); +                                    const audio_attributes_t* pAttributes = NULL, +                                    bool doNotReconnect = false);      /* Terminates the AudioTrack and unregisters it from AudioFlinger.       * Also destroys all resources associated with the AudioTrack. @@ -227,6 +255,7 @@ public:      /* Initialize an AudioTrack that was created using the AudioTrack() constructor.       * Don't call set() more than once, or after the AudioTrack() constructors that take parameters. +     * set() is not multi-thread safe.       * Returned status (from utils/Errors.h) can be:       *  - NO_ERROR: successful initialization       *  - INVALID_OPERATION: AudioTrack is already initialized @@ -259,7 +288,8 @@ public:                              const audio_offload_info_t *offloadInfo = NULL,                              int uid = -1,                              pid_t pid = -1, -                            const audio_attributes_t* pAttributes = NULL); +                            const audio_attributes_t* pAttributes = NULL, +                            bool doNotReconnect = false);      /* Result of constructing the AudioTrack. This must be checked for successful initialization       * before using any AudioTrack API (except for set()), because using @@ -347,6 +377,26 @@ public:      /* Return current source sample rate in Hz */              uint32_t    getSampleRate() const; +    /* Return the original source sample rate in Hz. This corresponds to the sample rate +     * if playback rate had normal speed and pitch. +     */ +            uint32_t    getOriginalSampleRate() const; + +    /* Set source playback rate for timestretch +     * 1.0 is normal speed: < 1.0 is slower, > 1.0 is faster +     * 1.0 is normal pitch: < 1.0 is lower pitch, > 1.0 is higher pitch +     * +     * AUDIO_TIMESTRETCH_SPEED_MIN <= speed <= AUDIO_TIMESTRETCH_SPEED_MAX +     * AUDIO_TIMESTRETCH_PITCH_MIN <= pitch <= AUDIO_TIMESTRETCH_PITCH_MAX +     * +     * Speed increases the playback rate of media, but does not alter pitch. +     * Pitch increases the "tonal frequency" of media, but does not affect the playback rate. +     */ +            status_t    setPlaybackRate(const AudioPlaybackRate &playbackRate); + +    /* Return current playback rate */ +            const AudioPlaybackRate& getPlaybackRate() const; +      /* Enables looping and sets the start and end points of looping.       * Only supported for static buffer mode.       * @@ -461,7 +511,38 @@ public:       *  handle on audio hardware output, or AUDIO_IO_HANDLE_NONE if the       *  track needed to be re-created but that failed       */ +private:              audio_io_handle_t    getOutput() const; +public: + +    /* Selects the audio device to use for output of this AudioTrack. A value of +     * AUDIO_PORT_HANDLE_NONE indicates default (AudioPolicyManager) routing. +     * +     * Parameters: +     *  The device ID of the selected device (as returned by the AudioDevicesManager API). +     * +     * Returned value: +     *  - NO_ERROR: successful operation +     *    TODO: what else can happen here? +     */ +            status_t    setOutputDevice(audio_port_handle_t deviceId); + +    /* Returns the ID of the audio device selected for this AudioTrack. +     * A value of AUDIO_PORT_HANDLE_NONE indicates default (AudioPolicyManager) routing. +     * +     * Parameters: +     *  none. +     */ +     audio_port_handle_t getOutputDevice(); + +     /* Returns the ID of the audio device actually used by the output to which this AudioTrack is +      * attached. +      * A value of AUDIO_PORT_HANDLE_NONE indicates the audio track is not attached to any output. +      * +      * Parameters: +      *  none. +      */ +     audio_port_handle_t getRoutedDeviceId();      /* Returns the unique session ID associated with this track.       * @@ -487,10 +568,18 @@ public:       */              status_t    attachAuxEffect(int effectId); -    /* Obtains a buffer of up to "audioBuffer->frameCount" empty slots for frames. +    /* Public API for TRANSFER_OBTAIN mode. +     * Obtains a buffer of up to "audioBuffer->frameCount" empty slots for frames.       * After filling these slots with data, the caller should release them with releaseBuffer().       * If the track buffer is not full, obtainBuffer() returns as many contiguous       * [empty slots for] frames as are available immediately. +     * +     * If nonContig is non-NULL, it is an output parameter that will be set to the number of +     * additional non-contiguous frames that are predicted to be available immediately, +     * if the client were to release the first frames and then call obtainBuffer() again. +     * This value is only a prediction, and needs to be confirmed. +     * It will be set to zero for an error return. +     *       * If the track buffer is full and track is stopped, obtainBuffer() returns WOULD_BLOCK       * regardless of the value of waitCount.       * If the track buffer is full and track is not stopped, obtainBuffer() blocks with a @@ -499,10 +588,6 @@ public:       * is exhausted, at which point obtainBuffer() will either block       * or return WOULD_BLOCK depending on the value of the "waitCount"       * parameter. -     * Each sample is 16-bit signed PCM. -     * -     * obtainBuffer() and releaseBuffer() are deprecated for direct use by applications, -     * which should use write() or callback EVENT_MORE_DATA instead.       *       * Interpretation of waitCount:       *  +n  limits wait time to n * WAIT_PERIOD_MS, @@ -511,24 +596,27 @@ public:       *       * Buffer fields       * On entry: -     *  frameCount  number of frames requested +     *  frameCount  number of [empty slots for] frames requested +     *  size        ignored +     *  raw         ignored       * After error return:       *  frameCount  0       *  size        0       *  raw         undefined       * After successful return: -     *  frameCount  actual number of frames available, <= number requested +     *  frameCount  actual number of [empty slots for] frames available, <= number requested       *  size        actual number of bytes available       *  raw         pointer to the buffer       */ - -    /* FIXME Deprecated public API for TRANSFER_OBTAIN mode */ -            status_t    obtainBuffer(Buffer* audioBuffer, int32_t waitCount) -                                __attribute__((__deprecated__)); +            status_t    obtainBuffer(Buffer* audioBuffer, int32_t waitCount, +                                size_t *nonContig = NULL);  private:      /* If nonContig is non-NULL, it is an output parameter that will be set to the number of -     * additional non-contiguous frames that are available immediately. +     * additional non-contiguous frames that are predicted to be available immediately, +     * if the client were to release the first frames and then call obtainBuffer() again. +     * This value is only a prediction, and needs to be confirmed. +     * It will be set to zero for an error return.       * FIXME We could pass an array of Buffers instead of only one Buffer to obtainBuffer(),       * in case the requested amount of frames is in two or more non-contiguous regions.       * FIXME requested and elapsed are both relative times.  Consider changing to absolute time. @@ -537,9 +625,15 @@ private:                                       struct timespec *elapsed = NULL, size_t *nonContig = NULL);  public: -    /* 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); +    /* Public API for TRANSFER_OBTAIN mode. +     * Release a filled buffer of frames for AudioFlinger to process. +     * +     * Buffer fields: +     *  frameCount  currently ignored but recommend to set to actual number of frames filled +     *  size        actual number of bytes filled, must be multiple of frameSize +     *  raw         ignored +     */ +            void        releaseBuffer(const Buffer* audioBuffer);      /* As a convenience we provide a write() interface to the audio buffer.       * Input parameter 'size' is in byte units. @@ -550,8 +644,14 @@ public:       *      BAD_VALUE           size is invalid       *      WOULD_BLOCK         when obtainBuffer() returns same, or       *                          AudioTrack was stopped during the write +     *      DEAD_OBJECT         when AudioFlinger dies or the output device changes and +     *                          the track cannot be automatically restored. +     *                          The application needs to recreate the AudioTrack +     *                          because the audio device changed or AudioFlinger died. +     *                          This typically occurs for direct or offload tracks +     *                          or if mDoNotReconnect is true.       *      or any other error code returned by IAudioTrack::start() or restoreTrack_l(). -     * Default behavior is to only return until all data has been transferred. Set 'blocking' to +     * Default behavior is to only return when all data has been transferred. Set 'blocking' to       * false for the method to return immediately without waiting to try multiple times to write       * the full content of the buffer.       */ @@ -559,6 +659,7 @@ public:      /*       * Dumps the state of an audio track. +     * Not a general-purpose API; intended only for use by media player service to dump its tracks.       */              status_t    dump(int fd, const Vector<String16>& args) const; @@ -589,19 +690,45 @@ public:       *                     overall hardware latency to physical output. In WOULD_BLOCK cases,       *                     one might poll again, or use getPosition(), or use 0 position and       *                     current time for the timestamp. +     *         DEAD_OBJECT if AudioFlinger dies or the output device changes and +     *                     the track cannot be automatically restored. +     *                     The application needs to recreate the AudioTrack +     *                     because the audio device changed or AudioFlinger died. +     *                     This typically occurs for direct or offload tracks +     *                     or if mDoNotReconnect is true.       *         INVALID_OPERATION  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); +    /* Add an AudioDeviceCallback. The caller will be notified when the audio device to which this +     * AudioTrack is routed is updated. +     * Replaces any previously installed callback. +     * Parameters: +     *  callback:  The callback interface +     * Returns NO_ERROR if successful. +     *         INVALID_OPERATION if the same callback is already installed. +     *         NO_INIT or PREMISSION_DENIED if AudioFlinger service is not reachable +     *         BAD_VALUE if the callback is NULL +     */ +            status_t addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback); + +    /* remove an AudioDeviceCallback. +     * Parameters: +     *  callback:  The callback interface +     * Returns NO_ERROR if successful. +     *         INVALID_OPERATION if the callback is not installed +     *         BAD_VALUE if the callback is NULL +     */ +            status_t removeAudioDeviceCallback( +                    const sp<AudioSystem::AudioDeviceCallback>& callback); +  protected:      /* copying audio tracks is not allowed */                          AudioTrack(const AudioTrack& other);              AudioTrack& operator = (const AudioTrack& other); -            void        setAttributesFromStreamType(audio_stream_type_t streamType); -      /* a small internal class to handle the callback */      class AudioTrackThread : public Thread      { @@ -614,6 +741,7 @@ protected:                  void        pause();    // suspend thread from execution at next loop boundary                  void        resume();   // allow thread to execute, if not requested to exit +                void        wake();     // wake to handle changed notification conditions.      private:                  void        pauseInternal(nsecs_t ns = 0LL); @@ -628,7 +756,9 @@ protected:          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 +        bool                mIgnoreNextPausedInt;   // skip any internal pause and go immediately +                                        // to processAudioBuffer() as state may have changed +                                        // since pause time calculated.      };              // body of AudioTrackThread::threadLoop() @@ -641,10 +771,6 @@ protected:              static const nsecs_t NS_WHENEVER = -1, NS_INACTIVE = -2, NS_NEVER = -3;              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(); @@ -657,6 +783,10 @@ protected:              // FIXME enum is faster than strcmp() for parameter 'from'              status_t restoreTrack_l(const char *from); +            bool     isOffloaded() const; +            bool     isDirect() const; +            bool     isOffloadedOrDirect() const; +              bool     isOffloaded_l() const                  { return (mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0; } @@ -670,6 +800,9 @@ protected:              // increment mPosition by the delta of mServer, and return new value of mPosition              uint32_t updateAndGetPosition_l(); +            // check sample rate and speed is compatible with AudioTrack +            bool     isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed) const; +      // Next 4 fields may be changed if IAudioTrack is re-created, but always != 0      sp<IAudioTrack>         mAudioTrack;      sp<IMemory>             mCblkMemory; @@ -680,12 +813,21 @@ protected:      float                   mVolume[2];      float                   mSendLevel; -    mutable uint32_t        mSampleRate;            // mutable because getSampleRate() can update it. +    mutable uint32_t        mSampleRate;            // mutable because getSampleRate() can update it +    uint32_t                mOriginalSampleRate; +    AudioPlaybackRate       mPlaybackRate;      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 +    // The following AudioFlinger server-side values are cached in createAudioTrack_l(). +    // These values can be used for informational purposes until the track is invalidated, +    // whereupon restoreTrack_l() calls createTrack_l() to update the values. +    uint32_t                mAfLatency;             // AudioFlinger latency in ms +    size_t                  mAfFrameCount;          // AudioFlinger frame count +    uint32_t                mAfSampleRate;          // AudioFlinger sample rate +      // constant after constructor or set()      audio_format_t          mFormat;                // as requested by client, not forced to 16-bit      audio_stream_type_t     mStreamType;            // mStreamType == AUDIO_STREAM_DEFAULT implies @@ -698,10 +840,7 @@ protected:      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. -    size_t                  mFrameSize;             // app-level frame size -    size_t                  mFrameSizeAF;           // AudioFlinger frame size +    size_t                  mFrameSize;             // frame size in bytes      status_t                mStatus; @@ -732,17 +871,25 @@ protected:      bool                    mRefreshRemaining;      // processAudioBuffer() should refresh                                                      // mRemainingFrames and mRetryOnPartialBuffer +                                                    // used for static track cbf and restoration +    int32_t                 mLoopCount;             // last setLoop loopCount; zero means disabled +    uint32_t                mLoopStart;             // last setLoop loopStart +    uint32_t                mLoopEnd;               // last setLoop loopEnd +    int32_t                 mLoopCountNotified;     // the last loopCount notified by callback. +                                                    // mLoopCountNotified counts down, matching +                                                    // the remaining loop count for static track +                                                    // playback. +      // These are private to processAudioBuffer(), and are not protected by a lock      uint32_t                mRemainingFrames;       // number of frames to request in obtainBuffer()      bool                    mRetryOnPartialBuffer;  // sleep and retry after partial obtainBuffer()      uint32_t                mObservedSequence;      // last observed value of mSequence -    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, @@ -758,10 +905,17 @@ protected:      int64_t                 mStartUs;               // the start time after flush or stop.                                                      // only used for offloaded and direct tracks. +    bool                    mPreviousTimestampValid;// true if mPreviousTimestamp is valid +    bool                    mTimestampStartupGlitchReported; // reduce log spam +    bool                    mRetrogradeMotionReported; // reduce log spam +    AudioTimestamp          mPreviousTimestamp;     // used to detect retrograde motion +      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. +    bool                    mDoNotReconnect; +      int                     mSessionId;      int                     mAuxEffectId; @@ -783,6 +937,10 @@ protected:      bool                    mInUnderrun;            // whether track is currently in underrun state      uint32_t                mPausedPosition; +    // For Device Selection API +    //  a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing. +    audio_port_handle_t     mSelectedDeviceId; +  private:      class DeathNotifier : public IBinder::DeathRecipient {      public: @@ -797,6 +955,8 @@ private:      uint32_t                mSequence;              // incremented for each new IAudioTrack attempt      int                     mClientUid;      pid_t                   mClientPid; + +    sp<AudioSystem::AudioDeviceCallback> mDeviceCallback;  };  class TimedAudioTrack : public AudioTrack diff --git a/include/media/EffectsFactoryApi.h b/include/media/EffectsFactoryApi.h index b1ed7b0..64a3212 100644 --- a/include/media/EffectsFactoryApi.h +++ b/include/media/EffectsFactoryApi.h @@ -171,6 +171,8 @@ int EffectGetDescriptor(const effect_uuid_t *pEffectUuid, effect_descriptor_t *p  ////////////////////////////////////////////////////////////////////////////////  int EffectIsNullUuid(const effect_uuid_t *pEffectUuid); +int EffectDumpEffects(int fd); +  #if __cplusplus  }  // extern "C"  #endif diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index 31a14f0..5051aff 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -85,15 +85,19 @@ public:                                  uint32_t sampleRate,                                  audio_format_t format,                                  audio_channel_mask_t channelMask, +                                const String16& callingPackage,                                  size_t *pFrameCount,                                  track_flags_t *flags,                                  pid_t tid,  // -1 means unused, otherwise must be valid non-0 +                                int clientUid,                                  int *sessionId,                                  size_t *notificationFrames,                                  sp<IMemory>& cblk,                                  sp<IMemory>& buffers,   // return value 0 means it follows cblk                                  status_t *status) = 0; +    // FIXME Surprisingly, sampleRate/format/frameCount/latency don't work for input handles +      /* query the audio hardware state. This state never changes,       * and therefore can be cached.       */ @@ -142,6 +146,7 @@ public:      virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0;      // retrieve the audio recording buffer size +    // FIXME This API assumes a route, and so should be deprecated.      virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,              audio_channel_mask_t channelMask) const = 0; @@ -195,6 +200,7 @@ public:                                      // AudioFlinger doesn't take over handle reference from client                                      audio_io_handle_t output,                                      int sessionId, +                                    const String16& callingPackage,                                      status_t *status,                                      int *id,                                      int *enabled) = 0; @@ -237,6 +243,9 @@ public:      /* Get the HW synchronization source used for an audio session */      virtual audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId) = 0; + +    /* Indicate JAVA services are ready (scheduling, power management ...) */ +    virtual status_t systemReady() = 0;  }; diff --git a/include/media/IAudioFlingerClient.h b/include/media/IAudioFlingerClient.h index 75a9971..0080bc9 100644 --- a/include/media/IAudioFlingerClient.h +++ b/include/media/IAudioFlingerClient.h @@ -22,6 +22,7 @@  #include <binder/IInterface.h>  #include <utils/KeyedVector.h>  #include <system/audio.h> +#include <media/AudioIoDescriptor.h>  namespace android { @@ -33,7 +34,8 @@ public:      DECLARE_META_INTERFACE(AudioFlingerClient);      // Notifies a change of audio input/output configuration. -    virtual void ioConfigChanged(int event, audio_io_handle_t ioHandle, const void *param2) = 0; +    virtual void ioConfigChanged(audio_io_config_event event, +                                 const sp<AudioIoDescriptor>& ioDesc) = 0;  }; diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h index c98c475..6b93f6f 100644 --- a/include/media/IAudioPolicyService.h +++ b/include/media/IAudioPolicyService.h @@ -44,7 +44,8 @@ public:      //      virtual status_t setDeviceConnectionState(audio_devices_t device,                                                audio_policy_dev_state_t state, -                                              const char *device_address) = 0; +                                              const char *device_address, +                                              const char *device_name) = 0;      virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,                                                                    const char *device_address) = 0;      virtual status_t setPhoneState(audio_mode_t state) = 0; @@ -61,10 +62,12 @@ public:                                          audio_io_handle_t *output,                                          audio_session_t session,                                          audio_stream_type_t *stream, +                                        uid_t uid,                                          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, +                                        audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE,                                          const audio_offload_info_t *offloadInfo = NULL) = 0;      virtual status_t startOutput(audio_io_handle_t output,                                   audio_stream_type_t stream, @@ -76,12 +79,14 @@ public:                                 audio_stream_type_t stream,                                 audio_session_t session) = 0;      virtual status_t  getInputForAttr(const audio_attributes_t *attr, -                                      audio_io_handle_t *input, -                                      audio_session_t session, -                                      uint32_t samplingRate, -                                      audio_format_t format, -                                      audio_channel_mask_t channelMask, -                                      audio_input_flags_t flags) = 0; +                              audio_io_handle_t *input, +                              audio_session_t session, +                              uid_t uid, +                              uint32_t samplingRate, +                              audio_format_t format, +                              audio_channel_mask_t channelMask, +                              audio_input_flags_t flags, +                              audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE) = 0;      virtual status_t startInput(audio_io_handle_t input,                                  audio_session_t session) = 0;      virtual status_t stopInput(audio_io_handle_t input, @@ -144,6 +149,8 @@ public:      virtual void registerClient(const sp<IAudioPolicyServiceClient>& client) = 0; +    virtual void setAudioPortCallbacksEnabled(bool enabled) = 0; +      virtual status_t acquireSoundTriggerSession(audio_session_t *session,                                             audio_io_handle_t *ioHandle,                                             audio_devices_t *device) = 0; @@ -153,6 +160,11 @@ public:      virtual audio_mode_t getPhoneState() = 0;      virtual status_t registerPolicyMixes(Vector<AudioMix> mixes, bool registration) = 0; + +    virtual status_t startAudioSource(const struct audio_port_config *source, +                                      const audio_attributes_t *attributes, +                                      audio_io_handle_t *handle) = 0; +    virtual status_t stopAudioSource(audio_io_handle_t handle) = 0;  }; diff --git a/include/media/IAudioPolicyServiceClient.h b/include/media/IAudioPolicyServiceClient.h index 59df046..a7f2cc3 100644 --- a/include/media/IAudioPolicyServiceClient.h +++ b/include/media/IAudioPolicyServiceClient.h @@ -35,6 +35,8 @@ public:      virtual void onAudioPortListUpdate() = 0;      // Notifies a change of audio patch configuration.      virtual void onAudioPatchListUpdate() = 0; +    // Notifies a change in the mixing state of a specific mix in a dynamic audio policy +    virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0;  }; diff --git a/include/media/ICrypto.h b/include/media/ICrypto.h index 07742ca..ea316de 100644 --- a/include/media/ICrypto.h +++ b/include/media/ICrypto.h @@ -25,6 +25,7 @@  namespace android {  struct AString; +class IMemory;  struct ICrypto : public IInterface {      DECLARE_META_INTERFACE(Crypto); @@ -43,12 +44,14 @@ struct ICrypto : public IInterface {      virtual void notifyResolution(uint32_t width, uint32_t height) = 0; +    virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId) = 0; +      virtual ssize_t decrypt(              bool secure,              const uint8_t key[16],              const uint8_t iv[16],              CryptoPlugin::Mode mode, -            const void *srcPtr, +            const sp<IMemory> &sharedBuffer, size_t offset,              const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,              void *dstPtr,              AString *errorDetailMsg) = 0; @@ -61,6 +64,9 @@ struct BnCrypto : public BnInterface<ICrypto> {      virtual status_t onTransact(              uint32_t code, const Parcel &data, Parcel *reply,              uint32_t flags = 0); +private: +    void readVector(const Parcel &data, Vector<uint8_t> &vector) const; +    void writeVector(Parcel *reply, Vector<uint8_t> const &vector) const;  };  }  // namespace android diff --git a/include/media/IDataSource.h b/include/media/IDataSource.h new file mode 100644 index 0000000..07e46f7 --- /dev/null +++ b/include/media/IDataSource.h @@ -0,0 +1,61 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IDATASOURCE_H +#define ANDROID_IDATASOURCE_H + +#include <binder/IInterface.h> +#include <media/stagefright/foundation/ABase.h> +#include <utils/Errors.h> + +namespace android { + +class IMemory; + +// A binder interface for implementing a stagefright DataSource remotely. +class IDataSource : public IInterface { +public: +    DECLARE_META_INTERFACE(DataSource); + +    // Get the memory that readAt writes into. +    virtual sp<IMemory> getIMemory() = 0; +    // Read up to |size| bytes into the memory returned by getIMemory(). Returns +    // the number of bytes read, or -1 on error. |size| must not be larger than +    // the buffer. +    virtual ssize_t readAt(off64_t offset, size_t size) = 0; +    // Get the size, or -1 if the size is unknown. +    virtual status_t getSize(off64_t* size) = 0; +    // This should be called before deleting |this|. The other methods may +    // return errors if they're called after calling close(). +    virtual void close() = 0; + +private: +    DISALLOW_EVIL_CONSTRUCTORS(IDataSource); +}; + +// ---------------------------------------------------------------------------- + +class BnDataSource : public BnInterface<IDataSource> { +public: +    virtual status_t onTransact(uint32_t code, +                                const Parcel& data, +                                Parcel* reply, +                                uint32_t flags = 0); +}; + +}; // namespace android + +#endif // ANDROID_IDATASOURCE_H diff --git a/include/media/IDrm.h b/include/media/IDrm.h index affcbd7..9449beb 100644 --- a/include/media/IDrm.h +++ b/include/media/IDrm.h @@ -47,7 +47,8 @@ struct IDrm : public IInterface {                        Vector<uint8_t> const &initData,                        String8 const &mimeType, DrmPlugin::KeyType keyType,                        KeyedVector<String8, String8> const &optionalParameters, -                      Vector<uint8_t> &request, String8 &defaultUrl) = 0; +                      Vector<uint8_t> &request, String8 &defaultUrl, +                      DrmPlugin::KeyRequestType *keyRequestType) = 0;      virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,                                          Vector<uint8_t> const &response, diff --git a/include/media/IMediaCodecList.h b/include/media/IMediaCodecList.h index e93ea8b..12b52d7 100644 --- a/include/media/IMediaCodecList.h +++ b/include/media/IMediaCodecList.h @@ -21,6 +21,8 @@  #include <binder/IInterface.h>  #include <binder/Parcel.h> +#include <media/stagefright/foundation/AMessage.h> +  namespace android {  struct MediaCodecInfo; @@ -33,6 +35,8 @@ public:      virtual size_t countCodecs() const = 0;      virtual sp<MediaCodecInfo> getCodecInfo(size_t index) const = 0; +    virtual const sp<AMessage> getGlobalSettings() const = 0; +      virtual ssize_t findCodecByType(              const char *type, bool encoder, size_t startIndex = 0) const = 0; diff --git a/include/media/IMediaMetadataRetriever.h b/include/media/IMediaMetadataRetriever.h index 2529800..c90f254 100644 --- a/include/media/IMediaMetadataRetriever.h +++ b/include/media/IMediaMetadataRetriever.h @@ -26,6 +26,7 @@  namespace android { +class IDataSource;  struct IMediaHTTPService;  class IMediaMetadataRetriever: public IInterface @@ -40,6 +41,7 @@ public:              const KeyedVector<String8, String8> *headers = NULL) = 0;      virtual status_t        setDataSource(int fd, int64_t offset, int64_t length) = 0; +    virtual status_t        setDataSource(const sp<IDataSource>& dataSource) = 0;      virtual sp<IMemory>     getFrameAtTime(int64_t timeUs, int option) = 0;      virtual sp<IMemory>     extractAlbumArt() = 0;      virtual const char*     extractMetadata(int keyCode) = 0; diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h index db62cd5..0fd8933 100644 --- a/include/media/IMediaPlayer.h +++ b/include/media/IMediaPlayer.h @@ -31,9 +31,12 @@ namespace android {  class Parcel;  class Surface; -class IStreamSource; +class IDataSource; +struct IStreamSource;  class IGraphicBufferProducer;  struct IMediaHTTPService; +struct AudioPlaybackRate; +struct AVSyncSettings;  class IMediaPlayer: public IInterface  { @@ -49,6 +52,7 @@ public:      virtual status_t        setDataSource(int fd, int64_t offset, int64_t length) = 0;      virtual status_t        setDataSource(const sp<IStreamSource>& source) = 0; +    virtual status_t        setDataSource(const sp<IDataSource>& source) = 0;      virtual status_t        setVideoSurfaceTexture(                                      const sp<IGraphicBufferProducer>& bufferProducer) = 0;      virtual status_t        prepareAsync() = 0; @@ -56,6 +60,11 @@ public:      virtual status_t        stop() = 0;      virtual status_t        pause() = 0;      virtual status_t        isPlaying(bool* state) = 0; +    virtual status_t        setPlaybackSettings(const AudioPlaybackRate& rate) = 0; +    virtual status_t        getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) = 0; +    virtual status_t        setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) = 0; +    virtual status_t        getSyncSettings(AVSyncSettings* sync /* nonnull */, +                                            float* videoFps /* nonnull */) = 0;      virtual status_t        seekTo(int msec) = 0;      virtual status_t        getCurrentPosition(int* msec) = 0;      virtual status_t        getDuration(int* msec) = 0; diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h index 67b599a..a316ce2 100644 --- a/include/media/IMediaPlayerService.h +++ b/include/media/IMediaPlayerService.h @@ -47,9 +47,10 @@ class IMediaPlayerService: public IInterface  public:      DECLARE_META_INTERFACE(MediaPlayerService); -    virtual sp<IMediaRecorder> createMediaRecorder() = 0; +    virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName) = 0;      virtual sp<IMediaMetadataRetriever> createMetadataRetriever() = 0; -    virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client, int audioSessionId = 0) = 0; +    virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client, int audioSessionId = 0) +            = 0;      virtual sp<IOMX>            getOMX() = 0;      virtual sp<ICrypto>         makeCrypto() = 0; @@ -64,8 +65,8 @@ public:      // display client when display connection, disconnection or errors occur.      // The assumption is that at most one remote display will be connected to the      // provided interface at a time. -    virtual sp<IRemoteDisplay> listenForRemoteDisplay(const sp<IRemoteDisplayClient>& client, -            const String8& iface) = 0; +    virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName, +            const sp<IRemoteDisplayClient>& client, const String8& iface) = 0;      // codecs and audio devices usage tracking for the battery app      enum BatteryDataBits { diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h index 3e67550..77ed5d3 100644 --- a/include/media/IMediaRecorder.h +++ b/include/media/IMediaRecorder.h @@ -26,6 +26,7 @@ class Surface;  class ICamera;  class ICameraRecordingProxy;  class IMediaRecorderClient; +class IGraphicBufferConsumer;  class IGraphicBufferProducer;  class IMediaRecorder: public IInterface @@ -41,7 +42,6 @@ public:      virtual status_t setOutputFormat(int of) = 0;      virtual status_t setVideoEncoder(int ve) = 0;      virtual status_t setAudioEncoder(int ae) = 0; -    virtual status_t setOutputFile(const char* path) = 0;      virtual status_t setOutputFile(int fd, int64_t offset, int64_t length) = 0;      virtual status_t setVideoSize(int width, int height) = 0;      virtual status_t setVideoFrameRate(int frames_per_second) = 0; @@ -56,6 +56,7 @@ public:      virtual status_t init() = 0;      virtual status_t close() = 0;      virtual status_t release() = 0; +    virtual status_t setInputSurface(const sp<IGraphicBufferConsumer>& surface) = 0;      virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() = 0;  }; diff --git a/include/media/IOMX.h b/include/media/IOMX.h index 627f23b..3d29e4a 100644 --- a/include/media/IOMX.h +++ b/include/media/IOMX.h @@ -20,10 +20,15 @@  #include <binder/IInterface.h>  #include <gui/IGraphicBufferProducer.h> +#include <gui/IGraphicBufferConsumer.h>  #include <ui/GraphicBuffer.h>  #include <utils/List.h>  #include <utils/String8.h> +#include <list> + +#include <media/hardware/MetadataBufferType.h> +  #include <OMX_Core.h>  #include <OMX_Video.h> @@ -80,14 +85,16 @@ public:      virtual status_t getState(              node_id node, OMX_STATETYPE* state) = 0; +    // This will set *type to previous metadata buffer type on OMX error (not on binder error), and +    // new metadata buffer type on success.      virtual status_t storeMetaDataInBuffers( -            node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0; +            node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type = NULL) = 0;      virtual status_t prepareForAdaptivePlayback(              node_id node, OMX_U32 portIndex, OMX_BOOL enable,              OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) = 0; -   virtual status_t configureVideoTunnelMode( +    virtual status_t configureVideoTunnelMode(              node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,              OMX_U32 audioHwSync, native_handle_t **sidebandHandle) = 0; @@ -97,9 +104,10 @@ public:      virtual status_t getGraphicBufferUsage(              node_id node, OMX_U32 port_index, OMX_U32* usage) = 0; +    // Use |params| as an OMX buffer, but limit the size of the OMX buffer to |allottedSize|.      virtual status_t useBuffer(              node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, -            buffer_id *buffer) = 0; +            buffer_id *buffer, OMX_U32 allottedSize) = 0;      virtual status_t useGraphicBuffer(              node_id node, OMX_U32 port_index, @@ -109,9 +117,23 @@ public:              node_id node, OMX_U32 port_index,              const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) = 0; +    // This will set *type to resulting metadata buffer type on OMX error (not on binder error) as +    // well as on success.      virtual status_t createInputSurface(              node_id node, OMX_U32 port_index, -            sp<IGraphicBufferProducer> *bufferProducer) = 0; +            sp<IGraphicBufferProducer> *bufferProducer, +            MetadataBufferType *type = NULL) = 0; + +    virtual status_t createPersistentInputSurface( +            sp<IGraphicBufferProducer> *bufferProducer, +            sp<IGraphicBufferConsumer> *bufferConsumer) = 0; + +    // This will set *type to resulting metadata buffer type on OMX error (not on binder error) as +    // well as on success. +    virtual status_t setInputSurface( +            node_id node, OMX_U32 port_index, +            const sp<IGraphicBufferConsumer> &bufferConsumer, +            MetadataBufferType *type) = 0;      virtual status_t signalEndOfInputStream(node_id node) = 0; @@ -123,20 +145,32 @@ public:              node_id node, OMX_U32 port_index, size_t size,              buffer_id *buffer, void **buffer_data) = 0; +    // Allocate an OMX buffer of size |allotedSize|. Use |params| as the backup buffer, which +    // may be larger.      virtual status_t allocateBufferWithBackup(              node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, -            buffer_id *buffer) = 0; +            buffer_id *buffer, OMX_U32 allottedSize) = 0;      virtual status_t freeBuffer(              node_id node, OMX_U32 port_index, buffer_id buffer) = 0; -    virtual status_t fillBuffer(node_id node, buffer_id buffer) = 0; - +    enum { +        kFenceTimeoutMs = 1000 +    }; +    // Calls OMX_FillBuffer on buffer, and passes |fenceFd| to component if it supports +    // fences. Otherwise, it waits on |fenceFd| before calling OMX_FillBuffer. +    // Takes ownership of |fenceFd| even if this call fails. +    virtual status_t fillBuffer(node_id node, buffer_id buffer, int fenceFd = -1) = 0; + +    // Calls OMX_EmptyBuffer on buffer (after updating buffer header with |range_offset|, +    // |range_length|, |flags| and |timestamp|). Passes |fenceFd| to component if it +    // supports fences. Otherwise, it waits on |fenceFd| before calling OMX_EmptyBuffer. +    // Takes ownership of |fenceFd| even if this call fails.      virtual status_t emptyBuffer(              node_id node,              buffer_id buffer,              OMX_U32 range_offset, OMX_U32 range_length, -            OMX_U32 flags, OMX_TICKS timestamp) = 0; +            OMX_U32 flags, OMX_TICKS timestamp, int fenceFd = -1) = 0;      virtual status_t getExtensionIndex(              node_id node, @@ -147,6 +181,7 @@ 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_MAX_FPS, // data is float          INTERNAL_OPTION_START_TIME, // data is an int64_t          INTERNAL_OPTION_TIME_LAPSE, // data is an int64_t[2]      }; @@ -163,10 +198,11 @@ struct omx_message {          EVENT,          EMPTY_BUFFER_DONE,          FILL_BUFFER_DONE, - +        FRAME_RENDERED,      } type;      IOMX::node_id node; +    int fenceFd; // used for EMPTY_BUFFER_DONE and FILL_BUFFER_DONE; client must close this      union {          // if type == EVENT @@ -190,6 +226,11 @@ struct omx_message {              OMX_TICKS timestamp;          } extended_buffer_data; +        // if type == FRAME_RENDERED +        struct { +            OMX_TICKS timestamp; +            OMX_S64 nanoTime; +        } render_data;      } u;  }; @@ -197,7 +238,8 @@ class IOMXObserver : public IInterface {  public:      DECLARE_META_INTERFACE(OMXObserver); -    virtual void onMessage(const omx_message &msg) = 0; +    // Handle (list of) messages. +    virtual void onMessages(const std::list<omx_message> &messages) = 0;  };  //////////////////////////////////////////////////////////////////////////////// @@ -223,4 +265,15 @@ struct CodecProfileLevel {  }  // namespace android +inline static const char *asString(android::MetadataBufferType i, const char *def = "??") { +    using namespace android; +    switch (i) { +        case kMetadataBufferTypeCameraSource:   return "CameraSource"; +        case kMetadataBufferTypeGrallocSource:  return "GrallocSource"; +        case kMetadataBufferTypeANWBuffer:      return "ANWBuffer"; +        case kMetadataBufferTypeInvalid:        return "Invalid"; +        default:                                return def; +    } +} +  #endif  // ANDROID_IOMX_H_ diff --git a/include/media/IResourceManagerClient.h b/include/media/IResourceManagerClient.h new file mode 100644 index 0000000..aa0cd88 --- /dev/null +++ b/include/media/IResourceManagerClient.h @@ -0,0 +1,49 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IRESOURCEMANAGERCLIENT_H +#define ANDROID_IRESOURCEMANAGERCLIENT_H + +#include <utils/RefBase.h> +#include <utils/String8.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> + +namespace android { + +class IResourceManagerClient: public IInterface +{ +public: +    DECLARE_META_INTERFACE(ResourceManagerClient); + +    virtual bool reclaimResource() = 0; +    virtual String8 getName() = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnResourceManagerClient: public BnInterface<IResourceManagerClient> +{ +public: +    virtual status_t onTransact(uint32_t code, +                                const Parcel &data, +                                Parcel *reply, +                                uint32_t flags = 0); +}; + +}; // namespace android + +#endif // ANDROID_IRESOURCEMANAGERCLIENT_H diff --git a/include/media/IResourceManagerService.h b/include/media/IResourceManagerService.h new file mode 100644 index 0000000..1e4f6de --- /dev/null +++ b/include/media/IResourceManagerService.h @@ -0,0 +1,66 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IRESOURCEMANAGERSERVICE_H +#define ANDROID_IRESOURCEMANAGERSERVICE_H + +#include <utils/Errors.h>  // for status_t +#include <utils/KeyedVector.h> +#include <utils/RefBase.h> +#include <utils/String8.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> + +#include <media/IResourceManagerClient.h> +#include <media/MediaResource.h> +#include <media/MediaResourcePolicy.h> + +namespace android { + +class IResourceManagerService: public IInterface +{ +public: +    DECLARE_META_INTERFACE(ResourceManagerService); + +    virtual void config(const Vector<MediaResourcePolicy> &policies) = 0; + +    virtual void addResource( +            int pid, +            int64_t clientId, +            const sp<IResourceManagerClient> client, +            const Vector<MediaResource> &resources) = 0; + +    virtual void removeResource(int pid, int64_t clientId) = 0; + +    virtual bool reclaimResource( +            int callingPid, +            const Vector<MediaResource> &resources) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnResourceManagerService: public BnInterface<IResourceManagerService> +{ +public: +    virtual status_t onTransact(uint32_t code, +                                const Parcel &data, +                                Parcel *reply, +                                uint32_t flags = 0); +}; + +}; // namespace android + +#endif // ANDROID_IRESOURCEMANAGERSERVICE_H diff --git a/include/media/IStreamSource.h b/include/media/IStreamSource.h index 677119b..4a6aafd 100644 --- a/include/media/IStreamSource.h +++ b/include/media/IStreamSource.h @@ -23,7 +23,7 @@  namespace android {  struct AMessage; -struct IMemory; +class IMemory;  struct IStreamListener;  struct IStreamSource : public IInterface { @@ -81,6 +81,13 @@ struct IStreamListener : public IInterface {      // with the next PTS occuring in the stream. The value is of type int64_t.      static const char *const kKeyMediaTimeUs; +    // Optionally signalled as part of a discontinuity that includes +    // DISCONTINUITY_TIME. It indicates the media time (in us) of a recent +    // sample from the same content, and is used as a hint for the parser to +    // handle PTS wraparound. This is required when a new parser is created +    // to continue parsing content from the same timeline. +    static const char *const kKeyRecentMediaTimeUs; +      virtual void issueCommand(              Command cmd, bool synchronous, const sp<AMessage> &msg = NULL) = 0;  }; diff --git a/include/media/MediaCodecInfo.h b/include/media/MediaCodecInfo.h index cd56adb..4067b47 100644 --- a/include/media/MediaCodecInfo.h +++ b/include/media/MediaCodecInfo.h @@ -32,9 +32,11 @@  namespace android {  struct AMessage; -struct Parcel; +class Parcel;  struct CodecCapabilities; +typedef KeyedVector<AString, AString> CodecSettings; +  struct MediaCodecInfo : public RefBase {      struct ProfileLevel {          uint32_t mProfile; @@ -104,6 +106,7 @@ private:      MediaCodecInfo(AString name, bool encoder, const char *mime);      void addQuirk(const char *name);      status_t addMime(const char *mime); +    status_t updateMime(const char *mime);      status_t initializeCapabilities(const CodecCapabilities &caps);      void addDetail(const AString &key, const AString &value);      void addFeature(const AString &key, int32_t value); @@ -114,6 +117,7 @@ private:      DISALLOW_EVIL_CONSTRUCTORS(MediaCodecInfo);      friend class MediaCodecList; +    friend class MediaCodecListOverridesTest;  };  }  // namespace android diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h index 38dbb20..bce6ee3 100644 --- a/include/media/MediaMetadataRetrieverInterface.h +++ b/include/media/MediaMetadataRetrieverInterface.h @@ -25,6 +25,7 @@  namespace android { +class DataSource;  struct IMediaHTTPService;  // Abstract base class @@ -40,6 +41,7 @@ public:              const KeyedVector<String8, String8> *headers = NULL) = 0;      virtual status_t    setDataSource(int fd, int64_t offset, int64_t length) = 0; +    virtual status_t setDataSource(const sp<DataSource>& source) = 0;      virtual VideoFrame* getFrameAtTime(int64_t timeUs, int option) = 0;      virtual MediaAlbumArt* extractAlbumArt() = 0;      virtual const char* extractMetadata(int keyCode) = 0; diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index 4a6bf28..de82554 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -26,8 +26,10 @@  #include <utils/RefBase.h>  #include <media/mediaplayer.h> +#include <media/AudioResamplerPublic.h>  #include <media/AudioSystem.h>  #include <media/AudioTimestamp.h> +#include <media/AVSyncSettings.h>  #include <media/Metadata.h>  // Fwd decl to make sure everyone agrees that the scope of struct sockaddr_in is @@ -36,6 +38,7 @@ struct sockaddr_in;  namespace android { +class DataSource;  class Parcel;  class Surface;  class IGraphicBufferProducer; @@ -110,20 +113,35 @@ public:                  AudioCallback cb = NULL,                  void *cookie = NULL,                  audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, -                const audio_offload_info_t *offloadInfo = NULL) = 0; +                const audio_offload_info_t *offloadInfo = NULL, +                bool doNotReconnect = false, +                uint32_t suggestedFrameCount = 0) = 0;          virtual status_t    start() = 0; -        virtual ssize_t     write(const void* buffer, size_t size) = 0; + +        /* Input parameter |size| is in byte units stored in |buffer|. +         * Data is copied over and actual number of bytes written (>= 0) +         * is returned, or no data is copied and a negative status code +         * is returned (even when |blocking| is true). +         * When |blocking| is false, AudioSink will immediately return after +         * part of or full |buffer| is copied over. +         * When |blocking| is true, AudioSink will wait to copy the entire +         * buffer, unless an error occurs or the copy operation is +         * prematurely stopped. +         */ +        virtual ssize_t     write(const void* buffer, size_t size, bool blocking = true) = 0; +          virtual void        stop() = 0;          virtual void        flush() = 0;          virtual void        pause() = 0;          virtual void        close() = 0; -        virtual status_t    setPlaybackRatePermille(int32_t rate) { return INVALID_OPERATION; } +        virtual status_t    setPlaybackRate(const AudioPlaybackRate& rate) = 0; +        virtual status_t    getPlaybackRate(AudioPlaybackRate* rate /* nonnull */) = 0;          virtual bool        needsTrailingPadding() { return true; } -        virtual status_t    setParameters(const String8& keyValuePairs) { return NO_ERROR; }; -        virtual String8     getParameters(const String8& keys) { return String8::empty(); }; +        virtual status_t    setParameters(const String8& /* keyValuePairs */) { return NO_ERROR; } +        virtual String8     getParameters(const String8& /* keys */) { return String8::empty(); }      };                          MediaPlayerBase() : mCookie(0), mNotify(0) {} @@ -131,7 +149,7 @@ public:      virtual status_t    initCheck() = 0;      virtual bool        hardwareOutput() = 0; -    virtual status_t    setUID(uid_t uid) { +    virtual status_t    setUID(uid_t /* uid */) {          return INVALID_OPERATION;      } @@ -142,7 +160,11 @@ public:      virtual status_t    setDataSource(int fd, int64_t offset, int64_t length) = 0; -    virtual status_t    setDataSource(const sp<IStreamSource> &source) { +    virtual status_t    setDataSource(const sp<IStreamSource>& /* source */) { +        return INVALID_OPERATION; +    } + +    virtual status_t    setDataSource(const sp<DataSource>& /* source */) {          return INVALID_OPERATION;      } @@ -156,6 +178,31 @@ public:      virtual status_t    stop() = 0;      virtual status_t    pause() = 0;      virtual bool        isPlaying() = 0; +    virtual status_t    setPlaybackSettings(const AudioPlaybackRate& rate) { +        // by default, players only support setting rate to the default +        if (!isAudioPlaybackRateEqual(rate, AUDIO_PLAYBACK_RATE_DEFAULT)) { +            return BAD_VALUE; +        } +        return OK; +    } +    virtual status_t    getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) { +        *rate = AUDIO_PLAYBACK_RATE_DEFAULT; +        return OK; +    } +    virtual status_t    setSyncSettings(const AVSyncSettings& sync, float /* videoFps */) { +        // By default, players only support setting sync source to default; all other sync +        // settings are ignored. There is no requirement for getters to return set values. +        if (sync.mSource != AVSYNC_SOURCE_DEFAULT) { +            return BAD_VALUE; +        } +        return OK; +    } +    virtual status_t    getSyncSettings( +                                AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) { +        *sync = AVSyncSettings(); +        *videoFps = -1.f; +        return OK; +    }      virtual status_t    seekTo(int msec) = 0;      virtual status_t    getCurrentPosition(int *msec) = 0;      virtual status_t    getDuration(int *msec) = 0; @@ -166,13 +213,13 @@ public:      virtual status_t    getParameter(int key, Parcel *reply) = 0;      // default no-op implementation of optional extensions -    virtual status_t setRetransmitEndpoint(const struct sockaddr_in* endpoint) { +    virtual status_t setRetransmitEndpoint(const struct sockaddr_in* /* endpoint */) {          return INVALID_OPERATION;      } -    virtual status_t getRetransmitEndpoint(struct sockaddr_in* endpoint) { +    virtual status_t getRetransmitEndpoint(struct sockaddr_in* /* endpoint */) {          return INVALID_OPERATION;      } -    virtual status_t setNextPlayer(const sp<MediaPlayerBase>& next) { +    virtual status_t setNextPlayer(const sp<MediaPlayerBase>& /* next */) {          return OK;      } @@ -192,8 +239,8 @@ public:      //            the known metadata should be returned.      // @param[inout] records Parcel where the player appends its metadata.      // @return OK if the call was successful. -    virtual status_t    getMetadata(const media::Metadata::Filter& ids, -                                    Parcel *records) { +    virtual status_t    getMetadata(const media::Metadata::Filter& /* ids */, +                                    Parcel* /* records */) {          return INVALID_OPERATION;      }; @@ -216,7 +263,7 @@ public:          if (notifyCB) notifyCB(cookie, msg, ext1, ext2, obj);      } -    virtual status_t dump(int fd, const Vector<String16> &args) const { +    virtual status_t dump(int /* fd */, const Vector<String16>& /* args */) const {          return INVALID_OPERATION;      } diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h index f061d22..e02918f 100644 --- a/include/media/MediaProfiles.h +++ b/include/media/MediaProfiles.h @@ -58,24 +58,6 @@ enum camcorder_quality {      CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2005,  }; -/** - * Set CIF as default maximum import and export resolution of video editor. - * The maximum import and export resolutions are platform specific, - * which should be defined in media_profiles.xml. - * Set default maximum prefetch YUV frames to 6, which means video editor can - * queue up to 6 YUV frames in the video encoder source. - * This value is used to limit the amount of memory used by video editor - * engine when the encoder consumes YUV frames at a lower speed - * than video editor engine produces. - */ -enum videoeditor_capability { -    VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH = 352, -    VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT = 288, -    VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH = 352, -    VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT = 288, -    VIDEOEDITOR_DEFAULT_MAX_PREFETCH_YUV_FRAMES = 6 -}; -  enum video_decoder {      VIDEO_DECODER_WMV,  }; @@ -148,32 +130,6 @@ public:      int getVideoEncoderParamByName(const char *name, video_encoder codec) const;      /** -     * Returns the value for the given param name for the video editor cap -     * param or -1 if error. -     * Supported param name are: -     * videoeditor.input.width.max - max input video frame width -     * videoeditor.input.height.max - max input video frame height -     * videoeditor.output.width.max - max output video frame width -     * videoeditor.output.height.max - max output video frame height -     * maxPrefetchYUVFrames - max prefetch YUV frames in video editor engine. This value is used -     * to limit the memory consumption. -     */ -    int getVideoEditorCapParamByName(const char *name) const; - -    /** -     * Returns the value for the given param name for the video editor export codec format -     * param or -1 if error. -     * Supported param name are: -     * videoeditor.export.profile - export video profile -     * videoeditor.export.level - export video level -     * Supported param codec are: -     * 1 for h263 -     * 2 for h264 -     * 3 for mpeg4 -     */ -    int getVideoEditorExportParamByName(const char *name, int codec) const; - -    /**       * Returns the audio encoders supported.       */      Vector<audio_encoder> getAudioEncoders() const; @@ -221,7 +177,7 @@ private:      MediaProfiles& operator=(const MediaProfiles&);  // Don't call me      MediaProfiles(const MediaProfiles&);             // Don't call me -    MediaProfiles() { mVideoEditorCap = NULL; }        // Dummy default constructor +    MediaProfiles() {}                               // Dummy default constructor      ~MediaProfiles();                                // Don't delete me      struct VideoCodec { @@ -366,31 +322,6 @@ private:          int mCameraId;          Vector<int> mLevels;      }; -    struct ExportVideoProfile { -        ExportVideoProfile(int codec, int profile, int level) -            :mCodec(codec),mProfile(profile),mLevel(level) {} -        ~ExportVideoProfile() {} -        int mCodec; -        int mProfile; -        int mLevel; -    }; -    struct VideoEditorCap { -        VideoEditorCap(int inFrameWidth, int inFrameHeight, -            int outFrameWidth, int outFrameHeight, int frames) -            : mMaxInputFrameWidth(inFrameWidth), -              mMaxInputFrameHeight(inFrameHeight), -              mMaxOutputFrameWidth(outFrameWidth), -              mMaxOutputFrameHeight(outFrameHeight), -              mMaxPrefetchYUVFrames(frames) {} - -        ~VideoEditorCap() {} - -        int mMaxInputFrameWidth; -        int mMaxInputFrameHeight; -        int mMaxOutputFrameWidth; -        int mMaxOutputFrameHeight; -        int mMaxPrefetchYUVFrames; -    };      int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const;      void initRequiredProfileRefs(const Vector<int>& cameraIds); @@ -403,7 +334,6 @@ private:      static void logAudioEncoderCap(const AudioEncoderCap& cap);      static void logVideoDecoderCap(const VideoDecoderCap& cap);      static void logAudioDecoderCap(const AudioDecoderCap& cap); -    static void logVideoEditorCap(const VideoEditorCap& cap);      // If the xml configuration file does exist, use the settings      // from the xml @@ -415,9 +345,6 @@ private:      static VideoDecoderCap* createVideoDecoderCap(const char **atts);      static VideoEncoderCap* createVideoEncoderCap(const char **atts);      static AudioEncoderCap* createAudioEncoderCap(const char **atts); -    static VideoEditorCap* createVideoEditorCap( -                const char **atts, MediaProfiles *profiles); -    static ExportVideoProfile* createExportVideoProfile(const char **atts);      static CamcorderProfile* createCamcorderProfile(                  int cameraId, const char **atts, Vector<int>& cameraIds); @@ -461,8 +388,6 @@ private:      static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles);      static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles);      static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles); -    static void createDefaultVideoEditorCap(MediaProfiles *profiles); -    static void createDefaultExportVideoProfiles(MediaProfiles *profiles);      static VideoEncoderCap* createDefaultH263VideoEncoderCap();      static VideoEncoderCap* createDefaultM4vVideoEncoderCap(); @@ -520,8 +445,6 @@ private:      RequiredProfiles *mRequiredProfileRefs;      Vector<int>              mCameraIds; -    VideoEditorCap* mVideoEditorCap; -    Vector<ExportVideoProfile*> mVideoEditorExportProfiles;  };  }; // namespace android diff --git a/include/media/MediaRecorderBase.h b/include/media/MediaRecorderBase.h index d7ac302..d6cc4bb 100644 --- a/include/media/MediaRecorderBase.h +++ b/include/media/MediaRecorderBase.h @@ -26,10 +26,12 @@ namespace android {  class ICameraRecordingProxy;  class Surface; +class IGraphicBufferConsumer;  class IGraphicBufferProducer;  struct MediaRecorderBase { -    MediaRecorderBase() {} +    MediaRecorderBase(const String16 &opPackageName) +        : mOpPackageName(opPackageName) {}      virtual ~MediaRecorderBase() {}      virtual status_t init() = 0; @@ -43,7 +45,6 @@ struct MediaRecorderBase {      virtual status_t setCamera(const sp<ICamera>& camera,                                 const sp<ICameraRecordingProxy>& proxy) = 0;      virtual status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface) = 0; -    virtual status_t setOutputFile(const char *path) = 0;      virtual status_t setOutputFile(int fd, int64_t offset, int64_t length) = 0;      virtual status_t setOutputFileAuxiliary(int fd) {return INVALID_OPERATION;}      virtual status_t setParameters(const String8& params) = 0; @@ -56,8 +57,13 @@ struct MediaRecorderBase {      virtual status_t reset() = 0;      virtual status_t getMaxAmplitude(int *max) = 0;      virtual status_t dump(int fd, const Vector<String16>& args) const = 0; +    virtual status_t setInputSurface(const sp<IGraphicBufferConsumer>& surface) = 0;      virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() const = 0; + +protected: +    String16 mOpPackageName; +  private:      MediaRecorderBase(const MediaRecorderBase &);      MediaRecorderBase &operator=(const MediaRecorderBase &); diff --git a/include/media/MediaResource.h b/include/media/MediaResource.h new file mode 100644 index 0000000..20f2cad --- /dev/null +++ b/include/media/MediaResource.h @@ -0,0 +1,53 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_MEDIA_RESOURCE_H +#define ANDROID_MEDIA_RESOURCE_H + +#include <binder/Parcel.h> +#include <utils/String8.h> + +namespace android { + +extern const char kResourceSecureCodec[]; +extern const char kResourceNonSecureCodec[]; +extern const char kResourceAudioCodec[]; +extern const char kResourceVideoCodec[]; +extern const char kResourceGraphicMemory[]; + +class MediaResource { +public: +    MediaResource(); +    MediaResource(String8 type, uint64_t value); +    MediaResource(String8 type, String8 subType, uint64_t value); + +    void readFromParcel(const Parcel &parcel); +    void writeToParcel(Parcel *parcel) const; + +    String8 toString() const; + +    bool operator==(const MediaResource &other) const; +    bool operator!=(const MediaResource &other) const; + +    String8 mType; +    String8 mSubType; +    uint64_t mValue; +}; + +}; // namespace android + +#endif  // ANDROID_MEDIA_RESOURCE_H diff --git a/include/media/MediaResourcePolicy.h b/include/media/MediaResourcePolicy.h new file mode 100644 index 0000000..9bc2eec --- /dev/null +++ b/include/media/MediaResourcePolicy.h @@ -0,0 +1,45 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_MEDIA_RESOURCE_POLICY_H +#define ANDROID_MEDIA_RESOURCE_POLICY_H + +#include <binder/Parcel.h> +#include <utils/String8.h> + +namespace android { + +extern const char kPolicySupportsMultipleSecureCodecs[]; +extern const char kPolicySupportsSecureWithNonSecureCodec[]; + +class MediaResourcePolicy { +public: +    MediaResourcePolicy(); +    MediaResourcePolicy(String8 type, String8 value); + +    void readFromParcel(const Parcel &parcel); +    void writeToParcel(Parcel *parcel) const; + +    String8 toString() const; + +    String8 mType; +    String8 mValue; +}; + +}; // namespace android + +#endif  // ANDROID_MEDIA_RESOURCE_POLICY_H diff --git a/include/media/RingBuffer.h b/include/media/RingBuffer.h new file mode 100644 index 0000000..df7c00e --- /dev/null +++ b/include/media/RingBuffer.h @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_SERVICE_UTILS_RING_BUFFER_H +#define ANDROID_SERVICE_UTILS_RING_BUFFER_H + +#include <utils/Log.h> +#include <cutils/compiler.h> + +#include <iterator> +#include <utility> +#include <vector> + +namespace android { + +/** + * A RingBuffer class that maintains an array of objects that can grow up to a certain size. + * Elements added to the RingBuffer are inserted in the logical front of the buffer, and + * invalidate all current iterators for that RingBuffer object. + */ +template <class T> +class RingBuffer final { +public: + +    /** +     * Construct a RingBuffer that can grow up to the given length. +     */ +    RingBuffer(size_t length); + +    /** +     * Forward iterator to this class.  Implements an std:forward_iterator. +     */ +    class iterator : public std::iterator<std::forward_iterator_tag, T> { +    public: +        iterator(T* ptr, size_t size, size_t pos, size_t ctr); + +        iterator& operator++(); + +        iterator operator++(int); + +        bool operator==(const iterator& rhs); + +        bool operator!=(const iterator& rhs); + +        T& operator*(); + +        T* operator->(); + +    private: +        T* mPtr; +        size_t mSize; +        size_t mPos; +        size_t mCtr; +    }; + +    /** +     * Constant forward iterator to this class.  Implements an std:forward_iterator. +     */ +    class const_iterator : public std::iterator<std::forward_iterator_tag, T> { +    public: +        const_iterator(const T* ptr, size_t size, size_t pos, size_t ctr); + +        const_iterator& operator++(); + +        const_iterator operator++(int); + +        bool operator==(const const_iterator& rhs); + +        bool operator!=(const const_iterator& rhs); + +        const T& operator*(); + +        const T* operator->(); + +    private: +        const T* mPtr; +        size_t mSize; +        size_t mPos; +        size_t mCtr; +    }; + +    /** +     * Adds item to the front of this RingBuffer.  If the RingBuffer is at its maximum length, +     * this will result in the last element being replaced (this is done using the element's +     * assignment operator). +     * +     * All current iterators are invalidated. +     */ +    void add(const T& item); + +    /** +     * Moves item to the front of this RingBuffer.  Following a call to this, item should no +     * longer be used.  If the RingBuffer is at its maximum length, this will result in the +     * last element being replaced (this is done using the element's assignment operator). +     * +     * All current iterators are invalidated. +     */ +    void add(T&& item); + +    /** +     * Construct item in-place in the front of this RingBuffer using the given arguments.  If +     * the RingBuffer is at its maximum length, this will result in the last element being +     * replaced (this is done using the element's assignment operator). +     * +     * All current iterators are invalidated. +     */ +    template <class... Args> +    void emplace(Args&&... args); + +    /** +     * Get an iterator to the front of this RingBuffer. +     */ +    iterator begin(); + +    /** +     * Get an iterator to the end of this RingBuffer. +     */ +    iterator end(); + +    /** +     * Get a const_iterator to the front of this RingBuffer. +     */ +    const_iterator begin() const; + +    /** +     * Get a const_iterator to the end of this RingBuffer. +     */ +    const_iterator end() const; + +    /** +     * Return a reference to the element at a given index.  If the index is out of range for +     * this ringbuffer, [0, size), the behavior for this is undefined. +     */ +    T& operator[](size_t index); + +    /** +     * Return a const reference to the element at a given index.  If the index is out of range +     * for this ringbuffer, [0, size), the behavior for this is undefined. +     */ +    const T& operator[](size_t index) const; + +    /** +     * Return the current size of this RingBuffer. +     */ +    size_t size() const; + +    /** +     * Remove all elements from this RingBuffer and set the size to 0. +     */ +    void clear(); + +private: +    size_t mFrontIdx; +    size_t mMaxBufferSize; +    std::vector<T> mBuffer; +}; // class RingBuffer + + +template <class T> +RingBuffer<T>::RingBuffer(size_t length) : mFrontIdx{0}, mMaxBufferSize{length} {} + +template <class T> +RingBuffer<T>::iterator::iterator(T* ptr, size_t size, size_t pos, size_t ctr) : +        mPtr{ptr}, mSize{size}, mPos{pos}, mCtr{ctr} {} + +template <class T> +typename RingBuffer<T>::iterator& RingBuffer<T>::iterator::operator++() { +    ++mCtr; + +    if (CC_UNLIKELY(mCtr == mSize)) { +        mPos = mSize; +        return *this; +    } + +    mPos = ((CC_UNLIKELY(mPos == 0)) ? mSize - 1 : mPos - 1); +    return *this; +} + +template <class T> +typename RingBuffer<T>::iterator RingBuffer<T>::iterator::operator++(int) { +    iterator tmp{mPtr, mSize, mPos, mCtr}; +    ++(*this); +    return tmp; +} + +template <class T> +bool RingBuffer<T>::iterator::operator==(const iterator& rhs) { +    return (mPtr + mPos) == (rhs.mPtr + rhs.mPos); +} + +template <class T> +bool RingBuffer<T>::iterator::operator!=(const iterator& rhs) { +    return (mPtr + mPos) != (rhs.mPtr + rhs.mPos); +} + +template <class T> +T& RingBuffer<T>::iterator::operator*() { +    return *(mPtr + mPos); +} + +template <class T> +T* RingBuffer<T>::iterator::operator->() { +    return mPtr + mPos; +} + +template <class T> +RingBuffer<T>::const_iterator::const_iterator(const T* ptr, size_t size, size_t pos, size_t ctr) : +        mPtr{ptr}, mSize{size}, mPos{pos}, mCtr{ctr} {} + +template <class T> +typename RingBuffer<T>::const_iterator& RingBuffer<T>::const_iterator::operator++() { +    ++mCtr; + +    if (CC_UNLIKELY(mCtr == mSize)) { +        mPos = mSize; +        return *this; +    } + +    mPos = ((CC_UNLIKELY(mPos == 0)) ? mSize - 1 : mPos - 1); +    return *this; +} + +template <class T> +typename RingBuffer<T>::const_iterator RingBuffer<T>::const_iterator::operator++(int) { +    const_iterator tmp{mPtr, mSize, mPos, mCtr}; +    ++(*this); +    return tmp; +} + +template <class T> +bool RingBuffer<T>::const_iterator::operator==(const const_iterator& rhs) { +    return (mPtr + mPos) == (rhs.mPtr + rhs.mPos); +} + +template <class T> +bool RingBuffer<T>::const_iterator::operator!=(const const_iterator& rhs) { +    return (mPtr + mPos) != (rhs.mPtr + rhs.mPos); +} + +template <class T> +const T& RingBuffer<T>::const_iterator::operator*() { +    return *(mPtr + mPos); +} + +template <class T> +const T* RingBuffer<T>::const_iterator::operator->() { +    return mPtr + mPos; +} + +template <class T> +void RingBuffer<T>::add(const T& item) { +    if (mBuffer.size() < mMaxBufferSize) { +        mBuffer.push_back(item); +        mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); +        return; +    } + +    mBuffer[mFrontIdx] = item; +    mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); +} + +template <class T> +void RingBuffer<T>::add(T&& item) { +    if (mBuffer.size() != mMaxBufferSize) { +        mBuffer.push_back(std::forward<T>(item)); +        mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); +        return; +    } + +    // Only works for types with move assignment operator +    mBuffer[mFrontIdx] = std::forward<T>(item); +    mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); +} + +template <class T> +template <class... Args> +void RingBuffer<T>::emplace(Args&&... args) { +    if (mBuffer.size() != mMaxBufferSize) { +        mBuffer.emplace_back(std::forward<Args>(args)...); +        mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); +        return; +    } + +    // Only works for types with move assignment operator +    mBuffer[mFrontIdx] = T(std::forward<Args>(args)...); +    mFrontIdx = ((mFrontIdx + 1) % mMaxBufferSize); +} + +template <class T> +typename RingBuffer<T>::iterator RingBuffer<T>::begin() { +    size_t tmp = (mBuffer.size() == 0) ? 0 : mBuffer.size() - 1; +    return iterator(mBuffer.data(), mBuffer.size(), (mFrontIdx == 0) ? tmp : mFrontIdx - 1, 0); +} + +template <class T> +typename RingBuffer<T>::iterator RingBuffer<T>::end() { +    size_t s = mBuffer.size(); +    return iterator(mBuffer.data(), s, s, s); +} + +template <class T> +typename RingBuffer<T>::const_iterator RingBuffer<T>::begin() const { +    size_t tmp = (mBuffer.size() == 0) ? 0 : mBuffer.size() - 1; +    return const_iterator(mBuffer.data(), mBuffer.size(), +            (mFrontIdx == 0) ? tmp : mFrontIdx - 1, 0); +} + +template <class T> +typename RingBuffer<T>::const_iterator RingBuffer<T>::end() const { +    size_t s = mBuffer.size(); +    return const_iterator(mBuffer.data(), s, s, s); +} + +template <class T> +T& RingBuffer<T>::operator[](size_t index) { +    LOG_ALWAYS_FATAL_IF(index >= mBuffer.size(), "Index %zu out of bounds, size is %zu.", +            index, mBuffer.size()); +    size_t pos = (index >= mFrontIdx) ? +            mBuffer.size() - 1 - (index - mFrontIdx) : mFrontIdx - 1 - index; +    return mBuffer[pos]; +} + +template <class T> +const T& RingBuffer<T>::operator[](size_t index) const { +    LOG_ALWAYS_FATAL_IF(index >= mBuffer.size(), "Index %zu out of bounds, size is %zu.", +            index, mBuffer.size()); +    size_t pos = (index >= mFrontIdx) ? +            mBuffer.size() - 1 - (index - mFrontIdx) : mFrontIdx - 1 - index; +    return mBuffer[pos]; +} + +template <class T> +size_t RingBuffer<T>::size() const { +    return mBuffer.size(); +} + +template <class T> +void RingBuffer<T>::clear() { +    mBuffer.clear(); +    mFrontIdx = 0; +} + +}; // namespace android + +#endif // ANDROID_SERVICE_UTILS_RING_BUFFER_H + + diff --git a/include/media/SingleStateQueue.h b/include/media/SingleStateQueue.h index 04c5fd0..d423962 100644 --- a/include/media/SingleStateQueue.h +++ b/include/media/SingleStateQueue.h @@ -21,6 +21,7 @@  // Non-blocking single-reader / single-writer multi-word atomic load / store  #include <stdint.h> +#include <cutils/atomic.h>  namespace android { @@ -31,6 +32,12 @@ public:      class Mutator;      class Observer; +    enum SSQ_STATUS { +        SSQ_PENDING, /* = 0 */ +        SSQ_READ, +        SSQ_DONE, +    }; +      struct Shared {          // needs to be part of a union so don't define constructor or destructor @@ -41,28 +48,56 @@ private:          void                init() { mAck = 0; mSequence = 0; }          volatile int32_t    mAck; -#if 0 -        int                 mPad[7]; -        // cache line boundary -#endif          volatile int32_t    mSequence;          T                   mValue;      };      class Mutator {      public: -        Mutator(Shared *shared); -        /*virtual*/ ~Mutator() { } +        Mutator(Shared *shared) +            : mSequence(0), mShared(shared) +        { +            // exactly one of Mutator and Observer must initialize, currently it is Observer +            // shared->init(); +        }          // push new value onto state queue, overwriting previous value;          // returns a sequence number which can be used with ack() -        int32_t push(const T& value); - -        // return true if most recent push has been observed -        bool ack(); +        int32_t push(const T& value) +        { +            Shared *shared = mShared; +            int32_t sequence = mSequence; +            sequence++; +            android_atomic_acquire_store(sequence, &shared->mSequence); +            shared->mValue = value; +            sequence++; +            android_atomic_release_store(sequence, &shared->mSequence); +            mSequence = sequence; +            // consider signalling a futex here, if we know that observer is waiting +            return sequence; +        } + +        // returns the status of the last state push.  This may be a stale value. +        // +        // SSQ_PENDING, or 0, means it has not been observed +        // SSQ_READ means it has been read +        // SSQ_DONE means it has been acted upon, after Observer::done() is called +        enum SSQ_STATUS ack() const +        { +            // in the case of SSQ_DONE, prevent any subtle data-races of subsequent reads +            // being performed (out-of-order) before the ack read, should the caller be +            // depending on sequentiality of reads. +            const int32_t ack = android_atomic_acquire_load(&mShared->mAck); +            return ack - mSequence & ~1 ? SSQ_PENDING /* seq differ */ : +                    ack & 1 ? SSQ_DONE : SSQ_READ; +        }          // return true if a push with specified sequence number or later has been observed -        bool ack(int32_t sequence); +        bool ack(int32_t sequence) const +        { +            // this relies on 2's complement rollover to detect an ancient sequence number +            return mShared->mAck - sequence >= 0; +        }      private:          int32_t     mSequence; @@ -71,11 +106,54 @@ private:      class Observer {      public: -        Observer(Shared *shared); -        /*virtual*/ ~Observer() { } +        Observer(Shared *shared) +            : mSequence(0), mSeed(1), mShared(shared) +        { +            // exactly one of Mutator and Observer must initialize, currently it is Observer +            shared->init(); +        }          // return true if value has changed -        bool poll(T& value); +        bool poll(T& value) +        { +            Shared *shared = mShared; +            int32_t before = shared->mSequence; +            if (before == mSequence) { +                return false; +            } +            for (int tries = 0; ; ) { +                const int MAX_TRIES = 5; +                if (before & 1) { +                    if (++tries >= MAX_TRIES) { +                        return false; +                    } +                    before = shared->mSequence; +                } else { +                    android_memory_barrier(); +                    T temp = shared->mValue; +                    int32_t after = android_atomic_release_load(&shared->mSequence); +                    if (after == before) { +                        value = temp; +                        shared->mAck = before; +                        mSequence = before; // mSequence is even after poll success +                        return true; +                    } +                    if (++tries >= MAX_TRIES) { +                        return false; +                    } +                    before = after; +                } +            } +        } + +        // (optional) used to indicate to the Mutator that the state that has been polled +        // has also been acted upon. +        void done() +        { +            const int32_t ack = mShared->mAck + 1; +            // ensure all previous writes have been performed. +            android_atomic_release_store(ack, &mShared->mAck); // mSequence is odd after "done" +        }      private:          int32_t     mSequence; diff --git a/include/media/StringArray.h b/include/media/StringArray.h index ae47085..48d98bf 100644 --- a/include/media/StringArray.h +++ b/include/media/StringArray.h @@ -16,7 +16,7 @@  //  // Sortable array of strings.  STL-ish, but STL-free. -//   +//  #ifndef _LIBS_MEDIA_STRING_ARRAY_H  #define _LIBS_MEDIA_STRING_ARRAY_H diff --git a/include/media/Visualizer.h b/include/media/Visualizer.h index 6167dd6..186e018 100644 --- a/include/media/Visualizer.h +++ b/include/media/Visualizer.h @@ -65,7 +65,8 @@ public:      /* Constructor.       * See AudioEffect constructor for details on parameters.       */ -                        Visualizer(int32_t priority = 0, +                        Visualizer(const String16& opPackageName, +                                   int32_t priority = 0,                                     effect_callback_t cbf = NULL,                                     void* user = NULL,                                     int sessionId = 0); @@ -94,7 +95,8 @@ public:      // install a callback to receive periodic captures. The capture rate is specified in milliHertz      // and the capture format is according to flags  (see callback_flags). -    status_t setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate); +    status_t setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate, +                                bool force = false);      // set the capture size capture size must be a power of two in the range      // [VISUALIZER_CAPTURE_SIZE_MAX. VISUALIZER_CAPTURE_SIZE_MIN] diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h index b35cf32..f655f35 100644 --- a/include/media/mediametadataretriever.h +++ b/include/media/mediametadataretriever.h @@ -25,6 +25,7 @@  namespace android { +class IDataSource;  struct IMediaHTTPService;  class IMediaPlayerService;  class IMediaMetadataRetriever; @@ -57,6 +58,7 @@ enum {      METADATA_KEY_IS_DRM          = 22,      METADATA_KEY_LOCATION        = 23,      METADATA_KEY_VIDEO_ROTATION  = 24, +    METADATA_KEY_CAPTURE_FRAMERATE = 25,      // Add more here...  }; @@ -74,6 +76,7 @@ public:              const KeyedVector<String8, String8> *headers = NULL);      status_t setDataSource(int fd, int64_t offset, int64_t length); +    status_t setDataSource(const sp<IDataSource>& dataSource);      sp<IMemory> getFrameAtTime(int64_t timeUs, int option);      sp<IMemory> extractAlbumArt();      const char* extractMetadata(int keyCode); diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h index 5830933..3fe749c 100644 --- a/include/media/mediaplayer.h +++ b/include/media/mediaplayer.h @@ -20,6 +20,8 @@  #include <arpa/inet.h>  #include <binder/IMemory.h> + +#include <media/AudioResamplerPublic.h>  #include <media/IMediaPlayerClient.h>  #include <media/IMediaPlayer.h>  #include <media/IMediaDeathNotifier.h> @@ -32,8 +34,9 @@ class ANativeWindow;  namespace android { -class Surface; +struct AVSyncSettings;  class IGraphicBufferProducer; +class Surface;  enum media_event_type {      MEDIA_NOP               = 0, // interface test message @@ -50,6 +53,7 @@ enum media_event_type {      MEDIA_ERROR             = 100,      MEDIA_INFO              = 200,      MEDIA_SUBTITLE_DATA     = 201, +    MEDIA_META_DATA         = 202,  };  // Generic error codes for the media player framework.  Errors are fatal, the @@ -183,6 +187,7 @@ enum media_track_type {      MEDIA_TRACK_TYPE_AUDIO = 2,      MEDIA_TRACK_TYPE_TIMEDTEXT = 3,      MEDIA_TRACK_TYPE_SUBTITLE = 4, +    MEDIA_TRACK_TYPE_METADATA = 5,  };  // ---------------------------------------------------------------------------- @@ -211,6 +216,7 @@ public:              status_t        setDataSource(int fd, int64_t offset, int64_t length);              status_t        setDataSource(const sp<IStreamSource> &source); +            status_t        setDataSource(const sp<IDataSource> &source);              status_t        setVideoSurfaceTexture(                                      const sp<IGraphicBufferProducer>& bufferProducer);              status_t        setListener(const sp<MediaPlayerListener>& listener); @@ -220,6 +226,12 @@ public:              status_t        stop();              status_t        pause();              bool            isPlaying(); +            status_t        setPlaybackSettings(const AudioPlaybackRate& rate); +            status_t        getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */); +            status_t        setSyncSettings(const AVSyncSettings& sync, float videoFpsHint); +            status_t        getSyncSettings( +                                    AVSyncSettings* sync /* nonnull */, +                                    float* videoFps /* nonnull */);              status_t        getVideoWidth(int *w);              status_t        getVideoHeight(int *h);              status_t        seekTo(int msec); diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h index b0a62a7..15ff82d 100644 --- a/include/media/mediarecorder.h +++ b/include/media/mediarecorder.h @@ -32,6 +32,7 @@ class IMediaRecorder;  class ICamera;  class ICameraRecordingProxy;  class IGraphicBufferProducer; +struct PersistentSurface;  class Surface;  typedef void (*media_completion_f)(status_t status, void *cookie); @@ -209,7 +210,7 @@ class MediaRecorder : public BnMediaRecorderClient,                        public virtual IMediaDeathNotifier  {  public: -    MediaRecorder(); +    MediaRecorder(const String16& opPackageName);      ~MediaRecorder();      void        died(); @@ -221,7 +222,6 @@ public:      status_t    setOutputFormat(int of);      status_t    setVideoEncoder(int ve);      status_t    setAudioEncoder(int ae); -    status_t    setOutputFile(const char* path);      status_t    setOutputFile(int fd, int64_t offset, int64_t length);      status_t    setVideoSize(int width, int height);      status_t    setVideoFrameRate(int frames_per_second); @@ -237,6 +237,7 @@ public:      status_t    close();      status_t    release();      void        notify(int msg, int ext1, int ext2); +    status_t    setInputSurface(const sp<PersistentSurface>& surface);      sp<IGraphicBufferProducer>     querySurfaceMediaSourceFromMediaServer();  private: diff --git a/include/media/nbaio/NBAIO.h b/include/media/nbaio/NBAIO.h index d422576..d9bbc8d 100644 --- a/include/media/nbaio/NBAIO.h +++ b/include/media/nbaio/NBAIO.h @@ -231,7 +231,8 @@ public:      virtual status_t getTimestamp(AudioTimestamp& timestamp) { return INVALID_OPERATION; }  protected: -    NBAIO_Sink(const 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 @@ -322,7 +323,8 @@ public:      virtual void    onTimestamp(const AudioTimestamp& timestamp) { }  protected: -    NBAIO_Source(const 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/NBLog.h b/include/media/nbaio/NBLog.h index bcbbc04..1297b51 100644 --- a/include/media/nbaio/NBLog.h +++ b/include/media/nbaio/NBLog.h @@ -21,7 +21,7 @@  #include <binder/IMemory.h>  #include <utils/Mutex.h> -#include <media/nbaio/roundup.h> +#include <audio_utils/roundup.h>  namespace android { diff --git a/include/media/stagefright/AACWriter.h b/include/media/stagefright/AACWriter.h index d22707a..aa60a19 100644 --- a/include/media/stagefright/AACWriter.h +++ b/include/media/stagefright/AACWriter.h @@ -24,10 +24,9 @@  namespace android {  struct MediaSource; -struct MetaData; +class MetaData;  struct AACWriter : public MediaWriter { -    AACWriter(const char *filename);      AACWriter(int fd);      status_t initCheck() const; diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index cd2bd27..05f6786 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -20,9 +20,11 @@  #include <stdint.h>  #include <android/native_window.h> +#include <media/hardware/MetadataBufferType.h>  #include <media/IOMX.h>  #include <media/stagefright/foundation/AHierarchicalStateMachine.h>  #include <media/stagefright/CodecBase.h> +#include <media/stagefright/FrameRenderTracker.h>  #include <media/stagefright/SkipCutBuffer.h>  #include <OMX_Audio.h> @@ -44,9 +46,12 @@ struct ACodec : public AHierarchicalStateMachine, public CodecBase {      virtual void initiateAllocateComponent(const sp<AMessage> &msg);      virtual void initiateConfigureComponent(const sp<AMessage> &msg);      virtual void initiateCreateInputSurface(); +    virtual void initiateSetInputSurface(const sp<PersistentSurface> &surface);      virtual void initiateStart();      virtual void initiateShutdown(bool keepComponentAllocated = false); +    virtual status_t setSurface(const sp<Surface> &surface); +      virtual void signalFlush();      virtual void signalResume(); @@ -105,6 +110,10 @@ private:      enum {          kWhatSetup                   = 'setu',          kWhatOMXMessage              = 'omx ', +        // same as kWhatOMXMessage - but only used with +        // handleMessage during OMX message-list handling +        kWhatOMXMessageItem          = 'omxI', +        kWhatOMXMessageList          = 'omxL',          kWhatInputBufferFilled       = 'inpF',          kWhatOutputBufferDrained     = 'outD',          kWhatShutdown                = 'shut', @@ -113,12 +122,14 @@ private:          kWhatDrainDeferredMessages   = 'drai',          kWhatAllocateComponent       = 'allo',          kWhatConfigureComponent      = 'conf', +        kWhatSetSurface              = 'setS',          kWhatCreateInputSurface      = 'cisf', +        kWhatSetInputSurface         = 'sisf',          kWhatSignalEndOfInputStream  = 'eois',          kWhatStart                   = 'star',          kWhatRequestIDRFrame         = 'ridr',          kWhatSetParameters           = 'setP', -        kWhatSubmitOutputMetaDataBufferIfEOS = 'subm', +        kWhatSubmitOutputMetadataBufferIfEOS = 'subm',          kWhatOMXDied                 = 'OMXd',          kWhatReleaseCodecInstance    = 'relC',      }; @@ -134,6 +145,12 @@ private:          kFlagIsGrallocUsageProtected                  = 4,      }; +    enum { +        kVideoGrallocUsage = (GRALLOC_USAGE_HW_TEXTURE +                            | GRALLOC_USAGE_HW_COMPOSER +                            | GRALLOC_USAGE_EXTERNAL_DISP), +    }; +      struct BufferInfo {          enum Status {              OWNED_BY_US, @@ -141,16 +158,39 @@ private:              OWNED_BY_UPSTREAM,              OWNED_BY_DOWNSTREAM,              OWNED_BY_NATIVE_WINDOW, +            UNRECOGNIZED,            // not a tracked buffer          }; +        static inline Status getSafeStatus(BufferInfo *info) { +            return info == NULL ? UNRECOGNIZED : info->mStatus; +        } +          IOMX::buffer_id mBufferID;          Status mStatus;          unsigned mDequeuedAt;          sp<ABuffer> mData;          sp<GraphicBuffer> mGraphicBuffer; +        int mFenceFd; +        FrameRenderTracker::Info *mRenderInfo; + +        // The following field and 4 methods are used for debugging only +        bool mIsReadFence; +        // Store |fenceFd| and set read/write flag. Log error, if there is already a fence stored. +        void setReadFence(int fenceFd, const char *dbg); +        void setWriteFence(int fenceFd, const char *dbg); +        // Log error, if the current fence is not a read/write fence. +        void checkReadFence(const char *dbg); +        void checkWriteFence(const char *dbg);      }; +    static const char *_asString(BufferInfo::Status s); +    void dumpBuffers(OMX_U32 portIndex); + +    // If |fd| is non-negative, waits for fence with |fd| and logs an error if it fails. Returns +    // the error code or OK on success. If |fd| is negative, it returns OK +    status_t waitForFence(int fd, const char *dbg); +  #if TRACK_BUFFER_TIMING      struct BufferStats {          int64_t mEmptyBufferTimeUs; @@ -181,10 +221,12 @@ private:      sp<MemoryDealer> mDealer[2];      sp<ANativeWindow> mNativeWindow; +    int mNativeWindowUsageBits;      sp<AMessage> mInputFormat;      sp<AMessage> mOutputFormat;      sp<AMessage> mBaseOutputFormat; +    FrameRenderTracker mRenderTracker; // render information for buffers rendered by ACodec      Vector<BufferInfo> mBuffers[2];      bool mPortEOS[2];      status_t mInputEOSResult; @@ -192,8 +234,8 @@ private:      List<sp<AMessage> > mDeferredQueue;      bool mSentFormat; +    bool mIsVideo;      bool mIsEncoder; -    bool mUseMetadataOnEncoderOutput;      bool mShutdownInProgress;      bool mExplicitShutdown; @@ -208,12 +250,15 @@ private:      bool mChannelMaskPresent;      int32_t mChannelMask;      unsigned mDequeueCounter; -    bool mStoreMetaDataInOutputBuffers; -    int32_t mMetaDataBuffersToSubmit; +    MetadataBufferType mInputMetadataType; +    MetadataBufferType mOutputMetadataType; +    bool mLegacyAdaptiveExperiment; +    int32_t mMetadataBuffersToSubmit;      size_t mNumUndequeuedBuffers;      int64_t mRepeatFrameDelayUs;      int64_t mMaxPtsGapUs; +    float mMaxFps;      int64_t mTimePerFrameUs;      int64_t mTimePerCaptureUs; @@ -227,17 +272,29 @@ private:      status_t freeBuffersOnPort(OMX_U32 portIndex);      status_t freeBuffer(OMX_U32 portIndex, size_t i); +    status_t handleSetSurface(const sp<Surface> &surface); +    status_t setupNativeWindowSizeFormatAndUsage( +            ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */); +      status_t configureOutputBuffersFromNativeWindow(              OMX_U32 *nBufferCount, OMX_U32 *nBufferSize,              OMX_U32 *nMinUndequeuedBuffers); -    status_t allocateOutputMetaDataBuffers(); -    status_t submitOutputMetaDataBuffer(); -    void signalSubmitOutputMetaDataBufferIfEOS_workaround(); +    status_t allocateOutputMetadataBuffers(); +    status_t submitOutputMetadataBuffer(); +    void signalSubmitOutputMetadataBufferIfEOS_workaround();      status_t allocateOutputBuffersFromNativeWindow();      status_t cancelBufferToNativeWindow(BufferInfo *info);      status_t freeOutputBuffersNotOwnedByComponent();      BufferInfo *dequeueBufferFromNativeWindow(); +    inline bool storingMetadataInDecodedBuffers() { +        return mOutputMetadataType >= 0 && !mIsEncoder; +    } + +    inline bool usingMetadataOnEncoderOutput() { +        return mOutputMetadataType >= 0 && mIsEncoder; +    } +      BufferInfo *findBufferByID(              uint32_t portIndex, IOMX::buffer_id bufferID,              ssize_t *index = NULL); @@ -298,6 +355,9 @@ private:      status_t setupRawAudioFormat(              OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels); +    status_t setPriority(int32_t priority); +    status_t setOperatingRate(float rateFloat, bool isVideo); +      status_t setMinBufferSize(OMX_U32 portIndex, size_t size);      status_t setupMPEG4EncoderParameters(const sp<AMessage> &msg); @@ -315,8 +375,6 @@ private:      status_t initNativeWindow(); -    status_t pushBlankBuffersToNativeWindow(); -      // Returns true iff all buffers on the given port have status      // OWNED_BY_US or OWNED_BY_NATIVE_WINDOW.      bool allYourBuffersAreBelongToUs(OMX_U32 portIndex); @@ -331,6 +389,23 @@ private:      void deferMessage(const sp<AMessage> &msg);      void processDeferredMessages(); +    void onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); +    // called when we have dequeued a buffer |buf| from the native window to track render info. +    // |fenceFd| is the dequeue fence, and |info| points to the buffer info where this buffer is +    // stored. +    void updateRenderInfoForDequeuedBuffer( +            ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info); + +    // Checks to see if any frames have rendered up until |until|, and to notify client +    // (MediaCodec) of rendered frames up-until the frame pointed to by |until| or the first +    // unrendered frame. These frames are removed from the render queue. +    // If |dropIncomplete| is true, unrendered frames up-until |until| will be dropped from the +    // queue, allowing all rendered framed up till then to be notified of. +    // (This will effectively clear the render queue up-until (and including) |until|.) +    // If |until| is NULL, or is not in the rendered queue, this method will check all frames. +    void notifyOfRenderedFrames( +            bool dropIncomplete = false, FrameRenderTracker::Info *until = NULL); +      void sendFormatChange(const sp<AMessage> &reply);      status_t getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify); diff --git a/include/media/stagefright/AMRWriter.h b/include/media/stagefright/AMRWriter.h index 392f968..b38be55 100644 --- a/include/media/stagefright/AMRWriter.h +++ b/include/media/stagefright/AMRWriter.h @@ -26,10 +26,9 @@  namespace android {  struct MediaSource; -struct MetaData; +class MetaData;  struct AMRWriter : public MediaWriter { -    AMRWriter(const char *filename);      AMRWriter(int fd);      status_t initCheck() const; diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h index 14afb85..e0cd965 100644 --- a/include/media/stagefright/AudioPlayer.h +++ b/include/media/stagefright/AudioPlayer.h @@ -25,9 +25,10 @@  namespace android { -class MediaSource; +struct AudioPlaybackRate;  class AudioTrack; -class AwesomePlayer; +struct AwesomePlayer; +class MediaSource;  class AudioPlayer : public TimeSource {  public: @@ -73,7 +74,8 @@ public:      bool isSeeking();      bool reachedEOS(status_t *finalStatus); -    status_t setPlaybackRatePermille(int32_t ratePermille); +    status_t setPlaybackRate(const AudioPlaybackRate &rate); +    status_t getPlaybackRate(AudioPlaybackRate *rate /* nonnull */);      void notifyAudioEOS(); diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h index 4c9aaad..3074910 100644 --- a/include/media/stagefright/AudioSource.h +++ b/include/media/stagefright/AudioSource.h @@ -35,8 +35,10 @@ struct AudioSource : public MediaSource, public MediaBufferObserver {      // _not_ a bitmask of audio_channels_t constants.      AudioSource(              audio_source_t inputSource, +            const String16 &opPackageName,              uint32_t sampleRate, -            uint32_t channels = 1); +            uint32_t channels, +            uint32_t outSampleRate = 0);      status_t initCheck() const; @@ -77,11 +79,13 @@ private:      status_t mInitCheck;      bool mStarted;      int32_t mSampleRate; +    int32_t mOutSampleRate;      bool mTrackMaxAmplitude;      int64_t mStartTimeUs;      int16_t mMaxAmplitude;      int64_t mPrevSampleTimeUs; +    int64_t mFirstSampleTimeUs;      int64_t mInitialReadTimeUs;      int64_t mNumFramesReceived;      int64_t mNumClientOwnedBuffers; diff --git a/include/media/stagefright/BufferProducerWrapper.h b/include/media/stagefright/BufferProducerWrapper.h index d8acf30..4caa2c6 100644 --- a/include/media/stagefright/BufferProducerWrapper.h +++ b/include/media/stagefright/BufferProducerWrapper.h @@ -19,6 +19,7 @@  #define BUFFER_PRODUCER_WRAPPER_H_  #include <gui/IGraphicBufferProducer.h> +#include <media/stagefright/foundation/ABase.h>  namespace android { diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h index dd0a106..069e897 100644 --- a/include/media/stagefright/CameraSource.h +++ b/include/media/stagefright/CameraSource.h @@ -83,7 +83,7 @@ public:                                            Size videoSize,                                            int32_t frameRate,                                            const sp<IGraphicBufferProducer>& surface, -                                          bool storeMetaDataInVideoBuffers = false); +                                          bool storeMetaDataInVideoBuffers = true);      virtual ~CameraSource(); @@ -149,6 +149,8 @@ protected:      int32_t  mNumInputBuffers;      int32_t  mVideoFrameRate;      int32_t  mColorFormat; +    int32_t  mEncoderFormat; +    int32_t  mEncoderDataSpace;      status_t mInitCheck;      sp<Camera>   mCamera; @@ -188,7 +190,7 @@ protected:      void releaseCamera();  private: -    friend class CameraSourceListener; +    friend struct CameraSourceListener;      Mutex mLock;      Condition mFrameAvailableCondition; diff --git a/include/media/stagefright/CodecBase.h b/include/media/stagefright/CodecBase.h index 1bf27a6..bb36052 100644 --- a/include/media/stagefright/CodecBase.h +++ b/include/media/stagefright/CodecBase.h @@ -26,6 +26,7 @@  namespace android {  struct ABuffer; +struct PersistentSurface;  struct CodecBase : public AHandler {      enum { @@ -39,8 +40,10 @@ struct CodecBase : public AHandler {          kWhatComponentAllocated  = 'cAll',          kWhatComponentConfigured = 'cCon',          kWhatInputSurfaceCreated = 'isfc', +        kWhatInputSurfaceAccepted = 'isfa',          kWhatSignaledInputEOS    = 'seos',          kWhatBuffersAllocated    = 'allc', +        kWhatOutputFramesRendered = 'outR',      };      virtual void setNotificationMessage(const sp<AMessage> &msg) = 0; @@ -48,12 +51,16 @@ struct CodecBase : public AHandler {      virtual void initiateAllocateComponent(const sp<AMessage> &msg) = 0;      virtual void initiateConfigureComponent(const sp<AMessage> &msg) = 0;      virtual void initiateCreateInputSurface() = 0; +    virtual void initiateSetInputSurface( +            const sp<PersistentSurface> &surface) = 0;      virtual void initiateStart() = 0;      virtual void initiateShutdown(bool keepComponentAllocated = false) = 0;      // require an explicit message handler      virtual void onMessageReceived(const sp<AMessage> &msg) = 0; +    virtual status_t setSurface(const sp<Surface> &surface) { return INVALID_OPERATION; } +      virtual void signalFlush() = 0;      virtual void signalResume() = 0; diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h index 3630263..dcde36f 100644 --- a/include/media/stagefright/DataSource.h +++ b/include/media/stagefright/DataSource.h @@ -32,6 +32,7 @@ namespace android {  struct AMessage;  struct AString; +class  IDataSource;  struct IMediaHTTPService;  class String8;  struct HTTPBase; @@ -53,11 +54,15 @@ public:              HTTPBase *httpSource = NULL);      static sp<DataSource> CreateMediaHTTP(const sp<IMediaHTTPService> &httpService); +    static sp<DataSource> CreateFromIDataSource(const sp<IDataSource> &source);      DataSource() {}      virtual status_t initCheck() const = 0; +    // Returns the number of bytes read, or -1 on failure. It's not an error if +    // this returns zero; it just means the given offset is equal to, or +    // beyond, the end of the source.      virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;      // Convenience methods: diff --git a/include/media/stagefright/FrameRenderTracker.h b/include/media/stagefright/FrameRenderTracker.h new file mode 100644 index 0000000..9333e8f --- /dev/null +++ b/include/media/stagefright/FrameRenderTracker.h @@ -0,0 +1,143 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FRAME_RENDER_TRACKER_H_ + +#define FRAME_RENDER_TRACKER_H_ + +#include <utils/RefBase.h> +#include <utils/Timers.h> +#include <system/window.h> + +#include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/foundation/AString.h> + +#include <list> + +namespace android { + +class Fence; +class GraphicBuffer; + +struct FrameRenderTracker : public RefBase { +    // Tracks the render information about a frame. Frames go through several states while +    // the render information is tracked: +    // +    // 1. queued frame: mMediaTime and mGraphicBuffer are set for the frame. mFence is the +    // queue fence (read fence). mIndex is negative, and mRenderTimeNs is invalid. +    // Key characteristics: mFence is not NULL and mIndex is negative. +    // +    // 2. dequeued frame: mFence is updated with the dequeue fence (write fence). mIndex is set. +    // Key characteristics: mFence is not NULL and mIndex is non-negative. mRenderTime is still +    // invalid. +    // +    // 3. rendered frame or frame: mFence is cleared, mRenderTimeNs is set. +    // Key characteristics: mFence is NULL. +    // +    struct Info { +        // set by client during onFrameQueued or onFrameRendered +        int64_t getMediaTimeUs() const  { return mMediaTimeUs; } + +        // -1 if frame is not yet rendered +        nsecs_t getRenderTimeNs() const { return mRenderTimeNs; } + +        // set by client during updateRenderInfoForDequeuedBuffer; -1 otherwise +        ssize_t getIndex() const        { return mIndex; } + +        // creates information for a queued frame +        Info(int64_t mediaTimeUs, const sp<GraphicBuffer> &graphicBuffer, const sp<Fence> &fence) +            : mMediaTimeUs(mediaTimeUs), +              mRenderTimeNs(-1), +              mIndex(-1), +              mGraphicBuffer(graphicBuffer), +              mFence(fence) { +        } + +        // creates information for a frame rendered on a tunneled surface +        Info(int64_t mediaTimeUs, nsecs_t renderTimeNs) +            : mMediaTimeUs(mediaTimeUs), +              mRenderTimeNs(renderTimeNs), +              mIndex(-1), +              mGraphicBuffer(NULL), +              mFence(NULL) { +        } + +    private: +        int64_t mMediaTimeUs; +        nsecs_t mRenderTimeNs; +        ssize_t mIndex;         // to be used by client +        sp<GraphicBuffer> mGraphicBuffer; +        sp<Fence> mFence; + +        friend class FrameRenderTracker; +    }; + +    FrameRenderTracker(); + +    void setComponentName(const AString &componentName); + +    // clears all tracked frames, and resets last render time +    void clear(nsecs_t lastRenderTimeNs); + +    // called when |graphicBuffer| corresponding to |mediaTimeUs| is +    // queued to the output surface using |fence|. +    void onFrameQueued( +            int64_t mediaTimeUs, const sp<GraphicBuffer> &graphicBuffer, const sp<Fence> &fence); + +    // Called when we have dequeued a buffer |buf| from the native window to track render info. +    // |fenceFd| is the dequeue fence, and |index| is a positive buffer ID to be usable by the +    // client to track this render info among the dequeued buffers. +    // Returns pointer to the tracked info, or NULL if buffer is not tracked or if |index| +    // is negative. +    Info *updateInfoForDequeuedBuffer(ANativeWindowBuffer *buf, int fenceFd, int index); + +    // called when tunneled codec signals frame rendered event +    // returns BAD_VALUE if systemNano is not monotonic. Otherwise, returns OK. +    status_t onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); + +    // Checks to see if any frames have rendered up until |until|. If |until| is NULL or not a +    // tracked info, this method searches the entire render queue. +    // Returns list of rendered frames up-until the frame pointed to by |until| or the first +    // unrendered frame, as well as any dropped frames (those with invalid fence) up-until |until|. +    // These frames are removed from the render queue. +    // If |dropIncomplete| is true, unrendered frames up-until |until| will also be dropped from the +    // queue, allowing all rendered framed up till then to be notified of. +    // (This will effectively clear the render queue up-until (and including) |until|.) +    std::list<Info> checkFencesAndGetRenderedFrames(const Info *until, bool dropIncomplete); + +    // Stop tracking a queued frame (e.g. if the frame has been discarded). If |info| is NULL or is +    // not tracked, this method is a no-op. If |index| is specified, all indices larger that |index| +    // are decremented. This is useful if the untracked frame is deleted from the frame vector. +    void untrackFrame(const Info *info, ssize_t index = SSIZE_MAX); + +    void dumpRenderQueue() const; + +    virtual ~FrameRenderTracker(); + +private: + +    // Render information for buffers. Regular surface buffers are queued in the order of +    // rendering. Tunneled buffers are queued in the order of receipt. +    std::list<Info> mRenderQueue; +    nsecs_t mLastRenderTimeNs; +    AString mComponentName; + +    DISALLOW_EVIL_CONSTRUCTORS(FrameRenderTracker); +}; + +}  // namespace android + +#endif  // FRAME_RENDER_TRACKER_H_ diff --git a/include/media/stagefright/MPEG2TSWriter.h b/include/media/stagefright/MPEG2TSWriter.h index 2e2922e..3d7960b 100644 --- a/include/media/stagefright/MPEG2TSWriter.h +++ b/include/media/stagefright/MPEG2TSWriter.h @@ -29,7 +29,6 @@ struct ABuffer;  struct MPEG2TSWriter : public MediaWriter {      MPEG2TSWriter(int fd); -    MPEG2TSWriter(const char *filename);      MPEG2TSWriter(              void *cookie, diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h index 26ce5f9..a195fe8 100644 --- a/include/media/stagefright/MPEG4Writer.h +++ b/include/media/stagefright/MPEG4Writer.h @@ -26,13 +26,13 @@  namespace android { +class AMessage;  class MediaBuffer;  class MediaSource;  class MetaData;  class MPEG4Writer : public MediaWriter {  public: -    MPEG4Writer(const char *filename);      MPEG4Writer(int fd);      // Limitations @@ -49,6 +49,7 @@ public:      virtual status_t dump(int fd, const Vector<String16>& args);      void beginBox(const char *fourcc); +    void beginBox(uint32_t id);      void writeInt8(int8_t x);      void writeInt16(int16_t x);      void writeInt32(int32_t x); @@ -63,6 +64,7 @@ public:      int32_t getTimeScale() const { return mTimeScale; }      status_t setGeoData(int latitudex10000, int longitudex10000); +    status_t setCaptureRate(float captureFps);      virtual void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }      virtual int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; } @@ -89,6 +91,7 @@ private:      off64_t mFreeBoxOffset;      bool mStreamableFile;      off64_t mEstimatedMoovBoxSize; +    off64_t mMoovExtraSize;      uint32_t mInterleaveDurationUs;      int32_t mTimeScale;      int64_t mStartTimestampUs; @@ -103,6 +106,8 @@ private:      List<off64_t> mBoxes; +    sp<AMessage> mMetaKeys; +      void setStartTimestampUs(int64_t timeUs);      int64_t getStartTimestampUs();  // Not const      status_t startTracks(MetaData *params); @@ -196,6 +201,12 @@ private:      void writeGeoDataBox();      void writeLatitude(int degreex10000);      void writeLongitude(int degreex10000); + +    void addDeviceMeta(); +    void writeHdlr(); +    void writeKeys(); +    void writeIlst(); +    void writeMetaBox();      void sendSessionSummary();      void release();      status_t reset(); diff --git a/include/media/stagefright/MediaClock.h b/include/media/stagefright/MediaClock.h new file mode 100644 index 0000000..dd1a809 --- /dev/null +++ b/include/media/stagefright/MediaClock.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_CLOCK_H_ + +#define MEDIA_CLOCK_H_ + +#include <media/stagefright/foundation/ABase.h> +#include <utils/Mutex.h> +#include <utils/RefBase.h> + +namespace android { + +struct AMessage; + +struct MediaClock : public RefBase { +    MediaClock(); + +    void setStartingTimeMedia(int64_t startingTimeMediaUs); + +    void clearAnchor(); +    // It's required to use timestamp of just rendered frame as +    // anchor time in paused state. +    void updateAnchor( +            int64_t anchorTimeMediaUs, +            int64_t anchorTimeRealUs, +            int64_t maxTimeMediaUs = INT64_MAX); + +    void updateMaxTimeMedia(int64_t maxTimeMediaUs); + +    void setPlaybackRate(float rate); +    float getPlaybackRate() const; + +    // query media time corresponding to real time |realUs|, and save the +    // result in |outMediaUs|. +    status_t getMediaTime( +            int64_t realUs, +            int64_t *outMediaUs, +            bool allowPastMaxTime = false) const; +    // query real time corresponding to media time |targetMediaUs|. +    // The result is saved in |outRealUs|. +    status_t getRealTimeFor(int64_t targetMediaUs, int64_t *outRealUs) const; + +protected: +    virtual ~MediaClock(); + +private: +    status_t getMediaTime_l( +            int64_t realUs, +            int64_t *outMediaUs, +            bool allowPastMaxTime) const; + +    mutable Mutex mLock; + +    int64_t mAnchorTimeMediaUs; +    int64_t mAnchorTimeRealUs; +    int64_t mMaxTimeMediaUs; +    int64_t mStartingTimeMediaUs; + +    float mPlaybackRate; + +    DISALLOW_EVIL_CONSTRUCTORS(MediaClock); +}; + +}  // namespace android + +#endif  // MEDIA_CLOCK_H_ diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h index d448097..c10963d 100644 --- a/include/media/stagefright/MediaCodec.h +++ b/include/media/stagefright/MediaCodec.h @@ -20,17 +20,25 @@  #include <gui/IGraphicBufferProducer.h>  #include <media/hardware/CryptoAPI.h> +#include <media/MediaResource.h>  #include <media/stagefright/foundation/AHandler.h> +#include <media/stagefright/FrameRenderTracker.h>  #include <utils/Vector.h>  namespace android {  struct ABuffer;  struct AMessage; +struct AReplyToken;  struct AString;  struct CodecBase; -struct ICrypto;  struct IBatteryStats; +struct ICrypto; +class IMemory; +struct MemoryDealer; +class IResourceManagerClient; +class IResourceManagerService; +struct PersistentSurface;  struct SoftwareRenderer;  struct Surface; @@ -50,15 +58,20 @@ struct MediaCodec : public AHandler {          CB_OUTPUT_AVAILABLE = 2,          CB_ERROR = 3,          CB_OUTPUT_FORMAT_CHANGED = 4, +        CB_RESOURCE_RECLAIMED = 5,      }; -    struct BatteryNotifier; +    static const pid_t kNoPid = -1;      static sp<MediaCodec> CreateByType( -            const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err = NULL); +            const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err = NULL, +            pid_t pid = kNoPid);      static sp<MediaCodec> CreateByComponentName( -            const sp<ALooper> &looper, const char *name, status_t *err = NULL); +            const sp<ALooper> &looper, const char *name, status_t *err = NULL, +            pid_t pid = kNoPid); + +    static sp<PersistentSurface> CreatePersistentInputSurface();      status_t configure(              const sp<AMessage> &format, @@ -68,8 +81,12 @@ struct MediaCodec : public AHandler {      status_t setCallback(const sp<AMessage> &callback); +    status_t setOnFrameRenderedNotification(const sp<AMessage> ¬ify); +      status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer); +    status_t setInputSurface(const sp<PersistentSurface> &surface); +      status_t start();      // Returns to a state in which the component remains allocated but @@ -125,6 +142,8 @@ struct MediaCodec : public AHandler {      status_t getOutputFormat(sp<AMessage> *format) const;      status_t getInputFormat(sp<AMessage> *format) const; +    status_t getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const; +      status_t getInputBuffers(Vector<sp<ABuffer> > *buffers) const;      status_t getOutputBuffers(Vector<sp<ABuffer> > *buffers) const; @@ -132,6 +151,8 @@ struct MediaCodec : public AHandler {      status_t getOutputFormat(size_t index, sp<AMessage> *format);      status_t getInputBuffer(size_t index, sp<ABuffer> *buffer); +    status_t setSurface(const sp<Surface> &nativeWindow); +      status_t requestIDRFrame();      // Notification will be posted once there "is something to do", i.e. @@ -143,11 +164,22 @@ struct MediaCodec : public AHandler {      status_t setParameters(const sp<AMessage> ¶ms); +    // Create a MediaCodec notification message from a list of rendered or dropped render infos +    // by adding rendered frame information to a base notification message. Returns the number +    // of frames that were rendered. +    static size_t CreateFramesRenderedMessage( +            std::list<FrameRenderTracker::Info> done, sp<AMessage> &msg); +  protected:      virtual ~MediaCodec();      virtual void onMessageReceived(const sp<AMessage> &msg);  private: +    // used by ResourceManagerClient +    status_t reclaim(); +    friend struct ResourceManagerClient; + +private:      enum State {          UNINITIALIZED,          INITIALIZING, @@ -170,7 +202,9 @@ private:      enum {          kWhatInit                           = 'init',          kWhatConfigure                      = 'conf', +        kWhatSetSurface                     = 'sSur',          kWhatCreateInputSurface             = 'cisf', +        kWhatSetInputSurface                = 'sisf',          kWhatStart                          = 'strt',          kWhatStop                           = 'stop',          kWhatRelease                        = 'rele', @@ -191,6 +225,7 @@ private:          kWhatGetName                        = 'getN',          kWhatSetParameters                  = 'setP',          kWhatSetCallback                    = 'setC', +        kWhatSetNotification                = 'setN',      };      enum { @@ -206,39 +241,78 @@ private:          kFlagGatherCodecSpecificData    = 512,          kFlagIsAsync                    = 1024,          kFlagIsComponentAllocated       = 2048, +        kFlagPushBlankBuffersOnShutdown = 4096,      };      struct BufferInfo {          uint32_t mBufferID;          sp<ABuffer> mData;          sp<ABuffer> mEncryptedData; +        sp<IMemory> mSharedEncryptedBuffer;          sp<AMessage> mNotify;          sp<AMessage> mFormat;          bool mOwnedByClient;      }; +    struct ResourceManagerServiceProxy : public IBinder::DeathRecipient { +        ResourceManagerServiceProxy(pid_t pid); +        ~ResourceManagerServiceProxy(); + +        void init(); + +        // implements DeathRecipient +        virtual void binderDied(const wp<IBinder>& /*who*/); + +        void addResource( +                int64_t clientId, +                const sp<IResourceManagerClient> client, +                const Vector<MediaResource> &resources); + +        void removeResource(int64_t clientId); + +        bool reclaimResource(const Vector<MediaResource> &resources); + +    private: +        Mutex mLock; +        sp<IResourceManagerService> mService; +        pid_t mPid; +    }; +      State mState; +    bool mReleasedByResourceManager;      sp<ALooper> mLooper;      sp<ALooper> mCodecLooper;      sp<CodecBase> mCodec;      AString mComponentName; -    uint32_t mReplyID; +    sp<AReplyToken> mReplyID;      uint32_t mFlags;      status_t mStickyError; -    sp<Surface> mNativeWindow; +    sp<Surface> mSurface;      SoftwareRenderer *mSoftRenderer; +      sp<AMessage> mOutputFormat;      sp<AMessage> mInputFormat;      sp<AMessage> mCallback; +    sp<AMessage> mOnFrameRenderedNotification; +    sp<MemoryDealer> mDealer; + +    sp<IResourceManagerClient> mResourceManagerClient; +    sp<ResourceManagerServiceProxy> mResourceManagerService;      bool mBatteryStatNotified;      bool mIsVideo; +    int32_t mVideoWidth; +    int32_t mVideoHeight; +    int32_t mRotationDegrees;      // initial create parameters      AString mInitName;      bool mInitNameIsType;      bool mInitIsEncoder; +    // configure parameter +    sp<AMessage> mConfigureMsg; +      // Used only to synchronize asynchronous getBufferAndFormat      // across all the other (synchronous) buffer state change      // operations, such as de/queueIn/OutputBuffer, start and @@ -249,10 +323,10 @@ private:      Vector<BufferInfo> mPortBuffers[2];      int32_t mDequeueInputTimeoutGeneration; -    uint32_t mDequeueInputReplyID; +    sp<AReplyToken> mDequeueInputReplyID;      int32_t mDequeueOutputTimeoutGeneration; -    uint32_t mDequeueOutputReplyID; +    sp<AReplyToken> mDequeueOutputReplyID;      sp<ICrypto> mCrypto; @@ -261,13 +335,14 @@ private:      sp<AMessage> mActivityNotify;      bool mHaveInputSurface; +    bool mHavePendingInputBuffers; -    MediaCodec(const sp<ALooper> &looper); +    MediaCodec(const sp<ALooper> &looper, pid_t pid);      static status_t PostAndAwaitResponse(              const sp<AMessage> &msg, sp<AMessage> *response); -    static void PostReplyWithError(int32_t replyID, int32_t err); +    void PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err);      status_t init(const AString &name, bool nameIsType, bool encoder); @@ -283,15 +358,16 @@ private:              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); +    bool handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false); +    bool handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest = false);      void cancelPendingDequeueOperations();      void extractCSD(const sp<AMessage> &format);      status_t queueCSDInputBuffer(size_t bufferIndex); -    status_t setNativeWindow( -            const sp<Surface> &surface); +    status_t handleSetSurface(const sp<Surface> &surface); +    status_t connectToSurface(const sp<Surface> &surface); +    status_t disconnectFromSurface();      void postActivityNotificationIfPossible(); @@ -306,6 +382,9 @@ private:      void updateBatteryStat();      bool isExecuting() const; +    uint64_t getGraphicBufferSize(); +    void addResource(const String8 &type, const String8 &subtype, uint64_t value); +      /* called to get the last codec error when the sticky flag is set.       * if no such codec error is found, returns UNKNOWN_ERROR.       */ diff --git a/include/media/stagefright/MediaCodecList.h b/include/media/stagefright/MediaCodecList.h index c2bbe4d..3aaa032 100644 --- a/include/media/stagefright/MediaCodecList.h +++ b/include/media/stagefright/MediaCodecList.h @@ -32,6 +32,8 @@  namespace android { +extern const char *kMaxEncoderInputBuffers; +  struct AMessage;  struct MediaCodecList : public BnMediaCodecList { @@ -48,9 +50,17 @@ struct MediaCodecList : public BnMediaCodecList {          return mCodecInfos.itemAt(index);      } +    virtual const sp<AMessage> getGlobalSettings() const; +      // to be used by MediaPlayerService alone      static sp<IMediaCodecList> getLocalInstance(); +    // only to be used by getLocalInstance +    static void *profilerThreadWrapper(void * /*arg*/); + +    // only to be used by MediaPlayerService +    void parseTopLevelXMLFile(const char *path, bool ignore_errors = false); +  private:      class BinderDeathObserver : public IBinder::DeathRecipient {          void binderDied(const wp<IBinder> &the_late_who __unused); @@ -60,6 +70,7 @@ private:      enum Section {          SECTION_TOPLEVEL, +        SECTION_SETTINGS,          SECTION_DECODERS,          SECTION_DECODER,          SECTION_DECODER_TYPE, @@ -74,10 +85,14 @@ private:      status_t mInitCheck;      Section mCurrentSection; +    bool mUpdate;      Vector<Section> mPastSections;      int32_t mDepth;      AString mHrefBase; +    sp<AMessage> mGlobalSettings; +    KeyedVector<AString, CodecSettings> mOverrides; +      Vector<sp<MediaCodecInfo> > mCodecInfos;      sp<MediaCodecInfo> mCurrentInfo;      sp<IOMX> mOMX; @@ -87,7 +102,6 @@ private:      status_t initCheck() const;      void parseXMLFile(const char *path); -    void parseTopLevelXMLFile(const char *path);      static void StartElementHandlerWrapper(              void *me, const char *name, const char **attrs); @@ -98,9 +112,12 @@ private:      void endElementHandler(const char *name);      status_t includeXMLFile(const char **attrs); +    status_t addSettingFromAttributes(const char **attrs);      status_t addMediaCodecFromAttributes(bool encoder, const char **attrs);      void addMediaCodec(bool encoder, const char *name, const char *type = NULL); +    void setCurrentCodecInfo(bool encoder, const char *name, const char *type); +      status_t addQuirk(const char **attrs);      status_t addTypeFromAttributes(const char **attrs);      status_t addLimit(const char **attrs); diff --git a/include/media/stagefright/MediaCodecSource.h b/include/media/stagefright/MediaCodecSource.h index 0970b2b..71f58a9 100644 --- a/include/media/stagefright/MediaCodecSource.h +++ b/include/media/stagefright/MediaCodecSource.h @@ -23,9 +23,11 @@  namespace android { -class ALooper; +struct ALooper;  class AMessage; +struct AReplyToken;  class IGraphicBufferProducer; +class IGraphicBufferConsumer;  class MediaCodec;  class MetaData; @@ -40,6 +42,7 @@ struct MediaCodecSource : public MediaSource,              const sp<ALooper> &looper,              const sp<AMessage> &format,              const sp<MediaSource> &source, +            const sp<IGraphicBufferConsumer> &consumer = NULL,              uint32_t flags = 0);      bool isVideo() const { return mIsVideo; } @@ -78,6 +81,7 @@ private:              const sp<ALooper> &looper,              const sp<AMessage> &outputFormat,              const sp<MediaSource> &source, +            const sp<IGraphicBufferConsumer> &consumer,              uint32_t flags = 0);      status_t onStart(MetaData *params); @@ -99,13 +103,17 @@ private:      sp<Puller> mPuller;      sp<MediaCodec> mEncoder;      uint32_t mFlags; -    List<uint32_t> mStopReplyIDQueue; +    List<sp<AReplyToken>> mStopReplyIDQueue;      bool mIsVideo;      bool mStarted;      bool mStopping;      bool mDoMoreWorkPending; +    bool mSetEncoderFormat; +    int mEncoderFormat; +    int mEncoderDataSpace;      sp<AMessage> mEncoderActivityNotify;      sp<IGraphicBufferProducer> mGraphicBufferProducer; +    sp<IGraphicBufferConsumer> mGraphicBufferConsumer;      List<MediaBuffer *> mInputBufferQueue;      List<size_t> mAvailEncoderInputIndices;      List<int64_t> mDecodingTimeQueue; // decoding time (us) for video diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h index a0036e0..21eb04a 100644 --- a/include/media/stagefright/MediaDefs.h +++ b/include/media/stagefright/MediaDefs.h @@ -64,6 +64,7 @@ extern const char *MEDIA_MIMETYPE_TEXT_3GPP;  extern const char *MEDIA_MIMETYPE_TEXT_SUBRIP;  extern const char *MEDIA_MIMETYPE_TEXT_VTT;  extern const char *MEDIA_MIMETYPE_TEXT_CEA_608; +extern const char *MEDIA_MIMETYPE_DATA_TIMED_ID3;  }  // namespace android diff --git a/include/media/stagefright/MediaFilter.h b/include/media/stagefright/MediaFilter.h new file mode 100644 index 0000000..d0a572c --- /dev/null +++ b/include/media/stagefright/MediaFilter.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_FILTER_H_ +#define MEDIA_FILTER_H_ + +#include <media/stagefright/CodecBase.h> + +namespace android { + +struct ABuffer; +struct GraphicBufferListener; +struct MemoryDealer; +struct SimpleFilter; + +struct MediaFilter : public CodecBase { +    MediaFilter(); + +    virtual void setNotificationMessage(const sp<AMessage> &msg); + +    virtual void initiateAllocateComponent(const sp<AMessage> &msg); +    virtual void initiateConfigureComponent(const sp<AMessage> &msg); +    virtual void initiateCreateInputSurface(); +    virtual void initiateSetInputSurface(const sp<PersistentSurface> &surface); + +    virtual void initiateStart(); +    virtual void initiateShutdown(bool keepComponentAllocated = false); + +    virtual void signalFlush(); +    virtual void signalResume(); + +    virtual void signalRequestIDRFrame(); +    virtual void signalSetParameters(const sp<AMessage> &msg); +    virtual void signalEndOfInputStream(); + +    virtual void onMessageReceived(const sp<AMessage> &msg); + +    struct PortDescription : public CodecBase::PortDescription { +        virtual size_t countBuffers(); +        virtual IOMX::buffer_id bufferIDAt(size_t index) const; +        virtual sp<ABuffer> bufferAt(size_t index) const; + +    protected: +        PortDescription(); + +    private: +        friend struct MediaFilter; + +        Vector<IOMX::buffer_id> mBufferIDs; +        Vector<sp<ABuffer> > mBuffers; + +        void addBuffer(IOMX::buffer_id id, const sp<ABuffer> &buffer); + +        DISALLOW_EVIL_CONSTRUCTORS(PortDescription); +    }; + +protected: +    virtual ~MediaFilter(); + +private: +    struct BufferInfo { +        enum Status { +            OWNED_BY_US, +            OWNED_BY_UPSTREAM, +        }; + +        IOMX::buffer_id mBufferID; +        int32_t mGeneration; +        int32_t mOutputFlags; +        Status mStatus; + +        sp<ABuffer> mData; +    }; + +    enum State { +      UNINITIALIZED, +      INITIALIZED, +      CONFIGURED, +      STARTED, +    }; + +    enum { +        kWhatInputBufferFilled       = 'inpF', +        kWhatOutputBufferDrained     = 'outD', +        kWhatShutdown                = 'shut', +        kWhatFlush                   = 'flus', +        kWhatResume                  = 'resm', +        kWhatAllocateComponent       = 'allo', +        kWhatConfigureComponent      = 'conf', +        kWhatCreateInputSurface      = 'cisf', +        kWhatSignalEndOfInputStream  = 'eois', +        kWhatStart                   = 'star', +        kWhatSetParameters           = 'setP', +        kWhatProcessBuffers          = 'proc', +    }; + +    enum { +        kPortIndexInput  = 0, +        kPortIndexOutput = 1 +    }; + +    // member variables +    AString mComponentName; +    State mState; +    status_t mInputEOSResult; +    int32_t mWidth, mHeight; +    int32_t mStride, mSliceHeight; +    int32_t mColorFormatIn, mColorFormatOut; +    size_t mMaxInputSize, mMaxOutputSize; +    int32_t mGeneration; +    sp<AMessage> mNotify; +    sp<AMessage> mInputFormat; +    sp<AMessage> mOutputFormat; + +    sp<MemoryDealer> mDealer[2]; +    Vector<BufferInfo> mBuffers[2]; +    Vector<BufferInfo*> mAvailableInputBuffers; +    Vector<BufferInfo*> mAvailableOutputBuffers; +    bool mPortEOS[2]; + +    sp<SimpleFilter> mFilter; +    sp<GraphicBufferListener> mGraphicBufferListener; + +    // helper functions +    void signalProcessBuffers(); +    void signalError(status_t error); + +    status_t allocateBuffersOnPort(OMX_U32 portIndex); +    BufferInfo *findBufferByID( +            uint32_t portIndex, IOMX::buffer_id bufferID, +            ssize_t *index = NULL); +    void postFillThisBuffer(BufferInfo *info); +    void postDrainThisBuffer(BufferInfo *info); +    void postEOS(); +    void sendFormatChange(); +    void requestFillEmptyInput(); +    void processBuffers(); + +    void onAllocateComponent(const sp<AMessage> &msg); +    void onConfigureComponent(const sp<AMessage> &msg); +    void onStart(); +    void onInputBufferFilled(const sp<AMessage> &msg); +    void onOutputBufferDrained(const sp<AMessage> &msg); +    void onShutdown(const sp<AMessage> &msg); +    void onFlush(); +    void onSetParameters(const sp<AMessage> &msg); +    void onCreateInputSurface(); +    void onInputFrameAvailable(); +    void onSignalEndOfInputStream(); + +    DISALLOW_EVIL_CONSTRUCTORS(MediaFilter); +}; + +}  // namespace android + +#endif  // MEDIA_FILTER_H_ diff --git a/include/media/stagefright/MediaMuxer.h b/include/media/stagefright/MediaMuxer.h index 9da98d9..fa855a8 100644 --- a/include/media/stagefright/MediaMuxer.h +++ b/include/media/stagefright/MediaMuxer.h @@ -29,9 +29,9 @@ namespace android {  struct ABuffer;  struct AMessage;  struct MediaAdapter; -struct MediaBuffer; +class MediaBuffer;  struct MediaSource; -struct MetaData; +class MetaData;  struct MediaWriter;  // MediaMuxer is used to mux multiple tracks into a video. Currently, we only @@ -50,9 +50,6 @@ public:          OUTPUT_FORMAT_LIST_END // must be last - used to validate format type      }; -    // Construct the muxer with the output file path. -    MediaMuxer(const char *path, OutputFormat format); -      // Construct the muxer with the file descriptor. Note that the MediaMuxer      // will close this file at stop().      MediaMuxer(int fd, OutputFormat format); diff --git a/include/media/stagefright/MediaSync.h b/include/media/stagefright/MediaSync.h new file mode 100644 index 0000000..ef8cb23 --- /dev/null +++ b/include/media/stagefright/MediaSync.h @@ -0,0 +1,291 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MEDIA_SYNC_H +#define MEDIA_SYNC_H + +#include <gui/IConsumerListener.h> +#include <gui/IProducerListener.h> + +#include <media/AudioResamplerPublic.h> +#include <media/AVSyncSettings.h> +#include <media/stagefright/foundation/AHandler.h> + +#include <utils/Condition.h> +#include <utils/KeyedVector.h> +#include <utils/Mutex.h> + +namespace android { + +class AudioTrack; +class BufferItem; +class Fence; +class GraphicBuffer; +class IGraphicBufferConsumer; +class IGraphicBufferProducer; +struct MediaClock; +struct VideoFrameScheduler; + +// MediaSync manages media playback and its synchronization to a media clock +// source. It can be also used for video-only playback. +// +// For video playback, it requires an output surface and provides an input +// surface. It then controls the rendering of input buffers (buffer queued to +// the input surface) on the output surface to happen at the appropriate time. +// +// For audio playback, it requires an audio track and takes updates of +// information of rendered audio data to maintain media clock when audio track +// serves as media clock source. (TODO: move audio rendering from JAVA to +// native code). +// +// It can use the audio or video track as media clock source, as well as an +// external clock. (TODO: actually support external clock as media clock +// sources; use video track as media clock source for audio-and-video stream). +// +// In video-only mode, MediaSync will playback every video frame even though +// a video frame arrives late based on its timestamp and last frame's. +// +// The client needs to configure surface (for output video rendering) and audio +// track (for querying information of audio rendering) for MediaSync. +// +// Then the client needs to obtain a surface from MediaSync and render video +// frames onto that surface. Internally, the MediaSync will receive those video +// frames and render them onto the output surface at the appropriate time. +// +// The client needs to call updateQueuedAudioData() immediately after it writes +// audio data to the audio track. Such information will be used to update media +// clock. +// +class MediaSync : public AHandler { +public: +    // Create an instance of MediaSync. +    static sp<MediaSync> create(); + +    // Called when MediaSync is used to render video. It should be called +    // before createInputSurface(). +    status_t setSurface(const sp<IGraphicBufferProducer> &output); + +    // Called when audio track is used as media clock source. It should be +    // called before updateQueuedAudioData(). +    status_t setAudioTrack(const sp<AudioTrack> &audioTrack); + +    // Create a surface for client to render video frames. This is the surface +    // on which the client should render video frames. Those video frames will +    // be internally directed to output surface for rendering at appropriate +    // time. +    status_t createInputSurface(sp<IGraphicBufferProducer> *outBufferProducer); + +    // Update just-rendered audio data size and the presentation timestamp of +    // the first frame of that audio data. It should be called immediately +    // after the client write audio data into AudioTrack. +    // This function assumes continous audio stream. +    // TODO: support gap or backwards updates. +    status_t updateQueuedAudioData( +            size_t sizeInBytes, int64_t presentationTimeUs); + +    // Set the consumer name of the input queue. +    void setName(const AString &name); + +    // Get the media clock used by the MediaSync so that the client can obtain +    // corresponding media time or real time via +    // MediaClock::getMediaTime() and MediaClock::getRealTimeFor(). +    sp<const MediaClock> getMediaClock(); + +    // Flush mediasync +    void flush(); + +    // Set the video frame rate hint - this is used by the video FrameScheduler +    status_t setVideoFrameRateHint(float rate); + +    // Get the video frame rate measurement from the FrameScheduler +    // returns -1 if there is no measurement +    float getVideoFrameRate(); + +    // Set the sync settings parameters. +    status_t setSyncSettings(const AVSyncSettings &syncSettings); + +    // Gets the sync settings parameters. +    void getSyncSettings(AVSyncSettings *syncSettings /* nonnull */); + +    // Sets the playback rate using playback settings. +    // This method can be called any time. +    status_t setPlaybackSettings(const AudioPlaybackRate &rate); + +    // Gets the playback rate (playback settings parameters). +    void getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */); + +    // Get the play time for pending audio frames in audio sink. +    status_t getPlayTimeForPendingAudioFrames(int64_t *outTimeUs); + +protected: +    virtual void onMessageReceived(const sp<AMessage> &msg); + +private: +    enum { +        kWhatDrainVideo = 'dVid', +    }; + +    // This is a thin wrapper class that lets us listen to +    // IConsumerListener::onFrameAvailable from mInput. +    class InputListener : public BnConsumerListener, +                          public IBinder::DeathRecipient { +    public: +        InputListener(const sp<MediaSync> &sync); +        virtual ~InputListener(); + +        // From IConsumerListener +        virtual void onFrameAvailable(const BufferItem &item); + +        // From IConsumerListener +        // We don't care about released buffers because we detach each buffer as +        // soon as we acquire it. See the comment for onBufferReleased below for +        // some clarifying notes about the name. +        virtual void onBuffersReleased() {} + +        // From IConsumerListener +        // We don't care about sideband streams, since we won't relay them. +        virtual void onSidebandStreamChanged(); + +        // From IBinder::DeathRecipient +        virtual void binderDied(const wp<IBinder> &who); + +    private: +        sp<MediaSync> mSync; +    }; + +    // This is a thin wrapper class that lets us listen to +    // IProducerListener::onBufferReleased from mOutput. +    class OutputListener : public BnProducerListener, +                           public IBinder::DeathRecipient { +    public: +        OutputListener(const sp<MediaSync> &sync, const sp<IGraphicBufferProducer> &output); +        virtual ~OutputListener(); + +        // From IProducerListener +        virtual void onBufferReleased(); + +        // From IBinder::DeathRecipient +        virtual void binderDied(const wp<IBinder> &who); + +    private: +        sp<MediaSync> mSync; +        sp<IGraphicBufferProducer> mOutput; +    }; + +    // mIsAbandoned is set to true when the input or output dies. +    // Once the MediaSync has been abandoned by one side, it will disconnect +    // from the other side and not attempt to communicate with it further. +    bool mIsAbandoned; + +    mutable Mutex mMutex; +    Condition mReleaseCondition; +    size_t mNumOutstandingBuffers; +    sp<IGraphicBufferConsumer> mInput; +    sp<IGraphicBufferProducer> mOutput; +    int mUsageFlagsFromOutput; +    uint32_t mMaxAcquiredBufferCount; // max acquired buffer count +    bool mReturnPendingInputFrame;    // set while we are pending before acquiring an input frame + +    sp<AudioTrack> mAudioTrack; +    uint32_t mNativeSampleRateInHz; +    int64_t mNumFramesWritten; +    bool mHasAudio; + +    int64_t mNextBufferItemMediaUs; +    List<BufferItem> mBufferItems; +    sp<VideoFrameScheduler> mFrameScheduler; + +    // Keep track of buffers received from |mInput|. This is needed because +    // it's possible the consumer of |mOutput| could return a different +    // GraphicBuffer::handle (e.g., due to passing buffers through IPC), +    // and that could cause problem if the producer of |mInput| only +    // supports pre-registered buffers. +    KeyedVector<uint64_t, sp<GraphicBuffer> > mBuffersFromInput; + +    // Keep track of buffers sent to |mOutput|. When a new output surface comes +    // in, those buffers will be returned to input and old output surface will +    // be disconnected immediately. +    KeyedVector<uint64_t, sp<GraphicBuffer> > mBuffersSentToOutput; + +    sp<ALooper> mLooper; +    float mPlaybackRate; + +    AudioPlaybackRate mPlaybackSettings; +    AVSyncSettings mSyncSettings; + +    sp<MediaClock> mMediaClock; + +    MediaSync(); + +    // Must be accessed through RefBase +    virtual ~MediaSync(); + +    int64_t getRealTime(int64_t mediaTimeUs, int64_t nowUs); +    int64_t getDurationIfPlayedAtNativeSampleRate_l(int64_t numFrames); +    int64_t getPlayedOutAudioDurationMedia_l(int64_t nowUs); + +    void onDrainVideo_l(); + +    // This implements the onFrameAvailable callback from IConsumerListener. +    // It gets called from an InputListener. +    // During this callback, we detach the buffer from the input, and queue +    // it for rendering on the output. This call can block if there are too +    // many outstanding buffers. If it blocks, it will resume when +    // onBufferReleasedByOutput releases a buffer back to the input. +    void onFrameAvailableFromInput(); + +    // Send |bufferItem| to the output for rendering. +    void renderOneBufferItem_l(const BufferItem &bufferItem); + +    // This implements the onBufferReleased callback from IProducerListener. +    // It gets called from an OutputListener. +    // During this callback, we detach the buffer from the output, and release +    // it to the input. A blocked onFrameAvailable call will be allowed to proceed. +    void onBufferReleasedByOutput(sp<IGraphicBufferProducer> &output); + +    // Return |buffer| back to the input. +    void returnBufferToInput_l(const sp<GraphicBuffer> &buffer, const sp<Fence> &fence); + +    // When this is called, the MediaSync disconnects from (i.e., abandons) its +    // input or output, and signals any waiting onFrameAvailable calls to wake +    // up. This must be called with mMutex locked. +    void onAbandoned_l(bool isInput); + +    // Set the playback in a desired speed. +    // This method can be called any time. +    // |rate| is the ratio between desired speed and the normal one, and should +    // be non-negative. The meaning of rate values: +    // 1.0 -- normal playback +    // 0.0 -- stop or pause +    // larger than 1.0 -- faster than normal speed +    // between 0.0 and 1.0 -- slower than normal speed +    void updatePlaybackRate_l(float rate); + +    // apply new sync settings +    void resync_l(); + +    // apply playback settings only - without resyncing or updating playback rate +    status_t setPlaybackSettings_l(const AudioPlaybackRate &rate); + +    // helper. +    bool isPlaying() { return mPlaybackRate != 0.0; } + +    DISALLOW_EVIL_CONSTRUCTORS(MediaSync); +}; + +} // namespace android + +#endif diff --git a/include/media/stagefright/MediaWriter.h b/include/media/stagefright/MediaWriter.h index e27ea1d..8e02506 100644 --- a/include/media/stagefright/MediaWriter.h +++ b/include/media/stagefright/MediaWriter.h @@ -24,7 +24,7 @@  namespace android {  struct MediaSource; -struct MetaData; +class MetaData;  struct MediaWriter : public RefBase {      MediaWriter() diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h index 3f42790..8d4e15a 100644 --- a/include/media/stagefright/MetaData.h +++ b/include/media/stagefright/MetaData.h @@ -70,11 +70,15 @@ enum {      kKeyDriftTime         = 'dftT',  // int64_t (usecs)      kKeyAnchorTime        = 'ancT',  // int64_t (usecs)      kKeyDuration          = 'dura',  // int64_t (usecs) -    kKeyColorFormat       = 'colf', +    kKeyPixelFormat       = 'pixf',  // int32_t +    kKeyColorFormat       = 'colf',  // int32_t +    kKeyColorSpace        = 'cols',  // int32_t      kKeyPlatformPrivate   = 'priv',  // pointer      kKeyDecoderComponent  = 'decC',  // cstring      kKeyBufferID          = 'bfID',      kKeyMaxInputSize      = 'inpS', +    kKeyMaxWidth          = 'maxW', +    kKeyMaxHeight         = 'maxH',      kKeyThumbnailTime     = 'thbT',  // int64_t (usecs)      kKeyTrackID           = 'trID',      kKeyIsDRM             = 'idrm',  // int32_t (bool) @@ -98,6 +102,7 @@ enum {      kKeyCompilation       = 'cpil',  // cstring      kKeyLocation          = 'loc ',  // cstring      kKeyTimeScale         = 'tmsl',  // int32_t +    kKeyCaptureFramerate  = 'capF',  // float (capture fps)      // video profile and level      kKeyVideoProfile      = 'vprf',  // int32_t @@ -173,6 +178,9 @@ enum {      kKeyTrackIsDefault    = 'dflt', // bool (int32_t)      // Similar to MediaFormat.KEY_IS_FORCED_SUBTITLE but pertains to av tracks as well.      kKeyTrackIsForced     = 'frcd', // bool (int32_t) + +    // H264 supplemental enhancement information offsets/sizes +    kKeySEI               = 'sei ', // raw data  };  enum { diff --git a/include/media/stagefright/NativeWindowWrapper.h b/include/media/stagefright/NativeWindowWrapper.h deleted file mode 100644 index cfeec22..0000000 --- a/include/media/stagefright/NativeWindowWrapper.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NATIVE_WINDOW_WRAPPER_H_ - -#define NATIVE_WINDOW_WRAPPER_H_ - -#include <gui/Surface.h> - -namespace android { - -// Surface derives from ANativeWindow which derives from multiple -// base classes, in order to carry it in AMessages, we'll temporarily wrap it -// into a NativeWindowWrapper. - -struct NativeWindowWrapper : RefBase { -    NativeWindowWrapper( -            const sp<Surface> &surfaceTextureClient) : -        mSurfaceTextureClient(surfaceTextureClient) { } - -    sp<ANativeWindow> getNativeWindow() const { -        return mSurfaceTextureClient; -    } - -    sp<Surface> getSurfaceTextureClient() const { -        return mSurfaceTextureClient; -    } - -private: -    const sp<Surface> mSurfaceTextureClient; - -    DISALLOW_EVIL_CONSTRUCTORS(NativeWindowWrapper); -}; - -}  // namespace android - -#endif  // NATIVE_WINDOW_WRAPPER_H_ diff --git a/include/media/stagefright/NuMediaExtractor.h b/include/media/stagefright/NuMediaExtractor.h index 402e7f8..fd74452 100644 --- a/include/media/stagefright/NuMediaExtractor.h +++ b/include/media/stagefright/NuMediaExtractor.h @@ -30,12 +30,12 @@ namespace android {  struct ABuffer;  struct AMessage; -struct DataSource; +class DataSource;  struct IMediaHTTPService; -struct MediaBuffer; +class MediaBuffer;  struct MediaExtractor;  struct MediaSource; -struct MetaData; +class MetaData;  struct NuMediaExtractor : public RefBase {      enum SampleFlags { diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index 84b1b1a..7fabcb3 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -298,7 +298,6 @@ private:      status_t queueBufferToNativeWindow(BufferInfo *info);      status_t cancelBufferToNativeWindow(BufferInfo *info);      BufferInfo* dequeueBufferFromNativeWindow(); -    status_t pushBlankBuffersToNativeWindow();      status_t freeBuffersOnPort(              OMX_U32 portIndex, bool onlyThoseWeOwn = false); @@ -347,7 +346,6 @@ private:      status_t configureCodec(const sp<MetaData> &meta); -    status_t applyRotation();      status_t waitForBufferFilled_l();      int64_t getDecodingTimeUs(); diff --git a/include/media/stagefright/PersistentSurface.h b/include/media/stagefright/PersistentSurface.h new file mode 100644 index 0000000..a35b9f1 --- /dev/null +++ b/include/media/stagefright/PersistentSurface.h @@ -0,0 +1,51 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PERSISTENT_SURFACE_H_ + +#define PERSISTENT_SURFACE_H_ + +#include <gui/IGraphicBufferProducer.h> +#include <gui/IGraphicBufferConsumer.h> +#include <media/stagefright/foundation/ABase.h> + +namespace android { + +struct PersistentSurface : public RefBase { +    PersistentSurface( +            const sp<IGraphicBufferProducer>& bufferProducer, +            const sp<IGraphicBufferConsumer>& bufferConsumer) : +        mBufferProducer(bufferProducer), +        mBufferConsumer(bufferConsumer) { } + +    sp<IGraphicBufferProducer> getBufferProducer() const { +        return mBufferProducer; +    } + +    sp<IGraphicBufferConsumer> getBufferConsumer() const { +        return mBufferConsumer; +    } + +private: +    const sp<IGraphicBufferProducer> mBufferProducer; +    const sp<IGraphicBufferConsumer> mBufferConsumer; + +    DISALLOW_EVIL_CONSTRUCTORS(PersistentSurface); +}; + +}  // namespace android + +#endif  // PERSISTENT_SURFACE_H_ diff --git a/include/media/stagefright/ProcessInfo.h b/include/media/stagefright/ProcessInfo.h new file mode 100644 index 0000000..ec0cdff --- /dev/null +++ b/include/media/stagefright/ProcessInfo.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PROCESS_INFO_H_ + +#define PROCESS_INFO_H_ + +#include <media/stagefright/foundation/ABase.h> +#include <media/stagefright/ProcessInfoInterface.h> + +namespace android { + +struct ProcessInfo : public ProcessInfoInterface { +    ProcessInfo(); + +    virtual bool getPriority(int pid, int* priority); + +protected: +    virtual ~ProcessInfo(); + +private: +    DISALLOW_EVIL_CONSTRUCTORS(ProcessInfo); +}; + +}  // namespace android + +#endif  // PROCESS_INFO_H_ diff --git a/include/media/nbaio/roundup.h b/include/media/stagefright/ProcessInfoInterface.h index 4c3cc25..222f92d 100644 --- a/include/media/nbaio/roundup.h +++ b/include/media/stagefright/ProcessInfoInterface.h @@ -1,5 +1,5 @@  /* - * Copyright (C) 2012 The Android Open Source Project + * Copyright (C) 2015 The Android Open Source Project   *   * Licensed under the Apache License, Version 2.0 (the "License");   * you may not use this file except in compliance with the License. @@ -14,18 +14,20 @@   * limitations under the License.   */ -#ifndef ROUNDUP_H -#define ROUNDUP_H +#ifndef PROCESS_INFO_INTERFACE_H_ +#define PROCESS_INFO_INTERFACE_H_ -#ifdef __cplusplus -extern "C" { -#endif +#include <utils/RefBase.h> -// Round up to the next highest power of 2 -unsigned roundup(unsigned v); +namespace android { -#ifdef __cplusplus -} -#endif +struct ProcessInfoInterface : public RefBase { +    virtual bool getPriority(int pid, int* priority) = 0; -#endif  // ROUNDUP_H +protected: +    virtual ~ProcessInfoInterface() {} +}; + +}  // namespace android + +#endif  // PROCESS_INFO_INTERFACE_H_ diff --git a/include/media/stagefright/RenderScriptWrapper.h b/include/media/stagefright/RenderScriptWrapper.h new file mode 100644 index 0000000..b42649e --- /dev/null +++ b/include/media/stagefright/RenderScriptWrapper.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RENDERSCRIPT_WRAPPER_H_ +#define RENDERSCRIPT_WRAPPER_H_ + +#include <RenderScript.h> + +namespace android { + +struct RenderScriptWrapper : public RefBase { +public: +    struct RSFilterCallback : public RefBase { +    public: +        // called by RSFilter to process each input buffer +        virtual status_t processBuffers( +                RSC::Allocation* inBuffer, +                RSC::Allocation* outBuffer) = 0; + +        virtual status_t handleSetParameters(const sp<AMessage> &msg) = 0; +    }; + +    sp<RSFilterCallback> mCallback; +    RSC::sp<RSC::RS> mContext; +}; + +}   // namespace android + +#endif  // RENDERSCRIPT_WRAPPER_H_ diff --git a/include/media/stagefright/SurfaceUtils.h b/include/media/stagefright/SurfaceUtils.h new file mode 100644 index 0000000..c1a9c0a --- /dev/null +++ b/include/media/stagefright/SurfaceUtils.h @@ -0,0 +1,34 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SURFACE_UTILS_H_ + +#define SURFACE_UTILS_H_ + +#include <utils/Errors.h> + +struct ANativeWindow; + +namespace android { + +status_t setNativeWindowSizeFormatAndUsage( +        ANativeWindow *nativeWindow /* nonnull */, +        int width, int height, int format, int rotation, int usage); +status_t pushBlankBuffersToNativeWindow(ANativeWindow *nativeWindow /* nonnull */); + +} // namespace android + +#endif  // SURFACE_UTILS_H_ diff --git a/include/media/stagefright/Utils.h b/include/media/stagefright/Utils.h index a795c80..5e9d7d4 100644 --- a/include/media/stagefright/Utils.h +++ b/include/media/stagefright/Utils.h @@ -41,7 +41,7 @@ uint64_t U64LE_AT(const uint8_t *ptr);  uint64_t ntoh64(uint64_t x);  uint64_t hton64(uint64_t x); -struct MetaData; +class MetaData;  struct AMessage;  status_t convertMetaDataToMessage(          const sp<MetaData> &meta, sp<AMessage> *format); @@ -65,6 +65,26 @@ bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,  AString uriDebugString(const AString &uri, bool incognito = false); +struct HLSTime { +    int32_t mSeq; +    int64_t mTimeUs; +    sp<AMessage> mMeta; + +    HLSTime(const sp<AMessage> &meta = NULL); +    int64_t getSegmentTimeUs() const; +}; + +bool operator <(const HLSTime &t0, const HLSTime &t1); + +// read and write various object to/from AMessage + +void writeToAMessage(sp<AMessage> msg, const AudioPlaybackRate &rate); +void readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */); + +void writeToAMessage(sp<AMessage> msg, const AVSyncSettings &sync, float videoFpsHint); +void readFromAMessage( +        const sp<AMessage> &msg, AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */); +  }  // namespace android  #endif  // UTILS_H_ diff --git a/include/media/stagefright/VideoFrameScheduler.h b/include/media/stagefright/VideoFrameScheduler.h new file mode 100644 index 0000000..9d97dfd --- /dev/null +++ b/include/media/stagefright/VideoFrameScheduler.h @@ -0,0 +1,103 @@ +/* + * Copyright 2014, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *     http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef VIDEO_FRAME_SCHEDULER_H_ +#define VIDEO_FRAME_SCHEDULER_H_ + +#include <utils/RefBase.h> +#include <utils/Timers.h> + +#include <media/stagefright/foundation/ABase.h> + +namespace android { + +class ISurfaceComposer; + +struct VideoFrameScheduler : public RefBase { +    VideoFrameScheduler(); + +    // (re)initialize scheduler +    void init(float videoFps = -1); +    // use in case of video render-time discontinuity, e.g. seek +    void restart(); +    // get adjusted nanotime for a video frame render at renderTime +    nsecs_t schedule(nsecs_t renderTime); + +    // returns the vsync period for the main display +    nsecs_t getVsyncPeriod(); + +    // returns the current frames-per-second, or 0.f if not primed +    float getFrameRate(); + +    void release(); + +    static const size_t kHistorySize = 8; + +protected: +    virtual ~VideoFrameScheduler(); + +private: +    struct PLL { +        PLL(); + +        // reset PLL to new PLL +        void reset(float fps = -1); +        // keep current estimate, but restart phase +        void restart(); +        // returns period or 0 if not yet primed +        nsecs_t addSample(nsecs_t time); +        nsecs_t getPeriod() const; + +    private: +        nsecs_t mPeriod; +        nsecs_t mPhase; + +        bool    mPrimed;        // have an estimate for the period +        size_t  mSamplesUsedForPriming; + +        nsecs_t mLastTime;      // last input time +        nsecs_t mRefitAt;       // next input time to fit at + +        size_t  mNumSamples;    // can go past kHistorySize +        nsecs_t mTimes[kHistorySize]; + +        void test(); +        // returns whether fit was successful +        bool fit(nsecs_t phase, nsecs_t period, size_t numSamples, +                int64_t *a, int64_t *b, int64_t *err); +        void prime(size_t numSamples); +    }; + +    void updateVsync(); + +    nsecs_t mVsyncTime;        // vsync timing from display +    nsecs_t mVsyncPeriod; +    nsecs_t mVsyncRefreshAt;   // next time to refresh timing info + +    nsecs_t mLastVsyncTime;    // estimated vsync time for last frame +    nsecs_t mTimeCorrection;   // running adjustment + +    PLL mPll;                  // PLL for video frame rate based on render time + +    sp<ISurfaceComposer> mComposer; + +    DISALLOW_EVIL_CONSTRUCTORS(VideoFrameScheduler); +}; + +}  // namespace android + +#endif  // VIDEO_FRAME_SCHEDULER_H_ + diff --git a/include/media/stagefright/foundation/ABase.h b/include/media/stagefright/foundation/ABase.h index 72e3d87..ef1e010 100644 --- a/include/media/stagefright/foundation/ABase.h +++ b/include/media/stagefright/foundation/ABase.h @@ -18,7 +18,9 @@  #define A_BASE_H_ +#ifndef ARRAY_SIZE  #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) +#endif  #define DISALLOW_EVIL_CONSTRUCTORS(name) \      name(const name &); \ diff --git a/include/media/stagefright/foundation/ADebug.h b/include/media/stagefright/foundation/ADebug.h index 1d0e2cb..65f415a 100644 --- a/include/media/stagefright/foundation/ADebug.h +++ b/include/media/stagefright/foundation/ADebug.h @@ -24,6 +24,31 @@  #include <media/stagefright/foundation/AString.h>  #include <utils/Log.h> +inline static const char *asString(android::status_t i, const char *def = "??") { +    using namespace android; +    switch (i) { +        case NO_ERROR:              return "NO_ERROR"; +        case UNKNOWN_ERROR:         return "UNKNOWN_ERROR"; +        case NO_MEMORY:             return "NO_MEMORY"; +        case INVALID_OPERATION:     return "INVALID_OPERATION"; +        case BAD_VALUE:             return "BAD_VALUE"; +        case BAD_TYPE:              return "BAD_TYPE"; +        case NAME_NOT_FOUND:        return "NAME_NOT_FOUND"; +        case PERMISSION_DENIED:     return "PERMISSION_DENIED"; +        case NO_INIT:               return "NO_INIT"; +        case ALREADY_EXISTS:        return "ALREADY_EXISTS"; +        case DEAD_OBJECT:           return "DEAD_OBJECT"; +        case FAILED_TRANSACTION:    return "FAILED_TRANSACTION"; +        case BAD_INDEX:             return "BAD_INDEX"; +        case NOT_ENOUGH_DATA:       return "NOT_ENOUGH_DATA"; +        case WOULD_BLOCK:           return "WOULD_BLOCK"; +        case TIMED_OUT:             return "TIMED_OUT"; +        case UNKNOWN_TRANSACTION:   return "UNKNOWN_TRANSACTION"; +        case FDS_NOT_ALLOWED:       return "FDS_NOT_ALLOWED"; +        default:                    return def; +    } +} +  namespace android {  #define LITERAL_TO_STRING_INTERNAL(x)    #x @@ -92,7 +117,7 @@ struct ADebug {      }; -    // parse the property or string to get the debug level for a component name +    // parse the property or string to get a long-type level for a component name      // string format is:      // <level>[:<glob>][,<level>[:<glob>]...]      // - <level> is 0-5 corresponding to ADebug::Level @@ -100,14 +125,38 @@ struct ADebug {      //   matches all components      // - string is read left-to-right, and the last matching level is returned, or      //   the def if no terms matched +    static long GetLevelFromSettingsString( +            const char *name, const char *value, long def); +    static long GetLevelFromProperty( +            const char *name, const char *value, long def); + +    // same for ADebug::Level - performs clamping to valid debug ranges      static Level GetDebugLevelFromProperty(              const char *name, const char *propertyName, Level def = kDebugNone); -    static Level GetDebugLevelFromString( -            const char *name, const char *value, Level def = kDebugNone);      // remove redundant segments of a codec name, and return a newly allocated      // string suitable for debugging      static char *GetDebugName(const char *name); + +    inline static bool isExperimentEnabled( +            const char *name __unused /* nonnull */, bool allow __unused = true) { +#ifdef ENABLE_STAGEFRIGHT_EXPERIMENTS +        if (!strcmp(name, "legacy-adaptive")) { +            return getExperimentFlag(allow, name, 2, 1); // every other day +        } else if (!strcmp(name, "legacy-setsurface")) { +            return getExperimentFlag(allow, name, 3, 1); // every third day +        } else { +            ALOGE("unknown experiment '%s' (disabled)", name); +        } +#endif +        return false; +    } + +private: +    // pass in allow, so we can print in the log if the experiment is disabled +    static bool getExperimentFlag( +            bool allow, const char *name, uint64_t modulo, uint64_t limit, +            uint64_t plus = 0, uint64_t timeDivisor = 24 * 60 * 60 /* 1 day */);  };  }  // namespace android diff --git a/include/media/stagefright/foundation/AHandler.h b/include/media/stagefright/foundation/AHandler.h index 41ade77..fe02a86 100644 --- a/include/media/stagefright/foundation/AHandler.h +++ b/include/media/stagefright/foundation/AHandler.h @@ -29,6 +29,7 @@ struct AMessage;  struct AHandler : public RefBase {      AHandler()          : mID(0), +          mVerboseStats(false),            mMessageCounter(0) {      } @@ -36,23 +37,40 @@ struct AHandler : public RefBase {          return mID;      } -    sp<ALooper> looper(); +    sp<ALooper> looper() const { +        return mLooper.promote(); +    } + +    wp<ALooper> getLooper() const { +        return mLooper; +    } + +    wp<AHandler> getHandler() const { +        // allow getting a weak reference to a const handler +        return const_cast<AHandler *>(this); +    }  protected:      virtual void onMessageReceived(const sp<AMessage> &msg) = 0;  private: -    friend struct ALooperRoster; +    friend struct AMessage;      // deliverMessage() +    friend struct ALooperRoster; // setID()      ALooper::handler_id mID; +    wp<ALooper> mLooper; -    void setID(ALooper::handler_id id) { +    inline void setID(ALooper::handler_id id, wp<ALooper> looper) {          mID = id; +        mLooper = looper;      } +    bool mVerboseStats;      uint32_t mMessageCounter;      KeyedVector<uint32_t, uint32_t> mMessages; +    void deliverMessage(const sp<AMessage> &msg); +      DISALLOW_EVIL_CONSTRUCTORS(AHandler);  }; diff --git a/include/media/stagefright/foundation/ALooper.h b/include/media/stagefright/foundation/ALooper.h index 70e0c5e..09c469b 100644 --- a/include/media/stagefright/foundation/ALooper.h +++ b/include/media/stagefright/foundation/ALooper.h @@ -30,6 +30,7 @@ namespace android {  struct AHandler;  struct AMessage; +struct AReplyToken;  struct ALooper : public RefBase {      typedef int32_t event_id; @@ -53,11 +54,15 @@ struct ALooper : public RefBase {      static int64_t GetNowUs(); +    const char *getName() const { +        return mName.c_str(); +    } +  protected:      virtual ~ALooper();  private: -    friend struct ALooperRoster; +    friend struct AMessage;       // post()      struct Event {          int64_t mWhenUs; @@ -75,12 +80,32 @@ private:      sp<LooperThread> mThread;      bool mRunningLocally; +    // use a separate lock for reply handling, as it is always on another thread +    // use a central lock, however, to avoid creating a mutex for each reply +    Mutex mRepliesLock; +    Condition mRepliesCondition; + +    // START --- methods used only by AMessage + +    // posts a message on this looper with the given timeout      void post(const sp<AMessage> &msg, int64_t delayUs); + +    // creates a reply token to be used with this looper +    sp<AReplyToken> createReplyToken(); +    // waits for a response for the reply token.  If status is OK, the response +    // is stored into the supplied variable.  Otherwise, it is unchanged. +    status_t awaitResponse(const sp<AReplyToken> &replyToken, sp<AMessage> *response); +    // posts a reply for a reply token.  If the reply could be successfully posted, +    // it returns OK. Otherwise, it returns an error value. +    status_t postReply(const sp<AReplyToken> &replyToken, const sp<AMessage> &msg); + +    // END --- methods used only by AMessage +      bool loop();      DISALLOW_EVIL_CONSTRUCTORS(ALooper);  }; -}  // namespace android +} // namespace android  #endif  // A_LOOPER_H_ diff --git a/include/media/stagefright/foundation/ALooperRoster.h b/include/media/stagefright/foundation/ALooperRoster.h index a0be8eb..9912455 100644 --- a/include/media/stagefright/foundation/ALooperRoster.h +++ b/include/media/stagefright/foundation/ALooperRoster.h @@ -33,16 +33,6 @@ struct ALooperRoster {      void unregisterHandler(ALooper::handler_id handlerID);      void unregisterStaleHandlers(); -    status_t postMessage(const sp<AMessage> &msg, int64_t delayUs = 0); -    void deliverMessage(const sp<AMessage> &msg); - -    status_t postAndAwaitResponse( -            const sp<AMessage> &msg, sp<AMessage> *response); - -    void postReply(uint32_t replyID, const sp<AMessage> &reply); - -    sp<ALooper> findLooper(ALooper::handler_id handlerID); -      void dump(int fd, const Vector<String16>& args);  private: @@ -54,10 +44,6 @@ private:      Mutex mLock;      KeyedVector<ALooper::handler_id, HandlerInfo> mHandlers;      ALooper::handler_id mNextHandlerID; -    uint32_t mNextReplyID; -    Condition mRepliesCondition; - -    KeyedVector<uint32_t, sp<AMessage> > mReplies;      DISALLOW_EVIL_CONSTRUCTORS(ALooperRoster);  }; diff --git a/include/media/stagefright/foundation/AMessage.h b/include/media/stagefright/foundation/AMessage.h index a9e235b..83b9444 100644 --- a/include/media/stagefright/foundation/AMessage.h +++ b/include/media/stagefright/foundation/AMessage.h @@ -26,11 +26,41 @@  namespace android {  struct ABuffer; +struct AHandler;  struct AString; -struct Parcel; +class Parcel; + +struct AReplyToken : public RefBase { +    AReplyToken(const sp<ALooper> &looper) +        : mLooper(looper), +          mReplied(false) { +    } + +private: +    friend struct AMessage; +    friend struct ALooper; +    wp<ALooper> mLooper; +    sp<AMessage> mReply; +    bool mReplied; + +    sp<ALooper> getLooper() const { +        return mLooper.promote(); +    } +    // if reply is not set, returns false; otherwise, it retrieves the reply and returns true +    bool retrieveReply(sp<AMessage> *reply) { +        if (mReplied) { +            *reply = mReply; +            mReply.clear(); +        } +        return mReplied; +    } +    // sets the reply for this token. returns OK or error +    status_t setReply(const sp<AMessage> &reply); +};  struct AMessage : public RefBase { -    AMessage(uint32_t what = 0, ALooper::handler_id target = 0); +    AMessage(); +    AMessage(uint32_t what, const sp<const AHandler> &handler);      static sp<AMessage> FromParcel(const Parcel &parcel);      void writeToParcel(Parcel *parcel) const; @@ -38,8 +68,7 @@ struct AMessage : public RefBase {      void setWhat(uint32_t what);      uint32_t what() const; -    void setTarget(ALooper::handler_id target); -    ALooper::handler_id target() const; +    void setTarget(const sp<const AHandler> &handler);      void clear(); @@ -76,18 +105,22 @@ struct AMessage : public RefBase {              const char *name,              int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) const; -    void post(int64_t delayUs = 0); +    status_t post(int64_t delayUs = 0);      // Posts the message to its target and waits for a response (or error)      // before returning.      status_t postAndAwaitResponse(sp<AMessage> *response);      // If this returns true, the sender of this message is synchronously -    // awaiting a response, the "replyID" can be used to send the response -    // via "postReply" below. -    bool senderAwaitsResponse(uint32_t *replyID) const; +    // awaiting a response and the reply token is consumed from the message +    // and stored into replyID. The reply token must be used to send the response +    // using "postReply" below. +    bool senderAwaitsResponse(sp<AReplyToken> *replyID); -    void postReply(uint32_t replyID); +    // Posts the message as a response to a reply token.  A reply token can +    // only be used once. Returns OK if the response could be posted; otherwise, +    // an error. +    status_t postReply(const sp<AReplyToken> &replyID);      // Performs a deep-copy of "this", contained messages are in turn "dup'ed".      // Warning: RefBase items, i.e. "objects" are _not_ copied but only have @@ -117,9 +150,16 @@ protected:      virtual ~AMessage();  private: +    friend struct ALooper; // deliver() +      uint32_t mWhat; + +    // used only for debugging      ALooper::handler_id mTarget; +    wp<AHandler> mHandler; +    wp<ALooper> mLooper; +      struct Rect {          int32_t mLeft, mTop, mRight, mBottom;      }; @@ -157,6 +197,8 @@ private:      size_t findItemIndex(const char *name, size_t len) const; +    void deliver(); +      DISALLOW_EVIL_CONSTRUCTORS(AMessage);  }; diff --git a/include/media/stagefright/foundation/AString.h b/include/media/stagefright/foundation/AString.h index 822dbb3..2f6d532 100644 --- a/include/media/stagefright/foundation/AString.h +++ b/include/media/stagefright/foundation/AString.h @@ -24,7 +24,7 @@  namespace android {  class String8; -struct Parcel; +class Parcel;  struct AString {      AString(); diff --git a/include/media/stagefright/timedtext/TimedTextDriver.h b/include/media/stagefright/timedtext/TimedTextDriver.h index 37ef674..6f7c693 100644 --- a/include/media/stagefright/timedtext/TimedTextDriver.h +++ b/include/media/stagefright/timedtext/TimedTextDriver.h @@ -24,7 +24,7 @@  namespace android { -class ALooper; +struct ALooper;  struct IMediaHTTPService;  class MediaPlayerBase;  class MediaSource; diff --git a/include/ndk/NdkMediaCodec.h b/include/ndk/NdkMediaCodec.h index c07f4c9..4f6a1ef 100644 --- a/include/ndk/NdkMediaCodec.h +++ b/include/ndk/NdkMediaCodec.h @@ -142,7 +142,8 @@ media_status_t AMediaCodec_queueSecureInputBuffer(AMediaCodec*,  /**   * Get the index of the next available buffer of processed data.   */ -ssize_t AMediaCodec_dequeueOutputBuffer(AMediaCodec*, AMediaCodecBufferInfo *info, int64_t timeoutUs); +ssize_t AMediaCodec_dequeueOutputBuffer(AMediaCodec*, AMediaCodecBufferInfo *info, +        int64_t timeoutUs);  AMediaFormat* AMediaCodec_getOutputFormat(AMediaCodec*);  /** diff --git a/include/ndk/NdkMediaExtractor.h b/include/ndk/NdkMediaExtractor.h index 7a4e702..7324d31 100644 --- a/include/ndk/NdkMediaExtractor.h +++ b/include/ndk/NdkMediaExtractor.h @@ -55,12 +55,14 @@ 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); +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 +media_status_t AMediaExtractor_setDataSource(AMediaExtractor*, const char *location); +        // TODO support headers  /**   * Return the number of tracks in the previously specified media file diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h index 31dff36..1e5064f 100644 --- a/include/private/media/AudioTrackShared.h +++ b/include/private/media/AudioTrackShared.h @@ -24,9 +24,9 @@  #include <utils/threads.h>  #include <utils/Log.h>  #include <utils/RefBase.h> -#include <media/nbaio/roundup.h> +#include <audio_utils/roundup.h> +#include <media/AudioResamplerPublic.h>  #include <media/SingleStateQueue.h> -#include <private/media/StaticAudioTrackState.h>  namespace android { @@ -54,24 +54,68 @@ namespace android {  struct AudioTrackSharedStreaming {      // similar to NBAIO MonoPipe      // in continuously incrementing frame units, take modulo buffer size, which must be a power of 2 -    volatile int32_t mFront;    // read by server -    volatile int32_t mRear;     // write by client +    volatile int32_t mFront;    // read by consumer (output: server, input: client) +    volatile int32_t mRear;     // written by producer (output: client, input: server)      volatile int32_t mFlush;    // incremented by client to indicate a request to flush;                                  // server notices and discards all data between mFront and mRear      volatile uint32_t mUnderrunFrames;  // server increments for each unavailable but desired frame  }; +// Represents a single state of an AudioTrack that was created in static mode (shared memory buffer +// supplied by the client).  This state needs to be communicated from the client to server.  As this +// state is too large to be updated atomically without a mutex, and mutexes aren't allowed here, the +// state is wrapped by a SingleStateQueue. +struct StaticAudioTrackState { +    // Do not define constructors, destructors, or virtual methods as this is part of a +    // union in shared memory and they will not get called properly. + +    // These fields should both be size_t, but since they are located in shared memory we +    // force to 32-bit.  The client and server may have different typedefs for size_t. + +    // The state has a sequence counter to indicate whether changes are made to loop or position. +    // The sequence counter also currently indicates whether loop or position is first depending +    // on which is greater; it jumps by max(mLoopSequence, mPositionSequence) + 1. + +    uint32_t    mLoopStart; +    uint32_t    mLoopEnd; +    int32_t     mLoopCount; +    uint32_t    mLoopSequence; // a sequence counter to indicate changes to loop +    uint32_t    mPosition; +    uint32_t    mPositionSequence; // a sequence counter to indicate changes to position +}; +  typedef SingleStateQueue<StaticAudioTrackState> StaticAudioTrackSingleStateQueue; +struct StaticAudioTrackPosLoop { +    // Do not define constructors, destructors, or virtual methods as this is part of a +    // union in shared memory and will not get called properly. + +    // These fields should both be size_t, but since they are located in shared memory we +    // force to 32-bit.  The client and server may have different typedefs for size_t. + +    // This struct information is stored in a single state queue to communicate the +    // static AudioTrack server state to the client while data is consumed. +    // It is smaller than StaticAudioTrackState to prevent unnecessary information from +    // being sent. + +    uint32_t mBufferPosition; +    int32_t  mLoopCount; +}; + +typedef SingleStateQueue<StaticAudioTrackPosLoop> StaticAudioTrackPosLoopQueue; +  struct AudioTrackSharedStatic { +    // client requests to the server for loop or position changes.      StaticAudioTrackSingleStateQueue::Shared                      mSingleStateQueue; -    // This field should be a size_t, but since it is located in shared memory we -    // force to 32-bit.  The client and server may have different typedefs for size_t. -    uint32_t        mBufferPosition;    // updated asynchronously by server, -                                        // "for entertainment purposes only" +    // position info updated asynchronously by server and read by client, +    // "for entertainment purposes only" +    StaticAudioTrackPosLoopQueue::Shared +                    mPosLoopQueue;  }; +typedef SingleStateQueue<AudioPlaybackRate> PlaybackRateQueue; +  // ----------------------------------------------------------------------------  // Important: do not add any virtual methods, including ~ @@ -96,7 +140,8 @@ struct audio_track_cblk_t                  uint32_t    mServer;    // Number of filled frames consumed by server (mIsOut),                                          // or filled frames provided by server (!mIsOut).                                          // It is updated asynchronously by server without a barrier. -                                        // The value should be used "for entertainment purposes only", +                                        // The value should be used +                                        // "for entertainment purposes only",                                          // which means don't make important decisions based on it.                  uint32_t    mPad1;      // unused @@ -117,6 +162,8 @@ private:                  uint32_t    mSampleRate;    // AudioTrack only: client's requested sample rate in Hz                                              // or 0 == default. Write-only client, read-only server. +                PlaybackRateQueue::Shared mPlaybackRateQueue; +                  // client write-only, server read-only                  uint16_t    mSendLevel;      // Fixed point U4.12 so 0x1000 means 1.0 @@ -271,7 +318,8 @@ public:      AudioTrackClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,              size_t frameSize, bool clientInServer = false)          : ClientProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, -          clientInServer) { } +          clientInServer), +          mPlaybackRateMutator(&cblk->mPlaybackRateQueue) { }      virtual ~AudioTrackClientProxy() { }      // No barriers on the following operations, so the ordering of loads/stores @@ -291,6 +339,10 @@ public:          mCblk->mSampleRate = sampleRate;      } +    void        setPlaybackRate(const AudioPlaybackRate& playbackRate) { +        mPlaybackRateMutator.push(playbackRate); +    } +      virtual void flush();      virtual uint32_t    getUnderrunFrames() const { @@ -302,6 +354,9 @@ public:      bool        getStreamEndDone() const;      status_t    waitStreamEndDone(const struct timespec *requested); + +private: +    PlaybackRateQueue::Mutator   mPlaybackRateMutator;  };  class StaticAudioTrackClientProxy : public AudioTrackClientProxy { @@ -313,8 +368,28 @@ public:      virtual void    flush();  #define MIN_LOOP    16  // minimum length of each loop iteration in frames + +            // setLoop(), setBufferPosition(), and setBufferPositionAndLoop() set the +            // static buffer position and looping parameters.  These commands are not +            // synchronous (they do not wait or block); instead they take effect at the +            // next buffer data read from the server side. However, the client side +            // getters will read a cached version of the position and loop variables +            // until the setting takes effect. +            // +            // setBufferPositionAndLoop() is equivalent to calling, in order, setLoop() and +            // setBufferPosition(). +            // +            // The functions should not be relied upon to do parameter or state checking. +            // That is done at the AudioTrack level. +              void    setLoop(size_t loopStart, size_t loopEnd, int loopCount); +            void    setBufferPosition(size_t position); +            void    setBufferPositionAndLoop(size_t position, size_t loopStart, size_t loopEnd, +                                             int loopCount);              size_t  getBufferPosition(); +                    // getBufferPositionAndLoopCount() provides the proper snapshot of +                    // position and loopCount together. +            void    getBufferPositionAndLoopCount(size_t *position, int *loopCount);      virtual size_t  getMisalignment() {          return 0; @@ -326,7 +401,9 @@ public:  private:      StaticAudioTrackSingleStateQueue::Mutator   mMutator; -    size_t          mBufferPosition;    // so that getBufferPosition() appears to be synchronous +    StaticAudioTrackPosLoopQueue::Observer      mPosLoopObserver; +                        StaticAudioTrackState   mState;   // last communicated state to server +                        StaticAudioTrackPosLoop mPosLoop; // snapshot of position and loop.  };  // ---------------------------------------------------------------------------- @@ -394,8 +471,10 @@ class AudioTrackServerProxy : public ServerProxy {  public:      AudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,              size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0) -        : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer) { +        : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer), +          mPlaybackRateObserver(&cblk->mPlaybackRateQueue) {          mCblk->mSampleRate = sampleRate; +        mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;      }  protected:      virtual ~AudioTrackServerProxy() { } @@ -429,6 +508,13 @@ public:      // Return the total number of frames that AudioFlinger has obtained and released      virtual size_t      framesReleased() const { return mCblk->mServer; } + +    // Return the playback speed and pitch read atomically. Not multi-thread safe on server side. +    AudioPlaybackRate getPlaybackRate(); + +private: +    AudioPlaybackRate             mPlaybackRate;  // last observed playback rate +    PlaybackRateQueue::Observer   mPlaybackRateObserver;  };  class StaticAudioTrackServerProxy : public AudioTrackServerProxy { @@ -447,10 +533,13 @@ public:      virtual uint32_t    getUnderrunFrames() const { return 0; }  private: +    status_t            updateStateWithLoop(StaticAudioTrackState *localState, +                                            const StaticAudioTrackState &update) const; +    status_t            updateStateWithPosition(StaticAudioTrackState *localState, +                                                const StaticAudioTrackState &update) const;      ssize_t             pollPosition(); // poll for state queue update, and return current position      StaticAudioTrackSingleStateQueue::Observer  mObserver; -    size_t              mPosition;  // server's current play position in frames, relative to 0 - +    StaticAudioTrackPosLoopQueue::Mutator       mPosLoopMutator;      size_t              mFramesReadySafe; // Assuming size_t read/writes are atomic on 32 / 64 bit                                            // processors, this is a thread-safe version of                                            // mFramesReady. @@ -459,7 +548,8 @@ private:                                            // can cause a track to appear to have a large number                                            // of frames. INT64_MAX means an infinite loop.      bool                mFramesReadyIsCalledByMultipleThreads; -    StaticAudioTrackState   mState; +    StaticAudioTrackState mState;         // Server side state. Any updates from client must be +                                          // passed by the mObserver SingleStateQueue.  };  // Proxy used by AudioFlinger for servicing AudioRecord diff --git a/include/private/media/StaticAudioTrackState.h b/include/private/media/StaticAudioTrackState.h deleted file mode 100644 index d483061..0000000 --- a/include/private/media/StaticAudioTrackState.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef STATIC_AUDIO_TRACK_STATE_H -#define STATIC_AUDIO_TRACK_STATE_H - -namespace android { - -// Represents a single state of an AudioTrack that was created in static mode (shared memory buffer -// supplied by the client).  This state needs to be communicated from the client to server.  As this -// state is too large to be updated atomically without a mutex, and mutexes aren't allowed here, the -// state is wrapped by a SingleStateQueue. -struct StaticAudioTrackState { -    // do not define constructors, destructors, or virtual methods - -    // These fields should both be size_t, but since they are located in shared memory we -    // force to 32-bit.  The client and server may have different typedefs for size_t. -    uint32_t    mLoopStart; -    uint32_t    mLoopEnd; - -    int         mLoopCount; -}; - -}   // namespace android - -#endif  // STATIC_AUDIO_TRACK_STATE_H diff --git a/include/radio/IRadio.h b/include/radio/IRadio.h new file mode 100644 index 0000000..1877f8f --- /dev/null +++ b/include/radio/IRadio.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_IRADIO_H +#define ANDROID_HARDWARE_IRADIO_H + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/IMemory.h> +#include <binder/Parcel.h> +#include <system/radio.h> + +namespace android { + +class IRadio : public IInterface +{ +public: + +    DECLARE_META_INTERFACE(Radio); + +    virtual void detach() = 0; + +    virtual status_t setConfiguration(const struct radio_band_config *config) = 0; + +    virtual status_t getConfiguration(struct radio_band_config *config) = 0; + +    virtual status_t setMute(bool mute) = 0; + +    virtual status_t getMute(bool *mute) = 0; + +    virtual status_t step(radio_direction_t direction, bool skipSubChannel) = 0; + +    virtual status_t scan(radio_direction_t direction, bool skipSubChannel) = 0; + +    virtual status_t tune(unsigned int channel, unsigned int subChannel) = 0; + +    virtual status_t cancel() = 0; + +    virtual status_t getProgramInformation(struct radio_program_info *info) = 0; + +    virtual status_t hasControl(bool *hasControl) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnRadio: public BnInterface<IRadio> +{ +public: +    virtual status_t    onTransact( uint32_t code, +                                    const Parcel& data, +                                    Parcel* reply, +                                    uint32_t flags = 0); +}; + +}; // namespace android + +#endif //ANDROID_HARDWARE_IRADIO_H diff --git a/include/radio/IRadioClient.h b/include/radio/IRadioClient.h new file mode 100644 index 0000000..9062ad6 --- /dev/null +++ b/include/radio/IRadioClient.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_IRADIO_CLIENT_H +#define ANDROID_HARDWARE_IRADIO_CLIENT_H + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/IMemory.h> +#include <binder/Parcel.h> + +namespace android { + +class IRadioClient : public IInterface +{ +public: + +    DECLARE_META_INTERFACE(RadioClient); + +    virtual void onEvent(const sp<IMemory>& eventMemory) = 0; + +}; + +// ---------------------------------------------------------------------------- + +class BnRadioClient : public BnInterface<IRadioClient> +{ +public: +    virtual status_t    onTransact( uint32_t code, +                                    const Parcel& data, +                                    Parcel* reply, +                                    uint32_t flags = 0); +}; + +}; // namespace android + +#endif //ANDROID_HARDWARE_IRADIO_CLIENT_H diff --git a/include/radio/IRadioService.h b/include/radio/IRadioService.h new file mode 100644 index 0000000..a946dd5 --- /dev/null +++ b/include/radio/IRadioService.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_IRADIO_SERVICE_H +#define ANDROID_HARDWARE_IRADIO_SERVICE_H + +#include <utils/RefBase.h> +#include <binder/IInterface.h> +#include <binder/Parcel.h> +#include <system/radio.h> + +namespace android { + +class IRadio; +class IRadioClient; + +class IRadioService : public IInterface +{ +public: + +    DECLARE_META_INTERFACE(RadioService); + +    virtual status_t listModules(struct radio_properties *properties, +                                 uint32_t *numModules) = 0; + +    virtual status_t attach(const radio_handle_t handle, +                            const sp<IRadioClient>& client, +                            const struct radio_band_config *config, +                            bool withAudio, +                            sp<IRadio>& radio) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnRadioService: public BnInterface<IRadioService> +{ +public: +    virtual status_t    onTransact( uint32_t code, +                                    const Parcel& data, +                                    Parcel* reply, +                                    uint32_t flags = 0); +}; + +}; // namespace android + +#endif //ANDROID_HARDWARE_IRADIO_SERVICE_H diff --git a/include/radio/Radio.h b/include/radio/Radio.h new file mode 100644 index 0000000..302bf16 --- /dev/null +++ b/include/radio/Radio.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_RADIO_H +#define ANDROID_HARDWARE_RADIO_H + +#include <binder/IBinder.h> +#include <utils/threads.h> +#include <radio/RadioCallback.h> +#include <radio/IRadio.h> +#include <radio/IRadioService.h> +#include <radio/IRadioClient.h> +#include <system/radio.h> + +namespace android { + +class MemoryDealer; + +class Radio : public BnRadioClient, +                        public IBinder::DeathRecipient +{ +public: + +    virtual ~Radio(); + +    static  status_t listModules(struct radio_properties *properties, +                                 uint32_t *numModules); +    static  sp<Radio> attach(radio_handle_t handle, +                             const struct radio_band_config *config, +                             bool withAudio, +                             const sp<RadioCallback>& callback); + + +            void detach(); + +            status_t setConfiguration(const struct radio_band_config *config); + +            status_t getConfiguration(struct radio_band_config *config); + +            status_t setMute(bool mute); + +            status_t getMute(bool *mute); + +            status_t step(radio_direction_t direction, bool skipSubChannel); + +            status_t scan(radio_direction_t direction, bool skipSubChannel); + +            status_t tune(unsigned int channel, unsigned int subChannel); + +            status_t cancel(); + +            status_t getProgramInformation(struct radio_program_info *info); + +            status_t hasControl(bool *hasControl); + +            // BpRadioClient +            virtual void onEvent(const sp<IMemory>& eventMemory); + +            //IBinder::DeathRecipient +            virtual void binderDied(const wp<IBinder>& who); + +private: +            Radio(radio_handle_t handle, +                            const sp<RadioCallback>&); +            static const sp<IRadioService>& getRadioService(); + +            Mutex                   mLock; +            sp<IRadio>              mIRadio; +            const radio_handle_t    mHandle; +            sp<RadioCallback>       mCallback; +}; + +}; // namespace android + +#endif //ANDROID_HARDWARE_RADIO_H diff --git a/include/radio/RadioCallback.h b/include/radio/RadioCallback.h new file mode 100644 index 0000000..4a7f1a6 --- /dev/null +++ b/include/radio/RadioCallback.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_RADIO_CALLBACK_H +#define ANDROID_HARDWARE_RADIO_CALLBACK_H + +#include <utils/RefBase.h> +#include <system/radio.h> + +namespace android { + +class RadioCallback : public RefBase +{ +public: + +            RadioCallback() {} +    virtual ~RadioCallback() {} + +    virtual void onEvent(struct radio_event *event) = 0; + +}; + +}; // namespace android + +#endif //ANDROID_HARDWARE_RADIO_CALLBACK_H  | 
