diff options
490 files changed, 13965 insertions, 5443 deletions
diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp index 25d632d..e5e4e90 100644 --- a/camera/CameraParameters.cpp +++ b/camera/CameraParameters.cpp @@ -488,6 +488,11 @@ void CameraParameters::getSupportedPreviewFormats(Vector<int>& formats) const {      const char* supportedPreviewFormats =            get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS); +    if (supportedPreviewFormats == NULL) { +        ALOGW("%s: No supported preview formats.", __FUNCTION__); +        return; +    } +      String8 fmtStr(supportedPreviewFormats);      char* prevFmts = fmtStr.lockBuffer(fmtStr.size()); diff --git a/camera/VendorTagDescriptor.cpp b/camera/VendorTagDescriptor.cpp index 0dda6b6..dce313a 100644 --- a/camera/VendorTagDescriptor.cpp +++ b/camera/VendorTagDescriptor.cpp @@ -206,7 +206,7 @@ status_t VendorTagDescriptor::createFromParcel(const Parcel* parcel,          return res;      } -    size_t sectionCount; +    size_t sectionCount = 0;      if (tagCount > 0) {          if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(§ionCount))) != OK) {              ALOGE("%s: could not read section count for.", __FUNCTION__); diff --git a/camera/camera2/CaptureRequest.cpp b/camera/camera2/CaptureRequest.cpp index 57e5319..fb74c8d 100644 --- a/camera/camera2/CaptureRequest.cpp +++ b/camera/camera2/CaptureRequest.cpp @@ -63,9 +63,9 @@ status_t CaptureRequest::readFromParcel(Parcel* parcel) {          }          // Surface.writeToParcel -        String16 name = parcel->readString16(); -        ALOGV("%s: Read surface name = %s", -              __FUNCTION__, String8(name).string()); +        const char16_t* name = parcel->readString16Inplace(&len); +        ALOGV("%s: Read surface name = %s", __FUNCTION__, +            name != NULL ? String8(name).string() : "<null>");          sp<IBinder> binder(parcel->readStrongBinder());          ALOGV("%s: Read surface binder = %p",                __FUNCTION__, binder.get()); diff --git a/cmds/screenrecord/FrameOutput.cpp b/cmds/screenrecord/FrameOutput.cpp index 03e0062..bef74f5 100644 --- a/cmds/screenrecord/FrameOutput.cpp +++ b/cmds/screenrecord/FrameOutput.cpp @@ -206,7 +206,7 @@ void FrameOutput::reduceRgbaToRgb(uint8_t* buf, unsigned int pixelCount) {  }  // Callback; executes on arbitrary thread. -void FrameOutput::onFrameAvailable() { +void FrameOutput::onFrameAvailable(const BufferItem& /* item */) {      Mutex::Autolock _l(mMutex);      mFrameAvailable = true;      mEventCond.signal(); diff --git a/cmds/screenrecord/FrameOutput.h b/cmds/screenrecord/FrameOutput.h index c49ec3b..4c0c3be 100644 --- a/cmds/screenrecord/FrameOutput.h +++ b/cmds/screenrecord/FrameOutput.h @@ -62,7 +62,7 @@ private:      }      // (overrides GLConsumer::FrameAvailableListener method) -    virtual void onFrameAvailable(); +    virtual void onFrameAvailable(const BufferItem& item);      // Reduces RGBA to RGB, in place.      static void reduceRgbaToRgb(uint8_t* buf, unsigned int pixelCount); diff --git a/cmds/screenrecord/Overlay.cpp b/cmds/screenrecord/Overlay.cpp index 7fef53d..c659170 100644 --- a/cmds/screenrecord/Overlay.cpp +++ b/cmds/screenrecord/Overlay.cpp @@ -274,7 +274,7 @@ void Overlay::getTimeString_l(nsecs_t monotonicNsec, char* buf, size_t bufLen) {  }  // Callback; executes on arbitrary thread. -void Overlay::onFrameAvailable() { +void Overlay::onFrameAvailable(const BufferItem& /* item */) {      ALOGV("Overlay::onFrameAvailable");      Mutex::Autolock _l(mMutex);      mFrameAvailable = true; diff --git a/cmds/screenrecord/Overlay.h b/cmds/screenrecord/Overlay.h index b1b5c29..ee3444d 100644 --- a/cmds/screenrecord/Overlay.h +++ b/cmds/screenrecord/Overlay.h @@ -78,7 +78,7 @@ private:              const Program& texRender, TextRenderer& textRenderer);      // (overrides GLConsumer::FrameAvailableListener method) -    virtual void onFrameAvailable(); +    virtual void onFrameAvailable(const BufferItem& item);      // (overrides Thread method)      virtual bool threadLoop(); diff --git a/drm/mediadrm/plugins/clearkey/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/DrmPlugin.h index 27df9cd..6139f1f 100644 --- a/drm/mediadrm/plugins/clearkey/DrmPlugin.h +++ b/drm/mediadrm/plugins/clearkey/DrmPlugin.h @@ -113,11 +113,21 @@ public:          return android::ERROR_DRM_CANNOT_HANDLE;      } +    virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) { +        UNUSED(ssid); +        UNUSED(secureStop); +        return android::ERROR_DRM_CANNOT_HANDLE; +    } +      virtual status_t releaseSecureStops(const Vector<uint8_t>& ssRelease) {          UNUSED(ssRelease);          return android::ERROR_DRM_CANNOT_HANDLE;      } +    virtual status_t releaseAllSecureStops() { +        return android::ERROR_DRM_CANNOT_HANDLE; +    } +      virtual status_t getPropertyString(              const String8& name, String8& value) const; diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp index 2ea554b..7eac0a1 100644 --- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp +++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp @@ -305,6 +305,24 @@ namespace android {          return OK;      } +    status_t MockDrmPlugin::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::getSecureStop()"); + +        // Properties used in mock test, set by cts test app returned from mock plugin +        //   byte[] mock-secure-stop  -> first secure stop in list + +        ssize_t index = mByteArrayProperties.indexOfKey(String8("mock-secure-stop")); +        if (index < 0) { +            ALOGD("Missing 'mock-secure-stop' parameter for mock"); +            return BAD_VALUE; +        } else { +            secureStop = mByteArrayProperties.valueAt(index); +        } +        return OK; +    } +      status_t MockDrmPlugin::getSecureStops(List<Vector<uint8_t> > &secureStops)      {          Mutex::Autolock lock(mLock); @@ -349,6 +367,13 @@ namespace android {          return OK;      } +    status_t MockDrmPlugin::releaseAllSecureStops() +    { +        Mutex::Autolock lock(mLock); +        ALOGD("MockDrmPlugin::releaseAllSecureStops()"); +        return OK; +    } +      status_t MockDrmPlugin::getPropertyString(String8 const &name, String8 &value) const      {          ALOGD("MockDrmPlugin::getPropertyString(name=%s)", name.string()); diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h index 4b63299..d1d8058 100644 --- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h +++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h @@ -88,7 +88,9 @@ namespace android {          status_t unprovisionDevice();          status_t getSecureStops(List<Vector<uint8_t> > &secureStops); +        status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop);          status_t releaseSecureStops(Vector<uint8_t> const &ssRelease); +        status_t releaseAllSecureStops();          status_t getPropertyString(String8 const &name, String8 &value ) const;          status_t getPropertyByteArray(String8 const &name, diff --git a/include/camera/ProCamera.h b/include/camera/ProCamera.h index 83a3028..e9b687a 100644 --- a/include/camera/ProCamera.h +++ b/include/camera/ProCamera.h @@ -265,7 +265,7 @@ private:          }      protected: -        virtual void onFrameAvailable() { +        virtual void onFrameAvailable(const BufferItem& /* item */) {              sp<ProCamera> c = mCamera.promote();              if (c.get() != NULL) {                  c->onFrameAvailable(mStreamId); diff --git a/include/media/AudioPolicy.h b/include/media/AudioPolicy.h new file mode 100644 index 0000000..a755e1e --- /dev/null +++ b/include/media/AudioPolicy.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_AUDIO_POLICY_H +#define ANDROID_AUDIO_POLICY_H + +#include <system/audio.h> +#include <system/audio_policy.h> +#include <binder/Parcel.h> +#include <utils/String8.h> +#include <utils/Vector.h> + +namespace android { + +// Keep in sync with AudioMix.java, AudioMixingRule.java, AudioPolicyConfig.java +#define RULE_EXCLUSION_MASK 0x8000 +#define RULE_MATCH_ATTRIBUTE_USAGE 0x1 +#define RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET (0x1 << 1) +#define RULE_EXCLUDE_ATTRIBUTE_USAGE (RULE_EXCLUSION_MASK|RULE_MATCH_ATTRIBUTE_USAGE) +#define RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET \ +    (RULE_EXCLUSION_MASK|RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET) + +#define MIX_TYPE_INVALID -1 +#define MIX_TYPE_PLAYERS 0 +#define MIX_TYPE_RECORDERS 1 + +#define ROUTE_FLAG_RENDER 0x1 +#define ROUTE_FLAG_LOOP_BACK (0x1 << 1) + +#define MAX_MIXES_PER_POLICY 10 +#define MAX_CRITERIA_PER_MIX 20 + +class AttributeMatchCriterion { +public: +    AttributeMatchCriterion() {} +    AttributeMatchCriterion(audio_usage_t usage, audio_source_t source, uint32_t rule); + +    status_t readFromParcel(Parcel *parcel); +    status_t writeToParcel(Parcel *parcel) const; + +    union { +        audio_usage_t   mUsage; +        audio_source_t  mSource; +    } mAttr; +    uint32_t        mRule; +}; + +class AudioMix { +public: +    AudioMix() {} +    AudioMix(Vector<AttributeMatchCriterion> criteria, uint32_t mixType, audio_config_t format, +             uint32_t routeFlags, String8 registrationId) : +        mCriteria(criteria), mMixType(mixType), mFormat(format), +        mRouteFlags(routeFlags), mRegistrationId(registrationId) {} + +    status_t readFromParcel(Parcel *parcel); +    status_t writeToParcel(Parcel *parcel) const; + +    Vector<AttributeMatchCriterion> mCriteria; +    uint32_t        mMixType; +    audio_config_t  mFormat; +    uint32_t        mRouteFlags; +    String8         mRegistrationId; +}; + +}; // namespace android + +#endif  // ANDROID_AUDIO_POLICY_H diff --git a/include/media/AudioPolicyHelper.h b/include/media/AudioPolicyHelper.h index f4afd45..79231be 100644 --- a/include/media/AudioPolicyHelper.h +++ b/include/media/AudioPolicyHelper.h @@ -18,7 +18,7 @@  #include <system/audio.h> -audio_stream_type_t audio_attributes_to_stream_type(const audio_attributes_t *attr) +static audio_stream_type_t audio_attributes_to_stream_type(const audio_attributes_t *attr)  {      // flags to stream type mapping      if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) { @@ -61,4 +61,55 @@ audio_stream_type_t audio_attributes_to_stream_type(const audio_attributes_t *at      }  } +static void stream_type_to_audio_attributes(audio_stream_type_t streamType, +                                     audio_attributes_t *attr) { +    memset(attr, 0, sizeof(audio_attributes_t)); + +    switch (streamType) { +    case AUDIO_STREAM_DEFAULT: +    case AUDIO_STREAM_MUSIC: +        attr->content_type = AUDIO_CONTENT_TYPE_MUSIC; +        attr->usage = AUDIO_USAGE_MEDIA; +        break; +    case AUDIO_STREAM_VOICE_CALL: +        attr->content_type = AUDIO_CONTENT_TYPE_SPEECH; +        attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION; +        break; +    case AUDIO_STREAM_ENFORCED_AUDIBLE: +        attr->flags  |= AUDIO_FLAG_AUDIBILITY_ENFORCED; +        // intended fall through, attributes in common with STREAM_SYSTEM +    case AUDIO_STREAM_SYSTEM: +        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION; +        attr->usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION; +        break; +    case AUDIO_STREAM_RING: +        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION; +        attr->usage = AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE; +        break; +    case AUDIO_STREAM_ALARM: +        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION; +        attr->usage = AUDIO_USAGE_ALARM; +        break; +    case AUDIO_STREAM_NOTIFICATION: +        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION; +        attr->usage = AUDIO_USAGE_NOTIFICATION; +        break; +    case AUDIO_STREAM_BLUETOOTH_SCO: +        attr->content_type = AUDIO_CONTENT_TYPE_SPEECH; +        attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION; +        attr->flags |= AUDIO_FLAG_SCO; +        break; +    case AUDIO_STREAM_DTMF: +        attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION; +        attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING; +        break; +    case AUDIO_STREAM_TTS: +        attr->content_type = AUDIO_CONTENT_TYPE_SPEECH; +        attr->usage = AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY; +        break; +    default: +        ALOGE("invalid stream type %d when converting to attributes", streamType); +    } +} +  #endif //AUDIO_POLICY_HELPER_H_ diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index 4edc1bf..f70d981 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -152,6 +152,7 @@ public:       * transferType:       How data is transferred from AudioRecord.       * flags:              See comments on audio_input_flags_t in <system/audio.h>       * 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, @@ -164,7 +165,8 @@ public:                                      uint32_t notificationFrames = 0,                                      int sessionId = AUDIO_SESSION_ALLOCATE,                                      transfer_type transferType = TRANSFER_DEFAULT, -                                    audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE); +                                    audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE, +                                    const audio_attributes_t* pAttributes = NULL);      /* Terminates the AudioRecord and unregisters it from AudioFlinger.       * Also destroys all resources associated with the AudioRecord. @@ -198,7 +200,8 @@ public:                              bool threadCanCallJava = false,                              int sessionId = AUDIO_SESSION_ALLOCATE,                              transfer_type transferType = TRANSFER_DEFAULT, -                            audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE); +                            audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE, +                            const audio_attributes_t* pAttributes = NULL);      /* Result of constructing the AudioRecord. This must be checked for successful initialization       * before using any AudioRecord API (except for set()), because using @@ -219,7 +222,7 @@ public:              uint32_t    channelCount() const    { return mChannelCount; }              size_t      frameCount() const  { return mFrameCount; }              size_t      frameSize() const   { return mFrameSize; } -            audio_source_t inputSource() const  { return mInputSource; } +            audio_source_t inputSource() const  { return mAttributes.source; }      /* After it's created the track is not active. Call start() to       * make it active. If set, the callback will start being called. @@ -489,7 +492,6 @@ private:      audio_format_t          mFormat;      uint32_t                mChannelCount;      size_t                  mFrameSize;         // app-level frame size == AudioFlinger frame size -    audio_source_t          mInputSource;      uint32_t                mLatency;           // in ms      audio_channel_mask_t    mChannelMask;      audio_input_flags_t     mFlags; @@ -529,6 +531,7 @@ private:      sp<DeathNotifier>       mDeathNotifier;      uint32_t                mSequence;              // incremented for each new IAudioRecord attempt +    audio_attributes_t      mAttributes;  };  }; // namespace android diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index f8c0198..843a354 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -18,6 +18,7 @@  #define ANDROID_AUDIOSYSTEM_H_  #include <hardware/audio_effect.h> +#include <media/AudioPolicy.h>  #include <media/IAudioFlingerClient.h>  #include <media/IAudioPolicyServiceClient.h>  #include <system/audio.h> @@ -90,7 +91,7 @@ public:      static void setErrorCallback(audio_error_callback cb);      // helper function to obtain AudioFlinger service handle -    static const sp<IAudioFlinger>& get_audio_flinger(); +    static const sp<IAudioFlinger> get_audio_flinger();      static float linearToLog(int volume);      static int logToLinear(float volume); @@ -99,8 +100,6 @@ public:      // to be non-zero if status == NO_ERROR      static status_t getOutputSamplingRate(uint32_t* samplingRate,              audio_stream_type_t stream); -    static status_t getOutputSamplingRateForAttr(uint32_t* samplingRate, -                const audio_attributes_t *attr);      static status_t getOutputFrameCount(size_t* frameCount,              audio_stream_type_t stream);      static status_t getOutputLatency(uint32_t* latency, @@ -116,8 +115,6 @@ public:      static status_t getLatency(audio_io_handle_t output,                                 uint32_t* latency); -    static bool routedToA2dpOutput(audio_stream_type_t streamType); -      // return status NO_ERROR implies *buffSize > 0      static status_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,          audio_channel_mask_t channelMask, size_t* buffSize); @@ -219,7 +216,10 @@ public:                                          audio_channel_mask_t channelMask = AUDIO_CHANNEL_OUT_STEREO,                                          audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,                                          const audio_offload_info_t *offloadInfo = NULL); -    static audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr, +    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, @@ -227,20 +227,23 @@ public:                                          const audio_offload_info_t *offloadInfo = NULL);      static status_t startOutput(audio_io_handle_t output,                                  audio_stream_type_t stream, -                                int session); +                                audio_session_t session);      static status_t stopOutput(audio_io_handle_t output,                                 audio_stream_type_t stream, -                               int session); -    static void releaseOutput(audio_io_handle_t output); +                               audio_session_t session); +    static void releaseOutput(audio_io_handle_t output, +                              audio_stream_type_t stream, +                              audio_session_t session);      // Client must successfully hand off the handle reference to AudioFlinger via openRecord(),      // or release it with releaseInput(). -    static audio_io_handle_t getInput(audio_source_t inputSource, +    static 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, -                                    int sessionId, -                                    audio_input_flags_t); +                                    audio_input_flags_t flags);      static status_t startInput(audio_io_handle_t input,                                 audio_session_t session); @@ -274,7 +277,7 @@ public:      // and output configuration cache (gOutputs)      static void clearAudioConfigCache(); -    static const sp<IAudioPolicyService>& get_audio_policy_service(); +    static const sp<IAudioPolicyService> get_audio_policy_service();      // helpers for android.media.AudioManager.getProperty(), see description there for meaning      static uint32_t getPrimaryOutputSamplingRate(); @@ -322,6 +325,8 @@ public:      static audio_mode_t getPhoneState(); +    static status_t registerPolicyMixes(Vector<AudioMix> mixes, bool registration); +      // ----------------------------------------------------------------------------      class AudioPortCallback : public RefBase @@ -377,7 +382,11 @@ private:      friend class AudioFlingerClient;      friend class AudioPolicyServiceClient; -    static Mutex gLock; +    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; diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index b5256f0..fd51b8f 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -239,6 +239,9 @@ public:       * Parameters not listed in the AudioTrack constructors above:       *       * threadCanCallJava:  Whether callbacks are made from an attached thread and thus can call JNI. +     * +     * Internal state post condition: +     *      (mStreamType == AUDIO_STREAM_DEFAULT) implies this AudioTrack has valid attributes       */              status_t    set(audio_stream_type_t streamType,                              uint32_t sampleRate, @@ -273,7 +276,7 @@ public:      /* getters, see constructors and set() */ -            audio_stream_type_t streamType() const { return mStreamType; } +            audio_stream_type_t streamType() const;              audio_format_t format() const   { return mFormat; }      /* Return frame size in bytes, which for linear PCM is @@ -598,9 +601,6 @@ protected:              AudioTrack& operator = (const AudioTrack& other);              void        setAttributesFromStreamType(audio_stream_type_t streamType); -            void        setStreamTypeFromAttributes(audio_attributes_t& aa); -    /* paa is guaranteed non-NULL */ -            bool        isValidAttributes(const audio_attributes_t *paa);      /* a small internal class to handle the callback */      class AudioTrackThread : public Thread @@ -688,7 +688,8 @@ protected:      // constant after constructor or set()      audio_format_t          mFormat;                // as requested by client, not forced to 16-bit -    audio_stream_type_t     mStreamType; +    audio_stream_type_t     mStreamType;            // mStreamType == AUDIO_STREAM_DEFAULT implies +                                                    // this AudioTrack has valid attributes      uint32_t                mChannelCount;      audio_channel_mask_t    mChannelMask;      sp<IMemory>             mSharedBuffer; diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h index 16fe9cf..c98c475 100644 --- a/include/media/IAudioPolicyService.h +++ b/include/media/IAudioPolicyService.h @@ -25,6 +25,7 @@  #include <utils/Errors.h>  #include <binder/IInterface.h>  #include <media/AudioSystem.h> +#include <media/AudioPolicy.h>  #include <media/IAudioPolicyServiceClient.h>  #include <system/audio_policy.h> @@ -56,25 +57,31 @@ public:                                          audio_channel_mask_t channelMask = 0,                                          audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,                                          const audio_offload_info_t *offloadInfo = NULL) = 0; -    virtual audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr, -                                            uint32_t samplingRate = 0, -                                            audio_format_t format = AUDIO_FORMAT_DEFAULT, -                                            audio_channel_mask_t channelMask = 0, -                                            audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, -                                            const audio_offload_info_t *offloadInfo = NULL) = 0; +    virtual status_t 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 = 0, +                                        audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, +                                        const audio_offload_info_t *offloadInfo = NULL) = 0;      virtual status_t startOutput(audio_io_handle_t output,                                   audio_stream_type_t stream, -                                 int session = 0) = 0; +                                 audio_session_t session) = 0;      virtual status_t stopOutput(audio_io_handle_t output,                                  audio_stream_type_t stream, -                                int session = 0) = 0; -    virtual void releaseOutput(audio_io_handle_t output) = 0; -    virtual audio_io_handle_t getInput(audio_source_t inputSource, -                                    uint32_t samplingRate, -                                    audio_format_t format, -                                    audio_channel_mask_t channelMask, -                                    int audioSession, -                                    audio_input_flags_t flags) = 0; +                                audio_session_t session) = 0; +    virtual void releaseOutput(audio_io_handle_t output, +                               audio_stream_type_t stream, +                               audio_session_t session) = 0; +    virtual status_t  getInputForAttr(const audio_attributes_t *attr, +                                      audio_io_handle_t *input, +                                      audio_session_t session, +                                      uint32_t samplingRate, +                                      audio_format_t format, +                                      audio_channel_mask_t channelMask, +                                      audio_input_flags_t flags) = 0;      virtual status_t startInput(audio_io_handle_t input,                                  audio_session_t session) = 0;      virtual status_t stopInput(audio_io_handle_t input, @@ -144,6 +151,8 @@ public:      virtual status_t releaseSoundTriggerSession(audio_session_t session) = 0;      virtual audio_mode_t getPhoneState() = 0; + +    virtual status_t registerPolicyMixes(Vector<AudioMix> mixes, bool registration) = 0;  }; diff --git a/include/media/ICrypto.h b/include/media/ICrypto.h index 9dcb8d9..07742ca 100644 --- a/include/media/ICrypto.h +++ b/include/media/ICrypto.h @@ -41,6 +41,8 @@ struct ICrypto : public IInterface {      virtual bool requiresSecureDecoderComponent(              const char *mime) const = 0; +    virtual void notifyResolution(uint32_t width, uint32_t height) = 0; +      virtual ssize_t decrypt(              bool secure,              const uint8_t key[16], @@ -64,4 +66,3 @@ struct BnCrypto : public BnInterface<ICrypto> {  }  // namespace android  #endif // ANDROID_ICRYPTO_H_ - diff --git a/include/media/IDrm.h b/include/media/IDrm.h index 68de87a..affcbd7 100644 --- a/include/media/IDrm.h +++ b/include/media/IDrm.h @@ -73,8 +73,10 @@ struct IDrm : public IInterface {      virtual status_t unprovisionDevice() = 0;      virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0; +    virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) = 0;      virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0; +    virtual status_t releaseAllSecureStops() = 0;      virtual status_t getPropertyString(String8 const &name, String8 &value) const = 0;      virtual status_t getPropertyByteArray(String8 const &name, @@ -137,4 +139,3 @@ private:  }  // namespace android  #endif // ANDROID_IDRM_H_ - diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index cf18a45..c412299 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -208,8 +208,15 @@ public:      void        sendEvent(int msg, int ext1=0, int ext2=0,                            const Parcel *obj=NULL) { -        Mutex::Autolock autoLock(mNotifyLock); -        if (mNotify) mNotify(mCookie, msg, ext1, ext2, obj); +        notify_callback_f notifyCB; +        void* cookie; +        { +            Mutex::Autolock autoLock(mNotifyLock); +            notifyCB = mNotify; +            cookie = mCookie; +        } + +        if (notifyCB) notifyCB(cookie, msg, ext1, ext2, obj);      }      virtual status_t dump(int fd, const Vector<String16> &args) const { diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index a0e5d84..29c9002 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -78,7 +78,7 @@ struct ACodec : public AHierarchicalStateMachine, public CodecBase {      static bool isFlexibleColorFormat(              const sp<IOMX> &omx, IOMX::node_id node, -            uint32_t colorFormat, OMX_U32 *flexibleEquivalent); +            uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent);      // Returns 0 if configuration is not supported.  NOTE: this is treated by      // some OMX components as auto level, and by others as invalid level. @@ -131,6 +131,7 @@ private:      enum {          kFlagIsSecure                                 = 1,          kFlagPushBlankBuffersToNativeWindowOnShutdown = 2, +        kFlagIsGrallocUsageProtected                  = 4,      };      struct BufferInfo { @@ -182,6 +183,7 @@ private:      sp<ANativeWindow> mNativeWindow;      sp<AMessage> mInputFormat;      sp<AMessage> mOutputFormat; +    sp<AMessage> mBaseOutputFormat;      Vector<BufferInfo> mBuffers[2];      bool mPortEOS[2]; @@ -250,12 +252,13 @@ private:      status_t setVideoPortFormatType(              OMX_U32 portIndex,              OMX_VIDEO_CODINGTYPE compressionFormat, -            OMX_COLOR_FORMATTYPE colorFormat); +            OMX_COLOR_FORMATTYPE colorFormat, +            bool usingNativeBuffers = false); -    status_t setSupportedOutputFormat(); +    status_t setSupportedOutputFormat(bool getLegacyFlexibleFormat);      status_t setupVideoDecoder( -            const char *mime, const sp<AMessage> &msg); +            const char *mime, const sp<AMessage> &msg, bool usingNativeBuffers);      status_t setupVideoEncoder(              const char *mime, const sp<AMessage> &msg); @@ -263,7 +266,7 @@ private:      status_t setVideoFormatOnPort(              OMX_U32 portIndex,              int32_t width, int32_t height, -            OMX_VIDEO_CODINGTYPE compressionFormat); +            OMX_VIDEO_CODINGTYPE compressionFormat, float frameRate = -1.0);      typedef struct drcParams {          int32_t drcCut; @@ -282,6 +285,8 @@ private:      status_t setupAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate); +    status_t setupEAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate); +      status_t selectAudioPortFormat(              OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat); diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h index 54a4e8b..d448097 100644 --- a/include/media/stagefright/MediaCodec.h +++ b/include/media/stagefright/MediaCodec.h @@ -194,7 +194,7 @@ private:      };      enum { -        kFlagIsSoftwareCodec            = 1, +        kFlagUsesSoftwareRenderer       = 1,          kFlagOutputFormatChanged        = 2,          kFlagOutputBuffersChanged       = 4,          kFlagStickyError                = 8, diff --git a/include/media/stagefright/MediaCodecList.h b/include/media/stagefright/MediaCodecList.h index 8605d99..c2bbe4d 100644 --- a/include/media/stagefright/MediaCodecList.h +++ b/include/media/stagefright/MediaCodecList.h @@ -52,6 +52,12 @@ struct MediaCodecList : public BnMediaCodecList {      static sp<IMediaCodecList> getLocalInstance();  private: +    class BinderDeathObserver : public IBinder::DeathRecipient { +        void binderDied(const wp<IBinder> &the_late_who __unused); +    }; + +    static sp<BinderDeathObserver> sBinderDeathObserver; +      enum Section {          SECTION_TOPLEVEL,          SECTION_DECODERS, diff --git a/include/media/stagefright/MediaCodecSource.h b/include/media/stagefright/MediaCodecSource.h index 3629c8b..0970b2b 100644 --- a/include/media/stagefright/MediaCodecSource.h +++ b/include/media/stagefright/MediaCodecSource.h @@ -85,8 +85,6 @@ private:      status_t initEncoder();      void releaseEncoder();      status_t feedEncoderInputBuffers(); -    void scheduleDoMoreWork(); -    status_t doMoreWork(int32_t numInput, int32_t numOutput);      void suspend();      void resume(int64_t skipFramesBeforeUs = -1ll);      void signalEOS(status_t err = ERROR_END_OF_STREAM); @@ -108,8 +106,6 @@ private:      bool mDoMoreWorkPending;      sp<AMessage> mEncoderActivityNotify;      sp<IGraphicBufferProducer> mGraphicBufferProducer; -    Vector<sp<ABuffer> > mEncoderInputBuffers; -    Vector<sp<ABuffer> > mEncoderOutputBuffers;      List<MediaBuffer *> mInputBufferQueue;      List<size_t> mAvailEncoderInputIndices;      List<int64_t> mDecodingTimeQueue; // decoding time (us) for video diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h index e67d4d5..13695d5 100644 --- a/include/media/stagefright/MediaDefs.h +++ b/include/media/stagefright/MediaDefs.h @@ -47,6 +47,7 @@ extern const char *MEDIA_MIMETYPE_AUDIO_FLAC;  extern const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS;  extern const char *MEDIA_MIMETYPE_AUDIO_MSGSM;  extern const char *MEDIA_MIMETYPE_AUDIO_AC3; +extern const char *MEDIA_MIMETYPE_AUDIO_EAC3;  extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;  extern const char *MEDIA_MIMETYPE_CONTAINER_WAV; diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h index 43b75fd..d15a226 100644 --- a/include/media/stagefright/SurfaceMediaSource.h +++ b/include/media/stagefright/SurfaceMediaSource.h @@ -124,7 +124,7 @@ protected:      // Implementation of the BufferQueue::ConsumerListener interface.  These      // calls are used to notify the Surface of asynchronous events in the      // BufferQueue. -    virtual void onFrameAvailable(); +    virtual void onFrameAvailable(const BufferItem& item);      // Used as a hook to BufferQueue::disconnect()      // This is called by the client side when it is done diff --git a/include/media/stagefright/foundation/ADebug.h b/include/media/stagefright/foundation/ADebug.h index 450dcfe..1d0e2cb 100644 --- a/include/media/stagefright/foundation/ADebug.h +++ b/include/media/stagefright/foundation/ADebug.h @@ -80,6 +80,36 @@ MAKE_COMPARATOR(GT,>)              __FILE__ ":" LITERAL_TO_STRING(__LINE__)            \                  " Should not be here."); +struct ADebug { +    enum Level { +        kDebugNone,             // no debug +        kDebugLifeCycle,        // lifecycle events: creation/deletion +        kDebugState,            // commands and events +        kDebugConfig,           // configuration +        kDebugInternalState,    // internal state changes +        kDebugAll,              // all +        kDebugMax = kDebugAll, + +    }; + +    // parse the property or string to get the debug level for a component name +    // string format is: +    // <level>[:<glob>][,<level>[:<glob>]...] +    // - <level> is 0-5 corresponding to ADebug::Level +    // - <glob> is used to match component name case insensitively, if omitted, it +    //   matches all components +    // - string is read left-to-right, and the last matching level is returned, or +    //   the def if no terms matched +    static 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); +}; +  }  // namespace android  #endif  // A_DEBUG_H_ diff --git a/include/media/stagefright/foundation/AStringUtils.h b/include/media/stagefright/foundation/AStringUtils.h new file mode 100644 index 0000000..76a7791 --- /dev/null +++ b/include/media/stagefright/foundation/AStringUtils.h @@ -0,0 +1,36 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef A_STRING_UTILS_H_ +#define A_STRING_UTILS_H_ + +#include <stdlib.h> + +namespace android { + +struct AStringUtils { +    // similar to strncmp or strcasecmp, but case sensitivity is parametric +    static int Compare(const char *a, const char *b, size_t len, bool ignoreCase); + +    // matches a string (str) to a glob pattern that supports: +    //    * - matches any number of characters +    static bool MatchesGlob( +            const char *glob, size_t globLen, const char *str, size_t strLen, bool ignoreCase); +}; + +}  // namespace android + +#endif  // A_STRING_UTILS_H_ diff --git a/include/media/stagefright/foundation/AUtils.h b/include/media/stagefright/foundation/AUtils.h index 255bcbe..47444c1 100644 --- a/include/media/stagefright/foundation/AUtils.h +++ b/include/media/stagefright/foundation/AUtils.h @@ -40,6 +40,12 @@ inline static const T divUp(const T &nom, const T &den) {      }  } +/* == ceil(nom / den) * den. T must be integer type, alignment must be positive power of 2 */ +template<class T, class U> +inline static const T align(const T &nom, const U &den) { +    return (nom + (T)(den - 1)) & (T)~(den - 1); +} +  template<class T>  inline static T abs(const T &a) {      return a < 0 ? -a : a; diff --git a/include/media/stagefright/foundation/AWakeLock.h b/include/media/stagefright/foundation/AWakeLock.h new file mode 100644 index 0000000..57716c1 --- /dev/null +++ b/include/media/stagefright/foundation/AWakeLock.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef A_WAKELOCK_H_ +#define A_WAKELOCK_H_ + +#include <media/stagefright/foundation/ABase.h> +#include <powermanager/IPowerManager.h> +#include <utils/RefBase.h> + +namespace android { + +class AWakeLock : public RefBase { + +public: +    AWakeLock(); + +    // NOTE: acquire and release are not thread safe + +    // returns true if wakelock was acquired +    bool acquire(); +    void release(bool force = false); + +    virtual ~AWakeLock(); + +private: +    sp<IPowerManager> mPowerManager; +    sp<IBinder>       mWakeLockToken; +    uint32_t          mWakeLockCount; + +    class PMDeathRecipient : public IBinder::DeathRecipient { +    public: +        PMDeathRecipient(AWakeLock *wakeLock) : mWakeLock(wakeLock) {} +        virtual ~PMDeathRecipient() {} + +        // IBinder::DeathRecipient +        virtual void binderDied(const wp<IBinder> &who); + +    private: +        PMDeathRecipient(const PMDeathRecipient&); +        PMDeathRecipient& operator= (const PMDeathRecipient&); + +        AWakeLock *mWakeLock; +    }; + +    const sp<PMDeathRecipient> mDeathRecipient; + +    void clearPowerManager(); + +    DISALLOW_EVIL_CONSTRUCTORS(AWakeLock); +}; + +}  // namespace android + +#endif  // A_WAKELOCK_H_ diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h index fa1b20a..31dff36 100644 --- a/include/private/media/AudioTrackShared.h +++ b/include/private/media/AudioTrackShared.h @@ -450,7 +450,14 @@ private:      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 -    size_t              mEnd;       // cached value computed from mState, safe for asynchronous read + +    size_t              mFramesReadySafe; // Assuming size_t read/writes are atomic on 32 / 64 bit +                                          // processors, this is a thread-safe version of +                                          // mFramesReady. +    int64_t             mFramesReady;     // The number of frames ready in the static buffer +                                          // including loops.  This is 64 bits since loop mode +                                          // can cause a track to appear to have a large number +                                          // of frames. INT64_MAX means an infinite loop.      bool                mFramesReadyIsCalledByMultipleThreads;      StaticAudioTrackState   mState;  }; diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp index aa41252..40c7fef 100644 --- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp +++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp @@ -766,6 +766,122 @@ int LvmBundle_process(LVM_INT16        *pIn,      return 0;  }    /* end LvmBundle_process */ + +//---------------------------------------------------------------------------- +// EqualizerUpdateActiveParams() +//---------------------------------------------------------------------------- +// Purpose: Update ActiveParams for Equalizer +// +// Inputs: +//  pContext:   effect engine context +// +// Outputs: +// +//---------------------------------------------------------------------------- +void EqualizerUpdateActiveParams(EffectContext *pContext) { +    LVM_ControlParams_t     ActiveParams;              /* Current control Parameters */ +    LVM_ReturnStatus_en     LvmStatus=LVM_SUCCESS;     /* Function call status */ + +    /* Get the current settings */ +    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams); +    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "EqualizerUpdateActiveParams") +    //ALOGV("\tEqualizerUpdateActiveParams Succesfully returned from LVM_GetControlParameters\n"); +    //ALOGV("\tEqualizerUpdateActiveParams just Got -> %d\n", +    //          ActiveParams.pEQNB_BandDefinition[band].Gain); + + +    for (int i = 0; i < FIVEBAND_NUMBANDS; i++) { +           ActiveParams.pEQNB_BandDefinition[i].Frequency = EQNB_5BandPresetsFrequencies[i]; +           ActiveParams.pEQNB_BandDefinition[i].QFactor   = EQNB_5BandPresetsQFactors[i]; +           ActiveParams.pEQNB_BandDefinition[i].Gain = pContext->pBundledContext->bandGaindB[i]; +       } + +    /* Activate the initial settings */ +    LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams); +    LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "EqualizerUpdateActiveParams") +    //ALOGV("\tEqualizerUpdateActiveParams just Set -> %d\n", +    //          ActiveParams.pEQNB_BandDefinition[band].Gain); + +} + +//---------------------------------------------------------------------------- +// LvmEffect_limitLevel() +//---------------------------------------------------------------------------- +// Purpose: limit the overall level to a value less than 0 dB preserving +//          the overall EQ band gain and BassBoost relative levels. +// +// Inputs: +//  pContext:   effect engine context +// +// Outputs: +// +//---------------------------------------------------------------------------- +void LvmEffect_limitLevel(EffectContext *pContext) { +    LVM_ControlParams_t     ActiveParams;              /* Current control Parameters */ +    LVM_ReturnStatus_en     LvmStatus=LVM_SUCCESS;     /* Function call status */ + +    /* Get the current settings */ +    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams); +    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "LvmEffect_limitLevel") +    //ALOGV("\tLvmEffect_limitLevel Succesfully returned from LVM_GetControlParameters\n"); +    //ALOGV("\tLvmEffect_limitLevel just Got -> %d\n", +    //          ActiveParams.pEQNB_BandDefinition[band].Gain); + +    int gainCorrection = 0; +    //Count the energy contribution per band for EQ and BassBoost only if they are active. +    float energyContribution = 0; + +    //EQ contribution +    if (pContext->pBundledContext->bEqualizerEnabled == LVM_TRUE) { +        for (int i = 0; i < FIVEBAND_NUMBANDS; i++) { +            float bandEnergy = (pContext->pBundledContext->bandGaindB[i] * +                    LimitLevel_bandEnergyContribution[i])/15.0; +            if (bandEnergy > 0) +                energyContribution += bandEnergy; +        } +    } + +    //BassBoost contribution +    if (pContext->pBundledContext->bBassEnabled == LVM_TRUE) { +        float bandEnergy = (pContext->pBundledContext->BassStrengthSaved * +                LimitLevel_bassBoostEnergyContribution)/1000.0; +        if (bandEnergy > 0) +            energyContribution += bandEnergy; +    } + +    //Virtualizer contribution +    if (pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE) { +                   energyContribution += LimitLevel_virtualizerContribution; +        } + +    //roundoff +    int maxLevelRound = (int)(energyContribution + 0.99); +    if (maxLevelRound + pContext->pBundledContext->volume > 0) { +        gainCorrection = maxLevelRound + pContext->pBundledContext->volume; +    } + +    ActiveParams.VC_EffectLevel  = pContext->pBundledContext->volume - gainCorrection; +    if (ActiveParams.VC_EffectLevel < -96) { +        ActiveParams.VC_EffectLevel = -96; +    } +    ALOGV("\tVol:%d, GainCorrection: %d, Actual vol: %d", pContext->pBundledContext->volume, +            gainCorrection, ActiveParams.VC_EffectLevel); + +    /* Activate the initial settings */ +    LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams); +    LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "LvmEffect_limitLevel") +    //ALOGV("\tLvmEffect_limitLevel just Set -> %d\n", +    //          ActiveParams.pEQNB_BandDefinition[band].Gain); + +    //ALOGV("\tLvmEffect_limitLevel just set (-96dB -> 0dB) -> %d\n",ActiveParams.VC_EffectLevel ); +    if (pContext->pBundledContext->firstVolume == LVM_TRUE){ +        LvmStatus = LVM_SetVolumeNoSmoothing(pContext->pBundledContext->hInstance, &ActiveParams); +        LVM_ERROR_CHECK(LvmStatus, "LVM_SetVolumeNoSmoothing", "LvmBundle_process") +        ALOGV("\tLVM_VOLUME: Disabling Smoothing for first volume change to remove spikes/clicks"); +        pContext->pBundledContext->firstVolume = LVM_FALSE; +    } +} +  //----------------------------------------------------------------------------  // LvmEffect_enable()  //---------------------------------------------------------------------------- @@ -814,6 +930,7 @@ int LvmEffect_enable(EffectContext *pContext){      //ALOGV("\tLvmEffect_enable Succesfully called LVM_SetControlParameters\n");      //ALOGV("\tLvmEffect_enable end"); +    LvmEffect_limitLevel(pContext);      return 0;  } @@ -864,6 +981,7 @@ int LvmEffect_disable(EffectContext *pContext){      //ALOGV("\tLvmEffect_disable Succesfully called LVM_SetControlParameters\n");      //ALOGV("\tLvmEffect_disable end"); +    LvmEffect_limitLevel(pContext);      return 0;  } @@ -1099,6 +1217,8 @@ void BassSetStrength(EffectContext *pContext, uint32_t strength){      LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "BassSetStrength")      //ALOGV("\tBassSetStrength Succesfully called LVM_SetControlParameters\n"); + +    LvmEffect_limitLevel(pContext);  }    /* end BassSetStrength */  //---------------------------------------------------------------------------- @@ -1159,13 +1279,14 @@ void VirtualizerSetStrength(EffectContext *pContext, uint32_t strength){      /* Virtualizer parameters */      ActiveParams.CS_EffectLevel             = (int)((strength*32767)/1000); -    //ALOGV("\tVirtualizerSetStrength() (0-1000)   -> %d\n", strength ); -    //ALOGV("\tVirtualizerSetStrength() (0- 100)   -> %d\n", ActiveParams.CS_EffectLevel ); +    ALOGV("\tVirtualizerSetStrength() (0-1000)   -> %d\n", strength ); +    ALOGV("\tVirtualizerSetStrength() (0- 100)   -> %d\n", ActiveParams.CS_EffectLevel );      /* Activate the initial settings */      LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);      LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "VirtualizerSetStrength")      //ALOGV("\tVirtualizerSetStrength Succesfully called LVM_SetControlParameters\n\n"); +    LvmEffect_limitLevel(pContext);  }    /* end setStrength */  //---------------------------------------------------------------------------- @@ -1236,10 +1357,12 @@ int VirtualizerForceVirtualizationMode(EffectContext *pContext, audio_devices_t      bool useVirtualizer = false;      if (VirtualizerIsDeviceSupported(forcedDevice) != 0) { -        // forced device is not supported, make it behave as a reset of forced mode -        forcedDevice = AUDIO_DEVICE_NONE; -        // but return an error -        status = -EINVAL; +        if (forcedDevice != AUDIO_DEVICE_NONE) { +            //forced device is not supported, make it behave as a reset of forced mode +            forcedDevice = AUDIO_DEVICE_NONE; +            // but return an error +            status = -EINVAL; +        }      }      if (forcedDevice == AUDIO_DEVICE_NONE) { @@ -1341,104 +1464,6 @@ audio_devices_t VirtualizerGetVirtualizationMode(EffectContext *pContext) {  }  //---------------------------------------------------------------------------- -// EqualizerLimitBandLevels() -//---------------------------------------------------------------------------- -// Purpose: limit all EQ band gains to a value less than 0 dB while -//          preserving the relative band levels. -// -// Inputs: -//  pContext:   effect engine context -// -// Outputs: -// -//---------------------------------------------------------------------------- -void EqualizerLimitBandLevels(EffectContext *pContext) { -    LVM_ControlParams_t     ActiveParams;              /* Current control Parameters */ -    LVM_ReturnStatus_en     LvmStatus=LVM_SUCCESS;     /* Function call status */ - -    /* Get the current settings */ -    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams); -    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "EqualizerLimitBandLevels") -    //ALOGV("\tEqualizerLimitBandLevels Succesfully returned from LVM_GetControlParameters\n"); -    //ALOGV("\tEqualizerLimitBandLevels just Got -> %d\n", -    //          ActiveParams.pEQNB_BandDefinition[band].Gain); - -    // Apply a volume correction to avoid clipping in the EQ based on 2 factors: -    // - the maximum EQ band gain: the volume correction is such that the total of volume + max -    // band gain is <= 0 dB -    // - the average gain in all bands weighted by their proximity to max gain band. -    int maxGain = 0; -    int avgGain = 0; -    int avgCount = 0; -    for (int i = 0; i < FIVEBAND_NUMBANDS; i++) { -        if (pContext->pBundledContext->bandGaindB[i] >= maxGain) { -            int tmpMaxGain = pContext->pBundledContext->bandGaindB[i]; -            int tmpAvgGain = 0; -            int tmpAvgCount = 0; -            for (int j = 0; j < FIVEBAND_NUMBANDS; j++) { -                int gain = pContext->pBundledContext->bandGaindB[j]; -                // skip current band and gains < 0 dB -                if (j == i || gain < 0) -                    continue; -                // no need to continue if one band not processed yet has a higher gain than current -                // max -                if (gain > tmpMaxGain) { -                    // force skipping "if (tmpAvgGain >= avgGain)" below as tmpAvgGain is not -                    // meaningful in this case -                    tmpAvgGain = -1; -                    break; -                } - -                int weight = 1; -                if (j < (i + 2) && j > (i - 2)) -                    weight = 4; -                tmpAvgGain += weight * gain; -                tmpAvgCount += weight; -            } -            if (tmpAvgGain >= avgGain) { -                maxGain = tmpMaxGain; -                avgGain = tmpAvgGain; -                avgCount = tmpAvgCount; -            } -        } -        ActiveParams.pEQNB_BandDefinition[i].Frequency = EQNB_5BandPresetsFrequencies[i]; -        ActiveParams.pEQNB_BandDefinition[i].QFactor   = EQNB_5BandPresetsQFactors[i]; -        ActiveParams.pEQNB_BandDefinition[i].Gain = pContext->pBundledContext->bandGaindB[i]; -    } - -    int gainCorrection = 0; -    if (maxGain + pContext->pBundledContext->volume > 0) { -        gainCorrection = maxGain + pContext->pBundledContext->volume; -    } -    if (avgCount) { -        gainCorrection += avgGain/avgCount; -    } - -    ALOGV("EqualizerLimitBandLevels() gainCorrection %d maxGain %d avgGain %d avgCount %d", -            gainCorrection, maxGain, avgGain, avgCount); - -    ActiveParams.VC_EffectLevel  = pContext->pBundledContext->volume - gainCorrection; -    if (ActiveParams.VC_EffectLevel < -96) { -        ActiveParams.VC_EffectLevel = -96; -    } - -    /* Activate the initial settings */ -    LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams); -    LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "EqualizerLimitBandLevels") -    //ALOGV("\tEqualizerLimitBandLevels just Set -> %d\n", -    //          ActiveParams.pEQNB_BandDefinition[band].Gain); - -    //ALOGV("\tEqualizerLimitBandLevels just set (-96dB -> 0dB)   -> %d\n",ActiveParams.VC_EffectLevel ); -    if(pContext->pBundledContext->firstVolume == LVM_TRUE){ -        LvmStatus = LVM_SetVolumeNoSmoothing(pContext->pBundledContext->hInstance, &ActiveParams); -        LVM_ERROR_CHECK(LvmStatus, "LVM_SetVolumeNoSmoothing", "LvmBundle_process") -        ALOGV("\tLVM_VOLUME: Disabling Smoothing for first volume change to remove spikes/clicks"); -        pContext->pBundledContext->firstVolume = LVM_FALSE; -    } -} - - -//----------------------------------------------------------------------------  // EqualizerGetBandLevel()  //----------------------------------------------------------------------------  // Purpose: Retrieve the gain currently being used for the band passed in @@ -1480,7 +1505,8 @@ void EqualizerSetBandLevel(EffectContext *pContext, int band, short Gain){      pContext->pBundledContext->bandGaindB[band] = gainRounded;      pContext->pBundledContext->CurPreset = PRESET_CUSTOM; -    EqualizerLimitBandLevels(pContext); +    EqualizerUpdateActiveParams(pContext); +    LvmEffect_limitLevel(pContext);  }  //---------------------------------------------------------------------------- @@ -1615,7 +1641,8 @@ void EqualizerSetPreset(EffectContext *pContext, int preset){                  EQNB_5BandSoftPresets[i + preset * FIVEBAND_NUMBANDS];      } -    EqualizerLimitBandLevels(pContext); +    EqualizerUpdateActiveParams(pContext); +    LvmEffect_limitLevel(pContext);      //ALOGV("\tEqualizerSetPreset Succesfully called LVM_SetControlParameters\n");      return; @@ -1670,7 +1697,7 @@ int VolumeSetVolumeLevel(EffectContext *pContext, int16_t level){          pContext->pBundledContext->volume = level / 100;      } -    EqualizerLimitBandLevels(pContext); +    LvmEffect_limitLevel(pContext);      return 0;  }    /* end VolumeSetVolumeLevel */ @@ -1719,7 +1746,7 @@ int32_t VolumeSetMute(EffectContext *pContext, uint32_t mute){          pContext->pBundledContext->volume = pContext->pBundledContext->levelSaved;      } -    EqualizerLimitBandLevels(pContext); +    LvmEffect_limitLevel(pContext);      return 0;  }    /* end setMute */ diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h index 420f973..b3071f4 100644 --- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h +++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h @@ -142,6 +142,7 @@ static const uint32_t bandFreqRange[FIVEBAND_NUMBANDS][2] = {                                         {1800001, 7000000},                                         {7000001, 1}}; +//Note: If these frequencies change, please update LimitLevel values accordingly.  static const LVM_UINT16  EQNB_5BandPresetsFrequencies[] = {                                         60,           /* Frequencies in Hz */                                         230, @@ -192,6 +193,20 @@ static const PresetConfig gEqualizerPresets[] = {                                          {"Pop"},                                          {"Rock"}}; +/* The following tables have been computed using the actual levels measured by the output of + * white noise or pink noise (IEC268-1) for the EQ and BassBoost Effects. These are estimates of + * the actual energy that 'could' be present in the given band. + * If the frequency values in EQNB_5BandPresetsFrequencies change, these values might need to be + * updated. + */ + +static const float LimitLevel_bandEnergyContribution[FIVEBAND_NUMBANDS] = { +        5.0, 6.5, 6.45, 4.8, 1.7 }; + +static const float LimitLevel_bassBoostEnergyContribution = 6.7; + +static const float LimitLevel_virtualizerContribution = 1.9; +  #if __cplusplus  }  // extern "C"  #endif diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index e012116..a2e0909 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -59,7 +59,8 @@ LOCAL_SRC_FILES:= \      MemoryLeakTrackUtil.cpp \      SoundPool.cpp \      SoundPoolThread.cpp \ -    StringArray.cpp +    StringArray.cpp \ +    AudioPolicy.cpp  LOCAL_SRC_FILES += ../libnbaio/roundup.c diff --git a/media/libmedia/AudioPolicy.cpp b/media/libmedia/AudioPolicy.cpp new file mode 100644 index 0000000..d2d0971 --- /dev/null +++ b/media/libmedia/AudioPolicy.cpp @@ -0,0 +1,115 @@ +/* + * 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. + */ + +#define LOG_TAG "AudioPolicy" +//#define LOG_NDEBUG 0 +#include <utils/Log.h> +#include <media/AudioPolicy.h> + +namespace android { + +// +//  AttributeMatchCriterion implementation +// +AttributeMatchCriterion::AttributeMatchCriterion(audio_usage_t usage, +                                                 audio_source_t source, +                                                 uint32_t rule) +: mRule(rule) +{ +    if (mRule == RULE_MATCH_ATTRIBUTE_USAGE || +            mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) { +        mAttr.mUsage = usage; +    } else { +        mAttr.mSource = source; +    } +} + +status_t AttributeMatchCriterion::readFromParcel(Parcel *parcel) +{ +    mRule = parcel->readInt32(); +    if (mRule == RULE_MATCH_ATTRIBUTE_USAGE || +            mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) { +        mAttr.mUsage = (audio_usage_t)parcel->readInt32(); +    } else { +        mAttr.mSource = (audio_source_t)parcel->readInt32(); +    } +    return NO_ERROR; +} + +status_t AttributeMatchCriterion::writeToParcel(Parcel *parcel) const +{ +    parcel->writeInt32(mRule); +    parcel->writeInt32(mAttr.mUsage); +    return NO_ERROR; +} + +// +//  AudioMix implementation +// + +status_t AudioMix::readFromParcel(Parcel *parcel) +{ +    mMixType = parcel->readInt32(); +    mFormat.sample_rate = (uint32_t)parcel->readInt32(); +    mFormat.channel_mask = (audio_channel_mask_t)parcel->readInt32(); +    mFormat.format = (audio_format_t)parcel->readInt32(); +    mRouteFlags = parcel->readInt32(); +    mRegistrationId = parcel->readString8(); +    size_t size = (size_t)parcel->readInt32(); +    if (size > MAX_CRITERIA_PER_MIX) { +        size = MAX_CRITERIA_PER_MIX; +    } +    for (size_t i = 0; i < size; i++) { +        AttributeMatchCriterion criterion; +        if (criterion.readFromParcel(parcel) == NO_ERROR) { +            mCriteria.add(criterion); +        } +    } +    return NO_ERROR; +} + +status_t AudioMix::writeToParcel(Parcel *parcel) const +{ +    parcel->writeInt32(mMixType); +    parcel->writeInt32(mFormat.sample_rate); +    parcel->writeInt32(mFormat.channel_mask); +    parcel->writeInt32(mFormat.format); +    parcel->writeInt32(mRouteFlags); +    parcel->writeString8(mRegistrationId); +    size_t size = mCriteria.size(); +    if (size > MAX_CRITERIA_PER_MIX) { +        size = MAX_CRITERIA_PER_MIX; +    } +    size_t sizePosition = parcel->dataPosition(); +    parcel->writeInt32(size); +    size_t finalSize = size; +    for (size_t i = 0; i < size; i++) { +        size_t position = parcel->dataPosition(); +        if (mCriteria[i].writeToParcel(parcel) != NO_ERROR) { +            parcel->setDataPosition(position); +            finalSize--; +        } +    } +    if (size != finalSize) { +        size_t position = parcel->dataPosition(); +        parcel->setDataPosition(sizePosition); +        parcel->writeInt32(finalSize); +        parcel->setDataPosition(position); +    } +    return NO_ERROR; +} + +}; // namespace android diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 9e7ba88..ca3832d 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -82,14 +82,16 @@ AudioRecord::AudioRecord(          uint32_t notificationFrames,          int sessionId,          transfer_type transferType, -        audio_input_flags_t flags) +        audio_input_flags_t flags, +        const audio_attributes_t* pAttributes)      : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE),        mPreviousPriority(ANDROID_PRIORITY_NORMAL),        mPreviousSchedulingGroup(SP_DEFAULT),        mProxy(NULL)  {      mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user, -            notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags); +            notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags, +            pAttributes);  }  AudioRecord::~AudioRecord() @@ -126,7 +128,8 @@ status_t AudioRecord::set(          bool threadCanCallJava,          int sessionId,          transfer_type transferType, -        audio_input_flags_t flags) +        audio_input_flags_t flags, +        const audio_attributes_t* pAttributes)  {      ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "            "notificationFrames %u, sessionId %d, transferType %d, flags %#x", @@ -164,11 +167,15 @@ status_t AudioRecord::set(          return INVALID_OPERATION;      } -    // handle default values first. -    if (inputSource == AUDIO_SOURCE_DEFAULT) { -        inputSource = AUDIO_SOURCE_MIC; +    if (pAttributes == NULL) { +        memset(&mAttributes, 0, sizeof(audio_attributes_t)); +        mAttributes.source = inputSource; +    } else { +        // stream type shouldn't be looked at, this track has audio attributes +        memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t)); +        ALOGV("Building AudioRecord with attributes: source=%d flags=0x%x tags=[%s]", +              mAttributes.source, mAttributes.flags, mAttributes.tags);      } -    mInputSource = inputSource;      if (sampleRate == 0) {          ALOGE("Invalid sample rate %u", sampleRate); @@ -444,12 +451,14 @@ status_t AudioRecord::openRecord_l(size_t epoch)          }      } -    audio_io_handle_t input = AudioSystem::getInput(mInputSource, mSampleRate, mFormat, -            mChannelMask, mSessionId, mFlags); -    if (input == AUDIO_IO_HANDLE_NONE) { +    audio_io_handle_t input; +    status = AudioSystem::getInputForAttr(&mAttributes, &input, (audio_session_t)mSessionId, +                                        mSampleRate, mFormat, mChannelMask, mFlags); + +    if (status != NO_ERROR) {          ALOGE("Could not get audio input for record source %d, sample rate %u, format %#x, "                "channel mask %#x, session %d, flags %#x", -              mInputSource, mSampleRate, mFormat, mChannelMask, mSessionId, mFlags); +              mAttributes.source, mSampleRate, mFormat, mChannelMask, mSessionId, mFlags);          return BAD_VALUE;      }      { diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index dda3657..9cae21c 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -32,6 +32,9 @@ namespace android {  // client singleton for AudioFlinger binder interface  Mutex AudioSystem::gLock; +Mutex AudioSystem::gLockCache; +Mutex AudioSystem::gLockAPS; +Mutex AudioSystem::gLockAPC;  sp<IAudioFlinger> AudioSystem::gAudioFlinger;  sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;  audio_error_callback AudioSystem::gAudioErrorCallback = NULL; @@ -48,33 +51,40 @@ size_t AudioSystem::gInBuffSize = 0;    // zero indicates cache is invalid  sp<AudioSystem::AudioPortCallback> AudioSystem::gAudioPortCallback;  // establish binder interface to AudioFlinger service -const sp<IAudioFlinger>& AudioSystem::get_audio_flinger() -{ -    Mutex::Autolock _l(gLock); -    if (gAudioFlinger == 0) { -        sp<IServiceManager> sm = defaultServiceManager(); -        sp<IBinder> binder; -        do { -            binder = sm->getService(String16("media.audio_flinger")); -            if (binder != 0) -                break; -            ALOGW("AudioFlinger not published, waiting..."); -            usleep(500000); // 0.5 s -        } while (true); -        if (gAudioFlingerClient == NULL) { -            gAudioFlingerClient = new AudioFlingerClient(); -        } else { -            if (gAudioErrorCallback) { -                gAudioErrorCallback(NO_ERROR); +const sp<IAudioFlinger> AudioSystem::get_audio_flinger() +{ +    sp<IAudioFlinger> af; +    sp<AudioFlingerClient> afc; +    { +        Mutex::Autolock _l(gLock); +        if (gAudioFlinger == 0) { +            sp<IServiceManager> sm = defaultServiceManager(); +            sp<IBinder> binder; +            do { +                binder = sm->getService(String16("media.audio_flinger")); +                if (binder != 0) +                    break; +                ALOGW("AudioFlinger not published, waiting..."); +                usleep(500000); // 0.5 s +            } while (true); +            if (gAudioFlingerClient == NULL) { +                gAudioFlingerClient = new AudioFlingerClient(); +            } else { +                if (gAudioErrorCallback) { +                    gAudioErrorCallback(NO_ERROR); +                }              } +            binder->linkToDeath(gAudioFlingerClient); +            gAudioFlinger = interface_cast<IAudioFlinger>(binder); +            LOG_ALWAYS_FATAL_IF(gAudioFlinger == 0); +            afc = gAudioFlingerClient;          } -        binder->linkToDeath(gAudioFlingerClient); -        gAudioFlinger = interface_cast<IAudioFlinger>(binder); -        gAudioFlinger->registerClient(gAudioFlingerClient); +        af = gAudioFlinger;      } -    ALOGE_IF(gAudioFlinger==0, "no AudioFlinger!?"); - -    return gAudioFlinger; +    if (afc != 0) { +        af->registerClient(afc); +    } +    return af;  }  /* static */ status_t AudioSystem::checkAudioFlinger() @@ -245,36 +255,23 @@ status_t AudioSystem::getOutputSamplingRate(uint32_t* samplingRate, audio_stream      return getSamplingRate(output, samplingRate);  } -status_t AudioSystem::getOutputSamplingRateForAttr(uint32_t* samplingRate, -        const audio_attributes_t *attr) -{ -    if (attr == NULL) { -        return BAD_VALUE; -    } -    audio_io_handle_t output = getOutputForAttr(attr); -    if (output == 0) { -        return PERMISSION_DENIED; -    } -    return getSamplingRate(output, samplingRate); -} -  status_t AudioSystem::getSamplingRate(audio_io_handle_t output,                                        uint32_t* samplingRate)  { -    OutputDescriptor *outputDesc; +    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); +    if (af == 0) return PERMISSION_DENIED; -    gLock.lock(); -    outputDesc = AudioSystem::gOutputs.valueFor(output); +    Mutex::Autolock _l(gLockCache); + +    OutputDescriptor *outputDesc = AudioSystem::gOutputs.valueFor(output);      if (outputDesc == NULL) {          ALOGV("getOutputSamplingRate() no output descriptor for output %d in gOutputs", output); -        gLock.unlock(); -        const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); -        if (af == 0) return PERMISSION_DENIED; +        gLockCache.unlock();          *samplingRate = af->sampleRate(output); +        gLockCache.lock();      } else {          ALOGV("getOutputSamplingRate() reading from output desc");          *samplingRate = outputDesc->samplingRate; -        gLock.unlock();      }      if (*samplingRate == 0) {          ALOGE("AudioSystem::getSamplingRate failed for output %d", output); @@ -305,18 +302,18 @@ status_t AudioSystem::getOutputFrameCount(size_t* frameCount, audio_stream_type_  status_t AudioSystem::getFrameCount(audio_io_handle_t output,                                      size_t* frameCount)  { -    OutputDescriptor *outputDesc; +    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); +    if (af == 0) return PERMISSION_DENIED; + +    Mutex::Autolock _l(gLockCache); -    gLock.lock(); -    outputDesc = AudioSystem::gOutputs.valueFor(output); +    OutputDescriptor *outputDesc = AudioSystem::gOutputs.valueFor(output);      if (outputDesc == NULL) { -        gLock.unlock(); -        const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); -        if (af == 0) return PERMISSION_DENIED; +        gLockCache.unlock();          *frameCount = af->frameCount(output); +        gLockCache.lock();      } else {          *frameCount = outputDesc->frameCount; -        gLock.unlock();      }      if (*frameCount == 0) {          ALOGE("AudioSystem::getFrameCount failed for output %d", output); @@ -347,18 +344,18 @@ status_t AudioSystem::getOutputLatency(uint32_t* latency, audio_stream_type_t st  status_t AudioSystem::getLatency(audio_io_handle_t output,                                   uint32_t* latency)  { -    OutputDescriptor *outputDesc; +    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); +    if (af == 0) return PERMISSION_DENIED; -    gLock.lock(); -    outputDesc = AudioSystem::gOutputs.valueFor(output); +    Mutex::Autolock _l(gLockCache); + +    OutputDescriptor *outputDesc = AudioSystem::gOutputs.valueFor(output);      if (outputDesc == NULL) { -        gLock.unlock(); -        const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); -        if (af == 0) return PERMISSION_DENIED; +        gLockCache.unlock();          *latency = af->latency(output); +        gLockCache.lock();      } else {          *latency = outputDesc->latency; -        gLock.unlock();      }      ALOGV("getLatency() output %d, latency %d", output, *latency); @@ -369,24 +366,24 @@ status_t AudioSystem::getLatency(audio_io_handle_t output,  status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, audio_format_t format,          audio_channel_mask_t channelMask, size_t* buffSize)  { -    gLock.lock(); +    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); +    if (af == 0) { +        return PERMISSION_DENIED; +    } +    Mutex::Autolock _l(gLockCache);      // Do we have a stale gInBufferSize or are we requesting the input buffer size for new values      size_t inBuffSize = gInBuffSize;      if ((inBuffSize == 0) || (sampleRate != gPrevInSamplingRate) || (format != gPrevInFormat)          || (channelMask != gPrevInChannelMask)) { -        gLock.unlock(); -        const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); -        if (af == 0) { -            return PERMISSION_DENIED; -        } +        gLockCache.unlock();          inBuffSize = af->getInputBufferSize(sampleRate, format, channelMask); +        gLockCache.lock();          if (inBuffSize == 0) {              ALOGE("AudioSystem::getInputBufferSize failed sampleRate %d format %#x channelMask %x",                      sampleRate, format, channelMask);              return BAD_VALUE;          }          // A benign race is possible here: we could overwrite a fresher cache entry -        gLock.lock();          // save the request params          gPrevInSamplingRate = sampleRate;          gPrevInFormat = format; @@ -394,7 +391,6 @@ status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, audio_format_t for          gInBuffSize = inBuffSize;      } -    gLock.unlock();      *buffSize = inBuffSize;      return NO_ERROR; @@ -461,14 +457,21 @@ audio_hw_sync_t AudioSystem::getAudioHwSyncForSession(audio_session_t sessionId)  void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who __unused)  { -    Mutex::Autolock _l(AudioSystem::gLock); +    audio_error_callback cb = NULL; +    { +        Mutex::Autolock _l(AudioSystem::gLock); +        AudioSystem::gAudioFlinger.clear(); +        cb = gAudioErrorCallback; +    } -    AudioSystem::gAudioFlinger.clear(); -    // clear output handles and stream to output map caches -    AudioSystem::gOutputs.clear(); +    { +        // clear output handles and stream to output map caches +        Mutex::Autolock _l(gLockCache); +        AudioSystem::gOutputs.clear(); +    } -    if (gAudioErrorCallback) { -        gAudioErrorCallback(DEAD_OBJECT); +    if (cb) { +        cb(DEAD_OBJECT);      }      ALOGW("AudioFlinger server died!");  } @@ -481,7 +484,7 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, audio_io_handle      if (ioHandle == AUDIO_IO_HANDLE_NONE) return; -    Mutex::Autolock _l(AudioSystem::gLock); +    Mutex::Autolock _l(AudioSystem::gLockCache);      switch (event) {      case STREAM_CONFIG_CHANGED: @@ -543,55 +546,44 @@ void AudioSystem::setErrorCallback(audio_error_callback cb)      gAudioErrorCallback = cb;  } - -bool AudioSystem::routedToA2dpOutput(audio_stream_type_t streamType) -{ -    switch (streamType) { -    case AUDIO_STREAM_MUSIC: -    case AUDIO_STREAM_VOICE_CALL: -    case AUDIO_STREAM_BLUETOOTH_SCO: -    case AUDIO_STREAM_SYSTEM: -        return true; -    default: -        return false; -    } -} - -  // client singleton for AudioPolicyService binder interface +// protected by gLockAPS  sp<IAudioPolicyService> AudioSystem::gAudioPolicyService;  sp<AudioSystem::AudioPolicyServiceClient> AudioSystem::gAudioPolicyServiceClient;  // establish binder interface to AudioPolicy service -const sp<IAudioPolicyService>& AudioSystem::get_audio_policy_service() -{ -    gLock.lock(); -    if (gAudioPolicyService == 0) { -        sp<IServiceManager> sm = defaultServiceManager(); -        sp<IBinder> binder; -        do { -            binder = sm->getService(String16("media.audio_policy")); -            if (binder != 0) -                break; -            ALOGW("AudioPolicyService not published, waiting..."); -            usleep(500000); // 0.5 s -        } while (true); -        if (gAudioPolicyServiceClient == NULL) { -            gAudioPolicyServiceClient = new AudioPolicyServiceClient(); +const sp<IAudioPolicyService> AudioSystem::get_audio_policy_service() +{ +    sp<IAudioPolicyService> ap; +    sp<AudioPolicyServiceClient> apc; +    { +        Mutex::Autolock _l(gLockAPS); +        if (gAudioPolicyService == 0) { +            sp<IServiceManager> sm = defaultServiceManager(); +            sp<IBinder> binder; +            do { +                binder = sm->getService(String16("media.audio_policy")); +                if (binder != 0) +                    break; +                ALOGW("AudioPolicyService not published, waiting..."); +                usleep(500000); // 0.5 s +            } while (true); +            if (gAudioPolicyServiceClient == NULL) { +                gAudioPolicyServiceClient = new AudioPolicyServiceClient(); +            } +            binder->linkToDeath(gAudioPolicyServiceClient); +            gAudioPolicyService = interface_cast<IAudioPolicyService>(binder); +            LOG_ALWAYS_FATAL_IF(gAudioPolicyService == 0); +            apc = gAudioPolicyServiceClient;          } -        binder->linkToDeath(gAudioPolicyServiceClient); -        gAudioPolicyService = interface_cast<IAudioPolicyService>(binder); -        gLock.unlock(); -        // Registering the client takes the AudioPolicyService lock. -        // Don't hold the AudioSystem lock at the same time. -        gAudioPolicyService->registerClient(gAudioPolicyServiceClient); -    } else { -        // There exists a benign race condition where gAudioPolicyService -        // is set, but gAudioPolicyServiceClient is not yet registered. -        gLock.unlock(); +        ap = gAudioPolicyService; +    } +    if (apc != 0) { +        ap->registerClient(apc);      } -    return gAudioPolicyService; + +    return ap;  }  // --------------------------------------------------------------------------- @@ -657,22 +649,26 @@ audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream,      return aps->getOutput(stream, samplingRate, format, channelMask, flags, offloadInfo);  } -audio_io_handle_t AudioSystem::getOutputForAttr(const audio_attributes_t *attr, -                                    uint32_t samplingRate, -                                    audio_format_t format, -                                    audio_channel_mask_t channelMask, -                                    audio_output_flags_t flags, -                                    const audio_offload_info_t *offloadInfo) +status_t AudioSystem::getOutputForAttr(const audio_attributes_t *attr, +                                        audio_io_handle_t *output, +                                        audio_session_t session, +                                        audio_stream_type_t *stream, +                                        uint32_t samplingRate, +                                        audio_format_t format, +                                        audio_channel_mask_t channelMask, +                                        audio_output_flags_t flags, +                                        const audio_offload_info_t *offloadInfo)  { -    if (attr == NULL) return 0;      const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); -    if (aps == 0) return 0; -    return aps->getOutputForAttr(attr, samplingRate, format, channelMask, flags, offloadInfo); +    if (aps == 0) return NO_INIT; +    return aps->getOutputForAttr(attr, output, session, stream, +                                 samplingRate, format, channelMask, +                                 flags, offloadInfo);  }  status_t AudioSystem::startOutput(audio_io_handle_t output,                                    audio_stream_type_t stream, -                                  int session) +                                  audio_session_t session)  {      const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();      if (aps == 0) return PERMISSION_DENIED; @@ -681,30 +677,33 @@ status_t AudioSystem::startOutput(audio_io_handle_t output,  status_t AudioSystem::stopOutput(audio_io_handle_t output,                                   audio_stream_type_t stream, -                                 int session) +                                 audio_session_t session)  {      const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();      if (aps == 0) return PERMISSION_DENIED;      return aps->stopOutput(output, stream, session);  } -void AudioSystem::releaseOutput(audio_io_handle_t output) +void AudioSystem::releaseOutput(audio_io_handle_t output, +                                audio_stream_type_t stream, +                                audio_session_t session)  {      const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();      if (aps == 0) return; -    aps->releaseOutput(output); +    aps->releaseOutput(output, stream, session);  } -audio_io_handle_t AudioSystem::getInput(audio_source_t inputSource, -                                    uint32_t samplingRate, -                                    audio_format_t format, -                                    audio_channel_mask_t channelMask, -                                    int sessionId, -                                    audio_input_flags_t flags) +status_t AudioSystem::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)  {      const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); -    if (aps == 0) return 0; -    return aps->getInput(inputSource, samplingRate, format, channelMask, sessionId, flags); +    if (aps == 0) return NO_INIT; +    return aps->getInputForAttr(attr, input, session, samplingRate, format, channelMask, flags);  }  status_t AudioSystem::startInput(audio_io_handle_t input, @@ -856,9 +855,21 @@ status_t AudioSystem::setLowRamDevice(bool isLowRamDevice)  void AudioSystem::clearAudioConfigCache()  { -    Mutex::Autolock _l(gLock); +    // called by restoreTrack_l(), which needs new IAudioFlinger and IAudioPolicyService instances      ALOGV("clearAudioConfigCache()"); -    gOutputs.clear(); +    { +        Mutex::Autolock _l(gLockCache); +        gOutputs.clear(); +    } +    { +        Mutex::Autolock _l(gLock); +        gAudioFlinger.clear(); +    } +    { +        Mutex::Autolock _l(gLockAPS); +        gAudioPolicyService.clear(); +    } +    // Do not clear gAudioPortCallback  }  bool AudioSystem::isOffloadSupported(const audio_offload_info_t& info) @@ -920,7 +931,7 @@ status_t AudioSystem::setAudioPortConfig(const struct audio_port_config *config)  void AudioSystem::setAudioPortCallback(sp<AudioPortCallback> callBack)  { -    Mutex::Autolock _l(gLock); +    Mutex::Autolock _l(gLockAPC);      gAudioPortCallback = callBack;  } @@ -947,23 +958,34 @@ audio_mode_t AudioSystem::getPhoneState()      return aps->getPhoneState();  } +status_t AudioSystem::registerPolicyMixes(Vector<AudioMix> mixes, bool registration) +{ +    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); +    if (aps == 0) return PERMISSION_DENIED; +    return aps->registerPolicyMixes(mixes, registration); +}  // ---------------------------------------------------------------------------  void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused)  { -    Mutex::Autolock _l(gLock); -    if (gAudioPortCallback != 0) { -        gAudioPortCallback->onServiceDied(); +    { +        Mutex::Autolock _l(gLockAPC); +        if (gAudioPortCallback != 0) { +            gAudioPortCallback->onServiceDied(); +        } +    } +    { +        Mutex::Autolock _l(gLockAPS); +        AudioSystem::gAudioPolicyService.clear();      } -    AudioSystem::gAudioPolicyService.clear();      ALOGW("AudioPolicyService server died!");  }  void AudioSystem::AudioPolicyServiceClient::onAudioPortListUpdate()  { -    Mutex::Autolock _l(gLock); +    Mutex::Autolock _l(gLockAPC);      if (gAudioPortCallback != 0) {          gAudioPortCallback->onAudioPortListUpdate();      } @@ -971,7 +993,7 @@ void AudioSystem::AudioPolicyServiceClient::onAudioPortListUpdate()  void AudioSystem::AudioPolicyServiceClient::onAudioPatchListUpdate()  { -    Mutex::Autolock _l(gLock); +    Mutex::Autolock _l(gLockAPC);      if (gAudioPortCallback != 0) {          gAudioPortCallback->onAudioPatchListUpdate();      } diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 0a89fbb..389aacc 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -28,6 +28,7 @@  #include <utils/Log.h>  #include <private/media/AudioTrackShared.h>  #include <media/IAudioFlinger.h> +#include <media/AudioPolicyHelper.h>  #include <media/AudioResamplerPublic.h>  #define WAIT_PERIOD_MS                  10 @@ -281,38 +282,21 @@ status_t AudioTrack::set(      if (streamType == AUDIO_STREAM_DEFAULT) {          streamType = AUDIO_STREAM_MUSIC;      } -      if (pAttributes == NULL) { -        if (uint32_t(streamType) >= AUDIO_STREAM_CNT) { +        if (uint32_t(streamType) >= AUDIO_STREAM_PUBLIC_CNT) {              ALOGE("Invalid stream type %d", streamType);              return BAD_VALUE;          } -        setAttributesFromStreamType(streamType);          mStreamType = streamType; +      } else { -        if (!isValidAttributes(pAttributes)) { -            ALOGE("Invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]", -                pAttributes->usage, pAttributes->content_type, pAttributes->flags, -                pAttributes->tags); -        }          // stream type shouldn't be looked at, this track has audio attributes          memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t)); -        setStreamTypeFromAttributes(mAttributes);          ALOGV("Building AudioTrack with attributes: usage=%d content=%d flags=0x%x tags=[%s]",                  mAttributes.usage, mAttributes.content_type, mAttributes.flags, mAttributes.tags); +        mStreamType = AUDIO_STREAM_DEFAULT;      } -    status_t status; -    if (sampleRate == 0) { -        status = AudioSystem::getOutputSamplingRateForAttr(&sampleRate, &mAttributes); -        if (status != NO_ERROR) { -            ALOGE("Could not get output sample rate for stream type %d; status %d", -                    mStreamType, status); -            return status; -        } -    } -    mSampleRate = sampleRate; -      // these below should probably come from the audioFlinger too...      if (format == AUDIO_FORMAT_DEFAULT) {          format = AUDIO_FORMAT_PCM_16_BIT; @@ -350,9 +334,10 @@ status_t AudioTrack::set(                  // FIXME why can't we allow direct AND fast?                  ((flags | AUDIO_OUTPUT_FLAG_DIRECT) & ~AUDIO_OUTPUT_FLAG_FAST);      } -    // only allow deep buffering for music stream type -    if (mStreamType != AUDIO_STREAM_MUSIC) { -        flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER); + +    // force direct flag if HW A/V sync requested +    if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) { +        flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);      }      if (flags & AUDIO_OUTPUT_FLAG_DIRECT) { @@ -371,6 +356,12 @@ status_t AudioTrack::set(          // so no need to check for specific PCM formats here      } +    // sampling rate must be specified for direct outputs +    if (sampleRate == 0 && (flags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) { +        return BAD_VALUE; +    } +    mSampleRate = sampleRate; +      // Make copy of input parameter offloadInfo so that in the future:      //  (a) createTrack_l doesn't need it as an input parameter      //  (b) we can support re-creation of offloaded tracks @@ -388,7 +379,11 @@ status_t AudioTrack::set(      mReqFrameCount = frameCount;      mNotificationFramesReq = notificationFrames;      mNotificationFramesAct = 0; -    mSessionId = sessionId; +    if (sessionId == AUDIO_SESSION_ALLOCATE) { +        mSessionId = AudioSystem::newAudioUniqueId(); +    } else { +        mSessionId = sessionId; +    }      int callingpid = IPCThreadState::self()->getCallingPid();      int mypid = getpid();      if (uid == -1 || (callingpid != mypid)) { @@ -411,7 +406,7 @@ status_t AudioTrack::set(      }      // create the IAudioTrack -    status = createTrack_l(); +    status_t status = createTrack_l();      if (status != NO_ERROR) {          if (mAudioTrackThread != 0) { @@ -678,15 +673,18 @@ status_t AudioTrack::setSampleRate(uint32_t rate)          return INVALID_OPERATION;      } +    AutoMutex lock(mLock); +    if (mOutput == AUDIO_IO_HANDLE_NONE) { +        return NO_INIT; +    }      uint32_t afSamplingRate; -    if (AudioSystem::getOutputSamplingRateForAttr(&afSamplingRate, &mAttributes) != NO_ERROR) { +    if (AudioSystem::getSamplingRate(mOutput, &afSamplingRate) != NO_ERROR) {          return NO_INIT;      }      if (rate == 0 || rate > afSamplingRate * AUDIO_RESAMPLER_DOWN_RATIO_MAX) {          return BAD_VALUE;      } -    AutoMutex lock(mLock);      mSampleRate = rate;      mProxy->setSampleRate(rate); @@ -742,8 +740,7 @@ status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount  void AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount)  { -    // FIXME If setting a loop also sets position to start of loop, then -    //       this is correct.  Otherwise it should be removed. +    // Setting the loop will reset next notification update period (like setPosition).      mNewPosition = updateAndGetPosition_l() + mUpdatePeriod;      mLoopPeriod = loopCount != 0 ? loopEnd - loopStart : 0;      mStaticProxy->setLoop(loopStart, loopEnd, loopCount); @@ -859,6 +856,10 @@ status_t AudioTrack::getPosition(uint32_t *position)          // due to hardware latency. We leave this behavior for now.          *position = dspFrames;      } else { +        if (mCblk->mFlags & CBLK_INVALID) { +            restoreTrack_l("getPosition"); +        } +          // IAudioTrack::stop() isn't synchronous; we don't know when presentation completes          *position = (mState == STATE_STOPPED || mState == STATE_FLUSHED) ?                  0 : updateAndGetPosition_l(); @@ -915,24 +916,38 @@ status_t AudioTrack::attachAuxEffect(int effectId)      return status;  } +audio_stream_type_t AudioTrack::streamType() const +{ +    if (mStreamType == AUDIO_STREAM_DEFAULT) { +        return audio_attributes_to_stream_type(&mAttributes); +    } +    return mStreamType; +} +  // -------------------------------------------------------------------------  // must be called with mLock held  status_t AudioTrack::createTrack_l()  { -    status_t status;      const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();      if (audioFlinger == 0) {          ALOGE("Could not get audioflinger");          return NO_INIT;      } -    audio_io_handle_t output = AudioSystem::getOutputForAttr(&mAttributes, mSampleRate, mFormat, -            mChannelMask, mFlags, mOffloadInfo); -    if (output == AUDIO_IO_HANDLE_NONE) { +    audio_io_handle_t output; +    audio_stream_type_t streamType = mStreamType; +    audio_attributes_t *attr = (mStreamType == AUDIO_STREAM_DEFAULT) ? &mAttributes : NULL; +    status_t status = AudioSystem::getOutputForAttr(attr, &output, +                                                    (audio_session_t)mSessionId, &streamType, +                                                    mSampleRate, mFormat, mChannelMask, +                                                    mFlags, mOffloadInfo); + + +    if (status != NO_ERROR || output == AUDIO_IO_HANDLE_NONE) {          ALOGE("Could not get audio output for stream type %d, usage %d, sample rate %u, format %#x,"                " channel mask %#x, flags %#x", -              mStreamType, mAttributes.usage, mSampleRate, mFormat, mChannelMask, mFlags); +              streamType, mAttributes.usage, mSampleRate, mFormat, mChannelMask, mFlags);          return BAD_VALUE;      }      { @@ -961,7 +976,9 @@ status_t AudioTrack::createTrack_l()          ALOGE("getSamplingRate(output=%d) status %d", output, status);          goto release;      } - +    if (mSampleRate == 0) { +        mSampleRate = afSampleRate; +    }      // Client decides whether the track is TIMED (see below), but can only express a preference      // for FAST.  Server will perform additional tests.      if ((mFlags & AUDIO_OUTPUT_FLAG_FAST) && !(( @@ -1084,7 +1101,7 @@ status_t AudioTrack::createTrack_l()      size_t temp = frameCount;   // temp may be replaced by a revised value of frameCount,                                  // but we will still need the original value also -    sp<IAudioTrack> track = audioFlinger->createTrack(mStreamType, +    sp<IAudioTrack> track = audioFlinger->createTrack(streamType,                                                        mSampleRate,                                                        // AudioFlinger only sees 16-bit PCM                                                        mFormat == AUDIO_FORMAT_PCM_8_BIT && @@ -1218,7 +1235,11 @@ status_t AudioTrack::createTrack_l()          mStaticProxy = new StaticAudioTrackClientProxy(cblk, buffers, frameCount, mFrameSizeAF);          mProxy = mStaticProxy;      } -    mProxy->setVolumeLR(GAIN_MINIFLOAT_PACKED_UNITY); + +    mProxy->setVolumeLR(gain_minifloat_pack( +            gain_from_float(mVolume[AUDIO_INTERLEAVE_LEFT]), +            gain_from_float(mVolume[AUDIO_INTERLEAVE_RIGHT]))); +      mProxy->setSendLevel(mSendLevel);      mProxy->setSampleRate(mSampleRate);      mProxy->setMinimum(mNotificationFramesAct); @@ -1230,7 +1251,7 @@ status_t AudioTrack::createTrack_l()      }  release: -    AudioSystem::releaseOutput(output); +    AudioSystem::releaseOutput(output, streamType, (audio_session_t)mSessionId);      if (status == NO_ERROR) {          status = NO_INIT;      } @@ -1826,7 +1847,7 @@ status_t AudioTrack::restoreTrack_l(const char *from)      status_t result;      // refresh the audio configuration cache in this process to make sure we get new -    // output parameters in createTrack_l() +    // output parameters and new IAudioFlinger in createTrack_l()      AudioSystem::clearAudioConfigCache();      if (isOffloadedOrDirect_l()) { @@ -1934,6 +1955,10 @@ status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp)          break;      } +    if (mCblk->mFlags & CBLK_INVALID) { +        restoreTrack_l("getTimestamp"); +    } +      // The presented frame count must always lag behind the consumed frame count.      // To avoid a race, read the presented frames first.  This ensures that presented <= consumed.      status_t status = mAudioTrack->getTimestamp(timestamp); @@ -2064,143 +2089,6 @@ uint32_t AudioTrack::getUnderrunFrames() const      return mProxy->getUnderrunFrames();  } -void AudioTrack::setAttributesFromStreamType(audio_stream_type_t streamType) { -    mAttributes.flags = 0x0; - -    switch(streamType) { -    case AUDIO_STREAM_DEFAULT: -    case AUDIO_STREAM_MUSIC: -        mAttributes.content_type = AUDIO_CONTENT_TYPE_MUSIC; -        mAttributes.usage = AUDIO_USAGE_MEDIA; -        break; -    case AUDIO_STREAM_VOICE_CALL: -        mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH; -        mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION; -        break; -    case AUDIO_STREAM_ENFORCED_AUDIBLE: -        mAttributes.flags  |= AUDIO_FLAG_AUDIBILITY_ENFORCED; -        // intended fall through, attributes in common with STREAM_SYSTEM -    case AUDIO_STREAM_SYSTEM: -        mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; -        mAttributes.usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION; -        break; -    case AUDIO_STREAM_RING: -        mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; -        mAttributes.usage = AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE; -        break; -    case AUDIO_STREAM_ALARM: -        mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; -        mAttributes.usage = AUDIO_USAGE_ALARM; -        break; -    case AUDIO_STREAM_NOTIFICATION: -        mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; -        mAttributes.usage = AUDIO_USAGE_NOTIFICATION; -        break; -    case AUDIO_STREAM_BLUETOOTH_SCO: -        mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH; -        mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION; -        mAttributes.flags |= AUDIO_FLAG_SCO; -        break; -    case AUDIO_STREAM_DTMF: -        mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION; -        mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING; -        break; -    case AUDIO_STREAM_TTS: -        mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH; -        mAttributes.usage = AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY; -        break; -    default: -        ALOGE("invalid stream type %d when converting to attributes", streamType); -    } -} - -void AudioTrack::setStreamTypeFromAttributes(audio_attributes_t& aa) { -    // flags to stream type mapping -    if ((aa.flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) { -        mStreamType = AUDIO_STREAM_ENFORCED_AUDIBLE; -        return; -    } -    if ((aa.flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) { -        mStreamType = AUDIO_STREAM_BLUETOOTH_SCO; -        return; -    } - -    // usage to stream type mapping -    switch (aa.usage) { -    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: -        // TODO once AudioPolicyManager fully supports audio_attributes_t, -        //   remove stream change based on phone state -        if (AudioSystem::getPhoneState() == AUDIO_MODE_RINGTONE) { -            mStreamType = AUDIO_STREAM_RING; -            break; -        } -        /// FALL THROUGH -    case AUDIO_USAGE_MEDIA: -    case AUDIO_USAGE_GAME: -    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: -        mStreamType = AUDIO_STREAM_MUSIC; -        return; -    case AUDIO_USAGE_ASSISTANCE_SONIFICATION: -        mStreamType = AUDIO_STREAM_SYSTEM; -        return; -    case AUDIO_USAGE_VOICE_COMMUNICATION: -        mStreamType = AUDIO_STREAM_VOICE_CALL; -        return; - -    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: -        mStreamType = AUDIO_STREAM_DTMF; -        return; - -    case AUDIO_USAGE_ALARM: -        mStreamType = AUDIO_STREAM_ALARM; -        return; -    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: -        mStreamType = AUDIO_STREAM_RING; -        return; - -    case AUDIO_USAGE_NOTIFICATION: -    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: -    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: -    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: -    case AUDIO_USAGE_NOTIFICATION_EVENT: -        mStreamType = AUDIO_STREAM_NOTIFICATION; -        return; - -    case AUDIO_USAGE_UNKNOWN: -    default: -        mStreamType = AUDIO_STREAM_MUSIC; -    } -} - -bool AudioTrack::isValidAttributes(const audio_attributes_t *paa) { -    // has flags that map to a strategy? -    if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO)) != 0) { -        return true; -    } - -    // has known usage? -    switch (paa->usage) { -    case AUDIO_USAGE_UNKNOWN: -    case AUDIO_USAGE_MEDIA: -    case AUDIO_USAGE_VOICE_COMMUNICATION: -    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: -    case AUDIO_USAGE_ALARM: -    case AUDIO_USAGE_NOTIFICATION: -    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: -    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: -    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: -    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: -    case AUDIO_USAGE_NOTIFICATION_EVENT: -    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: -    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: -    case AUDIO_USAGE_ASSISTANCE_SONIFICATION: -    case AUDIO_USAGE_GAME: -        break; -    default: -        return false; -    } -    return true; -}  // =========================================================================  void AudioTrack::DeathNotifier::binderDied(const wp<IBinder>& who __unused) diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp index eec025e..ff24475 100644 --- a/media/libmedia/AudioTrackShared.cpp +++ b/media/libmedia/AudioTrackShared.cpp @@ -25,6 +25,12 @@  namespace android { +// used to clamp a value to size_t.  TODO: move to another file. +template <typename T> +size_t clampToSize(T x) { +    return x > SIZE_MAX ? SIZE_MAX : x < 0 ? 0 : (size_t) x; +} +  audio_track_cblk_t::audio_track_cblk_t()      : mServer(0), mFutex(0), mMinimum(0),      mVolumeLR(GAIN_MINIFLOAT_PACKED_UNITY), mSampleRate(0), mSendLevel(0), mFlags(0) @@ -301,6 +307,7 @@ void ClientProxy::binderDied()  {      audio_track_cblk_t* cblk = mCblk;      if (!(android_atomic_or(CBLK_INVALID, &cblk->mFlags) & CBLK_INVALID)) { +        android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);          // it seems that a FUTEX_WAKE_PRIVATE will not wake a FUTEX_WAIT, even within same process          (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,                  1); @@ -311,6 +318,7 @@ void ClientProxy::interrupt()  {      audio_track_cblk_t* cblk = mCblk;      if (!(android_atomic_or(CBLK_INTERRUPT, &cblk->mFlags) & CBLK_INTERRUPT)) { +        android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);          (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,                  1);      } @@ -348,7 +356,13 @@ size_t ClientProxy::getFramesFilled() {  void AudioTrackClientProxy::flush()  { -    mCblk->u.mStreaming.mFlush++; +    // This works for mFrameCountP2 <= 2^30 +    size_t increment = mFrameCountP2 << 1; +    size_t mask = increment - 1; +    audio_track_cblk_t* cblk = mCblk; +    int32_t newFlush = (cblk->u.mStreaming.mRear & mask) | +                        ((cblk->u.mStreaming.mFlush & ~mask) + increment); +    android_atomic_release_store(newFlush, &cblk->u.mStreaming.mFlush);  }  bool AudioTrackClientProxy::clearStreamEndDone() { @@ -491,7 +505,11 @@ void StaticAudioTrackClientProxy::setLoop(size_t loopStart, size_t loopEnd, int      newState.mLoopStart = (uint32_t) loopStart;      newState.mLoopEnd = (uint32_t) loopEnd;      newState.mLoopCount = loopCount; -    mBufferPosition = loopStart; +    size_t bufferPosition; +    if (loopCount == 0 || (bufferPosition = getBufferPosition()) >= loopEnd) { +        bufferPosition = loopStart; +    } +    mBufferPosition = bufferPosition; // snapshot buffer position until loop is acknowledged.      (void) mMutator.push(newState);  } @@ -536,17 +554,27 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush)          rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);          front = cblk->u.mStreaming.mFront;          if (flush != mFlush) { -            mFlush = flush;              // effectively obtain then release whatever is in the buffer -            android_atomic_release_store(rear, &cblk->u.mStreaming.mFront); -            if (front != rear) { +            size_t mask = (mFrameCountP2 << 1) - 1; +            int32_t newFront = (front & ~mask) | (flush & mask); +            ssize_t filled = rear - newFront; +            // Rather than shutting down on a corrupt flush, just treat it as a full flush +            if (!(0 <= filled && (size_t) filled <= mFrameCount)) { +                ALOGE("mFlush %#x -> %#x, front %#x, rear %#x, mask %#x, newFront %#x, filled %d=%#x", +                        mFlush, flush, front, rear, mask, newFront, filled, filled); +                newFront = rear; +            } +            mFlush = flush; +            android_atomic_release_store(newFront, &cblk->u.mStreaming.mFront); +            // There is no danger from a false positive, so err on the side of caution +            if (true /*front != newFront*/) {                  int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);                  if (!(old & CBLK_FUTEX_WAKE)) {                      (void) syscall(__NR_futex, &cblk->mFutex,                              mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1);                  }              } -            front = rear; +            front = newFront;          }      } else {          front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront); @@ -668,6 +696,7 @@ size_t AudioTrackServerProxy::framesReady()      int32_t flush = cblk->u.mStreaming.mFlush;      if (flush != mFlush) { +        // FIXME should return an accurate value, but over-estimate is better than under-estimate          return mFrameCount;      }      // the acquire might not be necessary since not doing a subsequent read @@ -711,7 +740,8 @@ StaticAudioTrackServerProxy::StaticAudioTrackServerProxy(audio_track_cblk_t* cbl          size_t frameCount, size_t frameSize)      : AudioTrackServerProxy(cblk, buffers, frameCount, frameSize),        mObserver(&cblk->u.mStatic.mSingleStateQueue), mPosition(0), -      mEnd(frameCount), mFramesReadyIsCalledByMultipleThreads(false) +      mFramesReadySafe(frameCount), mFramesReady(frameCount), +      mFramesReadyIsCalledByMultipleThreads(false)  {      mState.mLoopStart = 0;      mState.mLoopEnd = 0; @@ -725,20 +755,11 @@ void StaticAudioTrackServerProxy::framesReadyIsCalledByMultipleThreads()  size_t StaticAudioTrackServerProxy::framesReady()  { -    // FIXME -    // This is racy if called by normal mixer thread, -    // as we're reading 2 independent variables without a lock. -    // Can't call mObserver.poll(), as we might be called from wrong thread. -    // If looping is enabled, should return a higher number (since includes non-contiguous). -    size_t position = mPosition; +    // Can't call pollPosition() from multiple threads.      if (!mFramesReadyIsCalledByMultipleThreads) { -        ssize_t positionOrStatus = pollPosition(); -        if (positionOrStatus >= 0) { -            position = (size_t) positionOrStatus; -        } +        (void) pollPosition();      } -    size_t end = mEnd; -    return position < end ? end - position : 0; +    return mFramesReadySafe;  }  ssize_t StaticAudioTrackServerProxy::pollPosition() @@ -755,25 +776,37 @@ ssize_t StaticAudioTrackServerProxy::pollPosition()              }              // ignore loopEnd              mPosition = position = loopStart; -            mEnd = mFrameCount; +            mFramesReady = mFrameCount - mPosition;              mState.mLoopCount = 0;              valid = true; -        } else { +        } else if (state.mLoopCount >= -1) {              if (loopStart < loopEnd && loopEnd <= mFrameCount &&                      loopEnd - loopStart >= MIN_LOOP) { -                if (!(loopStart <= position && position < loopEnd)) { +                // If the current position is greater than the end of the loop +                // we "wrap" to the loop start. This might cause an audible pop. +                if (position >= loopEnd) {                      mPosition = position = loopStart;                  } -                mEnd = loopEnd; +                if (state.mLoopCount == -1) { +                    mFramesReady = INT64_MAX; +                } else { +                    // mFramesReady is 64 bits to handle the effective number of frames +                    // that the static audio track contains, including loops. +                    // TODO: Later consider fixing overflow, but does not seem needed now +                    // as will not overflow if loopStart and loopEnd are Java "ints". +                    mFramesReady = int64_t(state.mLoopCount) * (loopEnd - loopStart) +                            + mFrameCount - mPosition; +                }                  mState = state;                  valid = true;              }          } -        if (!valid) { +        if (!valid || mPosition > mFrameCount) {              ALOGE("%s client pushed an invalid state, shutting down", __func__);              mIsShutdown = true;              return (ssize_t) NO_INIT;          } +        mFramesReadySafe = clampToSize(mFramesReady);          // This may overflow, but client is not supposed to rely on it          mCblk->u.mStatic.mBufferPosition = (uint32_t) position;      } @@ -798,9 +831,10 @@ status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush          return (status_t) positionOrStatus;      }      size_t position = (size_t) positionOrStatus; +    size_t end = mState.mLoopCount != 0 ? mState.mLoopEnd : mFrameCount;      size_t avail; -    if (position < mEnd) { -        avail = mEnd - position; +    if (position < end) { +        avail = end - position;          size_t wanted = buffer->mFrameCount;          if (avail < wanted) {              buffer->mFrameCount = avail; @@ -813,7 +847,10 @@ status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush          buffer->mFrameCount = 0;          buffer->mRaw = NULL;      } -    buffer->mNonContig = 0;     // FIXME should be > 0 for looping +    // As mFramesReady is the total remaining frames in the static audio track, +    // it is always larger or equal to avail. +    LOG_ALWAYS_FATAL_IF(mFramesReady < avail); +    buffer->mNonContig = mFramesReady == INT64_MAX ? SIZE_MAX : clampToSize(mFramesReady - avail);      mUnreleased = avail;      return NO_ERROR;  } @@ -821,6 +858,7 @@ status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush  void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer)  {      size_t stepCount = buffer->mFrameCount; +    LOG_ALWAYS_FATAL_IF(!(stepCount <= mFramesReady));      LOG_ALWAYS_FATAL_IF(!(stepCount <= mUnreleased));      if (stepCount == 0) {          // prevent accidental re-use of buffer @@ -837,11 +875,10 @@ void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer)          ALOGW("%s newPosition %zu outside [%zu, %zu]", __func__, newPosition, position, mFrameCount);          newPosition = mFrameCount;      } else if (mState.mLoopCount != 0 && newPosition == mState.mLoopEnd) { +        newPosition = mState.mLoopStart;          if (mState.mLoopCount == -1 || --mState.mLoopCount != 0) { -            newPosition = mState.mLoopStart;              setFlags = CBLK_LOOP_CYCLE;          } else { -            mEnd = mFrameCount;     // this is what allows playback to continue after the loop              setFlags = CBLK_LOOP_FINAL;          }      } @@ -849,6 +886,10 @@ void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer)          setFlags |= CBLK_BUFFER_END;      }      mPosition = newPosition; +    if (mFramesReady != INT64_MAX) { +        mFramesReady -= stepCount; +    } +    mFramesReadySafe = clampToSize(mFramesReady);      cblk->mServer += stepCount;      // This may overflow, but client is not supposed to rely on it diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index fc4a787..12efa8a 100644 --- a/media/libmedia/IAudioPolicyService.cpp +++ b/media/libmedia/IAudioPolicyService.cpp @@ -41,7 +41,7 @@ enum {      START_OUTPUT,      STOP_OUTPUT,      RELEASE_OUTPUT, -    GET_INPUT, +    GET_INPUT_FOR_ATTR,      START_INPUT,      STOP_INPUT,      RELEASE_INPUT, @@ -69,7 +69,8 @@ enum {      GET_OUTPUT_FOR_ATTR,      ACQUIRE_SOUNDTRIGGER_SESSION,      RELEASE_SOUNDTRIGGER_SESSION, -    GET_PHONE_STATE +    GET_PHONE_STATE, +    REGISTER_POLICY_MIXES,  };  #define MAX_ITEMS_PER_LIST 1024 @@ -162,21 +163,45 @@ public:          return static_cast <audio_io_handle_t> (reply.readInt32());      } -    virtual audio_io_handle_t getOutputForAttr( -                                            const audio_attributes_t *attr, -                                            uint32_t samplingRate, -                                            audio_format_t format, -                                            audio_channel_mask_t channelMask, -                                            audio_output_flags_t flags, -                                            const audio_offload_info_t *offloadInfo) +    virtual 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, +                                        audio_format_t format, +                                        audio_channel_mask_t channelMask, +                                        audio_output_flags_t flags, +                                        const audio_offload_info_t *offloadInfo)          {              Parcel data, reply;              data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());              if (attr == NULL) { -                ALOGE("Writing NULL audio attributes - shouldn't happen"); -                return (audio_io_handle_t) 0; +                if (stream == NULL) { +                    ALOGE("getOutputForAttr(): NULL audio attributes and stream type"); +                    return BAD_VALUE; +                } +                if (*stream == AUDIO_STREAM_DEFAULT) { +                    ALOGE("getOutputForAttr unspecified stream type"); +                    return BAD_VALUE; +                } +            } +            if (output == NULL) { +                ALOGE("getOutputForAttr NULL output - shouldn't happen"); +                return BAD_VALUE; +            } +            if (attr == NULL) { +                data.writeInt32(0); +            } else { +                data.writeInt32(1); +                data.write(attr, sizeof(audio_attributes_t)); +            } +            data.writeInt32(session); +            if (stream == NULL) { +                data.writeInt32(0); +            } else { +                data.writeInt32(1); +                data.writeInt32(*stream);              } -            data.write(attr, sizeof(audio_attributes_t));              data.writeInt32(samplingRate);              data.writeInt32(static_cast <uint32_t>(format));              data.writeInt32(channelMask); @@ -188,62 +213,93 @@ public:                  data.writeInt32(1);                  data.write(offloadInfo, sizeof(audio_offload_info_t));              } -            remote()->transact(GET_OUTPUT_FOR_ATTR, data, &reply); -            return static_cast <audio_io_handle_t> (reply.readInt32()); +            status_t status = remote()->transact(GET_OUTPUT_FOR_ATTR, data, &reply); +            if (status != NO_ERROR) { +                return status; +            } +            status = (status_t)reply.readInt32(); +            if (status != NO_ERROR) { +                return status; +            } +            *output = (audio_io_handle_t)reply.readInt32(); +            if (stream != NULL) { +                *stream = (audio_stream_type_t)reply.readInt32(); +            } +            return status;          }      virtual status_t startOutput(audio_io_handle_t output,                                   audio_stream_type_t stream, -                                 int session) +                                 audio_session_t session)      {          Parcel data, reply;          data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());          data.writeInt32(output);          data.writeInt32((int32_t) stream); -        data.writeInt32(session); +        data.writeInt32((int32_t)session);          remote()->transact(START_OUTPUT, data, &reply);          return static_cast <status_t> (reply.readInt32());      }      virtual status_t stopOutput(audio_io_handle_t output,                                  audio_stream_type_t stream, -                                int session) +                                audio_session_t session)      {          Parcel data, reply;          data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());          data.writeInt32(output);          data.writeInt32((int32_t) stream); -        data.writeInt32(session); +        data.writeInt32((int32_t)session);          remote()->transact(STOP_OUTPUT, data, &reply);          return static_cast <status_t> (reply.readInt32());      } -    virtual void releaseOutput(audio_io_handle_t output) +    virtual void releaseOutput(audio_io_handle_t output, +                               audio_stream_type_t stream, +                               audio_session_t session)      {          Parcel data, reply;          data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());          data.writeInt32(output); +        data.writeInt32((int32_t)stream); +        data.writeInt32((int32_t)session);          remote()->transact(RELEASE_OUTPUT, data, &reply);      } -    virtual audio_io_handle_t getInput( -                                    audio_source_t inputSource, -                                    uint32_t samplingRate, -                                    audio_format_t format, -                                    audio_channel_mask_t channelMask, -                                    int audioSession, -                                    audio_input_flags_t flags) +    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)      {          Parcel data, reply;          data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); -        data.writeInt32((int32_t) inputSource); +        if (attr == NULL) { +            ALOGE("getInputForAttr NULL attr - shouldn't happen"); +            return BAD_VALUE; +        } +        if (input == NULL) { +            ALOGE("getInputForAttr NULL input - shouldn't happen"); +            return BAD_VALUE; +        } +        data.write(attr, sizeof(audio_attributes_t)); +        data.writeInt32(session);          data.writeInt32(samplingRate);          data.writeInt32(static_cast <uint32_t>(format));          data.writeInt32(channelMask); -        data.writeInt32(audioSession);          data.writeInt32(flags); -        remote()->transact(GET_INPUT, data, &reply); -        return static_cast <audio_io_handle_t> (reply.readInt32()); +        status_t status = remote()->transact(GET_INPUT_FOR_ATTR, data, &reply); +        if (status != NO_ERROR) { +            return status; +        } +        status = reply.readInt32(); +        if (status != NO_ERROR) { +            return status; +        } +        *input = (audio_io_handle_t)reply.readInt32(); +        return NO_ERROR;      }      virtual status_t startInput(audio_io_handle_t input, @@ -622,6 +678,38 @@ public:          }          return (audio_mode_t)reply.readInt32();      } + +    virtual status_t registerPolicyMixes(Vector<AudioMix> mixes, bool registration) +    { +        Parcel data, reply; +        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); +        data.writeInt32(registration ? 1 : 0); +        size_t size = mixes.size(); +        if (size > MAX_MIXES_PER_POLICY) { +            size = MAX_MIXES_PER_POLICY; +        } +        size_t sizePosition = data.dataPosition(); +        data.writeInt32(size); +        size_t finalSize = size; +        for (size_t i = 0; i < size; i++) { +            size_t position = data.dataPosition(); +            if (mixes[i].writeToParcel(&data) != NO_ERROR) { +                data.setDataPosition(position); +                finalSize--; +            } +        } +        if (size != finalSize) { +            size_t position = data.dataPosition(); +            data.setDataPosition(sizePosition); +            data.writeInt32(finalSize); +            data.setDataPosition(position); +        } +        status_t status = remote()->transact(REGISTER_POLICY_MIXES, data, &reply); +        if (status == NO_ERROR) { +            status = (status_t)reply.readInt32(); +        } +        return status; +    }  };  IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService"); @@ -707,8 +795,17 @@ status_t BnAudioPolicyService::onTransact(          case GET_OUTPUT_FOR_ATTR: {              CHECK_INTERFACE(IAudioPolicyService, data, reply); -            audio_attributes_t *attr = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t)); -            data.read(attr, sizeof(audio_attributes_t)); +            audio_attributes_t attr; +            bool hasAttributes = data.readInt32() != 0; +            if (hasAttributes) { +                data.read(&attr, sizeof(audio_attributes_t)); +            } +            audio_session_t session = (audio_session_t)data.readInt32(); +            audio_stream_type_t stream = AUDIO_STREAM_DEFAULT; +            bool hasStream = data.readInt32() != 0; +            if (hasStream) { +                stream = (audio_stream_type_t)data.readInt32(); +            }              uint32_t samplingRate = data.readInt32();              audio_format_t format = (audio_format_t) data.readInt32();              audio_channel_mask_t channelMask = data.readInt32(); @@ -719,13 +816,14 @@ status_t BnAudioPolicyService::onTransact(              if (hasOffloadInfo) {                  data.read(&offloadInfo, sizeof(audio_offload_info_t));              } -            audio_io_handle_t output = getOutputForAttr(attr, -                    samplingRate, -                    format, -                    channelMask, -                    flags, -                    hasOffloadInfo ? &offloadInfo : NULL); -            reply->writeInt32(static_cast <int>(output)); +            audio_io_handle_t output; +            status_t status = getOutputForAttr(hasAttributes ? &attr : NULL, +                    &output, session, &stream, +                    samplingRate, format, channelMask, +                    flags, hasOffloadInfo ? &offloadInfo : NULL); +            reply->writeInt32(status); +            reply->writeInt32(output); +            reply->writeInt32(stream);              return NO_ERROR;          } break; @@ -734,7 +832,7 @@ status_t BnAudioPolicyService::onTransact(              audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32());              audio_stream_type_t stream =                                  static_cast <audio_stream_type_t>(data.readInt32()); -            int session = data.readInt32(); +            audio_session_t session = (audio_session_t)data.readInt32();              reply->writeInt32(static_cast <uint32_t>(startOutput(output,                                                                   stream,                                                                   session))); @@ -746,7 +844,7 @@ status_t BnAudioPolicyService::onTransact(              audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32());              audio_stream_type_t stream =                                  static_cast <audio_stream_type_t>(data.readInt32()); -            int session = data.readInt32(); +            audio_session_t session = (audio_session_t)data.readInt32();              reply->writeInt32(static_cast <uint32_t>(stopOutput(output,                                                                  stream,                                                                  session))); @@ -756,25 +854,29 @@ status_t BnAudioPolicyService::onTransact(          case RELEASE_OUTPUT: {              CHECK_INTERFACE(IAudioPolicyService, data, reply);              audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32()); -            releaseOutput(output); +            audio_stream_type_t stream = (audio_stream_type_t)data.readInt32(); +            audio_session_t session = (audio_session_t)data.readInt32(); +            releaseOutput(output, stream, session);              return NO_ERROR;          } break; -        case GET_INPUT: { +        case GET_INPUT_FOR_ATTR: {              CHECK_INTERFACE(IAudioPolicyService, data, reply); -            audio_source_t inputSource = (audio_source_t) data.readInt32(); +            audio_attributes_t attr; +            data.read(&attr, sizeof(audio_attributes_t)); +            audio_session_t session = (audio_session_t)data.readInt32();              uint32_t samplingRate = data.readInt32();              audio_format_t format = (audio_format_t) data.readInt32();              audio_channel_mask_t channelMask = data.readInt32(); -            int audioSession = data.readInt32();              audio_input_flags_t flags = (audio_input_flags_t) data.readInt32(); -            audio_io_handle_t input = getInput(inputSource, -                                               samplingRate, -                                               format, -                                               channelMask, -                                               audioSession, -                                               flags); -            reply->writeInt32(static_cast <int>(input)); +            audio_io_handle_t input; +            status_t status = getInputForAttr(&attr, &input, session, +                                              samplingRate, format, channelMask, +                                              flags); +            reply->writeInt32(status); +            if (status == NO_ERROR) { +                reply->writeInt32(input); +            }              return NO_ERROR;          } break; @@ -1096,6 +1198,25 @@ status_t BnAudioPolicyService::onTransact(              return NO_ERROR;          } break; +        case REGISTER_POLICY_MIXES: { +            CHECK_INTERFACE(IAudioPolicyService, data, reply); +            bool registration = data.readInt32() == 1; +            Vector<AudioMix> mixes; +            size_t size = (size_t)data.readInt32(); +            if (size > MAX_MIXES_PER_POLICY) { +                size = MAX_MIXES_PER_POLICY; +            } +            for (size_t i = 0; i < size; i++) { +                AudioMix mix; +                if (mix.readFromParcel((Parcel*)&data) == NO_ERROR) { +                    mixes.add(mix); +                } +            } +            status_t status = registerPolicyMixes(mixes, registration); +            reply->writeInt32(status); +            return NO_ERROR; +        } break; +          default:              return BBinder::onTransact(code, data, reply, flags);      } diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp index 7bd120e..f7d8bc6 100644 --- a/media/libmedia/ICrypto.cpp +++ b/media/libmedia/ICrypto.cpp @@ -33,6 +33,7 @@ enum {      DESTROY_PLUGIN,      REQUIRES_SECURE_COMPONENT,      DECRYPT, +    NOTIFY_RESOLUTION,  };  struct BpCrypto : public BpInterface<ICrypto> { @@ -149,6 +150,15 @@ struct BpCrypto : public BpInterface<ICrypto> {          return result;      } +    virtual void notifyResolution( +        uint32_t width, uint32_t height) { +        Parcel data, reply; +        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); +        data.writeInt32(width); +        data.writeInt32(height); +        remote()->transact(NOTIFY_RESOLUTION, data, &reply); +    } +  private:      DISALLOW_EVIL_CONSTRUCTORS(BpCrypto);  }; @@ -290,10 +300,20 @@ status_t BnCrypto::onTransact(              return OK;          } +        case NOTIFY_RESOLUTION: +        { +            CHECK_INTERFACE(ICrypto, data, reply); + +            int32_t width = data.readInt32(); +            int32_t height = data.readInt32(); +            notifyResolution(width, height); + +            return OK; +        } +          default:              return BBinder::onTransact(code, data, reply, flags);      }  }  }  // namespace android - diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp index 1904839..7e74de9 100644 --- a/media/libmedia/IDrm.cpp +++ b/media/libmedia/IDrm.cpp @@ -54,7 +54,9 @@ enum {      SIGN_RSA,      VERIFY,      SET_LISTENER, -    UNPROVISION_DEVICE +    UNPROVISION_DEVICE, +    GET_SECURE_STOP, +    RELEASE_ALL_SECURE_STOPS  };  struct BpDrm : public BpInterface<IDrm> { @@ -255,6 +257,17 @@ struct BpDrm : public BpInterface<IDrm> {          return reply.readInt32();      } +    virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) { +        Parcel data, reply; +        data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); + +        writeVector(data, ssid); +        remote()->transact(GET_SECURE_STOP, data, &reply); + +        readVector(reply, secureStop); +        return reply.readInt32(); +    } +      virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) {          Parcel data, reply;          data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); @@ -265,6 +278,15 @@ struct BpDrm : public BpInterface<IDrm> {          return reply.readInt32();      } +    virtual status_t releaseAllSecureStops() { +        Parcel data, reply; +        data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); + +        remote()->transact(RELEASE_ALL_SECURE_STOPS, data, &reply); + +        return reply.readInt32(); +    } +      virtual status_t getPropertyString(String8 const &name, String8 &value) const {          Parcel data, reply;          data.writeInterfaceToken(IDrm::getInterfaceDescriptor()); @@ -655,6 +677,17 @@ status_t BnDrm::onTransact(              return OK;          } +        case GET_SECURE_STOP: +        { +            CHECK_INTERFACE(IDrm, data, reply); +            Vector<uint8_t> ssid, secureStop; +            readVector(data, ssid); +            status_t result = getSecureStop(ssid, secureStop); +            writeVector(reply, secureStop); +            reply->writeInt32(result); +            return OK; +        } +          case RELEASE_SECURE_STOPS:          {              CHECK_INTERFACE(IDrm, data, reply); @@ -664,6 +697,13 @@ status_t BnDrm::onTransact(              return OK;          } +        case RELEASE_ALL_SECURE_STOPS: +        { +            CHECK_INTERFACE(IDrm, data, reply); +            reply->writeInt32(releaseAllSecureStops()); +            return OK; +        } +          case GET_PROPERTY_STRING:          {              CHECK_INTERFACE(IDrm, data, reply); @@ -809,4 +849,3 @@ status_t BnDrm::onTransact(  }  }  // namespace android - diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp index c146b8d..f91e3e4 100644 --- a/media/libmedia/Visualizer.cpp +++ b/media/libmedia/Visualizer.cpp @@ -52,6 +52,13 @@ Visualizer::Visualizer (int32_t priority,  Visualizer::~Visualizer()  { +    ALOGV("Visualizer::~Visualizer()"); +    if (mCaptureThread != NULL) { +        mCaptureThread->requestExitAndWait(); +        mCaptureThread.clear(); +    } +    mCaptureCallBack = NULL; +    mCaptureFlags = 0;  }  status_t Visualizer::setEnabled(bool enabled) @@ -102,20 +109,18 @@ status_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t          return INVALID_OPERATION;      } -    sp<CaptureThread> t = mCaptureThread; -    if (t != 0) { -        t->mLock.lock(); +    if (mCaptureThread != 0) { +        mCaptureLock.unlock(); +        mCaptureThread->requestExitAndWait(); +        mCaptureLock.lock();      } +      mCaptureThread.clear();      mCaptureCallBack = cbk;      mCaptureCbkUser = user;      mCaptureFlags = flags;      mCaptureRate = rate; -    if (t != 0) { -        t->mLock.unlock(); -    } -      if (cbk != NULL) {          mCaptureThread = new CaptureThread(*this, rate, ((flags & CAPTURE_CALL_JAVA) != 0));      } diff --git a/media/libmediaplayerservice/Crypto.cpp b/media/libmediaplayerservice/Crypto.cpp index 62593b2..8ee7c0b 100644 --- a/media/libmediaplayerservice/Crypto.cpp +++ b/media/libmediaplayerservice/Crypto.cpp @@ -257,4 +257,12 @@ ssize_t Crypto::decrypt(              errorDetailMsg);  } +void Crypto::notifyResolution(uint32_t width, uint32_t height) { +    Mutex::Autolock autoLock(mLock); + +    if (mInitCheck == OK && mPlugin != NULL) { +        mPlugin->notifyResolution(width, height); +    } +} +  }  // namespace android diff --git a/media/libmediaplayerservice/Crypto.h b/media/libmediaplayerservice/Crypto.h index c44ae34..0037c2e 100644 --- a/media/libmediaplayerservice/Crypto.h +++ b/media/libmediaplayerservice/Crypto.h @@ -45,6 +45,8 @@ struct Crypto : public BnCrypto {      virtual bool requiresSecureDecoderComponent(              const char *mime) const; +    virtual void notifyResolution(uint32_t width, uint32_t height); +      virtual ssize_t decrypt(              bool secure,              const uint8_t key[16], diff --git a/media/libmediaplayerservice/Drm.cpp b/media/libmediaplayerservice/Drm.cpp index d222316..ac948a6 100644 --- a/media/libmediaplayerservice/Drm.cpp +++ b/media/libmediaplayerservice/Drm.cpp @@ -46,6 +46,7 @@ static bool checkPermission(const char* permissionString) {  KeyedVector<Vector<uint8_t>, String8> Drm::mUUIDToLibraryPathMap;  KeyedVector<String8, wp<SharedLibrary> > Drm::mLibraryPathToOpenLibraryMap;  Mutex Drm::mMapLock; +Mutex Drm::mLock;  static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {      if (lhs.size() < rhs.size()) { @@ -449,6 +450,20 @@ status_t Drm::getSecureStops(List<Vector<uint8_t> > &secureStops) {      return mPlugin->getSecureStops(secureStops);  } +status_t Drm::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) { +    Mutex::Autolock autoLock(mLock); + +    if (mInitCheck != OK) { +        return mInitCheck; +    } + +    if (mPlugin == NULL) { +        return -EINVAL; +    } + +    return mPlugin->getSecureStop(ssid, secureStop); +} +  status_t Drm::releaseSecureStops(Vector<uint8_t> const &ssRelease) {      Mutex::Autolock autoLock(mLock); @@ -463,6 +478,20 @@ status_t Drm::releaseSecureStops(Vector<uint8_t> const &ssRelease) {      return mPlugin->releaseSecureStops(ssRelease);  } +status_t Drm::releaseAllSecureStops() { +    Mutex::Autolock autoLock(mLock); + +    if (mInitCheck != OK) { +        return mInitCheck; +    } + +    if (mPlugin == NULL) { +        return -EINVAL; +    } + +    return mPlugin->releaseAllSecureStops(); +} +  status_t Drm::getPropertyString(String8 const &name, String8 &value ) const {      Mutex::Autolock autoLock(mLock); @@ -646,10 +675,14 @@ status_t Drm::signRSA(Vector<uint8_t> const &sessionId,  void Drm::binderDied(const wp<IBinder> &the_late_who)  { +    mEventLock.lock(); +    mListener.clear(); +    mEventLock.unlock(); + +    Mutex::Autolock autoLock(mLock);      delete mPlugin;      mPlugin = NULL;      closeFactory(); -    mListener.clear();  }  }  // namespace android diff --git a/media/libmediaplayerservice/Drm.h b/media/libmediaplayerservice/Drm.h index 9e23e2e..2997da1 100644 --- a/media/libmediaplayerservice/Drm.h +++ b/media/libmediaplayerservice/Drm.h @@ -78,8 +78,10 @@ struct Drm : public BnDrm,      virtual status_t unprovisionDevice();      virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops); +    virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop);      virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease); +    virtual status_t releaseAllSecureStops();      virtual status_t getPropertyString(String8 const &name, String8 &value ) const;      virtual status_t getPropertyByteArray(String8 const &name, @@ -132,7 +134,7 @@ struct Drm : public BnDrm,      virtual void binderDied(const wp<IBinder> &the_late_who);  private: -    mutable Mutex mLock; +    static Mutex mLock;      status_t mInitCheck; diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp index 3e0fc0d..aeefb4c 100644 --- a/media/libmediaplayerservice/MediaPlayerFactory.cpp +++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp @@ -20,9 +20,12 @@  #include <cutils/properties.h>  #include <media/IMediaPlayer.h> +#include <media/stagefright/DataSource.h> +#include <media/stagefright/FileSource.h>  #include <media/stagefright/foundation/ADebug.h>  #include <utils/Errors.h>  #include <utils/misc.h> +#include <../libstagefright/include/WVMExtractor.h>  #include "MediaPlayerFactory.h" @@ -179,10 +182,18 @@ class StagefrightPlayerFactory :      virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,                                 int fd,                                 int64_t offset, -                               int64_t /*length*/, +                               int64_t length,                                 float /*curScore*/) { -        if (getDefaultPlayerType() -                == STAGEFRIGHT_PLAYER) { +        if (legacyDrm()) { +            sp<DataSource> source = new FileSource(dup(fd), offset, length); +            String8 mimeType; +            float confidence; +            if (SniffWVM(source, &mimeType, &confidence, NULL /* format */)) { +                return 1.0; +            } +        } + +        if (getDefaultPlayerType() == STAGEFRIGHT_PLAYER) {              char buf[20];              lseek(fd, offset, SEEK_SET);              read(fd, buf, sizeof(buf)); @@ -198,10 +209,28 @@ class StagefrightPlayerFactory :          return 0.0;      } +    virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, +                               const char* url, +                               float /*curScore*/) { +        if (legacyDrm() && !strncasecmp("widevine://", url, 11)) { +            return 1.0; +        } +        return 0.0; +    } +      virtual sp<MediaPlayerBase> createPlayer() {          ALOGV(" create StagefrightPlayer");          return new StagefrightPlayer();      } +  private: +    bool legacyDrm() { +        char value[PROPERTY_VALUE_MAX]; +        if (property_get("persist.sys.media.legacy-drm", value, NULL) +                && (!strcmp("1", value) || !strcasecmp("true", value))) { +            return true; +        } +        return false; +    }  };  class NuPlayerFactory : public MediaPlayerFactory::IFactory { diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 8eb1269..d461af3 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -2125,6 +2125,7 @@ ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size)          // immutable with respect to future writes.          //          // It is thus safe for another thread to read the AudioCache. +        Mutex::Autolock lock(mLock);          mCommandComplete = true;          mSignal.signal();      } @@ -2159,7 +2160,6 @@ void MediaPlayerService::AudioCache::notify(      {      case MEDIA_ERROR:          ALOGE("Error %d, %d occurred", ext1, ext2); -        p->mError = ext1;          break;      case MEDIA_PREPARED:          ALOGV("prepared"); @@ -2174,6 +2174,9 @@ void MediaPlayerService::AudioCache::notify(      // wake up thread      Mutex::Autolock lock(p->mLock); +    if (msg == MEDIA_ERROR) { +        p->mError = ext1; +    }      p->mCommandComplete = true;      p->mSignal.signal();  } diff --git a/media/libmediaplayerservice/MidiFile.cpp b/media/libmediaplayerservice/MidiFile.cpp index 749ef96..60cbd3c 100644 --- a/media/libmediaplayerservice/MidiFile.cpp +++ b/media/libmediaplayerservice/MidiFile.cpp @@ -293,7 +293,7 @@ bool MidiFile::isPlaying()  {      ALOGV("MidiFile::isPlaying, mState=%d", int(mState));      if (!mEasHandle || mPaused) return false; -    return (mState == EAS_STATE_PLAY); +    return (mState == EAS_STATE_PLAY || (mState == EAS_STATE_READY && mRender));  }  status_t MidiFile::getCurrentPosition(int* position) diff --git a/media/libmediaplayerservice/nuplayer/Android.mk b/media/libmediaplayerservice/nuplayer/Android.mk index 676c0a6..6609874 100644 --- a/media/libmediaplayerservice/nuplayer/Android.mk +++ b/media/libmediaplayerservice/nuplayer/Android.mk @@ -5,7 +5,9 @@ LOCAL_SRC_FILES:=                       \          GenericSource.cpp               \          HTTPLiveSource.cpp              \          NuPlayer.cpp                    \ +        NuPlayerCCDecoder.cpp           \          NuPlayerDecoder.cpp             \ +        NuPlayerDecoderBase.cpp         \          NuPlayerDecoderPassThrough.cpp  \          NuPlayerDriver.cpp              \          NuPlayerRenderer.cpp            \ diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index 6859a1a..1b2fc5e 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -40,35 +40,50 @@  namespace android { +static int64_t kLowWaterMarkUs = 2000000ll;  // 2secs +static int64_t kHighWaterMarkUs = 5000000ll;  // 5secs +static const ssize_t kLowWaterMarkBytes = 40000; +static const ssize_t kHighWaterMarkBytes = 200000; +  NuPlayer::GenericSource::GenericSource(          const sp<AMessage> ¬ify,          bool uidValid,          uid_t uid)      : Source(notify), +      mAudioTimeUs(0), +      mAudioLastDequeueTimeUs(0), +      mVideoTimeUs(0), +      mVideoLastDequeueTimeUs(0),        mFetchSubtitleDataGeneration(0),        mFetchTimedTextDataGeneration(0),        mDurationUs(0ll),        mAudioIsVorbis(false),        mIsWidevine(false), +      mIsSecure(false), +      mIsStreaming(false),        mUIDValid(uidValid),        mUID(uid), +      mFd(-1),        mDrmManagerClient(NULL),        mMetaDataSize(-1ll),        mBitrate(-1ll),        mPollBufferingGeneration(0), -      mPendingReadBufferTypes(0) { +      mPendingReadBufferTypes(0), +      mBuffering(false), +      mPrepareBuffering(false) {      resetDataSource();      DataSource::RegisterDefaultSniffers();  }  void NuPlayer::GenericSource::resetDataSource() { -    mAudioTimeUs = 0; -    mVideoTimeUs = 0;      mHTTPService.clear();      mHttpSource.clear();      mUri.clear();      mUriHeaders.clear(); -    mFd = -1; +    if (mFd >= 0) { +        close(mFd); +        mFd = -1; +    }      mOffset = 0;      mLength = 0;      setDrmPlaybackStatusIfNeeded(Playback::STOP, 0); @@ -157,6 +172,25 @@ status_t NuPlayer::GenericSource::initFromDataSource() {          if (mFileMeta->findInt64(kKeyDuration, &duration)) {              mDurationUs = duration;          } + +        if (!mIsWidevine) { +            // Check mime to see if we actually have a widevine source. +            // If the data source is not URL-type (eg. file source), we +            // won't be able to tell until now. +            const char *fileMime; +            if (mFileMeta->findCString(kKeyMIMEType, &fileMime) +                    && !strncasecmp(fileMime, "video/wvm", 9)) { +                mIsWidevine = true; +                if (!mUri.empty()) { +                  // streaming, but the app forgot to specify widevine:// url +                  mWVMExtractor = static_cast<WVMExtractor *>(extractor.get()); +                  mWVMExtractor->setAdaptiveStreamingMode(true); +                  if (mUIDValid) { +                    mWVMExtractor->setUID(mUID); +                  } +                } +            } +        }      }      int32_t totalBitrate = 0; @@ -202,7 +236,7 @@ status_t NuPlayer::GenericSource::initFromDataSource() {                  int32_t secure;                  if (meta->findInt32(kKeyRequiresSecureBuffers, &secure)                          && secure) { -                    mIsWidevine = true; +                    mIsSecure = true;                      if (mUIDValid) {                          extractor->setUID(mUID);                      } @@ -233,6 +267,24 @@ status_t NuPlayer::GenericSource::initFromDataSource() {      return OK;  } +status_t NuPlayer::GenericSource::startSources() { +    // Start the selected A/V tracks now before we start buffering. +    // Widevine sources might re-initialize crypto when starting, if we delay +    // this to start(), all data buffered during prepare would be wasted. +    // (We don't actually start reading until start().) +    if (mAudioTrack.mSource != NULL && mAudioTrack.mSource->start() != OK) { +        ALOGE("failed to start audio track!"); +        return UNKNOWN_ERROR; +    } + +    if (mVideoTrack.mSource != NULL && mVideoTrack.mSource->start() != OK) { +        ALOGE("failed to start video track!"); +        return UNKNOWN_ERROR; +    } + +    return OK; +} +  void NuPlayer::GenericSource::checkDrmStatus(const sp<DataSource>& dataSource) {      dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);      if (mDecryptHandle != NULL) { @@ -257,7 +309,7 @@ int64_t NuPlayer::GenericSource::getLastReadPosition() {  status_t NuPlayer::GenericSource::setBuffers(          bool audio, Vector<MediaBuffer *> &buffers) { -    if (mIsWidevine && !audio) { +    if (mIsSecure && !audio) {          return mVideoTrack.mSource->setBuffers(buffers);      }      return INVALID_OPERATION; @@ -268,6 +320,7 @@ NuPlayer::GenericSource::~GenericSource() {          mLooper->unregisterHandler(id());          mLooper->stop();      } +    resetDataSource();  }  void NuPlayer::GenericSource::prepareAsync() { @@ -286,6 +339,10 @@ void NuPlayer::GenericSource::prepareAsync() {  void NuPlayer::GenericSource::onPrepareAsync() {      // delayed data source creation      if (mDataSource == NULL) { +        // set to false first, if the extractor +        // comes back as secure, set it to true then. +        mIsSecure = false; +          if (!mUri.empty()) {              const char* uri = mUri.c_str();              mIsWidevine = !strncasecmp(uri, "widevine://", 11); @@ -305,11 +362,10 @@ void NuPlayer::GenericSource::onPrepareAsync() {                     mHTTPService, uri, &mUriHeaders, &mContentType,                     static_cast<HTTPBase *>(mHttpSource.get()));          } else { -            // set to false first, if the extractor -            // comes back as secure, set it to true then.              mIsWidevine = false;              mDataSource = new FileSource(mFd, mOffset, mLength); +            mFd = -1;          }          if (mDataSource == NULL) { @@ -322,9 +378,13 @@ void NuPlayer::GenericSource::onPrepareAsync() {              mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());          } -        if (mIsWidevine || mCachedSource != NULL) { -            schedulePollBuffering(); -        } +        // For widevine or other cached streaming cases, we need to wait for +        // enough buffering before reporting prepared. +        // Note that even when URL doesn't start with widevine://, mIsWidevine +        // could still be set to true later, if the streaming or file source +        // is sniffed to be widevine. We don't want to buffer for file source +        // in that case, so must check the flag now. +        mIsStreaming = (mIsWidevine || mCachedSource != NULL);      }      // check initial caching status @@ -360,13 +420,47 @@ void NuPlayer::GenericSource::onPrepareAsync() {      }      notifyFlagsChanged( -            (mIsWidevine ? FLAG_SECURE : 0) +            (mIsSecure ? FLAG_SECURE : 0) +            | (mDecryptHandle != NULL ? FLAG_PROTECTED : 0)              | FLAG_CAN_PAUSE              | FLAG_CAN_SEEK_BACKWARD              | FLAG_CAN_SEEK_FORWARD              | FLAG_CAN_SEEK); -    notifyPrepared(); +    if (mIsSecure) { +        // secure decoders must be instantiated before starting widevine source +        sp<AMessage> reply = new AMessage(kWhatSecureDecodersInstantiated, id()); +        notifyInstantiateSecureDecoders(reply); +    } else { +        finishPrepareAsync(); +    } +} + +void NuPlayer::GenericSource::onSecureDecodersInstantiated(status_t err) { +    if (err != OK) { +        ALOGE("Failed to instantiate secure decoders!"); +        notifyPreparedAndCleanup(err); +        return; +    } +    finishPrepareAsync(); +} + +void NuPlayer::GenericSource::finishPrepareAsync() { +    status_t err = startSources(); +    if (err != OK) { +        ALOGE("Failed to init start data source!"); +        notifyPreparedAndCleanup(err); +        return; +    } + +    if (mIsStreaming) { +        mPrepareBuffering = true; + +        ensureCacheIsFetching(); +        restartPollBuffering(); +    } else { +        notifyPrepared(); +    }  }  void NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) { @@ -377,6 +471,7 @@ void NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) {          mDataSource.clear();          mCachedSource.clear();          mHttpSource.clear(); +        mBitrate = -1;          cancelPollBuffering();      } @@ -458,27 +553,25 @@ void NuPlayer::GenericSource::start() {      mStopRead = false;      if (mAudioTrack.mSource != NULL) { -        CHECK_EQ(mAudioTrack.mSource->start(), (status_t)OK); -          postReadBuffer(MEDIA_TRACK_TYPE_AUDIO);      }      if (mVideoTrack.mSource != NULL) { -        CHECK_EQ(mVideoTrack.mSource->start(), (status_t)OK); -          postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);      }      setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);      mStarted = true; + +    (new AMessage(kWhatStart, id()))->post();  }  void NuPlayer::GenericSource::stop() {      // nothing to do, just account for DRM playback status      setDrmPlaybackStatusIfNeeded(Playback::STOP, 0);      mStarted = false; -    if (mIsWidevine) { -        // For a widevine source we need to prevent any further reads. +    if (mIsWidevine || mIsSecure) { +        // For widevine or secure sources we need to prevent any further reads.          sp<AMessage> msg = new AMessage(kWhatStopWidevine, id());          sp<AMessage> response;          (void) msg->postAndAwaitResponse(&response); @@ -495,6 +588,8 @@ void NuPlayer::GenericSource::resume() {      // nothing to do, just account for DRM playback status      setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);      mStarted = true; + +    (new AMessage(kWhatResume, id()))->post();  }  void NuPlayer::GenericSource::disconnect() { @@ -527,22 +622,98 @@ void NuPlayer::GenericSource::schedulePollBuffering() {  }  void NuPlayer::GenericSource::cancelPollBuffering() { +    mBuffering = false;      ++mPollBufferingGeneration;  } +void NuPlayer::GenericSource::restartPollBuffering() { +    if (mIsStreaming) { +        cancelPollBuffering(); +        onPollBuffering(); +    } +} +  void NuPlayer::GenericSource::notifyBufferingUpdate(int percentage) { +    ALOGV("notifyBufferingUpdate: buffering %d%%", percentage); +      sp<AMessage> msg = dupNotify();      msg->setInt32("what", kWhatBufferingUpdate);      msg->setInt32("percentage", percentage);      msg->post();  } +void NuPlayer::GenericSource::startBufferingIfNecessary() { +    ALOGV("startBufferingIfNecessary: mPrepareBuffering=%d, mBuffering=%d", +            mPrepareBuffering, mBuffering); + +    if (mPrepareBuffering) { +        return; +    } + +    if (!mBuffering) { +        mBuffering = true; + +        ensureCacheIsFetching(); +        sendCacheStats(); + +        sp<AMessage> notify = dupNotify(); +        notify->setInt32("what", kWhatPauseOnBufferingStart); +        notify->post(); +    } +} + +void NuPlayer::GenericSource::stopBufferingIfNecessary() { +    ALOGV("stopBufferingIfNecessary: mPrepareBuffering=%d, mBuffering=%d", +            mPrepareBuffering, mBuffering); + +    if (mPrepareBuffering) { +        mPrepareBuffering = false; +        notifyPrepared(); +        return; +    } + +    if (mBuffering) { +        mBuffering = false; + +        sendCacheStats(); + +        sp<AMessage> notify = dupNotify(); +        notify->setInt32("what", kWhatResumeOnBufferingEnd); +        notify->post(); +    } +} + +void NuPlayer::GenericSource::sendCacheStats() { +    int32_t kbps = 0; +    status_t err = UNKNOWN_ERROR; + +    if (mCachedSource != NULL) { +        err = mCachedSource->getEstimatedBandwidthKbps(&kbps); +    } else if (mWVMExtractor != NULL) { +        err = mWVMExtractor->getEstimatedBandwidthKbps(&kbps); +    } + +    if (err == OK) { +        sp<AMessage> notify = dupNotify(); +        notify->setInt32("what", kWhatCacheStats); +        notify->setInt32("bandwidth", kbps); +        notify->post(); +    } +} + +void NuPlayer::GenericSource::ensureCacheIsFetching() { +    if (mCachedSource != NULL) { +        mCachedSource->resumeFetchingIfNecessary(); +    } +} +  void NuPlayer::GenericSource::onPollBuffering() {      status_t finalStatus = UNKNOWN_ERROR; -    int64_t cachedDurationUs = 0ll; +    int64_t cachedDurationUs = -1ll; +    ssize_t cachedDataRemaining = -1;      if (mCachedSource != NULL) { -        size_t cachedDataRemaining = +        cachedDataRemaining =                  mCachedSource->approxDataRemaining(&finalStatus);          if (finalStatus == OK) { @@ -562,23 +733,48 @@ void NuPlayer::GenericSource::onPollBuffering() {              = mWVMExtractor->getCachedDurationUs(&finalStatus);      } -    if (finalStatus == ERROR_END_OF_STREAM) { -        notifyBufferingUpdate(100); -        cancelPollBuffering(); +    if (finalStatus != OK) { +        ALOGV("onPollBuffering: EOS (finalStatus = %d)", finalStatus); + +        if (finalStatus == ERROR_END_OF_STREAM) { +            notifyBufferingUpdate(100); +        } + +        stopBufferingIfNecessary();          return; -    } else if (cachedDurationUs > 0ll && mDurationUs > 0ll) { -        int percentage = 100.0 * cachedDurationUs / mDurationUs; -        if (percentage > 100) { -            percentage = 100; +    } else if (cachedDurationUs >= 0ll) { +        if (mDurationUs > 0ll) { +            int64_t cachedPosUs = getLastReadPosition() + cachedDurationUs; +            int percentage = 100.0 * cachedPosUs / mDurationUs; +            if (percentage > 100) { +                percentage = 100; +            } + +            notifyBufferingUpdate(percentage);          } -        notifyBufferingUpdate(percentage); +        ALOGV("onPollBuffering: cachedDurationUs %.1f sec", +                cachedDurationUs / 1000000.0f); + +        if (cachedDurationUs < kLowWaterMarkUs) { +            startBufferingIfNecessary(); +        } else if (cachedDurationUs > kHighWaterMarkUs) { +            stopBufferingIfNecessary(); +        } +    } else if (cachedDataRemaining >= 0) { +        ALOGV("onPollBuffering: cachedDataRemaining %d bytes", +                cachedDataRemaining); + +        if (cachedDataRemaining < kLowWaterMarkBytes) { +            startBufferingIfNecessary(); +        } else if (cachedDataRemaining > kHighWaterMarkBytes) { +            stopBufferingIfNecessary(); +        }      }      schedulePollBuffering();  } -  void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) {      switch (msg->what()) {        case kWhatPrepareAsync: @@ -644,23 +840,27 @@ void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) {            track->mSource->start();            track->mIndex = trackIndex; -          status_t avail; -          if (!track->mPackets->hasBufferAvailable(&avail)) { -              // sync from other source -              TRESPASS(); -              break; -          } -            int64_t timeUs, actualTimeUs;            const bool formatChange = true; -          sp<AMessage> latestMeta = track->mPackets->getLatestEnqueuedMeta(); -          CHECK(latestMeta != NULL && latestMeta->findInt64("timeUs", &timeUs)); +          if (trackType == MEDIA_TRACK_TYPE_AUDIO) { +              timeUs = mAudioLastDequeueTimeUs; +          } else { +              timeUs = mVideoLastDequeueTimeUs; +          }            readBuffer(trackType, timeUs, &actualTimeUs, formatChange);            readBuffer(counterpartType, -1, NULL, formatChange);            ALOGV("timeUs %lld actualTimeUs %lld", timeUs, actualTimeUs);            break;        } + +      case kWhatStart: +      case kWhatResume: +      { +          restartPollBuffering(); +          break; +      } +        case kWhatPollBuffering:        {            int32_t generation; @@ -701,6 +901,14 @@ void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) {            break;        } +      case kWhatSecureDecodersInstantiated: +      { +          int32_t err; +          CHECK(msg->findInt32("err", &err)); +          onSecureDecodersInstantiated(err); +          break; +      } +        case kWhatStopWidevine:        {            // mStopRead is only used for Widevine to prevent the video source @@ -842,7 +1050,12 @@ status_t NuPlayer::GenericSource::dequeueAccessUnit(      status_t finalResult;      if (!track->mPackets->hasBufferAvailable(&finalResult)) { -        return (finalResult == OK ? -EWOULDBLOCK : finalResult); +        if (finalResult == OK) { +            postReadBuffer( +                    audio ? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO); +            return -EWOULDBLOCK; +        } +        return finalResult;      }      status_t result = track->mPackets->dequeueAccessUnit(accessUnit); @@ -866,6 +1079,11 @@ status_t NuPlayer::GenericSource::dequeueAccessUnit(      int64_t timeUs;      status_t eosResult; // ignored      CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs)); +    if (audio) { +        mAudioLastDequeueTimeUs = timeUs; +    } else { +        mVideoLastDequeueTimeUs = timeUs; +    }      if (mSubtitleTrack.mSource != NULL              && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) { @@ -996,11 +1214,12 @@ ssize_t NuPlayer::GenericSource::doGetSelectedTrack(media_track_type type) const      return -1;  } -status_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select) { +status_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {      ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex);      sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());      msg->setInt32("trackIndex", trackIndex);      msg->setInt32("select", select); +    msg->setInt64("timeUs", timeUs);      sp<AMessage> response;      status_t err = msg->postAndAwaitResponse(&response); @@ -1013,11 +1232,13 @@ status_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select) {  void NuPlayer::GenericSource::onSelectTrack(sp<AMessage> msg) {      int32_t trackIndex, select; +    int64_t timeUs;      CHECK(msg->findInt32("trackIndex", &trackIndex));      CHECK(msg->findInt32("select", &select)); +    CHECK(msg->findInt64("timeUs", &timeUs));      sp<AMessage> response = new AMessage; -    status_t err = doSelectTrack(trackIndex, select); +    status_t err = doSelectTrack(trackIndex, select, timeUs);      response->setInt32("err", err);      uint32_t replyID; @@ -1025,7 +1246,7 @@ void NuPlayer::GenericSource::onSelectTrack(sp<AMessage> msg) {      response->postReply(replyID);  } -status_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select) { +status_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select, int64_t timeUs) {      if (trackIndex >= mSources.size()) {          return BAD_INDEX;      } @@ -1078,6 +1299,23 @@ status_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select)              mFetchTimedTextDataGeneration++;          } +        status_t eosResult; // ignored +        if (mSubtitleTrack.mSource != NULL +                && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) { +            sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id()); +            msg->setInt64("timeUs", timeUs); +            msg->setInt32("generation", mFetchSubtitleDataGeneration); +            msg->post(); +        } + +        if (mTimedTextTrack.mSource != NULL +                && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) { +            sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, id()); +            msg->setInt64("timeUs", timeUs); +            msg->setInt32("generation", mFetchTimedTextDataGeneration); +            msg->post(); +        } +          return OK;      } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) {          bool audio = !strncasecmp(mime, "audio/", 6); @@ -1132,22 +1370,32 @@ status_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs) {          readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, &actualTimeUs);          seekTimeUs = actualTimeUs; +        mVideoLastDequeueTimeUs = seekTimeUs;      }      if (mAudioTrack.mSource != NULL) {          readBuffer(MEDIA_TRACK_TYPE_AUDIO, seekTimeUs); +        mAudioLastDequeueTimeUs = seekTimeUs;      }      setDrmPlaybackStatusIfNeeded(Playback::START, seekTimeUs / 1000);      if (!mStarted) {          setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0);      } + +    // If currently buffering, post kWhatBufferingEnd first, so that +    // NuPlayer resumes. Otherwise, if cache hits high watermark +    // before new polling happens, no one will resume the playback. +    stopBufferingIfNecessary(); +    restartPollBuffering(); +      return OK;  }  sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(          MediaBuffer* mb,          media_track_type trackType, +        int64_t /* seekTimeUs */,          int64_t *actualTimeUs) {      bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;      size_t outLength = mb->range_length(); @@ -1157,7 +1405,7 @@ sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(      }      sp<ABuffer> ab; -    if (mIsWidevine && !audio) { +    if (mIsSecure && !audio) {          // data is already provided in the buffer          ab = new ABuffer(NULL, mb->range_length());          mb->add_ref(); @@ -1185,6 +1433,16 @@ sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(      CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs));      meta->setInt64("timeUs", timeUs); +#if 0 +    // Temporarily disable pre-roll till we have a full solution to handle +    // both single seek and continous seek gracefully. +    if (seekTimeUs > timeUs) { +        sp<AMessage> extra = new AMessage; +        extra->setInt64("resume-at-mediaTimeUs", seekTimeUs); +        meta->setMessage("extra", extra); +    } +#endif +      if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {          const char *mime;          CHECK(mTimedTextTrack.mSource != NULL @@ -1226,14 +1484,13 @@ void NuPlayer::GenericSource::onReadBuffer(sp<AMessage> msg) {      int32_t tmpType;      CHECK(msg->findInt32("trackType", &tmpType));      media_track_type trackType = (media_track_type)tmpType; +    readBuffer(trackType);      {          // only protect the variable change, as readBuffer may -        // take considerable time.  This may result in one extra -        // read being processed, but that is benign. +        // take considerable time.          Mutex::Autolock _l(mReadBufferLock);          mPendingReadBufferTypes &= ~(1 << trackType);      } -    readBuffer(trackType);  }  void NuPlayer::GenericSource::readBuffer( @@ -1286,7 +1543,7 @@ void NuPlayer::GenericSource::readBuffer(          seeking = true;      } -    if (mIsWidevine && trackType != MEDIA_TRACK_TYPE_AUDIO) { +    if (mIsWidevine) {          options.setNonBlocking();      } @@ -1311,15 +1568,14 @@ void NuPlayer::GenericSource::readBuffer(              if ((seeking || formatChange)                      && (trackType == MEDIA_TRACK_TYPE_AUDIO                      || trackType == MEDIA_TRACK_TYPE_VIDEO)) { -                ATSParser::DiscontinuityType type = formatChange -                        ? (seeking -                                ? ATSParser::DISCONTINUITY_FORMATCHANGE -                                : ATSParser::DISCONTINUITY_NONE) -                        : ATSParser::DISCONTINUITY_SEEK; +                ATSParser::DiscontinuityType type = (formatChange && seeking) +                        ? ATSParser::DISCONTINUITY_FORMATCHANGE +                        : ATSParser::DISCONTINUITY_NONE;                  track->mPackets->queueDiscontinuity( type, NULL, true /* discard */);              } -            sp<ABuffer> buffer = mediaBufferToABuffer(mbuf, trackType, actualTimeUs); +            sp<ABuffer> buffer = mediaBufferToABuffer( +                    mbuf, trackType, seekTimeUs, actualTimeUs);              track->mPackets->queueAccessUnit(buffer);              formatChange = false;              seeking = false; diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index f8601ea..2d73ea9 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -67,7 +67,7 @@ struct NuPlayer::GenericSource : public NuPlayer::Source {      virtual size_t getTrackCount() const;      virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;      virtual ssize_t getSelectedTrack(media_track_type type) const; -    virtual status_t selectTrack(size_t trackIndex, bool select); +    virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);      virtual status_t seekTo(int64_t seekTimeUs);      virtual status_t setBuffers(bool audio, Vector<MediaBuffer *> &buffers); @@ -94,20 +94,24 @@ private:          kWhatSeek,          kWhatReadBuffer,          kWhatStopWidevine, +        kWhatStart, +        kWhatResume, +        kWhatSecureDecodersInstantiated,      }; -    Vector<sp<MediaSource> > mSources; -      struct Track {          size_t mIndex;          sp<MediaSource> mSource;          sp<AnotherPacketSource> mPackets;      }; +    Vector<sp<MediaSource> > mSources;      Track mAudioTrack;      int64_t mAudioTimeUs; +    int64_t mAudioLastDequeueTimeUs;      Track mVideoTrack;      int64_t mVideoTimeUs; +    int64_t mVideoLastDequeueTimeUs;      Track mSubtitleTrack;      Track mTimedTextTrack; @@ -116,6 +120,8 @@ private:      int64_t mDurationUs;      bool mAudioIsVorbis;      bool mIsWidevine; +    bool mIsSecure; +    bool mIsStreaming;      bool mUIDValid;      uid_t mUID;      sp<IMediaHTTPService> mHTTPService; @@ -140,6 +146,8 @@ private:      int64_t mBitrate;      int32_t mPollBufferingGeneration;      uint32_t mPendingReadBufferTypes; +    bool mBuffering; +    bool mPrepareBuffering;      mutable Mutex mReadBufferLock;      sp<ALooper> mLooper; @@ -154,6 +162,9 @@ private:      status_t prefillCacheIfNecessary();      void notifyPreparedAndCleanup(status_t err); +    void onSecureDecodersInstantiated(status_t err); +    void finishPrepareAsync(); +    status_t startSources();      void onGetFormatMeta(sp<AMessage> msg) const;      sp<MetaData> doGetFormatMeta(bool audio) const; @@ -162,7 +173,7 @@ private:      ssize_t doGetSelectedTrack(media_track_type type) const;      void onSelectTrack(sp<AMessage> msg); -    status_t doSelectTrack(size_t trackIndex, bool select); +    status_t doSelectTrack(size_t trackIndex, bool select, int64_t timeUs);      void onSeek(sp<AMessage> msg);      status_t doSeek(int64_t seekTimeUs); @@ -180,6 +191,7 @@ private:      sp<ABuffer> mediaBufferToABuffer(              MediaBuffer *mbuf,              media_track_type trackType, +            int64_t seekTimeUs,              int64_t *actualTimeUs = NULL);      void postReadBuffer(media_track_type trackType); @@ -190,8 +202,13 @@ private:      void schedulePollBuffering();      void cancelPollBuffering(); +    void restartPollBuffering();      void onPollBuffering();      void notifyBufferingUpdate(int percentage); +    void startBufferingIfNecessary(); +    void stopBufferingIfNecessary(); +    void sendCacheStats(); +    void ensureCacheIsFetching();      DISALLOW_EVIL_CONSTRUCTORS(GenericSource);  }; diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp index a003c81..a26ef9e 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp @@ -98,6 +98,10 @@ void NuPlayer::HTTPLiveSource::start() {  }  sp<AMessage> NuPlayer::HTTPLiveSource::getFormat(bool audio) { +    if (mLiveSession == NULL) { +        return NULL; +    } +      sp<AMessage> format;      status_t err = mLiveSession->getStreamFormat(              audio ? LiveSession::STREAMTYPE_AUDIO @@ -135,7 +139,15 @@ sp<AMessage> NuPlayer::HTTPLiveSource::getTrackInfo(size_t trackIndex) const {      return mLiveSession->getTrackInfo(trackIndex);  } -status_t NuPlayer::HTTPLiveSource::selectTrack(size_t trackIndex, bool select) { +ssize_t NuPlayer::HTTPLiveSource::getSelectedTrack(media_track_type type) const { +    if (mLiveSession == NULL) { +        return -1; +    } else { +        return mLiveSession->getSelectedTrack(type); +    } +} + +status_t NuPlayer::HTTPLiveSource::selectTrack(size_t trackIndex, bool select, int64_t /*timeUs*/) {      status_t err = mLiveSession->selectTrack(trackIndex, select);      if (err == OK) { diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h index 6b5f6af..bbb8981 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h @@ -42,7 +42,8 @@ struct NuPlayer::HTTPLiveSource : public NuPlayer::Source {      virtual status_t getDuration(int64_t *durationUs);      virtual size_t getTrackCount() const;      virtual sp<AMessage> getTrackInfo(size_t trackIndex) const; -    virtual status_t selectTrack(size_t trackIndex, bool select); +    virtual ssize_t getSelectedTrack(media_track_type /* type */) const; +    virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);      virtual status_t seekTo(int64_t seekTimeUs);  protected: diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index a63a940..aeea204 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -21,7 +21,9 @@  #include "NuPlayer.h"  #include "HTTPLiveSource.h" +#include "NuPlayerCCDecoder.h"  #include "NuPlayerDecoder.h" +#include "NuPlayerDecoderBase.h"  #include "NuPlayerDecoderPassThrough.h"  #include "NuPlayerDriver.h"  #include "NuPlayerRenderer.h" @@ -33,6 +35,8 @@  #include "ATSParser.h" +#include <cutils/properties.h> +  #include <media/stagefright/foundation/hexdump.h>  #include <media/stagefright/foundation/ABuffer.h>  #include <media/stagefright/foundation/ADebug.h> @@ -50,10 +54,6 @@  namespace android { -// TODO optimize buffer size for power consumption -// The offload read buffer size is 32 KB but 24 KB uses less power. -const size_t NuPlayer::kAggregateBufferSizeBytes = 24 * 1024; -  struct NuPlayer::Action : public RefBase {      Action() {} @@ -80,6 +80,21 @@ private:      DISALLOW_EVIL_CONSTRUCTORS(SeekAction);  }; +struct NuPlayer::ResumeDecoderAction : public Action { +    ResumeDecoderAction(bool needNotify) +        : mNeedNotify(needNotify) { +    } + +    virtual void execute(NuPlayer *player) { +        player->performResumeDecoders(mNeedNotify); +    } + +private: +    bool mNeedNotify; + +    DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction); +}; +  struct NuPlayer::SetSurfaceAction : public Action {      SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)          : mWrapper(wrapper) { @@ -95,21 +110,21 @@ private:      DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);  }; -struct NuPlayer::ShutdownDecoderAction : public Action { -    ShutdownDecoderAction(bool audio, bool video) +struct NuPlayer::FlushDecoderAction : public Action { +    FlushDecoderAction(FlushCommand audio, FlushCommand video)          : mAudio(audio),            mVideo(video) {      }      virtual void execute(NuPlayer *player) { -        player->performDecoderShutdown(mAudio, mVideo); +        player->performDecoderFlush(mAudio, mVideo);      }  private: -    bool mAudio; -    bool mVideo; +    FlushCommand mAudio; +    FlushCommand mVideo; -    DISALLOW_EVIL_CONSTRUCTORS(ShutdownDecoderAction); +    DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);  };  struct NuPlayer::PostMessageAction : public Action { @@ -151,7 +166,6 @@ private:  NuPlayer::NuPlayer()      : mUIDValid(false),        mSourceFlags(0), -      mVideoIsAVC(false),        mOffloadAudio(false),        mAudioDecoderGeneration(0),        mVideoDecoderGeneration(0), @@ -162,15 +176,13 @@ NuPlayer::NuPlayer()        mScanSourcesGeneration(0),        mPollDurationGeneration(0),        mTimedTextGeneration(0), -      mTimeDiscontinuityPending(false),        mFlushingAudio(NONE),        mFlushingVideo(NONE), -      mSkipRenderingAudioUntilMediaTimeUs(-1ll), -      mSkipRenderingVideoUntilMediaTimeUs(-1ll), -      mNumFramesTotal(0ll), -      mNumFramesDropped(0ll), +      mResumePending(false),        mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW), -      mStarted(false) { +      mStarted(false), +      mPaused(false), +      mPausedByClient(false) {      clearFlushComplete();  } @@ -306,10 +318,6 @@ void NuPlayer::pause() {      (new AMessage(kWhatPause, id()))->post();  } -void NuPlayer::resume() { -    (new AMessage(kWhatResume, id()))->post(); -} -  void NuPlayer::resetAsync() {      if (mSource != NULL) {          // During a reset, the data source might be unresponsive already, we need to @@ -459,8 +467,10 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {              size_t trackIndex;              int32_t select; +            int64_t timeUs;              CHECK(msg->findSize("trackIndex", &trackIndex));              CHECK(msg->findInt32("select", &select)); +            CHECK(msg->findInt64("timeUs", &timeUs));              status_t err = INVALID_OPERATION; @@ -474,7 +484,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {              }              if (trackIndex < inbandTracks) { -                err = mSource->selectTrack(trackIndex, select); +                err = mSource->selectTrack(trackIndex, select, timeUs);                  if (!select && err == OK) {                      int32_t type; @@ -526,19 +536,24 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {          {              ALOGV("kWhatSetVideoNativeWindow"); -            mDeferredActions.push_back( -                    new ShutdownDecoderAction( -                        false /* audio */, true /* video */)); -              sp<RefBase> obj;              CHECK(msg->findObject("native-window", &obj)); +            if (mSource == NULL || mSource->getFormat(false /* audio */) == NULL) { +                performSetSurface(static_cast<NativeWindowWrapper *>(obj.get())); +                break; +            } + +            mDeferredActions.push_back( +                    new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */, +                                           FLUSH_CMD_SHUTDOWN /* video */)); +              mDeferredActions.push_back(                      new SetSurfaceAction(                          static_cast<NativeWindowWrapper *>(obj.get())));              if (obj != NULL) { -                if (mStarted && mSource->getFormat(false /* audio */) != NULL) { +                if (mStarted) {                      // Issue a seek to refresh the video screen only if started otherwise                      // the extractor may not yet be started and will assert.                      // If the video decoder is not set (perhaps audio only in this case) @@ -556,6 +571,12 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {                          new SimpleAction(&NuPlayer::performScanSources));              } +            // After a flush without shutdown, decoder is paused. +            // Don't resume it until source seek is done, otherwise it could +            // start pulling stale data too soon. +            mDeferredActions.push_back( +                    new ResumeDecoderAction(false /* needNotify */)); +              processDeferredActions();              break;          } @@ -574,69 +595,12 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {          case kWhatStart:          {              ALOGV("kWhatStart"); - -            mVideoIsAVC = false; -            mOffloadAudio = false; -            mAudioEOS = false; -            mVideoEOS = false; -            mSkipRenderingAudioUntilMediaTimeUs = -1; -            mSkipRenderingVideoUntilMediaTimeUs = -1; -            mNumFramesTotal = 0; -            mNumFramesDropped = 0; -            mStarted = true; - -            /* instantiate decoders now for secure playback */ -            if (mSourceFlags & Source::FLAG_SECURE) { -                if (mNativeWindow != NULL) { -                    instantiateDecoder(false, &mVideoDecoder); -                } - -                if (mAudioSink != NULL) { -                    instantiateDecoder(true, &mAudioDecoder); -                } -            } - -            mSource->start(); - -            uint32_t flags = 0; - -            if (mSource->isRealTime()) { -                flags |= Renderer::FLAG_REAL_TIME; -            } - -            sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */); -            audio_stream_type_t streamType = AUDIO_STREAM_MUSIC; -            if (mAudioSink != NULL) { -                streamType = mAudioSink->getAudioStreamType(); -            } - -            sp<AMessage> videoFormat = mSource->getFormat(false /* audio */); - -            mOffloadAudio = -                canOffloadStream(audioMeta, (videoFormat != NULL), -                                 true /* is_streaming */, streamType); -            if (mOffloadAudio) { -                flags |= Renderer::FLAG_OFFLOAD_AUDIO; -            } - -            sp<AMessage> notify = new AMessage(kWhatRendererNotify, id()); -            ++mRendererGeneration; -            notify->setInt32("generation", mRendererGeneration); -            mRenderer = new Renderer(mAudioSink, notify, flags); - -            mRendererLooper = new ALooper; -            mRendererLooper->setName("NuPlayerRenderer"); -            mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO); -            mRendererLooper->registerHandler(mRenderer); - -            sp<MetaData> meta = getFileMeta(); -            int32_t rate; -            if (meta != NULL -                    && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) { -                mRenderer->setVideoFrameRate(rate); +            if (mStarted) { +                onResume(); +            } else { +                onStart();              } - -            postScanSources(); +            mPausedByClient = false;              break;          } @@ -663,11 +627,21 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {                  instantiateDecoder(false, &mVideoDecoder);              } -            if (mAudioSink != NULL) { -                if (mOffloadAudio) { +            // Don't try to re-open audio sink if there's an existing decoder. +            if (mAudioSink != NULL && mAudioDecoder == NULL) { +                sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */); +                sp<AMessage> videoFormat = mSource->getFormat(false /* audio */); +                audio_stream_type_t streamType = mAudioSink->getAudioStreamType(); +                const bool hasVideo = (videoFormat != NULL); +                const bool canOffload = canOffloadStream( +                        audioMeta, hasVideo, true /* is_streaming */, streamType); +                if (canOffload) { +                    if (!mOffloadAudio) { +                        mRenderer->signalEnableOffloadAudio(); +                    }                      // open audio sink early under offload mode.                      sp<AMessage> format = mSource->getFormat(true /*audio*/); -                    openAudioSink(format, true /*offloadOnly*/); +                    tryOpenAudioSinkForOffload(format, hasVideo);                  }                  instantiateDecoder(true, &mAudioDecoder);              } @@ -731,16 +705,26 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {              int32_t what;              CHECK(msg->findInt32("what", &what)); -            if (what == Decoder::kWhatFillThisBuffer) { -                status_t err = feedDecoderInputData( -                        audio, msg); +            if (what == DecoderBase::kWhatInputDiscontinuity) { +                int32_t formatChange; +                CHECK(msg->findInt32("formatChange", &formatChange)); -                if (err == -EWOULDBLOCK) { -                    if (mSource->feedMoreTSData() == OK) { -                        msg->post(10 * 1000ll); -                    } +                ALOGV("%s discontinuity: formatChange %d", +                        audio ? "audio" : "video", formatChange); + +                if (formatChange) { +                    mDeferredActions.push_back( +                            new FlushDecoderAction( +                                audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE, +                                audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));                  } -            } else if (what == Decoder::kWhatEOS) { + +                mDeferredActions.push_back( +                        new SimpleAction( +                                &NuPlayer::performScanSources)); + +                processDeferredActions(); +            } else if (what == DecoderBase::kWhatEOS) {                  int32_t err;                  CHECK(msg->findInt32("err", &err)); @@ -753,25 +737,20 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {                  }                  mRenderer->queueEOS(audio, err); -            } else if (what == Decoder::kWhatFlushCompleted) { +            } else if (what == DecoderBase::kWhatFlushCompleted) {                  ALOGV("decoder %s flush completed", audio ? "audio" : "video");                  handleFlushComplete(audio, true /* isDecoder */);                  finishFlushIfPossible(); -            } else if (what == Decoder::kWhatOutputFormatChanged) { +            } else if (what == DecoderBase::kWhatVideoSizeChanged) {                  sp<AMessage> format;                  CHECK(msg->findMessage("format", &format)); -                if (audio) { -                    openAudioSink(format, false /*offloadOnly*/); -                } else { -                    // video -                    sp<AMessage> inputFormat = -                            mSource->getFormat(false /* audio */); +                sp<AMessage> inputFormat = +                        mSource->getFormat(false /* audio */); -                    updateVideoSize(inputFormat, format); -                } -            } else if (what == Decoder::kWhatShutdownCompleted) { +                updateVideoSize(inputFormat, format); +            } else if (what == DecoderBase::kWhatShutdownCompleted) {                  ALOGV("%s shutdown completed", audio ? "audio" : "video");                  if (audio) {                      mAudioDecoder.clear(); @@ -788,7 +767,9 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {                  }                  finishFlushIfPossible(); -            } else if (what == Decoder::kWhatError) { +            } else if (what == DecoderBase::kWhatResumeCompleted) { +                finishResume(); +            } else if (what == DecoderBase::kWhatError) {                  status_t err;                  if (!msg->findInt32("err", &err) || err == OK) {                      err = UNKNOWN_ERROR; @@ -797,6 +778,8 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {                  // Decoder errors can be due to Source (e.g. from streaming),                  // or from decoding corrupted bitstreams, or from other decoder                  // MediaCodec operations (e.g. from an ongoing reset or seek). +                // They may also be due to openAudioSink failure at +                // decoder start or after a format change.                  //                  // We try to gracefully shut down the affected decoder if possible,                  // rather than trying to force the shutdown with something @@ -811,7 +794,9 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {                  switch (*flushing) {                      case NONE:                          mDeferredActions.push_back( -                                new ShutdownDecoderAction(audio, !audio /* video */)); +                                new FlushDecoderAction( +                                    audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE, +                                    audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));                          processDeferredActions();                          break;                      case FLUSHING_DECODER: @@ -834,8 +819,6 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {                          break;                    // Finish anyways.                  }                  notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); -            } else if (what == Decoder::kWhatDrainThisBuffer) { -                renderBuffer(audio, msg);              } else {                  ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",                        what, @@ -901,7 +884,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {                  ALOGV("media rendering started");                  notifyListener(MEDIA_STARTED, 0, 0);              } else if (what == Renderer::kWhatAudioOffloadTearDown) { -                ALOGV("Tear down audio offload, fall back to s/w path"); +                ALOGV("Tear down audio offload, fall back to s/w path if due to error.");                  int64_t positionUs;                  CHECK(msg->findInt64("positionUs", &positionUs));                  int32_t reason; @@ -909,15 +892,17 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {                  closeAudioSink();                  mAudioDecoder.clear();                  ++mAudioDecoderGeneration; -                mRenderer->flush(true /* audio */); +                mRenderer->flush( +                        true /* audio */, false /* notifyComplete */);                  if (mVideoDecoder != NULL) { -                    mRenderer->flush(false /* audio */); +                    mRenderer->flush( +                            false /* audio */, false /* notifyComplete */);                  } -                mRenderer->signalDisableOffloadAudio(); -                mOffloadAudio = false;                  performSeek(positionUs, false /* needNotify */);                  if (reason == Renderer::kDueToError) { +                    mRenderer->signalDisableOffloadAudio(); +                    mOffloadAudio = false;                      instantiateDecoder(true /* audio */, &mAudioDecoder);                  }              } @@ -934,8 +919,9 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {              ALOGV("kWhatReset");              mDeferredActions.push_back( -                    new ShutdownDecoderAction( -                        true /* audio */, true /* video */)); +                    new FlushDecoderAction( +                        FLUSH_CMD_SHUTDOWN /* audio */, +                        FLUSH_CMD_SHUTDOWN /* video */));              mDeferredActions.push_back(                      new SimpleAction(&NuPlayer::performReset)); @@ -955,47 +941,26 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {                      seekTimeUs, needNotify);              mDeferredActions.push_back( -                    new SimpleAction(&NuPlayer::performDecoderFlush)); +                    new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */, +                                           FLUSH_CMD_FLUSH /* video */));              mDeferredActions.push_back(                      new SeekAction(seekTimeUs, needNotify)); +            // After a flush without shutdown, decoder is paused. +            // Don't resume it until source seek is done, otherwise it could +            // start pulling stale data too soon. +            mDeferredActions.push_back( +                    new ResumeDecoderAction(needNotify)); +              processDeferredActions();              break;          }          case kWhatPause:          { -            if (mSource != NULL) { -                mSource->pause(); -            } else { -                ALOGW("pause called when source is gone or not set"); -            } -            if (mRenderer != NULL) { -                mRenderer->pause(); -            } else { -                ALOGW("pause called when renderer is gone or not set"); -            } -            break; -        } - -        case kWhatResume: -        { -            if (mSource != NULL) { -                mSource->resume(); -            } else { -                ALOGW("resume called when source is gone or not set"); -            } -            // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if -            // needed. -            if (audioDecoderStillNeeded() && mAudioDecoder == NULL) { -                instantiateDecoder(true /* audio */, &mAudioDecoder); -            } -            if (mRenderer != NULL) { -                mRenderer->resume(); -            } else { -                ALOGW("resume called when renderer is gone or not set"); -            } +            onPause(); +            mPausedByClient = true;              break;          } @@ -1017,6 +982,130 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {      }  } +void NuPlayer::onResume() { +    if (!mPaused) { +        return; +    } +    mPaused = false; +    if (mSource != NULL) { +        mSource->resume(); +    } else { +        ALOGW("resume called when source is gone or not set"); +    } +    // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if +    // needed. +    if (audioDecoderStillNeeded() && mAudioDecoder == NULL) { +        instantiateDecoder(true /* audio */, &mAudioDecoder); +    } +    if (mRenderer != NULL) { +        mRenderer->resume(); +    } else { +        ALOGW("resume called when renderer is gone or not set"); +    } +} + +status_t NuPlayer::onInstantiateSecureDecoders() { +    status_t err; +    if (!(mSourceFlags & Source::FLAG_SECURE)) { +        return BAD_TYPE; +    } + +    if (mRenderer != NULL) { +        ALOGE("renderer should not be set when instantiating secure decoders"); +        return UNKNOWN_ERROR; +    } + +    // TRICKY: We rely on mRenderer being null, so that decoder does not start requesting +    // data on instantiation. +    if (mNativeWindow != NULL) { +        err = instantiateDecoder(false, &mVideoDecoder); +        if (err != OK) { +            return err; +        } +    } + +    if (mAudioSink != NULL) { +        err = instantiateDecoder(true, &mAudioDecoder); +        if (err != OK) { +            return err; +        } +    } +    return OK; +} + +void NuPlayer::onStart() { +    mOffloadAudio = false; +    mAudioEOS = false; +    mVideoEOS = false; +    mStarted = true; + +    mSource->start(); + +    uint32_t flags = 0; + +    if (mSource->isRealTime()) { +        flags |= Renderer::FLAG_REAL_TIME; +    } + +    sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */); +    audio_stream_type_t streamType = AUDIO_STREAM_MUSIC; +    if (mAudioSink != NULL) { +        streamType = mAudioSink->getAudioStreamType(); +    } + +    sp<AMessage> videoFormat = mSource->getFormat(false /* audio */); + +    mOffloadAudio = +        canOffloadStream(audioMeta, (videoFormat != NULL), +                         true /* is_streaming */, streamType); +    if (mOffloadAudio) { +        flags |= Renderer::FLAG_OFFLOAD_AUDIO; +    } + +    sp<AMessage> notify = new AMessage(kWhatRendererNotify, id()); +    ++mRendererGeneration; +    notify->setInt32("generation", mRendererGeneration); +    mRenderer = new Renderer(mAudioSink, notify, flags); + +    mRendererLooper = new ALooper; +    mRendererLooper->setName("NuPlayerRenderer"); +    mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO); +    mRendererLooper->registerHandler(mRenderer); + +    sp<MetaData> meta = getFileMeta(); +    int32_t rate; +    if (meta != NULL +            && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) { +        mRenderer->setVideoFrameRate(rate); +    } + +    if (mVideoDecoder != NULL) { +        mVideoDecoder->setRenderer(mRenderer); +    } +    if (mAudioDecoder != NULL) { +        mAudioDecoder->setRenderer(mRenderer); +    } + +    postScanSources(); +} + +void NuPlayer::onPause() { +    if (mPaused) { +        return; +    } +    mPaused = true; +    if (mSource != NULL) { +        mSource->pause(); +    } else { +        ALOGW("pause called when source is gone or not set"); +    } +    if (mRenderer != NULL) { +        mRenderer->pause(); +    } else { +        ALOGW("pause called when renderer is gone or not set"); +    } +} +  bool NuPlayer::audioDecoderStillNeeded() {      // Audio decoder is no longer needed if it's in shut/shutting down status.      return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER)); @@ -1074,22 +1163,6 @@ void NuPlayer::finishFlushIfPossible() {      ALOGV("both audio and video are flushed now."); -    mPendingAudioAccessUnit.clear(); -    mAggregateBuffer.clear(); - -    if (mTimeDiscontinuityPending) { -        mRenderer->signalTimeDiscontinuity(); -        mTimeDiscontinuityPending = false; -    } - -    if (mAudioDecoder != NULL && mFlushingAudio == FLUSHED) { -        mAudioDecoder->signalResume(); -    } - -    if (mVideoDecoder != NULL && mFlushingVideo == FLUSHED) { -        mVideoDecoder->signalResume(); -    } -      mFlushingAudio = NONE;      mFlushingVideo = NONE; @@ -1110,28 +1183,16 @@ void NuPlayer::postScanSources() {      mScanSourcesPending = true;  } -void NuPlayer::openAudioSink(const sp<AMessage> &format, bool offloadOnly) { -    uint32_t flags; -    int64_t durationUs; -    bool hasVideo = (mVideoDecoder != NULL); -    // FIXME: we should handle the case where the video decoder -    // is created after we receive the format change indication. -    // Current code will just make that we select deep buffer -    // with video which should not be a problem as it should -    // not prevent from keeping A/V sync. -    if (hasVideo && -            mSource->getDuration(&durationUs) == OK && -            durationUs -                > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) { -        flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; -    } else { -        flags = AUDIO_OUTPUT_FLAG_NONE; -    } - -    mOffloadAudio = mRenderer->openAudioSink( -            format, offloadOnly, hasVideo, flags); +void NuPlayer::tryOpenAudioSinkForOffload(const sp<AMessage> &format, bool hasVideo) { +    // Note: This is called early in NuPlayer to determine whether offloading +    // is possible; otherwise the decoders call the renderer openAudioSink directly. -    if (mOffloadAudio) { +    status_t err = mRenderer->openAudioSink( +            format, true /* offloadOnly */, hasVideo, AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio); +    if (err != OK) { +        // Any failure we turn off mOffloadAudio. +        mOffloadAudio = false; +    } else if (mOffloadAudio) {          sp<MetaData> audioMeta =                  mSource->getFormatMeta(true /* audio */);          sendMetaDataToHal(mAudioSink, audioMeta); @@ -1142,7 +1203,7 @@ void NuPlayer::closeAudioSink() {      mRenderer->closeAudioSink();  } -status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { +status_t NuPlayer::instantiateDecoder(bool audio, sp<DecoderBase> *decoder) {      if (*decoder != NULL) {          return OK;      } @@ -1156,14 +1217,19 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {      if (!audio) {          AString mime;          CHECK(format->findString("mime", &mime)); -        mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());          sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, id()); -        mCCDecoder = new CCDecoder(ccNotify); +        if (mCCDecoder == NULL) { +            mCCDecoder = new CCDecoder(ccNotify); +        }          if (mSourceFlags & Source::FLAG_SECURE) {              format->setInt32("secure", true);          } + +        if (mSourceFlags & Source::FLAG_PROTECTED) { +            format->setInt32("protected", true); +        }      }      if (audio) { @@ -1172,16 +1238,28 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {          notify->setInt32("generation", mAudioDecoderGeneration);          if (mOffloadAudio) { -            *decoder = new DecoderPassThrough(notify); +            *decoder = new DecoderPassThrough(notify, mSource, mRenderer);          } else { -            *decoder = new Decoder(notify); +            *decoder = new Decoder(notify, mSource, mRenderer);          }      } else {          sp<AMessage> notify = new AMessage(kWhatVideoNotify, id());          ++mVideoDecoderGeneration;          notify->setInt32("generation", mVideoDecoderGeneration); -        *decoder = new Decoder(notify, mNativeWindow); +        *decoder = new Decoder( +                notify, mSource, mRenderer, mNativeWindow, mCCDecoder); + +        // enable FRC if high-quality AV sync is requested, even if not +        // queuing to native window, as this will even improve textureview +        // playback. +        { +            char value[PROPERTY_VALUE_MAX]; +            if (property_get("persist.sys.media.avsync", value, NULL) && +                    (!strcmp("1", value) || !strcasecmp("true", value))) { +                format->setInt32("auto-frc", 1); +            } +        }      }      (*decoder)->init();      (*decoder)->configure(format); @@ -1211,281 +1289,6 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {      return OK;  } -status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { -    sp<AMessage> reply; -    CHECK(msg->findMessage("reply", &reply)); - -    if ((audio && mFlushingAudio != NONE) -            || (!audio && mFlushingVideo != NONE) -            || mSource == NULL) { -        reply->setInt32("err", INFO_DISCONTINUITY); -        reply->post(); -        return OK; -    } - -    sp<ABuffer> accessUnit; - -    // Aggregate smaller buffers into a larger buffer. -    // The goal is to reduce power consumption. -    // Note this will not work if the decoder requires one frame per buffer. -    bool doBufferAggregation = (audio && mOffloadAudio); -    bool needMoreData = false; - -    bool dropAccessUnit; -    do { -        status_t err; -        // Did we save an accessUnit earlier because of a discontinuity? -        if (audio && (mPendingAudioAccessUnit != NULL)) { -            accessUnit = mPendingAudioAccessUnit; -            mPendingAudioAccessUnit.clear(); -            err = mPendingAudioErr; -            ALOGV("feedDecoderInputData() use mPendingAudioAccessUnit"); -        } else { -            err = mSource->dequeueAccessUnit(audio, &accessUnit); -        } - -        if (err == -EWOULDBLOCK) { -            return err; -        } else if (err != OK) { -            if (err == INFO_DISCONTINUITY) { -                if (doBufferAggregation && (mAggregateBuffer != NULL)) { -                    // We already have some data so save this for later. -                    mPendingAudioErr = err; -                    mPendingAudioAccessUnit = accessUnit; -                    accessUnit.clear(); -                    ALOGD("feedDecoderInputData() save discontinuity for later"); -                    break; -                } -                int32_t type; -                CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); - -                bool formatChange = -                    (audio && -                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) -                    || (!audio && -                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); - -                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; - -                ALOGI("%s discontinuity (formatChange=%d, time=%d)", -                     audio ? "audio" : "video", formatChange, timeChange); - -                if (audio) { -                    mSkipRenderingAudioUntilMediaTimeUs = -1; -                } else { -                    mSkipRenderingVideoUntilMediaTimeUs = -1; -                } - -                if (timeChange) { -                    sp<AMessage> extra; -                    if (accessUnit->meta()->findMessage("extra", &extra) -                            && extra != NULL) { -                        int64_t resumeAtMediaTimeUs; -                        if (extra->findInt64( -                                    "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) { -                            ALOGI("suppressing rendering of %s until %lld us", -                                    audio ? "audio" : "video", resumeAtMediaTimeUs); - -                            if (audio) { -                                mSkipRenderingAudioUntilMediaTimeUs = -                                    resumeAtMediaTimeUs; -                            } else { -                                mSkipRenderingVideoUntilMediaTimeUs = -                                    resumeAtMediaTimeUs; -                            } -                        } -                    } -                } - -                mTimeDiscontinuityPending = -                    mTimeDiscontinuityPending || timeChange; - -                bool seamlessFormatChange = false; -                sp<AMessage> newFormat = mSource->getFormat(audio); -                if (formatChange) { -                    seamlessFormatChange = -                        getDecoder(audio)->supportsSeamlessFormatChange(newFormat); -                    // treat seamless format change separately -                    formatChange = !seamlessFormatChange; -                } -                bool shutdownOrFlush = formatChange || timeChange; - -                // We want to queue up scan-sources only once per discontinuity. -                // We control this by doing it only if neither audio nor video are -                // flushing or shutting down.  (After handling 1st discontinuity, one -                // of the flushing states will not be NONE.) -                // No need to scan sources if this discontinuity does not result -                // in a flush or shutdown, as the flushing state will stay NONE. -                if (mFlushingAudio == NONE && mFlushingVideo == NONE && -                        shutdownOrFlush) { -                    // And we'll resume scanning sources once we're done -                    // flushing. -                    mDeferredActions.push_front( -                            new SimpleAction( -                                &NuPlayer::performScanSources)); -                } - -                if (formatChange /* not seamless */) { -                    // must change decoder -                    flushDecoder(audio, /* needShutdown = */ true); -                } else if (timeChange) { -                    // need to flush -                    flushDecoder(audio, /* needShutdown = */ false, newFormat); -                    err = OK; -                } else if (seamlessFormatChange) { -                    // reuse existing decoder and don't flush -                    updateDecoderFormatWithoutFlush(audio, newFormat); -                    err = OK; -                } else { -                    // This stream is unaffected by the discontinuity -                    return -EWOULDBLOCK; -                } -            } - -            reply->setInt32("err", err); -            reply->post(); -            return OK; -        } - -        if (!audio) { -            ++mNumFramesTotal; -        } - -        dropAccessUnit = false; -        if (!audio -                && !(mSourceFlags & Source::FLAG_SECURE) -                && mRenderer->getVideoLateByUs() > 100000ll -                && mVideoIsAVC -                && !IsAVCReferenceFrame(accessUnit)) { -            dropAccessUnit = true; -            ++mNumFramesDropped; -        } - -        size_t smallSize = accessUnit->size(); -        needMoreData = false; -        if (doBufferAggregation && (mAggregateBuffer == NULL) -                // Don't bother if only room for a few small buffers. -                && (smallSize < (kAggregateBufferSizeBytes / 3))) { -            // Create a larger buffer for combining smaller buffers from the extractor. -            mAggregateBuffer = new ABuffer(kAggregateBufferSizeBytes); -            mAggregateBuffer->setRange(0, 0); // start empty -        } - -        if (doBufferAggregation && (mAggregateBuffer != NULL)) { -            int64_t timeUs; -            int64_t dummy; -            bool smallTimestampValid = accessUnit->meta()->findInt64("timeUs", &timeUs); -            bool bigTimestampValid = mAggregateBuffer->meta()->findInt64("timeUs", &dummy); -            // Will the smaller buffer fit? -            size_t bigSize = mAggregateBuffer->size(); -            size_t roomLeft = mAggregateBuffer->capacity() - bigSize; -            // Should we save this small buffer for the next big buffer? -            // If the first small buffer did not have a timestamp then save -            // any buffer that does have a timestamp until the next big buffer. -            if ((smallSize > roomLeft) -                || (!bigTimestampValid && (bigSize > 0) && smallTimestampValid)) { -                mPendingAudioErr = err; -                mPendingAudioAccessUnit = accessUnit; -                accessUnit.clear(); -            } else { -                // Grab time from first small buffer if available. -                if ((bigSize == 0) && smallTimestampValid) { -                    mAggregateBuffer->meta()->setInt64("timeUs", timeUs); -                } -                // Append small buffer to the bigger buffer. -                memcpy(mAggregateBuffer->base() + bigSize, accessUnit->data(), smallSize); -                bigSize += smallSize; -                mAggregateBuffer->setRange(0, bigSize); - -                // Keep looping until we run out of room in the mAggregateBuffer. -                needMoreData = true; - -                ALOGV("feedDecoderInputData() smallSize = %zu, bigSize = %zu, capacity = %zu", -                        smallSize, bigSize, mAggregateBuffer->capacity()); -            } -        } -    } while (dropAccessUnit || needMoreData); - -    // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video"); - -#if 0 -    int64_t mediaTimeUs; -    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); -    ALOGV("feeding %s input buffer at media time %.2f secs", -         audio ? "audio" : "video", -         mediaTimeUs / 1E6); -#endif - -    if (!audio) { -        mCCDecoder->decode(accessUnit); -    } - -    if (doBufferAggregation && (mAggregateBuffer != NULL)) { -        ALOGV("feedDecoderInputData() reply with aggregated buffer, %zu", -                mAggregateBuffer->size()); -        reply->setBuffer("buffer", mAggregateBuffer); -        mAggregateBuffer.clear(); -    } else { -        reply->setBuffer("buffer", accessUnit); -    } - -    reply->post(); - -    return OK; -} - -void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) { -    // ALOGV("renderBuffer %s", audio ? "audio" : "video"); - -    sp<AMessage> reply; -    CHECK(msg->findMessage("reply", &reply)); - -    if ((audio && mFlushingAudio != NONE) -            || (!audio && mFlushingVideo != NONE)) { -        // We're currently attempting to flush the decoder, in order -        // to complete this, the decoder wants all its buffers back, -        // so we don't want any output buffers it sent us (from before -        // we initiated the flush) to be stuck in the renderer's queue. - -        ALOGV("we're still flushing the %s decoder, sending its output buffer" -             " right back.", audio ? "audio" : "video"); - -        reply->post(); -        return; -    } - -    sp<ABuffer> buffer; -    CHECK(msg->findBuffer("buffer", &buffer)); - -    int64_t mediaTimeUs; -    CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs)); - -    int64_t &skipUntilMediaTimeUs = -        audio -            ? mSkipRenderingAudioUntilMediaTimeUs -            : mSkipRenderingVideoUntilMediaTimeUs; - -    if (skipUntilMediaTimeUs >= 0) { - -        if (mediaTimeUs < skipUntilMediaTimeUs) { -            ALOGV("dropping %s buffer at time %lld as requested.", -                 audio ? "audio" : "video", -                 mediaTimeUs); - -            reply->post(); -            return; -        } - -        skipUntilMediaTimeUs = -1; -    } - -    if (!audio && mCCDecoder->isSelected()) { -        mCCDecoder->display(mediaTimeUs); -    } - -    mRenderer->queueBuffer(audio, buffer, reply); -} -  void NuPlayer::updateVideoSize(          const sp<AMessage> &inputFormat,          const sp<AMessage> &outputFormat) { @@ -1566,12 +1369,11 @@ void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {      driver->notifyListener(msg, ext1, ext2, in);  } -void NuPlayer::flushDecoder( -        bool audio, bool needShutdown, const sp<AMessage> &newFormat) { +void NuPlayer::flushDecoder(bool audio, bool needShutdown) {      ALOGV("[%s] flushDecoder needShutdown=%d",            audio ? "audio" : "video", needShutdown); -    const sp<Decoder> &decoder = getDecoder(audio); +    const sp<DecoderBase> &decoder = getDecoder(audio);      if (decoder == NULL) {          ALOGI("flushDecoder %s without decoder present",               audio ? "audio" : "video"); @@ -1582,13 +1384,12 @@ void NuPlayer::flushDecoder(      ++mScanSourcesGeneration;      mScanSourcesPending = false; -    decoder->signalFlush(newFormat); -    mRenderer->flush(audio); +    decoder->signalFlush();      FlushStatus newStatus =          needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER; -    mFlushComplete[audio][false /* isDecoder */] = false; +    mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);      mFlushComplete[audio][true /* isDecoder */] = false;      if (audio) {          ALOGE_IF(mFlushingAudio != NONE, @@ -1598,25 +1399,7 @@ void NuPlayer::flushDecoder(          ALOGE_IF(mFlushingVideo != NONE,                  "video flushDecoder() is called in state %d", mFlushingVideo);          mFlushingVideo = newStatus; - -        if (mCCDecoder != NULL) { -            mCCDecoder->flush(); -        } -    } -} - -void NuPlayer::updateDecoderFormatWithoutFlush( -        bool audio, const sp<AMessage> &format) { -    ALOGV("[%s] updateDecoderFormatWithoutFlush", audio ? "audio" : "video"); - -    const sp<Decoder> &decoder = getDecoder(audio); -    if (decoder == NULL) { -        ALOGI("updateDecoderFormatWithoutFlush %s without decoder present", -             audio ? "audio" : "video"); -        return;      } - -    decoder->signalUpdateFormat(format);  }  void NuPlayer::queueDecoderShutdown( @@ -1624,7 +1407,9 @@ void NuPlayer::queueDecoderShutdown(      ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);      mDeferredActions.push_back( -            new ShutdownDecoderAction(audio, video)); +            new FlushDecoderAction( +                audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE, +                video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));      mDeferredActions.push_back(              new SimpleAction(&NuPlayer::performScanSources)); @@ -1670,10 +1455,11 @@ status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {      return err;  } -status_t NuPlayer::selectTrack(size_t trackIndex, bool select) { +status_t NuPlayer::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {      sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());      msg->setSize("trackIndex", trackIndex);      msg->setInt32("select", select); +    msg->setInt64("timeUs", timeUs);      sp<AMessage> response;      status_t err = msg->postAndAwaitResponse(&response); @@ -1699,8 +1485,13 @@ status_t NuPlayer::getCurrentPosition(int64_t *mediaUs) {  }  void NuPlayer::getStats(int64_t *numFramesTotal, int64_t *numFramesDropped) { -    *numFramesTotal = mNumFramesTotal; -    *numFramesDropped = mNumFramesDropped; +    sp<DecoderBase> decoder = getDecoder(false /* audio */); +    if (decoder != NULL) { +        decoder->getStats(numFramesTotal, numFramesDropped); +    } else { +        *numFramesTotal = 0; +        *numFramesDropped = 0; +    }  }  sp<MetaData> NuPlayer::getFileMeta() { @@ -1757,52 +1548,23 @@ void NuPlayer::performSeek(int64_t seekTimeUs, bool needNotify) {      mSource->seekTo(seekTimeUs);      ++mTimedTextGeneration; -    if (mDriver != NULL) { -        sp<NuPlayerDriver> driver = mDriver.promote(); -        if (driver != NULL) { -            if (needNotify) { -                driver->notifySeekComplete(); -            } -        } -    } -      // everything's flushed, continue playback.  } -void NuPlayer::performDecoderFlush() { -    ALOGV("performDecoderFlush"); - -    if (mAudioDecoder == NULL && mVideoDecoder == NULL) { -        return; -    } - -    mTimeDiscontinuityPending = true; - -    if (mAudioDecoder != NULL) { -        flushDecoder(true /* audio */, false /* needShutdown */); -    } - -    if (mVideoDecoder != NULL) { -        flushDecoder(false /* audio */, false /* needShutdown */); -    } -} - -void NuPlayer::performDecoderShutdown(bool audio, bool video) { -    ALOGV("performDecoderShutdown audio=%d, video=%d", audio, video); +void NuPlayer::performDecoderFlush(FlushCommand audio, FlushCommand video) { +    ALOGV("performDecoderFlush audio=%d, video=%d", audio, video); -    if ((!audio || mAudioDecoder == NULL) -            && (!video || mVideoDecoder == NULL)) { +    if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL) +            && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {          return;      } -    mTimeDiscontinuityPending = true; - -    if (audio && mAudioDecoder != NULL) { -        flushDecoder(true /* audio */, true /* needShutdown */); +    if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) { +        flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));      } -    if (video && mVideoDecoder != NULL) { -        flushDecoder(false /* audio */, true /* needShutdown */); +    if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) { +        flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));      }  } @@ -1871,11 +1633,64 @@ void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {      }  } +void NuPlayer::performResumeDecoders(bool needNotify) { +    if (needNotify) { +        mResumePending = true; +        if (mVideoDecoder == NULL) { +            // if audio-only, we can notify seek complete now, +            // as the resume operation will be relatively fast. +            finishResume(); +        } +    } + +    if (mVideoDecoder != NULL) { +        // When there is continuous seek, MediaPlayer will cache the seek +        // position, and send down new seek request when previous seek is +        // complete. Let's wait for at least one video output frame before +        // notifying seek complete, so that the video thumbnail gets updated +        // when seekbar is dragged. +        mVideoDecoder->signalResume(needNotify); +    } + +    if (mAudioDecoder != NULL) { +        mAudioDecoder->signalResume(false /* needNotify */); +    } +} + +void NuPlayer::finishResume() { +    if (mResumePending) { +        mResumePending = false; +        if (mDriver != NULL) { +            sp<NuPlayerDriver> driver = mDriver.promote(); +            if (driver != NULL) { +                driver->notifySeekComplete(); +            } +        } +    } +} +  void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {      int32_t what;      CHECK(msg->findInt32("what", &what));      switch (what) { +        case Source::kWhatInstantiateSecureDecoders: +        { +            if (mSource == NULL) { +                // This is a stale notification from a source that was +                // asynchronously preparing when the client called reset(). +                // We handled the reset, the source is gone. +                break; +            } + +            sp<AMessage> reply; +            CHECK(msg->findMessage("reply", &reply)); +            status_t err = onInstantiateSecureDecoders(); +            reply->setInt32("err", err); +            reply->post(); +            break; +        } +          case Source::kWhatPrepared:          {              if (mSource == NULL) { @@ -1888,6 +1703,14 @@ void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {              int32_t err;              CHECK(msg->findInt32("err", &err)); +            if (err != OK) { +                // shut down potential secure codecs in case client never calls reset +                mDeferredActions.push_back( +                        new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */, +                                               FLUSH_CMD_SHUTDOWN /* video */)); +                processDeferredActions(); +            } +              sp<NuPlayerDriver> driver = mDriver.promote();              if (driver != NULL) {                  // notify duration first, so that it's definitely set when @@ -1909,6 +1732,10 @@ void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {              sp<NuPlayerDriver> driver = mDriver.promote();              if (driver != NULL) { +                if ((flags & NuPlayer::Source::FLAG_CAN_SEEK) == 0) { +                    driver->notifyListener( +                            MEDIA_INFO, MEDIA_INFO_NOT_SEEKABLE, 0); +                }                  driver->notifyFlagsChanged(flags);              } @@ -1943,18 +1770,49 @@ void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {              break;          } +        case Source::kWhatPauseOnBufferingStart: +        { +            // ignore if not playing +            if (mStarted && !mPausedByClient) { +                ALOGI("buffer low, pausing..."); + +                onPause(); +            } +            // fall-thru +        } +          case Source::kWhatBufferingStart:          {              notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);              break;          } +        case Source::kWhatResumeOnBufferingEnd: +        { +            // ignore if not playing +            if (mStarted && !mPausedByClient) { +                ALOGI("buffer ready, resuming..."); + +                onResume(); +            } +            // fall-thru +        } +          case Source::kWhatBufferingEnd:          {              notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);              break;          } +        case Source::kWhatCacheStats: +        { +            int32_t kbps; +            CHECK(msg->findInt32("bandwidth", &kbps)); + +            notifyListener(MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps); +            break; +        } +          case Source::kWhatSubtitleData:          {              sp<ABuffer> buffer; @@ -2137,6 +1995,13 @@ void NuPlayer::Source::notifyPrepared(status_t err) {      notify->post();  } +void NuPlayer::Source::notifyInstantiateSecureDecoders(const sp<AMessage> &reply) { +    sp<AMessage> notify = dupNotify(); +    notify->setInt32("what", kWhatInstantiateSecureDecoders); +    notify->setMessage("reply", reply); +    notify->post(); +} +  void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {      TRESPASS();  } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index d6120d2..e99e598 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -54,7 +54,6 @@ struct NuPlayer : public AHandler {      void start();      void pause(); -    void resume();      // Will notify the driver through "notifyResetComplete" once finished.      void resetAsync(); @@ -66,14 +65,12 @@ struct NuPlayer : public AHandler {      status_t setVideoScalingMode(int32_t mode);      status_t getTrackInfo(Parcel* reply) const;      status_t getSelectedTrack(int32_t type, Parcel* reply) const; -    status_t selectTrack(size_t trackIndex, bool select); +    status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);      status_t getCurrentPosition(int64_t *mediaUs);      void getStats(int64_t *mNumFramesTotal, int64_t *mNumFramesDropped);      sp<MetaData> getFileMeta(); -    static const size_t kAggregateBufferSizeBytes; -  protected:      virtual ~NuPlayer(); @@ -85,6 +82,7 @@ public:  private:      struct Decoder; +    struct DecoderBase;      struct DecoderPassThrough;      struct CCDecoder;      struct GenericSource; @@ -95,7 +93,8 @@ private:      struct Action;      struct SeekAction;      struct SetSurfaceAction; -    struct ShutdownDecoderAction; +    struct ResumeDecoderAction; +    struct FlushDecoderAction;      struct PostMessageAction;      struct SimpleAction; @@ -129,10 +128,9 @@ private:      uint32_t mSourceFlags;      sp<NativeWindowWrapper> mNativeWindow;      sp<MediaPlayerBase::AudioSink> mAudioSink; -    sp<Decoder> mVideoDecoder; -    bool mVideoIsAVC; +    sp<DecoderBase> mVideoDecoder;      bool mOffloadAudio; -    sp<Decoder> mAudioDecoder; +    sp<DecoderBase> mAudioDecoder;      sp<CCDecoder> mCCDecoder;      sp<Renderer> mRenderer;      sp<ALooper> mRendererLooper; @@ -160,32 +158,34 @@ private:          SHUT_DOWN,      }; -    // Once the current flush is complete this indicates whether the -    // notion of time has changed. -    bool mTimeDiscontinuityPending; +    enum FlushCommand { +        FLUSH_CMD_NONE, +        FLUSH_CMD_FLUSH, +        FLUSH_CMD_SHUTDOWN, +    };      // Status of flush responses from the decoder and renderer.      bool mFlushComplete[2][2]; -    // Used by feedDecoderInputData to aggregate small buffers into -    // one large buffer. -    sp<ABuffer> mPendingAudioAccessUnit; -    status_t    mPendingAudioErr; -    sp<ABuffer> mAggregateBuffer; -      FlushStatus mFlushingAudio;      FlushStatus mFlushingVideo; -    int64_t mSkipRenderingAudioUntilMediaTimeUs; -    int64_t mSkipRenderingVideoUntilMediaTimeUs; - -    int64_t mNumFramesTotal, mNumFramesDropped; +    // Status of flush responses from the decoder and renderer. +    bool mResumePending;      int32_t mVideoScalingMode;      bool mStarted; -    inline const sp<Decoder> &getDecoder(bool audio) { +    // Actual pause state, either as requested by client or due to buffering. +    bool mPaused; + +    // Pause state as requested by client. Note that if mPausedByClient is +    // true, mPaused is always true; if mPausedByClient is false, mPaused could +    // still become true, when we pause internally due to buffering. +    bool mPausedByClient; + +    inline const sp<DecoderBase> &getDecoder(bool audio) {          return audio ? mAudioDecoder : mVideoDecoder;      } @@ -196,28 +196,31 @@ private:          mFlushComplete[1][1] = false;      } -    void openAudioSink(const sp<AMessage> &format, bool offloadOnly); +    void tryOpenAudioSinkForOffload(const sp<AMessage> &format, bool hasVideo);      void closeAudioSink(); -    status_t instantiateDecoder(bool audio, sp<Decoder> *decoder); +    status_t instantiateDecoder(bool audio, sp<DecoderBase> *decoder); + +    status_t onInstantiateSecureDecoders();      void updateVideoSize(              const sp<AMessage> &inputFormat,              const sp<AMessage> &outputFormat = NULL); -    status_t feedDecoderInputData(bool audio, const sp<AMessage> &msg); -    void renderBuffer(bool audio, const sp<AMessage> &msg); -      void notifyListener(int msg, int ext1, int ext2, const Parcel *in = NULL);      void handleFlushComplete(bool audio, bool isDecoder);      void finishFlushIfPossible(); +    void onStart(); +    void onResume(); +    void onPause(); +      bool audioDecoderStillNeeded(); -    void flushDecoder( -            bool audio, bool needShutdown, const sp<AMessage> &newFormat = NULL); -    void updateDecoderFormatWithoutFlush(bool audio, const sp<AMessage> &format); +    void flushDecoder(bool audio, bool needShutdown); + +    void finishResume();      void postScanSources(); @@ -227,11 +230,11 @@ private:      void processDeferredActions();      void performSeek(int64_t seekTimeUs, bool needNotify); -    void performDecoderFlush(); -    void performDecoderShutdown(bool audio, bool video); +    void performDecoderFlush(FlushCommand audio, FlushCommand video);      void performReset();      void performScanSources();      void performSetSurface(const sp<NativeWindowWrapper> &wrapper); +    void performResumeDecoders(bool needNotify);      void onSourceNotify(const sp<AMessage> &msg);      void onClosedCaptionNotify(const sp<AMessage> &msg); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp new file mode 100644 index 0000000..9229704 --- /dev/null +++ b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp @@ -0,0 +1,361 @@ +/* + * 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. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "NuPlayerCCDecoder" +#include <utils/Log.h> +#include <inttypes.h> + +#include "NuPlayerCCDecoder.h" + +#include <media/stagefright/foundation/ABitReader.h> +#include <media/stagefright/foundation/ABuffer.h> +#include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/foundation/AMessage.h> +#include <media/stagefright/MediaDefs.h> + +namespace android { + +struct CCData { +    CCData(uint8_t type, uint8_t data1, uint8_t data2) +        : mType(type), mData1(data1), mData2(data2) { +    } +    bool getChannel(size_t *channel) const { +        if (mData1 >= 0x10 && mData1 <= 0x1f) { +            *channel = (mData1 >= 0x18 ? 1 : 0) + (mType ? 2 : 0); +            return true; +        } +        return false; +    } + +    uint8_t mType; +    uint8_t mData1; +    uint8_t mData2; +}; + +static bool isNullPad(CCData *cc) { +    return cc->mData1 < 0x10 && cc->mData2 < 0x10; +} + +static void dumpBytePair(const sp<ABuffer> &ccBuf) { +    size_t offset = 0; +    AString out; + +    while (offset < ccBuf->size()) { +        char tmp[128]; + +        CCData *cc = (CCData *) (ccBuf->data() + offset); + +        if (isNullPad(cc)) { +            // 1 null pad or XDS metadata, ignore +            offset += sizeof(CCData); +            continue; +        } + +        if (cc->mData1 >= 0x20 && cc->mData1 <= 0x7f) { +            // 2 basic chars +            sprintf(tmp, "[%d]Basic: %c %c", cc->mType, cc->mData1, cc->mData2); +        } else if ((cc->mData1 == 0x11 || cc->mData1 == 0x19) +                 && cc->mData2 >= 0x30 && cc->mData2 <= 0x3f) { +            // 1 special char +            sprintf(tmp, "[%d]Special: %02x %02x", cc->mType, cc->mData1, cc->mData2); +        } else if ((cc->mData1 == 0x12 || cc->mData1 == 0x1A) +                 && cc->mData2 >= 0x20 && cc->mData2 <= 0x3f){ +            // 1 Spanish/French char +            sprintf(tmp, "[%d]Spanish: %02x %02x", cc->mType, cc->mData1, cc->mData2); +        } else if ((cc->mData1 == 0x13 || cc->mData1 == 0x1B) +                 && cc->mData2 >= 0x20 && cc->mData2 <= 0x3f){ +            // 1 Portuguese/German/Danish char +            sprintf(tmp, "[%d]German: %02x %02x", cc->mType, cc->mData1, cc->mData2); +        } else if ((cc->mData1 == 0x11 || cc->mData1 == 0x19) +                 && cc->mData2 >= 0x20 && cc->mData2 <= 0x2f){ +            // Mid-Row Codes (Table 69) +            sprintf(tmp, "[%d]Mid-row: %02x %02x", cc->mType, cc->mData1, cc->mData2); +        } else if (((cc->mData1 == 0x14 || cc->mData1 == 0x1c) +                  && cc->mData2 >= 0x20 && cc->mData2 <= 0x2f) +                  || +                   ((cc->mData1 == 0x17 || cc->mData1 == 0x1f) +                  && cc->mData2 >= 0x21 && cc->mData2 <= 0x23)){ +            // Misc Control Codes (Table 70) +            sprintf(tmp, "[%d]Ctrl: %02x %02x", cc->mType, cc->mData1, cc->mData2); +        } else if ((cc->mData1 & 0x70) == 0x10 +                && (cc->mData2 & 0x40) == 0x40 +                && ((cc->mData1 & 0x07) || !(cc->mData2 & 0x20)) ) { +            // Preamble Address Codes (Table 71) +            sprintf(tmp, "[%d]PAC: %02x %02x", cc->mType, cc->mData1, cc->mData2); +        } else { +            sprintf(tmp, "[%d]Invalid: %02x %02x", cc->mType, cc->mData1, cc->mData2); +        } + +        if (out.size() > 0) { +            out.append(", "); +        } + +        out.append(tmp); + +        offset += sizeof(CCData); +    } + +    ALOGI("%s", out.c_str()); +} + +NuPlayer::CCDecoder::CCDecoder(const sp<AMessage> ¬ify) +    : mNotify(notify), +      mCurrentChannel(0), +      mSelectedTrack(-1) { +      for (size_t i = 0; i < sizeof(mTrackIndices)/sizeof(mTrackIndices[0]); ++i) { +          mTrackIndices[i] = -1; +      } +} + +size_t NuPlayer::CCDecoder::getTrackCount() const { +    return mFoundChannels.size(); +} + +sp<AMessage> NuPlayer::CCDecoder::getTrackInfo(size_t index) const { +    if (!isTrackValid(index)) { +        return NULL; +    } + +    sp<AMessage> format = new AMessage(); + +    format->setInt32("type", MEDIA_TRACK_TYPE_SUBTITLE); +    format->setString("language", "und"); +    format->setString("mime", MEDIA_MIMETYPE_TEXT_CEA_608); +    //CC1, field 0 channel 0 +    bool isDefaultAuto = (mFoundChannels[index] == 0); +    format->setInt32("auto", isDefaultAuto); +    format->setInt32("default", isDefaultAuto); +    format->setInt32("forced", 0); + +    return format; +} + +status_t NuPlayer::CCDecoder::selectTrack(size_t index, bool select) { +    if (!isTrackValid(index)) { +        return BAD_VALUE; +    } + +    if (select) { +        if (mSelectedTrack == (ssize_t)index) { +            ALOGE("track %zu already selected", index); +            return BAD_VALUE; +        } +        ALOGV("selected track %zu", index); +        mSelectedTrack = index; +    } else { +        if (mSelectedTrack != (ssize_t)index) { +            ALOGE("track %zu is not selected", index); +            return BAD_VALUE; +        } +        ALOGV("unselected track %zu", index); +        mSelectedTrack = -1; +    } + +    return OK; +} + +bool NuPlayer::CCDecoder::isSelected() const { +    return mSelectedTrack >= 0 && mSelectedTrack < (int32_t) getTrackCount(); +} + +bool NuPlayer::CCDecoder::isTrackValid(size_t index) const { +    return index < getTrackCount(); +} + +int32_t NuPlayer::CCDecoder::getTrackIndex(size_t channel) const { +    if (channel < sizeof(mTrackIndices)/sizeof(mTrackIndices[0])) { +        return mTrackIndices[channel]; +    } +    return -1; +} + +// returns true if a new CC track is found +bool NuPlayer::CCDecoder::extractFromSEI(const sp<ABuffer> &accessUnit) { +    int64_t timeUs; +    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); + +    sp<ABuffer> sei; +    if (!accessUnit->meta()->findBuffer("sei", &sei) || sei == NULL) { +        return false; +    } + +    bool trackAdded = false; + +    NALBitReader br(sei->data() + 1, sei->size() - 1); +    // sei_message() +    while (br.atLeastNumBitsLeft(16)) { // at least 16-bit for sei_message() +        uint32_t payload_type = 0; +        size_t payload_size = 0; +        uint8_t last_byte; + +        do { +            last_byte = br.getBits(8); +            payload_type += last_byte; +        } while (last_byte == 0xFF); + +        do { +            last_byte = br.getBits(8); +            payload_size += last_byte; +        } while (last_byte == 0xFF); + +        // sei_payload() +        if (payload_type == 4) { +            // user_data_registered_itu_t_t35() + +            // ATSC A/72: 6.4.2 +            uint8_t itu_t_t35_country_code = br.getBits(8); +            uint16_t itu_t_t35_provider_code = br.getBits(16); +            uint32_t user_identifier = br.getBits(32); +            uint8_t user_data_type_code = br.getBits(8); + +            payload_size -= 1 + 2 + 4 + 1; + +            if (itu_t_t35_country_code == 0xB5 +                    && itu_t_t35_provider_code == 0x0031 +                    && user_identifier == 'GA94' +                    && user_data_type_code == 0x3) { +                // MPEG_cc_data() +                // ATSC A/53 Part 4: 6.2.3.1 +                br.skipBits(1); //process_em_data_flag +                bool process_cc_data_flag = br.getBits(1); +                br.skipBits(1); //additional_data_flag +                size_t cc_count = br.getBits(5); +                br.skipBits(8); // em_data; +                payload_size -= 2; + +                if (process_cc_data_flag) { +                    AString out; + +                    sp<ABuffer> ccBuf = new ABuffer(cc_count * sizeof(CCData)); +                    ccBuf->setRange(0, 0); + +                    for (size_t i = 0; i < cc_count; i++) { +                        uint8_t marker = br.getBits(5); +                        CHECK_EQ(marker, 0x1f); + +                        bool cc_valid = br.getBits(1); +                        uint8_t cc_type = br.getBits(2); +                        // remove odd parity bit +                        uint8_t cc_data_1 = br.getBits(8) & 0x7f; +                        uint8_t cc_data_2 = br.getBits(8) & 0x7f; + +                        if (cc_valid +                                && (cc_type == 0 || cc_type == 1)) { +                            CCData cc(cc_type, cc_data_1, cc_data_2); +                            if (!isNullPad(&cc)) { +                                size_t channel; +                                if (cc.getChannel(&channel) && getTrackIndex(channel) < 0) { +                                    mTrackIndices[channel] = mFoundChannels.size(); +                                    mFoundChannels.push_back(channel); +                                    trackAdded = true; +                                } +                                memcpy(ccBuf->data() + ccBuf->size(), +                                        (void *)&cc, sizeof(cc)); +                                ccBuf->setRange(0, ccBuf->size() + sizeof(CCData)); +                            } +                        } +                    } +                    payload_size -= cc_count * 3; + +                    mCCMap.add(timeUs, ccBuf); +                    break; +                } +            } else { +                ALOGV("Malformed SEI payload type 4"); +            } +        } else { +            ALOGV("Unsupported SEI payload type %d", payload_type); +        } + +        // skipping remaining bits of this payload +        br.skipBits(payload_size * 8); +    } + +    return trackAdded; +} + +sp<ABuffer> NuPlayer::CCDecoder::filterCCBuf( +        const sp<ABuffer> &ccBuf, size_t index) { +    sp<ABuffer> filteredCCBuf = new ABuffer(ccBuf->size()); +    filteredCCBuf->setRange(0, 0); + +    size_t cc_count = ccBuf->size() / sizeof(CCData); +    const CCData* cc_data = (const CCData*)ccBuf->data(); +    for (size_t i = 0; i < cc_count; ++i) { +        size_t channel; +        if (cc_data[i].getChannel(&channel)) { +            mCurrentChannel = channel; +        } +        if (mCurrentChannel == mFoundChannels[index]) { +            memcpy(filteredCCBuf->data() + filteredCCBuf->size(), +                    (void *)&cc_data[i], sizeof(CCData)); +            filteredCCBuf->setRange(0, filteredCCBuf->size() + sizeof(CCData)); +        } +    } + +    return filteredCCBuf; +} + +void NuPlayer::CCDecoder::decode(const sp<ABuffer> &accessUnit) { +    if (extractFromSEI(accessUnit)) { +        ALOGI("Found CEA-608 track"); +        sp<AMessage> msg = mNotify->dup(); +        msg->setInt32("what", kWhatTrackAdded); +        msg->post(); +    } +    // TODO: extract CC from other sources +} + +void NuPlayer::CCDecoder::display(int64_t timeUs) { +    if (!isTrackValid(mSelectedTrack)) { +        ALOGE("Could not find current track(index=%d)", mSelectedTrack); +        return; +    } + +    ssize_t index = mCCMap.indexOfKey(timeUs); +    if (index < 0) { +        ALOGV("cc for timestamp %" PRId64 " not found", timeUs); +        return; +    } + +    sp<ABuffer> ccBuf = filterCCBuf(mCCMap.valueAt(index), mSelectedTrack); + +    if (ccBuf->size() > 0) { +#if 0 +        dumpBytePair(ccBuf); +#endif + +        ccBuf->meta()->setInt32("trackIndex", mSelectedTrack); +        ccBuf->meta()->setInt64("timeUs", timeUs); +        ccBuf->meta()->setInt64("durationUs", 0ll); + +        sp<AMessage> msg = mNotify->dup(); +        msg->setInt32("what", kWhatClosedCaptionData); +        msg->setBuffer("buffer", ccBuf); +        msg->post(); +    } + +    // remove all entries before timeUs +    mCCMap.removeItemsAt(0, index + 1); +} + +void NuPlayer::CCDecoder::flush() { +    mCCMap.clear(); +} + +}  // namespace android + diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.h new file mode 100644 index 0000000..5e06f4e --- /dev/null +++ b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.h @@ -0,0 +1,59 @@ +/* + * 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 NUPLAYER_CCDECODER_H_ + +#define NUPLAYER_CCDECODER_H_ + +#include "NuPlayer.h" + +namespace android { + +struct NuPlayer::CCDecoder : public RefBase { +    enum { +        kWhatClosedCaptionData, +        kWhatTrackAdded, +    }; + +    CCDecoder(const sp<AMessage> ¬ify); + +    size_t getTrackCount() const; +    sp<AMessage> getTrackInfo(size_t index) const; +    status_t selectTrack(size_t index, bool select); +    bool isSelected() const; +    void decode(const sp<ABuffer> &accessUnit); +    void display(int64_t timeUs); +    void flush(); + +private: +    sp<AMessage> mNotify; +    KeyedVector<int64_t, sp<ABuffer> > mCCMap; +    size_t mCurrentChannel; +    int32_t mSelectedTrack; +    int32_t mTrackIndices[4]; +    Vector<size_t> mFoundChannels; + +    bool isTrackValid(size_t index) const; +    int32_t getTrackIndex(size_t channel) const; +    bool extractFromSEI(const sp<ABuffer> &accessUnit); +    sp<ABuffer> filterCCBuf(const sp<ABuffer> &ccBuf, size_t index); + +    DISALLOW_EVIL_CONSTRUCTORS(CCDecoder); +}; + +}  // namespace android + +#endif  // NUPLAYER_CCDECODER_H_ diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index 27f6131..5d98d98 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -1,5 +1,5 @@  /* - * Copyright (C) 2010 The Android Open Source Project + * 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. @@ -19,10 +19,12 @@  #include <utils/Log.h>  #include <inttypes.h> +#include "NuPlayerCCDecoder.h"  #include "NuPlayerDecoder.h" +#include "NuPlayerRenderer.h" +#include "NuPlayerSource.h"  #include <media/ICrypto.h> -#include <media/stagefright/foundation/ABitReader.h>  #include <media/stagefright/foundation/ABuffer.h>  #include <media/stagefright/foundation/ADebug.h>  #include <media/stagefright/foundation/AMessage.h> @@ -31,71 +33,103 @@  #include <media/stagefright/MediaDefs.h>  #include <media/stagefright/MediaErrors.h> +#include "avc_utils.h" +#include "ATSParser.h" +  namespace android {  NuPlayer::Decoder::Decoder(          const sp<AMessage> ¬ify, -        const sp<NativeWindowWrapper> &nativeWindow) -    : mNotify(notify), +        const sp<Source> &source, +        const sp<Renderer> &renderer, +        const sp<NativeWindowWrapper> &nativeWindow, +        const sp<CCDecoder> &ccDecoder) +    : DecoderBase(notify),        mNativeWindow(nativeWindow), -      mBufferGeneration(0), +      mSource(source), +      mRenderer(renderer), +      mCCDecoder(ccDecoder), +      mSkipRenderingUntilMediaTimeUs(-1ll), +      mNumFramesTotal(0ll), +      mNumFramesDropped(0ll), +      mIsAudio(true), +      mIsVideoAVC(false), +      mIsSecure(false), +      mFormatChangePending(false),        mPaused(true), +      mResumePending(false),        mComponentName("decoder") { -    // Every decoder has its own looper because MediaCodec operations -    // are blocking, but NuPlayer needs asynchronous operations. -    mDecoderLooper = new ALooper; -    mDecoderLooper->setName("NPDecoder"); -    mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO); -      mCodecLooper = new ALooper;      mCodecLooper->setName("NPDecoder-CL");      mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);  }  NuPlayer::Decoder::~Decoder() { -    mDecoderLooper->unregisterHandler(id()); -    mDecoderLooper->stop(); -      releaseAndResetMediaBuffers();  } -static -status_t PostAndAwaitResponse( -        const sp<AMessage> &msg, sp<AMessage> *response) { -    status_t err = msg->postAndAwaitResponse(response); +void NuPlayer::Decoder::getStats( +        int64_t *numFramesTotal, +        int64_t *numFramesDropped) const { +    *numFramesTotal = mNumFramesTotal; +    *numFramesDropped = mNumFramesDropped; +} -    if (err != OK) { -        return err; -    } +void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { +    ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str()); -    if (!(*response)->findInt32("err", &err)) { -        err = OK; -    } +    switch (msg->what()) { +        case kWhatCodecNotify: +        { +            if (!isStaleReply(msg)) { +                int32_t numInput, numOutput; -    return err; -} +                if (!msg->findInt32("input-buffers", &numInput)) { +                    numInput = INT32_MAX; +                } -void NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) { -    mCSDsForCurrentFormat.clear(); -    for (int32_t i = 0; ; ++i) { -        AString tag = "csd-"; -        tag.append(i); -        sp<ABuffer> buffer; -        if (!format->findBuffer(tag.c_str(), &buffer)) { +                if (!msg->findInt32("output-buffers", &numOutput)) { +                    numOutput = INT32_MAX; +                } + +                if (!mPaused) { +                    while (numInput-- > 0 && handleAnInputBuffer()) {} +                } + +                while (numOutput-- > 0 && handleAnOutputBuffer()) {} +            } + +            requestCodecNotification();              break;          } -        mCSDsForCurrentFormat.push(buffer); + +        case kWhatRenderBuffer: +        { +            if (!isStaleReply(msg)) { +                onRenderBuffer(msg); +            } +            break; +        } + +        default: +            DecoderBase::onMessageReceived(msg); +            break;      }  }  void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {      CHECK(mCodec == NULL); +    mFormatChangePending = false; +      ++mBufferGeneration;      AString mime;      CHECK(format->findString("mime", &mime)); +    mIsAudio = !strncasecmp("audio/", mime.c_str(), 6); +    mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); +      sp<Surface> surface = NULL;      if (mNativeWindow != NULL) {          surface = mNativeWindow->getSurfaceTextureClient(); @@ -123,6 +157,7 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {          handleError(UNKNOWN_ERROR);          return;      } +    mIsSecure = secure;      mCodec->getName(&mComponentName); @@ -169,83 +204,141 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {              mInputBuffers.size(),              mOutputBuffers.size()); -    requestCodecNotification(); +    if (mRenderer != NULL) { +        requestCodecNotification(); +    }      mPaused = false; +    mResumePending = false;  } -void NuPlayer::Decoder::releaseAndResetMediaBuffers() { -    for (size_t i = 0; i < mMediaBuffers.size(); i++) { -        if (mMediaBuffers[i] != NULL) { -            mMediaBuffers[i]->release(); -            mMediaBuffers.editItemAt(i) = NULL; -        } -    } -    mMediaBuffers.resize(mInputBuffers.size()); -    for (size_t i = 0; i < mMediaBuffers.size(); i++) { -        mMediaBuffers.editItemAt(i) = NULL; +void NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) { +    bool hadNoRenderer = (mRenderer == NULL); +    mRenderer = renderer; +    if (hadNoRenderer && mRenderer != NULL) { +        requestCodecNotification();      } -    mInputBufferIsDequeued.clear(); -    mInputBufferIsDequeued.resize(mInputBuffers.size()); -    for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) { -        mInputBufferIsDequeued.editItemAt(i) = false; +} + +void NuPlayer::Decoder::onGetInputBuffers( +        Vector<sp<ABuffer> > *dstBuffers) { +    dstBuffers->clear(); +    for (size_t i = 0; i < mInputBuffers.size(); i++) { +        dstBuffers->push(mInputBuffers[i]);      } +} -    mPendingInputMessages.clear(); +void NuPlayer::Decoder::onResume(bool notifyComplete) { +    mPaused = false; + +    if (notifyComplete) { +        mResumePending = true; +    }  } -void NuPlayer::Decoder::requestCodecNotification() { +void NuPlayer::Decoder::onFlush(bool notifyComplete) { +    if (mCCDecoder != NULL) { +        mCCDecoder->flush(); +    } + +    if (mRenderer != NULL) { +        mRenderer->flush(mIsAudio, notifyComplete); +        mRenderer->signalTimeDiscontinuity(); +    } + +    status_t err = OK;      if (mCodec != NULL) { -        sp<AMessage> reply = new AMessage(kWhatCodecNotify, id()); -        reply->setInt32("generation", mBufferGeneration); -        mCodec->requestActivityNotification(reply); +        err = mCodec->flush(); +        mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator +        ++mBufferGeneration;      } -} -bool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) { -    int32_t generation; -    CHECK(msg->findInt32("generation", &generation)); -    return generation != mBufferGeneration; -} +    if (err != OK) { +        ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err); +        handleError(err); +        // finish with posting kWhatFlushCompleted. +        // we attempt to release the buffers even if flush fails. +    } +    releaseAndResetMediaBuffers(); -void NuPlayer::Decoder::init() { -    mDecoderLooper->registerHandler(this); +    if (notifyComplete) { +        sp<AMessage> notify = mNotify->dup(); +        notify->setInt32("what", kWhatFlushCompleted); +        notify->post(); +        mPaused = true; +    }  } -void NuPlayer::Decoder::configure(const sp<AMessage> &format) { -    sp<AMessage> msg = new AMessage(kWhatConfigure, id()); -    msg->setMessage("format", format); -    msg->post(); -} +void NuPlayer::Decoder::onShutdown(bool notifyComplete) { +    status_t err = OK; -void NuPlayer::Decoder::signalUpdateFormat(const sp<AMessage> &format) { -    sp<AMessage> msg = new AMessage(kWhatUpdateFormat, id()); -    msg->setMessage("format", format); -    msg->post(); -} +    // if there is a pending resume request, notify complete now +    notifyResumeCompleteIfNecessary(); + +    if (mCodec != NULL) { +        err = mCodec->release(); +        mCodec = NULL; +        ++mBufferGeneration; + +        if (mNativeWindow != NULL) { +            // reconnect to surface as MediaCodec disconnected from it +            status_t error = +                    native_window_api_connect( +                            mNativeWindow->getNativeWindow().get(), +                            NATIVE_WINDOW_API_MEDIA); +            ALOGW_IF(error != NO_ERROR, +                    "[%s] failed to connect to native window, error=%d", +                    mComponentName.c_str(), error); +        } +        mComponentName = "decoder"; +    } -status_t NuPlayer::Decoder::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { -    sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, id()); -    msg->setPointer("buffers", buffers); +    releaseAndResetMediaBuffers(); -    sp<AMessage> response; -    return PostAndAwaitResponse(msg, &response); +    if (err != OK) { +        ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err); +        handleError(err); +        // finish with posting kWhatShutdownCompleted. +    } + +    if (notifyComplete) { +        sp<AMessage> notify = mNotify->dup(); +        notify->setInt32("what", kWhatShutdownCompleted); +        notify->post(); +        mPaused = true; +    }  } -void NuPlayer::Decoder::handleError(int32_t err) -{ -    // We cannot immediately release the codec due to buffers still outstanding -    // in the renderer.  We signal to the player the error so it can shutdown/release the -    // decoder after flushing and increment the generation to discard unnecessary messages. +void NuPlayer::Decoder::doRequestBuffers() { +    if (mFormatChangePending) { +        return; +    } +    status_t err = OK; +    while (!mDequeuedInputBuffers.empty()) { +        size_t bufferIx = *mDequeuedInputBuffers.begin(); +        sp<AMessage> msg = new AMessage(); +        msg->setSize("buffer-ix", bufferIx); +        err = fetchInputData(msg); +        if (err != OK) { +            break; +        } +        mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin()); -    ++mBufferGeneration; +        if (!mPendingInputMessages.empty() +                || !onInputBufferFetched(msg)) { +            mPendingInputMessages.push_back(msg); +        } +    } -    sp<AMessage> notify = mNotify->dup(); -    notify->setInt32("what", kWhatError); -    notify->setInt32("err", err); -    notify->post(); +    if (err == -EWOULDBLOCK +            && mSource->feedMoreTSData() == OK) { +        scheduleRequestBuffers(); +    }  }  bool NuPlayer::Decoder::handleAnInputBuffer() { +    if (mFormatChangePending) { +        return false; +    }      size_t bufferIx = -1;      status_t res = mCodec->dequeueInputBuffer(&bufferIx);      ALOGV("[%s] dequeued input: %d", @@ -267,22 +360,21 @@ bool NuPlayer::Decoder::handleAnInputBuffer() {      }      mInputBufferIsDequeued.editItemAt(bufferIx) = true; -    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id()); -    reply->setSize("buffer-ix", bufferIx); -    reply->setInt32("generation", mBufferGeneration); -      if (!mCSDsToSubmit.isEmpty()) { +        sp<AMessage> msg = new AMessage(); +        msg->setSize("buffer-ix", bufferIx); +          sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0);          ALOGI("[%s] resubmitting CSD", mComponentName.c_str()); -        reply->setBuffer("buffer", buffer); +        msg->setBuffer("buffer", buffer);          mCSDsToSubmit.removeAt(0); -        CHECK(onInputBufferFilled(reply)); +        CHECK(onInputBufferFetched(msg));          return true;      }      while (!mPendingInputMessages.empty()) {          sp<AMessage> msg = *mPendingInputMessages.begin(); -        if (!onInputBufferFilled(msg)) { +        if (!onInputBufferFetched(msg)) {              break;          }          mPendingInputMessages.erase(mPendingInputMessages.begin()); @@ -292,15 +384,273 @@ bool NuPlayer::Decoder::handleAnInputBuffer() {          return true;      } -    sp<AMessage> notify = mNotify->dup(); -    notify->setInt32("what", kWhatFillThisBuffer); -    notify->setBuffer("buffer", mInputBuffers[bufferIx]); -    notify->setMessage("reply", reply); -    notify->post(); +    mDequeuedInputBuffers.push_back(bufferIx); + +    onRequestInputBuffers();      return true;  } -bool android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) { +bool NuPlayer::Decoder::handleAnOutputBuffer() { +    if (mFormatChangePending) { +        return false; +    } +    size_t bufferIx = -1; +    size_t offset; +    size_t size; +    int64_t timeUs; +    uint32_t flags; +    status_t res = mCodec->dequeueOutputBuffer( +            &bufferIx, &offset, &size, &timeUs, &flags); + +    if (res != OK) { +        ALOGV("[%s] dequeued output: %d", mComponentName.c_str(), res); +    } else { +        ALOGV("[%s] dequeued output: %d (time=%lld flags=%" PRIu32 ")", +                mComponentName.c_str(), (int)bufferIx, timeUs, flags); +    } + +    if (res == INFO_OUTPUT_BUFFERS_CHANGED) { +        res = mCodec->getOutputBuffers(&mOutputBuffers); +        if (res != OK) { +            ALOGE("Failed to get output buffers for %s after INFO event (err=%d)", +                    mComponentName.c_str(), res); +            handleError(res); +            return false; +        } +        // NuPlayer ignores this +        return true; +    } else if (res == INFO_FORMAT_CHANGED) { +        sp<AMessage> format = new AMessage(); +        res = mCodec->getOutputFormat(&format); +        if (res != OK) { +            ALOGE("Failed to get output format for %s after INFO event (err=%d)", +                    mComponentName.c_str(), res); +            handleError(res); +            return false; +        } + +        if (!mIsAudio) { +            sp<AMessage> notify = mNotify->dup(); +            notify->setInt32("what", kWhatVideoSizeChanged); +            notify->setMessage("format", format); +            notify->post(); +        } else if (mRenderer != NULL) { +            uint32_t flags; +            int64_t durationUs; +            bool hasVideo = (mSource->getFormat(false /* audio */) != NULL); +            if (!hasVideo && +                    mSource->getDuration(&durationUs) == OK && +                    durationUs +                        > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) { +                flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; +            } else { +                flags = AUDIO_OUTPUT_FLAG_NONE; +            } + +            res = mRenderer->openAudioSink( +                    format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaded */); +            if (res != OK) { +                ALOGE("Failed to open AudioSink on format change for %s (err=%d)", +                        mComponentName.c_str(), res); +                handleError(res); +                return false; +            } +        } +        return true; +    } else if (res == INFO_DISCONTINUITY) { +        // nothing to do +        return true; +    } else if (res != OK) { +        if (res != -EAGAIN) { +            ALOGE("Failed to dequeue output buffer for %s (err=%d)", +                    mComponentName.c_str(), res); +            handleError(res); +        } +        return false; +    } + +    CHECK_LT(bufferIx, mOutputBuffers.size()); +    sp<ABuffer> buffer = mOutputBuffers[bufferIx]; +    buffer->setRange(offset, size); +    buffer->meta()->clear(); +    buffer->meta()->setInt64("timeUs", timeUs); +    if (flags & MediaCodec::BUFFER_FLAG_EOS) { +        buffer->meta()->setInt32("eos", true); +        notifyResumeCompleteIfNecessary(); +    } +    // we do not expect CODECCONFIG or SYNCFRAME for decoder + +    sp<AMessage> reply = new AMessage(kWhatRenderBuffer, id()); +    reply->setSize("buffer-ix", bufferIx); +    reply->setInt32("generation", mBufferGeneration); + +    if (mSkipRenderingUntilMediaTimeUs >= 0) { +        if (timeUs < mSkipRenderingUntilMediaTimeUs) { +            ALOGV("[%s] dropping buffer at time %lld as requested.", +                     mComponentName.c_str(), (long long)timeUs); + +            reply->post(); +            return true; +        } + +        mSkipRenderingUntilMediaTimeUs = -1; +    } + +    // wait until 1st frame comes out to signal resume complete +    notifyResumeCompleteIfNecessary(); + +    if (mRenderer != NULL) { +        // send the buffer to renderer. +        mRenderer->queueBuffer(mIsAudio, buffer, reply); +        if (flags & MediaCodec::BUFFER_FLAG_EOS) { +            mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM); +        } +    } + +    return true; +} + +void NuPlayer::Decoder::releaseAndResetMediaBuffers() { +    for (size_t i = 0; i < mMediaBuffers.size(); i++) { +        if (mMediaBuffers[i] != NULL) { +            mMediaBuffers[i]->release(); +            mMediaBuffers.editItemAt(i) = NULL; +        } +    } +    mMediaBuffers.resize(mInputBuffers.size()); +    for (size_t i = 0; i < mMediaBuffers.size(); i++) { +        mMediaBuffers.editItemAt(i) = NULL; +    } +    mInputBufferIsDequeued.clear(); +    mInputBufferIsDequeued.resize(mInputBuffers.size()); +    for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) { +        mInputBufferIsDequeued.editItemAt(i) = false; +    } + +    mPendingInputMessages.clear(); +    mDequeuedInputBuffers.clear(); +    mSkipRenderingUntilMediaTimeUs = -1; +} + +void NuPlayer::Decoder::requestCodecNotification() { +    if (mFormatChangePending) { +        return; +    } +    if (mCodec != NULL) { +        sp<AMessage> reply = new AMessage(kWhatCodecNotify, id()); +        reply->setInt32("generation", mBufferGeneration); +        mCodec->requestActivityNotification(reply); +    } +} + +bool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) { +    int32_t generation; +    CHECK(msg->findInt32("generation", &generation)); +    return generation != mBufferGeneration; +} + +status_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) { +    sp<ABuffer> accessUnit; +    bool dropAccessUnit; +    do { +        status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit); + +        if (err == -EWOULDBLOCK) { +            return err; +        } else if (err != OK) { +            if (err == INFO_DISCONTINUITY) { +                int32_t type; +                CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); + +                bool formatChange = +                    (mIsAudio && +                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) +                    || (!mIsAudio && +                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); + +                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; + +                ALOGI("%s discontinuity (format=%d, time=%d)", +                        mIsAudio ? "audio" : "video", formatChange, timeChange); + +                bool seamlessFormatChange = false; +                sp<AMessage> newFormat = mSource->getFormat(mIsAudio); +                if (formatChange) { +                    seamlessFormatChange = +                        supportsSeamlessFormatChange(newFormat); +                    // treat seamless format change separately +                    formatChange = !seamlessFormatChange; +                } + +                if (formatChange || timeChange) { +                    sp<AMessage> msg = mNotify->dup(); +                    msg->setInt32("what", kWhatInputDiscontinuity); +                    msg->setInt32("formatChange", formatChange); +                    msg->post(); +                } + +                if (formatChange /* not seamless */) { +                    // must change decoder +                    // return EOS and wait to be killed +                    mFormatChangePending = true; +                    return ERROR_END_OF_STREAM; +                } else if (timeChange) { +                    // need to flush +                    // TODO: Ideally we shouldn't need a flush upon time +                    // discontinuity, flushing will cause loss of frames. +                    // We probably should queue a time change marker to the +                    // output queue, and handles it in renderer instead. +                    rememberCodecSpecificData(newFormat); +                    onFlush(false /* notifyComplete */); +                    err = OK; +                } else if (seamlessFormatChange) { +                    // reuse existing decoder and don't flush +                    rememberCodecSpecificData(newFormat); +                    err = OK; +                } else { +                    // This stream is unaffected by the discontinuity +                    return -EWOULDBLOCK; +                } +            } + +            reply->setInt32("err", err); +            return OK; +        } + +        if (!mIsAudio) { +            ++mNumFramesTotal; +        } + +        dropAccessUnit = false; +        if (!mIsAudio +                && !mIsSecure +                && mRenderer->getVideoLateByUs() > 100000ll +                && mIsVideoAVC +                && !IsAVCReferenceFrame(accessUnit)) { +            dropAccessUnit = true; +            ++mNumFramesDropped; +        } +    } while (dropAccessUnit); + +    // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video"); +#if 0 +    int64_t mediaTimeUs; +    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); +    ALOGV("feeding %s input buffer at media time %.2f secs", +         mIsAudio ? "audio" : "video", +         mediaTimeUs / 1E6); +#endif + +    if (mCCDecoder != NULL) { +        mCCDecoder->decode(accessUnit); +    } + +    reply->setBuffer("buffer", accessUnit); + +    return OK; +} + +bool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) {      size_t bufferIx;      CHECK(msg->findSize("buffer-ix", &bufferIx));      CHECK_LT(bufferIx, mInputBuffers.size()); @@ -342,8 +692,6 @@ bool android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) {          }      } - -      if (buffer == NULL /* includes !hasBuffer */) {          int32_t streamErr = ERROR_END_OF_STREAM;          CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); @@ -375,6 +723,17 @@ bool android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) {              handleError(streamErr);          }      } else { +        sp<AMessage> extra; +        if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) { +            int64_t resumeAtMediaTimeUs; +            if (extra->findInt64( +                        "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) { +                ALOGI("[%s] suppressing rendering until %lld us", +                        mComponentName.c_str(), (long long)resumeAtMediaTimeUs); +                mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs; +            } +        } +          int64_t timeUs = 0;          uint32_t flags = 0;          CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); @@ -418,96 +777,22 @@ bool android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) {      return true;  } -bool NuPlayer::Decoder::handleAnOutputBuffer() { -    size_t bufferIx = -1; -    size_t offset; -    size_t size; -    int64_t timeUs; -    uint32_t flags; -    status_t res = mCodec->dequeueOutputBuffer( -            &bufferIx, &offset, &size, &timeUs, &flags); - -    if (res != OK) { -        ALOGV("[%s] dequeued output: %d", mComponentName.c_str(), res); -    } else { -        ALOGV("[%s] dequeued output: %d (time=%lld flags=%" PRIu32 ")", -                mComponentName.c_str(), (int)bufferIx, timeUs, flags); -    } - -    if (res == INFO_OUTPUT_BUFFERS_CHANGED) { -        res = mCodec->getOutputBuffers(&mOutputBuffers); -        if (res != OK) { -            ALOGE("Failed to get output buffers for %s after INFO event (err=%d)", -                    mComponentName.c_str(), res); -            handleError(res); -            return false; -        } -        // NuPlayer ignores this -        return true; -    } else if (res == INFO_FORMAT_CHANGED) { -        sp<AMessage> format = new AMessage(); -        res = mCodec->getOutputFormat(&format); -        if (res != OK) { -            ALOGE("Failed to get output format for %s after INFO event (err=%d)", -                    mComponentName.c_str(), res); -            handleError(res); -            return false; -        } - -        sp<AMessage> notify = mNotify->dup(); -        notify->setInt32("what", kWhatOutputFormatChanged); -        notify->setMessage("format", format); -        notify->post(); -        return true; -    } else if (res == INFO_DISCONTINUITY) { -        // nothing to do -        return true; -    } else if (res != OK) { -        if (res != -EAGAIN) { -            ALOGE("Failed to dequeue output buffer for %s (err=%d)", -                    mComponentName.c_str(), res); -            handleError(res); -        } -        return false; -    } - -    CHECK_LT(bufferIx, mOutputBuffers.size()); -    sp<ABuffer> buffer = mOutputBuffers[bufferIx]; -    buffer->setRange(offset, size); -    buffer->meta()->clear(); -    buffer->meta()->setInt64("timeUs", timeUs); -    if (flags & MediaCodec::BUFFER_FLAG_EOS) { -        buffer->meta()->setInt32("eos", true); -    } -    // we do not expect CODECCONFIG or SYNCFRAME for decoder - -    sp<AMessage> reply = new AMessage(kWhatRenderBuffer, id()); -    reply->setSize("buffer-ix", bufferIx); -    reply->setInt32("generation", mBufferGeneration); - -    sp<AMessage> notify = mNotify->dup(); -    notify->setInt32("what", kWhatDrainThisBuffer); -    notify->setBuffer("buffer", buffer); -    notify->setMessage("reply", reply); -    notify->post(); - -    // FIXME: This should be handled after rendering is complete, -    // but Renderer needs it now -    if (flags & MediaCodec::BUFFER_FLAG_EOS) { -        ALOGV("queueing eos [%s]", mComponentName.c_str()); -        sp<AMessage> notify = mNotify->dup(); -        notify->setInt32("what", kWhatEOS); -        notify->setInt32("err", ERROR_END_OF_STREAM); -        notify->post(); -    } -    return true; -} -  void NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) {      status_t err;      int32_t render;      size_t bufferIx;      CHECK(msg->findSize("buffer-ix", &bufferIx)); + +    if (!mIsAudio) { +        int64_t timeUs; +        sp<ABuffer> buffer = mOutputBuffers[bufferIx]; +        buffer->meta()->findInt64("timeUs", &timeUs); + +        if (mCCDecoder != NULL && mCCDecoder->isSelected()) { +            mCCDecoder->display(timeUs); +        } +    } +      if (msg->findInt32("render", &render) && render) {          int64_t timestampNs;          CHECK(msg->findInt64("timestampNs", ×tampNs)); @@ -522,192 +807,8 @@ void NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) {      }  } -void NuPlayer::Decoder::onFlush() { -    status_t err = OK; -    if (mCodec != NULL) { -        err = mCodec->flush(); -        mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator -        ++mBufferGeneration; -    } - -    if (err != OK) { -        ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err); -        handleError(err); -        // finish with posting kWhatFlushCompleted. -        // we attempt to release the buffers even if flush fails. -    } -    releaseAndResetMediaBuffers(); - -    sp<AMessage> notify = mNotify->dup(); -    notify->setInt32("what", kWhatFlushCompleted); -    notify->post(); -    mPaused = true; -} - -void NuPlayer::Decoder::onResume() { -    mPaused = false; -} - -void NuPlayer::Decoder::onShutdown() { -    status_t err = OK; -    if (mCodec != NULL) { -        err = mCodec->release(); -        mCodec = NULL; -        ++mBufferGeneration; - -        if (mNativeWindow != NULL) { -            // reconnect to surface as MediaCodec disconnected from it -            status_t error = -                    native_window_api_connect( -                            mNativeWindow->getNativeWindow().get(), -                            NATIVE_WINDOW_API_MEDIA); -            ALOGW_IF(error != NO_ERROR, -                    "[%s] failed to connect to native window, error=%d", -                    mComponentName.c_str(), error); -        } -        mComponentName = "decoder"; -    } - -    releaseAndResetMediaBuffers(); - -    if (err != OK) { -        ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err); -        handleError(err); -        // finish with posting kWhatShutdownCompleted. -    } - -    sp<AMessage> notify = mNotify->dup(); -    notify->setInt32("what", kWhatShutdownCompleted); -    notify->post(); -    mPaused = true; -} - -void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { -    ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str()); - -    switch (msg->what()) { -        case kWhatConfigure: -        { -            sp<AMessage> format; -            CHECK(msg->findMessage("format", &format)); -            onConfigure(format); -            break; -        } - -        case kWhatUpdateFormat: -        { -            sp<AMessage> format; -            CHECK(msg->findMessage("format", &format)); -            rememberCodecSpecificData(format); -            break; -        } - -        case kWhatGetInputBuffers: -        { -            uint32_t replyID; -            CHECK(msg->senderAwaitsResponse(&replyID)); - -            Vector<sp<ABuffer> > *dstBuffers; -            CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); - -            dstBuffers->clear(); -            for (size_t i = 0; i < mInputBuffers.size(); i++) { -                dstBuffers->push(mInputBuffers[i]); -            } - -            (new AMessage)->postReply(replyID); -            break; -        } - -        case kWhatCodecNotify: -        { -            if (!isStaleReply(msg)) { -                int32_t numInput, numOutput; - -                if (!msg->findInt32("input-buffers", &numInput)) { -                    numInput = INT32_MAX; -                } - -                if (!msg->findInt32("output-buffers", &numOutput)) { -                    numOutput = INT32_MAX; -                } - -                if (!mPaused) { -                    while (numInput-- > 0 && handleAnInputBuffer()) {} -                } - -                while (numOutput-- > 0 && handleAnOutputBuffer()) {} -            } - -            requestCodecNotification(); -            break; -        } - -        case kWhatInputBufferFilled: -        { -            if (!isStaleReply(msg)) { -                if (!mPendingInputMessages.empty() -                        || !onInputBufferFilled(msg)) { -                    mPendingInputMessages.push_back(msg); -                } -            } - -            break; -        } - -        case kWhatRenderBuffer: -        { -            if (!isStaleReply(msg)) { -                onRenderBuffer(msg); -            } -            break; -        } - -        case kWhatFlush: -        { -            sp<AMessage> format; -            if (msg->findMessage("new-format", &format)) { -                rememberCodecSpecificData(format); -            } -            onFlush(); -            break; -        } - -        case kWhatResume: -        { -            onResume(); -            break; -        } - -        case kWhatShutdown: -        { -            onShutdown(); -            break; -        } - -        default: -            TRESPASS(); -            break; -    } -} - -void NuPlayer::Decoder::signalFlush(const sp<AMessage> &format) { -    sp<AMessage> msg = new AMessage(kWhatFlush, id()); -    if (format != NULL) { -        msg->setMessage("new-format", format); -    } -    msg->post(); -} - -void NuPlayer::Decoder::signalResume() { -    (new AMessage(kWhatResume, id()))->post(); -} - -void NuPlayer::Decoder::initiateShutdown() { -    (new AMessage(kWhatShutdown, id()))->post(); -} - -bool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const { +bool NuPlayer::Decoder::supportsSeamlessAudioFormatChange( +        const sp<AMessage> &targetFormat) const {      if (targetFormat == NULL) {          return true;      } @@ -722,7 +823,7 @@ bool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(const sp<AMessage> &ta          const char * keys[] = { "channel-count", "sample-rate", "is-adts" };          for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {              int32_t oldVal, newVal; -            if (!mOutputFormat->findInt32(keys[i], &oldVal) || +            if (!mInputFormat->findInt32(keys[i], &oldVal) ||                      !targetFormat->findInt32(keys[i], &newVal) ||                      oldVal != newVal) {                  return false; @@ -730,7 +831,7 @@ bool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(const sp<AMessage> &ta          }          sp<ABuffer> oldBuf, newBuf; -        if (mOutputFormat->findBuffer("csd-0", &oldBuf) && +        if (mInputFormat->findBuffer("csd-0", &oldBuf) &&                  targetFormat->findBuffer("csd-0", &newBuf)) {              if (oldBuf->size() != newBuf->size()) {                  return false; @@ -742,7 +843,7 @@ bool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(const sp<AMessage> &ta  }  bool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const { -    if (mOutputFormat == NULL) { +    if (mInputFormat == NULL) {          return false;      } @@ -751,7 +852,7 @@ bool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetF      }      AString oldMime, newMime; -    if (!mOutputFormat->findString("mime", &oldMime) +    if (!mInputFormat->findString("mime", &oldMime)              || !targetFormat->findString("mime", &newMime)              || !(oldMime == newMime)) {          return false; @@ -772,332 +873,30 @@ bool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetF      return seamless;  } -struct CCData { -    CCData(uint8_t type, uint8_t data1, uint8_t data2) -        : mType(type), mData1(data1), mData2(data2) { -    } -    bool getChannel(size_t *channel) const { -        if (mData1 >= 0x10 && mData1 <= 0x1f) { -            *channel = (mData1 >= 0x18 ? 1 : 0) + (mType ? 2 : 0); -            return true; -        } -        return false; -    } - -    uint8_t mType; -    uint8_t mData1; -    uint8_t mData2; -}; - -static bool isNullPad(CCData *cc) { -    return cc->mData1 < 0x10 && cc->mData2 < 0x10; -} - -static void dumpBytePair(const sp<ABuffer> &ccBuf) { -    size_t offset = 0; -    AString out; - -    while (offset < ccBuf->size()) { -        char tmp[128]; - -        CCData *cc = (CCData *) (ccBuf->data() + offset); - -        if (isNullPad(cc)) { -            // 1 null pad or XDS metadata, ignore -            offset += sizeof(CCData); -            continue; -        } - -        if (cc->mData1 >= 0x20 && cc->mData1 <= 0x7f) { -            // 2 basic chars -            sprintf(tmp, "[%d]Basic: %c %c", cc->mType, cc->mData1, cc->mData2); -        } else if ((cc->mData1 == 0x11 || cc->mData1 == 0x19) -                 && cc->mData2 >= 0x30 && cc->mData2 <= 0x3f) { -            // 1 special char -            sprintf(tmp, "[%d]Special: %02x %02x", cc->mType, cc->mData1, cc->mData2); -        } else if ((cc->mData1 == 0x12 || cc->mData1 == 0x1A) -                 && cc->mData2 >= 0x20 && cc->mData2 <= 0x3f){ -            // 1 Spanish/French char -            sprintf(tmp, "[%d]Spanish: %02x %02x", cc->mType, cc->mData1, cc->mData2); -        } else if ((cc->mData1 == 0x13 || cc->mData1 == 0x1B) -                 && cc->mData2 >= 0x20 && cc->mData2 <= 0x3f){ -            // 1 Portuguese/German/Danish char -            sprintf(tmp, "[%d]German: %02x %02x", cc->mType, cc->mData1, cc->mData2); -        } else if ((cc->mData1 == 0x11 || cc->mData1 == 0x19) -                 && cc->mData2 >= 0x20 && cc->mData2 <= 0x2f){ -            // Mid-Row Codes (Table 69) -            sprintf(tmp, "[%d]Mid-row: %02x %02x", cc->mType, cc->mData1, cc->mData2); -        } else if (((cc->mData1 == 0x14 || cc->mData1 == 0x1c) -                  && cc->mData2 >= 0x20 && cc->mData2 <= 0x2f) -                  || -                   ((cc->mData1 == 0x17 || cc->mData1 == 0x1f) -                  && cc->mData2 >= 0x21 && cc->mData2 <= 0x23)){ -            // Misc Control Codes (Table 70) -            sprintf(tmp, "[%d]Ctrl: %02x %02x", cc->mType, cc->mData1, cc->mData2); -        } else if ((cc->mData1 & 0x70) == 0x10 -                && (cc->mData2 & 0x40) == 0x40 -                && ((cc->mData1 & 0x07) || !(cc->mData2 & 0x20)) ) { -            // Preamble Address Codes (Table 71) -            sprintf(tmp, "[%d]PAC: %02x %02x", cc->mType, cc->mData1, cc->mData2); -        } else { -            sprintf(tmp, "[%d]Invalid: %02x %02x", cc->mType, cc->mData1, cc->mData2); -        } - -        if (out.size() > 0) { -            out.append(", "); -        } - -        out.append(tmp); - -        offset += sizeof(CCData); -    } - -    ALOGI("%s", out.c_str()); -} - -NuPlayer::CCDecoder::CCDecoder(const sp<AMessage> ¬ify) -    : mNotify(notify), -      mCurrentChannel(0), -      mSelectedTrack(-1) { -      for (size_t i = 0; i < sizeof(mTrackIndices)/sizeof(mTrackIndices[0]); ++i) { -          mTrackIndices[i] = -1; -      } -} - -size_t NuPlayer::CCDecoder::getTrackCount() const { -    return mFoundChannels.size(); -} - -sp<AMessage> NuPlayer::CCDecoder::getTrackInfo(size_t index) const { -    if (!isTrackValid(index)) { -        return NULL; -    } - -    sp<AMessage> format = new AMessage(); - -    format->setInt32("type", MEDIA_TRACK_TYPE_SUBTITLE); -    format->setString("language", "und"); -    format->setString("mime", MEDIA_MIMETYPE_TEXT_CEA_608); -    //CC1, field 0 channel 0 -    bool isDefaultAuto = (mFoundChannels[index] == 0); -    format->setInt32("auto", isDefaultAuto); -    format->setInt32("default", isDefaultAuto); -    format->setInt32("forced", 0); - -    return format; -} - -status_t NuPlayer::CCDecoder::selectTrack(size_t index, bool select) { -    if (!isTrackValid(index)) { -        return BAD_VALUE; -    } - -    if (select) { -        if (mSelectedTrack == (ssize_t)index) { -            ALOGE("track %zu already selected", index); -            return BAD_VALUE; -        } -        ALOGV("selected track %zu", index); -        mSelectedTrack = index; -    } else { -        if (mSelectedTrack != (ssize_t)index) { -            ALOGE("track %zu is not selected", index); -            return BAD_VALUE; -        } -        ALOGV("unselected track %zu", index); -        mSelectedTrack = -1; -    } - -    return OK; -} - -bool NuPlayer::CCDecoder::isSelected() const { -    return mSelectedTrack >= 0 && mSelectedTrack < (int32_t) getTrackCount(); -} - -bool NuPlayer::CCDecoder::isTrackValid(size_t index) const { -    return index < getTrackCount(); -} - -int32_t NuPlayer::CCDecoder::getTrackIndex(size_t channel) const { -    if (channel < sizeof(mTrackIndices)/sizeof(mTrackIndices[0])) { -        return mTrackIndices[channel]; -    } -    return -1; -} - -// returns true if a new CC track is found -bool NuPlayer::CCDecoder::extractFromSEI(const sp<ABuffer> &accessUnit) { -    int64_t timeUs; -    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); - -    sp<ABuffer> sei; -    if (!accessUnit->meta()->findBuffer("sei", &sei) || sei == NULL) { -        return false; -    } - -    bool trackAdded = false; - -    NALBitReader br(sei->data() + 1, sei->size() - 1); -    // sei_message() -    while (br.atLeastNumBitsLeft(16)) { // at least 16-bit for sei_message() -        uint32_t payload_type = 0; -        size_t payload_size = 0; -        uint8_t last_byte; - -        do { -            last_byte = br.getBits(8); -            payload_type += last_byte; -        } while (last_byte == 0xFF); - -        do { -            last_byte = br.getBits(8); -            payload_size += last_byte; -        } while (last_byte == 0xFF); - -        // sei_payload() -        if (payload_type == 4) { -            // user_data_registered_itu_t_t35() - -            // ATSC A/72: 6.4.2 -            uint8_t itu_t_t35_country_code = br.getBits(8); -            uint16_t itu_t_t35_provider_code = br.getBits(16); -            uint32_t user_identifier = br.getBits(32); -            uint8_t user_data_type_code = br.getBits(8); - -            payload_size -= 1 + 2 + 4 + 1; - -            if (itu_t_t35_country_code == 0xB5 -                    && itu_t_t35_provider_code == 0x0031 -                    && user_identifier == 'GA94' -                    && user_data_type_code == 0x3) { -                // MPEG_cc_data() -                // ATSC A/53 Part 4: 6.2.3.1 -                br.skipBits(1); //process_em_data_flag -                bool process_cc_data_flag = br.getBits(1); -                br.skipBits(1); //additional_data_flag -                size_t cc_count = br.getBits(5); -                br.skipBits(8); // em_data; -                payload_size -= 2; - -                if (process_cc_data_flag) { -                    AString out; - -                    sp<ABuffer> ccBuf = new ABuffer(cc_count * sizeof(CCData)); -                    ccBuf->setRange(0, 0); - -                    for (size_t i = 0; i < cc_count; i++) { -                        uint8_t marker = br.getBits(5); -                        CHECK_EQ(marker, 0x1f); - -                        bool cc_valid = br.getBits(1); -                        uint8_t cc_type = br.getBits(2); -                        // remove odd parity bit -                        uint8_t cc_data_1 = br.getBits(8) & 0x7f; -                        uint8_t cc_data_2 = br.getBits(8) & 0x7f; - -                        if (cc_valid -                                && (cc_type == 0 || cc_type == 1)) { -                            CCData cc(cc_type, cc_data_1, cc_data_2); -                            if (!isNullPad(&cc)) { -                                size_t channel; -                                if (cc.getChannel(&channel) && getTrackIndex(channel) < 0) { -                                    mTrackIndices[channel] = mFoundChannels.size(); -                                    mFoundChannels.push_back(channel); -                                    trackAdded = true; -                                } -                                memcpy(ccBuf->data() + ccBuf->size(), -                                        (void *)&cc, sizeof(cc)); -                                ccBuf->setRange(0, ccBuf->size() + sizeof(CCData)); -                            } -                        } -                    } -                    payload_size -= cc_count * 3; - -                    mCCMap.add(timeUs, ccBuf); -                    break; -                } -            } else { -                ALOGV("Malformed SEI payload type 4"); -            } -        } else { -            ALOGV("Unsupported SEI payload type %d", payload_type); -        } - -        // skipping remaining bits of this payload -        br.skipBits(payload_size * 8); +void NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) { +    if (format == NULL) { +        return;      } - -    return trackAdded; -} - -sp<ABuffer> NuPlayer::CCDecoder::filterCCBuf( -        const sp<ABuffer> &ccBuf, size_t index) { -    sp<ABuffer> filteredCCBuf = new ABuffer(ccBuf->size()); -    filteredCCBuf->setRange(0, 0); - -    size_t cc_count = ccBuf->size() / sizeof(CCData); -    const CCData* cc_data = (const CCData*)ccBuf->data(); -    for (size_t i = 0; i < cc_count; ++i) { -        size_t channel; -        if (cc_data[i].getChannel(&channel)) { -            mCurrentChannel = channel; -        } -        if (mCurrentChannel == mFoundChannels[index]) { -            memcpy(filteredCCBuf->data() + filteredCCBuf->size(), -                    (void *)&cc_data[i], sizeof(CCData)); -            filteredCCBuf->setRange(0, filteredCCBuf->size() + sizeof(CCData)); +    mCSDsForCurrentFormat.clear(); +    for (int32_t i = 0; ; ++i) { +        AString tag = "csd-"; +        tag.append(i); +        sp<ABuffer> buffer; +        if (!format->findBuffer(tag.c_str(), &buffer)) { +            break;          } +        mCSDsForCurrentFormat.push(buffer);      } - -    return filteredCCBuf; -} - -void NuPlayer::CCDecoder::decode(const sp<ABuffer> &accessUnit) { -    if (extractFromSEI(accessUnit)) { -        ALOGI("Found CEA-608 track"); -        sp<AMessage> msg = mNotify->dup(); -        msg->setInt32("what", kWhatTrackAdded); -        msg->post(); -    } -    // TODO: extract CC from other sources  } -void NuPlayer::CCDecoder::display(int64_t timeUs) { -    if (!isTrackValid(mSelectedTrack)) { -        ALOGE("Could not find current track(index=%d)", mSelectedTrack); -        return; -    } - -    ssize_t index = mCCMap.indexOfKey(timeUs); -    if (index < 0) { -        ALOGV("cc for timestamp %" PRId64 " not found", timeUs); -        return; -    } - -    sp<ABuffer> ccBuf = filterCCBuf(mCCMap.valueAt(index), mSelectedTrack); +void NuPlayer::Decoder::notifyResumeCompleteIfNecessary() { +    if (mResumePending) { +        mResumePending = false; -    if (ccBuf->size() > 0) { -#if 0 -        dumpBytePair(ccBuf); -#endif - -        ccBuf->meta()->setInt32("trackIndex", mSelectedTrack); -        ccBuf->meta()->setInt64("timeUs", timeUs); -        ccBuf->meta()->setInt64("durationUs", 0ll); - -        sp<AMessage> msg = mNotify->dup(); -        msg->setInt32("what", kWhatClosedCaptionData); -        msg->setBuffer("buffer", ccBuf); -        msg->post(); +        sp<AMessage> notify = mNotify->dup(); +        notify->setInt32("what", kWhatResumeCompleted); +        notify->post();      } - -    // remove all entries before timeUs -    mCCMap.removeItemsAt(0, index + 1); -} - -void NuPlayer::CCDecoder::flush() { -    mCCMap.clear();  }  }  // namespace android diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h index dba3eee..1bfa94f 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h @@ -1,5 +1,5 @@  /* - * Copyright (C) 2010 The Android Open Source Project + * 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. @@ -15,70 +15,54 @@   */  #ifndef NUPLAYER_DECODER_H_ -  #define NUPLAYER_DECODER_H_  #include "NuPlayer.h" -#include <media/stagefright/foundation/AHandler.h> +#include "NuPlayerDecoderBase.h"  namespace android { -struct ABuffer; -struct MediaCodec; -struct MediaBuffer; - -struct NuPlayer::Decoder : public AHandler { +struct NuPlayer::Decoder : public DecoderBase {      Decoder(const sp<AMessage> ¬ify, -            const sp<NativeWindowWrapper> &nativeWindow = NULL); - -    virtual void configure(const sp<AMessage> &format); -    virtual void init(); - -    status_t getInputBuffers(Vector<sp<ABuffer> > *dstBuffers) const; -    virtual void signalFlush(const sp<AMessage> &format = NULL); -    virtual void signalUpdateFormat(const sp<AMessage> &format); -    virtual void signalResume(); -    virtual void initiateShutdown(); +            const sp<Source> &source, +            const sp<Renderer> &renderer = NULL, +            const sp<NativeWindowWrapper> &nativeWindow = NULL, +            const sp<CCDecoder> &ccDecoder = NULL); -    virtual bool supportsSeamlessFormatChange(const sp<AMessage> &to) const; - -    enum { -        kWhatFillThisBuffer      = 'flTB', -        kWhatDrainThisBuffer     = 'drTB', -        kWhatOutputFormatChanged = 'fmtC', -        kWhatFlushCompleted      = 'flsC', -        kWhatShutdownCompleted   = 'shDC', -        kWhatEOS                 = 'eos ', -        kWhatError               = 'err ', -    }; +    virtual void getStats( +            int64_t *mNumFramesTotal, +            int64_t *mNumFramesDropped) const;  protected: -      virtual ~Decoder();      virtual void onMessageReceived(const sp<AMessage> &msg); +    virtual void onConfigure(const sp<AMessage> &format); +    virtual void onSetRenderer(const sp<Renderer> &renderer); +    virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers); +    virtual void onResume(bool notifyComplete); +    virtual void onFlush(bool notifyComplete); +    virtual void onShutdown(bool notifyComplete); +    virtual void doRequestBuffers(); +  private:      enum { -        kWhatCodecNotify        = 'cdcN', -        kWhatConfigure          = 'conf', -        kWhatGetInputBuffers    = 'gInB', -        kWhatInputBufferFilled  = 'inpF', -        kWhatRenderBuffer       = 'rndr', -        kWhatFlush              = 'flus', -        kWhatShutdown           = 'shuD', -        kWhatUpdateFormat       = 'uFmt', +        kWhatCodecNotify         = 'cdcN', +        kWhatRenderBuffer        = 'rndr',      }; -    sp<AMessage> mNotify;      sp<NativeWindowWrapper> mNativeWindow; +    sp<Source> mSource; +    sp<Renderer> mRenderer; +    sp<CCDecoder> mCCDecoder; +      sp<AMessage> mInputFormat;      sp<AMessage> mOutputFormat;      sp<MediaCodec> mCodec;      sp<ALooper> mCodecLooper; -    sp<ALooper> mDecoderLooper;      List<sp<AMessage> > mPendingInputMessages; @@ -88,8 +72,20 @@ private:      Vector<sp<ABuffer> > mCSDsToSubmit;      Vector<bool> mInputBufferIsDequeued;      Vector<MediaBuffer *> mMediaBuffers; +    Vector<size_t> mDequeuedInputBuffers; + +    int64_t mSkipRenderingUntilMediaTimeUs; +    int64_t mNumFramesTotal; +    int64_t mNumFramesDropped; +    bool mIsAudio; +    bool mIsVideoAVC; +    bool mIsSecure; +    bool mFormatChangePending; + +    bool mPaused; +    bool mResumePending; +    AString mComponentName; -    void handleError(int32_t err);      bool handleAnInputBuffer();      bool handleAnOutputBuffer(); @@ -97,53 +93,17 @@ private:      void requestCodecNotification();      bool isStaleReply(const sp<AMessage> &msg); -    void onConfigure(const sp<AMessage> &format); -    void onFlush(); -    void onResume(); -    bool onInputBufferFilled(const sp<AMessage> &msg); +    status_t fetchInputData(sp<AMessage> &reply); +    bool onInputBufferFetched(const sp<AMessage> &msg);      void onRenderBuffer(const sp<AMessage> &msg); -    void onShutdown(); - -    int32_t mBufferGeneration; -    bool mPaused; -    AString mComponentName; +    bool supportsSeamlessFormatChange(const sp<AMessage> &to) const;      bool supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const;      void rememberCodecSpecificData(const sp<AMessage> &format); -    DISALLOW_EVIL_CONSTRUCTORS(Decoder); -}; +    void notifyResumeCompleteIfNecessary(); -struct NuPlayer::CCDecoder : public RefBase { -    enum { -        kWhatClosedCaptionData, -        kWhatTrackAdded, -    }; - -    CCDecoder(const sp<AMessage> ¬ify); - -    size_t getTrackCount() const; -    sp<AMessage> getTrackInfo(size_t index) const; -    status_t selectTrack(size_t index, bool select); -    bool isSelected() const; -    void decode(const sp<ABuffer> &accessUnit); -    void display(int64_t timeUs); -    void flush(); - -private: -    sp<AMessage> mNotify; -    KeyedVector<int64_t, sp<ABuffer> > mCCMap; -    size_t mCurrentChannel; -    int32_t mSelectedTrack; -    int32_t mTrackIndices[4]; -    Vector<size_t> mFoundChannels; - -    bool isTrackValid(size_t index) const; -    int32_t getTrackIndex(size_t channel) const; -    bool extractFromSEI(const sp<ABuffer> &accessUnit); -    sp<ABuffer> filterCCBuf(const sp<ABuffer> &ccBuf, size_t index); - -    DISALLOW_EVIL_CONSTRUCTORS(CCDecoder); +    DISALLOW_EVIL_CONSTRUCTORS(Decoder);  };  }  // namespace android diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp new file mode 100644 index 0000000..d56fc4d --- /dev/null +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "NuPlayerDecoderBase" +#include <utils/Log.h> +#include <inttypes.h> + +#include "NuPlayerDecoderBase.h" + +#include "NuPlayerRenderer.h" + +#include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/foundation/AMessage.h> + +namespace android { + +NuPlayer::DecoderBase::DecoderBase(const sp<AMessage> ¬ify) +    :  mNotify(notify), +       mBufferGeneration(0), +       mRequestInputBuffersPending(false) { +    // Every decoder has its own looper because MediaCodec operations +    // are blocking, but NuPlayer needs asynchronous operations. +    mDecoderLooper = new ALooper; +    mDecoderLooper->setName("NPDecoder"); +    mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO); +} + +NuPlayer::DecoderBase::~DecoderBase() { +    mDecoderLooper->unregisterHandler(id()); +    mDecoderLooper->stop(); +} + +static +status_t PostAndAwaitResponse( +        const sp<AMessage> &msg, sp<AMessage> *response) { +    status_t err = msg->postAndAwaitResponse(response); + +    if (err != OK) { +        return err; +    } + +    if (!(*response)->findInt32("err", &err)) { +        err = OK; +    } + +    return err; +} + +void NuPlayer::DecoderBase::configure(const sp<AMessage> &format) { +    sp<AMessage> msg = new AMessage(kWhatConfigure, id()); +    msg->setMessage("format", format); +    msg->post(); +} + +void NuPlayer::DecoderBase::init() { +    mDecoderLooper->registerHandler(this); +} + +void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) { +    sp<AMessage> msg = new AMessage(kWhatSetRenderer, id()); +    msg->setObject("renderer", renderer); +    msg->post(); +} + +status_t NuPlayer::DecoderBase::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { +    sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, id()); +    msg->setPointer("buffers", buffers); + +    sp<AMessage> response; +    return PostAndAwaitResponse(msg, &response); +} + +void NuPlayer::DecoderBase::signalFlush() { +    (new AMessage(kWhatFlush, id()))->post(); +} + +void NuPlayer::DecoderBase::signalResume(bool notifyComplete) { +    sp<AMessage> msg = new AMessage(kWhatResume, id()); +    msg->setInt32("notifyComplete", notifyComplete); +    msg->post(); +} + +void NuPlayer::DecoderBase::initiateShutdown() { +    (new AMessage(kWhatShutdown, id()))->post(); +} + +void NuPlayer::DecoderBase::onRequestInputBuffers() { +    if (mRequestInputBuffersPending) { +        return; +    } + +    doRequestBuffers(); +} + +void NuPlayer::DecoderBase::scheduleRequestBuffers() { +    if (mRequestInputBuffersPending) { +        return; +    } +    mRequestInputBuffersPending = true; +    sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, id()); +    msg->post(10 * 1000ll); +} + +void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) { + +    switch (msg->what()) { +        case kWhatConfigure: +        { +            sp<AMessage> format; +            CHECK(msg->findMessage("format", &format)); +            onConfigure(format); +            break; +        } + +        case kWhatSetRenderer: +        { +            sp<RefBase> obj; +            CHECK(msg->findObject("renderer", &obj)); +            onSetRenderer(static_cast<Renderer *>(obj.get())); +            break; +        } + +        case kWhatGetInputBuffers: +        { +            uint32_t replyID; +            CHECK(msg->senderAwaitsResponse(&replyID)); + +            Vector<sp<ABuffer> > *dstBuffers; +            CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); + +            onGetInputBuffers(dstBuffers); + +            (new AMessage)->postReply(replyID); +            break; +        } + +        case kWhatRequestInputBuffers: +        { +            mRequestInputBuffersPending = false; +            onRequestInputBuffers(); +            break; +        } + +        case kWhatFlush: +        { +            onFlush(true); +            break; +        } + +        case kWhatResume: +        { +            int32_t notifyComplete; +            CHECK(msg->findInt32("notifyComplete", ¬ifyComplete)); + +            onResume(notifyComplete); +            break; +        } + +        case kWhatShutdown: +        { +            onShutdown(true); +            break; +        } + +        default: +            TRESPASS(); +            break; +    } +} + +void NuPlayer::DecoderBase::handleError(int32_t err) +{ +    // We cannot immediately release the codec due to buffers still outstanding +    // in the renderer.  We signal to the player the error so it can shutdown/release the +    // decoder after flushing and increment the generation to discard unnecessary messages. + +    ++mBufferGeneration; + +    sp<AMessage> notify = mNotify->dup(); +    notify->setInt32("what", kWhatError); +    notify->setInt32("err", err); +    notify->post(); +} + +}  // namespace android + diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h new file mode 100644 index 0000000..6732ff4 --- /dev/null +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NUPLAYER_DECODER_BASE_H_ + +#define NUPLAYER_DECODER_BASE_H_ + +#include "NuPlayer.h" + +#include <media/stagefright/foundation/AHandler.h> + +namespace android { + +struct ABuffer; +struct MediaCodec; +struct MediaBuffer; + +struct NuPlayer::DecoderBase : public AHandler { +    DecoderBase(const sp<AMessage> ¬ify); + +    void configure(const sp<AMessage> &format); +    void init(); + +    void setRenderer(const sp<Renderer> &renderer); + +    status_t getInputBuffers(Vector<sp<ABuffer> > *dstBuffers) const; +    void signalFlush(); +    void signalResume(bool notifyComplete); +    void initiateShutdown(); + +    virtual void getStats( +            int64_t *mNumFramesTotal, +            int64_t *mNumFramesDropped) const = 0; + +    enum { +        kWhatInputDiscontinuity  = 'inDi', +        kWhatVideoSizeChanged    = 'viSC', +        kWhatFlushCompleted      = 'flsC', +        kWhatShutdownCompleted   = 'shDC', +        kWhatResumeCompleted     = 'resC', +        kWhatEOS                 = 'eos ', +        kWhatError               = 'err ', +    }; + +protected: + +    virtual ~DecoderBase(); + +    virtual void onMessageReceived(const sp<AMessage> &msg); + +    virtual void onConfigure(const sp<AMessage> &format) = 0; +    virtual void onSetRenderer(const sp<Renderer> &renderer) = 0; +    virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers) = 0; +    virtual void onResume(bool notifyComplete) = 0; +    virtual void onFlush(bool notifyComplete) = 0; +    virtual void onShutdown(bool notifyComplete) = 0; + +    void onRequestInputBuffers(); +    void scheduleRequestBuffers(); +    virtual void doRequestBuffers() = 0; +    virtual void handleError(int32_t err); + +    sp<AMessage> mNotify; +    int32_t mBufferGeneration; + +private: +    enum { +        kWhatConfigure           = 'conf', +        kWhatSetRenderer         = 'setR', +        kWhatGetInputBuffers     = 'gInB', +        kWhatRequestInputBuffers = 'reqB', +        kWhatFlush               = 'flus', +        kWhatShutdown            = 'shuD', +    }; + +    sp<ALooper> mDecoderLooper; +    bool mRequestInputBuffersPending; + +    DISALLOW_EVIL_CONSTRUCTORS(DecoderBase); +}; + +}  // namespace android + +#endif  // NUPLAYER_DECODER_BASE_H_ diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp index f7aacdd..9f7f09a 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp @@ -21,79 +21,80 @@  #include "NuPlayerDecoderPassThrough.h" +#include "NuPlayerRenderer.h" +#include "NuPlayerSource.h" +  #include <media/ICrypto.h>  #include <media/stagefright/foundation/ABuffer.h>  #include <media/stagefright/foundation/ADebug.h>  #include <media/stagefright/foundation/AMessage.h> -#include <media/stagefright/MediaDefs.h>  #include <media/stagefright/MediaErrors.h> +#include "ATSParser.h" +  namespace android { +// TODO optimize buffer size for power consumption +// The offload read buffer size is 32 KB but 24 KB uses less power. +static const size_t kAggregateBufferSizeBytes = 24 * 1024;  static const size_t kMaxCachedBytes = 200000; -// The buffers will contain a bit less than kAggregateBufferSizeBytes. -// So we can start off with just enough buffers to keep the cache full. -static const size_t kMaxPendingBuffers = 1 + (kMaxCachedBytes / NuPlayer::kAggregateBufferSizeBytes);  NuPlayer::DecoderPassThrough::DecoderPassThrough( -        const sp<AMessage> ¬ify) -    : Decoder(notify), -      mNotify(notify), -      mBufferGeneration(0), +        const sp<AMessage> ¬ify, +        const sp<Source> &source, +        const sp<Renderer> &renderer) +    : DecoderBase(notify), +      mSource(source), +      mRenderer(renderer), +      mSkipRenderingUntilMediaTimeUs(-1ll), +      mPaused(false),        mReachedEOS(true), -      mPendingBuffersToFill(0), +      mPendingAudioErr(OK),        mPendingBuffersToDrain(0),        mCachedBytes(0),        mComponentName("pass through decoder") { -    mDecoderLooper = new ALooper; -    mDecoderLooper->setName("NuPlayerDecoderPassThrough"); -    mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO); +    ALOGW_IF(renderer == NULL, "expect a non-NULL renderer");  }  NuPlayer::DecoderPassThrough::~DecoderPassThrough() {  } -void NuPlayer::DecoderPassThrough::configure(const sp<AMessage> &format) { -    sp<AMessage> msg = new AMessage(kWhatConfigure, id()); -    msg->setMessage("format", format); -    msg->post(); -} - -void NuPlayer::DecoderPassThrough::init() { -    mDecoderLooper->registerHandler(this); -} - -void NuPlayer::DecoderPassThrough::signalFlush() { -    (new AMessage(kWhatFlush, id()))->post(); -} - -void NuPlayer::DecoderPassThrough::signalResume() { -    (new AMessage(kWhatResume, id()))->post(); -} - -void NuPlayer::DecoderPassThrough::initiateShutdown() { -    (new AMessage(kWhatShutdown, id()))->post(); -} - -bool NuPlayer::DecoderPassThrough::supportsSeamlessFormatChange( -        const sp<AMessage> & /* targetFormat */) const { -    return true; +void NuPlayer::DecoderPassThrough::getStats( +        int64_t *numFramesTotal, int64_t *numFramesDropped) const { +    *numFramesTotal = 0; +    *numFramesDropped = 0;  }  void NuPlayer::DecoderPassThrough::onConfigure(const sp<AMessage> &format) {      ALOGV("[%s] onConfigure", mComponentName.c_str());      mCachedBytes = 0; -    mPendingBuffersToFill = 0;      mPendingBuffersToDrain = 0;      mReachedEOS = false;      ++mBufferGeneration; -    requestMaxBuffers(); +    onRequestInputBuffers(); -    sp<AMessage> notify = mNotify->dup(); -    notify->setInt32("what", kWhatOutputFormatChanged); -    notify->setMessage("format", format); -    notify->post(); +    // The audio sink is already opened before the PassThrough decoder is created. +    // Opening again might be relevant if decoder is instantiated after shutdown and +    // format is different. +    status_t err = mRenderer->openAudioSink( +            format, true /* offloadOnly */, false /* hasVideo */, +            AUDIO_OUTPUT_FLAG_NONE /* flags */, NULL /* isOffloaded */); +    if (err != OK) { +        handleError(err); +    } +} + +void NuPlayer::DecoderPassThrough::onSetRenderer( +        const sp<Renderer> &renderer) { +    // renderer can't be changed during offloading +    ALOGW_IF(renderer != mRenderer, +            "ignoring request to change renderer"); +} + +void NuPlayer::DecoderPassThrough::onGetInputBuffers( +        Vector<sp<ABuffer> > * /* dstBuffers */) { +    ALOGE("onGetInputBuffers() called unexpectedly");  }  bool NuPlayer::DecoderPassThrough::isStaleReply(const sp<AMessage> &msg) { @@ -102,100 +103,301 @@ bool NuPlayer::DecoderPassThrough::isStaleReply(const sp<AMessage> &msg) {      return generation != mBufferGeneration;  } -bool NuPlayer::DecoderPassThrough::requestABuffer() { -    if (mCachedBytes >= kMaxCachedBytes) { -        ALOGV("[%s] mCachedBytes = %zu", -                mComponentName.c_str(), mCachedBytes); -        return false; +bool NuPlayer::DecoderPassThrough::isDoneFetching() const { +    ALOGV("[%s] mCachedBytes = %zu, mReachedEOS = %d mPaused = %d", +            mComponentName.c_str(), mCachedBytes, mReachedEOS, mPaused); + +    return mCachedBytes >= kMaxCachedBytes || mReachedEOS || mPaused; +} + +void NuPlayer::DecoderPassThrough::doRequestBuffers() { +    status_t err = OK; +    while (!isDoneFetching()) { +        sp<AMessage> msg = new AMessage(); + +        err = fetchInputData(msg); +        if (err != OK) { +            break; +        } + +        onInputBufferFetched(msg);      } -    if (mReachedEOS) { -        ALOGV("[%s] reached EOS", mComponentName.c_str()); -        return false; + +    if (err == -EWOULDBLOCK +            && mSource->feedMoreTSData() == OK) { +        scheduleRequestBuffers();      } +} -    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id()); -    reply->setInt32("generation", mBufferGeneration); +status_t NuPlayer::DecoderPassThrough::dequeueAccessUnit(sp<ABuffer> *accessUnit) { +    status_t err; + +    // Did we save an accessUnit earlier because of a discontinuity? +    if (mPendingAudioAccessUnit != NULL) { +        *accessUnit = mPendingAudioAccessUnit; +        mPendingAudioAccessUnit.clear(); +        err = mPendingAudioErr; +        ALOGV("feedDecoderInputData() use mPendingAudioAccessUnit"); +    } else { +        err = mSource->dequeueAccessUnit(true /* audio */, accessUnit); +    } -    sp<AMessage> notify = mNotify->dup(); -    notify->setInt32("what", kWhatFillThisBuffer); -    notify->setMessage("reply", reply); -    notify->post(); -    mPendingBuffersToFill++; -    ALOGV("requestABuffer: #ToFill = %zu, #ToDrain = %zu", mPendingBuffersToFill, -            mPendingBuffersToDrain); +    if (err == INFO_DISCONTINUITY || err == ERROR_END_OF_STREAM) { +        if (mAggregateBuffer != NULL) { +            // We already have some data so save this for later. +            mPendingAudioErr = err; +            mPendingAudioAccessUnit = *accessUnit; +            (*accessUnit).clear(); +            ALOGD("return aggregated buffer and save err(=%d) for later", err); +            err = OK; +        } +    } -    return true; +    return err;  } -void android::NuPlayer::DecoderPassThrough::onInputBufferFilled( +sp<ABuffer> NuPlayer::DecoderPassThrough::aggregateBuffer( +        const sp<ABuffer> &accessUnit) { +    sp<ABuffer> aggregate; + +    if (accessUnit == NULL) { +        // accessUnit is saved to mPendingAudioAccessUnit +        // return current mAggregateBuffer +        aggregate = mAggregateBuffer; +        mAggregateBuffer.clear(); +        return aggregate; +    } + +    size_t smallSize = accessUnit->size(); +    if ((mAggregateBuffer == NULL) +            // Don't bother if only room for a few small buffers. +            && (smallSize < (kAggregateBufferSizeBytes / 3))) { +        // Create a larger buffer for combining smaller buffers from the extractor. +        mAggregateBuffer = new ABuffer(kAggregateBufferSizeBytes); +        mAggregateBuffer->setRange(0, 0); // start empty +    } + +    if (mAggregateBuffer != NULL) { +        int64_t timeUs; +        int64_t dummy; +        bool smallTimestampValid = accessUnit->meta()->findInt64("timeUs", &timeUs); +        bool bigTimestampValid = mAggregateBuffer->meta()->findInt64("timeUs", &dummy); +        // Will the smaller buffer fit? +        size_t bigSize = mAggregateBuffer->size(); +        size_t roomLeft = mAggregateBuffer->capacity() - bigSize; +        // Should we save this small buffer for the next big buffer? +        // If the first small buffer did not have a timestamp then save +        // any buffer that does have a timestamp until the next big buffer. +        if ((smallSize > roomLeft) +            || (!bigTimestampValid && (bigSize > 0) && smallTimestampValid)) { +            mPendingAudioErr = OK; +            mPendingAudioAccessUnit = accessUnit; +            aggregate = mAggregateBuffer; +            mAggregateBuffer.clear(); +        } else { +            // Grab time from first small buffer if available. +            if ((bigSize == 0) && smallTimestampValid) { +                mAggregateBuffer->meta()->setInt64("timeUs", timeUs); +            } +            // Append small buffer to the bigger buffer. +            memcpy(mAggregateBuffer->base() + bigSize, accessUnit->data(), smallSize); +            bigSize += smallSize; +            mAggregateBuffer->setRange(0, bigSize); + +            ALOGV("feedDecoderInputData() smallSize = %zu, bigSize = %zu, capacity = %zu", +                    smallSize, bigSize, mAggregateBuffer->capacity()); +        } +    } else { +        // decided not to aggregate +        aggregate = accessUnit; +    } + +    return aggregate; +} + +status_t NuPlayer::DecoderPassThrough::fetchInputData(sp<AMessage> &reply) { +    sp<ABuffer> accessUnit; + +    do { +        status_t err = dequeueAccessUnit(&accessUnit); + +        if (err == -EWOULDBLOCK) { +            return err; +        } else if (err != OK) { +            if (err == INFO_DISCONTINUITY) { +                int32_t type; +                CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); + +                bool formatChange = +                        (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT) != 0; + +                bool timeChange = +                        (type & ATSParser::DISCONTINUITY_TIME) != 0; + +                ALOGI("audio discontinuity (formatChange=%d, time=%d)", +                        formatChange, timeChange); + +                if (formatChange || timeChange) { +                    sp<AMessage> msg = mNotify->dup(); +                    msg->setInt32("what", kWhatInputDiscontinuity); +                    // will perform seamless format change, +                    // only notify NuPlayer to scan sources +                    msg->setInt32("formatChange", false); +                    msg->post(); +                } + +                if (timeChange) { +                    onFlush(false /* notifyComplete */); +                    err = OK; +                } else if (formatChange) { +                    // do seamless format change +                    err = OK; +                } else { +                    // This stream is unaffected by the discontinuity +                    return -EWOULDBLOCK; +                } +            } + +            reply->setInt32("err", err); +            return OK; +        } + +        accessUnit = aggregateBuffer(accessUnit); +    } while (accessUnit == NULL); + +#if 0 +    int64_t mediaTimeUs; +    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); +    ALOGV("feeding audio input buffer at media time %.2f secs", +         mediaTimeUs / 1E6); +#endif + +    reply->setBuffer("buffer", accessUnit); + +    return OK; +} + +void NuPlayer::DecoderPassThrough::onInputBufferFetched(          const sp<AMessage> &msg) { -    --mPendingBuffersToFill;      if (mReachedEOS) {          return;      }      sp<ABuffer> buffer; -    msg->findBuffer("buffer", &buffer); +    bool hasBuffer = msg->findBuffer("buffer", &buffer);      if (buffer == NULL) { -        mReachedEOS = true; +        int32_t streamErr = ERROR_END_OF_STREAM; +        CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); +        if (streamErr == OK) { +            return; +        } -        sp<AMessage> notify = mNotify->dup(); -        notify->setInt32("what", kWhatEOS); -        notify->setInt32("err", ERROR_END_OF_STREAM); -        notify->post(); +        mReachedEOS = true; +        if (mRenderer != NULL) { +            mRenderer->queueEOS(true /* audio */, ERROR_END_OF_STREAM); +        }          return;      } -    mCachedBytes += buffer->size(); +    sp<AMessage> extra; +    if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) { +        int64_t resumeAtMediaTimeUs; +        if (extra->findInt64( +                    "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) { +            ALOGI("[%s] suppressing rendering until %lld us", +                    mComponentName.c_str(), (long long)resumeAtMediaTimeUs); +            mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs; +        } +    } + +    int32_t bufferSize = buffer->size(); +    mCachedBytes += bufferSize; + +    if (mSkipRenderingUntilMediaTimeUs >= 0) { +        int64_t timeUs = 0; +        CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); + +        if (timeUs < mSkipRenderingUntilMediaTimeUs) { +            ALOGV("[%s] dropping buffer at time %lld as requested.", +                     mComponentName.c_str(), (long long)timeUs); + +            onBufferConsumed(bufferSize); +            return; +        } + +        mSkipRenderingUntilMediaTimeUs = -1; +    } + +    if (mRenderer == NULL) { +        onBufferConsumed(bufferSize); +        return; +    }      sp<AMessage> reply = new AMessage(kWhatBufferConsumed, id());      reply->setInt32("generation", mBufferGeneration); -    reply->setInt32("size", buffer->size()); +    reply->setInt32("size", bufferSize); + +    mRenderer->queueBuffer(true /* audio */, buffer, reply); -    sp<AMessage> notify = mNotify->dup(); -    notify->setInt32("what", kWhatDrainThisBuffer); -    notify->setBuffer("buffer", buffer); -    notify->setMessage("reply", reply); -    notify->post();      ++mPendingBuffersToDrain; -    ALOGV("onInputBufferFilled: #ToFill = %zu, #ToDrain = %zu, cachedBytes = %zu", -            mPendingBuffersToFill, mPendingBuffersToDrain, mCachedBytes); +    ALOGV("onInputBufferFilled: #ToDrain = %zu, cachedBytes = %zu", +            mPendingBuffersToDrain, mCachedBytes);  }  void NuPlayer::DecoderPassThrough::onBufferConsumed(int32_t size) {      --mPendingBuffersToDrain;      mCachedBytes -= size; -    ALOGV("onBufferConsumed: #ToFill = %zu, #ToDrain = %zu, cachedBytes = %zu", -           mPendingBuffersToFill, mPendingBuffersToDrain, mCachedBytes); -    requestABuffer(); +    ALOGV("onBufferConsumed: #ToDrain = %zu, cachedBytes = %zu", +            mPendingBuffersToDrain, mCachedBytes); +    onRequestInputBuffers(); +} + +void NuPlayer::DecoderPassThrough::onResume(bool notifyComplete) { +    mPaused = false; + +    onRequestInputBuffers(); + +    if (notifyComplete) { +        sp<AMessage> notify = mNotify->dup(); +        notify->setInt32("what", kWhatResumeCompleted); +        notify->post(); +    }  } -void NuPlayer::DecoderPassThrough::onFlush() { +void NuPlayer::DecoderPassThrough::onFlush(bool notifyComplete) {      ++mBufferGeneration; +    mSkipRenderingUntilMediaTimeUs = -1; +    mPendingAudioAccessUnit.clear(); +    mPendingAudioErr = OK; +    mAggregateBuffer.clear(); + +    if (mRenderer != NULL) { +        mRenderer->flush(true /* audio */, notifyComplete); +        mRenderer->signalTimeDiscontinuity(); +    } + +    if (notifyComplete) { +        mPaused = true; +        sp<AMessage> notify = mNotify->dup(); +        notify->setInt32("what", kWhatFlushCompleted); +        notify->post(); +    } -    sp<AMessage> notify = mNotify->dup(); -    notify->setInt32("what", kWhatFlushCompleted); -    notify->post(); -    mPendingBuffersToFill = 0;      mPendingBuffersToDrain = 0;      mCachedBytes = 0;      mReachedEOS = false;  } -void NuPlayer::DecoderPassThrough::requestMaxBuffers() { -    for (size_t i = 0; i < kMaxPendingBuffers; i++) { -        if (!requestABuffer()) { -            break; -        } -    } -} - -void NuPlayer::DecoderPassThrough::onShutdown() { +void NuPlayer::DecoderPassThrough::onShutdown(bool notifyComplete) {      ++mBufferGeneration; +    mSkipRenderingUntilMediaTimeUs = -1; + +    if (notifyComplete) { +        sp<AMessage> notify = mNotify->dup(); +        notify->setInt32("what", kWhatShutdownCompleted); +        notify->post(); +    } -    sp<AMessage> notify = mNotify->dup(); -    notify->setInt32("what", kWhatShutdownCompleted); -    notify->post();      mReachedEOS = true;  } @@ -204,31 +406,6 @@ void NuPlayer::DecoderPassThrough::onMessageReceived(const sp<AMessage> &msg) {              msg->debugString().c_str());      switch (msg->what()) { -        case kWhatConfigure: -        { -            sp<AMessage> format; -            CHECK(msg->findMessage("format", &format)); -            onConfigure(format); -            break; -        } - -        case kWhatRequestABuffer: -        { -            if (!isStaleReply(msg)) { -                requestABuffer(); -            } - -            break; -        } - -        case kWhatInputBufferFilled: -        { -            if (!isStaleReply(msg)) { -                onInputBufferFilled(msg); -            } -            break; -        } -          case kWhatBufferConsumed:          {              if (!isStaleReply(msg)) { @@ -239,26 +416,8 @@ void NuPlayer::DecoderPassThrough::onMessageReceived(const sp<AMessage> &msg) {              break;          } -        case kWhatFlush: -        { -            onFlush(); -            break; -        } - -        case kWhatResume: -        { -            requestMaxBuffers(); -            break; -        } - -        case kWhatShutdown: -        { -            onShutdown(); -            break; -        } -          default: -            TRESPASS(); +            DecoderBase::onMessageReceived(msg);              break;      }  } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h index fb20257..a6e1faf 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h @@ -20,21 +20,18 @@  #include "NuPlayer.h" -#include "NuPlayerDecoder.h" +#include "NuPlayerDecoderBase.h"  namespace android { -struct NuPlayer::DecoderPassThrough : public Decoder { -    DecoderPassThrough(const sp<AMessage> ¬ify); +struct NuPlayer::DecoderPassThrough : public DecoderBase { +    DecoderPassThrough(const sp<AMessage> ¬ify, +                       const sp<Source> &source, +                       const sp<Renderer> &renderer); -    virtual void configure(const sp<AMessage> &format); -    virtual void init(); - -    virtual void signalFlush(); -    virtual void signalResume(); -    virtual void initiateShutdown(); - -    bool supportsSeamlessFormatChange(const sp<AMessage> &to) const; +    virtual void getStats( +            int64_t *mNumFramesTotal, +            int64_t *mNumFramesDropped) const;  protected: @@ -42,41 +39,48 @@ protected:      virtual void onMessageReceived(const sp<AMessage> &msg); +    virtual void onConfigure(const sp<AMessage> &format); +    virtual void onSetRenderer(const sp<Renderer> &renderer); +    virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers); +    virtual void onResume(bool notifyComplete); +    virtual void onFlush(bool notifyComplete); +    virtual void onShutdown(bool notifyComplete); +    virtual void doRequestBuffers(); +  private:      enum { -        kWhatRequestABuffer     = 'reqB', -        kWhatConfigure          = 'conf', -        kWhatInputBufferFilled  = 'inpF',          kWhatBufferConsumed     = 'bufC', -        kWhatFlush              = 'flus', -        kWhatShutdown           = 'shuD',      }; -    sp<AMessage> mNotify; -    sp<ALooper> mDecoderLooper; +    sp<Source> mSource; +    sp<Renderer> mRenderer; +    int64_t mSkipRenderingUntilMediaTimeUs; +    bool mPaused; -    /** Returns true if a buffer was requested. -     * Returns false if at EOS or cache already full. -     */ -    bool requestABuffer(); -    bool isStaleReply(const sp<AMessage> &msg); +    bool    mReachedEOS; -    void onConfigure(const sp<AMessage> &format); -    void onFlush(); -    void onInputBufferFilled(const sp<AMessage> &msg); -    void onBufferConsumed(int32_t size); -    void requestMaxBuffers(); -    void onShutdown(); +    // Used by feedDecoderInputData to aggregate small buffers into +    // one large buffer. +    sp<ABuffer> mPendingAudioAccessUnit; +    status_t    mPendingAudioErr; +    sp<ABuffer> mAggregateBuffer; -    int32_t mBufferGeneration; -    bool    mReachedEOS; -    // TODO mPendingBuffersToFill and mPendingBuffersToDrain are only for -    // debugging. They can be removed when the power investigation is done. -    size_t  mPendingBuffersToFill; +    // mPendingBuffersToDrain are only for debugging. It can be removed +    // when the power investigation is done.      size_t  mPendingBuffersToDrain;      size_t  mCachedBytes;      AString mComponentName; +    bool isStaleReply(const sp<AMessage> &msg); +    bool isDoneFetching() const; + +    status_t dequeueAccessUnit(sp<ABuffer> *accessUnit); +    sp<ABuffer> aggregateBuffer(const sp<ABuffer> &accessUnit); +    status_t fetchInputData(sp<AMessage> &reply); + +    void onInputBufferFetched(const sp<AMessage> &msg); +    void onBufferConsumed(int32_t size); +      DISALLOW_EVIL_CONSTRUCTORS(DecoderPassThrough);  }; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp index ab46074..e7e1759 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp @@ -239,16 +239,24 @@ status_t NuPlayerDriver::start() {              // fall through          } +        case STATE_PAUSED: +        case STATE_STOPPED_AND_PREPARED: +        { +            if (mAtEOS && mStartupSeekTimeUs < 0) { +                mStartupSeekTimeUs = 0; +                mPositionUs = -1; +            } + +            // fall through +        } +          case STATE_PREPARED:          {              mAtEOS = false;              mPlayer->start();              if (mStartupSeekTimeUs >= 0) { -                if (mStartupSeekTimeUs > 0) { -                    mPlayer->seekToAsync(mStartupSeekTimeUs); -                } - +                mPlayer->seekToAsync(mStartupSeekTimeUs);                  mStartupSeekTimeUs = -1;              }              break; @@ -264,20 +272,6 @@ status_t NuPlayerDriver::start() {              break;          } -        case STATE_PAUSED: -        case STATE_STOPPED_AND_PREPARED: -        { -            if (mAtEOS) { -                mPlayer->seekToAsync(0); -                mAtEOS = false; -                mPlayer->resume(); -                mPositionUs = -1; -            } else { -                mPlayer->resume(); -            } -            break; -        } -          default:              return INVALID_OPERATION;      } @@ -316,6 +310,13 @@ status_t NuPlayerDriver::stop() {  }  status_t NuPlayerDriver::pause() { +    // The NuPlayerRenderer may get flushed if pause for long enough, e.g. the pause timeout tear +    // down for audio offload mode. If that happens, the NuPlayerRenderer will no longer know the +    // current position. So similar to seekTo, update |mPositionUs| to the pause position by calling +    // getCurrentPosition here. +    int msec; +    getCurrentPosition(&msec); +      Mutex::Autolock autoLock(mLock);      switch (mState) { @@ -348,6 +349,7 @@ status_t NuPlayerDriver::seekTo(int msec) {      switch (mState) {          case STATE_PREPARED: +        case STATE_STOPPED_AND_PREPARED:          {              mStartupSeekTimeUs = seekTimeUs;              // pretend that the seek completed. It will actually happen when starting playback. @@ -378,13 +380,22 @@ status_t NuPlayerDriver::seekTo(int msec) {  status_t NuPlayerDriver::getCurrentPosition(int *msec) {      int64_t tempUs = 0; +    { +        Mutex::Autolock autoLock(mLock); +        if (mSeekInProgress || mState == STATE_PAUSED) { +            tempUs = (mPositionUs <= 0) ? 0 : mPositionUs; +            *msec = (int)divRound(tempUs, (int64_t)(1000)); +            return OK; +        } +    } +      status_t ret = mPlayer->getCurrentPosition(&tempUs);      Mutex::Autolock autoLock(mLock);      // We need to check mSeekInProgress here because mPlayer->seekToAsync is an async call, which      // means getCurrentPosition can be called before seek is completed. Iow, renderer may return a      // position value that's different the seek to position. -    if (ret != OK || mSeekInProgress) { +    if (ret != OK) {          tempUs = (mPositionUs <= 0) ? 0 : mPositionUs;      } else {          mPositionUs = tempUs; @@ -485,13 +496,16 @@ status_t NuPlayerDriver::invoke(const Parcel &request, Parcel *reply) {          case INVOKE_ID_SELECT_TRACK:          {              int trackIndex = request.readInt32(); -            return mPlayer->selectTrack(trackIndex, true /* select */); +            int msec = 0; +            // getCurrentPosition should always return OK +            getCurrentPosition(&msec); +            return mPlayer->selectTrack(trackIndex, true /* select */, msec * 1000ll);          }          case INVOKE_ID_UNSELECT_TRACK:          {              int trackIndex = request.readInt32(); -            return mPlayer->selectTrack(trackIndex, false /* select */); +            return mPlayer->selectTrack(trackIndex, false /* select */, 0xdeadbeef /* not used */);          }          case INVOKE_ID_GET_SELECTED_TRACK: @@ -630,9 +644,24 @@ void NuPlayerDriver::notifyListener_l(          case MEDIA_PLAYBACK_COMPLETE:          {              if (mState != STATE_RESET_IN_PROGRESS) { +                if (mAutoLoop) { +                    audio_stream_type_t streamType = AUDIO_STREAM_MUSIC; +                    if (mAudioSink != NULL) { +                        streamType = mAudioSink->getAudioStreamType(); +                    } +                    if (streamType == AUDIO_STREAM_NOTIFICATION) { +                        ALOGW("disabling auto-loop for notification"); +                        mAutoLoop = false; +                    } +                }                  if (mLooping || (mAutoLoop                          && (mAudioSink == NULL || mAudioSink->realtime()))) {                      mPlayer->seekToAsync(0); +                    if (mAudioSink != NULL) { +                        // The renderer has stopped the sink at the end in order to play out +                        // the last little bit of audio. If we're looping, we need to restart it. +                        mAudioSink->start(); +                    }                      break;                  } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 86ce385..25225a8 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -20,12 +20,11 @@  #include "NuPlayerRenderer.h" -#include <cutils/properties.h> -  #include <media/stagefright/foundation/ABuffer.h>  #include <media/stagefright/foundation/ADebug.h>  #include <media/stagefright/foundation/AMessage.h>  #include <media/stagefright/foundation/AUtils.h> +#include <media/stagefright/foundation/AWakeLock.h>  #include <media/stagefright/MediaErrors.h>  #include <media/stagefright/MetaData.h>  #include <media/stagefright/Utils.h> @@ -38,20 +37,19 @@ namespace android {  // Maximum time in paused state when offloading audio decompression. When elapsed, the AudioSink  // is closed to allow the audio DSP to power down. -static const int64_t kOffloadPauseMaxUs = 60000000ll; +static const int64_t kOffloadPauseMaxUs = 10000000ll;  // static -const int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll; +const NuPlayer::Renderer::PcmInfo NuPlayer::Renderer::AUDIO_PCMINFO_INITIALIZER = { +        AUDIO_CHANNEL_NONE, +        AUDIO_OUTPUT_FLAG_NONE, +        AUDIO_FORMAT_INVALID, +        0, // mNumChannels +        0 // mSampleRate +}; -static bool sFrameAccurateAVsync = false; - -static void readProperties() { -    char value[PROPERTY_VALUE_MAX]; -    if (property_get("persist.sys.media.avsync", value, NULL)) { -        sFrameAccurateAVsync = -            !strcmp("1", value) || !strcasecmp("true", value); -    } -} +// static +const int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll;  NuPlayer::Renderer::Renderer(          const sp<MediaPlayerBase::AudioSink> &sink, @@ -76,8 +74,11 @@ NuPlayer::Renderer::Renderer(        mPauseStartedTimeRealUs(-1),        mFlushingAudio(false),        mFlushingVideo(false), +      mNotifyCompleteAudio(false), +      mNotifyCompleteVideo(false),        mSyncQueues(false),        mPaused(false), +      mPausePositionMediaTimeUs(-1),        mVideoSampleReceived(false),        mVideoRenderingStarted(false),        mVideoRenderingStartGeneration(0), @@ -85,9 +86,11 @@ NuPlayer::Renderer::Renderer(        mAudioOffloadPauseTimeoutGeneration(0),        mAudioOffloadTornDown(false),        mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER), +      mCurrentPcmInfo(AUDIO_PCMINFO_INITIALIZER),        mTotalBuffersQueued(0), -      mLastAudioBufferDrained(0) { -    readProperties(); +      mLastAudioBufferDrained(0), +      mWakeLock(new AWakeLock()) { +  }  NuPlayer::Renderer::~Renderer() { @@ -118,15 +121,17 @@ void NuPlayer::Renderer::queueEOS(bool audio, status_t finalResult) {      msg->post();  } -void NuPlayer::Renderer::flush(bool audio) { +void NuPlayer::Renderer::flush(bool audio, bool notifyComplete) {      {          Mutex::Autolock autoLock(mFlushLock);          if (audio) { +            mNotifyCompleteAudio |= notifyComplete;              if (mFlushingAudio) {                  return;              }              mFlushingAudio = true;          } else { +            mNotifyCompleteVideo |= notifyComplete;              if (mFlushingVideo) {                  return;              } @@ -157,6 +162,10 @@ void NuPlayer::Renderer::signalDisableOffloadAudio() {      (new AMessage(kWhatDisableOffloadAudio, id()))->post();  } +void NuPlayer::Renderer::signalEnableOffloadAudio() { +    (new AMessage(kWhatEnableOffloadAudio, id()))->post(); +} +  void NuPlayer::Renderer::pause() {      (new AMessage(kWhatPause, id()))->post();  } @@ -171,11 +180,48 @@ void NuPlayer::Renderer::setVideoFrameRate(float fps) {      msg->post();  } +// Called on any threads, except renderer's thread.  status_t NuPlayer::Renderer::getCurrentPosition(int64_t *mediaUs) { -    return getCurrentPosition(mediaUs, ALooper::GetNowUs()); +    { +        Mutex::Autolock autoLock(mLock); +        int64_t currentPositionUs; +        if (getCurrentPositionIfPaused_l(¤tPositionUs)) { +            *mediaUs = currentPositionUs; +            return OK; +        } +    } +    return getCurrentPositionFromAnchor(mediaUs, ALooper::GetNowUs()); +} + +// Called on only renderer's thread. +status_t NuPlayer::Renderer::getCurrentPositionOnLooper(int64_t *mediaUs) { +    return getCurrentPositionOnLooper(mediaUs, ALooper::GetNowUs());  } -status_t NuPlayer::Renderer::getCurrentPosition( +// Called on only renderer's thread. +// Since mPaused and mPausePositionMediaTimeUs are changed only on renderer's +// thread, no need to acquire mLock. +status_t NuPlayer::Renderer::getCurrentPositionOnLooper( +        int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo) { +    int64_t currentPositionUs; +    if (getCurrentPositionIfPaused_l(¤tPositionUs)) { +        *mediaUs = currentPositionUs; +        return OK; +    } +    return getCurrentPositionFromAnchor(mediaUs, nowUs, allowPastQueuedVideo); +} + +// Called either with mLock acquired or on renderer's thread. +bool NuPlayer::Renderer::getCurrentPositionIfPaused_l(int64_t *mediaUs) { +    if (!mPaused || mPausePositionMediaTimeUs < 0ll) { +        return false; +    } +    *mediaUs = mPausePositionMediaTimeUs; +    return true; +} + +// Called on any threads. +status_t NuPlayer::Renderer::getCurrentPositionFromAnchor(          int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo) {      Mutex::Autolock autoLock(mTimeLock);      if (!mHasAudio && !mHasVideo) { @@ -255,11 +301,12 @@ void NuPlayer::Renderer::setPauseStartedTimeRealUs(int64_t realUs) {      mPauseStartedTimeRealUs = realUs;  } -bool NuPlayer::Renderer::openAudioSink( +status_t NuPlayer::Renderer::openAudioSink(          const sp<AMessage> &format,          bool offloadOnly,          bool hasVideo, -        uint32_t flags) { +        uint32_t flags, +        bool *isOffloaded) {      sp<AMessage> msg = new AMessage(kWhatOpenAudioSink, id());      msg->setMessage("format", format);      msg->setInt32("offload-only", offloadOnly); @@ -269,9 +316,15 @@ bool NuPlayer::Renderer::openAudioSink(      sp<AMessage> response;      msg->postAndAwaitResponse(&response); -    int32_t offload; -    CHECK(response->findInt32("offload", &offload)); -    return (offload != 0); +    int32_t err; +    if (!response->findInt32("err", &err)) { +        err = INVALID_OPERATION; +    } else if (err == OK && isOffloaded != NULL) { +        int32_t offload; +        CHECK(response->findInt32("offload", &offload)); +        *isOffloaded = (offload != 0); +    } +    return err;  }  void NuPlayer::Renderer::closeAudioSink() { @@ -297,10 +350,11 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {              uint32_t flags;              CHECK(msg->findInt32("flags", (int32_t *)&flags)); -            bool offload = onOpenAudioSink(format, offloadOnly, hasVideo, flags); +            status_t err = onOpenAudioSink(format, offloadOnly, hasVideo, flags);              sp<AMessage> response = new AMessage; -            response->setInt32("offload", offload); +            response->setInt32("err", err); +            response->setInt32("offload", offloadingAudio());              uint32_t replyID;              CHECK(msg->senderAwaitsResponse(&replyID)); @@ -373,7 +427,8 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {              onDrainVideoQueue(); -            postDrainVideoQueue(); +            Mutex::Autolock autoLock(mLock); +            postDrainVideoQueue_l();              break;          } @@ -386,7 +441,8 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {              }              mDrainVideoQueuePending = false; -            postDrainVideoQueue(); +            Mutex::Autolock autoLock(mLock); +            postDrainVideoQueue_l();              break;          } @@ -420,6 +476,12 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {              break;          } +        case kWhatEnableOffloadAudio: +        { +            onEnableOffloadAudio(); +            break; +        } +          case kWhatPause:          {              onPause(); @@ -455,6 +517,7 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {              }              ALOGV("Audio Offload tear down due to pause timeout.");              onAudioOffloadTearDown(kDueToTimeout); +            mWakeLock->release();              break;          } @@ -629,6 +692,13 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {              mAudioQueue.erase(mAudioQueue.begin());              entry = NULL; +            if (mAudioSink->needsTrailingPadding()) { +                // If we're not in gapless playback (i.e. through setNextPlayer), we +                // need to stop the track here, because that will play out the last +                // little bit at the end of the file. Otherwise short files won't play. +                mAudioSink->stop(); +                mNumFramesWritten = 0; +            }              return false;          } @@ -646,8 +716,9 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {          ssize_t written = mAudioSink->write(entry->mBuffer->data() + entry->mOffset, copy);          if (written < 0) { -            // An error in AudioSink write is fatal here. -            LOG_ALWAYS_FATAL("AudioSink write error(%zd) when writing %zu bytes", written, copy); +            // An error in AudioSink write. Perhaps the AudioSink was not properly opened. +            ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy); +            break;          }          entry->mOffset += written; @@ -701,7 +772,8 @@ int64_t NuPlayer::Renderer::getPendingAudioPlayoutDurationUs(int64_t nowUs) {  int64_t NuPlayer::Renderer::getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs) {      int64_t currentPositionUs; -    if (getCurrentPosition(¤tPositionUs, nowUs, true /* allowPastQueuedVideo */) != OK) { +    if (mPaused || getCurrentPositionOnLooper( +            ¤tPositionUs, nowUs, true /* allowPastQueuedVideo */) != OK) {          // If failed to get current position, e.g. due to audio clock is not ready, then just          // play out video immediately without delay.          return nowUs; @@ -721,7 +793,7 @@ void NuPlayer::Renderer::onNewAudioMediaTime(int64_t mediaTimeUs) {              mediaTimeUs, nowUs + getPendingAudioPlayoutDurationUs(nowUs), mNumFramesWritten);  } -void NuPlayer::Renderer::postDrainVideoQueue() { +void NuPlayer::Renderer::postDrainVideoQueue_l() {      if (mDrainVideoQueuePending              || mSyncQueues              || (mPaused && mVideoSampleReceived)) { @@ -757,6 +829,8 @@ void NuPlayer::Renderer::postDrainVideoQueue() {          if (mAnchorTimeMediaUs < 0) {              setAnchorTime(mediaTimeUs, nowUs); +            mPausePositionMediaTimeUs = mediaTimeUs; +            mAnchorMaxMediaUs = mediaTimeUs;              realTimeUs = nowUs;          } else {              realTimeUs = getRealTimeUs(mediaTimeUs, nowUs); @@ -792,11 +866,6 @@ void NuPlayer::Renderer::postDrainVideoQueue() {      ALOGW_IF(delayUs > 500000, "unusually high delayUs: %" PRId64, delayUs);      // post 2 display refreshes before rendering is due -    // FIXME currently this increases power consumption, so unless frame-accurate -    // AV sync is requested, post closer to required render time (at 0.63 vsyncs) -    if (!sFrameAccurateAVsync) { -        twoVsyncsUs >>= 4; -    }      msg->post(delayUs > twoVsyncsUs ? delayUs - twoVsyncsUs : 0);      mDrainVideoQueuePending = true; @@ -924,16 +993,15 @@ void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) {      entry.mFinalResult = OK;      entry.mBufferOrdinal = ++mTotalBuffersQueued; +    Mutex::Autolock autoLock(mLock);      if (audio) { -        Mutex::Autolock autoLock(mLock);          mAudioQueue.push_back(entry);          postDrainAudioQueue_l();      } else {          mVideoQueue.push_back(entry); -        postDrainVideoQueue(); +        postDrainVideoQueue_l();      } -    Mutex::Autolock autoLock(mLock);      if (!mSyncQueues || mAudioQueue.empty() || mVideoQueue.empty()) {          return;      } @@ -982,7 +1050,7 @@ void NuPlayer::Renderer::syncQueuesDone_l() {      }      if (!mVideoQueue.empty()) { -        postDrainVideoQueue(); +        postDrainVideoQueue_l();      }  } @@ -1001,8 +1069,8 @@ void NuPlayer::Renderer::onQueueEOS(const sp<AMessage> &msg) {      entry.mOffset = 0;      entry.mFinalResult = finalResult; +    Mutex::Autolock autoLock(mLock);      if (audio) { -        Mutex::Autolock autoLock(mLock);          if (mAudioQueue.empty() && mSyncQueues) {              syncQueuesDone_l();          } @@ -1010,24 +1078,27 @@ void NuPlayer::Renderer::onQueueEOS(const sp<AMessage> &msg) {          postDrainAudioQueue_l();      } else {          if (mVideoQueue.empty() && mSyncQueues) { -            Mutex::Autolock autoLock(mLock);              syncQueuesDone_l();          }          mVideoQueue.push_back(entry); -        postDrainVideoQueue(); +        postDrainVideoQueue_l();      }  }  void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) { -    int32_t audio; +    int32_t audio, notifyComplete;      CHECK(msg->findInt32("audio", &audio));      {          Mutex::Autolock autoLock(mFlushLock);          if (audio) {              mFlushingAudio = false; +            notifyComplete = mNotifyCompleteAudio; +            mNotifyCompleteAudio = false;          } else {              mFlushingVideo = false; +            notifyComplete = mNotifyCompleteVideo; +            mNotifyCompleteVideo = false;          }      } @@ -1043,6 +1114,7 @@ void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) {           Mutex::Autolock autoLock(mLock);           syncQueuesDone_l();           setPauseStartedTimeRealUs(-1); +         setAnchorTime(-1, -1);      }      ALOGV("flushing %s", audio ? "audio" : "video"); @@ -1080,7 +1152,10 @@ void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) {      }      mVideoSampleReceived = false; -    notifyFlushComplete(audio); + +    if (notifyComplete) { +        notifyFlushComplete(audio); +    }  }  void NuPlayer::Renderer::flushQueue(List<QueueEntry> *queue) { @@ -1147,13 +1222,32 @@ void NuPlayer::Renderer::onDisableOffloadAudio() {      ++mAudioQueueGeneration;  } +void NuPlayer::Renderer::onEnableOffloadAudio() { +    Mutex::Autolock autoLock(mLock); +    mFlags |= FLAG_OFFLOAD_AUDIO; +    ++mAudioQueueGeneration; +} +  void NuPlayer::Renderer::onPause() {      if (mPaused) {          ALOGW("Renderer::onPause() called while already paused!");          return;      } +    int64_t currentPositionUs; +    int64_t pausePositionMediaTimeUs; +    if (getCurrentPositionFromAnchor( +            ¤tPositionUs, ALooper::GetNowUs()) == OK) { +        pausePositionMediaTimeUs = currentPositionUs; +    } else { +        // Set paused position to -1 (unavailabe) if we don't have anchor time +        // This could happen if client does a seekTo() immediately followed by +        // pause(). Renderer will be flushed with anchor time cleared. We don't +        // want to leave stale value in mPausePositionMediaTimeUs. +        pausePositionMediaTimeUs = -1; +    }      {          Mutex::Autolock autoLock(mLock); +        mPausePositionMediaTimeUs = pausePositionMediaTimeUs;          ++mAudioQueueGeneration;          ++mVideoQueueGeneration;          prepareForMediaRenderingStart(); @@ -1174,8 +1268,6 @@ void NuPlayer::Renderer::onPause() {  }  void NuPlayer::Renderer::onResume() { -    readProperties(); -      if (!mPaused) {          return;      } @@ -1199,7 +1291,7 @@ void NuPlayer::Renderer::onResume() {      }      if (!mVideoQueue.empty()) { -        postDrainVideoQueue(); +        postDrainVideoQueue_l();      }  } @@ -1281,7 +1373,7 @@ void NuPlayer::Renderer::onAudioOffloadTearDown(AudioOffloadTearDownReason reaso      mAudioOffloadTornDown = true;      int64_t currentPositionUs; -    if (getCurrentPosition(¤tPositionUs) != OK) { +    if (getCurrentPositionOnLooper(¤tPositionUs) != OK) {          currentPositionUs = 0;      } @@ -1297,6 +1389,7 @@ void NuPlayer::Renderer::onAudioOffloadTearDown(AudioOffloadTearDownReason reaso  void NuPlayer::Renderer::startAudioOffloadPauseTimeout() {      if (offloadingAudio()) { +        mWakeLock->acquire();          sp<AMessage> msg = new AMessage(kWhatAudioOffloadPauseTimeout, id());          msg->setInt32("generation", mAudioOffloadPauseTimeoutGeneration);          msg->post(kOffloadPauseMaxUs); @@ -1305,11 +1398,12 @@ void NuPlayer::Renderer::startAudioOffloadPauseTimeout() {  void NuPlayer::Renderer::cancelAudioOffloadPauseTimeout() {      if (offloadingAudio()) { +        mWakeLock->release(true);          ++mAudioOffloadPauseTimeoutGeneration;      }  } -bool NuPlayer::Renderer::onOpenAudioSink( +status_t NuPlayer::Renderer::onOpenAudioSink(          const sp<AMessage> &format,          bool offloadOnly,          bool hasVideo, @@ -1371,11 +1465,14 @@ bool NuPlayer::Renderer::onOpenAudioSink(              if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) {                  ALOGV("openAudioSink: no change in offload mode");                  // no change from previous configuration, everything ok. -                return offloadingAudio(); +                return OK;              } +            mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER; +              ALOGV("openAudioSink: try to open AudioSink in offload mode"); -            flags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; -            flags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER; +            uint32_t offloadFlags = flags; +            offloadFlags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; +            offloadFlags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER;              audioSinkChanged = true;              mAudioSink->close();              err = mAudioSink->open( @@ -1386,7 +1483,7 @@ bool NuPlayer::Renderer::onOpenAudioSink(                      8 /* bufferCount */,                      &NuPlayer::Renderer::AudioSinkCallback,                      this, -                    (audio_output_flags_t)flags, +                    (audio_output_flags_t)offloadFlags,                      &offloadInfo);              if (err == OK) { @@ -1410,13 +1507,27 @@ bool NuPlayer::Renderer::onOpenAudioSink(          }      }      if (!offloadOnly && !offloadingAudio()) { -        flags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;          ALOGV("openAudioSink: open AudioSink in NON-offload mode"); +        uint32_t pcmFlags = flags; +        pcmFlags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; + +        const PcmInfo info = { +                (audio_channel_mask_t)channelMask, +                (audio_output_flags_t)pcmFlags, +                AUDIO_FORMAT_PCM_16_BIT, // TODO: change to audioFormat +                numChannels, +                sampleRate +        }; +        if (memcmp(&mCurrentPcmInfo, &info, sizeof(info)) == 0) { +            ALOGV("openAudioSink: no change in pcm mode"); +            // no change from previous configuration, everything ok. +            return OK; +        }          audioSinkChanged = true;          mAudioSink->close();          mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER; -        CHECK_EQ(mAudioSink->open( +        status_t err = mAudioSink->open(                      sampleRate,                      numChannels,                      (audio_channel_mask_t)channelMask, @@ -1424,20 +1535,28 @@ bool NuPlayer::Renderer::onOpenAudioSink(                      8 /* bufferCount */,                      NULL,                      NULL, -                    (audio_output_flags_t)flags), -                 (status_t)OK); +                    (audio_output_flags_t)pcmFlags); +        if (err != OK) { +            ALOGW("openAudioSink: non offloaded open failed status: %d", err); +            mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER; +            return err; +        } +        mCurrentPcmInfo = info;          mAudioSink->start();      }      if (audioSinkChanged) {          onAudioSinkChanged();      } - -    return offloadingAudio(); +    if (offloadingAudio()) { +        mAudioOffloadTornDown = false; +    } +    return OK;  }  void NuPlayer::Renderer::onCloseAudioSink() {      mAudioSink->close();      mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER; +    mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;  }  }  // namespace android diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h index 7b46a59..003d1d0 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h @@ -23,6 +23,7 @@  namespace android {  struct ABuffer; +class  AWakeLock;  struct VideoFrameScheduler;  struct NuPlayer::Renderer : public AHandler { @@ -46,13 +47,14 @@ struct NuPlayer::Renderer : public AHandler {      void queueEOS(bool audio, status_t finalResult); -    void flush(bool audio); +    void flush(bool audio, bool notifyComplete);      void signalTimeDiscontinuity();      void signalAudioSinkChanged();      void signalDisableOffloadAudio(); +    void signalEnableOffloadAudio();      void pause();      void resume(); @@ -61,8 +63,6 @@ struct NuPlayer::Renderer : public AHandler {      // Following setters and getters are protected by mTimeLock.      status_t getCurrentPosition(int64_t *mediaUs); -    status_t getCurrentPosition( -            int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false);      void setHasMedia(bool audio);      void setAudioFirstAnchorTime(int64_t mediaUs);      void setAudioFirstAnchorTimeIfNeeded(int64_t mediaUs); @@ -72,11 +72,12 @@ struct NuPlayer::Renderer : public AHandler {      int64_t getVideoLateByUs();      void setPauseStartedTimeRealUs(int64_t realUs); -    bool openAudioSink( +    status_t openAudioSink(              const sp<AMessage> &format,              bool offloadOnly,              bool hasVideo, -            uint32_t flags); +            uint32_t flags, +            bool *isOffloaded);      void closeAudioSink();      enum { @@ -114,6 +115,7 @@ private:          kWhatCloseAudioSink      = 'clsA',          kWhatStopAudioSink       = 'stpA',          kWhatDisableOffloadAudio = 'noOA', +        kWhatEnableOffloadAudio  = 'enOA',          kWhatSetVideoFrameRate   = 'sVFR',      }; @@ -160,10 +162,15 @@ private:      Mutex mFlushLock;  // protects the following 2 member vars.      bool mFlushingAudio;      bool mFlushingVideo; +    bool mNotifyCompleteAudio; +    bool mNotifyCompleteVideo;      bool mSyncQueues; +    // modified on only renderer's thread.      bool mPaused; +    int64_t mPausePositionMediaTimeUs; +      bool mVideoSampleReceived;      bool mVideoRenderingStarted;      int32_t mVideoRenderingStartGeneration; @@ -175,9 +182,27 @@ private:      bool mAudioOffloadTornDown;      audio_offload_info_t mCurrentOffloadInfo; +    struct PcmInfo { +        audio_channel_mask_t mChannelMask; +        audio_output_flags_t mFlags; +        audio_format_t mFormat; +        int32_t mNumChannels; +        int32_t mSampleRate; +    }; +    PcmInfo mCurrentPcmInfo; +    static const PcmInfo AUDIO_PCMINFO_INITIALIZER; +      int32_t mTotalBuffersQueued;      int32_t mLastAudioBufferDrained; +    sp<AWakeLock> mWakeLock; + +    status_t getCurrentPositionOnLooper(int64_t *mediaUs); +    status_t getCurrentPositionOnLooper( +            int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false); +    bool getCurrentPositionIfPaused_l(int64_t *mediaUs); +    status_t getCurrentPositionFromAnchor( +            int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false);      size_t fillAudioBuffer(void *buffer, size_t size); @@ -190,7 +215,7 @@ private:      int64_t getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs);      void onDrainVideoQueue(); -    void postDrainVideoQueue(); +    void postDrainVideoQueue_l();      void prepareForMediaRenderingStart();      void notifyIfMediaRenderingStarted(); @@ -200,11 +225,12 @@ private:      void onFlush(const sp<AMessage> &msg);      void onAudioSinkChanged();      void onDisableOffloadAudio(); +    void onEnableOffloadAudio();      void onPause();      void onResume();      void onSetVideoFrameRate(float fps);      void onAudioOffloadTearDown(AudioOffloadTearDownReason reason); -    bool onOpenAudioSink( +    status_t onOpenAudioSink(              const sp<AMessage> &format,              bool offloadOnly,              bool hasVideo, diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h index 2f06c31..6daad1b 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h @@ -39,6 +39,7 @@ struct NuPlayer::Source : public AHandler {          FLAG_CAN_SEEK           = 8,  // the "seek bar"          FLAG_DYNAMIC_DURATION   = 16,          FLAG_SECURE             = 32, +        FLAG_PROTECTED          = 64,      };      enum { @@ -48,10 +49,14 @@ struct NuPlayer::Source : public AHandler {          kWhatBufferingUpdate,          kWhatBufferingStart,          kWhatBufferingEnd, +        kWhatPauseOnBufferingStart, +        kWhatResumeOnBufferingEnd, +        kWhatCacheStats,          kWhatSubtitleData,          kWhatTimedTextData,          kWhatQueueDecoderShutdown,          kWhatDrmNoLicense, +        kWhatInstantiateSecureDecoders,      };      // The provides message is used to notify the player about various @@ -97,7 +102,7 @@ struct NuPlayer::Source : public AHandler {          return INVALID_OPERATION;      } -    virtual status_t selectTrack(size_t /* trackIndex */, bool /* select */) { +    virtual status_t selectTrack(size_t /* trackIndex */, bool /* select */, int64_t /* timeUs*/) {          return INVALID_OPERATION;      } @@ -122,6 +127,7 @@ protected:      void notifyFlagsChanged(uint32_t flags);      void notifyVideoSizeChanged(const sp<AMessage> &format = NULL); +    void notifyInstantiateSecureDecoders(const sp<AMessage> &reply);      void notifyPrepared(status_t err = OK);  private: diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp index ffacb8f..0282a9f 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp @@ -50,7 +50,7 @@ NuPlayer::RTSPSource::RTSPSource(        mState(DISCONNECTED),        mFinalResult(OK),        mDisconnectReplyID(0), -      mBuffering(true), +      mBuffering(false),        mSeekGeneration(0),        mEOSTimeoutAudio(0),        mEOSTimeoutVideo(0) { @@ -106,9 +106,7 @@ void NuPlayer::RTSPSource::prepareAsync() {          mHandler->connect();      } -    sp<AMessage> notifyStart = dupNotify(); -    notifyStart->setInt32("what", kWhatBufferingStart); -    notifyStart->post(); +    startBufferingIfNecessary();  }  void NuPlayer::RTSPSource::start() { @@ -144,6 +142,7 @@ void NuPlayer::RTSPSource::resume() {  }  status_t NuPlayer::RTSPSource::feedMoreTSData() { +    Mutex::Autolock _l(mBufferingLock);      return mFinalResult;  } @@ -195,16 +194,8 @@ bool NuPlayer::RTSPSource::haveSufficientDataOnAllTracks() {  status_t NuPlayer::RTSPSource::dequeueAccessUnit(          bool audio, sp<ABuffer> *accessUnit) { -    if (mBuffering) { -        if (!haveSufficientDataOnAllTracks()) { -            return -EWOULDBLOCK; -        } - -        mBuffering = false; - -        sp<AMessage> notify = dupNotify(); -        notify->setInt32("what", kWhatBufferingEnd); -        notify->post(); +    if (!stopBufferingIfNecessary()) { +        return -EWOULDBLOCK;      }      sp<AnotherPacketSource> source = getSource(audio); @@ -246,11 +237,7 @@ status_t NuPlayer::RTSPSource::dequeueAccessUnit(              if (!(otherSource != NULL && otherSource->isFinished(mediaDurationUs))) {                  // We should not enter buffering mode                  // if any of the sources already have detected EOS. -                mBuffering = true; - -                sp<AMessage> notify = dupNotify(); -                notify->setInt32("what", kWhatBufferingStart); -                notify->post(); +                startBufferingIfNecessary();              }              return -EWOULDBLOCK; @@ -506,7 +493,7 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {              sp<AnotherPacketSource> source = info->mSource;              if (source != NULL) {                  source->queueDiscontinuity( -                        ATSParser::DISCONTINUITY_SEEK, +                        ATSParser::DISCONTINUITY_TIME,                          NULL,                          true /* discard */);              } @@ -630,7 +617,7 @@ void NuPlayer::RTSPSource::onSDPLoaded(const sp<AMessage> &msg) {          }          mState = DISCONNECTED; -        mFinalResult = err; +        setError(err);          if (mDisconnectReplyID != 0) {              finishDisconnectIfPossible(); @@ -657,7 +644,7 @@ void NuPlayer::RTSPSource::onDisconnected(const sp<AMessage> &msg) {      }      mState = DISCONNECTED; -    mFinalResult = err; +    setError(err);      if (mDisconnectReplyID != 0) {          finishDisconnectIfPossible(); @@ -678,4 +665,40 @@ void NuPlayer::RTSPSource::finishDisconnectIfPossible() {      mDisconnectReplyID = 0;  } +void NuPlayer::RTSPSource::setError(status_t err) { +    Mutex::Autolock _l(mBufferingLock); +    mFinalResult = err; +} + +void NuPlayer::RTSPSource::startBufferingIfNecessary() { +    Mutex::Autolock _l(mBufferingLock); + +    if (!mBuffering) { +        mBuffering = true; + +        sp<AMessage> notify = dupNotify(); +        notify->setInt32("what", kWhatBufferingStart); +        notify->post(); +    } +} + +bool NuPlayer::RTSPSource::stopBufferingIfNecessary() { +    Mutex::Autolock _l(mBufferingLock); + +    if (mBuffering) { +        if (!haveSufficientDataOnAllTracks()) { +            return false; +        } + +        mBuffering = false; + +        sp<AMessage> notify = dupNotify(); +        notify->setInt32("what", kWhatBufferingEnd); +        notify->post(); +    } + +    return true; +} + +  }  // namespace android diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h index f1cae53..ac3299a 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.h +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h @@ -97,6 +97,7 @@ private:      State mState;      status_t mFinalResult;      uint32_t mDisconnectReplyID; +    Mutex mBufferingLock;      bool mBuffering;      sp<ALooper> mLooper; @@ -126,6 +127,9 @@ private:      bool haveSufficientDataOnAllTracks();      void setEOSTimeout(bool audio, int64_t timeout); +    void setError(status_t err); +    void startBufferingIfNecessary(); +    bool stopBufferingIfNecessary();      DISALLOW_EVIL_CONSTRUCTORS(RTSPSource);  }; diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp index 2e9a29a..b3f224d 100644 --- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp +++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp @@ -37,13 +37,26 @@ NuPlayer::StreamingSource::StreamingSource(          const sp<IStreamSource> &source)      : Source(notify),        mSource(source), -      mFinalResult(OK) { +      mFinalResult(OK), +      mBuffering(false) {  }  NuPlayer::StreamingSource::~StreamingSource() { +    if (mLooper != NULL) { +        mLooper->unregisterHandler(id()); +        mLooper->stop(); +    }  }  void NuPlayer::StreamingSource::prepareAsync() { +    if (mLooper == NULL) { +        mLooper = new ALooper; +        mLooper->setName("streaming"); +        mLooper->start(); + +        mLooper->registerHandler(this); +    } +      notifyVideoSizeChanged();      notifyFlagsChanged(0);      notifyPrepared(); @@ -62,13 +75,15 @@ void NuPlayer::StreamingSource::start() {      mTSParser = new ATSParser(parserFlags);      mStreamListener->start(); + +    postReadBuffer();  }  status_t NuPlayer::StreamingSource::feedMoreTSData() { -    if (mFinalResult != OK) { -        return mFinalResult; -    } +    return postReadBuffer(); +} +void NuPlayer::StreamingSource::onReadBuffer() {      for (int32_t i = 0; i < 50; ++i) {          char buffer[188];          sp<AMessage> extra; @@ -77,10 +92,10 @@ status_t NuPlayer::StreamingSource::feedMoreTSData() {          if (n == 0) {              ALOGI("input data EOS reached.");              mTSParser->signalEOS(ERROR_END_OF_STREAM); -            mFinalResult = ERROR_END_OF_STREAM; +            setError(ERROR_END_OF_STREAM);              break;          } else if (n == INFO_DISCONTINUITY) { -            int32_t type = ATSParser::DISCONTINUITY_SEEK; +            int32_t type = ATSParser::DISCONTINUITY_TIME;              int32_t mask;              if (extra != NULL @@ -88,7 +103,8 @@ status_t NuPlayer::StreamingSource::feedMoreTSData() {                          IStreamListener::kKeyDiscontinuityMask, &mask)) {                  if (mask == 0) {                      ALOGE("Client specified an illegal discontinuity type."); -                    return ERROR_UNSUPPORTED; +                    setError(ERROR_UNSUPPORTED); +                    break;                  }                  type = mask; @@ -97,7 +113,6 @@ status_t NuPlayer::StreamingSource::feedMoreTSData() {              mTSParser->signalDiscontinuity(                      (ATSParser::DiscontinuityType)type, extra);          } else if (n < 0) { -            CHECK_EQ(n, -EWOULDBLOCK);              break;          } else {              if (buffer[0] == 0x00) { @@ -118,7 +133,7 @@ status_t NuPlayer::StreamingSource::feedMoreTSData() {                  mTSParser->signalDiscontinuity(                          ((type & 1) == 0) -                            ? ATSParser::DISCONTINUITY_SEEK +                            ? ATSParser::DISCONTINUITY_TIME                              : ATSParser::DISCONTINUITY_FORMATCHANGE,                          extra);              } else { @@ -128,22 +143,80 @@ status_t NuPlayer::StreamingSource::feedMoreTSData() {                      ALOGE("TS Parser returned error %d", err);                      mTSParser->signalEOS(err); -                    mFinalResult = err; +                    setError(err);                      break;                  }              }          }      } +} + +status_t NuPlayer::StreamingSource::postReadBuffer() { +    { +        Mutex::Autolock _l(mBufferingLock); +        if (mFinalResult != OK) { +            return mFinalResult; +        } +        if (mBuffering) { +            return OK; +        } +        mBuffering = true; +    } +    (new AMessage(kWhatReadBuffer, id()))->post();      return OK;  } -sp<MetaData> NuPlayer::StreamingSource::getFormatMeta(bool audio) { -    ATSParser::SourceType type = -        audio ? ATSParser::AUDIO : ATSParser::VIDEO; +bool NuPlayer::StreamingSource::haveSufficientDataOnAllTracks() { +    // We're going to buffer at least 2 secs worth data on all tracks before +    // starting playback (both at startup and after a seek). -    sp<AnotherPacketSource> source = -        static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get()); +    static const int64_t kMinDurationUs = 2000000ll; + +    sp<AnotherPacketSource> audioTrack = getSource(true /*audio*/); +    sp<AnotherPacketSource> videoTrack = getSource(false /*audio*/); + +    status_t err; +    int64_t durationUs; +    if (audioTrack != NULL +            && (durationUs = audioTrack->getBufferedDurationUs(&err)) +                    < kMinDurationUs +            && err == OK) { +        ALOGV("audio track doesn't have enough data yet. (%.2f secs buffered)", +              durationUs / 1E6); +        return false; +    } + +    if (videoTrack != NULL +            && (durationUs = videoTrack->getBufferedDurationUs(&err)) +                    < kMinDurationUs +            && err == OK) { +        ALOGV("video track doesn't have enough data yet. (%.2f secs buffered)", +              durationUs / 1E6); +        return false; +    } + +    return true; +} + +void NuPlayer::StreamingSource::setError(status_t err) { +    Mutex::Autolock _l(mBufferingLock); +    mFinalResult = err; +} + +sp<AnotherPacketSource> NuPlayer::StreamingSource::getSource(bool audio) { +    if (mTSParser == NULL) { +        return NULL; +    } + +    sp<MediaSource> source = mTSParser->getSource( +            audio ? ATSParser::AUDIO : ATSParser::VIDEO); + +    return static_cast<AnotherPacketSource *>(source.get()); +} + +sp<MetaData> NuPlayer::StreamingSource::getFormatMeta(bool audio) { +    sp<AnotherPacketSource> source = getSource(audio);      if (source == NULL) {          return NULL; @@ -154,16 +227,16 @@ sp<MetaData> NuPlayer::StreamingSource::getFormatMeta(bool audio) {  status_t NuPlayer::StreamingSource::dequeueAccessUnit(          bool audio, sp<ABuffer> *accessUnit) { -    ATSParser::SourceType type = -        audio ? ATSParser::AUDIO : ATSParser::VIDEO; - -    sp<AnotherPacketSource> source = -        static_cast<AnotherPacketSource *>(mTSParser->getSource(type).get()); +    sp<AnotherPacketSource> source = getSource(audio);      if (source == NULL) {          return -EWOULDBLOCK;      } +    if (!haveSufficientDataOnAllTracks()) { +        postReadBuffer(); +    } +      status_t finalResult;      if (!source->hasBufferAvailable(&finalResult)) {          return finalResult == OK ? -EWOULDBLOCK : finalResult; @@ -186,5 +259,26 @@ bool NuPlayer::StreamingSource::isRealTime() const {      return mSource->flags() & IStreamSource::kFlagIsRealTimeData;  } +void NuPlayer::StreamingSource::onMessageReceived( +        const sp<AMessage> &msg) { +    switch (msg->what()) { +        case kWhatReadBuffer: +        { +            onReadBuffer(); + +            { +                Mutex::Autolock _l(mBufferingLock); +                mBuffering = false; +            } +            break; +        } +        default: +        { +            TRESPASS(); +        } +    } +} + +  }  // namespace android diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.h b/media/libmediaplayerservice/nuplayer/StreamingSource.h index 412b6c4..1f95f3c 100644 --- a/media/libmediaplayerservice/nuplayer/StreamingSource.h +++ b/media/libmediaplayerservice/nuplayer/StreamingSource.h @@ -25,6 +25,7 @@ namespace android {  struct ABuffer;  struct ATSParser; +struct AnotherPacketSource;  struct NuPlayer::StreamingSource : public NuPlayer::Source {      StreamingSource( @@ -43,14 +44,29 @@ struct NuPlayer::StreamingSource : public NuPlayer::Source {  protected:      virtual ~StreamingSource(); +    virtual void onMessageReceived(const sp<AMessage> &msg); +      virtual sp<MetaData> getFormatMeta(bool audio);  private: +    enum { +        kWhatReadBuffer, +    };      sp<IStreamSource> mSource;      status_t mFinalResult;      sp<NuPlayerStreamListener> mStreamListener;      sp<ATSParser> mTSParser; +    bool mBuffering; +    Mutex mBufferingLock; +    sp<ALooper> mLooper; + +    void setError(status_t err); +    sp<AnotherPacketSource> getSource(bool audio); +    bool haveSufficientDataOnAllTracks(); +    status_t postReadBuffer(); +    void onReadBuffer(); +      DISALLOW_EVIL_CONSTRUCTORS(StreamingSource);  }; diff --git a/media/libstagefright/AACWriter.cpp b/media/libstagefright/AACWriter.cpp index 353920e..7cc9430 100644 --- a/media/libstagefright/AACWriter.cpp +++ b/media/libstagefright/AACWriter.cpp @@ -61,7 +61,8 @@ AACWriter::AACWriter(int fd)        mPaused(false),        mResumed(false),        mChannelCount(-1), -      mSampleRate(-1) { +      mSampleRate(-1), +      mAACProfile(OMX_AUDIO_AACObjectLC) {  }  AACWriter::~AACWriter() { diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 2e16552..85e98f1 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -672,8 +672,9 @@ status_t ACodec::configureOutputBuffersFromNativeWindow(          // XXX: Currently this error is logged, but not fatal.          usage = 0;      } +    int omxUsage = usage; -    if (mFlags & kFlagIsSecure) { +    if (mFlags & kFlagIsGrallocUsageProtected) {          usage |= GRALLOC_USAGE_PROTECTED;      } @@ -696,6 +697,18 @@ status_t ACodec::configureOutputBuffersFromNativeWindow(          }      } +    int consumerUsage = 0; +    err = mNativeWindow->query( +            mNativeWindow.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS, +            &consumerUsage); +    if (err != 0) { +        ALOGW("failed to get consumer usage bits. ignoring"); +        err = 0; +    } + +    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec) + %#x(Consumer) = %#x", +            omxUsage, usage, consumerUsage, usage | consumerUsage); +    usage |= consumerUsage;      err = native_window_set_usage(              mNativeWindow.get(),              usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP); @@ -1116,6 +1129,8 @@ status_t ACodec::setComponentRole(              "video_decoder.mpeg2", "video_encoder.mpeg2" },          { MEDIA_MIMETYPE_AUDIO_AC3,              "audio_decoder.ac3", "audio_encoder.ac3" }, +        { MEDIA_MIMETYPE_AUDIO_EAC3, +            "audio_decoder.eac3", "audio_encoder.eac3" },      };      static const size_t kNumMimeToRole = @@ -1168,7 +1183,7 @@ status_t ACodec::configureCodec(      }      sp<AMessage> inputFormat = new AMessage(); -    sp<AMessage> outputFormat = new AMessage(); +    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged      mIsEncoder = encoder; @@ -1266,18 +1281,47 @@ status_t ACodec::configureCodec(          }      } +    // NOTE: we only use native window for video decoders      sp<RefBase> obj; -    int32_t haveNativeWindow = msg->findObject("native-window", &obj) && -        obj != NULL; +    bool haveNativeWindow = msg->findObject("native-window", &obj) +            && obj != NULL && video && !encoder;      mStoreMetaDataInOutputBuffers = false;      if (video && !encoder) {          inputFormat->setInt32("adaptive-playback", false); + +        int32_t usageProtected; +        if (msg->findInt32("protected", &usageProtected) && usageProtected) { +            if (!haveNativeWindow) { +                ALOGE("protected output buffers must be sent to an ANativeWindow"); +                return PERMISSION_DENIED; +            } +            mFlags |= kFlagIsGrallocUsageProtected; +            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; +        }      } -    if (!encoder && video && haveNativeWindow) { +    if (haveNativeWindow) {          sp<NativeWindowWrapper> windowWrapper(                  static_cast<NativeWindowWrapper *>(obj.get()));          sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow(); +        // START of temporary support for automatic FRC - THIS WILL BE REMOVED +        int32_t autoFrc; +        if (msg->findInt32("auto-frc", &autoFrc)) { +            bool enabled = autoFrc; +            OMX_CONFIG_BOOLEANTYPE config; +            InitOMXParams(&config); +            config.bEnabled = (OMX_BOOL)enabled; +            status_t temp = mOMX->setConfig( +                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion, +                    &config, sizeof(config)); +            if (temp == OK) { +                outputFormat->setInt32("auto-frc", enabled); +            } else if (enabled) { +                ALOGI("codec does not support requested auto-frc (err %d)", temp); +            } +        } +        // END of temporary support for automatic FRC +          int32_t tunneled;          if (msg->findInt32("feature-tunneled-playback", &tunneled) &&              tunneled != 0) { @@ -1295,11 +1339,36 @@ status_t ACodec::configureCodec(                  return err;              } -            inputFormat->setInt32("adaptive-playback", true); +            int32_t maxWidth = 0, maxHeight = 0; +            if (msg->findInt32("max-width", &maxWidth) && +                    msg->findInt32("max-height", &maxHeight)) { + +                err = mOMX->prepareForAdaptivePlayback( +                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight); +                if (err != OK) { +                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d", +                            mComponentName.c_str(), err); +                    // allow failure +                    err = OK; +                } else { +                    inputFormat->setInt32("max-width", maxWidth); +                    inputFormat->setInt32("max-height", maxHeight); +                    inputFormat->setInt32("adaptive-playback", true); +                } +            }          } else {              ALOGV("Configuring CPU controlled video playback.");              mTunneled = false; +            // Explicity reset the sideband handle of the window for +            // non-tunneled video in case the window was previously used +            // for a tunneled video playback. +            err = native_window_set_sideband_stream(nativeWindow.get(), NULL); +            if (err != OK) { +                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err); +                return err; +            } +              // Always try to enable dynamic output buffers on native surface              err = mOMX->storeMetaDataInBuffers(                      mNode, kPortIndexOutput, OMX_TRUE); @@ -1374,10 +1443,79 @@ status_t ACodec::configureCodec(      }      if (video) { +        // determine need for software renderer +        bool usingSwRenderer = false; +        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) { +            usingSwRenderer = true; +            haveNativeWindow = false; +        } +          if (encoder) {              err = setupVideoEncoder(mime, msg);          } else { -            err = setupVideoDecoder(mime, msg); +            err = setupVideoDecoder(mime, msg, haveNativeWindow); +        } + +        if (err != OK) { +            return err; +        } + +        if (haveNativeWindow) { +            sp<NativeWindowWrapper> nativeWindow( +                    static_cast<NativeWindowWrapper *>(obj.get())); +            CHECK(nativeWindow != NULL); +            mNativeWindow = nativeWindow->getNativeWindow(); + +            native_window_set_scaling_mode( +                    mNativeWindow.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); +        } + +        // initialize native window now to get actual output format +        // TODO: this is needed for some encoders even though they don't use native window +        CHECK_EQ((status_t)OK, initNativeWindow()); + +        // fallback for devices that do not handle flex-YUV for native buffers +        if (haveNativeWindow) { +            int32_t requestedColorFormat = OMX_COLOR_FormatUnused; +            if (msg->findInt32("color-format", &requestedColorFormat) && +                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) { +                CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK); +                int32_t colorFormat = OMX_COLOR_FormatUnused; +                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused; +                CHECK(outputFormat->findInt32("color-format", &colorFormat)); +                ALOGD("[%s] Requested output format %#x and got %#x.", +                        mComponentName.c_str(), requestedColorFormat, colorFormat); +                if (!isFlexibleColorFormat( +                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent) +                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) { +                    // device did not handle flex-YUV request for native window, fall back +                    // to SW renderer +                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str()); +                    mNativeWindow.clear(); +                    haveNativeWindow = false; +                    usingSwRenderer = true; +                    if (mStoreMetaDataInOutputBuffers) { +                        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_FALSE); +                        mStoreMetaDataInOutputBuffers = false; +                        // TODO: implement adaptive-playback support for bytebuffer mode. +                        // This is done by SW codecs, but most HW codecs don't support it. +                        inputFormat->setInt32("adaptive-playback", false); +                    } +                    if (err == OK) { +                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE); +                    } +                    if (mFlags & kFlagIsGrallocUsageProtected) { +                        // fallback is not supported for protected playback +                        err = PERMISSION_DENIED; +                    } else if (err == OK) { +                        err = setupVideoDecoder(mime, msg, false); +                    } +                } +            } +        } + +        if (usingSwRenderer) { +            outputFormat->setInt32("using-sw-renderer", 1);          }      } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {          int32_t numChannels, sampleRate; @@ -1508,6 +1646,15 @@ status_t ACodec::configureCodec(          } else {              err = setupAC3Codec(encoder, numChannels, sampleRate);          } +    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) { +        int32_t numChannels; +        int32_t sampleRate; +        if (!msg->findInt32("channel-count", &numChannels) +                || !msg->findInt32("sample-rate", &sampleRate)) { +            err = INVALID_OPERATION; +        } else { +            err = setupEAC3Codec(encoder, numChannels, sampleRate); +        }      }      if (err != OK) { @@ -1535,6 +1682,8 @@ status_t ACodec::configureCodec(          err = setMinBufferSize(kPortIndexInput, 8192);  // XXX      } +    mBaseOutputFormat = outputFormat; +      CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);      CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);      mInputFormat = inputFormat; @@ -1791,6 +1940,44 @@ status_t ACodec::setupAC3Codec(              sizeof(def));  } +status_t ACodec::setupEAC3Codec( +        bool encoder, int32_t numChannels, int32_t sampleRate) { +    status_t err = setupRawAudioFormat( +            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels); + +    if (err != OK) { +        return err; +    } + +    if (encoder) { +        ALOGW("EAC3 encoding is not supported."); +        return INVALID_OPERATION; +    } + +    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def; +    InitOMXParams(&def); +    def.nPortIndex = kPortIndexInput; + +    err = mOMX->getParameter( +            mNode, +            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, +            &def, +            sizeof(def)); + +    if (err != OK) { +        return err; +    } + +    def.nChannels = numChannels; +    def.nSampleRate = sampleRate; + +    return mOMX->setParameter( +            mNode, +            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, +            &def, +            sizeof(def)); +} +  static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(          bool isAMRWB, int32_t bps) {      if (isAMRWB) { @@ -1971,7 +2158,8 @@ status_t ACodec::configureTunneledVideoPlayback(  status_t ACodec::setVideoPortFormatType(          OMX_U32 portIndex,          OMX_VIDEO_CODINGTYPE compressionFormat, -        OMX_COLOR_FORMATTYPE colorFormat) { +        OMX_COLOR_FORMATTYPE colorFormat, +        bool usingNativeBuffers) {      OMX_VIDEO_PARAM_PORTFORMATTYPE format;      InitOMXParams(&format);      format.nPortIndex = portIndex; @@ -1991,10 +2179,10 @@ status_t ACodec::setVideoPortFormatType(          // substitute back flexible color format to codec supported format          OMX_U32 flexibleEquivalent; -        if (compressionFormat == OMX_VIDEO_CodingUnused && -                isFlexibleColorFormat( -                        mOMX, mNode, format.eColorFormat, &flexibleEquivalent) && -                colorFormat == flexibleEquivalent) { +        if (compressionFormat == OMX_VIDEO_CodingUnused +                && isFlexibleColorFormat( +                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent) +                && colorFormat == flexibleEquivalent) {              ALOGI("[%s] using color format %#x in place of %#x",                      mComponentName.c_str(), format.eColorFormat, colorFormat);              colorFormat = format.eColorFormat; @@ -2038,18 +2226,66 @@ status_t ACodec::setVideoPortFormatType(      return err;  } -status_t ACodec::setSupportedOutputFormat() { -    OMX_VIDEO_PARAM_PORTFORMATTYPE format; +// Set optimal output format. OMX component lists output formats in the order +// of preference, but this got more complicated since the introduction of flexible +// YUV formats. We support a legacy behavior for applications that do not use +// surface output, do not specify an output format, but expect a "usable" standard +// OMX format. SW readable and standard formats must be flex-YUV. +// +// Suggested preference order: +// - optimal format for texture rendering (mediaplayer behavior) +// - optimal SW readable & texture renderable format (flex-YUV support) +// - optimal SW readable non-renderable format (flex-YUV bytebuffer support) +// - legacy "usable" standard formats +// +// For legacy support, we prefer a standard format, but will settle for a SW readable +// flex-YUV format. +status_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) { +    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;      InitOMXParams(&format);      format.nPortIndex = kPortIndexOutput; -    format.nIndex = 0; -    status_t err = mOMX->getParameter( -            mNode, OMX_IndexParamVideoPortFormat, -            &format, sizeof(format)); -    CHECK_EQ(err, (status_t)OK); -    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused); +    InitOMXParams(&legacyFormat); +    // this field will change when we find a suitable legacy format +    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused; +    for (OMX_U32 index = 0; ; ++index) { +        format.nIndex = index; +        status_t err = mOMX->getParameter( +                mNode, OMX_IndexParamVideoPortFormat, +                &format, sizeof(format)); +        if (err != OK) { +            // no more formats, pick legacy format if found +            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) { +                 memcpy(&format, &legacyFormat, sizeof(format)); +                 break; +            } +            return err; +        } +        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) { +            return OMX_ErrorBadParameter; +        } +        if (!getLegacyFlexibleFormat) { +            break; +        } +        // standard formats that were exposed to users before +        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar +                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar +                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar +                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar +                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) { +            break; +        } +        // find best legacy non-standard format +        OMX_U32 flexibleEquivalent; +        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused +                && isFlexibleColorFormat( +                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */, +                        &flexibleEquivalent) +                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) { +            memcpy(&legacyFormat, &format, sizeof(format)); +        } +    }      return mOMX->setParameter(              mNode, OMX_IndexParamVideoPortFormat,              &format, sizeof(format)); @@ -2101,7 +2337,7 @@ static status_t GetMimeTypeForVideoCoding(  }  status_t ACodec::setupVideoDecoder( -        const char *mime, const sp<AMessage> &msg) { +        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {      int32_t width, height;      if (!msg->findInt32("width", &width)              || !msg->findInt32("height", &height)) { @@ -2127,22 +2363,31 @@ status_t ACodec::setupVideoDecoder(          OMX_COLOR_FORMATTYPE colorFormat =              static_cast<OMX_COLOR_FORMATTYPE>(tmp);          err = setVideoPortFormatType( -                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat); +                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);          if (err != OK) {              ALOGW("[%s] does not support color format %d",                    mComponentName.c_str(), colorFormat); -            err = setSupportedOutputFormat(); +            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);          }      } else { -        err = setSupportedOutputFormat(); +        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);      }      if (err != OK) {          return err;      } +    int32_t frameRateInt; +    float frameRateFloat; +    if (!msg->findFloat("frame-rate", &frameRateFloat)) { +        if (!msg->findInt32("frame-rate", &frameRateInt)) { +            frameRateInt = -1; +        } +        frameRateFloat = (float)frameRateInt; +    } +      err = setVideoFormatOnPort( -            kPortIndexInput, width, height, compressionFormat); +            kPortIndexInput, width, height, compressionFormat, frameRateFloat);      if (err != OK) {          return err; @@ -2231,7 +2476,11 @@ status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {      video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);      video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; -    video_def->eColorFormat = colorFormat; +    // this is redundant as it was already set up in setVideoPortFormatType +    // FIXME for now skip this only for flexible YUV formats +    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) { +        video_def->eColorFormat = colorFormat; +    }      err = mOMX->setParameter(              mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); @@ -2902,7 +3151,8 @@ status_t ACodec::setupErrorCorrectionParameters() {  status_t ACodec::setVideoFormatOnPort(          OMX_U32 portIndex, -        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) { +        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat, +        float frameRate) {      OMX_PARAM_PORTDEFINITIONTYPE def;      InitOMXParams(&def);      def.nPortIndex = portIndex; @@ -2930,6 +3180,9 @@ status_t ACodec::setVideoFormatOnPort(      if (portIndex == kPortIndexInput) {          video_def->eCompressionFormat = compressionFormat;          video_def->eColorFormat = OMX_COLOR_FormatUnused; +        if (frameRate >= 0) { +            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f); +        }      }      err = mOMX->setParameter( @@ -3042,7 +3295,8 @@ bool ACodec::describeDefaultColorFormat(DescribeColorFormatParams ¶ms) {      if (fmt != OMX_COLOR_FormatYUV420Planar &&          fmt != OMX_COLOR_FormatYUV420PackedPlanar &&          fmt != OMX_COLOR_FormatYUV420SemiPlanar && -        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar) { +        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar && +        fmt != HAL_PIXEL_FORMAT_YV12) {          ALOGW("do not know color format 0x%x = %d", fmt, fmt);          return false;      } @@ -3071,8 +3325,31 @@ bool ACodec::describeDefaultColorFormat(DescribeColorFormatParams ¶ms) {      image.mPlane[image.Y].mHorizSubsampling = 1;      image.mPlane[image.Y].mVertSubsampling = 1; -    switch (fmt) { -        case OMX_COLOR_FormatYUV420Planar: // used for YV12 +    switch ((int)fmt) { +        case HAL_PIXEL_FORMAT_YV12: +            if (params.bUsingNativeBuffers) { +                size_t ystride = align(params.nStride, 16); +                size_t cstride = align(params.nStride / 2, 16); +                image.mPlane[image.Y].mRowInc = ystride; + +                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight; +                image.mPlane[image.V].mColInc = 1; +                image.mPlane[image.V].mRowInc = cstride; +                image.mPlane[image.V].mHorizSubsampling = 2; +                image.mPlane[image.V].mVertSubsampling = 2; + +                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset +                        + (cstride * params.nSliceHeight / 2); +                image.mPlane[image.U].mColInc = 1; +                image.mPlane[image.U].mRowInc = cstride; +                image.mPlane[image.U].mHorizSubsampling = 2; +                image.mPlane[image.U].mVertSubsampling = 2; +                break; +            } else { +                // fall through as YV12 is used for YUV420Planar by some codecs +            } + +        case OMX_COLOR_FormatYUV420Planar:          case OMX_COLOR_FormatYUV420PackedPlanar:              image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;              image.mPlane[image.U].mColInc = 1; @@ -3132,7 +3409,7 @@ bool ACodec::describeColorFormat(  // static  bool ACodec::isFlexibleColorFormat(           const sp<IOMX> &omx, IOMX::node_id node, -         uint32_t colorFormat, OMX_U32 *flexibleEquivalent) { +         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {      DescribeColorFormatParams describeParams;      InitOMXParams(&describeParams);      describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat; @@ -3141,6 +3418,7 @@ bool ACodec::isFlexibleColorFormat(      describeParams.nFrameHeight = 128;      describeParams.nStride = 128;      describeParams.nSliceHeight = 128; +    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;      CHECK(flexibleEquivalent != NULL); @@ -3198,20 +3476,30 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) {                      notify->setInt32("slice-height", videoDef->nSliceHeight);                      notify->setInt32("color-format", videoDef->eColorFormat); -                    DescribeColorFormatParams describeParams; -                    InitOMXParams(&describeParams); -                    describeParams.eColorFormat = videoDef->eColorFormat; -                    describeParams.nFrameWidth = videoDef->nFrameWidth; -                    describeParams.nFrameHeight = videoDef->nFrameHeight; -                    describeParams.nStride = videoDef->nStride; -                    describeParams.nSliceHeight = videoDef->nSliceHeight; - -                    if (describeColorFormat(mOMX, mNode, describeParams)) { -                        notify->setBuffer( -                                "image-data", -                                ABuffer::CreateAsCopy( -                                        &describeParams.sMediaImage, -                                        sizeof(describeParams.sMediaImage))); +                    if (mNativeWindow == NULL) { +                        DescribeColorFormatParams describeParams; +                        InitOMXParams(&describeParams); +                        describeParams.eColorFormat = videoDef->eColorFormat; +                        describeParams.nFrameWidth = videoDef->nFrameWidth; +                        describeParams.nFrameHeight = videoDef->nFrameHeight; +                        describeParams.nStride = videoDef->nStride; +                        describeParams.nSliceHeight = videoDef->nSliceHeight; +                        describeParams.bUsingNativeBuffers = OMX_FALSE; + +                        if (describeColorFormat(mOMX, mNode, describeParams)) { +                            notify->setBuffer( +                                    "image-data", +                                    ABuffer::CreateAsCopy( +                                            &describeParams.sMediaImage, +                                            sizeof(describeParams.sMediaImage))); + +                            MediaImage *img = &describeParams.sMediaImage; +                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }", +                                    mComponentName.c_str(), img->mWidth, img->mHeight, +                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc, +                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc, +                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc); +                        }                      }                      if (portIndex != kPortIndexOutput) { @@ -3308,9 +3596,12 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) {                      break;                  }              } -              notify->setInt32("width", videoDef->nFrameWidth);              notify->setInt32("height", videoDef->nFrameHeight); +            ALOGV("[%s] %s format is %s", mComponentName.c_str(), +                    portIndex == kPortIndexInput ? "input" : "output", +                    notify->debugString().c_str()); +              break;          } @@ -3462,6 +3753,24 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) {                      break;                  } +                case OMX_AUDIO_CodingAndroidEAC3: +                { +                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params; +                    InitOMXParams(¶ms); +                    params.nPortIndex = portIndex; + +                    CHECK_EQ((status_t)OK, mOMX->getParameter( +                            mNode, +                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, +                            ¶ms, +                            sizeof(params))); + +                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3); +                    notify->setInt32("channel-count", params.nChannels); +                    notify->setInt32("sample-rate", params.nSampleRate); +                    break; +                } +                  case OMX_AUDIO_CodingAndroidOPUS:                  {                      OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params; @@ -3506,6 +3815,23 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) {                      break;                  } +                case OMX_AUDIO_CodingGSMFR: +                { +                    OMX_AUDIO_PARAM_MP3TYPE params; +                    InitOMXParams(¶ms); +                    params.nPortIndex = portIndex; + +                    CHECK_EQ(mOMX->getParameter( +                                mNode, OMX_IndexParamAudioPcm, +                                ¶ms, sizeof(params)), +                             (status_t)OK); + +                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM); +                    notify->setInt32("channel-count", params.nChannels); +                    notify->setInt32("sample-rate", params.nSampleRate); +                    break; +                } +                  default:                      ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);                      TRESPASS(); @@ -3521,7 +3847,7 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> ¬ify) {  }  void ACodec::sendFormatChange(const sp<AMessage> &reply) { -    sp<AMessage> notify = mNotify->dup(); +    sp<AMessage> notify = mBaseOutputFormat->dup();      notify->setInt32("what", kWhatOutputFormatChanged);      CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK); @@ -4229,7 +4555,8 @@ bool ACodec::BaseState::onOMXFillBufferDone(          case RESUBMIT_BUFFERS:          { -            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) { +            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS) +                    || mCodec->mPortEOS[kPortIndexOutput])) {                  ALOGV("[%s] calling fillBuffer %u",                       mCodec->mComponentName.c_str(), info->mBufferID); @@ -4601,6 +4928,7 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {      if (componentName.endsWith(".secure")) {          mCodec->mFlags |= kFlagIsSecure; +        mCodec->mFlags |= kFlagIsGrallocUsageProtected;          mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;      } @@ -4639,6 +4967,7 @@ void ACodec::LoadedState::stateEntered() {      mCodec->mRepeatFrameDelayUs = -1ll;      mCodec->mInputFormat.clear();      mCodec->mOutputFormat.clear(); +    mCodec->mBaseOutputFormat.clear();      if (mCodec->mShutdownInProgress) {          bool keepComponentAllocated = mCodec->mKeepComponentAllocated; @@ -4742,20 +5071,6 @@ bool ACodec::LoadedState::onConfigureComponent(          return false;      } -    sp<RefBase> obj; -    if (msg->findObject("native-window", &obj) -            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) { -        sp<NativeWindowWrapper> nativeWindow( -                static_cast<NativeWindowWrapper *>(obj.get())); -        CHECK(nativeWindow != NULL); -        mCodec->mNativeWindow = nativeWindow->getNativeWindow(); - -        native_window_set_scaling_mode( -                mCodec->mNativeWindow.get(), -                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); -    } -    CHECK_EQ((status_t)OK, mCodec->initNativeWindow()); -      {          sp<AMessage> notify = mCodec->mNotify->dup();          notify->setInt32("what", CodecBase::kWhatComponentConfigured); diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index ab8ac79..007c090 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -75,7 +75,7 @@ static const size_t kHighWaterMarkBytes = 200000;  // maximum time in paused state when offloading audio decompression. When elapsed, the AudioPlayer  // is destroyed to allow the audio DSP to power down. -static int64_t kOffloadPauseMaxUs = 60000000ll; +static int64_t kOffloadPauseMaxUs = 10000000ll;  struct AwesomeEvent : public TimedEventQueue::Event { @@ -878,6 +878,16 @@ void AwesomePlayer::onStreamDone() {          return;      } +    if (mFlags & AUTO_LOOPING) { +        audio_stream_type_t streamType = AUDIO_STREAM_MUSIC; +        if (mAudioSink != NULL) { +            streamType = mAudioSink->getAudioStreamType(); +        } +        if (streamType == AUDIO_STREAM_NOTIFICATION) { +            ALOGW("disabling auto-loop for notification"); +            modifyFlags(AUTO_LOOPING, CLEAR); +        } +    }      if ((mFlags & LOOPING)              || ((mFlags & AUTO_LOOPING)                  && (mAudioSink == NULL || mAudioSink->realtime()))) { diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index f76aed6..c3a940a 100644 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -130,6 +130,7 @@ static int32_t getColorFormat(const char* colorFormat) {           "CameraSource::getColorFormat", colorFormat);      CHECK(!"Unknown color format"); +    return -1;  }  CameraSource *CameraSource::Create(const String16 &clientName) { diff --git a/media/libstagefright/HTTPBase.cpp b/media/libstagefright/HTTPBase.cpp index 32291c8..0c2ff15 100644 --- a/media/libstagefright/HTTPBase.cpp +++ b/media/libstagefright/HTTPBase.cpp @@ -36,7 +36,8 @@ HTTPBase::HTTPBase()        mTotalTransferBytes(0),        mPrevBandwidthMeasureTimeUs(0),        mPrevEstimatedBandWidthKbps(0), -      mBandWidthCollectFreqMs(5000) { +      mBandWidthCollectFreqMs(5000), +      mMaxBandwidthHistoryItems(100) {  }  void HTTPBase::addBandwidthMeasurement( @@ -50,7 +51,7 @@ void HTTPBase::addBandwidthMeasurement(      mTotalTransferBytes += numBytes;      mBandwidthHistory.push_back(entry); -    if (++mNumBandwidthHistoryItems > 100) { +    if (++mNumBandwidthHistoryItems > mMaxBandwidthHistoryItems) {          BandwidthEntry *entry = &*mBandwidthHistory.begin();          mTotalTransferTimeUs -= entry->mDelayUs;          mTotalTransferBytes -= entry->mNumBytes; @@ -104,6 +105,10 @@ status_t HTTPBase::setBandwidthStatCollectFreq(int32_t freqMs) {      return OK;  } +void HTTPBase::setBandwidthHistorySize(size_t numHistoryItems) { +    mMaxBandwidthHistoryItems = numHistoryItems; +} +  // static  void HTTPBase::RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag) {      int res = qtaguid_tagSocket(sockfd, kTag, uid); diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index e09ecc2..66a3793 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -1003,6 +1003,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {                  int64_t duration;                  int32_t samplerate; +                if (!mLastTrack) { +                    return ERROR_MALFORMED; +                }                  if (mLastTrack->meta->findInt64(kKeyDuration, &duration) &&                          mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) { @@ -1145,7 +1148,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {          {              *offset += chunk_size; -            if (chunk_data_size < 4) { +            if (chunk_data_size < 4 || mLastTrack == NULL) {                  return ERROR_MALFORMED;              } diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index 4b8440b..9f20b1d 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -41,8 +41,13 @@  #include "include/ESDS.h" + +#ifndef __predict_false +#define __predict_false(exp) __builtin_expect((exp) != 0, 0) +#endif +  #define WARN_UNLESS(condition, message, ...) \ -( (CONDITION(condition)) ? false : ({ \ +( (__predict_false(condition)) ? false : ({ \      ALOGW("Condition %s failed "  message, #condition, ##__VA_ARGS__); \      true; \  })) diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index df47bd5..a9c3a04 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -869,9 +869,9 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {                      CHECK(msg->findString("componentName", &mComponentName));                      if (mComponentName.startsWith("OMX.google.")) { -                        mFlags |= kFlagIsSoftwareCodec; +                        mFlags |= kFlagUsesSoftwareRenderer;                      } else { -                        mFlags &= ~kFlagIsSoftwareCodec; +                        mFlags &= ~kFlagUsesSoftwareRenderer;                      }                      if (mComponentName.endsWith(".secure")) { @@ -894,6 +894,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {                      CHECK(msg->findMessage("input-format", &mInputFormat));                      CHECK(msg->findMessage("output-format", &mOutputFormat)); +                    int32_t usingSwRenderer; +                    if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer) +                            && usingSwRenderer) { +                        mFlags |= kFlagUsesSoftwareRenderer; +                    }                      setState(CONFIGURED);                      (new AMessage)->postReply(mReplyID);                      break; @@ -989,7 +994,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {                      if (mSoftRenderer == NULL &&                              mNativeWindow != NULL && -                            (mFlags & kFlagIsSoftwareCodec)) { +                            (mFlags & kFlagUsesSoftwareRenderer)) {                          AString mime;                          CHECK(msg->findString("mime", &mime)); @@ -1011,6 +1016,18 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {                          mFlags |= kFlagOutputFormatChanged;                          postActivityNotificationIfPossible();                      } + +                    // Notify mCrypto of video resolution changes +                    if (mCrypto != NULL) { +                        int32_t left, top, right, bottom, width, height; +                        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) { +                            mCrypto->notifyResolution(right - left + 1, bottom - top + 1); +                        } else if (mOutputFormat->findInt32("width", &width) +                                && mOutputFormat->findInt32("height", &height)) { +                            mCrypto->notifyResolution(width, height); +                        } +                    } +                      break;                  } @@ -1316,8 +1333,10 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {              CHECK(msg->senderAwaitsResponse(&replyID));              if (mState == FLUSHED) { +                setState(STARTED);                  mCodec->signalResume();                  PostReplyWithError(replyID, OK); +                break;              } else if (mState != CONFIGURED) {                  PostReplyWithError(replyID, INVALID_OPERATION);                  break; @@ -1339,9 +1358,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {              uint32_t replyID;              CHECK(msg->senderAwaitsResponse(&replyID)); -            if (!(mFlags & kFlagIsComponentAllocated) && mState != INITIALIZED +            if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1 +                    && mState != INITIALIZED                      && mState != CONFIGURED && !isExecuting()) { -                // We may be in "UNINITIALIZED" state already and +                // 1) Permit release to shut down the component if allocated. +                // +                // 2) We may be in "UNINITIALIZED" state already and                  // also shutdown the encoder/decoder without the                  // client being aware of this if media server died while                  // we were being stopped. The client would assume that diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp index 5b8be46..cf6e937 100644 --- a/media/libstagefright/MediaCodecList.cpp +++ b/media/libstagefright/MediaCodecList.cpp @@ -62,6 +62,14 @@ static Mutex sRemoteInitMutex;  sp<IMediaCodecList> MediaCodecList::sRemoteList; +sp<MediaCodecList::BinderDeathObserver> MediaCodecList::sBinderDeathObserver; + +void MediaCodecList::BinderDeathObserver::binderDied(const wp<IBinder> &who __unused) { +    Mutex::Autolock _l(sRemoteInitMutex); +    sRemoteList.clear(); +    sBinderDeathObserver.clear(); +} +  // static  sp<IMediaCodecList> MediaCodecList::getInstance() {      Mutex::Autolock _l(sRemoteInitMutex); @@ -72,8 +80,11 @@ sp<IMediaCodecList> MediaCodecList::getInstance() {              interface_cast<IMediaPlayerService>(binder);          if (service.get() != NULL) {              sRemoteList = service->getCodecList(); +            if (sRemoteList != NULL) { +                sBinderDeathObserver = new BinderDeathObserver(); +                binder->linkToDeath(sBinderDeathObserver.get()); +            }          } -          if (sRemoteList == NULL) {              // if failed to get remote list, create local list              sRemoteList = getLocalInstance(); diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp index 0fecda8..c26e909 100644 --- a/media/libstagefright/MediaCodecSource.cpp +++ b/media/libstagefright/MediaCodecSource.cpp @@ -422,19 +422,11 @@ status_t MediaCodecSource::initEncoder() {          }      } -    err = mEncoder->start(); - -    if (err != OK) { -        return err; -    } - -    err = mEncoder->getInputBuffers(&mEncoderInputBuffers); +    mEncoderActivityNotify = new AMessage( +            kWhatEncoderActivity, mReflector->id()); +    mEncoder->setCallback(mEncoderActivityNotify); -    if (err != OK) { -        return err; -    } - -    err = mEncoder->getOutputBuffers(&mEncoderOutputBuffers); +    err = mEncoder->start();      if (err != OK) {          return err; @@ -461,14 +453,6 @@ void MediaCodecSource::releaseEncoder() {              mbuf->release();          }      } - -    for (size_t i = 0; i < mEncoderInputBuffers.size(); ++i) { -        sp<ABuffer> accessUnit = mEncoderInputBuffers.itemAt(i); -        accessUnit->setMediaBufferBase(NULL); -    } - -    mEncoderInputBuffers.clear(); -    mEncoderOutputBuffers.clear();  }  status_t MediaCodecSource::postSynchronouslyAndReturnError( @@ -539,20 +523,6 @@ void MediaCodecSource::resume(int64_t skipFramesBeforeUs) {      }  } -void MediaCodecSource::scheduleDoMoreWork() { -    if (mDoMoreWorkPending) { -        return; -    } - -    mDoMoreWorkPending = true; - -    if (mEncoderActivityNotify == NULL) { -        mEncoderActivityNotify = new AMessage( -                kWhatEncoderActivity, mReflector->id()); -    } -    mEncoder->requestActivityNotification(mEncoderActivityNotify); -} -  status_t MediaCodecSource::feedEncoderInputBuffers() {      while (!mInputBufferQueue.empty()              && !mAvailEncoderInputIndices.empty()) { @@ -587,16 +557,22 @@ status_t MediaCodecSource::feedEncoderInputBuffers() {  #endif // DEBUG_DRIFT_TIME              } +            sp<ABuffer> inbuf; +            status_t err = mEncoder->getInputBuffer(bufferIndex, &inbuf); +            if (err != OK || inbuf == NULL) { +                mbuf->release(); +                signalEOS(); +                break; +            } +              size = mbuf->size(); -            memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(), -                   mbuf->data(), size); +            memcpy(inbuf->data(), mbuf->data(), size);              if (mIsVideo) {                  // video encoder will release MediaBuffer when done                  // with underlying data. -                mEncoderInputBuffers.itemAt(bufferIndex)->setMediaBufferBase( -                        mbuf); +                inbuf->setMediaBufferBase(mbuf);              } else {                  mbuf->release();              } @@ -615,113 +591,6 @@ status_t MediaCodecSource::feedEncoderInputBuffers() {      return OK;  } -status_t MediaCodecSource::doMoreWork(int32_t numInput, int32_t numOutput) { -    status_t err = OK; - -    if (!(mFlags & FLAG_USE_SURFACE_INPUT)) { -        while (numInput-- > 0) { -            size_t bufferIndex; -            err = mEncoder->dequeueInputBuffer(&bufferIndex); - -            if (err != OK) { -                break; -            } - -            mAvailEncoderInputIndices.push_back(bufferIndex); -        } - -        feedEncoderInputBuffers(); -    } - -    while (numOutput-- > 0) { -        size_t bufferIndex; -        size_t offset; -        size_t size; -        int64_t timeUs; -        uint32_t flags; -        native_handle_t* handle = NULL; -        err = mEncoder->dequeueOutputBuffer( -                &bufferIndex, &offset, &size, &timeUs, &flags); - -        if (err != OK) { -            if (err == INFO_FORMAT_CHANGED) { -                continue; -            } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) { -                mEncoder->getOutputBuffers(&mEncoderOutputBuffers); -                continue; -            } - -            if (err == -EAGAIN) { -                err = OK; -            } -            break; -        } -        if (!(flags & MediaCodec::BUFFER_FLAG_EOS)) { -            sp<ABuffer> outbuf = mEncoderOutputBuffers.itemAt(bufferIndex); - -            MediaBuffer *mbuf = new MediaBuffer(outbuf->size()); -            memcpy(mbuf->data(), outbuf->data(), outbuf->size()); - -            if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) { -                if (mIsVideo) { -                    int64_t decodingTimeUs; -                    if (mFlags & FLAG_USE_SURFACE_INPUT) { -                        // GraphicBufferSource is supposed to discard samples -                        // queued before start, and offset timeUs by start time -                        CHECK_GE(timeUs, 0ll); -                        // TODO: -                        // Decoding time for surface source is unavailable, -                        // use presentation time for now. May need to move -                        // this logic into MediaCodec. -                        decodingTimeUs = timeUs; -                    } else { -                        CHECK(!mDecodingTimeQueue.empty()); -                        decodingTimeUs = *(mDecodingTimeQueue.begin()); -                        mDecodingTimeQueue.erase(mDecodingTimeQueue.begin()); -                    } -                    mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); - -                    ALOGV("[video] time %" PRId64 " us (%.2f secs), dts/pts diff %" PRId64, -                            timeUs, timeUs / 1E6, decodingTimeUs - timeUs); -                } else { -                    int64_t driftTimeUs = 0; -#if DEBUG_DRIFT_TIME -                    CHECK(!mDriftTimeQueue.empty()); -                    driftTimeUs = *(mDriftTimeQueue.begin()); -                    mDriftTimeQueue.erase(mDriftTimeQueue.begin()); -                    mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs); -#endif // DEBUG_DRIFT_TIME -                    ALOGV("[audio] time %" PRId64 " us (%.2f secs), drift %" PRId64, -                            timeUs, timeUs / 1E6, driftTimeUs); -                } -                mbuf->meta_data()->setInt64(kKeyTime, timeUs); -            } else { -                mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true); -            } -            if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) { -                mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true); -            } -            mbuf->setObserver(this); -            mbuf->add_ref(); - -            { -                Mutex::Autolock autoLock(mOutputBufferLock); -                mOutputBufferQueue.push_back(mbuf); -                mOutputBufferCond.signal(); -            } -        } - -        mEncoder->releaseOutputBuffer(bufferIndex); - -        if (flags & MediaCodec::BUFFER_FLAG_EOS) { -            err = ERROR_END_OF_STREAM; -            break; -        } -    } - -    return err; -} -  status_t MediaCodecSource::onStart(MetaData *params) {      if (mStopping) {          ALOGE("Failed to start while we're stopping"); @@ -749,7 +618,6 @@ status_t MediaCodecSource::onStart(MetaData *params) {              startTimeUs = -1ll;          }          resume(startTimeUs); -        scheduleDoMoreWork();      } else {          CHECK(mPuller != NULL);          sp<AMessage> notify = new AMessage( @@ -793,37 +661,110 @@ void MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {          mInputBufferQueue.push_back(mbuf);          feedEncoderInputBuffers(); -        scheduleDoMoreWork();          break;      }      case kWhatEncoderActivity:      { -        mDoMoreWorkPending = false; -          if (mEncoder == NULL) {              break;          } -        int32_t numInput, numOutput; +        int32_t cbID; +        CHECK(msg->findInt32("callbackID", &cbID)); +        if (cbID == MediaCodec::CB_INPUT_AVAILABLE) { +            int32_t index; +            CHECK(msg->findInt32("index", &index)); + +            mAvailEncoderInputIndices.push_back(index); +            feedEncoderInputBuffers(); +        } else if (cbID == MediaCodec::CB_OUTPUT_AVAILABLE) { +            int32_t index; +            size_t offset; +            size_t size; +            int64_t timeUs; +            int32_t flags; +            native_handle_t* handle = NULL; + +            CHECK(msg->findInt32("index", &index)); +            CHECK(msg->findSize("offset", &offset)); +            CHECK(msg->findSize("size", &size)); +            CHECK(msg->findInt64("timeUs", &timeUs)); +            CHECK(msg->findInt32("flags", &flags)); + +            if (flags & MediaCodec::BUFFER_FLAG_EOS) { +                mEncoder->releaseOutputBuffer(index); +                signalEOS(); +                break; +            } -        if (!msg->findInt32("input-buffers", &numInput)) { -            numInput = INT32_MAX; -        } -        if (!msg->findInt32("output-buffers", &numOutput)) { -            numOutput = INT32_MAX; -        } +            sp<ABuffer> outbuf; +            status_t err = mEncoder->getOutputBuffer(index, &outbuf); +            if (err != OK || outbuf == NULL) { +                signalEOS(); +                break; +            } -        status_t err = doMoreWork(numInput, numOutput); +            MediaBuffer *mbuf = new MediaBuffer(outbuf->size()); +            memcpy(mbuf->data(), outbuf->data(), outbuf->size()); -        if (err == OK) { -            scheduleDoMoreWork(); -        } else { -            // reached EOS, or error -            signalEOS(err); -        } +            if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) { +                if (mIsVideo) { +                    int64_t decodingTimeUs; +                    if (mFlags & FLAG_USE_SURFACE_INPUT) { +                        // GraphicBufferSource is supposed to discard samples +                        // queued before start, and offset timeUs by start time +                        CHECK_GE(timeUs, 0ll); +                        // TODO: +                        // Decoding time for surface source is unavailable, +                        // use presentation time for now. May need to move +                        // this logic into MediaCodec. +                        decodingTimeUs = timeUs; +                    } else { +                        CHECK(!mDecodingTimeQueue.empty()); +                        decodingTimeUs = *(mDecodingTimeQueue.begin()); +                        mDecodingTimeQueue.erase(mDecodingTimeQueue.begin()); +                    } +                    mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); -        break; +                    ALOGV("[video] time %" PRId64 " us (%.2f secs), dts/pts diff %" PRId64, +                            timeUs, timeUs / 1E6, decodingTimeUs - timeUs); +                } else { +                    int64_t driftTimeUs = 0; +#if DEBUG_DRIFT_TIME +                    CHECK(!mDriftTimeQueue.empty()); +                    driftTimeUs = *(mDriftTimeQueue.begin()); +                    mDriftTimeQueue.erase(mDriftTimeQueue.begin()); +                    mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs); +#endif // DEBUG_DRIFT_TIME +                    ALOGV("[audio] time %" PRId64 " us (%.2f secs), drift %" PRId64, +                            timeUs, timeUs / 1E6, driftTimeUs); +                } +                mbuf->meta_data()->setInt64(kKeyTime, timeUs); +            } else { +                mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true); +            } +            if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) { +                mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true); +            } +            mbuf->setObserver(this); +            mbuf->add_ref(); + +            { +                Mutex::Autolock autoLock(mOutputBufferLock); +                mOutputBufferQueue.push_back(mbuf); +                mOutputBufferCond.signal(); +            } + +            mEncoder->releaseOutputBuffer(index); +       } else if (cbID == MediaCodec::CB_ERROR) { +            status_t err; +            CHECK(msg->findInt32("err", &err)); +            ALOGE("Encoder (%s) reported error : 0x%x", +                    mIsVideo ? "video" : "audio", err); +            signalEOS(); +       } +       break;      }      case kWhatStart:      { diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp index d48dd84..c5a6939 100644 --- a/media/libstagefright/MediaDefs.cpp +++ b/media/libstagefright/MediaDefs.cpp @@ -45,6 +45,7 @@ const char *MEDIA_MIMETYPE_AUDIO_FLAC = "audio/flac";  const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS = "audio/aac-adts";  const char *MEDIA_MIMETYPE_AUDIO_MSGSM = "audio/gsm";  const char *MEDIA_MIMETYPE_AUDIO_AC3 = "audio/ac3"; +const char *MEDIA_MIMETYPE_AUDIO_EAC3 = "audio/eac3";  const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mp4";  const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/x-wav"; diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp index bd0a41d..7d7d631 100644 --- a/media/libstagefright/NuCachedSource2.cpp +++ b/media/libstagefright/NuCachedSource2.cpp @@ -354,7 +354,7 @@ void NuCachedSource2::fetchInternal() {      Mutex::Autolock autoLock(mLock);      if (n == 0 || mDisconnecting) { -        ALOGI("ERROR_END_OF_STREAM"); +        ALOGI("caching reached eos.");          mNumRetriesLeft = 0;          mFinalStatus = ERROR_END_OF_STREAM; diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index a8806c8..6da00e6 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -47,10 +47,11 @@  #include <media/stagefright/SkipCutBuffer.h>  #include <utils/Vector.h> -#include <OMX_Audio.h>  #include <OMX_AudioExt.h>  #include <OMX_Component.h>  #include <OMX_IndexExt.h> +#include <OMX_VideoExt.h> +#include <OMX_AsString.h>  #include "include/avc_utils.h" @@ -817,6 +818,7 @@ static size_t getFrameSize(              CHECK(!"Should not be here. Unsupported color format.");              break;      } +    return 0;  }  status_t OMXCodec::findTargetColorFormat( @@ -4077,220 +4079,6 @@ void OMXCodec::signalBufferReturned(MediaBuffer *buffer) {      CHECK(!"should not be here.");  } -static const char *imageCompressionFormatString(OMX_IMAGE_CODINGTYPE type) { -    static const char *kNames[] = { -        "OMX_IMAGE_CodingUnused", -        "OMX_IMAGE_CodingAutoDetect", -        "OMX_IMAGE_CodingJPEG", -        "OMX_IMAGE_CodingJPEG2K", -        "OMX_IMAGE_CodingEXIF", -        "OMX_IMAGE_CodingTIFF", -        "OMX_IMAGE_CodingGIF", -        "OMX_IMAGE_CodingPNG", -        "OMX_IMAGE_CodingLZW", -        "OMX_IMAGE_CodingBMP", -    }; - -    size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - -    if (type < 0 || (size_t)type >= numNames) { -        return "UNKNOWN"; -    } else { -        return kNames[type]; -    } -} - -static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { -    static const char *kNames[] = { -        "OMX_COLOR_FormatUnused", -        "OMX_COLOR_FormatMonochrome", -        "OMX_COLOR_Format8bitRGB332", -        "OMX_COLOR_Format12bitRGB444", -        "OMX_COLOR_Format16bitARGB4444", -        "OMX_COLOR_Format16bitARGB1555", -        "OMX_COLOR_Format16bitRGB565", -        "OMX_COLOR_Format16bitBGR565", -        "OMX_COLOR_Format18bitRGB666", -        "OMX_COLOR_Format18bitARGB1665", -        "OMX_COLOR_Format19bitARGB1666", -        "OMX_COLOR_Format24bitRGB888", -        "OMX_COLOR_Format24bitBGR888", -        "OMX_COLOR_Format24bitARGB1887", -        "OMX_COLOR_Format25bitARGB1888", -        "OMX_COLOR_Format32bitBGRA8888", -        "OMX_COLOR_Format32bitARGB8888", -        "OMX_COLOR_FormatYUV411Planar", -        "OMX_COLOR_FormatYUV411PackedPlanar", -        "OMX_COLOR_FormatYUV420Planar", -        "OMX_COLOR_FormatYUV420PackedPlanar", -        "OMX_COLOR_FormatYUV420SemiPlanar", -        "OMX_COLOR_FormatYUV422Planar", -        "OMX_COLOR_FormatYUV422PackedPlanar", -        "OMX_COLOR_FormatYUV422SemiPlanar", -        "OMX_COLOR_FormatYCbYCr", -        "OMX_COLOR_FormatYCrYCb", -        "OMX_COLOR_FormatCbYCrY", -        "OMX_COLOR_FormatCrYCbY", -        "OMX_COLOR_FormatYUV444Interleaved", -        "OMX_COLOR_FormatRawBayer8bit", -        "OMX_COLOR_FormatRawBayer10bit", -        "OMX_COLOR_FormatRawBayer8bitcompressed", -        "OMX_COLOR_FormatL2", -        "OMX_COLOR_FormatL4", -        "OMX_COLOR_FormatL8", -        "OMX_COLOR_FormatL16", -        "OMX_COLOR_FormatL24", -        "OMX_COLOR_FormatL32", -        "OMX_COLOR_FormatYUV420PackedSemiPlanar", -        "OMX_COLOR_FormatYUV422PackedSemiPlanar", -        "OMX_COLOR_Format18BitBGR666", -        "OMX_COLOR_Format24BitARGB6666", -        "OMX_COLOR_Format24BitABGR6666", -    }; - -    size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - -    if (type == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) { -        return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar"; -    } else if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { -        return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; -    } else if (type < 0 || (size_t)type >= numNames) { -        return "UNKNOWN"; -    } else { -        return kNames[type]; -    } -} - -static const char *videoCompressionFormatString(OMX_VIDEO_CODINGTYPE type) { -    static const char *kNames[] = { -        "OMX_VIDEO_CodingUnused", -        "OMX_VIDEO_CodingAutoDetect", -        "OMX_VIDEO_CodingMPEG2", -        "OMX_VIDEO_CodingH263", -        "OMX_VIDEO_CodingMPEG4", -        "OMX_VIDEO_CodingWMV", -        "OMX_VIDEO_CodingRV", -        "OMX_VIDEO_CodingAVC", -        "OMX_VIDEO_CodingMJPEG", -    }; - -    size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - -    if (type < 0 || (size_t)type >= numNames) { -        return "UNKNOWN"; -    } else { -        return kNames[type]; -    } -} - -static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { -    static const char *kNames[] = { -        "OMX_AUDIO_CodingUnused", -        "OMX_AUDIO_CodingAutoDetect", -        "OMX_AUDIO_CodingPCM", -        "OMX_AUDIO_CodingADPCM", -        "OMX_AUDIO_CodingAMR", -        "OMX_AUDIO_CodingGSMFR", -        "OMX_AUDIO_CodingGSMEFR", -        "OMX_AUDIO_CodingGSMHR", -        "OMX_AUDIO_CodingPDCFR", -        "OMX_AUDIO_CodingPDCEFR", -        "OMX_AUDIO_CodingPDCHR", -        "OMX_AUDIO_CodingTDMAFR", -        "OMX_AUDIO_CodingTDMAEFR", -        "OMX_AUDIO_CodingQCELP8", -        "OMX_AUDIO_CodingQCELP13", -        "OMX_AUDIO_CodingEVRC", -        "OMX_AUDIO_CodingSMV", -        "OMX_AUDIO_CodingG711", -        "OMX_AUDIO_CodingG723", -        "OMX_AUDIO_CodingG726", -        "OMX_AUDIO_CodingG729", -        "OMX_AUDIO_CodingAAC", -        "OMX_AUDIO_CodingMP3", -        "OMX_AUDIO_CodingSBC", -        "OMX_AUDIO_CodingVORBIS", -        "OMX_AUDIO_CodingOPUS", -        "OMX_AUDIO_CodingWMA", -        "OMX_AUDIO_CodingRA", -        "OMX_AUDIO_CodingMIDI", -    }; - -    size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - -    if (type < 0 || (size_t)type >= numNames) { -        return "UNKNOWN"; -    } else { -        return kNames[type]; -    } -} - -static const char *audioPCMModeString(OMX_AUDIO_PCMMODETYPE type) { -    static const char *kNames[] = { -        "OMX_AUDIO_PCMModeLinear", -        "OMX_AUDIO_PCMModeALaw", -        "OMX_AUDIO_PCMModeMULaw", -    }; - -    size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - -    if (type < 0 || (size_t)type >= numNames) { -        return "UNKNOWN"; -    } else { -        return kNames[type]; -    } -} - -static const char *amrBandModeString(OMX_AUDIO_AMRBANDMODETYPE type) { -    static const char *kNames[] = { -        "OMX_AUDIO_AMRBandModeUnused", -        "OMX_AUDIO_AMRBandModeNB0", -        "OMX_AUDIO_AMRBandModeNB1", -        "OMX_AUDIO_AMRBandModeNB2", -        "OMX_AUDIO_AMRBandModeNB3", -        "OMX_AUDIO_AMRBandModeNB4", -        "OMX_AUDIO_AMRBandModeNB5", -        "OMX_AUDIO_AMRBandModeNB6", -        "OMX_AUDIO_AMRBandModeNB7", -        "OMX_AUDIO_AMRBandModeWB0", -        "OMX_AUDIO_AMRBandModeWB1", -        "OMX_AUDIO_AMRBandModeWB2", -        "OMX_AUDIO_AMRBandModeWB3", -        "OMX_AUDIO_AMRBandModeWB4", -        "OMX_AUDIO_AMRBandModeWB5", -        "OMX_AUDIO_AMRBandModeWB6", -        "OMX_AUDIO_AMRBandModeWB7", -        "OMX_AUDIO_AMRBandModeWB8", -    }; - -    size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - -    if (type < 0 || (size_t)type >= numNames) { -        return "UNKNOWN"; -    } else { -        return kNames[type]; -    } -} - -static const char *amrFrameFormatString(OMX_AUDIO_AMRFRAMEFORMATTYPE type) { -    static const char *kNames[] = { -        "OMX_AUDIO_AMRFrameFormatConformance", -        "OMX_AUDIO_AMRFrameFormatIF1", -        "OMX_AUDIO_AMRFrameFormatIF2", -        "OMX_AUDIO_AMRFrameFormatFSF", -        "OMX_AUDIO_AMRFrameFormatRTPPayload", -        "OMX_AUDIO_AMRFrameFormatITU", -    }; - -    size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - -    if (type < 0 || (size_t)type >= numNames) { -        return "UNKNOWN"; -    } else { -        return kNames[type]; -    } -} -  void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {      OMX_PARAM_PORTDEFINITIONTYPE def;      InitOMXParams(&def); @@ -4321,10 +4109,10 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {              printf("  nStride = %" PRIu32 "\n", imageDef->nStride);              printf("  eCompressionFormat = %s\n", -                   imageCompressionFormatString(imageDef->eCompressionFormat)); +                   asString(imageDef->eCompressionFormat));              printf("  eColorFormat = %s\n", -                   colorFormatString(imageDef->eColorFormat)); +                   asString(imageDef->eColorFormat));              break;          } @@ -4340,10 +4128,10 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {              printf("  nStride = %" PRIu32 "\n", videoDef->nStride);              printf("  eCompressionFormat = %s\n", -                   videoCompressionFormatString(videoDef->eCompressionFormat)); +                   asString(videoDef->eCompressionFormat));              printf("  eColorFormat = %s\n", -                   colorFormatString(videoDef->eColorFormat)); +                   asString(videoDef->eColorFormat));              break;          } @@ -4355,7 +4143,7 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {              printf("\n");              printf("  // Audio\n");              printf("  eEncoding = %s\n", -                   audioCodingTypeString(audioDef->eEncoding)); +                   asString(audioDef->eEncoding));              if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {                  OMX_AUDIO_PARAM_PCMMODETYPE params; @@ -4375,7 +4163,7 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {                         params.eNumData == OMX_NumericalDataSigned                          ? "signed" : "unsigned"); -                printf("  ePCMMode = %s\n", audioPCMModeString(params.ePCMMode)); +                printf("  ePCMMode = %s\n", asString(params.ePCMMode));              } else if (audioDef->eEncoding == OMX_AUDIO_CodingAMR) {                  OMX_AUDIO_PARAM_AMRTYPE amr;                  InitOMXParams(&amr); @@ -4387,9 +4175,9 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {                  printf("  nChannels = %" PRIu32 "\n", amr.nChannels);                  printf("  eAMRBandMode = %s\n", -                        amrBandModeString(amr.eAMRBandMode)); +                        asString(amr.eAMRBandMode));                  printf("  eAMRFrameFormat = %s\n", -                        amrFrameFormatString(amr.eAMRFrameFormat)); +                        asString(amr.eAMRFrameFormat));              }              break; @@ -4698,12 +4486,7 @@ status_t QueryCodec(          const char *componentName, const char *mime,          bool isEncoder,          CodecCapabilities *caps) { -    if (strncmp(componentName, "OMX.", 4)) { -        // Not an OpenMax component but a software codec. -        caps->mFlags = 0; -        caps->mComponentName = componentName; -        return OK; -    } +    bool isVideo = !strncasecmp(mime, "video/", 6);      sp<OMXCodecObserver> observer = new OMXCodecObserver;      IOMX::node_id node; @@ -4718,59 +4501,63 @@ status_t QueryCodec(      caps->mFlags = 0;      caps->mComponentName = componentName; -    OMX_VIDEO_PARAM_PROFILELEVELTYPE param; -    InitOMXParams(¶m); +    // NOTE: OMX does not provide a way to query AAC profile support +    if (isVideo) { +        OMX_VIDEO_PARAM_PROFILELEVELTYPE param; +        InitOMXParams(¶m); -    param.nPortIndex = !isEncoder ? 0 : 1; +        param.nPortIndex = !isEncoder ? 0 : 1; -    for (param.nProfileIndex = 0;; ++param.nProfileIndex) { -        err = omx->getParameter( -                node, OMX_IndexParamVideoProfileLevelQuerySupported, -                ¶m, sizeof(param)); - -        if (err != OK) { -            break; -        } +        for (param.nProfileIndex = 0;; ++param.nProfileIndex) { +            err = omx->getParameter( +                    node, OMX_IndexParamVideoProfileLevelQuerySupported, +                    ¶m, sizeof(param)); -        CodecProfileLevel profileLevel; -        profileLevel.mProfile = param.eProfile; -        profileLevel.mLevel = param.eLevel; +            if (err != OK) { +                break; +            } -        caps->mProfileLevels.push(profileLevel); -    } +            CodecProfileLevel profileLevel; +            profileLevel.mProfile = param.eProfile; +            profileLevel.mLevel = param.eLevel; -    // Color format query -    // return colors in the order reported by the OMX component -    // prefix "flexible" standard ones with the flexible equivalent -    OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; -    InitOMXParams(&portFormat); -    portFormat.nPortIndex = !isEncoder ? 1 : 0; -    for (portFormat.nIndex = 0;; ++portFormat.nIndex)  { -        err = omx->getParameter( -                node, OMX_IndexParamVideoPortFormat, -                &portFormat, sizeof(portFormat)); -        if (err != OK) { -            break; +            caps->mProfileLevels.push(profileLevel);          } -        OMX_U32 flexibleEquivalent; -        if (ACodec::isFlexibleColorFormat( -                    omx, node, portFormat.eColorFormat, &flexibleEquivalent)) { -            bool marked = false; -            for (size_t i = 0; i < caps->mColorFormats.size(); i++) { -                if (caps->mColorFormats.itemAt(i) == flexibleEquivalent) { -                    marked = true; -                    break; -                } +        // Color format query +        // return colors in the order reported by the OMX component +        // prefix "flexible" standard ones with the flexible equivalent +        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; +        InitOMXParams(&portFormat); +        portFormat.nPortIndex = !isEncoder ? 1 : 0; +        for (portFormat.nIndex = 0;; ++portFormat.nIndex)  { +            err = omx->getParameter( +                    node, OMX_IndexParamVideoPortFormat, +                    &portFormat, sizeof(portFormat)); +            if (err != OK) { +                break;              } -            if (!marked) { -                caps->mColorFormats.push(flexibleEquivalent); + +            OMX_U32 flexibleEquivalent; +            if (ACodec::isFlexibleColorFormat( +                        omx, node, portFormat.eColorFormat, false /* usingNativeWindow */, +                        &flexibleEquivalent)) { +                bool marked = false; +                for (size_t i = 0; i < caps->mColorFormats.size(); i++) { +                    if (caps->mColorFormats.itemAt(i) == flexibleEquivalent) { +                        marked = true; +                        break; +                    } +                } +                if (!marked) { +                    caps->mColorFormats.push(flexibleEquivalent); +                }              } +            caps->mColorFormats.push(portFormat.eColorFormat);          } -        caps->mColorFormats.push(portFormat.eColorFormat);      } -    if (!isEncoder && !strncmp(mime, "video/", 6)) { +    if (isVideo && !isEncoder) {          if (omx->storeMetaDataInBuffers(                      node, 1 /* port index */, OMX_TRUE) == OK ||              omx->prepareForAdaptivePlayback( diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp index b37c6b4..45095fc 100644 --- a/media/libstagefright/OggExtractor.cpp +++ b/media/libstagefright/OggExtractor.cpp @@ -38,6 +38,7 @@ extern "C" {      int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb);      int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb);      int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb); +    long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op);  }  namespace android { @@ -75,7 +76,7 @@ struct MyVorbisExtractor {      status_t seekToTime(int64_t timeUs);      status_t seekToOffset(off64_t offset); -    status_t readNextPacket(MediaBuffer **buffer); +    status_t readNextPacket(MediaBuffer **buffer, bool conf);      status_t init(); @@ -84,6 +85,8 @@ struct MyVorbisExtractor {  private:      struct Page {          uint64_t mGranulePosition; +        int32_t mPrevPacketSize; +        uint64_t mPrevPacketPos;          uint32_t mSerialNo;          uint32_t mPageNo;          uint8_t mFlags; @@ -121,6 +124,8 @@ private:      status_t verifyHeader(              MediaBuffer *buffer, uint8_t type); +    int32_t packetBlockSize(MediaBuffer *buffer); +      void parseFileMetaData();      status_t findPrevGranulePosition(off64_t pageOffset, uint64_t *granulePos); @@ -180,7 +185,7 @@ status_t OggSource::read(      }      MediaBuffer *packet; -    status_t err = mExtractor->mImpl->readNextPacket(&packet); +    status_t err = mExtractor->mImpl->readNextPacket(&packet, /* conf = */ false);      if (err != OK) {          return err; @@ -373,6 +378,7 @@ status_t MyVorbisExtractor::seekToOffset(off64_t offset) {      mFirstPacketInPage = true;      mCurrentPageSamples = 0;      mCurrentPage.mNumSegments = 0; +    mCurrentPage.mPrevPacketSize = -1;      mNextLaceIndex = 0;      // XXX what if new page continues packet from last??? @@ -451,7 +457,7 @@ ssize_t MyVorbisExtractor::readPage(off64_t offset, Page *page) {      return sizeof(header) + page->mNumSegments + totalSize;  } -status_t MyVorbisExtractor::readNextPacket(MediaBuffer **out) { +status_t MyVorbisExtractor::readNextPacket(MediaBuffer **out, bool conf) {      *out = NULL;      MediaBuffer *buffer = NULL; @@ -489,16 +495,6 @@ status_t MyVorbisExtractor::readNextPacket(MediaBuffer **out) {                  tmp->set_range(0, buffer->range_length());                  buffer->release();              } else { -                // XXX Not only is this not technically the correct time for -                // this packet, we also stamp every packet in this page -                // with the same time. This needs fixing later. - -                if (mVi.rate) { -                    // Rate may not have been initialized yet if we're currently -                    // reading the configuration packets... -                    // Fortunately, the timestamp doesn't matter for those. -                    timeUs = mCurrentPage.mGranulePosition * 1000000ll / mVi.rate; -                }                  tmp->set_range(0, 0);              }              buffer = tmp; @@ -521,16 +517,32 @@ status_t MyVorbisExtractor::readNextPacket(MediaBuffer **out) {              if (gotFullPacket) {                  // We've just read the entire packet. -                if (timeUs >= 0) { -                    buffer->meta_data()->setInt64(kKeyTime, timeUs); -                } -                  if (mFirstPacketInPage) {                      buffer->meta_data()->setInt32(                              kKeyValidSamples, mCurrentPageSamples);                      mFirstPacketInPage = false;                  } +                // ignore timestamp for configuration packets +                if (!conf) { +                    int32_t curBlockSize = packetBlockSize(buffer); +                    if (mCurrentPage.mPrevPacketSize < 0) { +                        mCurrentPage.mPrevPacketSize = curBlockSize; +                        mCurrentPage.mPrevPacketPos = +                                mCurrentPage.mGranulePosition - mCurrentPageSamples; +                        timeUs = mCurrentPage.mPrevPacketPos * 1000000ll / mVi.rate; +                    } else { +                        // The effective block size is the average of the two overlapped blocks +                        int32_t actualBlockSize = +                                (curBlockSize + mCurrentPage.mPrevPacketSize) / 2; +                        timeUs = mCurrentPage.mPrevPacketPos * 1000000ll / mVi.rate; +                        // The actual size output by the decoder will be half the effective +                        // size, due to the overlap +                        mCurrentPage.mPrevPacketPos += actualBlockSize / 2; +                        mCurrentPage.mPrevPacketSize = curBlockSize; +                    } +                    buffer->meta_data()->setInt64(kKeyTime, timeUs); +                }                  *out = buffer;                  return OK; @@ -591,7 +603,7 @@ status_t MyVorbisExtractor::init() {      MediaBuffer *packet;      status_t err; -    if ((err = readNextPacket(&packet)) != OK) { +    if ((err = readNextPacket(&packet, /* conf = */ true)) != OK) {          return err;      }      ALOGV("read packet of size %zu\n", packet->range_length()); @@ -602,7 +614,7 @@ status_t MyVorbisExtractor::init() {          return err;      } -    if ((err = readNextPacket(&packet)) != OK) { +    if ((err = readNextPacket(&packet, /* conf = */ true)) != OK) {          return err;      }      ALOGV("read packet of size %zu\n", packet->range_length()); @@ -613,7 +625,7 @@ status_t MyVorbisExtractor::init() {          return err;      } -    if ((err = readNextPacket(&packet)) != OK) { +    if ((err = readNextPacket(&packet, /* conf = */ true)) != OK) {          return err;      }      ALOGV("read packet of size %zu\n", packet->range_length()); @@ -686,6 +698,35 @@ void MyVorbisExtractor::buildTableOfContents() {      }  } +int32_t MyVorbisExtractor::packetBlockSize(MediaBuffer *buffer) { +    const uint8_t *data = +        (const uint8_t *)buffer->data() + buffer->range_offset(); + +    size_t size = buffer->range_length(); + +    ogg_buffer buf; +    buf.data = (uint8_t *)data; +    buf.size = size; +    buf.refcount = 1; +    buf.ptr.owner = NULL; + +    ogg_reference ref; +    ref.buffer = &buf; +    ref.begin = 0; +    ref.length = size; +    ref.next = NULL; + +    ogg_packet pack; +    pack.packet = &ref; +    pack.bytes = ref.length; +    pack.b_o_s = 0; +    pack.e_o_s = 0; +    pack.granulepos = 0; +    pack.packetno = 0; + +    return vorbis_packet_blocksize(&mVi, &pack); +} +  status_t MyVorbisExtractor::verifyHeader(          MediaBuffer *buffer, uint8_t type) {      const uint8_t *data = @@ -730,6 +771,10 @@ status_t MyVorbisExtractor::verifyHeader(              ALOGV("upper-bitrate = %ld", mVi.bitrate_upper);              ALOGV("nominal-bitrate = %ld", mVi.bitrate_nominal);              ALOGV("window-bitrate = %ld", mVi.bitrate_window); +            ALOGV("blocksizes: %d/%d", +                    vorbis_info_blocksize(&mVi, 0), +                    vorbis_info_blocksize(&mVi, 1) +                    );              off64_t size;              if (mSource->getSize(&size) == OK) { diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp index 4e1c65c..530383b 100644 --- a/media/libstagefright/SurfaceMediaSource.cpp +++ b/media/libstagefright/SurfaceMediaSource.cpp @@ -448,7 +448,7 @@ void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {  }  // Part of the BufferQueue::ConsumerListener -void SurfaceMediaSource::onFrameAvailable() { +void SurfaceMediaSource::onFrameAvailable(const BufferItem& /* item */) {      ALOGV("onFrameAvailable");      sp<FrameAvailableListener> listener; diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp index a4a651d..335ac84 100644 --- a/media/libstagefright/WAVExtractor.cpp +++ b/media/libstagefright/WAVExtractor.cpp @@ -439,10 +439,6 @@ status_t WAVSource::read(          maxBytesToRead = maxBytesAvailable;      } -    // read only integral amounts of audio unit frames. -    const size_t inputUnitFrameSize = mNumChannels * mBitsPerSample / 8; -    maxBytesToRead -= maxBytesToRead % inputUnitFrameSize; -      if (mWaveFormat == WAVE_FORMAT_MSGSM) {          // Microsoft packs 2 frames into 65 bytes, rather than using separate 33-byte frames,          // so read multiples of 65, and use smaller buffers to account for ~10:1 expansion ratio @@ -450,6 +446,10 @@ status_t WAVSource::read(              maxBytesToRead = 1024;          }          maxBytesToRead = (maxBytesToRead / 65) * 65; +    } else { +        // read only integral amounts of audio unit frames. +        const size_t inputUnitFrameSize = mNumChannels * mBitsPerSample / 8; +        maxBytesToRead -= maxBytesToRead % inputUnitFrameSize;      }      ssize_t n = mDataSource->readAt( diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp index 38a1f6b..cbdb816 100644 --- a/media/libstagefright/avc_utils.cpp +++ b/media/libstagefright/avc_utils.cpp @@ -222,28 +222,25 @@ status_t getNextNALUnit(      *nalStart = NULL;      *nalSize = 0; -    if (size == 0) { +    if (size < 3) {          return -EAGAIN;      } -    // Skip any number of leading 0x00. -      size_t offset = 0; -    while (offset < size && data[offset] == 0x00) { -        ++offset; -    } - -    if (offset == size) { -        return -EAGAIN; -    }      // A valid startcode consists of at least two 0x00 bytes followed by 0x01. - -    if (offset < 2 || data[offset] != 0x01) { -        return ERROR_MALFORMED; +    for (; offset + 2 < size; ++offset) { +        if (data[offset + 2] == 0x01 && data[offset] == 0x00 +                && data[offset + 1] == 0x00) { +            break; +        }      } - -    ++offset; +    if (offset + 2 >= size) { +        *_data = &data[offset]; +        *_size = 2; +        return -EAGAIN; +    } +    offset += 3;      size_t startOffset = offset; diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp index 40925fd..351ba1e 100644 --- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp +++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp @@ -929,33 +929,22 @@ void SoftAAC2::onQueueFilled(OMX_U32 /* portIndex */) {          }          if (mEndOfInput) { -            if (outputDelayRingBufferSamplesAvailable() > 0 -                    && outputDelayRingBufferSamplesAvailable() -                            < mStreamInfo->frameSize * mStreamInfo->numChannels) { -                ALOGE("not a complete frame of samples available"); -                mSignalledError = true; -                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); -                return; -            } - -            if (mEndOfInput && !outQueue.empty() && outputDelayRingBufferSamplesAvailable() == 0) { +            int ringBufAvail = outputDelayRingBufferSamplesAvailable(); +            if (!outQueue.empty() +                    && ringBufAvail < mStreamInfo->frameSize * mStreamInfo->numChannels) {                  if (!mEndOfOutput) { -                    // send empty block signaling EOS +                    // send partial or empty block signaling EOS                      mEndOfOutput = true;                      BufferInfo *outInfo = *outQueue.begin();                      OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; -                    if (outHeader->nOffset != 0) { -                        ALOGE("outHeader->nOffset != 0 is not handled"); -                        mSignalledError = true; -                        notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); -                        return; -                    } -                      INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(outHeader->pBuffer                              + outHeader->nOffset); -                    int32_t ns = 0; -                    outHeader->nFilledLen = 0; +                    int32_t ns = outputDelayRingBufferGetSamples(outBuffer, ringBufAvail); +                    if (ns < 0) { +                        ns = 0; +                    } +                    outHeader->nFilledLen = ns;                      outHeader->nFlags = OMX_BUFFERFLAG_EOS;                      outHeader->nTimeStamp = mBufferTimestamps.itemAt(0); @@ -994,7 +983,7 @@ void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) {              }              int32_t ns = outputDelayRingBufferGetSamples(0, avail);              if (ns != avail) { -                ALOGE("not a complete frame of samples available"); +                ALOGW("not a complete frame of samples available");                  break;              }              mOutputBufferCount++; diff --git a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp index e3fdc89..6a7b222 100644 --- a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp +++ b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp @@ -17,6 +17,7 @@  //#define LOG_NDEBUG 0  #define LOG_TAG "SoftAVCEncoder"  #include <utils/Log.h> +#include <utils/misc.h>  #include "avcenc_api.h"  #include "avcenc_int.h" @@ -25,6 +26,7 @@  #include <HardwareAPI.h>  #include <MetadataBufferType.h>  #include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/foundation/AUtils.h>  #include <media/stagefright/MediaDefs.h>  #include <media/stagefright/MediaErrors.h>  #include <media/stagefright/MetaData.h> @@ -51,31 +53,36 @@ static void InitOMXParams(T *params) {      params->nVersion.s.nStep = 0;  } +static const CodecProfileLevel kProfileLevels[] = { +    { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2  }, +}; +  typedef struct LevelConversion {      OMX_U32 omxLevel;      AVCLevel avcLevel; +    uint32_t maxMacroBlocks;  } LevelConcersion;  static LevelConversion ConversionTable[] = { -    { OMX_VIDEO_AVCLevel1,  AVC_LEVEL1_B }, -    { OMX_VIDEO_AVCLevel1b, AVC_LEVEL1   }, -    { OMX_VIDEO_AVCLevel11, AVC_LEVEL1_1 }, -    { OMX_VIDEO_AVCLevel12, AVC_LEVEL1_2 }, -    { OMX_VIDEO_AVCLevel13, AVC_LEVEL1_3 }, -    { OMX_VIDEO_AVCLevel2,  AVC_LEVEL2 }, +    { OMX_VIDEO_AVCLevel1,  AVC_LEVEL1_B, 99 }, +    { OMX_VIDEO_AVCLevel1b, AVC_LEVEL1,   99 }, +    { OMX_VIDEO_AVCLevel11, AVC_LEVEL1_1, 396 }, +    { OMX_VIDEO_AVCLevel12, AVC_LEVEL1_2, 396 }, +    { OMX_VIDEO_AVCLevel13, AVC_LEVEL1_3, 396 }, +    { OMX_VIDEO_AVCLevel2,  AVC_LEVEL2,   396 },  #if 0 -    // encoding speed is very poor if video -    // resolution is higher than CIF -    { OMX_VIDEO_AVCLevel21, AVC_LEVEL2_1 }, -    { OMX_VIDEO_AVCLevel22, AVC_LEVEL2_2 }, -    { OMX_VIDEO_AVCLevel3,  AVC_LEVEL3   }, -    { OMX_VIDEO_AVCLevel31, AVC_LEVEL3_1 }, -    { OMX_VIDEO_AVCLevel32, AVC_LEVEL3_2 }, -    { OMX_VIDEO_AVCLevel4,  AVC_LEVEL4   }, -    { OMX_VIDEO_AVCLevel41, AVC_LEVEL4_1 }, -    { OMX_VIDEO_AVCLevel42, AVC_LEVEL4_2 }, -    { OMX_VIDEO_AVCLevel5,  AVC_LEVEL5   }, -    { OMX_VIDEO_AVCLevel51, AVC_LEVEL5_1 }, +    // encoding speed is very poor if video resolution +    // is higher than CIF or if level is higher than 2 +    { OMX_VIDEO_AVCLevel21, AVC_LEVEL2_1, 792 }, +    { OMX_VIDEO_AVCLevel22, AVC_LEVEL2_2, 1620 }, +    { OMX_VIDEO_AVCLevel3,  AVC_LEVEL3,   1620 }, +    { OMX_VIDEO_AVCLevel31, AVC_LEVEL3_1, 3600 }, +    { OMX_VIDEO_AVCLevel32, AVC_LEVEL3_2, 5120 }, +    { OMX_VIDEO_AVCLevel4,  AVC_LEVEL4,   8192 }, +    { OMX_VIDEO_AVCLevel41, AVC_LEVEL4_1, 8192 }, +    { OMX_VIDEO_AVCLevel42, AVC_LEVEL4_2, 8704 }, +    { OMX_VIDEO_AVCLevel5,  AVC_LEVEL5,   22080 }, +    { OMX_VIDEO_AVCLevel51, AVC_LEVEL5_1, 36864 },  #endif  }; @@ -148,13 +155,11 @@ SoftAVCEncoder::SoftAVCEncoder(              const OMX_CALLBACKTYPE *callbacks,              OMX_PTR appData,              OMX_COMPONENTTYPE **component) -    : SoftVideoEncoderOMXComponent(name, callbacks, appData, component), -      mVideoWidth(176), -      mVideoHeight(144), -      mVideoFrameRate(30), -      mVideoBitRate(192000), -      mVideoColorFormat(OMX_COLOR_FormatYUV420Planar), -      mStoreMetaDataInBuffers(false), +    : SoftVideoEncoderOMXComponent( +            name, "video_encoder.avc", OMX_VIDEO_CodingAVC, +            kProfileLevels, NELEM(kProfileLevels), +            176 /* width */, 144 /* height */, +            callbacks, appData, component),        mIDRFrameRefreshIntervalInSec(1),        mAVCEncProfile(AVC_BASELINE),        mAVCEncLevel(AVC_LEVEL2), @@ -168,7 +173,13 @@ SoftAVCEncoder::SoftAVCEncoder(        mInputFrameData(NULL),        mSliceGroup(NULL) { -    initPorts(); +    const size_t kOutputBufferSize = +        320 * ConversionTable[NELEM(ConversionTable) - 1].maxMacroBlocks; + +    initPorts( +            kNumBuffers, kNumBuffers, kOutputBufferSize, +            MEDIA_MIMETYPE_VIDEO_AVC, 2 /* minCompressionRatio */); +      ALOGI("Construct SoftAVCEncoder");  } @@ -230,34 +241,32 @@ OMX_ERRORTYPE SoftAVCEncoder::initEncParams() {      mEncParams->use_overrun_buffer = AVC_OFF; -    if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar -            || mStoreMetaDataInBuffers) { +    if (mColorFormat != OMX_COLOR_FormatYUV420Planar || mInputDataIsMeta) {          // Color conversion is needed.          free(mInputFrameData); -        if (((uint64_t)mVideoWidth * mVideoHeight) > ((uint64_t)INT32_MAX / 3)) { +        if (((uint64_t)mWidth * mHeight) > ((uint64_t)INT32_MAX / 3)) {              ALOGE("Buffer size is too big.");              return OMX_ErrorUndefined;          }          mInputFrameData = -            (uint8_t *) malloc((mVideoWidth * mVideoHeight * 3 ) >> 1); +            (uint8_t *) malloc((mWidth * mHeight * 3 ) >> 1);          CHECK(mInputFrameData != NULL);      }      // PV's AVC encoder requires the video dimension of multiple -    if (mVideoWidth % 16 != 0 || mVideoHeight % 16 != 0) { +    if (mWidth % 16 != 0 || mHeight % 16 != 0) {          ALOGE("Video frame size %dx%d must be a multiple of 16", -            mVideoWidth, mVideoHeight); +            mWidth, mHeight);          return OMX_ErrorBadParameter;      } -    mEncParams->width = mVideoWidth; -    mEncParams->height = mVideoHeight; -    mEncParams->bitrate = mVideoBitRate; -    mEncParams->frame_rate = 1000 * mVideoFrameRate;  // In frames/ms! -    mEncParams->CPB_size = (uint32_t) (mVideoBitRate >> 1); +    mEncParams->width = mWidth; +    mEncParams->height = mHeight; +    mEncParams->bitrate = mBitrate; +    mEncParams->frame_rate = (1000 * mFramerate) >> 16;  // In frames/ms!, mFramerate is in Q16 +    mEncParams->CPB_size = (uint32_t) (mBitrate >> 1); -    int32_t nMacroBlocks = ((((mVideoWidth + 15) >> 4) << 4) * -            (((mVideoHeight + 15) >> 4) << 4)) >> 8; +    int32_t nMacroBlocks = divUp(mWidth, 16) * divUp(mHeight, 16);      CHECK(mSliceGroup == NULL);      if ((size_t)nMacroBlocks > SIZE_MAX / sizeof(uint32_t)) {          ALOGE("requested memory size is too big."); @@ -280,7 +289,7 @@ OMX_ERRORTYPE SoftAVCEncoder::initEncParams() {          mEncParams->idr_period = 1;  // All I frames      } else {          mEncParams->idr_period = -            (mIDRFrameRefreshIntervalInSec * mVideoFrameRate); +            (mIDRFrameRefreshIntervalInSec * mFramerate) >> 16; // mFramerate is in Q16      }      // Set profile and level @@ -353,71 +362,9 @@ void SoftAVCEncoder::releaseOutputBuffers() {      mOutputBuffers.clear();  } -void SoftAVCEncoder::initPorts() { -    OMX_PARAM_PORTDEFINITIONTYPE def; -    InitOMXParams(&def); - -    const size_t kInputBufferSize = (mVideoWidth * mVideoHeight * 3) >> 1; - -    // 31584 is PV's magic number.  Not sure why. -    const size_t kOutputBufferSize = -            (kInputBufferSize > 31584) ? kInputBufferSize: 31584; - -    def.nPortIndex = 0; -    def.eDir = OMX_DirInput; -    def.nBufferCountMin = kNumBuffers; -    def.nBufferCountActual = def.nBufferCountMin; -    def.nBufferSize = kInputBufferSize; -    def.bEnabled = OMX_TRUE; -    def.bPopulated = OMX_FALSE; -    def.eDomain = OMX_PortDomainVideo; -    def.bBuffersContiguous = OMX_FALSE; -    def.nBufferAlignment = 1; - -    def.format.video.cMIMEType = const_cast<char *>("video/raw"); -    def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; -    def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; -    def.format.video.xFramerate = (mVideoFrameRate << 16);  // Q16 format -    def.format.video.nBitrate = mVideoBitRate; -    def.format.video.nFrameWidth = mVideoWidth; -    def.format.video.nFrameHeight = mVideoHeight; -    def.format.video.nStride = mVideoWidth; -    def.format.video.nSliceHeight = mVideoHeight; - -    addPort(def); - -    def.nPortIndex = 1; -    def.eDir = OMX_DirOutput; -    def.nBufferCountMin = kNumBuffers; -    def.nBufferCountActual = def.nBufferCountMin; -    def.nBufferSize = kOutputBufferSize; -    def.bEnabled = OMX_TRUE; -    def.bPopulated = OMX_FALSE; -    def.eDomain = OMX_PortDomainVideo; -    def.bBuffersContiguous = OMX_FALSE; -    def.nBufferAlignment = 2; - -    def.format.video.cMIMEType = const_cast<char *>("video/avc"); -    def.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; -    def.format.video.eColorFormat = OMX_COLOR_FormatUnused; -    def.format.video.xFramerate = (0 << 16);  // Q16 format -    def.format.video.nBitrate = mVideoBitRate; -    def.format.video.nFrameWidth = mVideoWidth; -    def.format.video.nFrameHeight = mVideoHeight; -    def.format.video.nStride = mVideoWidth; -    def.format.video.nSliceHeight = mVideoHeight; - -    addPort(def); -} -  OMX_ERRORTYPE SoftAVCEncoder::internalGetParameter(          OMX_INDEXTYPE index, OMX_PTR params) {      switch (index) { -        case OMX_IndexParamVideoErrorCorrection: -        { -            return OMX_ErrorNotImplemented; -        } -          case OMX_IndexParamVideoBitrate:          {              OMX_VIDEO_PARAM_BITRATETYPE *bitRate = @@ -428,37 +375,7 @@ OMX_ERRORTYPE SoftAVCEncoder::internalGetParameter(              }              bitRate->eControlRate = OMX_Video_ControlRateVariable; -            bitRate->nTargetBitrate = mVideoBitRate; -            return OMX_ErrorNone; -        } - -        case OMX_IndexParamVideoPortFormat: -        { -            OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = -                (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; - -            if (formatParams->nPortIndex > 1) { -                return OMX_ErrorUndefined; -            } - -            if (formatParams->nIndex > 2) { -                return OMX_ErrorNoMore; -            } - -            if (formatParams->nPortIndex == 0) { -                formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused; -                if (formatParams->nIndex == 0) { -                    formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar; -                } else if (formatParams->nIndex == 1) { -                    formatParams->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; -                } else { -                    formatParams->eColorFormat = OMX_COLOR_FormatAndroidOpaque; -                } -            } else { -                formatParams->eCompressionFormat = OMX_VIDEO_CodingAVC; -                formatParams->eColorFormat = OMX_COLOR_FormatUnused; -            } - +            bitRate->nTargetBitrate = mBitrate;              return OMX_ErrorNone;          } @@ -495,30 +412,8 @@ OMX_ERRORTYPE SoftAVCEncoder::internalGetParameter(              return OMX_ErrorNone;          } -        case OMX_IndexParamVideoProfileLevelQuerySupported: -        { -            OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel = -                (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)params; - -            if (profileLevel->nPortIndex != 1) { -                return OMX_ErrorUndefined; -            } - -            const size_t size = -                    sizeof(ConversionTable) / sizeof(ConversionTable[0]); - -            if (profileLevel->nProfileIndex >= size) { -                return OMX_ErrorNoMore; -            } - -            profileLevel->eProfile = OMX_VIDEO_AVCProfileBaseline; -            profileLevel->eLevel = ConversionTable[profileLevel->nProfileIndex].omxLevel; - -            return OMX_ErrorNone; -        } -          default: -            return SimpleSoftOMXComponent::internalGetParameter(index, params); +            return SoftVideoEncoderOMXComponent::internalGetParameter(index, params);      }  } @@ -527,11 +422,6 @@ OMX_ERRORTYPE SoftAVCEncoder::internalSetParameter(      int32_t indexFull = index;      switch (indexFull) { -        case OMX_IndexParamVideoErrorCorrection: -        { -            return OMX_ErrorNotImplemented; -        } -          case OMX_IndexParamVideoBitrate:          {              OMX_VIDEO_PARAM_BITRATETYPE *bitRate = @@ -542,105 +432,7 @@ OMX_ERRORTYPE SoftAVCEncoder::internalSetParameter(                  return OMX_ErrorUndefined;              } -            mVideoBitRate = bitRate->nTargetBitrate; -            return OMX_ErrorNone; -        } - -        case OMX_IndexParamPortDefinition: -        { -            OMX_PARAM_PORTDEFINITIONTYPE *def = -                (OMX_PARAM_PORTDEFINITIONTYPE *)params; -            if (def->nPortIndex > 1) { -                return OMX_ErrorUndefined; -            } - -            if (def->nPortIndex == 0) { -                if (def->format.video.eCompressionFormat != OMX_VIDEO_CodingUnused || -                    (def->format.video.eColorFormat != OMX_COLOR_FormatYUV420Planar && -                     def->format.video.eColorFormat != OMX_COLOR_FormatYUV420SemiPlanar && -                     def->format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque)) { -                    return OMX_ErrorUndefined; -                } -            } else { -                if (def->format.video.eCompressionFormat != OMX_VIDEO_CodingAVC || -                    (def->format.video.eColorFormat != OMX_COLOR_FormatUnused)) { -                    return OMX_ErrorUndefined; -                } -            } - -            OMX_ERRORTYPE err = SimpleSoftOMXComponent::internalSetParameter(index, params); -            if (OMX_ErrorNone != err) { -                return err; -            } - -            if (def->nPortIndex == 0) { -                mVideoWidth = def->format.video.nFrameWidth; -                mVideoHeight = def->format.video.nFrameHeight; -                mVideoFrameRate = def->format.video.xFramerate >> 16; -                mVideoColorFormat = def->format.video.eColorFormat; - -                OMX_PARAM_PORTDEFINITIONTYPE *portDef = -                    &editPortInfo(0)->mDef; -                portDef->format.video.nFrameWidth = mVideoWidth; -                portDef->format.video.nFrameHeight = mVideoHeight; -                portDef->format.video.xFramerate = def->format.video.xFramerate; -                portDef->format.video.eColorFormat = -                    (OMX_COLOR_FORMATTYPE) mVideoColorFormat; -                portDef = &editPortInfo(1)->mDef; -                portDef->format.video.nFrameWidth = mVideoWidth; -                portDef->format.video.nFrameHeight = mVideoHeight; -            } else { -                mVideoBitRate = def->format.video.nBitrate; -            } - -            return OMX_ErrorNone; -        } - -        case OMX_IndexParamStandardComponentRole: -        { -            const OMX_PARAM_COMPONENTROLETYPE *roleParams = -                (const OMX_PARAM_COMPONENTROLETYPE *)params; - -            if (strncmp((const char *)roleParams->cRole, -                        "video_encoder.avc", -                        OMX_MAX_STRINGNAME_SIZE - 1)) { -                return OMX_ErrorUndefined; -            } - -            return OMX_ErrorNone; -        } - -        case OMX_IndexParamVideoPortFormat: -        { -            const OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = -                (const OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; - -            if (formatParams->nPortIndex > 1) { -                return OMX_ErrorUndefined; -            } - -            if (formatParams->nIndex > 2) { -                return OMX_ErrorNoMore; -            } - -            if (formatParams->nPortIndex == 0) { -                if (formatParams->eCompressionFormat != OMX_VIDEO_CodingUnused || -                    ((formatParams->nIndex == 0 && -                      formatParams->eColorFormat != OMX_COLOR_FormatYUV420Planar) || -                    (formatParams->nIndex == 1 && -                     formatParams->eColorFormat != OMX_COLOR_FormatYUV420SemiPlanar) || -                    (formatParams->nIndex == 2 && -                     formatParams->eColorFormat != OMX_COLOR_FormatAndroidOpaque) )) { -                    return OMX_ErrorUndefined; -                } -                mVideoColorFormat = formatParams->eColorFormat; -            } else { -                if (formatParams->eCompressionFormat != OMX_VIDEO_CodingAVC || -                    formatParams->eColorFormat != OMX_COLOR_FormatUnused) { -                    return OMX_ErrorUndefined; -                } -            } - +            mBitrate = bitRate->nTargetBitrate;              return OMX_ErrorNone;          } @@ -677,29 +469,8 @@ OMX_ERRORTYPE SoftAVCEncoder::internalSetParameter(              return OMX_ErrorNone;          } -        case kStoreMetaDataExtensionIndex: -        { -            StoreMetaDataInBuffersParams *storeParams = -                    (StoreMetaDataInBuffersParams*)params; -            if (storeParams->nPortIndex != 0) { -                ALOGE("%s: StoreMetadataInBuffersParams.nPortIndex not zero!", -                        __FUNCTION__); -                return OMX_ErrorUndefined; -            } - -            mStoreMetaDataInBuffers = storeParams->bStoreMetaData; -            ALOGV("StoreMetaDataInBuffers set to: %s", -                    mStoreMetaDataInBuffers ? " true" : "false"); - -            if (mStoreMetaDataInBuffers) { -                mVideoColorFormat = OMX_COLOR_FormatAndroidOpaque; -            } - -            return OMX_ErrorNone; -        } -          default: -            return SimpleSoftOMXComponent::internalSetParameter(index, params); +            return SoftVideoEncoderOMXComponent::internalSetParameter(index, params);      }  } @@ -793,11 +564,11 @@ void SoftAVCEncoder::onQueueFilled(OMX_U32 /* portIndex */) {              if (inHeader->nFilledLen > 0) {                  AVCFrameIO videoInput;                  memset(&videoInput, 0, sizeof(videoInput)); -                videoInput.height = ((mVideoHeight  + 15) >> 4) << 4; -                videoInput.pitch = ((mVideoWidth + 15) >> 4) << 4; +                videoInput.height = align(mHeight, 16); +                videoInput.pitch = align(mWidth, 16);                  videoInput.coding_timestamp = (inHeader->nTimeStamp + 500) / 1000;  // in ms                  const uint8_t *inputData = NULL; -                if (mStoreMetaDataInBuffers) { +                if (mInputDataIsMeta) {                      if (inHeader->nFilledLen != 8) {                          ALOGE("MetaData buffer is wrong size! "                                  "(got %u bytes, expected 8)", inHeader->nFilledLen); @@ -807,9 +578,9 @@ void SoftAVCEncoder::onQueueFilled(OMX_U32 /* portIndex */) {                      }                      inputData =                          extractGraphicBuffer( -                                mInputFrameData, (mVideoWidth * mVideoHeight * 3) >> 1, +                                mInputFrameData, (mWidth * mHeight * 3) >> 1,                                  inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen, -                                mVideoWidth, mVideoHeight); +                                mWidth, mHeight);                      if (inputData == NULL) {                          ALOGE("Unable to extract gralloc buffer in metadata mode");                          mSignalledError = true; @@ -819,9 +590,9 @@ void SoftAVCEncoder::onQueueFilled(OMX_U32 /* portIndex */) {                      // TODO: Verify/convert pixel format enum                  } else {                      inputData = (const uint8_t *)inHeader->pBuffer + inHeader->nOffset; -                    if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar) { +                    if (mColorFormat != OMX_COLOR_FormatYUV420Planar) {                          ConvertYUV420SemiPlanarToYUV420Planar( -                            inputData, mInputFrameData, mVideoWidth, mVideoHeight); +                            inputData, mInputFrameData, mWidth, mHeight);                          inputData = mInputFrameData;                      }                  } diff --git a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.h b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.h index 130593f..f31c1f4 100644 --- a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.h +++ b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.h @@ -68,12 +68,6 @@ private:          int32_t mFlags;      } InputBufferInfo; -    int32_t  mVideoWidth; -    int32_t  mVideoHeight; -    int32_t  mVideoFrameRate; -    int32_t  mVideoBitRate; -    int32_t  mVideoColorFormat; -    bool     mStoreMetaDataInBuffers;      int32_t  mIDRFrameRefreshIntervalInSec;      AVCProfile mAVCEncProfile;      AVCLevel   mAVCEncLevel; @@ -94,7 +88,6 @@ private:      Vector<MediaBuffer *> mOutputBuffers;      Vector<InputBufferInfo> mInputBufferInfoVec; -    void initPorts();      OMX_ERRORTYPE initEncParams();      OMX_ERRORTYPE initEncoder();      OMX_ERRORTYPE releaseEncoder(); diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp index f4cba54..cddd176 100644 --- a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp +++ b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp @@ -26,6 +26,7 @@  #include "SoftHEVC.h"  #include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/foundation/AUtils.h>  #include <media/stagefright/MediaDefs.h>  #include <OMX_VideoExt.h> @@ -75,8 +76,12 @@ SoftHEVC::SoftHEVC(        mNewWidth(mWidth),        mNewHeight(mHeight),        mChangingResolution(false) { -    initPorts(kNumBuffers, INPUT_BUF_SIZE, kNumBuffers, -            CODEC_MIME_TYPE); +    const size_t kMinCompressionRatio = 4 /* compressionRatio (for Level 4+) */; +    const size_t kMaxOutputBufferSize = 2048 * 2048 * 3 / 2; +    // INPUT_BUF_SIZE is given by HEVC codec as minimum input size +    initPorts( +            kNumBuffers, max(kMaxOutputBufferSize / kMinCompressionRatio, (size_t)INPUT_BUF_SIZE), +            kNumBuffers, CODEC_MIME_TYPE, kMinCompressionRatio);      CHECK_EQ(initDecoder(), (status_t)OK);  } @@ -644,7 +649,7 @@ void SoftHEVC::onQueueFilled(OMX_U32 portIndex) {              // The decoder should be fixed so that |u4_error_code| instead of |status| returns              // IHEVCD_UNSUPPORTED_DIMENSIONS.              bool unsupportedDimensions = -                ((IHEVCD_UNSUPPORTED_DIMENSIONS == status) +                ((IHEVCD_UNSUPPORTED_DIMENSIONS == (IHEVCD_CXA_ERROR_CODES_T)status)                      || (IHEVCD_UNSUPPORTED_DIMENSIONS == s_dec_op.u4_error_code));              bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & 0xFF)); diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp index 1f4b6fd..ede645c 100644 --- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp +++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp @@ -21,6 +21,7 @@  #include "SoftMPEG4.h"  #include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/foundation/AUtils.h>  #include <media/stagefright/MediaDefs.h>  #include <media/stagefright/MediaErrors.h>  #include <media/IOMX.h> @@ -70,7 +71,7 @@ SoftMPEG4::SoftMPEG4(        mPvTime(0) {      initPorts(              kNumInputBuffers, -            8192 /* inputBufferSize */, +            352 * 288 * 3 / 2 /* minInputBufferSize */,              kNumOutputBuffers,              (mMode == MODE_MPEG4)              ? MEDIA_MIMETYPE_VIDEO_MPEG4 : MEDIA_MIMETYPE_VIDEO_H263); @@ -353,14 +354,14 @@ void SoftMPEG4::onReset() {      }  } -void SoftMPEG4::updatePortDefinitions() { -    SoftVideoDecoderOMXComponent::updatePortDefinitions(); +void SoftMPEG4::updatePortDefinitions(bool updateCrop, bool updateInputSize) { +    SoftVideoDecoderOMXComponent::updatePortDefinitions(updateCrop, updateInputSize);      /* We have to align our width and height - this should affect stride! */      OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kOutputPortIndex)->mDef; -    def->nBufferSize = -        (((def->format.video.nFrameWidth + 15) & -16) -            * ((def->format.video.nFrameHeight + 15) & -16) * 3) / 2; +    def->format.video.nStride = align(def->format.video.nStride, 16); +    def->format.video.nSliceHeight = align(def->format.video.nSliceHeight, 16); +    def->nBufferSize = (def->format.video.nStride * def->format.video.nSliceHeight * 3) / 2;  }  }  // namespace android @@ -382,5 +383,6 @@ android::SoftOMXComponent *createSoftOMXComponent(      } else {          CHECK(!"Unknown component");      } +    return NULL;  } diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h index 8a06a00..4114e7d 100644 --- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h +++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.h @@ -66,7 +66,7 @@ private:      status_t initDecoder(); -    virtual void updatePortDefinitions(); +    virtual void updatePortDefinitions(bool updateCrop = true, bool updateInputSize = false);      bool handlePortSettingsChange();      DISALLOW_EVIL_CONSTRUCTORS(SoftMPEG4); diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp index 30d5cbd..c1720c6 100644 --- a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp +++ b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp @@ -265,10 +265,13 @@ OSCL_EXPORT_REF Bool PVInitVideoDecoder(VideoDecControls *decCtrl, uint8 *volbuf                          video->vol[idx]->useReverseVLC = 0;                          video->intra_acdcPredDisable = 1;                          video->vol[idx]->scalability = 0; -                        video->size = (int32)width * height; -                        video->displayWidth = video->width = width; -                        video->displayHeight = video->height = height; +                        video->displayWidth = width; +                        video->displayHeight = height; +                        video->width = (width + 15) & -16; +                        video->height = (height + 15) & -16; +                        video->size = (int32)video->width * video->height; +  #ifdef PV_ANNEX_IJKT_SUPPORT                          video->modified_quant = 0;                          video->advanced_INTRA = 0; @@ -308,8 +311,10 @@ Bool PVAllocVideoData(VideoDecControls *decCtrl, int width, int height, int nLay      if (video->shortVideoHeader == PV_TRUE)      { -        video->displayWidth = video->width = width; -        video->displayHeight = video->height = height; +        video->displayWidth = width; +        video->displayHeight = height; +        video->width = (width + 15) & -16; +        video->height = (height + 15) & -16;          video->nMBPerRow =              video->nMBinGOB  = video->width / MB_SIZE; diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp index b03ec8c..60c79a6 100644 --- a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp +++ b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp @@ -118,6 +118,10 @@ PV_STATUS DecodeVOLHeader(VideoDecData *video, int layer)          {              /* support SPL0-3 & SSPL0-2   */              if (tmpvar != 0x01 && tmpvar != 0x02 && tmpvar != 0x03 && tmpvar != 0x08 && +                    /* While not technically supported, try to decode SPL4&SPL5 files as well. */ +                    /* We'll fail later if the size is too large.  This is to allow playback of */ +                    /* some <=CIF files generated by other encoders. */ +                    tmpvar != 0x04 && tmpvar != 0x05 &&                      tmpvar != 0x10 && tmpvar != 0x11 && tmpvar != 0x12 &&                      tmpvar != 0x21 && tmpvar != 0x22 &&  /* Core Profile Levels */                      tmpvar != 0xA1 && tmpvar != 0xA2 && tmpvar != 0xA3 && diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp index c87d19c..fa3486c 100644 --- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp +++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp @@ -17,6 +17,7 @@  //#define LOG_NDEBUG 0  #define LOG_TAG "SoftMPEG4Encoder"  #include <utils/Log.h> +#include <utils/misc.h>  #include "mp4enc_api.h"  #include "OMX_Video.h" @@ -24,6 +25,7 @@  #include <HardwareAPI.h>  #include <MetadataBufferType.h>  #include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/foundation/AUtils.h>  #include <media/stagefright/MediaDefs.h>  #include <media/stagefright/MediaErrors.h>  #include <media/stagefright/MetaData.h> @@ -46,19 +48,30 @@ static void InitOMXParams(T *params) {      params->nVersion.s.nStep = 0;  } +static const CodecProfileLevel kMPEG4ProfileLevels[] = { +    { OMX_VIDEO_MPEG4ProfileCore, OMX_VIDEO_MPEG4Level2 }, +}; + +static const CodecProfileLevel kH263ProfileLevels[] = { +    { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45 }, +}; +  SoftMPEG4Encoder::SoftMPEG4Encoder(              const char *name, +            const char *componentRole, +            OMX_VIDEO_CODINGTYPE codingType, +            const char *mime, +            const CodecProfileLevel *profileLevels, +            size_t numProfileLevels,              const OMX_CALLBACKTYPE *callbacks,              OMX_PTR appData,              OMX_COMPONENTTYPE **component) -    : SoftVideoEncoderOMXComponent(name, callbacks, appData, component), +    : SoftVideoEncoderOMXComponent( +            name, componentRole, codingType, +            profileLevels, numProfileLevels, +            176 /* width */, 144 /* height */, +            callbacks, appData, component),        mEncodeMode(COMBINE_MODE_WITH_ERR_RES), -      mVideoWidth(176), -      mVideoHeight(144), -      mVideoFrameRate(30), -      mVideoBitRate(192000), -      mVideoColorFormat(OMX_COLOR_FormatYUV420Planar), -      mStoreMetaDataInBuffers(false),        mIDRFrameRefreshIntervalInSec(1),        mNumInputFrames(-1),        mStarted(false), @@ -68,13 +81,15 @@ SoftMPEG4Encoder::SoftMPEG4Encoder(        mEncParams(new tagvideoEncOptions),        mInputFrameData(NULL) { -   if (!strcmp(name, "OMX.google.h263.encoder")) { +    if (codingType == OMX_VIDEO_CodingH263) {          mEncodeMode = H263_MODE; -    } else { -        CHECK(!strcmp(name, "OMX.google.mpeg4.encoder"));      } -    initPorts(); +    // 256 * 1024 is a magic number for PV's encoder, not sure why +    const size_t kOutputBufferSize = 256 * 1024; + +    initPorts(kNumBuffers, kNumBuffers, kOutputBufferSize, mime); +      ALOGI("Construct SoftMPEG4Encoder");  } @@ -98,9 +113,9 @@ OMX_ERRORTYPE SoftMPEG4Encoder::initEncParams() {          return OMX_ErrorUndefined;      }      mEncParams->encMode = mEncodeMode; -    mEncParams->encWidth[0] = mVideoWidth; -    mEncParams->encHeight[0] = mVideoHeight; -    mEncParams->encFrameRate[0] = mVideoFrameRate; +    mEncParams->encWidth[0] = mWidth; +    mEncParams->encHeight[0] = mHeight; +    mEncParams->encFrameRate[0] = mFramerate >> 16; // mFramerate is in Q16 format      mEncParams->rcType = VBR_1;      mEncParams->vbvDelay = 5.0f; @@ -111,27 +126,26 @@ OMX_ERRORTYPE SoftMPEG4Encoder::initEncParams() {      mEncParams->rvlcEnable = PV_OFF;      mEncParams->numLayers = 1;      mEncParams->timeIncRes = 1000; -    mEncParams->tickPerSrc = mEncParams->timeIncRes / mVideoFrameRate; +    mEncParams->tickPerSrc = ((int64_t)mEncParams->timeIncRes << 16) / mFramerate; -    mEncParams->bitRate[0] = mVideoBitRate; +    mEncParams->bitRate[0] = mBitrate;      mEncParams->iQuant[0] = 15;      mEncParams->pQuant[0] = 12;      mEncParams->quantType[0] = 0;      mEncParams->noFrameSkipped = PV_OFF; -    if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar -            || mStoreMetaDataInBuffers) { +    if (mColorFormat != OMX_COLOR_FormatYUV420Planar || mInputDataIsMeta) {          // Color conversion is needed.          free(mInputFrameData);          mInputFrameData = -            (uint8_t *) malloc((mVideoWidth * mVideoHeight * 3 ) >> 1); +            (uint8_t *) malloc((mWidth * mHeight * 3 ) >> 1);          CHECK(mInputFrameData != NULL);      }      // PV's MPEG4 encoder requires the video dimension of multiple -    if (mVideoWidth % 16 != 0 || mVideoHeight % 16 != 0) { +    if (mWidth % 16 != 0 || mHeight % 16 != 0) {          ALOGE("Video frame size %dx%d must be a multiple of 16", -            mVideoWidth, mVideoHeight); +            mWidth, mHeight);          return OMX_ErrorBadParameter;      } @@ -142,7 +156,7 @@ OMX_ERRORTYPE SoftMPEG4Encoder::initEncParams() {          mEncParams->intraPeriod = 1;  // All I frames      } else {          mEncParams->intraPeriod = -            (mIDRFrameRefreshIntervalInSec * mVideoFrameRate); +            (mIDRFrameRefreshIntervalInSec * mFramerate) >> 16;      }      mEncParams->numIntraMB = 0; @@ -201,81 +215,9 @@ OMX_ERRORTYPE SoftMPEG4Encoder::releaseEncoder() {      return OMX_ErrorNone;  } -void SoftMPEG4Encoder::initPorts() { -    OMX_PARAM_PORTDEFINITIONTYPE def; -    InitOMXParams(&def); - -    const size_t kInputBufferSize = (mVideoWidth * mVideoHeight * 3) >> 1; - -    // 256 * 1024 is a magic number for PV's encoder, not sure why -    const size_t kOutputBufferSize = -        (kInputBufferSize > 256 * 1024) -            ? kInputBufferSize: 256 * 1024; - -    def.nPortIndex = 0; -    def.eDir = OMX_DirInput; -    def.nBufferCountMin = kNumBuffers; -    def.nBufferCountActual = def.nBufferCountMin; -    def.nBufferSize = kInputBufferSize; -    def.bEnabled = OMX_TRUE; -    def.bPopulated = OMX_FALSE; -    def.eDomain = OMX_PortDomainVideo; -    def.bBuffersContiguous = OMX_FALSE; -    def.nBufferAlignment = 1; - -    def.format.video.cMIMEType = const_cast<char *>("video/raw"); - -    def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; -    def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; -    def.format.video.xFramerate = (mVideoFrameRate << 16);  // Q16 format -    def.format.video.nBitrate = mVideoBitRate; -    def.format.video.nFrameWidth = mVideoWidth; -    def.format.video.nFrameHeight = mVideoHeight; -    def.format.video.nStride = mVideoWidth; -    def.format.video.nSliceHeight = mVideoHeight; - -    addPort(def); - -    def.nPortIndex = 1; -    def.eDir = OMX_DirOutput; -    def.nBufferCountMin = kNumBuffers; -    def.nBufferCountActual = def.nBufferCountMin; -    def.nBufferSize = kOutputBufferSize; -    def.bEnabled = OMX_TRUE; -    def.bPopulated = OMX_FALSE; -    def.eDomain = OMX_PortDomainVideo; -    def.bBuffersContiguous = OMX_FALSE; -    def.nBufferAlignment = 2; - -    def.format.video.cMIMEType = -        (mEncodeMode == COMBINE_MODE_WITH_ERR_RES) -            ? const_cast<char *>(MEDIA_MIMETYPE_VIDEO_MPEG4) -            : const_cast<char *>(MEDIA_MIMETYPE_VIDEO_H263); - -    def.format.video.eCompressionFormat = -        (mEncodeMode == COMBINE_MODE_WITH_ERR_RES) -            ? OMX_VIDEO_CodingMPEG4 -            : OMX_VIDEO_CodingH263; - -    def.format.video.eColorFormat = OMX_COLOR_FormatUnused; -    def.format.video.xFramerate = (0 << 16);  // Q16 format -    def.format.video.nBitrate = mVideoBitRate; -    def.format.video.nFrameWidth = mVideoWidth; -    def.format.video.nFrameHeight = mVideoHeight; -    def.format.video.nStride = mVideoWidth; -    def.format.video.nSliceHeight = mVideoHeight; - -    addPort(def); -} -  OMX_ERRORTYPE SoftMPEG4Encoder::internalGetParameter(          OMX_INDEXTYPE index, OMX_PTR params) {      switch (index) { -        case OMX_IndexParamVideoErrorCorrection: -        { -            return OMX_ErrorNotImplemented; -        } -          case OMX_IndexParamVideoBitrate:          {              OMX_VIDEO_PARAM_BITRATETYPE *bitRate = @@ -286,41 +228,7 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalGetParameter(              }              bitRate->eControlRate = OMX_Video_ControlRateVariable; -            bitRate->nTargetBitrate = mVideoBitRate; -            return OMX_ErrorNone; -        } - -        case OMX_IndexParamVideoPortFormat: -        { -            OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = -                (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; - -            if (formatParams->nPortIndex > 1) { -                return OMX_ErrorUndefined; -            } - -            if (formatParams->nIndex > 2) { -                return OMX_ErrorNoMore; -            } - -            if (formatParams->nPortIndex == 0) { -                formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused; -                if (formatParams->nIndex == 0) { -                    formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar; -                } else if (formatParams->nIndex == 1) { -                    formatParams->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; -                } else { -                    formatParams->eColorFormat = OMX_COLOR_FormatAndroidOpaque; -                } -            } else { -                formatParams->eCompressionFormat = -                    (mEncodeMode == COMBINE_MODE_WITH_ERR_RES) -                        ? OMX_VIDEO_CodingMPEG4 -                        : OMX_VIDEO_CodingH263; - -                formatParams->eColorFormat = OMX_COLOR_FormatUnused; -            } - +            bitRate->nTargetBitrate = mBitrate;              return OMX_ErrorNone;          } @@ -369,32 +277,8 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalGetParameter(              return OMX_ErrorNone;          } -        case OMX_IndexParamVideoProfileLevelQuerySupported: -        { -            OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel = -                (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)params; - -            if (profileLevel->nPortIndex != 1) { -                return OMX_ErrorUndefined; -            } - -            if (profileLevel->nProfileIndex > 0) { -                return OMX_ErrorNoMore; -            } - -            if (mEncodeMode == H263_MODE) { -                profileLevel->eProfile = OMX_VIDEO_H263ProfileBaseline; -                profileLevel->eLevel = OMX_VIDEO_H263Level45; -            } else { -                profileLevel->eProfile = OMX_VIDEO_MPEG4ProfileCore; -                profileLevel->eLevel = OMX_VIDEO_MPEG4Level2; -            } - -            return OMX_ErrorNone; -        } -          default: -            return SimpleSoftOMXComponent::internalGetParameter(index, params); +            return SoftVideoEncoderOMXComponent::internalGetParameter(index, params);      }  } @@ -403,11 +287,6 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalSetParameter(      int32_t indexFull = index;      switch (indexFull) { -        case OMX_IndexParamVideoErrorCorrection: -        { -            return OMX_ErrorNotImplemented; -        } -          case OMX_IndexParamVideoBitrate:          {              OMX_VIDEO_PARAM_BITRATETYPE *bitRate = @@ -418,112 +297,7 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalSetParameter(                  return OMX_ErrorUndefined;              } -            mVideoBitRate = bitRate->nTargetBitrate; -            return OMX_ErrorNone; -        } - -        case OMX_IndexParamPortDefinition: -        { -            OMX_PARAM_PORTDEFINITIONTYPE *def = -                (OMX_PARAM_PORTDEFINITIONTYPE *)params; -            if (def->nPortIndex > 1) { -                return OMX_ErrorUndefined; -            } - -            if (def->nPortIndex == 0) { -                if (def->format.video.eCompressionFormat != OMX_VIDEO_CodingUnused || -                    (def->format.video.eColorFormat != OMX_COLOR_FormatYUV420Planar && -                     def->format.video.eColorFormat != OMX_COLOR_FormatYUV420SemiPlanar && -                     def->format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque)) { -                    return OMX_ErrorUndefined; -                } -            } else { -                if ((mEncodeMode == COMBINE_MODE_WITH_ERR_RES && -                        def->format.video.eCompressionFormat != OMX_VIDEO_CodingMPEG4) || -                    (mEncodeMode == H263_MODE && -                        def->format.video.eCompressionFormat != OMX_VIDEO_CodingH263) || -                    (def->format.video.eColorFormat != OMX_COLOR_FormatUnused)) { -                    return OMX_ErrorUndefined; -                } -            } - -            OMX_ERRORTYPE err = SimpleSoftOMXComponent::internalSetParameter(index, params); -            if (OMX_ErrorNone != err) { -                return err; -            } - -            if (def->nPortIndex == 0) { -                mVideoWidth = def->format.video.nFrameWidth; -                mVideoHeight = def->format.video.nFrameHeight; -                mVideoFrameRate = def->format.video.xFramerate >> 16; -                mVideoColorFormat = def->format.video.eColorFormat; - -                OMX_PARAM_PORTDEFINITIONTYPE *portDef = -                    &editPortInfo(0)->mDef; -                portDef->format.video.nFrameWidth = mVideoWidth; -                portDef->format.video.nFrameHeight = mVideoHeight; -                portDef->format.video.xFramerate = def->format.video.xFramerate; -                portDef->format.video.eColorFormat = -                    (OMX_COLOR_FORMATTYPE) mVideoColorFormat; -                portDef = &editPortInfo(1)->mDef; -                portDef->format.video.nFrameWidth = mVideoWidth; -                portDef->format.video.nFrameHeight = mVideoHeight; -            } else { -                mVideoBitRate = def->format.video.nBitrate; -            } - -            return OMX_ErrorNone; -        } - -        case OMX_IndexParamStandardComponentRole: -        { -            const OMX_PARAM_COMPONENTROLETYPE *roleParams = -                (const OMX_PARAM_COMPONENTROLETYPE *)params; - -            if (strncmp((const char *)roleParams->cRole, -                        (mEncodeMode == H263_MODE) -                            ? "video_encoder.h263": "video_encoder.mpeg4", -                        OMX_MAX_STRINGNAME_SIZE - 1)) { -                return OMX_ErrorUndefined; -            } - -            return OMX_ErrorNone; -        } - -        case OMX_IndexParamVideoPortFormat: -        { -            const OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = -                (const OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; - -            if (formatParams->nPortIndex > 1) { -                return OMX_ErrorUndefined; -            } - -            if (formatParams->nIndex > 2) { -                return OMX_ErrorNoMore; -            } - -            if (formatParams->nPortIndex == 0) { -                if (formatParams->eCompressionFormat != OMX_VIDEO_CodingUnused || -                    ((formatParams->nIndex == 0 && -                      formatParams->eColorFormat != OMX_COLOR_FormatYUV420Planar) || -                    (formatParams->nIndex == 1 && -                     formatParams->eColorFormat != OMX_COLOR_FormatYUV420SemiPlanar) || -                    (formatParams->nIndex == 2 && -                     formatParams->eColorFormat != OMX_COLOR_FormatAndroidOpaque) )) { -                    return OMX_ErrorUndefined; -                } -                mVideoColorFormat = formatParams->eColorFormat; -            } else { -                if ((mEncodeMode == H263_MODE && -                        formatParams->eCompressionFormat != OMX_VIDEO_CodingH263) || -                    (mEncodeMode == COMBINE_MODE_WITH_ERR_RES && -                        formatParams->eCompressionFormat != OMX_VIDEO_CodingMPEG4) || -                    formatParams->eColorFormat != OMX_COLOR_FormatUnused) { -                    return OMX_ErrorUndefined; -                } -            } - +            mBitrate = bitRate->nTargetBitrate;              return OMX_ErrorNone;          } @@ -574,29 +348,8 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalSetParameter(              return OMX_ErrorNone;          } -        case kStoreMetaDataExtensionIndex: -        { -            StoreMetaDataInBuffersParams *storeParams = -                    (StoreMetaDataInBuffersParams*)params; -            if (storeParams->nPortIndex != 0) { -                ALOGE("%s: StoreMetadataInBuffersParams.nPortIndex not zero!", -                        __FUNCTION__); -                return OMX_ErrorUndefined; -            } - -            mStoreMetaDataInBuffers = storeParams->bStoreMetaData; -            ALOGV("StoreMetaDataInBuffers set to: %s", -                    mStoreMetaDataInBuffers ? " true" : "false"); - -            if (mStoreMetaDataInBuffers) { -                mVideoColorFormat = OMX_COLOR_FormatAndroidOpaque; -            } - -            return OMX_ErrorNone; -        } -          default: -            return SimpleSoftOMXComponent::internalSetParameter(index, params); +            return SoftVideoEncoderOMXComponent::internalSetParameter(index, params);      }  } @@ -659,7 +412,7 @@ void SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) {          if (inHeader->nFilledLen > 0) {              const uint8_t *inputData = NULL; -            if (mStoreMetaDataInBuffers) { +            if (mInputDataIsMeta) {                  if (inHeader->nFilledLen != 8) {                      ALOGE("MetaData buffer is wrong size! "                              "(got %u bytes, expected 8)", inHeader->nFilledLen); @@ -669,9 +422,9 @@ void SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) {                  }                  inputData =                      extractGraphicBuffer( -                            mInputFrameData, (mVideoWidth * mVideoHeight * 3) >> 1, +                            mInputFrameData, (mWidth * mHeight * 3) >> 1,                              inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen, -                            mVideoWidth, mVideoHeight); +                            mWidth, mHeight);                  if (inputData == NULL) {                      ALOGE("Unable to extract gralloc buffer in metadata mode");                      mSignalledError = true; @@ -680,9 +433,9 @@ void SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) {                  }              } else {                  inputData = (const uint8_t *)inHeader->pBuffer + inHeader->nOffset; -                if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar) { +                if (mColorFormat != OMX_COLOR_FormatYUV420Planar) {                      ConvertYUV420SemiPlanarToYUV420Planar( -                        inputData, mInputFrameData, mVideoWidth, mVideoHeight); +                        inputData, mInputFrameData, mWidth, mHeight);                      inputData = mInputFrameData;                  }              } @@ -692,8 +445,8 @@ void SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) {              VideoEncFrameIO vin, vout;              memset(&vin, 0, sizeof(vin));              memset(&vout, 0, sizeof(vout)); -            vin.height = ((mVideoHeight  + 15) >> 4) << 4; -            vin.pitch = ((mVideoWidth + 15) >> 4) << 4; +            vin.height = align(mHeight, 16); +            vin.pitch = align(mWidth, 16);              vin.timestamp = (inHeader->nTimeStamp + 500) / 1000;  // in ms              vin.yChan = (uint8_t *)inputData;              vin.uChan = vin.yChan + vin.height * vin.pitch; @@ -741,5 +494,19 @@ void SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) {  android::SoftOMXComponent *createSoftOMXComponent(          const char *name, const OMX_CALLBACKTYPE *callbacks,          OMX_PTR appData, OMX_COMPONENTTYPE **component) { -    return new android::SoftMPEG4Encoder(name, callbacks, appData, component); +    using namespace android; +    if (!strcmp(name, "OMX.google.h263.encoder")) { +        return new android::SoftMPEG4Encoder( +                name, "video_encoder.h263", OMX_VIDEO_CodingH263, MEDIA_MIMETYPE_VIDEO_H263, +                kH263ProfileLevels, NELEM(kH263ProfileLevels), +                callbacks, appData, component); +    } else if (!strcmp(name, "OMX.google.mpeg4.encoder")) { +        return new android::SoftMPEG4Encoder( +                name, "video_encoder.mpeg4", OMX_VIDEO_CodingMPEG4, MEDIA_MIMETYPE_VIDEO_MPEG4, +                kMPEG4ProfileLevels, NELEM(kMPEG4ProfileLevels), +                callbacks, appData, component); +    } else { +        CHECK(!"Unknown component"); +    } +    return NULL;  } diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h index b0605b4..25ecdc9 100644 --- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h +++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.h @@ -25,11 +25,17 @@  namespace android { +struct CodecProfileLevel;  struct MediaBuffer;  struct SoftMPEG4Encoder : public SoftVideoEncoderOMXComponent {      SoftMPEG4Encoder(              const char *name, +            const char *componentRole, +            OMX_VIDEO_CODINGTYPE codingType, +            const char *mime, +            const CodecProfileLevel *profileLevels, +            size_t numProfileLevels,              const OMX_CALLBACKTYPE *callbacks,              OMX_PTR appData,              OMX_COMPONENTTYPE **component); @@ -58,12 +64,6 @@ private:      } InputBufferInfo;      MP4EncodingMode mEncodeMode; -    int32_t  mVideoWidth; -    int32_t  mVideoHeight; -    int32_t  mVideoFrameRate; -    int32_t  mVideoBitRate; -    int32_t  mVideoColorFormat; -    bool     mStoreMetaDataInBuffers;      int32_t  mIDRFrameRefreshIntervalInSec;      int64_t  mNumInputFrames; @@ -76,7 +76,6 @@ private:      uint8_t               *mInputFrameData;      Vector<InputBufferInfo> mInputBufferInfoVec; -    void initPorts();      OMX_ERRORTYPE initEncParams();      OMX_ERRORTYPE initEncoder();      OMX_ERRORTYPE releaseEncoder(); diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp index 828577a..8a95643 100644 --- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp +++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp @@ -40,10 +40,13 @@ SoftVPX::SoftVPX(        mMode(codingType == OMX_VIDEO_CodingVP8 ? MODE_VP8 : MODE_VP9),        mCtx(NULL),        mImg(NULL) { -    initPorts(kNumBuffers, 768 * 1024 /* inputBufferSize */, -            kNumBuffers, -            codingType == OMX_VIDEO_CodingVP8 ? MEDIA_MIMETYPE_VIDEO_VP8 : MEDIA_MIMETYPE_VIDEO_VP9); - +    // arbitrary from avc/hevc as vpx does not specify a min compression ratio +    const size_t kMinCompressionRatio = mMode == MODE_VP8 ? 2 : 4; +    const char *mime = mMode == MODE_VP8 ? MEDIA_MIMETYPE_VIDEO_VP8 : MEDIA_MIMETYPE_VIDEO_VP9; +    const size_t kMaxOutputBufferSize = 2048 * 2048 * 3 / 2; +    initPorts( +            kNumBuffers, kMaxOutputBufferSize / kMinCompressionRatio /* inputBufferSize */, +            kNumBuffers, mime, kMinCompressionRatio);      CHECK_EQ(initDecoder(), (status_t)OK);  } @@ -189,4 +192,5 @@ android::SoftOMXComponent *createSoftOMXComponent(      } else {          CHECK(!"Unknown component");      } +    return NULL;  } diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp index eb621d5..970acf3 100644 --- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp +++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp @@ -19,6 +19,7 @@  #include "SoftVPXEncoder.h"  #include <utils/Log.h> +#include <utils/misc.h>  #include <media/hardware/HardwareAPI.h>  #include <media/hardware/MetadataBufferType.h> @@ -50,23 +51,29 @@ static int GetCPUCoreCount() {      return cpuCoreCount;  } +static const CodecProfileLevel kProfileLevels[] = { +    { OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version0 }, +    { OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version1 }, +    { OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version2 }, +    { OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version3 }, +}; +  SoftVPXEncoder::SoftVPXEncoder(const char *name,                                 const OMX_CALLBACKTYPE *callbacks,                                 OMX_PTR appData,                                 OMX_COMPONENTTYPE **component) -    : SoftVideoEncoderOMXComponent(name, callbacks, appData, component), +    : SoftVideoEncoderOMXComponent( +            name, "video_encoder.vp8", OMX_VIDEO_CodingVP8, +            kProfileLevels, NELEM(kProfileLevels), +            176 /* width */, 144 /* height */, +            callbacks, appData, component),        mCodecContext(NULL),        mCodecConfiguration(NULL),        mCodecInterface(NULL), -      mWidth(176), -      mHeight(144), -      mBitrate(192000),  // in bps -      mFramerate(30 << 16), // in Q16 format        mBitrateUpdated(false),        mBitrateControlMode(VPX_VBR),  // variable bitrate        mDCTPartitions(0),        mErrorResilience(OMX_FALSE), -      mColorFormat(OMX_COLOR_FormatYUV420Planar),        mLevel(OMX_VIDEO_VP8Level_Version0),        mKeyFrameInterval(0),        mMinQuantizer(0), @@ -77,83 +84,22 @@ SoftVPXEncoder::SoftVPXEncoder(const char *name,        mTemporalPatternIdx(0),        mLastTimestamp(0x7FFFFFFFFFFFFFFFLL),        mConversionBuffer(NULL), -      mInputDataIsMeta(false),        mKeyFrameRequested(false) {      memset(mTemporalLayerBitrateRatio, 0, sizeof(mTemporalLayerBitrateRatio));      mTemporalLayerBitrateRatio[0] = 100; -    initPorts(); -} +    const size_t kMinOutputBufferSize = 1024 * 1024; // arbitrary -SoftVPXEncoder::~SoftVPXEncoder() { -    releaseEncoder(); +    initPorts( +            kNumBuffers, kNumBuffers, kMinOutputBufferSize, +            MEDIA_MIMETYPE_VIDEO_VP8, 2 /* minCompressionRatio */);  } -void SoftVPXEncoder::initPorts() { -    OMX_PARAM_PORTDEFINITIONTYPE inputPort; -    OMX_PARAM_PORTDEFINITIONTYPE outputPort; - -    InitOMXParams(&inputPort); -    InitOMXParams(&outputPort); - -    inputPort.nBufferCountMin = kNumBuffers; -    inputPort.nBufferCountActual = inputPort.nBufferCountMin; -    inputPort.bEnabled = OMX_TRUE; -    inputPort.bPopulated = OMX_FALSE; -    inputPort.eDomain = OMX_PortDomainVideo; -    inputPort.bBuffersContiguous = OMX_FALSE; -    inputPort.format.video.pNativeRender = NULL; -    inputPort.format.video.nFrameWidth = mWidth; -    inputPort.format.video.nFrameHeight = mHeight; -    inputPort.format.video.nStride = inputPort.format.video.nFrameWidth; -    inputPort.format.video.nSliceHeight = inputPort.format.video.nFrameHeight; -    inputPort.format.video.nBitrate = 0; -    // frameRate is in Q16 format. -    inputPort.format.video.xFramerate = mFramerate; -    inputPort.format.video.bFlagErrorConcealment = OMX_FALSE; -    inputPort.nPortIndex = kInputPortIndex; -    inputPort.eDir = OMX_DirInput; -    inputPort.nBufferAlignment = kInputBufferAlignment; -    inputPort.format.video.cMIMEType = -        const_cast<char *>(MEDIA_MIMETYPE_VIDEO_RAW); -    inputPort.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; -    inputPort.format.video.eColorFormat = mColorFormat; -    inputPort.format.video.pNativeWindow = NULL; -    inputPort.nBufferSize = -        (inputPort.format.video.nStride * -        inputPort.format.video.nSliceHeight * 3) / 2; - -    addPort(inputPort); - -    outputPort.nBufferCountMin = kNumBuffers; -    outputPort.nBufferCountActual = outputPort.nBufferCountMin; -    outputPort.bEnabled = OMX_TRUE; -    outputPort.bPopulated = OMX_FALSE; -    outputPort.eDomain = OMX_PortDomainVideo; -    outputPort.bBuffersContiguous = OMX_FALSE; -    outputPort.format.video.pNativeRender = NULL; -    outputPort.format.video.nFrameWidth = mWidth; -    outputPort.format.video.nFrameHeight = mHeight; -    outputPort.format.video.nStride = outputPort.format.video.nFrameWidth; -    outputPort.format.video.nSliceHeight = outputPort.format.video.nFrameHeight; -    outputPort.format.video.nBitrate = mBitrate; -    outputPort.format.video.xFramerate = 0; -    outputPort.format.video.bFlagErrorConcealment = OMX_FALSE; -    outputPort.nPortIndex = kOutputPortIndex; -    outputPort.eDir = OMX_DirOutput; -    outputPort.nBufferAlignment = kOutputBufferAlignment; -    outputPort.format.video.cMIMEType = -        const_cast<char *>(MEDIA_MIMETYPE_VIDEO_VP8); -    outputPort.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8; -    outputPort.format.video.eColorFormat = OMX_COLOR_FormatUnused; -    outputPort.format.video.pNativeWindow = NULL; -    outputPort.nBufferSize = 1024 * 1024; // arbitrary - -    addPort(outputPort); +SoftVPXEncoder::~SoftVPXEncoder() { +    releaseEncoder();  } -  status_t SoftVPXEncoder::initEncoder() {      vpx_codec_err_t codec_return; @@ -409,38 +355,6 @@ OMX_ERRORTYPE SoftVPXEncoder::internalGetParameter(OMX_INDEXTYPE index,      const int32_t indexFull = index;      switch (indexFull) { -        case OMX_IndexParamVideoPortFormat: { -            OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = -                (OMX_VIDEO_PARAM_PORTFORMATTYPE *)param; - -            if (formatParams->nPortIndex == kInputPortIndex) { -                if (formatParams->nIndex >= kNumberOfSupportedColorFormats) { -                    return OMX_ErrorNoMore; -                } - -                // Color formats, in order of preference -                if (formatParams->nIndex == 0) { -                    formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar; -                } else if (formatParams->nIndex == 1) { -                    formatParams->eColorFormat = -                        OMX_COLOR_FormatYUV420SemiPlanar; -                } else { -                    formatParams->eColorFormat = OMX_COLOR_FormatAndroidOpaque; -                } - -                formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused; -                formatParams->xFramerate = mFramerate; -                return OMX_ErrorNone; -            } else if (formatParams->nPortIndex == kOutputPortIndex) { -                formatParams->eCompressionFormat = OMX_VIDEO_CodingVP8; -                formatParams->eColorFormat = OMX_COLOR_FormatUnused; -                formatParams->xFramerate = 0; -                return OMX_ErrorNone; -            } else { -                return OMX_ErrorBadPortIndex; -            } -        } -          case OMX_IndexParamVideoBitrate: {              OMX_VIDEO_PARAM_BITRATETYPE *bitrate =                  (OMX_VIDEO_PARAM_BITRATETYPE *)param; @@ -495,54 +409,8 @@ OMX_ERRORTYPE SoftVPXEncoder::internalGetParameter(OMX_INDEXTYPE index,                  return OMX_ErrorNone;          } -        case OMX_IndexParamVideoProfileLevelQuerySupported: { -            OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileAndLevel = -                (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)param; - -            if (profileAndLevel->nPortIndex != kOutputPortIndex) { -                return OMX_ErrorUnsupportedIndex; -            } - -            switch (profileAndLevel->nProfileIndex) { -                case 0: -                    profileAndLevel->eLevel = OMX_VIDEO_VP8Level_Version0; -                    break; - -                case 1: -                    profileAndLevel->eLevel = OMX_VIDEO_VP8Level_Version1; -                    break; - -                case 2: -                    profileAndLevel->eLevel = OMX_VIDEO_VP8Level_Version2; -                    break; - -                case 3: -                    profileAndLevel->eLevel = OMX_VIDEO_VP8Level_Version3; -                    break; - -                default: -                    return OMX_ErrorNoMore; -            } - -            profileAndLevel->eProfile = OMX_VIDEO_VP8ProfileMain; -            return OMX_ErrorNone; -        } - -        case OMX_IndexParamVideoProfileLevelCurrent: { -            OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileAndLevel = -                (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)param; - -            if (profileAndLevel->nPortIndex != kOutputPortIndex) { -                return OMX_ErrorUnsupportedIndex; -            } - -            profileAndLevel->eLevel = mLevel; -            profileAndLevel->eProfile = OMX_VIDEO_VP8ProfileMain; -            return OMX_ErrorNone; -        } -          default: -            return SimpleSoftOMXComponent::internalGetParameter(index, param); +            return SoftVideoEncoderOMXComponent::internalGetParameter(index, param);      }  } @@ -553,30 +421,10 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetParameter(OMX_INDEXTYPE index,      const int32_t indexFull = index;      switch (indexFull) { -        case OMX_IndexParamStandardComponentRole: -            return internalSetRoleParams( -                (const OMX_PARAM_COMPONENTROLETYPE *)param); -          case OMX_IndexParamVideoBitrate:              return internalSetBitrateParams(                  (const OMX_VIDEO_PARAM_BITRATETYPE *)param); -        case OMX_IndexParamPortDefinition: -        { -            OMX_ERRORTYPE err = internalSetPortParams( -                (const OMX_PARAM_PORTDEFINITIONTYPE *)param); - -            if (err != OMX_ErrorNone) { -                return err; -            } - -            return SimpleSoftOMXComponent::internalSetParameter(index, param); -        } - -        case OMX_IndexParamVideoPortFormat: -            return internalSetFormatParams( -                (const OMX_VIDEO_PARAM_PORTFORMATTYPE *)param); -          case OMX_IndexParamVideoVp8:              return internalSetVp8Params(                  (const OMX_VIDEO_PARAM_VP8TYPE *)param); @@ -585,27 +433,8 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetParameter(OMX_INDEXTYPE index,              return internalSetAndroidVp8Params(                  (const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *)param); -        case OMX_IndexParamVideoProfileLevelCurrent: -            return internalSetProfileLevel( -                (const OMX_VIDEO_PARAM_PROFILELEVELTYPE *)param); - -        case kStoreMetaDataExtensionIndex: -        { -            // storeMetaDataInBuffers -            const StoreMetaDataInBuffersParams *storeParam = -                (const StoreMetaDataInBuffersParams *)param; - -            if (storeParam->nPortIndex != kInputPortIndex) { -                return OMX_ErrorBadPortIndex; -            } - -            mInputDataIsMeta = (storeParam->bStoreMetaData == OMX_TRUE); - -            return OMX_ErrorNone; -        } -          default: -            return SimpleSoftOMXComponent::internalSetParameter(index, param); +            return SoftVideoEncoderOMXComponent::internalSetParameter(index, param);      }  } @@ -646,29 +475,6 @@ OMX_ERRORTYPE SoftVPXEncoder::setConfig(      }  } -OMX_ERRORTYPE SoftVPXEncoder::internalSetProfileLevel( -        const OMX_VIDEO_PARAM_PROFILELEVELTYPE* profileAndLevel) { -    if (profileAndLevel->nPortIndex != kOutputPortIndex) { -        return OMX_ErrorUnsupportedIndex; -    } - -    if (profileAndLevel->eProfile != OMX_VIDEO_VP8ProfileMain) { -        return OMX_ErrorBadParameter; -    } - -    if (profileAndLevel->eLevel == OMX_VIDEO_VP8Level_Version0 || -        profileAndLevel->eLevel == OMX_VIDEO_VP8Level_Version1 || -        profileAndLevel->eLevel == OMX_VIDEO_VP8Level_Version2 || -        profileAndLevel->eLevel == OMX_VIDEO_VP8Level_Version3) { -        mLevel = (OMX_VIDEO_VP8LEVELTYPE)profileAndLevel->eLevel; -    } else { -        return OMX_ErrorBadParameter; -    } - -    return OMX_ErrorNone; -} - -  OMX_ERRORTYPE SoftVPXEncoder::internalSetVp8Params(          const OMX_VIDEO_PARAM_VP8TYPE* vp8Params) {      if (vp8Params->nPortIndex != kOutputPortIndex) { @@ -743,91 +549,6 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetAndroidVp8Params(      return OMX_ErrorNone;  } -OMX_ERRORTYPE SoftVPXEncoder::internalSetFormatParams( -        const OMX_VIDEO_PARAM_PORTFORMATTYPE* format) { -    if (format->nPortIndex == kInputPortIndex) { -        if (format->eColorFormat == OMX_COLOR_FormatYUV420Planar || -            format->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar || -            format->eColorFormat == OMX_COLOR_FormatAndroidOpaque) { -            mColorFormat = format->eColorFormat; - -            OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kInputPortIndex)->mDef; -            def->format.video.eColorFormat = mColorFormat; - -            return OMX_ErrorNone; -        } else { -            ALOGE("Unsupported color format %i", format->eColorFormat); -            return OMX_ErrorUnsupportedSetting; -        } -    } else if (format->nPortIndex == kOutputPortIndex) { -        if (format->eCompressionFormat == OMX_VIDEO_CodingVP8) { -            return OMX_ErrorNone; -        } else { -            return OMX_ErrorUnsupportedSetting; -        } -    } else { -        return OMX_ErrorBadPortIndex; -    } -} - - -OMX_ERRORTYPE SoftVPXEncoder::internalSetRoleParams( -        const OMX_PARAM_COMPONENTROLETYPE* role) { -    const char* roleText = (const char*)role->cRole; -    const size_t roleTextMaxSize = OMX_MAX_STRINGNAME_SIZE - 1; - -    if (strncmp(roleText, "video_encoder.vp8", roleTextMaxSize)) { -        ALOGE("Unsupported component role"); -        return OMX_ErrorBadParameter; -    } - -    return OMX_ErrorNone; -} - - -OMX_ERRORTYPE SoftVPXEncoder::internalSetPortParams( -        const OMX_PARAM_PORTDEFINITIONTYPE* port) { -    if (port->nPortIndex == kInputPortIndex) { -        mWidth = port->format.video.nFrameWidth; -        mHeight = port->format.video.nFrameHeight; - -        // xFramerate comes in Q16 format, in frames per second unit -        mFramerate = port->format.video.xFramerate; - -        if (port->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar || -            port->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar || -            port->format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque) { -            mColorFormat = port->format.video.eColorFormat; -        } else { -            return OMX_ErrorUnsupportedSetting; -        } - -        OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kInputPortIndex)->mDef; -        def->format.video.nFrameWidth = mWidth; -        def->format.video.nFrameHeight = mHeight; -        def->format.video.xFramerate = mFramerate; -        def->format.video.eColorFormat = mColorFormat; -        def = &editPortInfo(kOutputPortIndex)->mDef; -        def->format.video.nFrameWidth = mWidth; -        def->format.video.nFrameHeight = mHeight; - -        return OMX_ErrorNone; -    } else if (port->nPortIndex == kOutputPortIndex) { -        mBitrate = port->format.video.nBitrate; -        mWidth = port->format.video.nFrameWidth; -        mHeight = port->format.video.nFrameHeight; - -        OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kOutputPortIndex)->mDef; -        def->format.video.nFrameWidth = mWidth; -        def->format.video.nFrameHeight = mHeight; -        def->format.video.nBitrate = mBitrate; -        return OMX_ErrorNone; -    } else { -        return OMX_ErrorBadPortIndex; -    } -} - -  OMX_ERRORTYPE SoftVPXEncoder::internalSetBitrateParams(          const OMX_VIDEO_PARAM_BITRATETYPE* bitrate) {      if (bitrate->nPortIndex != kOutputPortIndex) { @@ -916,7 +637,7 @@ vpx_enc_frame_flags_t SoftVPXEncoder::getEncodeFlags() {      return flags;  } -void SoftVPXEncoder::onQueueFilled(OMX_U32 portIndex) { +void SoftVPXEncoder::onQueueFilled(OMX_U32 /* portIndex */) {      // Initialize encoder if not already      if (mCodecContext == NULL) {          if (OK != initEncoder()) { diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h index f4c1564..cd0a0cf 100644 --- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h +++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h @@ -155,18 +155,6 @@ private:      // that specifies algorithm interface (e.g. vp8)      vpx_codec_iface_t* mCodecInterface; -    // Width of the input frames -    int32_t mWidth; - -    // Height of the input frames -    int32_t mHeight; - -    // Target bitrate set for the encoder, in bits per second. -    uint32_t mBitrate; - -    // Target framerate set for the encoder. -    uint32_t mFramerate; -      // If a request for a change it bitrate has been received.      bool mBitrateUpdated; @@ -182,9 +170,6 @@ private:      // is enabled in encoder      OMX_BOOL mErrorResilience; -    // Color format for the input port -    OMX_COLOR_FORMATTYPE mColorFormat; -      // Encoder profile corresponding to OMX level parameter      //      // The inconsistency in the naming is caused by @@ -229,14 +214,8 @@ private:      // indeed YUV420SemiPlanar.      uint8_t* mConversionBuffer; -    bool mInputDataIsMeta; -      bool mKeyFrameRequested; -    // Initializes input and output OMX ports with sensible -    // default values. -    void initPorts(); -      // Initializes vpx encoder with available settings.      status_t initEncoder(); @@ -250,23 +229,10 @@ private:      // Get current encode flags      vpx_enc_frame_flags_t getEncodeFlags(); -    // Handles port changes with respect to color formats -    OMX_ERRORTYPE internalSetFormatParams( -        const OMX_VIDEO_PARAM_PORTFORMATTYPE* format); - -    // Verifies the component role tried to be set to this OMX component is -    // strictly video_encoder.vp8 -    OMX_ERRORTYPE internalSetRoleParams( -        const OMX_PARAM_COMPONENTROLETYPE* role); -      // Updates bitrate to reflect port settings.      OMX_ERRORTYPE internalSetBitrateParams(          const OMX_VIDEO_PARAM_BITRATETYPE* bitrate); -    // Handles port definition changes. -    OMX_ERRORTYPE internalSetPortParams( -        const OMX_PARAM_PORTDEFINITIONTYPE* port); -      // Handles vp8 specific parameters.      OMX_ERRORTYPE internalSetVp8Params(          const OMX_VIDEO_PARAM_VP8TYPE* vp8Params); @@ -275,10 +241,6 @@ private:      OMX_ERRORTYPE internalSetAndroidVp8Params(          const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE* vp8AndroidParams); -    // Updates encoder profile -    OMX_ERRORTYPE internalSetProfileLevel( -        const OMX_VIDEO_PARAM_PROFILELEVELTYPE* profileAndLevel); -      DISALLOW_EVIL_CONSTRUCTORS(SoftVPXEncoder);  }; diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp index 168208f..6b8b395 100644 --- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp +++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp @@ -64,9 +64,11 @@ SoftAVC::SoftAVC(        mHeadersDecoded(false),        mEOSStatus(INPUT_DATA_AVAILABLE),        mSignalledError(false) { +    const size_t kMinCompressionRatio = 2; +    const size_t kMaxOutputBufferSize = 2048 * 2048 * 3 / 2;      initPorts( -            kNumInputBuffers, 8192 /* inputBufferSize */, -            kNumOutputBuffers, MEDIA_MIMETYPE_VIDEO_AVC); +            kNumInputBuffers, kMaxOutputBufferSize / kMinCompressionRatio /* minInputBufferSize */, +            kNumOutputBuffers, MEDIA_MIMETYPE_VIDEO_AVC, kMinCompressionRatio);      CHECK_EQ(initDecoder(), (status_t)OK);  } diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM.h index 2ed86a4..fbb97e2 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM.h @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *    diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_BitDec_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_BitDec_s.h index abb98fc..d5866fa 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_BitDec_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_BitDec_s.h @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armCOMM_BitDec_s.h  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;//  @@ -667,4 +681,4 @@ BitCount    SETS "$RBitCount"          MEND          END -        
\ No newline at end of file +         diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_Bitstream.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_Bitstream.h index 4f9bc3b..576b66d 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_Bitstream.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_Bitstream.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM_Bitstream.h @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_IDCTTable.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_IDCTTable.h index d5db32f..223684e 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_IDCTTable.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_IDCTTable.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_IDCT_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_IDCT_s.h index 03f7137..6a7d24f 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_IDCT_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_IDCT_s.h @@ -1,11 +1,19 @@  ;// -;// This confidential and proprietary software may be used only as -;// authorised by a licensing agreement from ARM Limited -;//   (C) COPYRIGHT 2004 ARM Limited -;//       ALL RIGHTS RESERVED -;// The entire notice above must be reproduced on all authorised -;// copies and copies may only be made to the extent permitted -;// by a licensing agreement from ARM Limited. +;// Copyright (C) 2004 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//  ;// IDCT_s.s  ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_MaskTable.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_MaskTable.h index b5da9dc..5246f15 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_MaskTable.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_MaskTable.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM_MaskTable.h @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_s.h index 2df1fc8..04735a9 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armCOMM_s.h @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armCOMM_s.h  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armOMX.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armOMX.h index f629f72..e7c0c26 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armOMX.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/armOMX.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /*    *    * File Name:  armOMX_ReleaseVersion.h @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes_s.h index 8d24b65..d41a037 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes_s.h @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxtypes_s.h  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/build_vc.pl b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/build_vc.pl index 1ae7005..5d672b3 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/build_vc.pl +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/build_vc.pl @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  #!/usr/bin/perl  #  #  @@ -6,7 +22,6 @@  # Revision:   9641  # Date:       Thursday, February 7, 2008  #  -# (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  #   #   # diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM.c index e572a89..e8dbf41 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_Bitstream.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_Bitstream.c index 9ef9319..99f53ca 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_Bitstream.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_Bitstream.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM_Bitstream.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_IDCTTable.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_IDCTTable.c index 9e4679c..6f0b87f 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_IDCTTable.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_IDCTTable.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM_IDCTTable.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *    diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_MaskTable.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_MaskTable.c index 3241db2..906a8e5 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_MaskTable.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/src/armCOMM_MaskTable.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/armVC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/armVC.h index 7fa7716..6dbe8b6 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/armVC.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/armVC.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVC.h @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/armVCCOMM_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/armVCCOMM_s.h index 7f0a9b8..a9d4644 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/armVCCOMM_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/api/armVCCOMM_s.h @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCCOMM_s.h  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -69,4 +83,4 @@      ENDIF ;// ARMACCOMM_S_H - END
\ No newline at end of file + END diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s index 02b4b08..f5d2271 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCCOMM_ExpandFrame_I_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -186,4 +200,4 @@ End      ENDIF                                                    ;//ARM1136JS         -    END
\ No newline at end of file +    END diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/api/armVCM4P10_CAVLCTables.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/api/armVCM4P10_CAVLCTables.h index 4340f2a..d43d86b 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/api/armVCM4P10_CAVLCTables.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/api/armVCM4P10_CAVLCTables.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *    *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s index b2cd9d1..198f0ac 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_Average_4x_Align_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -219,4 +233,4 @@ End3      ENDIF      END -    
\ No newline at end of file +     diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_CAVLCTables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_CAVLCTables.c index 17fe518..3b84c8d 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_CAVLCTables.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_CAVLCTables.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s index dcbcd00..51dcb92 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_DeblockingChroma_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -17,4 +31,4 @@ -        END
\ No newline at end of file +        END diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s index 14b37fe..2085233 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_DeblockingLuma_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -363,4 +377,4 @@ t11     RN 9      ENDIF -        END
\ No newline at end of file +        END diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s index ac448a0..33638bf 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_DecodeCoeffsToPair_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DequantTables_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DequantTables_s.s index b16f188..afe07b5 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DequantTables_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_DequantTables_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_DequantTables_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -120,4 +134,4 @@ -         END
\ No newline at end of file +         END diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s index 82b9542..ffe123d 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_InterpolateLuma_Align_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s index bc0b6ec..c9a89fd 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_InterpolateLuma_Copy_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -146,4 +160,4 @@ Copy4x4End      ENDIF      END -    
\ No newline at end of file +     diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s index 66cfe5e..98b67eb 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -175,4 +189,4 @@ End2      ENDIF      END -    
\ No newline at end of file +     diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s index 851ff6a..523eace 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s index 2f48e13..2e7c5c7 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s index 6690ced..81af75a 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s index 007cd0d..906cbf3 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -182,4 +196,4 @@ End      ENDIF      END -    
\ No newline at end of file +     diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s index b1ad17c..35bf67c 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_Interpolate_Chroma_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_QuantTables_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_QuantTables_s.s index f962f70..938c719 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_QuantTables_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_QuantTables_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_QuantTables_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// Description: @@ -71,4 +85,4 @@           END -         
\ No newline at end of file +          diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s index 241d188..e5372e1 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_TransformResidual4x4_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -404,4 +418,4 @@ End  ;// Guarding implementation by the processor name -    END
\ No newline at end of file +    END diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s index ad16d9c..d02b4f3 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_UnpackBlock4x4_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -89,4 +103,4 @@ unpackLoop      END -    
\ No newline at end of file +     diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c index c2e6b60..34adea8 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c index 6023862..8b47dc2 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c index a19f277..2cd65ca 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c index 99bb4ce..9f9706b 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s index 2b71486..3187f2b 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s @@ -1,5 +1,19 @@  ;// -;// (c) Copyright 2007 ARM Limited. All Rights Reserved. +;// Copyright (C) 2007 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//  ;// Description:  ;// H.264 inverse quantize and transform module diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s index 6d960f0..d940418 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s index 00c8354..2dc9369 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s index 1b84080..e4fbfa4 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -328,4 +342,4 @@ ExitLoopY          END -        
\ No newline at end of file +         diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s index 417ddc2..6adf27b 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -547,4 +561,4 @@ ExitLoopY          END -        
\ No newline at end of file +         diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c index de835bd..63d185f 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_InterpolateChroma.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s index cf611a3..cb3b4e2 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_InterpolateLuma_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -423,4 +437,4 @@ EndOfInterpolation      END -    
\ No newline at end of file +     diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s index 34fedd8..09b4cf6 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_PredictIntraChroma_8x8_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s index 1557208..0c0cba7 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_PredictIntra_16x16_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s index a90f460..112139f 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_PredictIntra_4x4_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s index 53597a8..b83d7f0 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_TransformDequantChromaDCFromPair_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s index 73caec2..6974cd1 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_TransformDequantLumaDCFromPair_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -466,4 +480,4 @@ QPR5                RN  5      ENDIF                                                           ;//ARM1136JS   -    END
\ No newline at end of file +    END diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h index 22115d3..359e752 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_Huff_Tables_VLC.h @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h index d5f865c..286ba04 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_ZigZag_Tables.h @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Clip8_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Clip8_s.s index 7801e57..241d441 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Clip8_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Clip8_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ; /**  ; *   ; * File Name:  armVCM4P2_Clip8_s.s @@ -5,7 +20,6 @@  ; * Revision:   9641  ; * Date:       Thursday, February 7, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s index 9e30900..96f5bed 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ;/**  ; *   ; * File Name:  armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s @@ -5,7 +20,6 @@  ; * Revision:   9641  ; * Date:       Thursday, February 7, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c index ba4d058..04d86ed 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */   /**   *    * File Name:  armVCM4P2_Huff_Tables_VLC.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Lookup_Tables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Lookup_Tables.c index 25cf8db..04739a5 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Lookup_Tables.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Lookup_Tables.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */   /**   *    * File Name:  armVCM4P2_Lookup_Tables.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_SetPredDir_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_SetPredDir_s.s index 3f92d85..d0d13d1 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_SetPredDir_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_SetPredDir_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P2_SetPredDir_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c index ed17f9b..b647559 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_Zigzag_Tables.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c index b63d295..127772a 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_DecodeBlockCoef_Inter.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c index c609a60..f24fc07 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_DecodeBlockCoef_Intra.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s index a1861da..65a01d7 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ; **********  ; *   ; * File Name:  omxVCM4P2_DecodePadMV_PVOP_s.s @@ -5,7 +20,6 @@  ; * Revision:   9641  ; * Date:       Thursday, February 7, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s index c43b253..5ee33d8 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ;/**  ; *   ; * File Name:  omxVCM4P2_DecodeVLCZigzag_Inter_s.s @@ -5,7 +20,6 @@  ; * Revision:   9641  ; * Date:       Thursday, February 7, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s index 166729e..9d5940c 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ;/**  ; *   ; * File Name:  omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s @@ -5,7 +20,6 @@  ; * Revision:   9641  ; * Date:       Thursday, February 7, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s index d19cb13..266a62b 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ;/**  ; *   ; * File Name:  omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s @@ -5,7 +20,6 @@  ; * Revision:   9641  ; * Date:       Thursday, February 7, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s index a4bfa71..92acd51 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P2_FindMVpred_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -191,4 +205,4 @@ BlkEnd          M_END      ENDIF ;// ARM1136JS :LOR: CortexA8 -    END
\ No newline at end of file +    END diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s index bfeb540..e4f91fb 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P2_IDCT8x8blk_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s index 20965bf..8ac6ff9 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P2_MCReconBlock_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s index 213444a..116c81d 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ; **********  ; *   ; * File Name:  omxVCM4P2_PredictReconCoefIntra_s.s @@ -5,7 +20,6 @@  ; * Revision:   9641  ; * Date:       Thursday, February 7, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s index c9591cb..d57160f 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ;/**  ; *   ; * File Name:  omxVCM4P2_QuantInvInter_I_s.s @@ -5,7 +20,6 @@  ; * Revision:   9641  ; * Date:       Thursday, February 7, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s index 6328e01..bd82da4 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ;/**  ; *   ; * File Name:  omxVCM4P2_QuantInvIntra_I_s.s @@ -5,7 +20,6 @@  ; * Revision:   9641  ; * Date:       Thursday, February 7, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h index 64c1958..91e38b8 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM.h @@ -5,7 +21,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *    diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_BitDec_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_BitDec_s.h index c738f72..56344e3 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_BitDec_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_BitDec_s.h @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armCOMM_BitDec_s.h  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;//  @@ -667,4 +681,4 @@ BitCount    SETS "$RBitCount"          MEND          END -        
\ No newline at end of file +         diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Bitstream.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Bitstream.h index b699034..8c0ef37 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Bitstream.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_Bitstream.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM_Bitstream.h @@ -5,7 +21,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCTTable.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCTTable.h index e0cfdaa..d761f61 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCTTable.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCTTable.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *   *  @@ -6,7 +22,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCT_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCT_s.h index 0baa087..9130223 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCT_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_IDCT_s.h @@ -1,11 +1,19 @@  ;// -;// This confidential and proprietary software may be used only as -;// authorised by a licensing agreement from ARM Limited -;//   (C) COPYRIGHT 2004 ARM Limited -;//       ALL RIGHTS RESERVED -;// The entire notice above must be reproduced on all authorised -;// copies and copies may only be made to the extent permitted -;// by a licensing agreement from ARM Limited. +;// Copyright (C) 2004 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//  ;// IDCT_s.s  ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_MaskTable.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_MaskTable.h index 51118fd..5ffc835 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_MaskTable.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_MaskTable.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM_MaskTable.h @@ -5,7 +21,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_s.h index 0956bd1..321d2d3 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM_s.h @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armCOMM_s.h  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armOMX.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armOMX.h index 7a68d14..303abd9 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armOMX.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armOMX.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /*    *    * File Name:  armOMX_ReleaseVersion.h @@ -5,7 +21,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes_s.h index 48703d1..6e742c7 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes_s.h @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxtypes_s.h  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/build_vc.pl b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/build_vc.pl index 649e74c..6a206c0 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/build_vc.pl +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/build_vc.pl @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  #!/usr/bin/perl  #  #  @@ -6,7 +22,6 @@  # Revision:   12290  # Date:       Wednesday, April 9, 2008  #  -# (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  #   #   # diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM.c index e572a89..e8dbf41 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_Bitstream.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_Bitstream.c index 9ef9319..99f53ca 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_Bitstream.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_Bitstream.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM_Bitstream.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_IDCTTable.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_IDCTTable.c index 3f5e279..85d4c67 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_IDCTTable.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_IDCTTable.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM_IDCTTable.c @@ -5,7 +21,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *    diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_MaskTable.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_MaskTable.c index 09f88c3..f169a16 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_MaskTable.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM_MaskTable.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVC.h index 35b510b..1d37a5d 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVC.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVC.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVC.h @@ -5,7 +21,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVCCOMM_s.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVCCOMM_s.h index 32a0166..cfc2a3b 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVCCOMM_s.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/api/armVCCOMM_s.h @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCCOMM_s.h  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -69,4 +83,4 @@      ENDIF ;// ARMACCOMM_S_H - END
\ No newline at end of file + END diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s index 5c5b7d8..3d6b669 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/comm/src/omxVCCOMM_ExpandFrame_I_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCCOMM_ExpandFrame_I_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -233,4 +247,4 @@ End -    END
\ No newline at end of file +    END diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/api/armVCM4P10_CAVLCTables.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/api/armVCM4P10_CAVLCTables.h index 547a2d9..7dde9a7 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/api/armVCM4P10_CAVLCTables.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/api/armVCM4P10_CAVLCTables.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *    *  @@ -6,7 +22,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s index 4f0892d..5f3eb9b 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_Average_4x_Align_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_Average_4x_Align_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -219,4 +233,4 @@ End3      ENDIF      END -    
\ No newline at end of file +     diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_CAVLCTables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_CAVLCTables.c index 137495d..bb4bd9e 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_CAVLCTables.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_CAVLCTables.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s index 4c3a77c..e3813d3 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DeblockingChroma_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_DeblockingChroma_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s index 0afe4fd..bcc01dd 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DeblockingLuma_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_DeblockingLuma_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s index 10a89e9..6e3a0d5 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_DecodeCoeffsToPair_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DequantTables_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DequantTables_s.s index 2761600..dce8c89 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DequantTables_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_DequantTables_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_DequantTables_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -120,4 +134,4 @@ -         END
\ No newline at end of file +         END diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s index 6e912d7..20b3e22 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_Align_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_InterpolateLuma_Align_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s index d275891..1415beb 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_Copy_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_InterpolateLuma_Copy_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -146,4 +160,4 @@ Copy4x4End      ENDIF      END -    
\ No newline at end of file +     diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s index 4e5a39d..f5a7326 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -175,4 +189,4 @@ End2      ENDIF      END -    
\ No newline at end of file +     diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s index d1684cb..4d86782 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s index 7bc091f..3bc9534 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s index babe8ad..ea1c345 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s index 89c90aa..5414d47 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s index 0f0ec78..afb9565 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_Interpolate_Chroma_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_Interpolate_Chroma_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   9641  ;// Date:       Thursday, February 7, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_QuantTables_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_QuantTables_s.s index 7e2642b..8cd33a4 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_QuantTables_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_QuantTables_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_QuantTables_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// Description: @@ -71,4 +85,4 @@           END -         
\ No newline at end of file +          diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s index ee9c339..9e16e49 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_TransformResidual4x4_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_TransformResidual4x4_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -183,4 +197,4 @@ End      ENDIF                                                           ;//CortexA8             -    END
\ No newline at end of file +    END diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s index 4c52e22..a24c7d5 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/armVCM4P10_UnpackBlock4x4_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P10_UnpackBlock4x4_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -89,4 +103,4 @@ unpackLoop      END -    
\ No newline at end of file +     diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c index 40d4d5e..0a6448d 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c index 619365f..7b89be7 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c index 4e871bf..950f348 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c index b29e576..5e78b4c 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s index 485a488..4787982 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s index 4606197..a099dcb 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s index 18e6c1d..bf2152c 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s index 0c3f4f2..5678670 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s index e6fbb34..d2a134e 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c index 3ce41be..c6b3f41 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_InterpolateChroma.c @@ -5,7 +21,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s index 942ebc6..9f8f69e 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_InterpolateLuma_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_InterpolateLuma_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s index 3a60705..1ff418f 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_PredictIntraChroma_8x8_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s index e9c0eee..de331f4 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_PredictIntra_16x16_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s index 39eb8a4..b5780ef 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_PredictIntra_4x4_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s index e394339..5981795 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_TransformDequantChromaDCFromPair_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s index 2529959..d8c2431 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P10_TransformDequantLumaDCFromPair_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -261,4 +275,4 @@ QPR5                RN  5      ENDIF                                                           ;//ARM1136JS   -    END
\ No newline at end of file +    END diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Average_4x_Align_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Average_4x_Align_unsafe_s.S index aca2df4..46e0018 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Average_4x_Align_unsafe_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Average_4x_Align_unsafe_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingChroma_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingChroma_unsafe_s.S index b9ee221..ca64a02 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingChroma_unsafe_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingChroma_unsafe_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingLuma_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingLuma_unsafe_s.S index 47f3d44..193bc5e 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingLuma_unsafe_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DeblockingLuma_unsafe_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DecodeCoeffsToPair_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DecodeCoeffsToPair_s.S index bcc6b6b..8e0db37 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DecodeCoeffsToPair_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DecodeCoeffsToPair_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DequantTables_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DequantTables_s.S index 5bc7875..6febf2f 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DequantTables_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DequantTables_s.S @@ -1,5 +1,19 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Align_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Align_unsafe_s.S index 37bc69b..7206d76 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Align_unsafe_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Align_unsafe_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Copy_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Copy_unsafe_s.S index fe92201..e41d662 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Copy_unsafe_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_Copy_unsafe_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.S index 544abe8..c8f5cda 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_DiagCopy_unsafe_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.S index a330972..f5868c0 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.S index 991c33f..065995d 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.S index 40e141b..1e2d16b 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.S index 955846f..c7def2a 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Interpolate_Chroma_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Interpolate_Chroma_s.S index 8599cab..2f4293f 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Interpolate_Chroma_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_Interpolate_Chroma_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_QuantTables_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_QuantTables_s.S index f5d6d1f..f4e6010 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_QuantTables_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_QuantTables_s.S @@ -1,5 +1,19 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_TransformResidual4x4_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_TransformResidual4x4_s.S index c24d717..d4cedb5 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_TransformResidual4x4_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_TransformResidual4x4_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_UnpackBlock4x4_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_UnpackBlock4x4_s.S index c552f8d..1652dc6 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_UnpackBlock4x4_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_UnpackBlock4x4_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DeblockLuma_I.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DeblockLuma_I.S index ba61059..90b0947 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DeblockLuma_I.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DeblockLuma_I.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.S index bc0f7fa..4a74594 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.S index 79ba538..f20fb78 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_HorEdge_I_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.S index dcdddbe..003526e 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingChroma_VerEdge_I_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.S index 9755899..7ddc42e 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_HorEdge_I_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.S index 66cc32e..f71aceb 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_FilterDeblockingLuma_VerEdge_I_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_InterpolateLuma_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_InterpolateLuma_s.S index 76c3d7d..000fbeb 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_InterpolateLuma_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_InterpolateLuma_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntraChroma_8x8_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntraChroma_8x8_s.S index a896a3a..4e2cff6 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntraChroma_8x8_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntraChroma_8x8_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_16x16_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_16x16_s.S index 3944f53..c71c93b 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_16x16_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_16x16_s.S @@ -1,5 +1,19 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_4x4_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_4x4_s.S index 6646b7f..cd5d356 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_4x4_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_PredictIntra_4x4_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantChromaDCFromPair_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantChromaDCFromPair_s.S index 7ba3bd6..5570892 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantChromaDCFromPair_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantChromaDCFromPair_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantLumaDCFromPair_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantLumaDCFromPair_s.S index 640f096..5b6eee0 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantLumaDCFromPair_s.S +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantLumaDCFromPair_s.S @@ -1,5 +1,20 @@  /* - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*   *   */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h index 74b5505..6cbc5ff 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_Huff_Tables_VLC.h @@ -5,7 +21,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h index e95203a..0d64a68 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_ZigZag_Tables.h @@ -5,7 +21,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Clip8_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Clip8_s.s index 95fe6d2..2f830fc 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Clip8_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Clip8_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ; /**  ; *   ; * File Name:  armVCM4P2_Clip8_s.s @@ -5,7 +20,6 @@  ; * Revision:   12290  ; * Date:       Wednesday, April 9, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s index e4a7f33..016e65b 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ;/**  ; *   ; * File Name:  armVCM4P2_DecodeVLCZigzag_AC_unsafe_s.s @@ -5,7 +20,6 @@  ; * Revision:   12290  ; * Date:       Wednesday, April 9, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c index 38af975..5a77832 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */   /**   *    * File Name:  armVCM4P2_Huff_Tables_VLC.c @@ -5,7 +21,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Lookup_Tables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Lookup_Tables.c index 6948f80..e915d3c 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Lookup_Tables.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Lookup_Tables.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */   /**   *    * File Name:  armVCM4P2_Lookup_Tables.c @@ -5,7 +21,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_SetPredDir_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_SetPredDir_s.s index 44f2460..bf3f363 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_SetPredDir_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_SetPredDir_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  armVCM4P2_SetPredDir_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c index 21fa715..719b434 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_Zigzag_Tables.c @@ -5,7 +21,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c index 796ad6e..95346ad 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_DecodeBlockCoef_Inter.c @@ -5,7 +21,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c index b28657c..91ec5d2 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_DecodeBlockCoef_Intra.c @@ -5,7 +21,6 @@   * Revision:   12290   * Date:       Wednesday, April 9, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s index cc16f5a..08e9538 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ; **********  ; *   ; * File Name:  omxVCM4P2_DecodePadMV_PVOP_s.s @@ -5,7 +20,6 @@  ; * Revision:   12290  ; * Date:       Wednesday, April 9, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s index 7208c21..636dfe4 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ;/**  ; *   ; * File Name:  omxVCM4P2_DecodeVLCZigzag_Inter_s.s @@ -5,7 +20,6 @@  ; * Revision:   12290  ; * Date:       Wednesday, April 9, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s index 9a37ec9..15cc5b4 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ;/**  ; *   ; * File Name:  omxVCM4P2_DecodeVLCZigzag_IntraACVLC_s.s @@ -5,7 +20,6 @@  ; * Revision:   12290  ; * Date:       Wednesday, April 9, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s index 778aaf2..e9fed80 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ;/**  ; *   ; * File Name:  omxVCM4P2_DecodeVLCZigzag_IntraDCVLC_s.s @@ -5,7 +20,6 @@  ; * Revision:   12290  ; * Date:       Wednesday, April 9, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s index caf7121..9344120 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_FindMVpred_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P2_FindMVpred_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// @@ -191,4 +205,4 @@ BlkEnd          M_END      ENDIF ;// ARM1136JS :LOR: CortexA8 -    END
\ No newline at end of file +    END diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s index b5e3d0d..01b925e 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_IDCT8x8blk_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P2_IDCT8x8blk_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s index dd00df5..3c1aec3 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_MCReconBlock_s.s @@ -1,11 +1,25 @@  ;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;// +;//  ;//   ;// File Name:  omxVCM4P2_MCReconBlock_s.s  ;// OpenMAX DL: v1.0.2  ;// Revision:   12290  ;// Date:       Wednesday, April 9, 2008  ;//  -;// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ;//   ;//   ;// diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s index a73f64a..6b4eb28 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ; **********  ; *   ; * File Name:  omxVCM4P2_PredictReconCoefIntra_s.s @@ -5,7 +20,6 @@  ; * Revision:   12290  ; * Date:       Wednesday, April 9, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s index bd0ad1f..744571f 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_QuantInvInter_I_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ;/**  ; *   ; * File Name:  omxVCM4P2_QuantInvInter_I_s.s @@ -5,7 +20,6 @@  ; * Revision:   12290  ; * Date:       Wednesday, April 9, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s index e00591f..61a7fd4 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I_s.s @@ -1,3 +1,18 @@ +;// +;// Copyright (C) 2007-2008 ARM Limited +;// +;// Licensed under the Apache License, Version 2.0 (the "License"); +;// you may not use this file except in compliance with the License. +;// You may obtain a copy of the License at +;// +;//      http://www.apache.org/licenses/LICENSE-2.0 +;// +;// Unless required by applicable law or agreed to in writing, software +;// distributed under the License is distributed on an "AS IS" BASIS, +;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;// See the License for the specific language governing permissions and +;// limitations under the License. +;//  ;/**  ; *   ; * File Name:  omxVCM4P2_QuantInvIntra_I_s.s @@ -5,7 +20,6 @@  ; * Revision:   12290  ; * Date:       Wednesday, April 9, 2008  ; *  -; * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  ; *   ; *   ; * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h index 2ed86a4..fbb97e2 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM.h @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *    diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM_Bitstream.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM_Bitstream.h index 4f9bc3b..576b66d 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM_Bitstream.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM_Bitstream.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM_Bitstream.h @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armOMX.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armOMX.h index f629f72..e7c0c26 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armOMX.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armOMX.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /*    *    * File Name:  armOMX_ReleaseVersion.h @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/build_vc.pl b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/build_vc.pl index f0b43e0..e59cded 100755 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/build_vc.pl +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/build_vc.pl @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  #!/usr/bin/perl  #  #  @@ -6,7 +22,6 @@  # Revision:   9641  # Date:       Thursday, February 7, 2008  #  -# (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.  #   #   # diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/src/armCOMM.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/src/armCOMM.c index e572a89..e8dbf41 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/src/armCOMM.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/src/armCOMM.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/src/armCOMM_Bitstream.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/src/armCOMM_Bitstream.c index 9ef9319..99f53ca 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/src/armCOMM_Bitstream.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/src/armCOMM_Bitstream.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armCOMM_Bitstream.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/api/armVC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/api/armVC.h index 7fa7716..6dbe8b6 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/api/armVC.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/api/armVC.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVC.h @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/armVCCOMM_Average.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/armVCCOMM_Average.c index 1e51077..b7b37bf 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/armVCCOMM_Average.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/armVCCOMM_Average.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCCOMM_Average.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/armVCCOMM_SAD.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/armVCCOMM_SAD.c index d41ac9a..05b96dc 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/armVCCOMM_SAD.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/armVCCOMM_SAD.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCCOMM_SAD.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Average_16x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Average_16x.c index 6d1447e..175bca8 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Average_16x.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Average_16x.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCCOMM_Average_16x.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Average_8x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Average_8x.c index 17b1326..2c14f43 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Average_8x.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Average_8x.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCCOMM_Average_8x.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock.c index e559adf..a1f5240 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCCOMM_ComputeTextureErrorBlock.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock_SAD.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock_SAD.c index c4731aa..a7f48c9 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock_SAD.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ComputeTextureErrorBlock_SAD.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCCOMM_ComputeTextureErrorBlock_SAD.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Copy16x16.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Copy16x16.c index 4857024..8e467a4 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Copy16x16.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Copy16x16.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCCOMM_Copy16x16.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Copy8x8.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Copy8x8.c index a4f9dde..3f5969b 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Copy8x8.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_Copy8x8.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCCOMM_Copy8x8.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ExpandFrame_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ExpandFrame_I.c index 9536df7..5379fd0 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ExpandFrame_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_ExpandFrame_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCCOMM_ExpandFrame_I.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_LimitMVToRect.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_LimitMVToRect.c index af04582..9ba9093 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_LimitMVToRect.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_LimitMVToRect.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCCOMM_LimitMVToRect.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_SAD_16x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_SAD_16x.c index 0f0cedb..83dbbd0 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_SAD_16x.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_SAD_16x.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCCOMM_SAD_16x.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_SAD_8x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_SAD_8x.c index 1421d99..7bfd1ec 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_SAD_8x.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/comm/src/omxVCCOMM_SAD_8x.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCCOMM_SAD_8x.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/api/armVCM4P10_CAVLCTables.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/api/armVCM4P10_CAVLCTables.h index 8d18a8f..37241ca 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/api/armVCM4P10_CAVLCTables.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/api/armVCM4P10_CAVLCTables.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *    *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CAVLCTables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CAVLCTables.c index f4e36ad..c4a3074 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CAVLCTables.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CAVLCTables.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CompareMotionCostToMV.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CompareMotionCostToMV.c index e4bedc2..6611a37 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CompareMotionCostToMV.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CompareMotionCostToMV.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P10_CompareMotionCostToMV.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DeBlockPixel.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DeBlockPixel.c index f4fb1d9..c6da8ab 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DeBlockPixel.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DeBlockPixel.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c index 7616add..831d53b 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DequantTables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DequantTables.c index d9c2541..ad6cef3 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DequantTables.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DequantTables.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_FwdTransformResidual4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_FwdTransformResidual4x4.c index 93d54c3..17d6c0f 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_FwdTransformResidual4x4.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_FwdTransformResidual4x4.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfDiag_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfDiag_Luma.c index 8732f4f..ce9df49 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfDiag_Luma.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfDiag_Luma.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P10_InterpolateHalfDiag_Luma.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfHor_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfHor_Luma.c index 89c0079..15462b2 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfHor_Luma.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfHor_Luma.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P10_InterpolateHalfHor_Luma.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfVer_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfVer_Luma.c index f7ecfc5..e8adf45 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfVer_Luma.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfVer_Luma.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P10_InterpolateHalfVer_Luma.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Chroma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Chroma.c index 1507d23..26730f8 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Chroma.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Chroma.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P10_Interpolate_Chroma.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Luma.c index 89978dd..538d62e 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Luma.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Luma.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P10_Interpolate_Luma.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_PredictIntraDC4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_PredictIntraDC4x4.c index b713073..a200d55 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_PredictIntraDC4x4.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_PredictIntraDC4x4.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_QuantTables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_QuantTables.c index f0b5bb0..c01d4f6 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_QuantTables.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_QuantTables.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_SADQuar.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_SADQuar.c index a41e04b..6ef8af5 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_SADQuar.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_SADQuar.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P10_SADQuar.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_TransformResidual4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_TransformResidual4x4.c index f9f756a..6c53731 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_TransformResidual4x4.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_TransformResidual4x4.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock2x2.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock2x2.c index dda49f6..fb004e5 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock2x2.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock2x2.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *    *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock4x4.c index 3c0dcbd..b40c933 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock4x4.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock4x4.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_Average_4x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_Average_4x.c index ac0d523..638605e 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_Average_4x.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_Average_4x.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_Average_4x.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Half.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Half.c index c490e10..6cfdb64 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Half.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Half.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_BlockMatch_Half.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Integer.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Integer.c index f7764e1..050200f 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Integer.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Integer.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_BlockMatch_Integer.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Quarter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Quarter.c index 513ee25..f450d2c 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Quarter.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Quarter.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_BlockMatch_Quarter.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c index a07b1bb..9aecf3f 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c index 1f3a646..a159631 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c index 830ddc7..f931eeb 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c index 7e83d1e..e8ab819 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd.c index ed5a158..8a022ba 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I.c index 75edee2..4f34a96 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I.c index 10b2592..70b0e87 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I.c index 30a37da..19294f8 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I.c index 8733427..53e232a 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_GetVLCInfo.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_GetVLCInfo.c index 81c59d6..c80552a 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_GetVLCInfo.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_GetVLCInfo.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_GetVLCInfo.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c index 8824de2..18824d8 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_InterpolateChroma.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfHor_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfHor_Luma.c index ef0befa..26c8208 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfHor_Luma.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfHor_Luma.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_InterpolateHalfHor_Luma.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfVer_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfVer_Luma.c index 3560ff8..96c186b 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfVer_Luma.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfVer_Luma.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_InterpolateHalfVer_Luma.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateLuma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateLuma.c index d233735..e2a8163 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateLuma.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateLuma.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_InterpolateLuma.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_ChromaDC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_ChromaDC.c index 92ba031..869e768 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_ChromaDC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_ChromaDC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_InvTransformDequant_ChromaDC.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_LumaDC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_LumaDC.c index a3b1200..75f15cf 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_LumaDC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_LumaDC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_InvTransformDequant_LumaDC.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformResidualAndAdd.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformResidualAndAdd.c index 3303997..e3e4519 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformResidualAndAdd.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformResidualAndAdd.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_InvTransformResidualAndAdd.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEGetBufSize.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEGetBufSize.c index 8c3a5c3..7a245e1 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEGetBufSize.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEGetBufSize.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_MEGetBufSize.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEInit.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEInit.c index 58ecc88..e463353 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEInit.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEInit.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_MEInit.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MotionEstimationMB.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MotionEstimationMB.c index 33dbf3f..5264394 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MotionEstimationMB.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MotionEstimationMB.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**                                                                            x   *    * File Name:  omxVCM4P10_MotionEstimationMB.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8.c index d6ca783..e850771 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16.c index c90cb4c..ec44526 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4.c index 3fa8212..44c25f6 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_16x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_16x.c index c8114ee..140a785 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_16x.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_16x.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_SADQuar_16x.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_4x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_4x.c index 4b330ba..4b60d34 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_4x.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_4x.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_SADQuar_4x.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_8x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_8x.c index c9e9c24..6c8cdf3 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_8x.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_8x.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_SADQuar_8x.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SAD_4x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SAD_4x.c index 927c454..e22d8dd 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SAD_4x.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SAD_4x.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_SAD_4x.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SATD_4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SATD_4x4.c index a91ae66..6f74499 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SATD_4x4.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SATD_4x4.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_SATD_4x4.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SubAndTransformQDQResidual.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SubAndTransformQDQResidual.c index 23a5662..f184d7c 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SubAndTransformQDQResidual.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SubAndTransformQDQResidual.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_SubAndTransformQDQResidual.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair.c index 9ad0e81..dd9f5a7 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair.c index 16c8be1..d333d49 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /* ----------------------------------------------------------------   *   *  @@ -6,7 +22,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_ChromaDC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_ChromaDC.c index b5544dd..1b6a3d0 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_ChromaDC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_ChromaDC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_TransformQuant_ChromaDC.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_LumaDC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_LumaDC.c index 2ccf7f0..ea99a2d 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_LumaDC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_LumaDC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P10_TransformQuant_LumaDC.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_DCT_Table.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_DCT_Table.h index 3255b61..a72da13 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_DCT_Table.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_DCT_Table.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_DCT_Table.h @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h index 92ecc05..a88bdbc 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_Huff_Tables_VLC.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_Huff_Tables_VLC.h @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h index c75ed89..90c163f 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/api/armVCM4P2_ZigZag_Tables.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_ZigZag_Tables.h @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_ACDCPredict.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_ACDCPredict.c index b6a396a..c993f73 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_ACDCPredict.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_ACDCPredict.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_ACDCPredict.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_BlockMatch_Half.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_BlockMatch_Half.c index 1b69a33..4ffda10 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_BlockMatch_Half.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_BlockMatch_Half.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_BlockMatch_Half.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_BlockMatch_Integer.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_BlockMatch_Integer.c index 77fe358..2b05660 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_BlockMatch_Integer.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_BlockMatch_Integer.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_BlockMatch_Integer.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_CheckVLCEscapeMode.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_CheckVLCEscapeMode.c index 94e8639..5e510e7 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_CheckVLCEscapeMode.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_CheckVLCEscapeMode.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_CheckVLCEscapeMode.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_CompareMV.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_CompareMV.c index 3b8845e..3b621a3 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_CompareMV.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_CompareMV.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_CompareMV.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_DCT_Table.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_DCT_Table.c index a6f713e..7d055d9 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_DCT_Table.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_DCT_Table.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */   /**   *    * File Name:  armVCM4P2_DCT_Table.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_intra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_intra.c index a2572e0..a5aa198 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_intra.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_DecodeVLCZigzag_intra.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_DecodeVLCZigzag_intra.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_EncodeVLCZigzag_intra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_EncodeVLCZigzag_intra.c index cd6b56d..b61c547 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_EncodeVLCZigzag_intra.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_EncodeVLCZigzag_intra.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_EncodeVLCZigzag_intra.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_FillVLCBuffer.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_FillVLCBuffer.c index 93c9504..aeb7714 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_FillVLCBuffer.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_FillVLCBuffer.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_FillVLCBuffer.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_FillVLDBuffer.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_FillVLDBuffer.c index 1712c3a..f09f5d5 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_FillVLDBuffer.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_FillVLDBuffer.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_FillVLDBuffer.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_GetVLCBits.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_GetVLCBits.c index 953f597..8eb1411 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_GetVLCBits.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_GetVLCBits.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_GetVLCBits.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c index cd7e9e4..b101d48 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_Huff_Tables_VLC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */   /**   *    * File Name:  armVCM4P2_Huff_Tables_VLC.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_PutVLCBits.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_PutVLCBits.c index ca9efec..21d5494 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_PutVLCBits.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_PutVLCBits.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_PutVLCBits.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_SetPredDir.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_SetPredDir.c index a9cd008..61d44d4 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_SetPredDir.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_SetPredDir.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  armVCM4P2_SetPredDir.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c index a247c69..bcfc0ef 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/armVCM4P2_Zigzag_Tables.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */   /**   *    * File Name:  armVCM4P2_Zigzag_Tables.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_16x16.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_16x16.c index dcd3ce1..f23c533 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_16x16.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_16x16.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_BlockMatch_Half_16x16.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    *  diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_8x8.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_8x8.c index 6996e6d..83da79f 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_8x8.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Half_8x8.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_BlockMatch_Half_8x8.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_16x16.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_16x16.c index e714ef1..e224016 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_16x16.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_16x16.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_BlockMatch_Integer_16x16.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_8x8.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_8x8.c index 607e64c..73a99bd 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_8x8.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_BlockMatch_Integer_8x8.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_BlockMatch_Integer_8x8.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DCT8x8blk.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DCT8x8blk.c index a077ac8..c73e24a 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DCT8x8blk.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DCT8x8blk.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_DCT8x8blk.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c index 51f7bab..9c9a7f6 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Inter.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_DecodeBlockCoef_Inter.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c index a0b2376..970da6c 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeBlockCoef_Intra.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_DecodeBlockCoef_Intra.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP.c index 7e159b7..ae2c220 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodePadMV_PVOP.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_DecodePadMV_PVOP.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter.c index 88a8d04..2d3cf6e 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_Inter.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_DecodeVLCZigzag_Inter.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC.c index 96593d1..6dddaf0 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraACVLC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_DecodeVLCZigzag_IntraACVLC.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC.c index 95e00d7..9c76ed1 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_DecodeVLCZigzag_IntraDCVLC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_DecodeVLCZigzag_IntraDCVLC.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeMV.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeMV.c index def2b6d..c04a236 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeMV.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeMV.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_EncodeMV.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_Inter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_Inter.c index b6c73ea..2158f88 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_Inter.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_Inter.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_EncodeVLCZigzag_Inter.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraACVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraACVLC.c index d047942..63b6d97 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraACVLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraACVLC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_EncodeVLCZigzag_IntraACVLC.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraDCVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraDCVLC.c index c57acd2..7bdda19 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraDCVLC.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraDCVLC.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_EncodeVLCZigzag_IntraDCVLC.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_FindMVpred.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_FindMVpred.c index a0cff48..054b486 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_FindMVpred.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_FindMVpred.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_FindMVpred.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_IDCT8x8blk.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_IDCT8x8blk.c index 1886d92..c512458 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_IDCT8x8blk.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_IDCT8x8blk.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_IDCT8x8blk.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MCReconBlock.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MCReconBlock.c index 7b3faee..33f0cf5 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MCReconBlock.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MCReconBlock.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_MCReconBlock.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * Description: diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MEGetBufSize.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MEGetBufSize.c index a8e51da..dda852e 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MEGetBufSize.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MEGetBufSize.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_MEGetBufSize.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MEInit.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MEInit.c index 419e71a..59c57c2 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MEInit.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MEInit.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_MEInit.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c index 9549050..f9bb297 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_MotionEstimationMB.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra.c index 1613f47..e091f31 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_PredictReconCoefIntra.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */   /**   *    * File Name:  omxVCM4P2_PredictReconCoefIntra.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInter_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInter_I.c index 5964f73..9055b66 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInter_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInter_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_QuantInter_I.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantIntra_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantIntra_I.c index a10da68..795b802 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantIntra_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantIntra_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_QuantIntra_I.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInvInter_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInvInter_I.c index 6e0de5c..189e244 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInvInter_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInvInter_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_QuantInvInter_I.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I.c index a946d7b..2f24cc7 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_QuantInvIntra_I.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_QuantInvIntra_I.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_inter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_inter.c index 6e0c59b..9615a77 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_inter.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_inter.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_TransRecBlockCoef_inter.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_intra.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_intra.c index dd444f9..4923e3f 100644 --- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_intra.c +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_TransRecBlockCoef_intra.c @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2007-2008 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */  /**   *    * File Name:  omxVCM4P2_TransRecBlockCoef_intra.c @@ -5,7 +21,6 @@   * Revision:   9641   * Date:       Thursday, February 7, 2008   *  - * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.   *    *    * diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp index 1899b40..4e75250 100644 --- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp +++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp @@ -104,6 +104,7 @@ void SoftwareRenderer::resetFormatIfChanged(const sp<AMessage> &format) {      switch (mColorFormat) {          case OMX_COLOR_FormatYUV420Planar:          case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: +        case OMX_COLOR_FormatYUV420SemiPlanar:          {              if (!runningInEmulator()) {                  halFormat = HAL_PIXEL_FORMAT_YV12; @@ -236,9 +237,8 @@ void SoftwareRenderer::render(              dst_u += dst_c_stride;              dst_v += dst_c_stride;          } -    } else { -        CHECK_EQ(mColorFormat, OMX_TI_COLOR_FormatYUV420PackedSemiPlanar); - +    } else if (mColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar +            || mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {          const uint8_t *src_y =              (const uint8_t *)data; @@ -271,6 +271,8 @@ void SoftwareRenderer::render(              dst_u += dst_c_stride;              dst_v += dst_c_stride;          } +    } else { +        LOG_ALWAYS_FATAL("bad color format %#x", mColorFormat);      }      CHECK_EQ(0, mapper.unlock(buf->handle)); diff --git a/media/libstagefright/data/media_codecs_google_audio.xml b/media/libstagefright/data/media_codecs_google_audio.xml index f599004..a06684b 100644 --- a/media/libstagefright/data/media_codecs_google_audio.xml +++ b/media/libstagefright/data/media_codecs_google_audio.xml @@ -48,7 +48,7 @@          </MediaCodec>          <MediaCodec name="OMX.google.vorbis.decoder" type="audio/vorbis">              <Limit name="channel-count" max="8" /> -            <Limit name="sample-rate" ranges="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000" /> +            <Limit name="sample-rate" ranges="8000-96000" />              <Limit name="bitrate" range="32000-500000" />          </MediaCodec>          <MediaCodec name="OMX.google.opus.decoder" type="audio/opus"> @@ -65,7 +65,8 @@      <Encoders>          <MediaCodec name="OMX.google.aac.encoder" type="audio/mp4a-latm">              <Limit name="channel-count" max="6" /> -            <Limit name="sample-rate" ranges="11025,12000,16000,22050,24000,32000,44100,48000" /> +            <Limit name="sample-rate" ranges="8000,11025,12000,16000,22050,24000,32000,44100,48000" /> +            <!-- also may support 64000, 88200  and 96000 Hz -->              <Limit name="bitrate" range="8000-960000" />          </MediaCodec>          <MediaCodec name="OMX.google.amrnb.encoder" type="audio/3gpp"> diff --git a/media/libstagefright/data/media_codecs_google_video.xml b/media/libstagefright/data/media_codecs_google_video.xml index 1cbef39..7e9fa18 100644 --- a/media/libstagefright/data/media_codecs_google_video.xml +++ b/media/libstagefright/data/media_codecs_google_video.xml @@ -73,7 +73,7 @@      <Encoders>          <MediaCodec name="OMX.google.h263.encoder" type="video/3gpp">              <!-- profiles and levels:  ProfileBaseline : Level45 --> -            <Limit name="size" min="16x16" max="176x144" /> +            <Limit name="size" min="176x144" max="176x144" />              <Limit name="alignment" value="16x16" />              <Limit name="bitrate" range="1-128000" />          </MediaCodec> diff --git a/media/libstagefright/data/media_codecs_google_video_le.xml b/media/libstagefright/data/media_codecs_google_video_le.xml new file mode 100644 index 0000000..034a038 --- /dev/null +++ b/media/libstagefright/data/media_codecs_google_video_le.xml @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- 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. +--> + +<Included> +    <Decoders> +        <MediaCodec name="OMX.google.mpeg4.decoder" type="video/mp4v-es"> +            <!-- profiles and levels:  ProfileSimple : Level3 --> +            <Limit name="size" min="2x2" max="352x288" /> +            <Limit name="alignment" value="2x2" /> +            <Limit name="block-size" value="16x16" /> +            <Limit name="blocks-per-second" range="12-11880" /> +            <Limit name="bitrate" range="1-384000" /> +            <Feature name="adaptive-playback" /> +        </MediaCodec> +        <MediaCodec name="OMX.google.h263.decoder" type="video/3gpp"> +            <!-- profiles and levels:  ProfileBaseline : Level30, ProfileBaseline : Level45 +                    ProfileISWV2 : Level30, ProfileISWV2 : Level45 --> +            <Limit name="size" min="2x2" max="352x288" /> +            <Limit name="alignment" value="2x2" /> +            <Limit name="bitrate" range="1-384000" /> +            <Feature name="adaptive-playback" /> +        </MediaCodec> +        <MediaCodec name="OMX.google.h264.decoder" type="video/avc"> +            <!-- profiles and levels:  ProfileBaseline : Level51 --> +            <Limit name="size" min="2x2" max="2048x2048" /> +            <Limit name="alignment" value="2x2" /> +            <Limit name="block-size" value="16x16" /> +            <Limit name="block-count" range="1-8160" /> +            <Limit name="blocks-per-second" range="1-489600" /> +            <Limit name="bitrate" range="1-40000000" /> +            <Feature name="adaptive-playback" /> +        </MediaCodec> +        <MediaCodec name="OMX.google.hevc.decoder" type="video/hevc"> +            <!-- profiles and levels:  ProfileMain : MainTierLevel51 --> +            <Limit name="size" min="2x2" max="1280x1280" /> +            <Limit name="alignment" value="2x2" /> +            <Limit name="block-size" value="8x8" /> +            <Limit name="block-count" range="1-139264" /> +            <Limit name="blocks-per-second" range="1-432000" /> +            <Limit name="bitrate" range="1-5000000" /> +            <Feature name="adaptive-playback" /> +        </MediaCodec> +        <MediaCodec name="OMX.google.vp8.decoder" type="video/x-vnd.on2.vp8"> +            <Limit name="size" min="2x2" max="2048x2048" /> +            <Limit name="alignment" value="2x2" /> +            <Limit name="block-size" value="16x16" /> +            <Limit name="block-count" range="1-8160" /> +            <Limit name="blocks-per-second" range="1-500000" /> +            <Limit name="bitrate" range="1-40000000" /> +            <Feature name="adaptive-playback" /> +        </MediaCodec> +        <MediaCodec name="OMX.google.vp9.decoder" type="video/x-vnd.on2.vp9"> +            <Limit name="size" min="2x2" max="1280x1280" /> +            <Limit name="alignment" value="2x2" /> +            <Limit name="block-size" value="16x16" /> +            <Limit name="block-count" range="1-3600" /> +            <Limit name="blocks-per-second" range="1-108000" /> +            <Limit name="bitrate" range="1-5000000" /> +            <Feature name="adaptive-playback" /> +        </MediaCodec> +    </Decoders> + +    <Encoders> +        <MediaCodec name="OMX.google.h263.encoder" type="video/3gpp"> +            <!-- profiles and levels:  ProfileBaseline : Level45 --> +            <Limit name="size" min="176x144" max="176x144" /> +            <Limit name="alignment" value="16x16" /> +            <Limit name="bitrate" range="1-128000" /> +        </MediaCodec> +        <MediaCodec name="OMX.google.h264.encoder" type="video/avc"> +            <!-- profiles and levels:  ProfileBaseline : Level2 --> +            <Limit name="size" min="16x16" max="896x896" /> +            <Limit name="alignment" value="16x16" /> +            <Limit name="block-size" value="16x16" /> +            <Limit name="blocks-per-second" range="1-11880" /> +            <Limit name="bitrate" range="1-2000000" /> +        </MediaCodec> +        <MediaCodec name="OMX.google.mpeg4.encoder" type="video/mp4v-es"> +            <!-- profiles and levels:  ProfileCore : Level2 --> +            <Limit name="size" min="16x16" max="176x144" /> +            <Limit name="alignment" value="16x16" /> +            <Limit name="block-size" value="16x16" /> +            <Limit name="blocks-per-second" range="12-1485" /> +            <Limit name="bitrate" range="1-64000" /> +        </MediaCodec> +        <MediaCodec name="OMX.google.vp8.encoder" type="video/x-vnd.on2.vp8"> +            <!-- profiles and levels:  ProfileMain : Level_Version0-3 --> +            <Limit name="size" min="2x2" max="1280x1280" /> +            <Limit name="alignment" value="2x2" /> +            <Limit name="block-count" range="1-3600" /> +            <Limit name="bitrate" range="1-20000000" /> +            <Feature name="bitrate-modes" value="VBR,CBR" /> +        </MediaCodec> +    </Encoders> +</Included> diff --git a/media/libstagefright/foundation/ADebug.cpp b/media/libstagefright/foundation/ADebug.cpp new file mode 100644 index 0000000..ec4a960 --- /dev/null +++ b/media/libstagefright/foundation/ADebug.cpp @@ -0,0 +1,117 @@ +/* + * 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. + */ + +#include <errno.h> +#include <stdlib.h> +#include <ctype.h> + +#define LOG_TAG "ADebug" +#include <utils/Log.h> +#include <utils/misc.h> + +#include <cutils/properties.h> + +#include <ADebug.h> +#include <AStringUtils.h> +#include <AUtils.h> + +namespace android { + +//static +ADebug::Level ADebug::GetDebugLevelFromString( +        const char *name, const char *value, ADebug::Level def) { +    // split on , +    const char *next = value, *current; +    const unsigned long maxLevel = (unsigned long)kDebugMax; +    while (next != NULL) { +        current = next; +        next = strchr(current, ','); +        if (next != NULL) { +            ++next;  // pass , +        } + +        while (isspace(*current)) { +            ++current; +        } +        // check for : +        char *colon = strchr(current, ':'); + +        // get level +        char *end; +        errno = 0;  // strtoul does not clear errno, but it can be set for any return value +        unsigned long level = strtoul(current, &end, 10); +        while (isspace(*end)) { +            ++end; +        } +        if (errno != 0 || end == current || (end != colon && *end != '\0' && end != next)) { +            // invalid level - skip +            continue; +        } +        if (colon != NULL) { +            // check if pattern matches +            do {  // skip colon and spaces +                ++colon; +            } while (isspace(*colon)); +            size_t globLen = (next == NULL ? strlen(colon) : (next - 1 - colon)); +            while (globLen > 0 && isspace(colon[globLen - 1])) { +                --globLen;  // trim glob +            } + +            if (!AStringUtils::MatchesGlob( +                    colon, globLen, name, strlen(name), true /* ignoreCase */)) { +                continue; +            } +        } + +        // update debug level +        def = (Level)min(level, maxLevel); +    } +    return def; +} + +//static +ADebug::Level ADebug::GetDebugLevelFromProperty( +        const char *name, const char *propertyName, ADebug::Level def) { +    char value[PROPERTY_VALUE_MAX]; +    if (property_get(propertyName, value, NULL)) { +        return GetDebugLevelFromString(name, value, def); +    } +    return def; +} + +//static +char *ADebug::GetDebugName(const char *name) { +    char *debugName = strdup(name); +    const char *terms[] = { "omx", "video", "audio" }; +    for (size_t i = 0; i < NELEM(terms) && debugName != NULL; i++) { +        const char *term = terms[i]; +        const size_t len = strlen(term); +        char *match = strcasestr(debugName, term); +        if (match != NULL && (match == debugName || match[-1] == '.' +                || match[len] == '.' || match[len] == '\0')) { +            char *src = match + len; +            if (match == debugName || match[-1] == '.') { +                src += (*src == '.');  // remove trailing or double . +            } +            memmove(match, src, debugName + strlen(debugName) - src + 1); +        } +    } + +    return debugName; +} + +}  // namespace android + diff --git a/media/libstagefright/foundation/AStringUtils.cpp b/media/libstagefright/foundation/AStringUtils.cpp new file mode 100644 index 0000000..e5a846c --- /dev/null +++ b/media/libstagefright/foundation/AStringUtils.cpp @@ -0,0 +1,77 @@ +/* + * 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. + */ + +#include <string.h> +#include <AStringUtils.h> + +namespace android { + +// static +int AStringUtils::Compare(const char *a, const char *b, size_t len, bool ignoreCase) { +    // this method relies on a trailing '\0' if a or b are shorter than len +    return ignoreCase ? strncasecmp(a, b, len) : strncmp(a, b, len); +} + +// static +bool AStringUtils::MatchesGlob( +        const char *glob, size_t globLen, const char *str, size_t strLen, bool ignoreCase) { +    // this method does not assume a trailing '\0' +    size_t ix = 0, globIx = 0; + +    // pattern must match until first '*' +    while (globIx < globLen && glob[globIx] != '*') { +        ++globIx; +    } +    if (strLen < globIx || Compare(str, glob, globIx /* len */, ignoreCase)) { +        return false; +    } +    ix = globIx; + +    // process by * separated sections +    while (globIx < globLen) { +        ++globIx; +        size_t start = globIx; +        while (globIx < globLen && glob[globIx] != '*') { +            ++globIx; +        } +        size_t len = globIx - start; +        const char *pattern = glob + start; + +        if (globIx == globLen) { +            // last pattern must match tail +            if (ix + len > strLen) { +                return false; +            } +            const char *tail = str + strLen - len; +            return !Compare(tail, pattern, len, ignoreCase); +        } +        // progress after first occurrence of pattern +        while (ix + len <= strLen && Compare(str + ix, pattern, len, ignoreCase)) { +            ++ix; +        } +        if (ix + len > strLen) { +            return false; +        } +        ix += len; +        // we will loop around as globIx < globLen +    } + +    // we only get here if there were no * in the pattern +    return ix == strLen; +} + +}  // namespace android + diff --git a/media/libstagefright/foundation/AWakeLock.cpp b/media/libstagefright/foundation/AWakeLock.cpp new file mode 100644 index 0000000..88c4f6e --- /dev/null +++ b/media/libstagefright/foundation/AWakeLock.cpp @@ -0,0 +1,109 @@ +/* + * 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. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "AWakeLock" +#include <utils/Log.h> + +#include "ADebug.h" +#include "AWakeLock.h" + +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> +#include <powermanager/PowerManager.h> + + +namespace android { + +AWakeLock::AWakeLock() : +    mPowerManager(NULL), +    mWakeLockToken(NULL), +    mWakeLockCount(0), +    mDeathRecipient(new PMDeathRecipient(this)) {} + +AWakeLock::~AWakeLock() { +    if (mPowerManager != NULL) { +        sp<IBinder> binder = mPowerManager->asBinder(); +        binder->unlinkToDeath(mDeathRecipient); +    } +    clearPowerManager(); +} + +bool AWakeLock::acquire() { +    if (mWakeLockCount == 0) { +        CHECK(mWakeLockToken == NULL); +        if (mPowerManager == NULL) { +            // use checkService() to avoid blocking if power service is not up yet +            sp<IBinder> binder = +                defaultServiceManager()->checkService(String16("power")); +            if (binder == NULL) { +                ALOGW("could not get the power manager service"); +            } else { +                mPowerManager = interface_cast<IPowerManager>(binder); +                binder->linkToDeath(mDeathRecipient); +            } +        } +        if (mPowerManager != NULL) { +            sp<IBinder> binder = new BBinder(); +            int64_t token = IPCThreadState::self()->clearCallingIdentity(); +            status_t status = mPowerManager->acquireWakeLock( +                    POWERMANAGER_PARTIAL_WAKE_LOCK, +                    binder, String16("AWakeLock"), String16("media")); +            IPCThreadState::self()->restoreCallingIdentity(token); +            if (status == NO_ERROR) { +                mWakeLockToken = binder; +                mWakeLockCount++; +                return true; +            } +        } +    } else { +        mWakeLockCount++; +        return true; +    } +    return false; +} + +void AWakeLock::release(bool force) { +    if (mWakeLockCount == 0) { +        return; +    } +    if (force) { +        // Force wakelock release below by setting reference count to 1. +        mWakeLockCount = 1; +    } +    if (--mWakeLockCount == 0) { +        CHECK(mWakeLockToken != NULL); +        if (mPowerManager != NULL) { +            int64_t token = IPCThreadState::self()->clearCallingIdentity(); +            mPowerManager->releaseWakeLock(mWakeLockToken, 0 /* flags */); +            IPCThreadState::self()->restoreCallingIdentity(token); +        } +        mWakeLockToken.clear(); +    } +} + +void AWakeLock::clearPowerManager() { +    release(true); +    mPowerManager.clear(); +} + +void AWakeLock::PMDeathRecipient::binderDied(const wp<IBinder>& who __unused) { +    if (mWakeLock != NULL) { +        mWakeLock->clearPowerManager(); +    } +} + +}  // namespace android diff --git a/media/libstagefright/foundation/Android.mk b/media/libstagefright/foundation/Android.mk index 90a6a23..08355c7 100644 --- a/media/libstagefright/foundation/Android.mk +++ b/media/libstagefright/foundation/Android.mk @@ -5,6 +5,7 @@ LOCAL_SRC_FILES:=                 \      AAtomizer.cpp                 \      ABitReader.cpp                \      ABuffer.cpp                   \ +    ADebug.cpp                    \      AHandler.cpp                  \      AHierarchicalStateMachine.cpp \      ALooper.cpp                   \ @@ -12,6 +13,8 @@ LOCAL_SRC_FILES:=                 \      AMessage.cpp                  \      ANetworkSession.cpp           \      AString.cpp                   \ +    AStringUtils.cpp              \ +    AWakeLock.cpp                 \      ParsedMessage.cpp             \      base64.cpp                    \      hexdump.cpp @@ -22,7 +25,9 @@ LOCAL_C_INCLUDES:= \  LOCAL_SHARED_LIBRARIES := \          libbinder         \          libutils          \ -        liblog +        libcutils         \ +        liblog            \ +        libpowermanager  LOCAL_CFLAGS += -Wno-multichar -Werror diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp index fba6b09..4355a3c 100644 --- a/media/libstagefright/httplive/LiveSession.cpp +++ b/media/libstagefright/httplive/LiveSession.cpp @@ -49,6 +49,9 @@  namespace android { +// Number of recently-read bytes to use for bandwidth estimation +const size_t LiveSession::kBandwidthHistoryBytes = 200 * 1024; +  LiveSession::LiveSession(          const sp<AMessage> ¬ify, uint32_t flags,          const sp<IMediaHTTPService> &httpService) @@ -84,6 +87,13 @@ LiveSession::LiveSession(          mPacketSources2.add(indexToType(i), new AnotherPacketSource(NULL /* meta */));          mBuffering[i] = false;      } + +    size_t numHistoryItems = kBandwidthHistoryBytes / +            PlaylistFetcher::kDownloadBlockSize + 1; +    if (numHistoryItems < 5) { +        numHistoryItems = 5; +    } +    mHTTPDataSource->setBandwidthHistorySize(numHistoryItems);  }  LiveSession::~LiveSession() { @@ -145,10 +155,24 @@ status_t LiveSession::dequeueAccessUnit(          }      } +    int32_t targetDuration = 0; +    sp<AMessage> meta = packetSource->getLatestEnqueuedMeta(); +    if (meta != NULL) { +        meta->findInt32("targetDuration", &targetDuration); +    } + +    int64_t targetDurationUs = targetDuration * 1000000ll; +    if (targetDurationUs == 0 || +            targetDurationUs > PlaylistFetcher::kMinBufferedDurationUs) { +        // Fetchers limit buffering to +        // min(3 * targetDuration, kMinBufferedDurationUs) +        targetDurationUs = PlaylistFetcher::kMinBufferedDurationUs; +    } +      if (mBuffering[idx]) {          if (mSwitchInProgress                  || packetSource->isFinished(0) -                || packetSource->getEstimatedDurationUs() > 10000000ll) { +                || packetSource->getEstimatedDurationUs() > targetDurationUs) {              mBuffering[idx] = false;          }      } @@ -859,7 +883,11 @@ ssize_t LiveSession::fetchFile(          // Only resize when we don't know the size.          size_t bufferRemaining = buffer->capacity() - buffer->size();          if (bufferRemaining == 0 && getSizeErr != OK) { -            bufferRemaining = 32768; +            size_t bufferIncrement = buffer->size() / 2; +            if (bufferIncrement < 32768) { +                bufferIncrement = 32768; +            } +            bufferRemaining = bufferIncrement;              ALOGV("increasing download buffer to %zu bytes",                   buffer->size() + bufferRemaining); @@ -1109,11 +1137,11 @@ status_t LiveSession::onSeek(const sp<AMessage> &msg) {  }  status_t LiveSession::getDuration(int64_t *durationUs) const { -    int64_t maxDurationUs = 0ll; +    int64_t maxDurationUs = -1ll;      for (size_t i = 0; i < mFetcherInfos.size(); ++i) {          int64_t fetcherDurationUs = mFetcherInfos.valueAt(i).mDurationUs; -        if (fetcherDurationUs >= 0ll && fetcherDurationUs > maxDurationUs) { +        if (fetcherDurationUs > maxDurationUs) {              maxDurationUs = fetcherDurationUs;          }      } @@ -1164,6 +1192,14 @@ status_t LiveSession::selectTrack(size_t index, bool select) {      return err;  } +ssize_t LiveSession::getSelectedTrack(media_track_type type) const { +    if (mPlaylist == NULL) { +        return -1; +    } else { +        return mPlaylist->getSelectedTrack(type); +    } +} +  bool LiveSession::canSwitchUp() {      // Allow upwards bandwidth switch when a stream has buffered at least 10 seconds.      status_t err = OK; @@ -1458,7 +1494,7 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {                      extra->setInt64("timeUs", timeUs);                      discontinuityQueue = mDiscontinuities.valueFor(indexToType(j));                      discontinuityQueue->queueDiscontinuity( -                            ATSParser::DISCONTINUITY_SEEK, extra, true); +                            ATSParser::DISCONTINUITY_TIME, extra, true);                  } else {                      int32_t type;                      int64_t srcSegmentStartTimeUs; @@ -1473,14 +1509,15 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {                      if (meta != NULL && !meta->findInt32("discontinuity", &type)) {                          int64_t tmpUs; +                        int64_t tmpSegmentUs; +                          CHECK(meta->findInt64("timeUs", &tmpUs)); -                        if (startTimeUs < 0 || tmpUs < startTimeUs) { +                        CHECK(meta->findInt64("segmentStartTimeUs", &tmpSegmentUs)); +                        if (startTimeUs < 0 || tmpSegmentUs < segmentStartTimeUs) { +                            startTimeUs = tmpUs; +                            segmentStartTimeUs = tmpSegmentUs; +                        } else if (tmpSegmentUs == segmentStartTimeUs && tmpUs < startTimeUs) {                              startTimeUs = tmpUs; -                        } - -                        CHECK(meta->findInt64("segmentStartTimeUs", &tmpUs)); -                        if (segmentStartTimeUs < 0 || tmpUs < segmentStartTimeUs) { -                            segmentStartTimeUs = tmpUs;                          }                          int32_t seq; @@ -1592,6 +1629,12 @@ void LiveSession::onCheckSwitchDown() {          return;      } +    if (mSwitchInProgress || mReconfigurationInProgress) { +        ALOGV("Switch/Reconfig in progress, defer switch down"); +        mSwitchDownMonitor->post(1000000ll); +        return; +    } +      for (size_t i = 0; i < kMaxStreams; ++i) {          int32_t targetDuration;          sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(indexToType(i)); @@ -1622,7 +1665,6 @@ void LiveSession::onSwitchDown() {          return;      } -    changeConfiguration(-1, mCurBandwidthIndex - 1, false);  }  // Mark switch done when: diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h index 7aacca6..dfb5e59 100644 --- a/media/libstagefright/httplive/LiveSession.h +++ b/media/libstagefright/httplive/LiveSession.h @@ -19,6 +19,7 @@  #define LIVE_SESSION_H_  #include <media/stagefright/foundation/AHandler.h> +#include <media/mediaplayer.h>  #include <utils/String8.h> @@ -73,6 +74,7 @@ struct LiveSession : public AHandler {      size_t getTrackCount() const;      sp<AMessage> getTrackInfo(size_t trackIndex) const;      status_t selectTrack(size_t index, bool select); +    ssize_t getSelectedTrack(media_track_type /* type */) const;      bool isSeekable() const;      bool hasDynamicDuration() const; @@ -112,6 +114,8 @@ private:          kWhatSwitchDown                 = 'sDwn',      }; +    static const size_t kBandwidthHistoryBytes; +      struct BandwidthItem {          size_t mPlaylistIndex;          unsigned long mBandwidth; diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp index 1651dee..997b694 100644 --- a/media/libstagefright/httplive/M3UParser.cpp +++ b/media/libstagefright/httplive/M3UParser.cpp @@ -35,6 +35,7 @@ struct M3UParser::MediaGroup : public RefBase {          TYPE_AUDIO,          TYPE_VIDEO,          TYPE_SUBS, +        TYPE_CC,      };      enum FlagBits { @@ -66,6 +67,9 @@ protected:      virtual ~MediaGroup();  private: + +    friend struct M3UParser; +      struct Media {          AString mName;          AString mURI; @@ -356,6 +360,38 @@ ssize_t M3UParser::getSelectedIndex() const {      return mSelectedIndex;  } +ssize_t M3UParser::getSelectedTrack(media_track_type type) const { +    MediaGroup::Type groupType; +    switch (type) { +        case MEDIA_TRACK_TYPE_VIDEO: +            groupType = MediaGroup::TYPE_VIDEO; +            break; + +        case MEDIA_TRACK_TYPE_AUDIO: +            groupType = MediaGroup::TYPE_AUDIO; +            break; + +        case MEDIA_TRACK_TYPE_SUBTITLE: +            groupType = MediaGroup::TYPE_SUBS; +            break; + +        default: +            return -1; +    } + +    for (size_t i = 0, ii = 0; i < mMediaGroups.size(); ++i) { +        sp<MediaGroup> group = mMediaGroups.valueAt(i); +        size_t tracks = group->countTracks(); +        if (groupType != group->mType) { +            ii += tracks; +        } else if (group->mSelectedIndex >= 0) { +            return ii + group->mSelectedIndex; +        } +    } + +    return -1; +} +  bool M3UParser::getTypeURI(size_t index, const char *key, AString *uri) const {      if (!mIsVariantPlaylist) {          *uri = mBaseURI; @@ -956,6 +992,8 @@ status_t M3UParser::parseMedia(const AString &line) {                  groupType = MediaGroup::TYPE_AUDIO;              } else if (!strcasecmp("video", val.c_str())) {                  groupType = MediaGroup::TYPE_VIDEO; +            } else if (!strcasecmp("closed-captions", val.c_str())){ +                groupType = MediaGroup::TYPE_CC;              } else {                  ALOGE("Invalid media group type '%s'", val.c_str());                  return ERROR_MALFORMED; @@ -1068,6 +1106,13 @@ status_t M3UParser::parseMedia(const AString &line) {          return ERROR_MALFORMED;      } +    if (groupType == MediaGroup::TYPE_CC) { +        // TODO: ignore this for now. +        // CC track will be detected by CCDecoder. But we still need to +        // pass the CC track flags (lang, auto) to the app in the future. +        return OK; +    } +      uint32_t flags = 0;      if (haveGroupAutoselect && groupAutoselect) {          flags |= MediaGroup::FLAG_AUTOSELECT; diff --git a/media/libstagefright/httplive/M3UParser.h b/media/libstagefright/httplive/M3UParser.h index d588afe..1cad060 100644 --- a/media/libstagefright/httplive/M3UParser.h +++ b/media/libstagefright/httplive/M3UParser.h @@ -21,6 +21,7 @@  #include <media/stagefright/foundation/ABase.h>  #include <media/stagefright/foundation/AMessage.h>  #include <media/stagefright/foundation/AString.h> +#include <media/mediaplayer.h>  #include <utils/Vector.h>  namespace android { @@ -46,6 +47,7 @@ struct M3UParser : public RefBase {      size_t getTrackCount() const;      sp<AMessage> getTrackInfo(size_t index) const;      ssize_t getSelectedIndex() const; +    ssize_t getSelectedTrack(media_track_type /* type */) const;      bool getTypeURI(size_t index, const char *key, AString *uri) const; diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp index 30fa868..00e52ee 100644 --- a/media/libstagefright/httplive/PlaylistFetcher.cpp +++ b/media/libstagefright/httplive/PlaylistFetcher.cpp @@ -49,8 +49,9 @@ namespace android {  // static  const int64_t PlaylistFetcher::kMinBufferedDurationUs = 10000000ll;  const int64_t PlaylistFetcher::kMaxMonitorDelayUs = 3000000ll; -const int32_t PlaylistFetcher::kDownloadBlockSize = 2048; -const int32_t PlaylistFetcher::kNumSkipFrames = 10; +// LCM of 188 (size of a TS packet) & 1k works well +const int32_t PlaylistFetcher::kDownloadBlockSize = 47 * 1024; +const int32_t PlaylistFetcher::kNumSkipFrames = 5;  PlaylistFetcher::PlaylistFetcher(          const sp<AMessage> ¬ify, @@ -561,7 +562,7 @@ status_t PlaylistFetcher::onResumeUntil(const sp<AMessage> &msg) {          // Don't resume if we would stop within a resume threshold.          int32_t discontinuitySeq;          int64_t latestTimeUs = 0, stopTimeUs = 0; -        sp<AMessage> latestMeta = packetSource->getLatestDequeuedMeta(); +        sp<AMessage> latestMeta = packetSource->getLatestEnqueuedMeta();          if (latestMeta != NULL                  && latestMeta->findInt32("discontinuitySeq", &discontinuitySeq)                  && discontinuitySeq == mDiscontinuitySeq @@ -610,7 +611,12 @@ void PlaylistFetcher::onMonitorQueue() {      int32_t targetDurationSecs;      int64_t targetDurationUs = kMinBufferedDurationUs;      if (mPlaylist != NULL) { -        CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); +        if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( +                "target-duration", &targetDurationSecs)) { +            ALOGE("Playlist is missing required EXT-X-TARGETDURATION tag"); +            notifyError(ERROR_MALFORMED); +            return; +        }          targetDurationUs = targetDurationSecs * 1000000ll;      } @@ -700,8 +706,7 @@ status_t PlaylistFetcher::refreshPlaylist() {                      mRefreshState = (RefreshState)(mRefreshState + 1);                  }              } else { -                ALOGE("failed to load playlist at url '%s'", mURI.c_str()); -                notifyError(ERROR_IO); +                ALOGE("failed to load playlist at url '%s'", uriDebugString(mURI).c_str());                  return ERROR_IO;              }          } else { @@ -724,26 +729,25 @@ bool PlaylistFetcher::bufferStartsWithTsSyncByte(const sp<ABuffer>& buffer) {  }  void PlaylistFetcher::onDownloadNext() { -    if (refreshPlaylist() != OK) { -        return; -    } - -    int32_t firstSeqNumberInPlaylist; -    if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( -                "media-sequence", &firstSeqNumberInPlaylist)) { -        firstSeqNumberInPlaylist = 0; -    } - +    status_t err = refreshPlaylist(); +    int32_t firstSeqNumberInPlaylist = 0; +    int32_t lastSeqNumberInPlaylist = 0;      bool discontinuity = false; -    const int32_t lastSeqNumberInPlaylist = -        firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; +    if (mPlaylist != NULL) { +        if (mPlaylist->meta() != NULL) { +            mPlaylist->meta()->findInt32("media-sequence", &firstSeqNumberInPlaylist); +        } -    if (mDiscontinuitySeq < 0) { -        mDiscontinuitySeq = mPlaylist->getDiscontinuitySeq(); +        lastSeqNumberInPlaylist = +                firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1; + +        if (mDiscontinuitySeq < 0) { +            mDiscontinuitySeq = mPlaylist->getDiscontinuitySeq(); +        }      } -    if (mSeqNumber < 0) { +    if (mPlaylist != NULL && mSeqNumber < 0) {          CHECK_GE(mStartTimeUs, 0ll);          if (mSegmentStartTimeUs < 0) { @@ -754,6 +758,9 @@ void PlaylistFetcher::onDownloadNext() {                      mSeqNumber = firstSeqNumberInPlaylist;                  }              } else { +                // When seeking mSegmentStartTimeUs is unavailable (< 0), we +                // use mStartTimeUs (client supplied timestamp) to determine both start segment +                // and relative position inside a segment                  mSeqNumber = getSeqNumberForTime(mStartTimeUs);                  mStartTimeUs -= getSegmentStartTimeUs(mSeqNumber);              } @@ -762,6 +769,10 @@ void PlaylistFetcher::onDownloadNext() {                      mStartTimeUs, mSeqNumber, firstSeqNumberInPlaylist,                      lastSeqNumberInPlaylist);          } else { +            // When adapting or track switching, mSegmentStartTimeUs (relative +            // to media time 0) is used to determine the start segment; mStartTimeUs (absolute +            // timestamps coming from the media container) is used to determine the position +            // inside a segments.              mSeqNumber = getSeqNumberForTime(mSegmentStartTimeUs);              if (mAdaptive) {                  // avoid double fetch/decode @@ -785,19 +796,26 @@ void PlaylistFetcher::onDownloadNext() {          }      } +    // if mPlaylist is NULL then err must be non-OK; but the other way around might not be true      if (mSeqNumber < firstSeqNumberInPlaylist -            || mSeqNumber > lastSeqNumberInPlaylist) { -        if (!mPlaylist->isComplete() && mNumRetries < kMaxNumRetries) { +            || mSeqNumber > lastSeqNumberInPlaylist +            || err != OK) { +        if ((err != OK || !mPlaylist->isComplete()) && mNumRetries < kMaxNumRetries) {              ++mNumRetries; -            if (mSeqNumber > lastSeqNumberInPlaylist) { +            if (mSeqNumber > lastSeqNumberInPlaylist || err != OK) { +                // make sure we reach this retry logic on refresh failures +                // by adding an err != OK clause to all enclosing if's. +                  // refresh in increasing fraction (1/2, 1/3, ...) of the                  // playlist's target duration or 3 seconds, whichever is less -                int32_t targetDurationSecs; -                CHECK(mPlaylist->meta()->findInt32( -                        "target-duration", &targetDurationSecs)); -                int64_t delayUs = mPlaylist->size() * targetDurationSecs * -                        1000000ll / (1 + mNumRetries); +                int64_t delayUs = kMaxMonitorDelayUs; +                if (mPlaylist != NULL && mPlaylist->meta() != NULL) { +                    int32_t targetDurationSecs; +                    CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); +                    delayUs = mPlaylist->size() * targetDurationSecs * +                            1000000ll / (1 + mNumRetries); +                }                  if (delayUs > kMaxMonitorDelayUs) {                      delayUs = kMaxMonitorDelayUs;                  } @@ -809,13 +827,30 @@ void PlaylistFetcher::onDownloadNext() {                  return;              } -            // we've missed the boat, let's start from the lowest sequence +            if (err != OK) { +                notifyError(err); +                return; +            } + +            // we've missed the boat, let's start 3 segments prior to the latest sequence              // number available and signal a discontinuity.              ALOGI("We've missed the boat, restarting playback."                    "  mStartup=%d, was  looking for %d in %d-%d",                      mStartup, mSeqNumber, firstSeqNumberInPlaylist,                      lastSeqNumberInPlaylist); +            if (mStopParams != NULL) { +                // we should have kept on fetching until we hit the boundaries in mStopParams, +                // but since the segments we are supposed to fetch have already rolled off +                // the playlist, i.e. we have already missed the boat, we inevitably have to +                // skip. +                for (size_t i = 0; i < mPacketSources.size(); i++) { +                    sp<ABuffer> formatChange = mSession->createFormatChangeBuffer(); +                    mPacketSources.valueAt(i)->queueAccessUnit(formatChange); +                } +                stopAsync(/* clear = */ false); +                return; +            }              mSeqNumber = lastSeqNumberInPlaylist - 3;              if (mSeqNumber < firstSeqNumberInPlaylist) {                  mSeqNumber = firstSeqNumberInPlaylist; @@ -949,6 +984,10 @@ void PlaylistFetcher::onDownloadNext() {          if (err == -EAGAIN) {              // starting sequence number too low/high              mTSParser.clear(); +            for (size_t i = 0; i < mPacketSources.size(); i++) { +                sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i); +                packetSource->clear(); +            }              postMonitorQueue();              return;          } else if (err == ERROR_OUT_OF_RANGE) { @@ -963,8 +1002,8 @@ void PlaylistFetcher::onDownloadNext() {      } while (bytesRead != 0);      if (bufferStartsWithTsSyncByte(buffer)) { -        // If we still don't see a stream after fetching a full ts segment mark it as -        // nonexistent. +        // If we don't see a stream in the program table after fetching a full ts segment +        // mark it as nonexistent.          const size_t kNumTypes = ATSParser::NUM_SOURCE_TYPES;          ATSParser::SourceType srcTypes[kNumTypes] =                  { ATSParser::VIDEO, ATSParser::AUDIO }; @@ -979,7 +1018,7 @@ void PlaylistFetcher::onDownloadNext() {                  static_cast<AnotherPacketSource *>(                      mTSParser->getSource(srcType).get()); -            if (source == NULL) { +            if (!mTSParser->hasSource(srcType)) {                  ALOGW("MPEG2 Transport stream does not contain %s data.",                        srcType == ATSParser::VIDEO ? "video" : "audio"); @@ -996,7 +1035,7 @@ void PlaylistFetcher::onDownloadNext() {          return;      } -    status_t err = OK; +    err = OK;      if (tsBuffer != NULL) {          AString method;          CHECK(buffer->meta()->findString("cipher-method", &method)); @@ -1137,6 +1176,11 @@ const sp<ABuffer> &PlaylistFetcher::setAccessUnitProperties(          accessUnit->meta()->setInt32("discard", discard);      } +    int32_t targetDurationSecs; +    if (mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)) { +        accessUnit->meta()->setInt32("targetDuration", targetDurationSecs); +    } +      accessUnit->meta()->setInt32("discontinuitySeq", mDiscontinuitySeq);      accessUnit->meta()->setInt64("segmentStartTimeUs", getSegmentStartTimeUs(mSeqNumber));      return accessUnit; @@ -1155,7 +1199,7 @@ status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &bu          extra->setInt64(IStreamListener::kKeyMediaTimeUs, 0);          mTSParser->signalDiscontinuity( -                ATSParser::DISCONTINUITY_SEEK, extra); +                ATSParser::DISCONTINUITY_TIME, extra);          mAbsoluteTimeAnchorUs = mNextPTSTimeUs;          mNextPTSTimeUs = -1ll; @@ -1256,6 +1300,11 @@ status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &bu              CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));              if (mStartTimeUsNotify != NULL && timeUs > mStartTimeUs) { +                int32_t firstSeqNumberInPlaylist; +                if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32( +                            "media-sequence", &firstSeqNumberInPlaylist)) { +                    firstSeqNumberInPlaylist = 0; +                }                  int32_t targetDurationSecs;                  CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)); @@ -1266,6 +1315,8 @@ status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &bu                  //   mStartTimeUs.                  // mSegmentStartTimeUs >= 0                  //   mSegmentStartTimeUs is non-negative when adapting or switching tracks +                // mSeqNumber > firstSeqNumberInPlaylist +                //   don't decrement mSeqNumber if it already points to the 1st segment                  // timeUs - mStartTimeUs > targetDurationUs:                  //   This and the 2 above conditions should only happen when adapting in a live                  //   stream; the old fetcher has already fetched to mStartTimeUs; the new fetcher @@ -1275,6 +1326,7 @@ status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &bu                  //   stop as early as possible. The definition of being "too far ahead" is                  //   arbitrary; here we use targetDurationUs as threshold.                  if (mStartup && mSegmentStartTimeUs >= 0 +                        && mSeqNumber > firstSeqNumberInPlaylist                          && timeUs - mStartTimeUs > targetDurationUs) {                      // we just guessed a starting timestamp that is too high when adapting in a                      // live stream; re-adjust based on the actual timestamp extracted from the @@ -1587,6 +1639,7 @@ status_t PlaylistFetcher::extractAndQueueAccessUnits(                  mStartTimeUsNotify->setInt32("streamMask", LiveSession::STREAMTYPE_AUDIO);                  mStartTimeUsNotify->post();                  mStartTimeUsNotify.clear(); +                mStartup = false;              }          } @@ -1637,7 +1690,7 @@ void PlaylistFetcher::updateDuration() {  int64_t PlaylistFetcher::resumeThreshold(const sp<AMessage> &msg) {      int64_t durationUs, threshold; -    if (msg->findInt64("durationUs", &durationUs)) { +    if (msg->findInt64("durationUs", &durationUs) && durationUs > 0) {          return kNumSkipFrames * durationUs;      } diff --git a/media/libstagefright/httplive/PlaylistFetcher.h b/media/libstagefright/httplive/PlaylistFetcher.h index 78c358f..67161a9 100644 --- a/media/libstagefright/httplive/PlaylistFetcher.h +++ b/media/libstagefright/httplive/PlaylistFetcher.h @@ -34,6 +34,9 @@ struct M3UParser;  struct String8;  struct PlaylistFetcher : public AHandler { +    static const int64_t kMinBufferedDurationUs; +    static const int32_t kDownloadBlockSize; +      enum {          kWhatStarted,          kWhatPaused, @@ -92,9 +95,7 @@ private:          kWhatDownloadNext   = 'dlnx',      }; -    static const int64_t kMinBufferedDurationUs;      static const int64_t kMaxMonitorDelayUs; -    static const int32_t kDownloadBlockSize;      static const int32_t kNumSkipFrames;      static bool bufferStartsWithTsSyncByte(const sp<ABuffer>& buffer); diff --git a/media/libstagefright/include/HTTPBase.h b/media/libstagefright/include/HTTPBase.h index 1c3cd5e..0c66e27 100644 --- a/media/libstagefright/include/HTTPBase.h +++ b/media/libstagefright/include/HTTPBase.h @@ -48,6 +48,8 @@ struct HTTPBase : public DataSource {      virtual status_t setBandwidthStatCollectFreq(int32_t freqMs); +    virtual void setBandwidthHistorySize(size_t numHistoryItems); +      static void RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag);      static void UnRegisterSocketUserTag(int sockfd); @@ -55,7 +57,7 @@ struct HTTPBase : public DataSource {      static void UnRegisterSocketUserMark(int sockfd);  protected: -    void addBandwidthMeasurement(size_t numBytes, int64_t delayUs); +    virtual void addBandwidthMeasurement(size_t numBytes, int64_t delayUs);  private:      struct BandwidthEntry { @@ -69,6 +71,7 @@ private:      size_t mNumBandwidthHistoryItems;      int64_t mTotalTransferTimeUs;      size_t mTotalTransferBytes; +    size_t mMaxBandwidthHistoryItems;      enum {          kMinBandwidthCollectFreqMs = 1000,   // 1 second diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h index 712cae5..b26e940 100644 --- a/media/libstagefright/include/OMXNodeInstance.h +++ b/media/libstagefright/include/OMXNodeInstance.h @@ -31,7 +31,7 @@ struct GraphicBufferSource;  struct OMXNodeInstance {      OMXNodeInstance( -            OMX *owner, const sp<IOMXObserver> &observer); +            OMX *owner, const sp<IOMXObserver> &observer, const char *name);      void setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle); @@ -148,6 +148,18 @@ private:      KeyedVector<OMX::buffer_id, OMX_BUFFERHEADERTYPE *> mBufferIDToBufferHeader;      KeyedVector<OMX_BUFFERHEADERTYPE *, OMX::buffer_id> mBufferHeaderToBufferID; +    // For debug support +    char *mName; +    int DEBUG; +    size_t mNumPortBuffers[2];  // modified under mLock, read outside for debug +    Mutex mDebugLock; +    // following are modified and read under mDebugLock +    int DEBUG_BUMP; +    SortedVector<OMX_BUFFERHEADERTYPE *> mInputBuffersWithCodec, mOutputBuffersWithCodec; +    size_t mDebugLevelBumpPendingBuffers[2]; +    void bumpDebugLevel_l(size_t numInputBuffers, size_t numOutputBuffers); +    void unbumpDebugLevel_l(size_t portIndex); +      ~OMXNodeInstance();      void addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id); @@ -185,6 +197,10 @@ private:              OMX_U32 portIndex, OMX_BOOL enable,              OMX_BOOL useGraphicBuffer, OMX_BOOL *usingGraphicBufferInMeta); +    status_t emptyBuffer_l( +            OMX_BUFFERHEADERTYPE *header, +            OMX_U32 flags, OMX_TICKS timestamp, intptr_t debugAddr); +      sp<GraphicBufferSource> getGraphicBufferSource();      void setGraphicBufferSource(const sp<GraphicBufferSource>& bufferSource); diff --git a/media/libstagefright/include/SoftVideoDecoderOMXComponent.h b/media/libstagefright/include/SoftVideoDecoderOMXComponent.h index 9e97ebd..4529007 100644 --- a/media/libstagefright/include/SoftVideoDecoderOMXComponent.h +++ b/media/libstagefright/include/SoftVideoDecoderOMXComponent.h @@ -61,9 +61,10 @@ protected:      void initPorts(OMX_U32 numInputBuffers,              OMX_U32 inputBufferSize,              OMX_U32 numOutputBuffers, -            const char *mimeType); +            const char *mimeType, +            OMX_U32 minCompressionRatio = 1u); -    virtual void updatePortDefinitions(bool updateCrop = true); +    virtual void updatePortDefinitions(bool updateCrop = true, bool updateInputSize = false);      uint32_t outputBufferWidth();      uint32_t outputBufferHeight(); @@ -99,6 +100,9 @@ protected:      } mOutputPortSettingsChange;  private: +    uint32_t mMinInputBufferSize; +    uint32_t mMinCompressionRatio; +      const char *mComponentRole;      OMX_VIDEO_CODINGTYPE mCodingType;      const CodecProfileLevel *mProfileLevels; diff --git a/media/libstagefright/include/SoftVideoEncoderOMXComponent.h b/media/libstagefright/include/SoftVideoEncoderOMXComponent.h index b3b810d..b43635d 100644 --- a/media/libstagefright/include/SoftVideoEncoderOMXComponent.h +++ b/media/libstagefright/include/SoftVideoEncoderOMXComponent.h @@ -18,6 +18,8 @@  #define SOFT_VIDEO_ENCODER_OMX_COMPONENT_H_ +#include <media/IOMX.h> +  #include "SimpleSoftOMXComponent.h"  #include <system/window.h> @@ -28,11 +30,26 @@ namespace android {  struct SoftVideoEncoderOMXComponent : public SimpleSoftOMXComponent {      SoftVideoEncoderOMXComponent(              const char *name, +            const char *componentRole, +            OMX_VIDEO_CODINGTYPE codingType, +            const CodecProfileLevel *profileLevels, +            size_t numProfileLevels, +            int32_t width, +            int32_t height,              const OMX_CALLBACKTYPE *callbacks,              OMX_PTR appData,              OMX_COMPONENTTYPE **component); +    virtual OMX_ERRORTYPE internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR param); +    virtual OMX_ERRORTYPE internalGetParameter(OMX_INDEXTYPE index, OMX_PTR params); +  protected: +    void initPorts( +            OMX_U32 numInputBuffers, OMX_U32 numOutputBuffers, OMX_U32 outputBufferSize, +            const char *mime, OMX_U32 minCompressionRatio = 1); + +    static void setRawVideoSize(OMX_PARAM_PORTDEFINITIONTYPE *def); +      static void ConvertFlexYUVToPlanar(              uint8_t *dst, size_t dstStride, size_t dstVStride,              struct android_ycbcr *ycbcr, int32_t width, int32_t height); @@ -56,9 +73,30 @@ protected:          kOutputPortIndex = 1,      }; +    bool mInputDataIsMeta; +    int32_t mWidth;      // width of the input frames +    int32_t mHeight;     // height of the input frames +    uint32_t mBitrate;   // target bitrate set for the encoder, in bits per second +    uint32_t mFramerate; // target framerate set for the encoder, in Q16 format +    OMX_COLOR_FORMATTYPE mColorFormat;  // Color format for the input port +  private: +    void updatePortParams(); +    OMX_ERRORTYPE internalSetPortParams(const OMX_PARAM_PORTDEFINITIONTYPE* port); + +    static const uint32_t kInputBufferAlignment = 1; +    static const uint32_t kOutputBufferAlignment = 2; +      mutable const hw_module_t *mGrallocModule; +    uint32_t mMinOutputBufferSize; +    uint32_t mMinCompressionRatio; + +    const char *mComponentRole; +    OMX_VIDEO_CODINGTYPE mCodingType; +    const CodecProfileLevel *mProfileLevels; +    size_t mNumProfileLevels; +      DISALLOW_EVIL_CONSTRUCTORS(SoftVideoEncoderOMXComponent);  }; diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp index 44a1e22..e53319b 100644 --- a/media/libstagefright/matroska/MatroskaExtractor.cpp +++ b/media/libstagefright/matroska/MatroskaExtractor.cpp @@ -414,16 +414,16 @@ void BlockIterator::seek(      const mkvparser::CuePoint* pCP;      mkvparser::Tracks const *pTracks = pSegment->GetTracks(); -    unsigned long int trackCount = pTracks->GetTracksCount();      while (!pCues->DoneParsing()) {          pCues->LoadCuePoint();          pCP = pCues->GetLast();          CHECK(pCP); +        size_t trackCount = mExtractor->mTracks.size();          for (size_t index = 0; index < trackCount; ++index) { -            const mkvparser::Track *pTrack = pTracks->GetTrackByIndex(index); +            MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(index); +            const mkvparser::Track *pTrack = pTracks->GetTrackByNumber(track.mTrackNum);              if (pTrack && pTrack->GetType() == 1 && pCP->Find(pTrack)) { // VIDEO_TRACK -                MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(index);                  track.mCuePoints.push_back(pCP);              }          } @@ -435,12 +435,13 @@ void BlockIterator::seek(      }      const mkvparser::CuePoint::TrackPosition *pTP = NULL; -    const mkvparser::Track *thisTrack = pTracks->GetTrackByIndex(mIndex); +    const mkvparser::Track *thisTrack = pTracks->GetTrackByNumber(mTrackNum);      if (thisTrack->GetType() == 1) { // video          MatroskaExtractor::TrackInfo& track = mExtractor->mTracks.editItemAt(mIndex);          pTP = track.find(seekTimeNs);      } else {          // The Cue index is built around video keyframes +        unsigned long int trackCount = pTracks->GetTracksCount();          for (size_t index = 0; index < trackCount; ++index) {              const mkvparser::Track *pTrack = pTracks->GetTrackByIndex(index);              if (pTrack && pTrack->GetType() == 1 && pCues->Find(seekTimeNs, pTrack, pCP, pTP)) { diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index 6d8866a..482ccff 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -63,6 +63,7 @@ struct ATSParser::Program : public RefBase {      void signalEOS(status_t finalResult);      sp<MediaSource> getSource(SourceType type); +    bool hasSource(SourceType type) const;      int64_t convertPTSToTimestamp(uint64_t PTS); @@ -119,6 +120,9 @@ struct ATSParser::Stream : public RefBase {      sp<MediaSource> getSource(SourceType type); +    bool isAudio() const; +    bool isVideo() const; +  protected:      virtual ~Stream(); @@ -146,9 +150,6 @@ private:      void extractAACFrames(const sp<ABuffer> &buffer); -    bool isAudio() const; -    bool isVideo() const; -      DISALLOW_EVIL_CONSTRUCTORS(Stream);  }; @@ -244,11 +245,16 @@ struct StreamInfo {  status_t ATSParser::Program::parseProgramMap(ABitReader *br) {      unsigned table_id = br->getBits(8);      ALOGV("  table_id = %u", table_id); -    CHECK_EQ(table_id, 0x02u); - +    if (table_id != 0x02u) { +        ALOGE("PMT data error!"); +        return ERROR_MALFORMED; +    }      unsigned section_syntax_indicator = br->getBits(1);      ALOGV("  section_syntax_indicator = %u", section_syntax_indicator); -    CHECK_EQ(section_syntax_indicator, 1u); +    if (section_syntax_indicator != 1u) { +        ALOGE("PMT data error!"); +        return ERROR_MALFORMED; +    }      CHECK_EQ(br->getBits(1), 0u);      MY_LOGV("  reserved = %u", br->getBits(2)); @@ -435,6 +441,19 @@ sp<MediaSource> ATSParser::Program::getSource(SourceType type) {      return NULL;  } +bool ATSParser::Program::hasSource(SourceType type) const { +    for (size_t i = 0; i < mStreams.size(); ++i) { +        const sp<Stream> &stream = mStreams.valueAt(i); +        if (type == AUDIO && stream->isAudio()) { +            return true; +        } else if (type == VIDEO && stream->isVideo()) { +            return true; +        } +    } + +    return false; +} +  int64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) {      if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) {          if (!mFirstPTSValid) { @@ -660,7 +679,7 @@ void ATSParser::Stream::signalDiscontinuity(              int64_t resumeAtMediaTimeUs =                  mProgram->convertPTSToTimestamp(resumeAtPTS); -            extra->setInt64("resume-at-mediatimeUs", resumeAtMediaTimeUs); +            extra->setInt64("resume-at-mediaTimeUs", resumeAtMediaTimeUs);          }      } @@ -739,8 +758,10 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) {          if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {              CHECK_GE(optional_bytes_remaining, 5u); -            CHECK_EQ(br->getBits(4), PTS_DTS_flags); - +            if (br->getBits(4) != PTS_DTS_flags) { +                ALOGE("PES data Error!"); +                return ERROR_MALFORMED; +            }              PTS = ((uint64_t)br->getBits(3)) << 30;              CHECK_EQ(br->getBits(1), 1u);              PTS |= ((uint64_t)br->getBits(15)) << 15; @@ -1003,8 +1024,10 @@ void ATSParser::signalEOS(status_t finalResult) {  void ATSParser::parseProgramAssociationTable(ABitReader *br) {      unsigned table_id = br->getBits(8);      ALOGV("  table_id = %u", table_id); -    CHECK_EQ(table_id, 0x00u); - +    if (table_id != 0x00u) { +        ALOGE("PAT data error!"); +        return ; +    }      unsigned section_syntax_indictor = br->getBits(1);      ALOGV("  section_syntax_indictor = %u", section_syntax_indictor);      CHECK_EQ(section_syntax_indictor, 1u); @@ -1074,7 +1097,9 @@ status_t ATSParser::parsePID(          sp<PSISection> section = mPSISections.valueAt(sectionIndex);          if (payload_unit_start_indicator) { -            CHECK(section->isEmpty()); +            if (!section->isEmpty()) { +                return ERROR_UNSUPPORTED; +            }              unsigned skip = br->getBits(8);              br->skipBits(skip * 8); @@ -1203,7 +1228,10 @@ status_t ATSParser::parseTS(ABitReader *br) {      ALOGV("---");      unsigned sync_byte = br->getBits(8); -    CHECK_EQ(sync_byte, 0x47u); +    if (sync_byte != 0x47u) { +        ALOGE("[error] parseTS: return error as sync_byte=0x%x", sync_byte); +        return BAD_VALUE; +    }      if (br->getBits(1)) {  // transport_error_indicator          // silently ignore. @@ -1264,6 +1292,17 @@ sp<MediaSource> ATSParser::getSource(SourceType type) {      return NULL;  } +bool ATSParser::hasSource(SourceType type) const { +    for (size_t i = 0; i < mPrograms.size(); ++i) { +        const sp<Program> &program = mPrograms.itemAt(i); +        if (program->hasSource(type)) { +            return true; +        } +    } + +    return false; +} +  bool ATSParser::PTSTimeDeltaEstablished() {      if (mPrograms.isEmpty()) {          return false; diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h index 8986a22..5d76cbd 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.h +++ b/media/libstagefright/mpeg2ts/ATSParser.h @@ -41,8 +41,6 @@ struct ATSParser : public RefBase {          DISCONTINUITY_ABSOLUTE_TIME     = 8,          DISCONTINUITY_TIME_OFFSET       = 16, -        DISCONTINUITY_SEEK              = DISCONTINUITY_TIME, -          // For legacy reasons this also implies a time discontinuity.          DISCONTINUITY_FORMATCHANGE      =              DISCONTINUITY_AUDIO_FORMAT @@ -76,6 +74,7 @@ struct ATSParser : public RefBase {          NUM_SOURCE_TYPES = 2      };      sp<MediaSource> getSource(SourceType type); +    bool hasSource(SourceType type) const;      bool PTSTimeDeltaEstablished(); diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp index a03f6f9..f266fe7 100644 --- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp +++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp @@ -218,12 +218,19 @@ void AnotherPacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {      }      if (mLatestEnqueuedMeta == NULL) { -        mLatestEnqueuedMeta = buffer->meta(); +        mLatestEnqueuedMeta = buffer->meta()->dup();      } else {          int64_t latestTimeUs = 0; +        int64_t frameDeltaUs = 0;          CHECK(mLatestEnqueuedMeta->findInt64("timeUs", &latestTimeUs));          if (lastQueuedTimeUs > latestTimeUs) { -            mLatestEnqueuedMeta = buffer->meta(); +            mLatestEnqueuedMeta = buffer->meta()->dup(); +            frameDeltaUs = lastQueuedTimeUs - latestTimeUs; +            mLatestEnqueuedMeta->setInt64("durationUs", frameDeltaUs); +        } else if (!mLatestEnqueuedMeta->findInt64("durationUs", &frameDeltaUs)) { +            // For B frames +            frameDeltaUs = latestTimeUs - lastQueuedTimeUs; +            mLatestEnqueuedMeta->setInt64("durationUs", frameDeltaUs);          }      }  } @@ -265,8 +272,12 @@ void AnotherPacketSource::queueDiscontinuity(      mEOSResult = OK;      mLastQueuedTimeUs = 0;      mLatestEnqueuedMeta = NULL; -    ++mQueuedDiscontinuityCount; +    if (type == ATSParser::DISCONTINUITY_NONE) { +        return; +    } + +    ++mQueuedDiscontinuityCount;      sp<ABuffer> buffer = new ABuffer(0);      buffer->meta()->setInt32("discontinuity", static_cast<int32_t>(type));      buffer->meta()->setMessage("extra", extra); diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp index ef1cd3d..2ed3ccc 100644 --- a/media/libstagefright/mpeg2ts/ESQueue.cpp +++ b/media/libstagefright/mpeg2ts/ESQueue.cpp @@ -173,8 +173,9 @@ static bool IsSeeminglyValidAC3Header(const uint8_t *ptr, size_t size) {      return parseAC3SyncFrame(ptr, size, NULL) > 0;  } -static bool IsSeeminglyValidADTSHeader(const uint8_t *ptr, size_t size) { -    if (size < 3) { +static bool IsSeeminglyValidADTSHeader( +        const uint8_t *ptr, size_t size, size_t *frameLength) { +    if (size < 7) {          // Not enough data to verify header.          return false;      } @@ -197,6 +198,13 @@ static bool IsSeeminglyValidADTSHeader(const uint8_t *ptr, size_t size) {          return false;      } +    size_t frameLengthInHeader = +            ((ptr[3] & 3) << 11) + (ptr[4] << 3) + ((ptr[5] >> 5) & 7); +    if (frameLengthInHeader > size) { +        return false; +    } + +    *frameLength = frameLengthInHeader;      return true;  } @@ -318,8 +326,10 @@ status_t ElementaryStreamQueue::appendData(                  }  #else                  ssize_t startOffset = -1; +                size_t frameLength;                  for (size_t i = 0; i < size; ++i) { -                    if (IsSeeminglyValidADTSHeader(&ptr[i], size - i)) { +                    if (IsSeeminglyValidADTSHeader( +                            &ptr[i], size - i, &frameLength)) {                          startOffset = i;                          break;                      } @@ -335,6 +345,12 @@ status_t ElementaryStreamQueue::appendData(                            startOffset);                  } +                if (frameLength != size - startOffset) { +                    ALOGV("First ADTS AAC frame length is %zd bytes, " +                          "while the buffer size is %zd bytes.", +                          frameLength, size - startOffset); +                } +                  data = &ptr[startOffset];                  size -= startOffset;  #endif diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp index 3e70956..44c7edc 100644 --- a/media/libstagefright/omx/GraphicBufferSource.cpp +++ b/media/libstagefright/omx/GraphicBufferSource.cpp @@ -750,7 +750,7 @@ int GraphicBufferSource::findMatchingCodecBuffer_l(  }  // BufferQueue::ConsumerListener callback -void GraphicBufferSource::onFrameAvailable() { +void GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) {      Mutex::Autolock autoLock(mMutex);      ALOGV("onFrameAvailable exec=%d avail=%zu", diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h index c0860ab..c8e3775 100644 --- a/media/libstagefright/omx/GraphicBufferSource.h +++ b/media/libstagefright/omx/GraphicBufferSource.h @@ -137,7 +137,7 @@ protected:      // into the codec buffer, and call Empty[This]Buffer.  If we're not yet      // executing or there's no codec buffer available, we just increment      // mNumFramesAvailable and return. -    virtual void onFrameAvailable(); +    virtual void onFrameAvailable(const BufferItem& item);      // BufferQueue::ConsumerListener interface, called when the client has      // released one or more GraphicBuffers.  We clear out the appropriate diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index 41407e4..6d46eee 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -225,7 +225,7 @@ status_t OMX::allocateNode(      *node = 0; -    OMXNodeInstance *instance = new OMXNodeInstance(this, observer); +    OMXNodeInstance *instance = new OMXNodeInstance(this, observer, name);      OMX_COMPONENTTYPE *handle;      OMX_ERRORTYPE err = mMaster->makeComponentInstance( diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index 086426d..a2318b6 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -18,11 +18,15 @@  #define LOG_TAG "OMXNodeInstance"  #include <utils/Log.h> +#include <inttypes.h> +  #include "../include/OMXNodeInstance.h"  #include "OMXMaster.h"  #include "GraphicBufferSource.h"  #include <OMX_Component.h> +#include <OMX_IndexExt.h> +#include <OMX_AsString.h>  #include <binder/IMemory.h>  #include <gui/BufferQueue.h> @@ -30,7 +34,68 @@  #include <media/stagefright/foundation/ADebug.h>  #include <media/stagefright/MediaErrors.h> +#include <utils/misc.h> +  static const OMX_U32 kPortIndexInput = 0; +static const OMX_U32 kPortIndexOutput = 1; + +#define CLOGW(fmt, ...) ALOGW("[%x:%s] " fmt, mNodeID, mName, ##__VA_ARGS__) + +#define CLOG_ERROR_IF(cond, fn, err, fmt, ...) \ +    ALOGE_IF(cond, #fn "(%x:%s, " fmt ") ERROR: %s(%#x)", \ +    mNodeID, mName, ##__VA_ARGS__, asString(err), err) +#define CLOG_ERROR(fn, err, fmt, ...) CLOG_ERROR_IF(true, fn, err, fmt, ##__VA_ARGS__) +#define CLOG_IF_ERROR(fn, err, fmt, ...) \ +    CLOG_ERROR_IF((err) != OMX_ErrorNone, fn, err, fmt, ##__VA_ARGS__) + +#define CLOGI_(level, fn, fmt, ...) \ +    ALOGI_IF(DEBUG >= (level), #fn "(%x:%s, " fmt ")", mNodeID, mName, ##__VA_ARGS__) +#define CLOGD_(level, fn, fmt, ...) \ +    ALOGD_IF(DEBUG >= (level), #fn "(%x:%s, " fmt ")", mNodeID, mName, ##__VA_ARGS__) + +#define CLOG_LIFE(fn, fmt, ...)     CLOGI_(ADebug::kDebugLifeCycle,     fn, fmt, ##__VA_ARGS__) +#define CLOG_STATE(fn, fmt, ...)    CLOGI_(ADebug::kDebugState,         fn, fmt, ##__VA_ARGS__) +#define CLOG_CONFIG(fn, fmt, ...)   CLOGI_(ADebug::kDebugConfig,        fn, fmt, ##__VA_ARGS__) +#define CLOG_INTERNAL(fn, fmt, ...) CLOGD_(ADebug::kDebugInternalState, fn, fmt, ##__VA_ARGS__) + +#define CLOG_DEBUG_IF(cond, fn, fmt, ...) \ +    ALOGD_IF(cond, #fn "(%x, " fmt ")", mNodeID, ##__VA_ARGS__) + +#define CLOG_BUFFER(fn, fmt, ...) \ +    CLOG_DEBUG_IF(DEBUG >= ADebug::kDebugAll, fn, fmt, ##__VA_ARGS__) +#define CLOG_BUMPED_BUFFER(fn, fmt, ...) \ +    CLOG_DEBUG_IF(DEBUG_BUMP >= ADebug::kDebugAll, fn, fmt, ##__VA_ARGS__) + +/* buffer formatting */ +#define BUFFER_FMT(port, fmt, ...) "%s:%u " fmt, portString(port), (port), ##__VA_ARGS__ +#define NEW_BUFFER_FMT(buffer_id, port, fmt, ...) \ +    BUFFER_FMT(port, fmt ") (#%zu => %#x", ##__VA_ARGS__, mActiveBuffers.size(), (buffer_id)) + +#define SIMPLE_BUFFER(port, size, data) BUFFER_FMT(port, "%zu@%p", (size), (data)) +#define SIMPLE_NEW_BUFFER(buffer_id, port, size, data) \ +    NEW_BUFFER_FMT(buffer_id, port, "%zu@%p", (size), (data)) + +#define EMPTY_BUFFER(addr, header) "%#x [%u@%p]", \ +    (addr), (header)->nAllocLen, (header)->pBuffer +#define FULL_BUFFER(addr, header) "%#" PRIxPTR " [%u@%p (%u..+%u) f=%x ts=%lld]", \ +    (intptr_t)(addr), (header)->nAllocLen, (header)->pBuffer, \ +    (header)->nOffset, (header)->nFilledLen, (header)->nFlags, (header)->nTimeStamp + +#define WITH_STATS_WRAPPER(fmt, ...) fmt " { IN=%zu/%zu OUT=%zu/%zu }", ##__VA_ARGS__, \ +    mInputBuffersWithCodec.size(), mNumPortBuffers[kPortIndexInput], \ +    mOutputBuffersWithCodec.size(), mNumPortBuffers[kPortIndexOutput] +// TRICKY: this is needed so formatting macros expand before substitution +#define WITH_STATS(fmt, ...) WITH_STATS_WRAPPER(fmt, ##__VA_ARGS__) + +template<class T> +static void InitOMXParams(T *params) { +    memset(params, 0, sizeof(T)); +    params->nSize = sizeof(T); +    params->nVersion.s.nVersionMajor = 1; +    params->nVersion.s.nVersionMinor = 0; +    params->nVersion.s.nRevision = 0; +    params->nVersion.s.nStep = 0; +}  namespace android { @@ -56,8 +121,8 @@ struct BufferMeta {          }          memcpy((OMX_U8 *)mMem->pointer() + header->nOffset, -               header->pBuffer + header->nOffset, -               header->nFilledLen); +                header->pBuffer + header->nOffset, +                header->nFilledLen);      }      void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) { @@ -66,8 +131,8 @@ struct BufferMeta {          }          memcpy(header->pBuffer + header->nOffset, -               (const OMX_U8 *)mMem->pointer() + header->nOffset, -               header->nFilledLen); +                (const OMX_U8 *)mMem->pointer() + header->nOffset, +                header->nFilledLen);      }      void setGraphicBuffer(const sp<GraphicBuffer> &graphicBuffer) { @@ -89,8 +154,17 @@ OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {      &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone  }; +static inline const char *portString(OMX_U32 portIndex) { +    switch (portIndex) { +        case kPortIndexInput:  return "Input"; +        case kPortIndexOutput: return "Output"; +        case ~0:               return "All"; +        default:               return "port"; +    } +} +  OMXNodeInstance::OMXNodeInstance( -        OMX *owner, const sp<IOMXObserver> &observer) +        OMX *owner, const sp<IOMXObserver> &observer, const char *name)      : mOwner(owner),        mNodeID(0),        mHandle(NULL), @@ -98,15 +172,25 @@ OMXNodeInstance::OMXNodeInstance(        mDying(false),        mBufferIDCount(0)  { +    mName = ADebug::GetDebugName(name); +    DEBUG = ADebug::GetDebugLevelFromProperty(name, "debug.stagefright.omx-debug"); +    ALOGV("debug level for %s is %d", name, DEBUG); +    DEBUG_BUMP = DEBUG; +    mNumPortBuffers[0] = 0; +    mNumPortBuffers[1] = 0; +    mDebugLevelBumpPendingBuffers[0] = 0; +    mDebugLevelBumpPendingBuffers[1] = 0;  }  OMXNodeInstance::~OMXNodeInstance() { +    free(mName);      CHECK(mHandle == NULL);  }  void OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) { -    CHECK(mHandle == NULL);      mNodeID = node_id; +    CLOG_LIFE(allocateNode, "handle=%p", handle); +    CHECK(mHandle == NULL);      mHandle = handle;  } @@ -118,6 +202,7 @@ sp<GraphicBufferSource> OMXNodeInstance::getGraphicBufferSource() {  void OMXNodeInstance::setGraphicBufferSource(          const sp<GraphicBufferSource>& bufferSource) {      Mutex::Autolock autoLock(mGraphicBufferSourceLock); +    CLOG_INTERNAL(setGraphicBufferSource, "%p", bufferSource.get());      mGraphicBufferSource = bufferSource;  } @@ -138,6 +223,7 @@ static status_t StatusFromOMXError(OMX_ERRORTYPE err) {          case OMX_ErrorNone:              return OK;          case OMX_ErrorUnsupportedSetting: +        case OMX_ErrorUnsupportedIndex:              return ERROR_UNSUPPORTED;          default:              return UNKNOWN_ERROR; @@ -145,6 +231,7 @@ static status_t StatusFromOMXError(OMX_ERRORTYPE err) {  }  status_t OMXNodeInstance::freeNode(OMXMaster *master) { +    CLOG_LIFE(freeNode, "handle=%p", mHandle);      static int32_t kMaxNumIterations = 10;      // exit if we have already freed the node @@ -173,10 +260,11 @@ status_t OMXNodeInstance::freeNode(OMXMaster *master) {              OMX_ERRORTYPE err;              int32_t iteration = 0;              while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone -                   && state != OMX_StateIdle -                   && state != OMX_StateInvalid) { +                    && state != OMX_StateIdle +                    && state != OMX_StateInvalid) {                  if (++iteration > kMaxNumIterations) { -                    ALOGE("component failed to enter Idle state, aborting."); +                    CLOGW("failed to enter Idle state (now %s(%d), aborting.", +                            asString(state), state);                      state = OMX_StateInvalid;                      break;                  } @@ -202,10 +290,11 @@ status_t OMXNodeInstance::freeNode(OMXMaster *master) {              OMX_ERRORTYPE err;              int32_t iteration = 0;              while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone -                   && state != OMX_StateLoaded -                   && state != OMX_StateInvalid) { +                    && state != OMX_StateLoaded +                    && state != OMX_StateInvalid) {                  if (++iteration > kMaxNumIterations) { -                    ALOGE("component failed to enter Loaded state, aborting."); +                    CLOGW("failed to enter Loaded state (now %s(%d), aborting.", +                            asString(state), state);                      state = OMX_StateInvalid;                      break;                  } @@ -223,20 +312,18 @@ status_t OMXNodeInstance::freeNode(OMXMaster *master) {              break;          default: -            CHECK(!"should not be here, unknown state."); +            LOG_ALWAYS_FATAL("unknown state %s(%#x).", asString(state), state);              break;      } -    ALOGV("calling destroyComponentInstance"); +    ALOGV("[%x:%s] calling destroyComponentInstance", mNodeID, mName);      OMX_ERRORTYPE err = master->destroyComponentInstance(              static_cast<OMX_COMPONENTTYPE *>(mHandle)); -    ALOGV("destroyComponentInstance returned err %d", err);      mHandle = NULL; - -    if (err != OMX_ErrorNone) { -        ALOGE("FreeHandle FAILED with error 0x%08x.", err); -    } +    CLOG_IF_ERROR(freeNode, err, ""); +    free(mName); +    mName = NULL;      mOwner->invalidateNodeID(mNodeID);      mNodeID = 0; @@ -268,7 +355,17 @@ status_t OMXNodeInstance::sendCommand(      Mutex::Autolock autoLock(mLock); +    // bump internal-state debug level for 2 input and output frames past a command +    { +        Mutex::Autolock _l(mDebugLock); +        bumpDebugLevel_l(2 /* numInputBuffers */, 2 /* numOutputBuffers */); +    } + +    const char *paramString = +        cmd == OMX_CommandStateSet ? asString((OMX_STATETYPE)param) : portString(param); +    CLOG_STATE(sendCommand, "%s(%d), %s(%d)", asString(cmd), cmd, paramString, param);      OMX_ERRORTYPE err = OMX_SendCommand(mHandle, cmd, param, NULL); +    CLOG_IF_ERROR(sendCommand, err, "%s(%d), %s(%d)", asString(cmd), cmd, paramString, param);      return StatusFromOMXError(err);  } @@ -277,17 +374,23 @@ status_t OMXNodeInstance::getParameter(      Mutex::Autolock autoLock(mLock);      OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params); -    ALOGE_IF(err != OMX_ErrorNone, "getParameter(%d) ERROR: %#x", index, err); +    OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; +    // some errors are expected for getParameter +    if (err != OMX_ErrorNoMore) { +        CLOG_IF_ERROR(getParameter, err, "%s(%#x)", asString(extIndex), index); +    }      return StatusFromOMXError(err);  }  status_t OMXNodeInstance::setParameter( -        OMX_INDEXTYPE index, const void *params, size_t /* size */) { +        OMX_INDEXTYPE index, const void *params, size_t size) {      Mutex::Autolock autoLock(mLock); +    OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; +    CLOG_CONFIG(setParameter, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params);      OMX_ERRORTYPE err = OMX_SetParameter(              mHandle, index, const_cast<void *>(params)); -    ALOGE_IF(err != OMX_ErrorNone, "setParameter(%d) ERROR: %#x", index, err); +    CLOG_IF_ERROR(setParameter, err, "%s(%#x)", asString(extIndex), index);      return StatusFromOMXError(err);  } @@ -296,16 +399,23 @@ status_t OMXNodeInstance::getConfig(      Mutex::Autolock autoLock(mLock);      OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params); +    OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; +    // some errors are expected for getConfig +    if (err != OMX_ErrorNoMore) { +        CLOG_IF_ERROR(getConfig, err, "%s(%#x)", asString(extIndex), index); +    }      return StatusFromOMXError(err);  }  status_t OMXNodeInstance::setConfig( -        OMX_INDEXTYPE index, const void *params, size_t /* size */) { +        OMX_INDEXTYPE index, const void *params, size_t size) {      Mutex::Autolock autoLock(mLock); +    OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index; +    CLOG_CONFIG(setConfig, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params);      OMX_ERRORTYPE err = OMX_SetConfig(              mHandle, index, const_cast<void *>(params)); - +    CLOG_IF_ERROR(setConfig, err, "%s(%#x)", asString(extIndex), index);      return StatusFromOMXError(err);  } @@ -313,13 +423,14 @@ status_t OMXNodeInstance::getState(OMX_STATETYPE* state) {      Mutex::Autolock autoLock(mLock);      OMX_ERRORTYPE err = OMX_GetState(mHandle, state); - +    CLOG_IF_ERROR(getState, err, "");      return StatusFromOMXError(err);  }  status_t OMXNodeInstance::enableGraphicBuffers(          OMX_U32 portIndex, OMX_BOOL enable) {      Mutex::Autolock autoLock(mLock); +    CLOG_CONFIG(enableGraphicBuffers, "%s:%u, %d", portString(portIndex), portIndex, enable);      OMX_STRING name = const_cast<OMX_STRING>(              "OMX.google.android.index.enableAndroidNativeBuffers"); @@ -327,32 +438,19 @@ status_t OMXNodeInstance::enableGraphicBuffers(      OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);      if (err != OMX_ErrorNone) { -        if (enable) { -            ALOGE("OMX_GetExtensionIndex %s failed", name); -        } - +        CLOG_ERROR_IF(enable, getExtensionIndex, err, "%s", name);          return StatusFromOMXError(err);      } -    OMX_VERSIONTYPE ver; -    ver.s.nVersionMajor = 1; -    ver.s.nVersionMinor = 0; -    ver.s.nRevision = 0; -    ver.s.nStep = 0; -    EnableAndroidNativeBuffersParams params = { -        sizeof(EnableAndroidNativeBuffersParams), ver, portIndex, enable, -    }; +    EnableAndroidNativeBuffersParams params; +    InitOMXParams(¶ms); +    params.nPortIndex = portIndex; +    params.enable = enable;      err = OMX_SetParameter(mHandle, index, ¶ms); - -    if (err != OMX_ErrorNone) { -        ALOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)", -                err, err); - -        return UNKNOWN_ERROR; -    } - -    return OK; +    CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d", name, index, +            portString(portIndex), portIndex, enable); +    return StatusFromOMXError(err);  }  status_t OMXNodeInstance::getGraphicBufferUsage( @@ -365,26 +463,19 @@ status_t OMXNodeInstance::getGraphicBufferUsage(      OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);      if (err != OMX_ErrorNone) { -        ALOGE("OMX_GetExtensionIndex %s failed", name); - +        CLOG_ERROR(getExtensionIndex, err, "%s", name);          return StatusFromOMXError(err);      } -    OMX_VERSIONTYPE ver; -    ver.s.nVersionMajor = 1; -    ver.s.nVersionMinor = 0; -    ver.s.nRevision = 0; -    ver.s.nStep = 0; -    GetAndroidNativeBufferUsageParams params = { -        sizeof(GetAndroidNativeBufferUsageParams), ver, portIndex, 0, -    }; +    GetAndroidNativeBufferUsageParams params; +    InitOMXParams(¶ms); +    params.nPortIndex = portIndex;      err = OMX_GetParameter(mHandle, index, ¶ms); -      if (err != OMX_ErrorNone) { -        ALOGE("OMX_GetAndroidNativeBufferUsage failed with error %d (0x%08x)", -                err, err); -        return UNKNOWN_ERROR; +        CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u", name, index, +                portString(portIndex), portIndex); +        return StatusFromOMXError(err);      }      *usage = params.nUsage; @@ -396,6 +487,7 @@ status_t OMXNodeInstance::storeMetaDataInBuffers(          OMX_U32 portIndex,          OMX_BOOL enable) {      Mutex::Autolock autolock(mLock); +    CLOG_CONFIG(storeMetaDataInBuffers, "%s:%u en:%d", portString(portIndex), portIndex, enable);      return storeMetaDataInBuffers_l(              portIndex, enable,              OMX_FALSE /* useGraphicBuffer */, NULL /* usingGraphicBufferInMetadata */); @@ -422,37 +514,42 @@ status_t OMXNodeInstance::storeMetaDataInBuffers_l(                  : OMX_ErrorBadParameter;      if (err == OMX_ErrorNone) {          *usingGraphicBufferInMetadata = OMX_TRUE; +        name = graphicBufferName;      } else { -        *usingGraphicBufferInMetadata = OMX_FALSE;          err = OMX_GetExtensionIndex(mHandle, name, &index);      } -    if (err != OMX_ErrorNone) { -        ALOGE("OMX_GetExtensionIndex %s failed", name); -        return StatusFromOMXError(err); -    } - -    StoreMetaDataInBuffersParams params; -    memset(¶ms, 0, sizeof(params)); -    params.nSize = sizeof(params); +    OMX_ERRORTYPE xerr = err; +    if (err == OMX_ErrorNone) { +        StoreMetaDataInBuffersParams params; +        InitOMXParams(¶ms); +        params.nPortIndex = portIndex; +        params.bStoreMetaData = enable; -    // Version: 1.0.0.0 -    params.nVersion.s.nVersionMajor = 1; +        err = OMX_SetParameter(mHandle, index, ¶ms); +    } -    params.nPortIndex = portIndex; -    params.bStoreMetaData = enable; -    if ((err = OMX_SetParameter(mHandle, index, ¶ms)) != OMX_ErrorNone) { -        ALOGE("OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x%08x", err); +    // don't log loud error if component does not support metadata mode on the output +    if (err != OMX_ErrorNone) {          *usingGraphicBufferInMetadata = OMX_FALSE; -        return UNKNOWN_ERROR; +        if (err == OMX_ErrorUnsupportedIndex && portIndex == kPortIndexOutput) { +            CLOGW("component does not support metadata mode; using fallback"); +        } else if (xerr != OMX_ErrorNone) { +            CLOG_ERROR(getExtensionIndex, xerr, "%s", name); +        } else { +            CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d GB=%d", name, index, +                    portString(portIndex), portIndex, enable, useGraphicBuffer); +        }      } -    return err; +    return StatusFromOMXError(err);  }  status_t OMXNodeInstance::prepareForAdaptivePlayback(          OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth,          OMX_U32 maxFrameHeight) {      Mutex::Autolock autolock(mLock); +    CLOG_CONFIG(prepareForAdaptivePlayback, "%s:%u en=%d max=%ux%u", +            portString(portIndex), portIndex, enable, maxFrameWidth, maxFrameHeight);      OMX_INDEXTYPE index;      OMX_STRING name = const_cast<OMX_STRING>( @@ -460,33 +557,29 @@ status_t OMXNodeInstance::prepareForAdaptivePlayback(      OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);      if (err != OMX_ErrorNone) { -        ALOGW_IF(enable, "OMX_GetExtensionIndex %s failed", name); +        CLOG_ERROR_IF(enable, getExtensionIndex, err, "%s", name);          return StatusFromOMXError(err);      }      PrepareForAdaptivePlaybackParams params; -    params.nSize = sizeof(params); -    params.nVersion.s.nVersionMajor = 1; -    params.nVersion.s.nVersionMinor = 0; -    params.nVersion.s.nRevision = 0; -    params.nVersion.s.nStep = 0; - +    InitOMXParams(¶ms);      params.nPortIndex = portIndex;      params.bEnable = enable;      params.nMaxFrameWidth = maxFrameWidth;      params.nMaxFrameHeight = maxFrameHeight; -    if ((err = OMX_SetParameter(mHandle, index, ¶ms)) != OMX_ErrorNone) { -        ALOGW("OMX_SetParameter failed for PrepareForAdaptivePlayback " -              "with error %d (0x%08x)", err, err); -        return UNKNOWN_ERROR; -    } -    return err; + +    err = OMX_SetParameter(mHandle, index, ¶ms); +    CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d max=%ux%u", name, index, +            portString(portIndex), portIndex, enable, maxFrameWidth, maxFrameHeight); +    return StatusFromOMXError(err);  }  status_t OMXNodeInstance::configureVideoTunnelMode(          OMX_U32 portIndex, OMX_BOOL tunneled, OMX_U32 audioHwSync,          native_handle_t **sidebandHandle) {      Mutex::Autolock autolock(mLock); +    CLOG_CONFIG(configureVideoTunnelMode, "%s:%u tun=%d sync=%u", +            portString(portIndex), portIndex, tunneled, audioHwSync);      OMX_INDEXTYPE index;      OMX_STRING name = const_cast<OMX_STRING>( @@ -494,36 +587,33 @@ status_t OMXNodeInstance::configureVideoTunnelMode(      OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);      if (err != OMX_ErrorNone) { -        ALOGE("configureVideoTunnelMode extension is missing!"); +        CLOG_ERROR_IF(tunneled, getExtensionIndex, err, "%s", name);          return StatusFromOMXError(err);      }      ConfigureVideoTunnelModeParams tunnelParams; -    tunnelParams.nSize = sizeof(tunnelParams); -    tunnelParams.nVersion.s.nVersionMajor = 1; -    tunnelParams.nVersion.s.nVersionMinor = 0; -    tunnelParams.nVersion.s.nRevision = 0; -    tunnelParams.nVersion.s.nStep = 0; - +    InitOMXParams(&tunnelParams);      tunnelParams.nPortIndex = portIndex;      tunnelParams.bTunneled = tunneled;      tunnelParams.nAudioHwSync = audioHwSync;      err = OMX_SetParameter(mHandle, index, &tunnelParams);      if (err != OMX_ErrorNone) { -        ALOGE("configureVideoTunnelMode failed! (err %d).", err); -        return UNKNOWN_ERROR; +        CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u tun=%d sync=%u", name, index, +                portString(portIndex), portIndex, tunneled, audioHwSync); +        return StatusFromOMXError(err);      }      err = OMX_GetParameter(mHandle, index, &tunnelParams);      if (err != OMX_ErrorNone) { -        ALOGE("GetVideoTunnelWindow failed! (err %d).", err); -        return UNKNOWN_ERROR; +        CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u tun=%d sync=%u", name, index, +                portString(portIndex), portIndex, tunneled, audioHwSync); +        return StatusFromOMXError(err);      }      if (sidebandHandle) {          *sidebandHandle = (native_handle_t*)tunnelParams.pSidebandWindow;      } -    return err; +    return OK;  }  status_t OMXNodeInstance::useBuffer( @@ -540,14 +630,14 @@ status_t OMXNodeInstance::useBuffer(              params->size(), static_cast<OMX_U8 *>(params->pointer()));      if (err != OMX_ErrorNone) { -        ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err); +        CLOG_ERROR(useBuffer, err, SIMPLE_BUFFER(portIndex, params->size(), params->pointer()));          delete buffer_meta;          buffer_meta = NULL;          *buffer = 0; -        return UNKNOWN_ERROR; +        return StatusFromOMXError(err);      }      CHECK_EQ(header->pAppPrivate, buffer_meta); @@ -561,6 +651,8 @@ status_t OMXNodeInstance::useBuffer(          bufferSource->addCodecBuffer(header);      } +    CLOG_BUFFER(useBuffer, NEW_BUFFER_FMT( +            *buffer, portIndex, "%zu@%p", params->size(), params->pointer()));      return OK;  } @@ -570,17 +662,14 @@ status_t OMXNodeInstance::useGraphicBuffer2_l(      // port definition      OMX_PARAM_PORTDEFINITIONTYPE def; -    def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); -    def.nVersion.s.nVersionMajor = 1; -    def.nVersion.s.nVersionMinor = 0; -    def.nVersion.s.nRevision = 0; -    def.nVersion.s.nStep = 0; +    InitOMXParams(&def);      def.nPortIndex = portIndex;      OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def); -    if (err != OMX_ErrorNone) -    { -        ALOGE("%s::%d:Error getting OMX_IndexParamPortDefinition", __FUNCTION__, __LINE__); -        return err; +    if (err != OMX_ErrorNone) { +        OMX_INDEXTYPE index = OMX_IndexParamPortDefinition; +        CLOG_ERROR(getParameter, err, "%s(%#x): %s:%u", +                asString(index), index, portString(portIndex), portIndex); +        return UNKNOWN_ERROR;      }      BufferMeta *bufferMeta = new BufferMeta(graphicBuffer); @@ -598,11 +687,11 @@ status_t OMXNodeInstance::useGraphicBuffer2_l(              bufferHandle);      if (err != OMX_ErrorNone) { -        ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err); +        CLOG_ERROR(useBuffer, err, BUFFER_FMT(portIndex, "%u@%p", def.nBufferSize, bufferHandle));          delete bufferMeta;          bufferMeta = NULL;          *buffer = 0; -        return UNKNOWN_ERROR; +        return StatusFromOMXError(err);      }      CHECK_EQ(header->pBuffer, bufferHandle); @@ -611,7 +700,8 @@ status_t OMXNodeInstance::useGraphicBuffer2_l(      *buffer = makeBufferID(header);      addActiveBuffer(portIndex, *buffer); - +    CLOG_BUFFER(useGraphicBuffer2, NEW_BUFFER_FMT( +            *buffer, portIndex, "%u@%p", def.nBufferSize, bufferHandle));      return OK;  } @@ -635,10 +725,8 @@ status_t OMXNodeInstance::useGraphicBuffer(      OMX_STRING name = const_cast<OMX_STRING>(          "OMX.google.android.index.useAndroidNativeBuffer");      OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index); -      if (err != OMX_ErrorNone) { -        ALOGE("OMX_GetExtensionIndex %s failed", name); - +        CLOG_ERROR(getExtensionIndex, err, "%s", name);          return StatusFromOMXError(err);      } @@ -659,15 +747,15 @@ status_t OMXNodeInstance::useGraphicBuffer(      err = OMX_SetParameter(mHandle, index, ¶ms);      if (err != OMX_ErrorNone) { -        ALOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err, -                err); +        CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u meta=%p GB=%p", name, index, +                portString(portIndex), portIndex, bufferMeta, graphicBuffer->handle);          delete bufferMeta;          bufferMeta = NULL;          *buffer = 0; -        return UNKNOWN_ERROR; +        return StatusFromOMXError(err);      }      CHECK_EQ(header->pAppPrivate, bufferMeta); @@ -675,12 +763,13 @@ status_t OMXNodeInstance::useGraphicBuffer(      *buffer = makeBufferID(header);      addActiveBuffer(portIndex, *buffer); - +    CLOG_BUFFER(useGraphicBuffer, NEW_BUFFER_FMT( +            *buffer, portIndex, "GB=%p", graphicBuffer->handle));      return OK;  }  status_t OMXNodeInstance::updateGraphicBufferInMeta( -        OMX_U32 /* portIndex */, const sp<GraphicBuffer>& graphicBuffer, +        OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,          OMX::buffer_id buffer) {      Mutex::Autolock autoLock(mLock); @@ -691,7 +780,8 @@ status_t OMXNodeInstance::updateGraphicBufferInMeta(      bufferMeta->setGraphicBuffer(graphicBuffer);      metadata->eType = kMetadataBufferTypeGrallocSource;      metadata->pHandle = graphicBuffer->handle; - +    CLOG_BUFFER(updateGraphicBufferInMeta, "%s:%u, %#x := %p", +            portString(portIndex), portIndex, buffer, graphicBuffer->handle);      return OK;  } @@ -717,19 +807,21 @@ status_t OMXNodeInstance::createInputSurface(      // Retrieve the width and height of the graphic buffer, set when the      // codec was configured.      OMX_PARAM_PORTDEFINITIONTYPE def; -    def.nSize = sizeof(def); -    def.nVersion.s.nVersionMajor = 1; -    def.nVersion.s.nVersionMinor = 0; -    def.nVersion.s.nRevision = 0; -    def.nVersion.s.nStep = 0; +    InitOMXParams(&def);      def.nPortIndex = portIndex;      OMX_ERRORTYPE oerr = OMX_GetParameter(              mHandle, OMX_IndexParamPortDefinition, &def); -    CHECK(oerr == OMX_ErrorNone); +    if (oerr != OMX_ErrorNone) { +        OMX_INDEXTYPE index = OMX_IndexParamPortDefinition; +        CLOG_ERROR(getParameter, oerr, "%s(%#x): %s:%u", +                asString(index), index, portString(portIndex), portIndex); +        return UNKNOWN_ERROR; +    }      if (def.format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque) { -        ALOGE("createInputSurface requires COLOR_FormatSurface " -              "(AndroidOpaque) color format"); +        CLOGW("createInputSurface requires COLOR_FormatSurface " +                "(AndroidOpaque) color format instead of %s(%#x)", +                asString(def.format.video.eColorFormat), def.format.video.eColorFormat);          return INVALID_OPERATION;      } @@ -752,9 +844,9 @@ status_t OMXNodeInstance::signalEndOfInputStream() {      // flag set).  Seems easier than doing the equivalent from here.      sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());      if (bufferSource == NULL) { -        ALOGW("signalEndOfInputStream can only be used with Surface input"); +        CLOGW("signalEndOfInputStream can only be used with Surface input");          return INVALID_OPERATION; -    }; +    }      return bufferSource->signalEndOfInputStream();  } @@ -771,14 +863,13 @@ status_t OMXNodeInstance::allocateBuffer(              mHandle, &header, portIndex, buffer_meta, size);      if (err != OMX_ErrorNone) { -        ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err); - +        CLOG_ERROR(allocateBuffer, err, BUFFER_FMT(portIndex, "%zu@", size));          delete buffer_meta;          buffer_meta = NULL;          *buffer = 0; -        return UNKNOWN_ERROR; +        return StatusFromOMXError(err);      }      CHECK_EQ(header->pAppPrivate, buffer_meta); @@ -792,6 +883,7 @@ status_t OMXNodeInstance::allocateBuffer(      if (bufferSource != NULL && portIndex == kPortIndexInput) {          bufferSource->addCodecBuffer(header);      } +    CLOG_BUFFER(allocateBuffer, NEW_BUFFER_FMT(*buffer, portIndex, "%zu@%p", size, *buffer_data));      return OK;  } @@ -809,14 +901,14 @@ status_t OMXNodeInstance::allocateBufferWithBackup(              mHandle, &header, portIndex, buffer_meta, params->size());      if (err != OMX_ErrorNone) { -        ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err); - +        CLOG_ERROR(allocateBufferWithBackup, err, +                SIMPLE_BUFFER(portIndex, params->size(), params->pointer()));          delete buffer_meta;          buffer_meta = NULL;          *buffer = 0; -        return UNKNOWN_ERROR; +        return StatusFromOMXError(err);      }      CHECK_EQ(header->pAppPrivate, buffer_meta); @@ -830,12 +922,16 @@ status_t OMXNodeInstance::allocateBufferWithBackup(          bufferSource->addCodecBuffer(header);      } +    CLOG_BUFFER(allocateBufferWithBackup, NEW_BUFFER_FMT(*buffer, portIndex, "%zu@%p :> %p", +            params->size(), params->pointer(), header->pBuffer)); +      return OK;  }  status_t OMXNodeInstance::freeBuffer(          OMX_U32 portIndex, OMX::buffer_id buffer) {      Mutex::Autolock autoLock(mLock); +    CLOG_BUFFER(freeBuffer, "%s:%u %#x", portString(portIndex), portIndex, buffer);      removeActiveBuffer(portIndex, buffer); @@ -843,6 +939,7 @@ status_t OMXNodeInstance::freeBuffer(      BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);      OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header); +    CLOG_IF_ERROR(freeBuffer, err, "%s:%u %#x", portString(portIndex), portIndex, buffer);      delete buffer_meta;      buffer_meta = NULL; @@ -859,8 +956,18 @@ status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {      header->nOffset = 0;      header->nFlags = 0; -    OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header); +    { +        Mutex::Autolock _l(mDebugLock); +        mOutputBuffersWithCodec.add(header); +        CLOG_BUMPED_BUFFER(fillBuffer, WITH_STATS(EMPTY_BUFFER(buffer, header))); +    } +    OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header); +    if (err != OMX_ErrorNone) { +        CLOG_ERROR(fillBuffer, err, EMPTY_BUFFER(buffer, header)); +        Mutex::Autolock _l(mDebugLock); +        mOutputBuffersWithCodec.remove(header); +    }      return StatusFromOMXError(err);  } @@ -879,14 +986,66 @@ status_t OMXNodeInstance::emptyBuffer(      }      header->nFilledLen = rangeLength;      header->nOffset = rangeOffset; -    header->nFlags = flags; -    header->nTimeStamp = timestamp;      BufferMeta *buffer_meta =          static_cast<BufferMeta *>(header->pAppPrivate);      buffer_meta->CopyToOMX(header); +    return emptyBuffer_l(header, flags, timestamp, (intptr_t)buffer); +} + +// log queued buffer activity for the next few input and/or output frames +// if logging at internal state level +void OMXNodeInstance::bumpDebugLevel_l(size_t numInputBuffers, size_t numOutputBuffers) { +    if (DEBUG == ADebug::kDebugInternalState) { +        DEBUG_BUMP = ADebug::kDebugAll; +        if (numInputBuffers > 0) { +            mDebugLevelBumpPendingBuffers[kPortIndexInput] = numInputBuffers; +        } +        if (numOutputBuffers > 0) { +            mDebugLevelBumpPendingBuffers[kPortIndexOutput] = numOutputBuffers; +        } +    } +} + +void OMXNodeInstance::unbumpDebugLevel_l(size_t portIndex) { +    if (mDebugLevelBumpPendingBuffers[portIndex]) { +        --mDebugLevelBumpPendingBuffers[portIndex]; +    } +    if (!mDebugLevelBumpPendingBuffers[0] +            && !mDebugLevelBumpPendingBuffers[1]) { +        DEBUG_BUMP = DEBUG; +    } +} + +status_t OMXNodeInstance::emptyBuffer_l( +        OMX_BUFFERHEADERTYPE *header, OMX_U32 flags, OMX_TICKS timestamp, intptr_t debugAddr) { +    header->nFlags = flags; +    header->nTimeStamp = timestamp; + +    { +        Mutex::Autolock _l(mDebugLock); +        mInputBuffersWithCodec.add(header); + +        // bump internal-state debug level for 2 input frames past a buffer with CSD +        if ((flags & OMX_BUFFERFLAG_CODECCONFIG) != 0) { +            bumpDebugLevel_l(2 /* numInputBuffers */, 0 /* numOutputBuffers */); +        } + +        CLOG_BUMPED_BUFFER(emptyBuffer, WITH_STATS(FULL_BUFFER(debugAddr, header))); +    } +      OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header); +    CLOG_IF_ERROR(emptyBuffer, err, FULL_BUFFER(debugAddr, header)); + +    { +        Mutex::Autolock _l(mDebugLock); +        if (err != OMX_ErrorNone) { +            mInputBuffersWithCodec.remove(header); +        } else if (!(flags & OMX_BUFFERFLAG_CODECCONFIG)) { +            unbumpDebugLevel_l(kPortIndexInput); +        } +    }      return StatusFromOMXError(err);  } @@ -900,15 +1059,8 @@ status_t OMXNodeInstance::emptyDirectBuffer(      header->nFilledLen = rangeLength;      header->nOffset = rangeOffset; -    header->nFlags = flags; -    header->nTimeStamp = timestamp; - -    OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header); -    if (err != OMX_ErrorNone) { -        ALOGW("emptyDirectBuffer failed, OMX err=0x%x", err); -    } -    return StatusFromOMXError(err); +    return emptyBuffer_l(header, flags, timestamp, (intptr_t)header->pBuffer);  }  status_t OMXNodeInstance::getExtensionIndex( @@ -921,11 +1073,25 @@ status_t OMXNodeInstance::getExtensionIndex(      return StatusFromOMXError(err);  } +inline static const char *asString(IOMX::InternalOptionType i, const char *def = "??") { +    switch (i) { +        case IOMX::INTERNAL_OPTION_SUSPEND:           return "SUSPEND"; +        case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY: +            return "REPEAT_PREVIOUS_FRAME_DELAY"; +        case IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP: return "MAX_TIMESTAMP_GAP"; +        case IOMX::INTERNAL_OPTION_START_TIME:        return "START_TIME"; +        case IOMX::INTERNAL_OPTION_TIME_LAPSE:        return "TIME_LAPSE"; +        default:                                      return def; +    } +} +  status_t OMXNodeInstance::setInternalOption(          OMX_U32 portIndex,          IOMX::InternalOptionType type,          const void *data,          size_t size) { +    CLOG_CONFIG(setInternalOption, "%s(%d): %s:%u %zu@%p", +            asString(type), type, portString(portIndex), portIndex, size, data);      switch (type) {          case IOMX::INTERNAL_OPTION_SUSPEND:          case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY: @@ -937,6 +1103,7 @@ status_t OMXNodeInstance::setInternalOption(                  getGraphicBufferSource();              if (bufferSource == NULL || portIndex != kPortIndexInput) { +                CLOGW("setInternalOption is only for Surface input");                  return ERROR_UNSUPPORTED;              } @@ -946,6 +1113,7 @@ status_t OMXNodeInstance::setInternalOption(                  }                  bool suspend = *(bool *)data; +                CLOG_CONFIG(setInternalOption, "suspend=%d", suspend);                  bufferSource->suspend(suspend);              } else if (type ==                      IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY){ @@ -954,7 +1122,7 @@ status_t OMXNodeInstance::setInternalOption(                  }                  int64_t delayUs = *(int64_t *)data; - +                CLOG_CONFIG(setInternalOption, "delayUs=%lld", (long long)delayUs);                  return bufferSource->setRepeatPreviousFrameDelayUs(delayUs);              } else if (type ==                      IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP){ @@ -963,7 +1131,7 @@ status_t OMXNodeInstance::setInternalOption(                  }                  int64_t maxGapUs = *(int64_t *)data; - +                CLOG_CONFIG(setInternalOption, "gapUs=%lld", (long long)maxGapUs);                  return bufferSource->setMaxTimestampGapUs(maxGapUs);              } else if (type == IOMX::INTERNAL_OPTION_START_TIME) {                  if (size != sizeof(int64_t)) { @@ -971,13 +1139,18 @@ status_t OMXNodeInstance::setInternalOption(                  }                  int64_t skipFramesBeforeUs = *(int64_t *)data; - +                CLOG_CONFIG(setInternalOption, "beforeUs=%lld", (long long)skipFramesBeforeUs);                  bufferSource->setSkipFramesBeforeUs(skipFramesBeforeUs);              } else { // IOMX::INTERNAL_OPTION_TIME_LAPSE                  if (size != sizeof(int64_t) * 2) {                      return INVALID_OPERATION;                  } +                int64_t timePerFrameUs = ((int64_t *)data)[0]; +                int64_t timePerCaptureUs = ((int64_t *)data)[1]; +                CLOG_CONFIG(setInternalOption, "perFrameUs=%lld perCaptureUs=%lld", +                        (long long)timePerFrameUs, (long long)timePerCaptureUs); +                  bufferSource->setTimeLapseUs((int64_t *)data);              } @@ -996,6 +1169,16 @@ void OMXNodeInstance::onMessage(const omx_message &msg) {          OMX_BUFFERHEADERTYPE *buffer =              findBufferHeader(msg.u.extended_buffer_data.buffer); +        { +            Mutex::Autolock _l(mDebugLock); +            mOutputBuffersWithCodec.remove(buffer); + +            CLOG_BUMPED_BUFFER( +                    FBD, WITH_STATS(FULL_BUFFER(msg.u.extended_buffer_data.buffer, buffer))); + +            unbumpDebugLevel_l(kPortIndexOutput); +        } +          BufferMeta *buffer_meta =              static_cast<BufferMeta *>(buffer->pAppPrivate); @@ -1011,16 +1194,23 @@ void OMXNodeInstance::onMessage(const omx_message &msg) {              return;          }      } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) { +        OMX_BUFFERHEADERTYPE *buffer = +            findBufferHeader(msg.u.buffer_data.buffer); + +        { +            Mutex::Autolock _l(mDebugLock); +            mInputBuffersWithCodec.remove(buffer); + +            CLOG_BUMPED_BUFFER( +                    EBD, WITH_STATS(EMPTY_BUFFER(msg.u.buffer_data.buffer, buffer))); +        } +          if (bufferSource != NULL) {              // This is one of the buffers used exclusively by              // GraphicBufferSource.              // Don't dispatch a message back to ACodec, since it doesn't              // know that anyone asked to have the buffer emptied and will              // be very confused. - -            OMX_BUFFERHEADERTYPE *buffer = -                findBufferHeader(msg.u.buffer_data.buffer); -              bufferSource->codecBufferEmptied(buffer);              return;          } @@ -1044,6 +1234,43 @@ void OMXNodeInstance::onGetHandleFailed() {  // Don't try to acquire mLock here -- in rare circumstances this will hang.  void OMXNodeInstance::onEvent(          OMX_EVENTTYPE event, OMX_U32 arg1, OMX_U32 arg2) { +    const char *arg1String = "??"; +    const char *arg2String = "??"; +    ADebug::Level level = ADebug::kDebugInternalState; + +    switch (event) { +        case OMX_EventCmdComplete: +            arg1String = asString((OMX_COMMANDTYPE)arg1); +            switch (arg1) { +                case OMX_CommandStateSet: +                    arg2String = asString((OMX_STATETYPE)arg2); +                    level = ADebug::kDebugState; +                    break; +                case OMX_CommandFlush: +                case OMX_CommandPortEnable: +                { +                    // bump internal-state debug level for 2 input and output frames +                    Mutex::Autolock _l(mDebugLock); +                    bumpDebugLevel_l(2 /* numInputBuffers */, 2 /* numOutputBuffers */); +                } +                // fall through +                default: +                    arg2String = portString(arg2); +            } +            break; +        case OMX_EventError: +            arg1String = asString((OMX_ERRORTYPE)arg1); +            level = ADebug::kDebugLifeCycle; +            break; +        case OMX_EventPortSettingsChanged: +            arg2String = asString((OMX_INDEXEXTTYPE)arg2); +            // fall through +        default: +            arg1String = portString(arg1); +    } + +    CLOGI_(level, onEvent, "%s(%x), %s(%x), %s(%x)", +            asString(event), event, arg1String, arg1, arg2String, arg2);      const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());      if (bufferSource != NULL @@ -1101,23 +1328,27 @@ void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {      active.mPortIndex = portIndex;      active.mID = id;      mActiveBuffers.push(active); + +    if (portIndex < NELEM(mNumPortBuffers)) { +        ++mNumPortBuffers[portIndex]; +    }  }  void OMXNodeInstance::removeActiveBuffer(          OMX_U32 portIndex, OMX::buffer_id id) { -    bool found = false;      for (size_t i = 0; i < mActiveBuffers.size(); ++i) {          if (mActiveBuffers[i].mPortIndex == portIndex -            && mActiveBuffers[i].mID == id) { -            found = true; +                && mActiveBuffers[i].mID == id) {              mActiveBuffers.removeItemsAt(i); -            break; + +            if (portIndex < NELEM(mNumPortBuffers)) { +                --mNumPortBuffers[portIndex]; +            } +            return;          }      } -    if (!found) { -        ALOGW("Attempt to remove an active buffer we know nothing about..."); -    } +     CLOGW("Attempt to remove an active buffer [%#x] we know nothing about...", id);  }  void OMXNodeInstance::freeActiveBuffers() { @@ -1136,7 +1367,7 @@ OMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader)      OMX::buffer_id buffer;      do { // handle the very unlikely case of ID overflow          if (++mBufferIDCount == 0) { -           ++mBufferIDCount; +            ++mBufferIDCount;          }          buffer = (OMX::buffer_id)mBufferIDCount;      } while (mBufferIDToBufferHeader.indexOfKey(buffer) >= 0); diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp index 4999663..7f99dcd 100644 --- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp +++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp @@ -152,28 +152,28 @@ OMX_ERRORTYPE SimpleSoftOMXComponent::internalSetParameter(              OMX_PARAM_PORTDEFINITIONTYPE *defParams =                  (OMX_PARAM_PORTDEFINITIONTYPE *)params; -            if (defParams->nPortIndex >= mPorts.size() -                    || defParams->nSize -                            != sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) { -                return OMX_ErrorUndefined; +            if (defParams->nPortIndex >= mPorts.size()) { +                return OMX_ErrorBadPortIndex; +            } +            if (defParams->nSize != sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) { +                return OMX_ErrorUnsupportedSetting;              }              PortInfo *port =                  &mPorts.editItemAt(defParams->nPortIndex); -            if (defParams->nBufferSize != port->mDef.nBufferSize) { -                CHECK_GE(defParams->nBufferSize, port->mDef.nBufferSize); +            // default behavior is that we only allow buffer size to increase +            if (defParams->nBufferSize > port->mDef.nBufferSize) {                  port->mDef.nBufferSize = defParams->nBufferSize;              } -            if (defParams->nBufferCountActual -                    != port->mDef.nBufferCountActual) { -                CHECK_GE(defParams->nBufferCountActual, -                         port->mDef.nBufferCountMin); - -                port->mDef.nBufferCountActual = defParams->nBufferCountActual; +            if (defParams->nBufferCountActual < port->mDef.nBufferCountMin) { +                ALOGW("component requires at least %u buffers (%u requested)", +                        port->mDef.nBufferCountMin, defParams->nBufferCountActual); +                return OMX_ErrorUnsupportedSetting;              } +            port->mDef.nBufferCountActual = defParams->nBufferCountActual;              return OMX_ErrorNone;          } diff --git a/media/libstagefright/omx/SoftOMXComponent.cpp b/media/libstagefright/omx/SoftOMXComponent.cpp index 646cd32..df978f8 100644 --- a/media/libstagefright/omx/SoftOMXComponent.cpp +++ b/media/libstagefright/omx/SoftOMXComponent.cpp @@ -283,7 +283,7 @@ OMX_ERRORTYPE SoftOMXComponent::setConfig(  OMX_ERRORTYPE SoftOMXComponent::getExtensionIndex(          const char * /* name */, OMX_INDEXTYPE * /* index */) { -    return OMX_ErrorUndefined; +    return OMX_ErrorUnsupportedIndex;  }  OMX_ERRORTYPE SoftOMXComponent::useBuffer( diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp index 2f83610..4ce165b 100644 --- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp +++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp @@ -26,6 +26,7 @@  #include <media/stagefright/foundation/ADebug.h>  #include <media/stagefright/foundation/ALooper.h>  #include <media/stagefright/foundation/AMessage.h> +#include <media/stagefright/foundation/AUtils.h>  #include <media/stagefright/MediaDefs.h>  namespace android { @@ -61,6 +62,8 @@ SoftVideoDecoderOMXComponent::SoftVideoDecoderOMXComponent(          mCropWidth(width),          mCropHeight(height),          mOutputPortSettingsChange(NONE), +        mMinInputBufferSize(384), // arbitrary, using one uncompressed macroblock +        mMinCompressionRatio(1),  // max input size is normally the output size          mComponentRole(componentRole),          mCodingType(codingType),          mProfileLevels(profileLevels), @@ -71,7 +74,11 @@ void SoftVideoDecoderOMXComponent::initPorts(          OMX_U32 numInputBuffers,          OMX_U32 inputBufferSize,          OMX_U32 numOutputBuffers, -        const char *mimeType) { +        const char *mimeType, +        OMX_U32 minCompressionRatio) { +    mMinInputBufferSize = inputBufferSize; +    mMinCompressionRatio = minCompressionRatio; +      OMX_PARAM_PORTDEFINITIONTYPE def;      InitOMXParams(&def); @@ -120,27 +127,32 @@ void SoftVideoDecoderOMXComponent::initPorts(      addPort(def); -    updatePortDefinitions(); +    updatePortDefinitions(true /* updateCrop */, true /* updateInputSize */);  } -void SoftVideoDecoderOMXComponent::updatePortDefinitions(bool updateCrop) { -    OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kInputPortIndex)->mDef; -    def->format.video.nFrameWidth = mWidth; -    def->format.video.nFrameHeight = mHeight; -    def->format.video.nStride = def->format.video.nFrameWidth; -    def->format.video.nSliceHeight = def->format.video.nFrameHeight; - -    def->nBufferSize = def->format.video.nFrameWidth * def->format.video.nFrameHeight * 3 / 2; - -    def = &editPortInfo(kOutputPortIndex)->mDef; -    def->format.video.nFrameWidth = outputBufferWidth(); -    def->format.video.nFrameHeight = outputBufferHeight(); -    def->format.video.nStride = def->format.video.nFrameWidth; -    def->format.video.nSliceHeight = def->format.video.nFrameHeight; - -    def->nBufferSize = -            (def->format.video.nFrameWidth * -             def->format.video.nFrameHeight * 3) / 2; +void SoftVideoDecoderOMXComponent::updatePortDefinitions(bool updateCrop, bool updateInputSize) { +    OMX_PARAM_PORTDEFINITIONTYPE *outDef = &editPortInfo(kOutputPortIndex)->mDef; +    outDef->format.video.nFrameWidth = outputBufferWidth(); +    outDef->format.video.nFrameHeight = outputBufferHeight(); +    outDef->format.video.nStride = outDef->format.video.nFrameWidth; +    outDef->format.video.nSliceHeight = outDef->format.video.nFrameHeight; + +    outDef->nBufferSize = +        (outDef->format.video.nStride * outDef->format.video.nSliceHeight * 3) / 2; + +    OMX_PARAM_PORTDEFINITIONTYPE *inDef = &editPortInfo(kInputPortIndex)->mDef; +    inDef->format.video.nFrameWidth = mWidth; +    inDef->format.video.nFrameHeight = mHeight; +    // input port is compressed, hence it has no stride +    inDef->format.video.nStride = 0; +    inDef->format.video.nSliceHeight = 0; + +    // when output format changes, input buffer size does not actually change +    if (updateInputSize) { +        inDef->nBufferSize = max( +                outDef->nBufferSize / mMinCompressionRatio, +                max(mMinInputBufferSize, inDef->nBufferSize)); +    }      if (updateCrop) {          mCropLeft = 0; @@ -169,7 +181,8 @@ void SoftVideoDecoderOMXComponent::handlePortSettingsChange(      bool strideChanged = false;      if (fakeStride) {          OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kOutputPortIndex)->mDef; -        if (def->format.video.nStride != width || def->format.video.nSliceHeight != height) { +        if (def->format.video.nStride != (OMX_S32)width +                || def->format.video.nSliceHeight != (OMX_U32)height) {              strideChanged = true;          }      } @@ -252,7 +265,7 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalGetParameter(                  (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;              if (formatParams->nPortIndex > kMaxPortIndex) { -                return OMX_ErrorUndefined; +                return OMX_ErrorBadPortIndex;              }              if (formatParams->nIndex != 0) { @@ -324,13 +337,25 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetParameter(                  (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;              if (formatParams->nPortIndex > kMaxPortIndex) { -                return OMX_ErrorUndefined; +                return OMX_ErrorBadPortIndex;              }              if (formatParams->nIndex != 0) {                  return OMX_ErrorNoMore;              } +            if (formatParams->nPortIndex == kInputPortIndex) { +                if (formatParams->eCompressionFormat != mCodingType +                        || formatParams->eColorFormat != OMX_COLOR_FormatUnused) { +                    return OMX_ErrorUnsupportedSetting; +                } +            } else { +                if (formatParams->eCompressionFormat != OMX_VIDEO_CodingUnused +                        || formatParams->eColorFormat != OMX_COLOR_FormatYUV420Planar) { +                    return OMX_ErrorUnsupportedSetting; +                } +            } +              return OMX_ErrorNone;          } @@ -348,7 +373,7 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetParameter(                  mAdaptiveMaxWidth = 0;                  mAdaptiveMaxHeight = 0;              } -            updatePortDefinitions(); +            updatePortDefinitions(true /* updateCrop */, true /* updateInputSize */);              return OMX_ErrorNone;          } @@ -365,23 +390,21 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetParameter(              uint32_t newHeight = video_def->nFrameHeight;              if (newWidth != oldWidth || newHeight != oldHeight) {                  bool outputPort = (newParams->nPortIndex == kOutputPortIndex); -                def->format.video.nFrameWidth = -                    (mIsAdaptive && outputPort) ? mAdaptiveMaxWidth : newWidth; -                def->format.video.nFrameHeight = -                    (mIsAdaptive && outputPort) ? mAdaptiveMaxHeight : newHeight; -                def->format.video.nStride = def->format.video.nFrameWidth; -                def->format.video.nSliceHeight = def->format.video.nFrameHeight; -                def->nBufferSize = -                    def->format.video.nFrameWidth * def->format.video.nFrameHeight * 3 / 2;                  if (outputPort) { +                    // only update (essentially crop) if size changes                      mWidth = newWidth;                      mHeight = newHeight; -                    mCropLeft = 0; -                    mCropTop = 0; -                    mCropWidth = newWidth; -                    mCropHeight = newHeight; + +                    updatePortDefinitions(true /* updateCrop */, true /* updateInputSize */); +                    // reset buffer size based on frame size +                    newParams->nBufferSize = def->nBufferSize; +                } else { +                    // For input port, we only set nFrameWidth and nFrameHeight. Buffer size +                    // is updated when configuring the output port using the max-frame-size, +                    // though client can still request a larger size. +                    def->format.video.nFrameWidth = newWidth; +                    def->format.video.nFrameHeight = newHeight;                  } -                newParams->nBufferSize = def->nBufferSize;              }              return SimpleSoftOMXComponent::internalSetParameter(index, params);          } diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp index 8bff142..b2d3623 100644 --- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp +++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp @@ -19,6 +19,7 @@  //#define LOG_NDEBUG 0  #define LOG_TAG "SoftVideoEncoderOMXComponent"  #include <utils/Log.h> +#include <utils/misc.h>  #include "include/SoftVideoEncoderOMXComponent.h" @@ -27,6 +28,7 @@  #include <media/stagefright/foundation/ADebug.h>  #include <media/stagefright/foundation/ALooper.h>  #include <media/stagefright/foundation/AMessage.h> +#include <media/stagefright/foundation/AUtils.h>  #include <media/stagefright/MediaDefs.h>  #include <ui/GraphicBuffer.h> @@ -34,13 +36,316 @@  namespace android { +const static OMX_COLOR_FORMATTYPE kSupportedColorFormats[] = { +    OMX_COLOR_FormatYUV420Planar, +    OMX_COLOR_FormatYUV420SemiPlanar, +    OMX_COLOR_FormatAndroidOpaque +}; + +template<class T> +static void InitOMXParams(T *params) { +    params->nSize = sizeof(T); +    params->nVersion.s.nVersionMajor = 1; +    params->nVersion.s.nVersionMinor = 0; +    params->nVersion.s.nRevision = 0; +    params->nVersion.s.nStep = 0; +} +  SoftVideoEncoderOMXComponent::SoftVideoEncoderOMXComponent(          const char *name, +        const char *componentRole, +        OMX_VIDEO_CODINGTYPE codingType, +        const CodecProfileLevel *profileLevels, +        size_t numProfileLevels, +        int32_t width, +        int32_t height,          const OMX_CALLBACKTYPE *callbacks,          OMX_PTR appData,          OMX_COMPONENTTYPE **component)      : SimpleSoftOMXComponent(name, callbacks, appData, component), -      mGrallocModule(NULL) { +      mInputDataIsMeta(false), +      mWidth(width), +      mHeight(height), +      mBitrate(192000), +      mFramerate(30 << 16), // Q16 format +      mColorFormat(OMX_COLOR_FormatYUV420Planar), +      mGrallocModule(NULL), +      mMinOutputBufferSize(384), // arbitrary, using one uncompressed macroblock +      mMinCompressionRatio(1),   // max output size is normally the input size +      mComponentRole(componentRole), +      mCodingType(codingType), +      mProfileLevels(profileLevels), +      mNumProfileLevels(numProfileLevels) { +} + +void SoftVideoEncoderOMXComponent::initPorts( +        OMX_U32 numInputBuffers, OMX_U32 numOutputBuffers, OMX_U32 outputBufferSize, +        const char *mime, OMX_U32 minCompressionRatio) { +    OMX_PARAM_PORTDEFINITIONTYPE def; + +    mMinOutputBufferSize = outputBufferSize; +    mMinCompressionRatio = minCompressionRatio; + +    InitOMXParams(&def); + +    def.nPortIndex = kInputPortIndex; +    def.eDir = OMX_DirInput; +    def.nBufferCountMin = numInputBuffers; +    def.nBufferCountActual = def.nBufferCountMin; +    def.bEnabled = OMX_TRUE; +    def.bPopulated = OMX_FALSE; +    def.eDomain = OMX_PortDomainVideo; +    def.bBuffersContiguous = OMX_FALSE; +    def.format.video.pNativeRender = NULL; +    def.format.video.nFrameWidth = mWidth; +    def.format.video.nFrameHeight = mHeight; +    def.format.video.nStride = def.format.video.nFrameWidth; +    def.format.video.nSliceHeight = def.format.video.nFrameHeight; +    def.format.video.nBitrate = 0; +    // frameRate is in Q16 format. +    def.format.video.xFramerate = mFramerate; +    def.format.video.bFlagErrorConcealment = OMX_FALSE; +    def.nBufferAlignment = kInputBufferAlignment; +    def.format.video.cMIMEType = const_cast<char *>("video/raw"); +    def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; +    def.format.video.eColorFormat = mColorFormat; +    def.format.video.pNativeWindow = NULL; +    // buffersize set in updatePortParams + +    addPort(def); + +    InitOMXParams(&def); + +    def.nPortIndex = kOutputPortIndex; +    def.eDir = OMX_DirOutput; +    def.nBufferCountMin = numOutputBuffers; +    def.nBufferCountActual = def.nBufferCountMin; +    def.bEnabled = OMX_TRUE; +    def.bPopulated = OMX_FALSE; +    def.eDomain = OMX_PortDomainVideo; +    def.bBuffersContiguous = OMX_FALSE; +    def.format.video.pNativeRender = NULL; +    def.format.video.nFrameWidth = mWidth; +    def.format.video.nFrameHeight = mHeight; +    def.format.video.nStride = 0; +    def.format.video.nSliceHeight = 0; +    def.format.video.nBitrate = mBitrate; +    def.format.video.xFramerate = 0 << 16; +    def.format.video.bFlagErrorConcealment = OMX_FALSE; +    def.nBufferAlignment = kOutputBufferAlignment; +    def.format.video.cMIMEType = const_cast<char *>(mime); +    def.format.video.eCompressionFormat = mCodingType; +    def.format.video.eColorFormat = OMX_COLOR_FormatUnused; +    def.format.video.pNativeWindow = NULL; +    // buffersize set in updatePortParams + +    addPort(def); + +    updatePortParams(); +} + +void SoftVideoEncoderOMXComponent::updatePortParams() { +    OMX_PARAM_PORTDEFINITIONTYPE *inDef = &editPortInfo(kInputPortIndex)->mDef; +    inDef->format.video.nFrameWidth = mWidth; +    inDef->format.video.nFrameHeight = mHeight; +    inDef->format.video.nStride = inDef->format.video.nFrameWidth; +    inDef->format.video.nSliceHeight = inDef->format.video.nFrameHeight; +    inDef->format.video.xFramerate = mFramerate; +    inDef->format.video.eColorFormat = mColorFormat; +    uint32_t rawBufferSize = +        inDef->format.video.nStride * inDef->format.video.nSliceHeight * 3 / 2; +    if (inDef->format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque) { +        inDef->nBufferSize = 4 + max(sizeof(buffer_handle_t), sizeof(GraphicBuffer *)); +    } else { +        inDef->nBufferSize = rawBufferSize; +    } + +    OMX_PARAM_PORTDEFINITIONTYPE *outDef = &editPortInfo(kOutputPortIndex)->mDef; +    outDef->format.video.nFrameWidth = mWidth; +    outDef->format.video.nFrameHeight = mHeight; +    outDef->format.video.nBitrate = mBitrate; + +    outDef->nBufferSize = max(mMinOutputBufferSize, rawBufferSize / mMinCompressionRatio); +} + +OMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalSetPortParams( +        const OMX_PARAM_PORTDEFINITIONTYPE *port) { +    if (port->nPortIndex == kInputPortIndex) { +        mWidth = port->format.video.nFrameWidth; +        mHeight = port->format.video.nFrameHeight; + +        // xFramerate comes in Q16 format, in frames per second unit +        mFramerate = port->format.video.xFramerate; + +        if (port->format.video.eCompressionFormat != OMX_VIDEO_CodingUnused +                || (port->format.video.eColorFormat != OMX_COLOR_FormatYUV420Planar +                        && port->format.video.eColorFormat != OMX_COLOR_FormatYUV420SemiPlanar +                        && port->format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque)) { +            return OMX_ErrorUnsupportedSetting; +        } + +        mColorFormat = port->format.video.eColorFormat; +    } else if (port->nPortIndex == kOutputPortIndex) { +        if (port->format.video.eCompressionFormat != mCodingType +                || port->format.video.eColorFormat != OMX_COLOR_FormatUnused) { +            return OMX_ErrorUnsupportedSetting; +        } + +        mBitrate = port->format.video.nBitrate; +    } else { +        return OMX_ErrorBadPortIndex; +    } + +    updatePortParams(); +    return OMX_ErrorNone; +} + +OMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalSetParameter( +        OMX_INDEXTYPE index, const OMX_PTR param) { +    // can include extension index OMX_INDEXEXTTYPE +    const int32_t indexFull = index; + +    switch (indexFull) { +        case OMX_IndexParamVideoErrorCorrection: +        { +            return OMX_ErrorNotImplemented; +        } + +        case OMX_IndexParamStandardComponentRole: +        { +            const OMX_PARAM_COMPONENTROLETYPE *roleParams = +                (const OMX_PARAM_COMPONENTROLETYPE *)param; + +            if (strncmp((const char *)roleParams->cRole, +                        mComponentRole, +                        OMX_MAX_STRINGNAME_SIZE - 1)) { +                return OMX_ErrorUnsupportedSetting; +            } + +            return OMX_ErrorNone; +        } + +        case OMX_IndexParamPortDefinition: +        { +            OMX_ERRORTYPE err = internalSetPortParams((const OMX_PARAM_PORTDEFINITIONTYPE *)param); + +            if (err != OMX_ErrorNone) { +                return err; +            } + +            return SimpleSoftOMXComponent::internalSetParameter(index, param); +        } + +        case OMX_IndexParamVideoPortFormat: +        { +            const OMX_VIDEO_PARAM_PORTFORMATTYPE* format = +                (const OMX_VIDEO_PARAM_PORTFORMATTYPE *)param; + +            if (format->nPortIndex == kInputPortIndex) { +                if (format->eColorFormat == OMX_COLOR_FormatYUV420Planar || +                    format->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar || +                    format->eColorFormat == OMX_COLOR_FormatAndroidOpaque) { +                    mColorFormat = format->eColorFormat; + +                    updatePortParams(); +                    return OMX_ErrorNone; +                } else { +                    ALOGE("Unsupported color format %i", format->eColorFormat); +                    return OMX_ErrorUnsupportedSetting; +                } +            } else if (format->nPortIndex == kOutputPortIndex) { +                if (format->eCompressionFormat == mCodingType) { +                    return OMX_ErrorNone; +                } else { +                    return OMX_ErrorUnsupportedSetting; +                } +            } else { +                return OMX_ErrorBadPortIndex; +            } +        } + +        case kStoreMetaDataExtensionIndex: +        { +            // storeMetaDataInBuffers +            const StoreMetaDataInBuffersParams *storeParam = +                (const StoreMetaDataInBuffersParams *)param; + +            if (storeParam->nPortIndex == kOutputPortIndex) { +                return storeParam->bStoreMetaData ? OMX_ErrorUnsupportedSetting : OMX_ErrorNone; +            } else if (storeParam->nPortIndex != kInputPortIndex) { +                return OMX_ErrorBadPortIndex; +            } + +            mInputDataIsMeta = (storeParam->bStoreMetaData == OMX_TRUE); +            if (mInputDataIsMeta) { +                mColorFormat = OMX_COLOR_FormatAndroidOpaque; +            } else if (mColorFormat == OMX_COLOR_FormatAndroidOpaque) { +                mColorFormat = OMX_COLOR_FormatYUV420Planar; +            } +            updatePortParams(); +            return OMX_ErrorNone; +        } + +        default: +            return SimpleSoftOMXComponent::internalSetParameter(index, param); +    } +} + +OMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalGetParameter( +        OMX_INDEXTYPE index, OMX_PTR param) { +    switch (index) { +        case OMX_IndexParamVideoErrorCorrection: +        { +            return OMX_ErrorNotImplemented; +        } + +        case OMX_IndexParamVideoPortFormat: +        { +            OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = +                (OMX_VIDEO_PARAM_PORTFORMATTYPE *)param; + +            if (formatParams->nPortIndex == kInputPortIndex) { +                if (formatParams->nIndex >= NELEM(kSupportedColorFormats)) { +                    return OMX_ErrorNoMore; +                } + +                // Color formats, in order of preference +                formatParams->eColorFormat = kSupportedColorFormats[formatParams->nIndex]; +                formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused; +                formatParams->xFramerate = mFramerate; +                return OMX_ErrorNone; +            } else if (formatParams->nPortIndex == kOutputPortIndex) { +                formatParams->eCompressionFormat = mCodingType; +                formatParams->eColorFormat = OMX_COLOR_FormatUnused; +                formatParams->xFramerate = 0; +                return OMX_ErrorNone; +            } else { +                return OMX_ErrorBadPortIndex; +            } +        } + +        case OMX_IndexParamVideoProfileLevelQuerySupported: +        { +            OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel = +                  (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) param; + +            if (profileLevel->nPortIndex != kOutputPortIndex) { +                ALOGE("Invalid port index: %u", profileLevel->nPortIndex); +                return OMX_ErrorUnsupportedIndex; +            } + +            if (profileLevel->nProfileIndex >= mNumProfileLevels) { +                return OMX_ErrorNoMore; +            } + +            profileLevel->eProfile = mProfileLevels[profileLevel->nProfileIndex].mProfile; +            profileLevel->eLevel   = mProfileLevels[profileLevel->nProfileIndex].mLevel; +            return OMX_ErrorNone; +        } + +        default: +            return SimpleSoftOMXComponent::internalGetParameter(index, param); +    }  }  // static diff --git a/media/libstagefright/tests/Utils_test.cpp b/media/libstagefright/tests/Utils_test.cpp index 1c13f19..c1e663c 100644 --- a/media/libstagefright/tests/Utils_test.cpp +++ b/media/libstagefright/tests/Utils_test.cpp @@ -24,6 +24,7 @@  #include <unistd.h>  #include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/foundation/AStringUtils.h>  #include <media/stagefright/foundation/AUtils.h>  #include <media/stagefright/Utils.h> @@ -32,6 +33,100 @@ namespace android {  class UtilsTest : public ::testing::Test {  }; +TEST_F(UtilsTest, TestStringUtils) { +    ASSERT_EQ(AStringUtils::Compare("Audio", "AudioExt", 5, false), 0); +    ASSERT_EQ(AStringUtils::Compare("Audio", "audiOExt", 5, true), 0); +    ASSERT_NE(AStringUtils::Compare("Audio", "audioExt", 5, false), 0); +    ASSERT_NE(AStringUtils::Compare("Audio", "AudiOExt", 5, false), 0); + +    ASSERT_LT(AStringUtils::Compare("Audio", "AudioExt", 7, false), 0); +    ASSERT_LT(AStringUtils::Compare("Audio", "audiOExt", 7, true), 0); + +    ASSERT_GT(AStringUtils::Compare("AudioExt", "Audio", 7, false), 0); +    ASSERT_GT(AStringUtils::Compare("audiOext", "Audio", 7, true), 0); + +    ASSERT_LT(AStringUtils::Compare("Audio", "Video", 5, false), 0); +    ASSERT_LT(AStringUtils::Compare("Audio1", "Audio2", 6, false), 0); +    ASSERT_LT(AStringUtils::Compare("audio", "VIDEO", 5, true), 0); +    ASSERT_LT(AStringUtils::Compare("audio1", "AUDIO2", 6, true), 0); + +    ASSERT_GT(AStringUtils::Compare("Video", "Audio", 5, false), 0); +    ASSERT_GT(AStringUtils::Compare("Audio2", "Audio1", 6, false), 0); +    ASSERT_GT(AStringUtils::Compare("VIDEO", "audio", 5, true), 0); +    ASSERT_GT(AStringUtils::Compare("AUDIO2", "audio1", 6, true), 0); + +    ASSERT_TRUE(AStringUtils::MatchesGlob("AudioA", 5, "AudioB", 5, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("AudioA", 6, "AudioA", 5, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("AudioA", 5, "AudioA", 6, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("AudioA", 5, "audiOB", 5, false)); +    ASSERT_TRUE(AStringUtils::MatchesGlob("AudioA", 5, "audiOB", 5, true)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("AudioA", 6, "AudioA", 5, true)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("AudioA", 5, "AudioA", 6, true)); + +    ASSERT_TRUE(AStringUtils::MatchesGlob("*1", 1, "String8", 6, true)); +    ASSERT_TRUE(AStringUtils::MatchesGlob("*1", 1, "String8", 6, false)); +    ASSERT_TRUE(AStringUtils::MatchesGlob("*1", 1, "String8", 0, true)); +    ASSERT_TRUE(AStringUtils::MatchesGlob("*1", 1, "String8", 0, false)); + +    ASSERT_TRUE(AStringUtils::MatchesGlob("*ring1", 5, "String8", 6, false)); +    ASSERT_TRUE(AStringUtils::MatchesGlob("*ring2", 5, "STRING8", 6, true)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("*ring4", 5, "StRing8", 6, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("*ring5", 5, "StrinG8", 6, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("*ring8", 5, "String8", 7, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("*ring8", 5, "String8", 7, true)); + +    ASSERT_TRUE(AStringUtils::MatchesGlob("Str*1", 4, "String8", 6, false)); +    ASSERT_TRUE(AStringUtils::MatchesGlob("Str*2", 4, "STRING8", 6, true)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("Str*3", 4, "string8", 6, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("Str*4", 4, "StRing8", 6, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("Str*5", 4, "AString8", 7, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("Str*6", 4, "AString8", 7, true)); + +    ASSERT_TRUE(AStringUtils::MatchesGlob("Str*ng1", 6, "String8", 6, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng2", 6, "string8", 6, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng3", 6, "StRing8", 6, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng4", 6, "StriNg8", 6, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng5", 6, "StrinG8", 6, false)); +    ASSERT_TRUE(AStringUtils::MatchesGlob("Str*ng6", 6, "STRING8", 6, true)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng8", 6, "AString8", 7, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng1", 6, "String16", 7, false)); +    ASSERT_TRUE(AStringUtils::MatchesGlob("Str*ing9", 7, "String8", 6, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ringA", 8, "String8", 6, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng8", 6, "AString8", 7, true)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ng1", 6, "String16", 7, true)); +    ASSERT_TRUE(AStringUtils::MatchesGlob("Str*ing9", 7, "STRING8", 6, true)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("Str*ringA", 8, "String8", 6, true)); + +    ASSERT_TRUE(AStringUtils::MatchesGlob("*str*str1", 8, "bestrestroom", 9, false)); +    ASSERT_TRUE(AStringUtils::MatchesGlob("*str*str1", 8, "bestrestrestroom", 13, false)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("*str*stro", 8, "bestrestrestroom", 14, false)); +    ASSERT_TRUE(AStringUtils::MatchesGlob("*str*str*1", 9, "bestrestrestroom", 14, false)); +    ASSERT_TRUE(AStringUtils::MatchesGlob("*str*str1", 8, "beSTReSTRoom", 9, true)); +    ASSERT_TRUE(AStringUtils::MatchesGlob("*str*str1", 8, "beSTRestreSTRoom", 13, true)); +    ASSERT_FALSE(AStringUtils::MatchesGlob("*str*stro", 8, "bestreSTReSTRoom", 14, true)); +    ASSERT_TRUE(AStringUtils::MatchesGlob("*str*str*1", 9, "bestreSTReSTRoom", 14, true)); +} + +TEST_F(UtilsTest, TestDebug) { +#define LVL(x) (ADebug::Level)(x) +    ASSERT_EQ(ADebug::GetDebugLevelFromString("video", "", LVL(5)), LVL(5)); +    ASSERT_EQ(ADebug::GetDebugLevelFromString("video", "   \t  \n ", LVL(2)), LVL(2)); +    ASSERT_EQ(ADebug::GetDebugLevelFromString("video", "3", LVL(5)), LVL(3)); +    ASSERT_EQ(ADebug::GetDebugLevelFromString("video", "3:*deo", LVL(5)), LVL(3)); +    ASSERT_EQ(ADebug::GetDebugLevelFromString( +            "video", "\t\n 3 \t\n:\t\n video \t\n", LVL(5)), LVL(3)); +    ASSERT_EQ(ADebug::GetDebugLevelFromString("video", "3:*deo,2:vid*", LVL(5)), LVL(2)); +    ASSERT_EQ(ADebug::GetDebugLevelFromString( +            "avideo", "\t\n 3 \t\n:\t\n avideo \t\n,\t\n 2 \t\n:\t\n video \t\n", LVL(5)), LVL(3)); +    ASSERT_EQ(ADebug::GetDebugLevelFromString( +            "audio.omx", "4:*omx,3:*d*o*,2:audio*", LVL(5)), LVL(2)); +    ASSERT_EQ(ADebug::GetDebugLevelFromString( +            "video.omx", "4:*omx,3:*d*o*,2:audio*", LVL(5)), LVL(3)); +    ASSERT_EQ(ADebug::GetDebugLevelFromString("video", "4:*omx,3:*d*o*,2:audio*", LVL(5)), LVL(3)); +    ASSERT_EQ(ADebug::GetDebugLevelFromString("omx", "4:*omx,3:*d*o*,2:audio*", LVL(5)), LVL(4)); +#undef LVL +} +  TEST_F(UtilsTest, TestFourCC) {      ASSERT_EQ(FOURCC('s', 't', 'm' , 'u'), 'stmu');  } @@ -77,6 +172,13 @@ TEST_F(UtilsTest, TestMathTemplates) {      ASSERT_EQ(divUp(12, 4), 3);      ASSERT_EQ(divUp(13, 4), 4); +    ASSERT_EQ(align(11, 4), 12); +    ASSERT_EQ(align(12, 4), 12); +    ASSERT_EQ(align(13, 4), 16); +    ASSERT_EQ(align(11, 8), 16); +    ASSERT_EQ(align(11, 2), 12); +    ASSERT_EQ(align(11, 1), 11); +      ASSERT_EQ(abs(5L), 5L);      ASSERT_EQ(abs(-25), 25); diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp index e6e19e3..052b700 100644 --- a/media/mtp/MtpDataPacket.cpp +++ b/media/mtp/MtpDataPacket.cpp @@ -51,104 +51,178 @@ void MtpDataPacket::setTransactionID(MtpTransactionID id) {      MtpPacket::putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id);  } -uint16_t MtpDataPacket::getUInt16() { +bool MtpDataPacket::getUInt8(uint8_t& value) { +    if (mPacketSize - mOffset < sizeof(value)) +        return false; +    value = mBuffer[mOffset++]; +    return true; +} + +bool MtpDataPacket::getUInt16(uint16_t& value) { +    if (mPacketSize - mOffset < sizeof(value)) +        return false;      int offset = mOffset; -    uint16_t result = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8); -    mOffset += 2; -    return result; +    value = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8); +    mOffset += sizeof(value); +    return true;  } -uint32_t MtpDataPacket::getUInt32() { +bool MtpDataPacket::getUInt32(uint32_t& value) { +    if (mPacketSize - mOffset < sizeof(value)) +        return false;      int offset = mOffset; -    uint32_t result = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) | +    value = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) |             ((uint32_t)mBuffer[offset + 2] << 16)  | ((uint32_t)mBuffer[offset + 3] << 24); -    mOffset += 4; -    return result; +    mOffset += sizeof(value); +    return true;  } -uint64_t MtpDataPacket::getUInt64() { +bool MtpDataPacket::getUInt64(uint64_t& value) { +    if (mPacketSize - mOffset < sizeof(value)) +        return false;      int offset = mOffset; -    uint64_t result = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) | +    value = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) |             ((uint64_t)mBuffer[offset + 2] << 16) | ((uint64_t)mBuffer[offset + 3] << 24) |             ((uint64_t)mBuffer[offset + 4] << 32) | ((uint64_t)mBuffer[offset + 5] << 40) |             ((uint64_t)mBuffer[offset + 6] << 48)  | ((uint64_t)mBuffer[offset + 7] << 56); -    mOffset += 8; -    return result; +    mOffset += sizeof(value); +    return true;  } -void MtpDataPacket::getUInt128(uint128_t& value) { -    value[0] = getUInt32(); -    value[1] = getUInt32(); -    value[2] = getUInt32(); -    value[3] = getUInt32(); +bool MtpDataPacket::getUInt128(uint128_t& value) { +    return getUInt32(value[0]) && getUInt32(value[1]) && getUInt32(value[2]) && getUInt32(value[3]);  } -void MtpDataPacket::getString(MtpStringBuffer& string) +bool MtpDataPacket::getString(MtpStringBuffer& string)  { -    string.readFromPacket(this); +    return string.readFromPacket(this);  }  Int8List* MtpDataPacket::getAInt8() { +    uint32_t count; +    if (!getUInt32(count)) +        return NULL;      Int8List* result = new Int8List; -    int count = getUInt32(); -    for (int i = 0; i < count; i++) -        result->push(getInt8()); +    for (uint32_t i = 0; i < count; i++) { +        int8_t value; +        if (!getInt8(value)) { +            delete result; +            return NULL; +        } +        result->push(value); +    }      return result;  }  UInt8List* MtpDataPacket::getAUInt8() { +    uint32_t count; +    if (!getUInt32(count)) +        return NULL;      UInt8List* result = new UInt8List; -    int count = getUInt32(); -    for (int i = 0; i < count; i++) -        result->push(getUInt8()); +    for (uint32_t i = 0; i < count; i++) { +        uint8_t value; +        if (!getUInt8(value)) { +            delete result; +            return NULL; +        } +        result->push(value); +    }      return result;  }  Int16List* MtpDataPacket::getAInt16() { +    uint32_t count; +    if (!getUInt32(count)) +        return NULL;      Int16List* result = new Int16List; -    int count = getUInt32(); -    for (int i = 0; i < count; i++) -        result->push(getInt16()); +    for (uint32_t i = 0; i < count; i++) { +        int16_t value; +        if (!getInt16(value)) { +            delete result; +            return NULL; +        } +        result->push(value); +    }      return result;  }  UInt16List* MtpDataPacket::getAUInt16() { +    uint32_t count; +    if (!getUInt32(count)) +        return NULL;      UInt16List* result = new UInt16List; -    int count = getUInt32(); -    for (int i = 0; i < count; i++) -        result->push(getUInt16()); +    for (uint32_t i = 0; i < count; i++) { +        uint16_t value; +        if (!getUInt16(value)) { +            delete result; +            return NULL; +        } +        result->push(value); +    }      return result;  }  Int32List* MtpDataPacket::getAInt32() { +    uint32_t count; +    if (!getUInt32(count)) +        return NULL;      Int32List* result = new Int32List; -    int count = getUInt32(); -    for (int i = 0; i < count; i++) -        result->push(getInt32()); +    for (uint32_t i = 0; i < count; i++) { +        int32_t value; +        if (!getInt32(value)) { +            delete result; +            return NULL; +        } +        result->push(value); +    }      return result;  }  UInt32List* MtpDataPacket::getAUInt32() { +    uint32_t count; +    if (!getUInt32(count)) +        return NULL;      UInt32List* result = new UInt32List; -    int count = getUInt32(); -    for (int i = 0; i < count; i++) -        result->push(getUInt32()); +    for (uint32_t i = 0; i < count; i++) { +        uint32_t value; +        if (!getUInt32(value)) { +            delete result; +            return NULL; +        } +        result->push(value); +    }      return result;  }  Int64List* MtpDataPacket::getAInt64() { +    uint32_t count; +    if (!getUInt32(count)) +        return NULL;      Int64List* result = new Int64List; -    int count = getUInt32(); -    for (int i = 0; i < count; i++) -        result->push(getInt64()); +    for (uint32_t i = 0; i < count; i++) { +        int64_t value; +        if (!getInt64(value)) { +            delete result; +            return NULL; +        } +        result->push(value); +    }      return result;  }  UInt64List* MtpDataPacket::getAUInt64() { +    uint32_t count; +    if (!getUInt32(count)) +        return NULL;      UInt64List* result = new UInt64List; -    int count = getUInt32(); -    for (int i = 0; i < count; i++) -        result->push(getUInt64()); +    for (uint32_t i = 0; i < count; i++) { +        uint64_t value; +        if (!getUInt64(value)) { +            delete result; +            return NULL; +        } +        result->push(value); +    }      return result;  } diff --git a/media/mtp/MtpDataPacket.h b/media/mtp/MtpDataPacket.h index 2b81063..13d3bd9 100644 --- a/media/mtp/MtpDataPacket.h +++ b/media/mtp/MtpDataPacket.h @@ -30,7 +30,7 @@ class MtpStringBuffer;  class MtpDataPacket : public MtpPacket {  private:      // current offset for get/put methods -    int                 mOffset; +    size_t              mOffset;  public:                          MtpDataPacket(); @@ -42,17 +42,18 @@ public:      void                setTransactionID(MtpTransactionID id);      inline const uint8_t*     getData() const { return mBuffer + MTP_CONTAINER_HEADER_SIZE; } -    inline uint8_t      getUInt8() { return (uint8_t)mBuffer[mOffset++]; } -    inline int8_t       getInt8() { return (int8_t)mBuffer[mOffset++]; } -    uint16_t            getUInt16(); -    inline int16_t      getInt16() { return (int16_t)getUInt16(); } -    uint32_t            getUInt32(); -    inline int32_t      getInt32() { return (int32_t)getUInt32(); } -    uint64_t            getUInt64(); -    inline int64_t      getInt64() { return (int64_t)getUInt64(); } -    void                getUInt128(uint128_t& value); -    inline void         getInt128(int128_t& value) { getUInt128((uint128_t&)value); } -    void                getString(MtpStringBuffer& string); + +    bool                getUInt8(uint8_t& value); +    inline bool         getInt8(int8_t& value) { return getUInt8((uint8_t&)value); } +    bool                getUInt16(uint16_t& value); +    inline bool         getInt16(int16_t& value) { return getUInt16((uint16_t&)value); } +    bool                getUInt32(uint32_t& value); +    inline bool         getInt32(int32_t& value) { return getUInt32((uint32_t&)value); } +    bool                getUInt64(uint64_t& value); +    inline bool         getInt64(int64_t& value) { return getUInt64((uint64_t&)value); } +    bool                getUInt128(uint128_t& value); +    inline bool         getInt128(int128_t& value) { return getUInt128((uint128_t&)value); } +    bool                getString(MtpStringBuffer& string);      Int8List*           getAInt8();      UInt8List*          getAUInt8(); diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp index d6d5dd5..e0d679d 100644 --- a/media/mtp/MtpDevice.cpp +++ b/media/mtp/MtpDevice.cpp @@ -313,8 +313,10 @@ MtpDeviceInfo* MtpDevice::getDeviceInfo() {      MtpResponseCode ret = readResponse();      if (ret == MTP_RESPONSE_OK) {          MtpDeviceInfo* info = new MtpDeviceInfo; -        info->read(mData); -        return info; +        if (info->read(mData)) +            return info; +        else +            delete info;      }      return NULL;  } @@ -346,8 +348,10 @@ MtpStorageInfo* MtpDevice::getStorageInfo(MtpStorageID storageID) {      MtpResponseCode ret = readResponse();      if (ret == MTP_RESPONSE_OK) {          MtpStorageInfo* info = new MtpStorageInfo(storageID); -        info->read(mData); -        return info; +        if (info->read(mData)) +            return info; +        else +            delete info;      }      return NULL;  } @@ -385,8 +389,10 @@ MtpObjectInfo* MtpDevice::getObjectInfo(MtpObjectHandle handle) {      MtpResponseCode ret = readResponse();      if (ret == MTP_RESPONSE_OK) {          MtpObjectInfo* info = new MtpObjectInfo(handle); -        info->read(mData); -        return info; +        if (info->read(mData)) +            return info; +        else +            delete info;      }      return NULL;  } @@ -547,8 +553,10 @@ MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) {      MtpResponseCode ret = readResponse();      if (ret == MTP_RESPONSE_OK) {          MtpProperty* property = new MtpProperty; -        property->read(mData); -        return property; +        if (property->read(mData)) +            return property; +        else +            delete property;      }      return NULL;  } @@ -566,15 +574,17 @@ MtpProperty* MtpDevice::getObjectPropDesc(MtpObjectProperty code, MtpObjectForma      MtpResponseCode ret = readResponse();      if (ret == MTP_RESPONSE_OK) {          MtpProperty* property = new MtpProperty; -        property->read(mData); -        return property; +        if (property->read(mData)) +            return property; +        else +            delete property;      }      return NULL;  }  bool MtpDevice::readObject(MtpObjectHandle handle,          bool (* callback)(void* data, int offset, int length, void* clientData), -        int objectSize, void* clientData) { +        size_t objectSize, void* clientData) {      Mutex::Autolock autoLock(mMutex);      bool result = false; diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h index b69203e..9b0acbf 100644 --- a/media/mtp/MtpDevice.h +++ b/media/mtp/MtpDevice.h @@ -98,7 +98,7 @@ public:      bool                    readObject(MtpObjectHandle handle,                                      bool (* callback)(void* data, int offset,                                              int length, void* clientData), -                                    int objectSize, void* clientData); +                                    size_t objectSize, void* clientData);      bool                    readObject(MtpObjectHandle handle, const char* destPath, int group,                                      int perm); diff --git a/media/mtp/MtpDeviceInfo.cpp b/media/mtp/MtpDeviceInfo.cpp index 108e2b8..3e1dff7 100644 --- a/media/mtp/MtpDeviceInfo.cpp +++ b/media/mtp/MtpDeviceInfo.cpp @@ -28,7 +28,7 @@ MtpDeviceInfo::MtpDeviceInfo()          mVendorExtensionID(0),          mVendorExtensionVersion(0),          mVendorExtensionDesc(NULL), -        mFunctionalCode(0), +        mFunctionalMode(0),          mOperations(NULL),          mEvents(NULL),          mDeviceProperties(NULL), @@ -59,39 +59,46 @@ MtpDeviceInfo::~MtpDeviceInfo() {          free(mSerial);  } -void MtpDeviceInfo::read(MtpDataPacket& packet) { +bool MtpDeviceInfo::read(MtpDataPacket& packet) {      MtpStringBuffer string;      // read the device info -    mStandardVersion = packet.getUInt16(); -    mVendorExtensionID = packet.getUInt32(); -    mVendorExtensionVersion = packet.getUInt16(); +    if (!packet.getUInt16(mStandardVersion)) return false; +    if (!packet.getUInt32(mVendorExtensionID)) return false; +    if (!packet.getUInt16(mVendorExtensionVersion)) return false; -    packet.getString(string); +    if (!packet.getString(string)) return false;      mVendorExtensionDesc = strdup((const char *)string); -    mFunctionalCode = packet.getUInt16(); +    if (!packet.getUInt16(mFunctionalMode)) return false;      mOperations = packet.getAUInt16(); +    if (!mOperations) return false;      mEvents = packet.getAUInt16(); +    if (!mEvents) return false;      mDeviceProperties = packet.getAUInt16(); +    if (!mDeviceProperties) return false;      mCaptureFormats = packet.getAUInt16(); +    if (!mCaptureFormats) return false;      mPlaybackFormats = packet.getAUInt16(); +    if (!mCaptureFormats) return false; -    packet.getString(string); +    if (!packet.getString(string)) return false;      mManufacturer = strdup((const char *)string); -    packet.getString(string); +    if (!packet.getString(string)) return false;      mModel = strdup((const char *)string); -    packet.getString(string); +    if (!packet.getString(string)) return false;      mVersion = strdup((const char *)string); -    packet.getString(string); +    if (!packet.getString(string)) return false;      mSerial = strdup((const char *)string); + +    return true;  }  void MtpDeviceInfo::print() {      ALOGV("Device Info:\n\tmStandardVersion: %d\n\tmVendorExtensionID: %d\n\tmVendorExtensionVersiony: %d\n",              mStandardVersion, mVendorExtensionID, mVendorExtensionVersion); -    ALOGV("\tmVendorExtensionDesc: %s\n\tmFunctionalCode: %d\n\tmManufacturer: %s\n\tmModel: %s\n\tmVersion: %s\n\tmSerial: %s\n", -            mVendorExtensionDesc, mFunctionalCode, mManufacturer, mModel, mVersion, mSerial); +    ALOGV("\tmVendorExtensionDesc: %s\n\tmFunctionalMode: %d\n\tmManufacturer: %s\n\tmModel: %s\n\tmVersion: %s\n\tmSerial: %s\n", +            mVendorExtensionDesc, mFunctionalMode, mManufacturer, mModel, mVersion, mSerial);  }  }  // namespace android diff --git a/media/mtp/MtpDeviceInfo.h b/media/mtp/MtpDeviceInfo.h index 2abaa10..bcda9a5 100644 --- a/media/mtp/MtpDeviceInfo.h +++ b/media/mtp/MtpDeviceInfo.h @@ -29,7 +29,7 @@ public:      uint32_t                mVendorExtensionID;      uint16_t                mVendorExtensionVersion;      char*                   mVendorExtensionDesc; -    uint16_t                mFunctionalCode; +    uint16_t                mFunctionalMode;      UInt16List*             mOperations;      UInt16List*             mEvents;      MtpDevicePropertyList*  mDeviceProperties; @@ -44,7 +44,7 @@ public:                              MtpDeviceInfo();      virtual                 ~MtpDeviceInfo(); -    void                    read(MtpDataPacket& packet); +    bool                    read(MtpDataPacket& packet);      void                    print();  }; diff --git a/media/mtp/MtpObjectInfo.cpp b/media/mtp/MtpObjectInfo.cpp index cd15343..0573104 100644 --- a/media/mtp/MtpObjectInfo.cpp +++ b/media/mtp/MtpObjectInfo.cpp @@ -55,39 +55,41 @@ MtpObjectInfo::~MtpObjectInfo() {          free(mKeywords);  } -void MtpObjectInfo::read(MtpDataPacket& packet) { +bool MtpObjectInfo::read(MtpDataPacket& packet) {      MtpStringBuffer string;      time_t time; -    mStorageID = packet.getUInt32(); -    mFormat = packet.getUInt16(); -    mProtectionStatus = packet.getUInt16(); -    mCompressedSize = packet.getUInt32(); -    mThumbFormat = packet.getUInt16(); -    mThumbCompressedSize = packet.getUInt32(); -    mThumbPixWidth = packet.getUInt32(); -    mThumbPixHeight = packet.getUInt32(); -    mImagePixWidth = packet.getUInt32(); -    mImagePixHeight = packet.getUInt32(); -    mImagePixDepth = packet.getUInt32(); -    mParent = packet.getUInt32(); -    mAssociationType = packet.getUInt16(); -    mAssociationDesc = packet.getUInt32(); -    mSequenceNumber = packet.getUInt32(); +    if (!packet.getUInt32(mStorageID)) return false; +    if (!packet.getUInt16(mFormat)) return false; +    if (!packet.getUInt16(mProtectionStatus)) return false; +    if (!packet.getUInt32(mCompressedSize)) return false; +    if (!packet.getUInt16(mThumbFormat)) return false; +    if (!packet.getUInt32(mThumbCompressedSize)) return false; +    if (!packet.getUInt32(mThumbPixWidth)) return false; +    if (!packet.getUInt32(mThumbPixHeight)) return false; +    if (!packet.getUInt32(mImagePixWidth)) return false; +    if (!packet.getUInt32(mImagePixHeight)) return false; +    if (!packet.getUInt32(mImagePixDepth)) return false; +    if (!packet.getUInt32(mParent)) return false; +    if (!packet.getUInt16(mAssociationType)) return false; +    if (!packet.getUInt32(mAssociationDesc)) return false; +    if (!packet.getUInt32(mSequenceNumber)) return false; -    packet.getString(string); +    if (!packet.getString(string)) return false;      mName = strdup((const char *)string); -    packet.getString(string); +    if (!packet.getString(string)) return false;      if (parseDateTime((const char*)string, time))          mDateCreated = time; -    packet.getString(string); +    if (!packet.getString(string)) return false;      if (parseDateTime((const char*)string, time))          mDateModified = time; -    packet.getString(string); +    if (!packet.getString(string)) return false;      mKeywords = strdup((const char *)string); + +    return true;  }  void MtpObjectInfo::print() { diff --git a/media/mtp/MtpObjectInfo.h b/media/mtp/MtpObjectInfo.h index c7a449c..86780f1 100644 --- a/media/mtp/MtpObjectInfo.h +++ b/media/mtp/MtpObjectInfo.h @@ -50,7 +50,7 @@ public:                          MtpObjectInfo(MtpObjectHandle handle);      virtual             ~MtpObjectInfo(); -    void                read(MtpDataPacket& packet); +    bool                read(MtpDataPacket& packet);      void                print();  }; diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp index dd07843..bab1335 100644 --- a/media/mtp/MtpPacket.cpp +++ b/media/mtp/MtpPacket.cpp @@ -52,7 +52,7 @@ void MtpPacket::reset() {      memset(mBuffer, 0, mBufferSize);  } -void MtpPacket::allocate(int length) { +void MtpPacket::allocate(size_t length) {      if (length > mBufferSize) {          int newLength = length + mAllocationIncrement;          mBuffer = (uint8_t *)realloc(mBuffer, newLength); diff --git a/media/mtp/MtpPacket.h b/media/mtp/MtpPacket.h index 0ffb1d3..037722a 100644 --- a/media/mtp/MtpPacket.h +++ b/media/mtp/MtpPacket.h @@ -28,11 +28,11 @@ class MtpPacket {  protected:      uint8_t*            mBuffer;      // current size of the buffer -    int                 mBufferSize; +    size_t              mBufferSize;      // number of bytes to add when resizing the buffer -    int                 mAllocationIncrement; +    size_t              mAllocationIncrement;      // size of the data in the packet -    int                 mPacketSize; +    size_t              mPacketSize;  public:                          MtpPacket(int bufferSize); @@ -41,7 +41,7 @@ public:      // sets packet size to the default container size and sets buffer to zero      virtual void        reset(); -    void                allocate(int length); +    void                allocate(size_t length);      void                dump();      void                copyFrom(const MtpPacket& src); diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp index c500901..d58e2a4 100644 --- a/media/mtp/MtpProperty.cpp +++ b/media/mtp/MtpProperty.cpp @@ -106,15 +106,15 @@ MtpProperty::~MtpProperty() {          free(mMinimumValue.str);          free(mMaximumValue.str);          if (mDefaultArrayValues) { -            for (int i = 0; i < mDefaultArrayLength; i++) +            for (uint32_t i = 0; i < mDefaultArrayLength; i++)                  free(mDefaultArrayValues[i].str);          }          if (mCurrentArrayValues) { -            for (int i = 0; i < mCurrentArrayLength; i++) +            for (uint32_t i = 0; i < mCurrentArrayLength; i++)                  free(mCurrentArrayValues[i].str);          }          if (mEnumValues) { -            for (int i = 0; i < mEnumLength; i++) +            for (uint16_t i = 0; i < mEnumLength; i++)                  free(mEnumValues[i].str);          }      } @@ -123,11 +123,14 @@ MtpProperty::~MtpProperty() {      delete[] mEnumValues;  } -void MtpProperty::read(MtpDataPacket& packet) { -    mCode = packet.getUInt16(); +bool MtpProperty::read(MtpDataPacket& packet) { +    uint8_t temp8; + +    if (!packet.getUInt16(mCode)) return false;      bool deviceProp = isDeviceProperty(); -    mType = packet.getUInt16(); -    mWriteable = (packet.getUInt8() == 1); +    if (!packet.getUInt16(mType)) return false; +    if (!packet.getUInt8(temp8)) return false; +    mWriteable = (temp8 == 1);      switch (mType) {          case MTP_TYPE_AINT8:          case MTP_TYPE_AUINT8: @@ -140,28 +143,36 @@ void MtpProperty::read(MtpDataPacket& packet) {          case MTP_TYPE_AINT128:          case MTP_TYPE_AUINT128:              mDefaultArrayValues = readArrayValues(packet, mDefaultArrayLength); -            if (deviceProp) +            if (!mDefaultArrayValues) return false; +            if (deviceProp) {                  mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength); +                if (!mCurrentArrayValues) return false; +            }              break;          default: -            readValue(packet, mDefaultValue); -            if (deviceProp) -                readValue(packet, mCurrentValue); +            if (!readValue(packet, mDefaultValue)) return false; +            if (deviceProp) { +                if (!readValue(packet, mCurrentValue)) return false; +            }      } -    if (!deviceProp) -        mGroupCode = packet.getUInt32(); -    mFormFlag = packet.getUInt8(); +    if (!deviceProp) { +        if (!packet.getUInt32(mGroupCode)) return false; +    } +    if (!packet.getUInt8(mFormFlag)) return false;      if (mFormFlag == kFormRange) { -            readValue(packet, mMinimumValue); -            readValue(packet, mMaximumValue); -            readValue(packet, mStepSize); +            if (!readValue(packet, mMinimumValue)) return false; +            if (!readValue(packet, mMaximumValue)) return false; +            if (!readValue(packet, mStepSize)) return false;      } else if (mFormFlag == kFormEnum) { -        mEnumLength = packet.getUInt16(); +        if (!packet.getUInt16(mEnumLength)) return false;          mEnumValues = new MtpPropertyValue[mEnumLength]; -        for (int i = 0; i < mEnumLength; i++) -            readValue(packet, mEnumValues[i]); +        for (int i = 0; i < mEnumLength; i++) { +            if (!readValue(packet, mEnumValues[i])) return false; +        }      } + +    return true;  }  void MtpProperty::write(MtpDataPacket& packet) { @@ -409,57 +420,59 @@ void MtpProperty::print(MtpPropertyValue& value, MtpString& buffer) {      }  } -void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) { +bool MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) {      MtpStringBuffer stringBuffer;      switch (mType) {          case MTP_TYPE_INT8:          case MTP_TYPE_AINT8: -            value.u.i8 = packet.getInt8(); +            if (!packet.getInt8(value.u.i8)) return false;              break;          case MTP_TYPE_UINT8:          case MTP_TYPE_AUINT8: -            value.u.u8 = packet.getUInt8(); +            if (!packet.getUInt8(value.u.u8)) return false;              break;          case MTP_TYPE_INT16:          case MTP_TYPE_AINT16: -            value.u.i16 = packet.getInt16(); +            if (!packet.getInt16(value.u.i16)) return false;              break;          case MTP_TYPE_UINT16:          case MTP_TYPE_AUINT16: -            value.u.u16 = packet.getUInt16(); +            if (!packet.getUInt16(value.u.u16)) return false;              break;          case MTP_TYPE_INT32:          case MTP_TYPE_AINT32: -            value.u.i32 = packet.getInt32(); +            if (!packet.getInt32(value.u.i32)) return false;              break;          case MTP_TYPE_UINT32:          case MTP_TYPE_AUINT32: -            value.u.u32 = packet.getUInt32(); +            if (!packet.getUInt32(value.u.u32)) return false;              break;          case MTP_TYPE_INT64:          case MTP_TYPE_AINT64: -            value.u.i64 = packet.getInt64(); +            if (!packet.getInt64(value.u.i64)) return false;              break;          case MTP_TYPE_UINT64:          case MTP_TYPE_AUINT64: -            value.u.u64 = packet.getUInt64(); +            if (!packet.getUInt64(value.u.u64)) return false;              break;          case MTP_TYPE_INT128:          case MTP_TYPE_AINT128: -            packet.getInt128(value.u.i128); +            if (!packet.getInt128(value.u.i128)) return false;              break;          case MTP_TYPE_UINT128:          case MTP_TYPE_AUINT128: -            packet.getUInt128(value.u.u128); +            if (!packet.getUInt128(value.u.u128)) return false;              break;          case MTP_TYPE_STR: -            packet.getString(stringBuffer); +            if (!packet.getString(stringBuffer)) return false;              value.str = strdup(stringBuffer);              break;          default:              ALOGE("unknown type %04X in MtpProperty::readValue", mType); +            return false;      } +    return true;  }  void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) { @@ -517,8 +530,9 @@ void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) {      }  } -MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& length) { -    length = packet.getUInt32(); +MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, uint32_t& length) { +    if (!packet.getUInt32(length)) return NULL; +      // Fail if resulting array is over 2GB.  This is because the maximum array      // size may be less than SIZE_MAX on some platforms.      if ( CC_UNLIKELY( @@ -528,14 +542,17 @@ MtpPropertyValue* MtpProperty::readArrayValues(MtpDataPacket& packet, int& lengt          return NULL;      }      MtpPropertyValue* result = new MtpPropertyValue[length]; -    for (int i = 0; i < length; i++) -        readValue(packet, result[i]); +    for (uint32_t i = 0; i < length; i++) +        if (!readValue(packet, result[i])) { +            delete result; +            return NULL; +        }      return result;  } -void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length) { +void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, uint32_t length) {      packet.putUInt32(length); -    for (int i = 0; i < length; i++) +    for (uint32_t i = 0; i < length; i++)          writeValue(packet, values[i]);  } diff --git a/media/mtp/MtpProperty.h b/media/mtp/MtpProperty.h index 06ca56e..2e2ead1 100644 --- a/media/mtp/MtpProperty.h +++ b/media/mtp/MtpProperty.h @@ -49,9 +49,9 @@ public:      MtpPropertyValue    mCurrentValue;      // for array types -    int                 mDefaultArrayLength; +    uint32_t            mDefaultArrayLength;      MtpPropertyValue*   mDefaultArrayValues; -    int                 mCurrentArrayLength; +    uint32_t            mCurrentArrayLength;      MtpPropertyValue*   mCurrentArrayValues;      enum { @@ -70,7 +70,7 @@ public:      MtpPropertyValue    mStepSize;      // for enum form -    int                 mEnumLength; +    uint16_t            mEnumLength;      MtpPropertyValue*   mEnumValues;  public: @@ -83,7 +83,7 @@ public:      inline MtpPropertyCode getPropertyCode() const { return mCode; } -    void                read(MtpDataPacket& packet); +    bool                read(MtpDataPacket& packet);      void                write(MtpDataPacket& packet);      void                setDefaultValue(const uint16_t* string); @@ -102,11 +102,11 @@ public:                          }  private: -    void                readValue(MtpDataPacket& packet, MtpPropertyValue& value); +    bool                readValue(MtpDataPacket& packet, MtpPropertyValue& value);      void                writeValue(MtpDataPacket& packet, MtpPropertyValue& value); -    MtpPropertyValue*   readArrayValues(MtpDataPacket& packet, int& length); +    MtpPropertyValue*   readArrayValues(MtpDataPacket& packet, uint32_t& length);      void                writeArrayValues(MtpDataPacket& packet, -                                            MtpPropertyValue* values, int length); +                                            MtpPropertyValue* values, uint32_t length);  };  }; // namespace android diff --git a/media/mtp/MtpRequestPacket.cpp b/media/mtp/MtpRequestPacket.cpp index 0e58e01..40b11b0 100644 --- a/media/mtp/MtpRequestPacket.cpp +++ b/media/mtp/MtpRequestPacket.cpp @@ -27,7 +27,8 @@  namespace android {  MtpRequestPacket::MtpRequestPacket() -    :   MtpPacket(512) +    :   MtpPacket(512), +        mParameterCount(0)  {  } @@ -37,10 +38,21 @@ MtpRequestPacket::~MtpRequestPacket() {  #ifdef MTP_DEVICE  int MtpRequestPacket::read(int fd) {      int ret = ::read(fd, mBuffer, mBufferSize); -    if (ret >= 0) +    if (ret < 0) { +        // file read error +        return ret; +    } + +    // request packet should have 12 byte header followed by 0 to 5 32-bit arguments +    if (ret >= MTP_CONTAINER_HEADER_SIZE +            && ret <= MTP_CONTAINER_HEADER_SIZE + 5 * sizeof(uint32_t) +            && ((ret - MTP_CONTAINER_HEADER_SIZE) & 3) == 0) {          mPacketSize = ret; -    else -        mPacketSize = 0; +        mParameterCount = (ret - MTP_CONTAINER_HEADER_SIZE) / sizeof(uint32_t); +    } else { +        ALOGE("Malformed MTP request packet"); +        ret = -1; +    }      return ret;  }  #endif diff --git a/media/mtp/MtpRequestPacket.h b/media/mtp/MtpRequestPacket.h index 1201f11..79b798d 100644 --- a/media/mtp/MtpRequestPacket.h +++ b/media/mtp/MtpRequestPacket.h @@ -43,6 +43,10 @@ public:      inline MtpOperationCode    getOperationCode() const { return getContainerCode(); }      inline void                setOperationCode(MtpOperationCode code)                                                      { return setContainerCode(code); } +    inline int                  getParameterCount() const { return mParameterCount; } + +private: +    int     mParameterCount;  };  }; // namespace android diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp index aa43967..07199e3 100644 --- a/media/mtp/MtpServer.cpp +++ b/media/mtp/MtpServer.cpp @@ -495,6 +495,9 @@ MtpResponseCode MtpServer::doOpenSession() {          mResponse.setParameter(1, mSessionID);          return MTP_RESPONSE_SESSION_ALREADY_OPEN;      } +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER; +      mSessionID = mRequest.getParameter(1);      mSessionOpen = true; @@ -529,6 +532,9 @@ MtpResponseCode MtpServer::doGetStorageInfo() {      if (!mSessionOpen)          return MTP_RESPONSE_SESSION_NOT_OPEN; +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER; +      MtpStorageID id = mRequest.getParameter(1);      MtpStorage* storage = getStorage(id);      if (!storage) @@ -550,6 +556,8 @@ MtpResponseCode MtpServer::doGetStorageInfo() {  MtpResponseCode MtpServer::doGetObjectPropsSupported() {      if (!mSessionOpen)          return MTP_RESPONSE_SESSION_NOT_OPEN; +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpObjectFormat format = mRequest.getParameter(1);      MtpObjectPropertyList* properties = mDatabase->getSupportedObjectProperties(format);      mData.putAUInt16(properties); @@ -560,6 +568,8 @@ MtpResponseCode MtpServer::doGetObjectPropsSupported() {  MtpResponseCode MtpServer::doGetObjectHandles() {      if (!mSessionOpen)          return MTP_RESPONSE_SESSION_NOT_OPEN; +    if (mRequest.getParameterCount() < 3) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpStorageID storageID = mRequest.getParameter(1);      // 0xFFFFFFFF for all storage      MtpObjectFormat format = mRequest.getParameter(2);      // 0 for all formats      MtpObjectHandle parent = mRequest.getParameter(3);      // 0xFFFFFFFF for objects with no parent @@ -577,6 +587,8 @@ MtpResponseCode MtpServer::doGetObjectHandles() {  MtpResponseCode MtpServer::doGetNumObjects() {      if (!mSessionOpen)          return MTP_RESPONSE_SESSION_NOT_OPEN; +    if (mRequest.getParameterCount() < 3) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpStorageID storageID = mRequest.getParameter(1);      // 0xFFFFFFFF for all storage      MtpObjectFormat format = mRequest.getParameter(2);      // 0 for all formats      MtpObjectHandle parent = mRequest.getParameter(3);      // 0xFFFFFFFF for objects with no parent @@ -599,6 +611,8 @@ MtpResponseCode MtpServer::doGetObjectReferences() {          return MTP_RESPONSE_SESSION_NOT_OPEN;      if (!hasStorage())          return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpObjectHandle handle = mRequest.getParameter(1);      // FIXME - check for invalid object handle @@ -617,9 +631,13 @@ MtpResponseCode MtpServer::doSetObjectReferences() {          return MTP_RESPONSE_SESSION_NOT_OPEN;      if (!hasStorage())          return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpStorageID handle = mRequest.getParameter(1);      MtpObjectHandleList* references = mData.getAUInt32(); +    if (!references) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpResponseCode result = mDatabase->setObjectReferences(handle, references);      delete references;      return result; @@ -628,6 +646,8 @@ MtpResponseCode MtpServer::doSetObjectReferences() {  MtpResponseCode MtpServer::doGetObjectPropValue() {      if (!hasStorage())          return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +    if (mRequest.getParameterCount() < 2) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpObjectHandle handle = mRequest.getParameter(1);      MtpObjectProperty property = mRequest.getParameter(2);      ALOGV("GetObjectPropValue %d %s\n", handle, @@ -639,6 +659,8 @@ MtpResponseCode MtpServer::doGetObjectPropValue() {  MtpResponseCode MtpServer::doSetObjectPropValue() {      if (!hasStorage())          return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +    if (mRequest.getParameterCount() < 2) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpObjectHandle handle = mRequest.getParameter(1);      MtpObjectProperty property = mRequest.getParameter(2);      ALOGV("SetObjectPropValue %d %s\n", handle, @@ -648,6 +670,8 @@ MtpResponseCode MtpServer::doSetObjectPropValue() {  }  MtpResponseCode MtpServer::doGetDevicePropValue() { +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpDeviceProperty property = mRequest.getParameter(1);      ALOGV("GetDevicePropValue %s\n",              MtpDebug::getDevicePropCodeName(property)); @@ -656,6 +680,8 @@ MtpResponseCode MtpServer::doGetDevicePropValue() {  }  MtpResponseCode MtpServer::doSetDevicePropValue() { +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpDeviceProperty property = mRequest.getParameter(1);      ALOGV("SetDevicePropValue %s\n",              MtpDebug::getDevicePropCodeName(property)); @@ -664,6 +690,8 @@ MtpResponseCode MtpServer::doSetDevicePropValue() {  }  MtpResponseCode MtpServer::doResetDevicePropValue() { +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpDeviceProperty property = mRequest.getParameter(1);      ALOGV("ResetDevicePropValue %s\n",              MtpDebug::getDevicePropCodeName(property)); @@ -674,6 +702,8 @@ MtpResponseCode MtpServer::doResetDevicePropValue() {  MtpResponseCode MtpServer::doGetObjectPropList() {      if (!hasStorage())          return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +    if (mRequest.getParameterCount() < 5) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpObjectHandle handle = mRequest.getParameter(1);      // use uint32_t so we can support 0xFFFFFFFF @@ -691,6 +721,8 @@ MtpResponseCode MtpServer::doGetObjectPropList() {  MtpResponseCode MtpServer::doGetObjectInfo() {      if (!hasStorage())          return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpObjectHandle handle = mRequest.getParameter(1);      MtpObjectInfo info(handle);      MtpResponseCode result = mDatabase->getObjectInfo(handle, info); @@ -732,6 +764,8 @@ MtpResponseCode MtpServer::doGetObjectInfo() {  MtpResponseCode MtpServer::doGetObject() {      if (!hasStorage())          return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpObjectHandle handle = mRequest.getParameter(1);      MtpString pathBuf;      int64_t fileLength; @@ -765,6 +799,8 @@ MtpResponseCode MtpServer::doGetObject() {  }  MtpResponseCode MtpServer::doGetThumb() { +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpObjectHandle handle = mRequest.getParameter(1);      size_t thumbSize;      void* thumb = mDatabase->getThumbnail(handle, thumbSize); @@ -788,11 +824,19 @@ MtpResponseCode MtpServer::doGetPartialObject(MtpOperationCode operation) {      uint32_t length;      offset = mRequest.getParameter(2);      if (operation == MTP_OPERATION_GET_PARTIAL_OBJECT_64) { +        // MTP_OPERATION_GET_PARTIAL_OBJECT_64 takes 4 arguments +        if (mRequest.getParameterCount() < 4) +            return MTP_RESPONSE_INVALID_PARAMETER; +          // android extension with 64 bit offset          uint64_t offset2 = mRequest.getParameter(3);          offset = offset | (offset2 << 32);          length = mRequest.getParameter(4);      } else { +        // MTP_OPERATION_GET_PARTIAL_OBJECT takes 3 arguments +        if (mRequest.getParameterCount() < 3) +            return MTP_RESPONSE_INVALID_PARAMETER; +          // standard GetPartialObject          length = mRequest.getParameter(3);      } @@ -832,6 +876,11 @@ MtpResponseCode MtpServer::doGetPartialObject(MtpOperationCode operation) {  MtpResponseCode MtpServer::doSendObjectInfo() {      MtpString path; +    uint16_t temp16; +    uint32_t temp32; + +    if (mRequest.getParameterCount() < 2) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpStorageID storageID = mRequest.getParameter(1);      MtpStorage* storage = getStorage(storageID);      MtpObjectHandle parent = mRequest.getParameter(2); @@ -853,25 +902,29 @@ MtpResponseCode MtpServer::doSendObjectInfo() {      }      // read only the fields we need -    mData.getUInt32();  // storage ID -    MtpObjectFormat format = mData.getUInt16(); -    mData.getUInt16();  // protection status -    mSendObjectFileSize = mData.getUInt32(); -    mData.getUInt16();  // thumb format -    mData.getUInt32();  // thumb compressed size -    mData.getUInt32();  // thumb pix width -    mData.getUInt32();  // thumb pix height -    mData.getUInt32();  // image pix width -    mData.getUInt32();  // image pix height -    mData.getUInt32();  // image bit depth -    mData.getUInt32();  // parent -    uint16_t associationType = mData.getUInt16(); -    uint32_t associationDesc = mData.getUInt32();   // association desc -    mData.getUInt32();  // sequence number +    if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER;  // storage ID +    if (!mData.getUInt16(temp16)) return MTP_RESPONSE_INVALID_PARAMETER; +    MtpObjectFormat format = temp16; +    if (!mData.getUInt16(temp16)) return MTP_RESPONSE_INVALID_PARAMETER;  // protection status +    if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; +    mSendObjectFileSize = temp32; +    if (!mData.getUInt16(temp16)) return MTP_RESPONSE_INVALID_PARAMETER;  // thumb format +    if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER;  // thumb compressed size +    if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER;  // thumb pix width +    if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER;  // thumb pix height +    if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER;  // image pix width +    if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER;  // image pix height +    if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER;  // image bit depth +    if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER;  // parent +    if (!mData.getUInt16(temp16)) return MTP_RESPONSE_INVALID_PARAMETER; +    uint16_t associationType = temp16; +    if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; +    uint32_t associationDesc = temp32;        // association desc +    if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER;  // sequence number      MtpStringBuffer name, created, modified; -    mData.getString(name);    // file name -    mData.getString(created);      // date created -    mData.getString(modified);     // date modified +    if (!mData.getString(name)) return MTP_RESPONSE_INVALID_PARAMETER;    // file name +    if (!mData.getString(created)) return MTP_RESPONSE_INVALID_PARAMETER;      // date created +    if (!mData.getString(modified)) return MTP_RESPONSE_INVALID_PARAMETER;     // date modified      // keywords follow      ALOGV("name: %s format: %04X\n", (const char *)name, format); @@ -1066,8 +1119,10 @@ static void deletePath(const char* path) {  MtpResponseCode MtpServer::doDeleteObject() {      if (!hasStorage())          return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpObjectHandle handle = mRequest.getParameter(1); -    MtpObjectFormat format = mRequest.getParameter(2); +    MtpObjectFormat format;      // FIXME - support deleting all objects if handle is 0xFFFFFFFF      // FIXME - implement deleting objects by format @@ -1087,6 +1142,8 @@ MtpResponseCode MtpServer::doDeleteObject() {  }  MtpResponseCode MtpServer::doGetObjectPropDesc() { +    if (mRequest.getParameterCount() < 2) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpObjectProperty propCode = mRequest.getParameter(1);      MtpObjectFormat format = mRequest.getParameter(2);      ALOGV("GetObjectPropDesc %s %s\n", MtpDebug::getObjectPropCodeName(propCode), @@ -1100,6 +1157,8 @@ MtpResponseCode MtpServer::doGetObjectPropDesc() {  }  MtpResponseCode MtpServer::doGetDevicePropDesc() { +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpDeviceProperty propCode = mRequest.getParameter(1);      ALOGV("GetDevicePropDesc %s\n", MtpDebug::getDevicePropCodeName(propCode));      MtpProperty* property = mDatabase->getDevicePropertyDesc(propCode); @@ -1113,6 +1172,8 @@ MtpResponseCode MtpServer::doGetDevicePropDesc() {  MtpResponseCode MtpServer::doSendPartialObject() {      if (!hasStorage())          return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +    if (mRequest.getParameterCount() < 4) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpObjectHandle handle = mRequest.getParameter(1);      uint64_t offset = mRequest.getParameter(2);      uint64_t offset2 = mRequest.getParameter(3); @@ -1180,6 +1241,8 @@ MtpResponseCode MtpServer::doSendPartialObject() {  }  MtpResponseCode MtpServer::doTruncateObject() { +    if (mRequest.getParameterCount() < 3) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpObjectHandle handle = mRequest.getParameter(1);      ObjectEdit* edit = getEditObject(handle);      if (!edit) { @@ -1199,6 +1262,8 @@ MtpResponseCode MtpServer::doTruncateObject() {  }  MtpResponseCode MtpServer::doBeginEditObject() { +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpObjectHandle handle = mRequest.getParameter(1);      if (getEditObject(handle)) {          ALOGE("object already open for edit in doBeginEditObject"); @@ -1223,6 +1288,8 @@ MtpResponseCode MtpServer::doBeginEditObject() {  }  MtpResponseCode MtpServer::doEndEditObject() { +    if (mRequest.getParameterCount() < 1) +        return MTP_RESPONSE_INVALID_PARAMETER;      MtpObjectHandle handle = mRequest.getParameter(1);      ObjectEdit* edit = getEditObject(handle);      if (!edit) { diff --git a/media/mtp/MtpStorageInfo.cpp b/media/mtp/MtpStorageInfo.cpp index 2b1a9ae..5d4ebbf 100644 --- a/media/mtp/MtpStorageInfo.cpp +++ b/media/mtp/MtpStorageInfo.cpp @@ -45,21 +45,23 @@ MtpStorageInfo::~MtpStorageInfo() {          free(mVolumeIdentifier);  } -void MtpStorageInfo::read(MtpDataPacket& packet) { +bool MtpStorageInfo::read(MtpDataPacket& packet) {      MtpStringBuffer string;      // read the device info -    mStorageType = packet.getUInt16(); -    mFileSystemType = packet.getUInt16(); -    mAccessCapability = packet.getUInt16(); -    mMaxCapacity = packet.getUInt64(); -    mFreeSpaceBytes = packet.getUInt64(); -    mFreeSpaceObjects = packet.getUInt32(); +    if (!packet.getUInt16(mStorageType)) return false; +    if (!packet.getUInt16(mFileSystemType)) return false; +    if (!packet.getUInt16(mAccessCapability)) return false; +    if (!packet.getUInt64(mMaxCapacity)) return false; +    if (!packet.getUInt64(mFreeSpaceBytes)) return false; +    if (!packet.getUInt32(mFreeSpaceObjects)) return false; -    packet.getString(string); +    if (!packet.getString(string)) return false;      mStorageDescription = strdup((const char *)string); -    packet.getString(string); +    if (!packet.getString(string)) return false;      mVolumeIdentifier = strdup((const char *)string); + +    return true;  }  void MtpStorageInfo::print() { diff --git a/media/mtp/MtpStorageInfo.h b/media/mtp/MtpStorageInfo.h index 2cb626e..35a8189 100644 --- a/media/mtp/MtpStorageInfo.h +++ b/media/mtp/MtpStorageInfo.h @@ -39,7 +39,7 @@ public:                          MtpStorageInfo(MtpStorageID id);      virtual             ~MtpStorageInfo(); -    void                read(MtpDataPacket& packet); +    bool                read(MtpDataPacket& packet);      void                print();  }; diff --git a/media/mtp/MtpStringBuffer.cpp b/media/mtp/MtpStringBuffer.cpp index f3420a4..df04694 100644 --- a/media/mtp/MtpStringBuffer.cpp +++ b/media/mtp/MtpStringBuffer.cpp @@ -123,11 +123,17 @@ void MtpStringBuffer::set(const uint16_t* src) {      mByteCount = dest - mBuffer;  } -void MtpStringBuffer::readFromPacket(MtpDataPacket* packet) { -    int count = packet->getUInt8(); +bool MtpStringBuffer::readFromPacket(MtpDataPacket* packet) { +    uint8_t count; +    if (!packet->getUInt8(count)) +        return false; +      uint8_t* dest = mBuffer;      for (int i = 0; i < count; i++) { -        uint16_t ch = packet->getUInt16(); +        uint16_t ch; + +        if (!packet->getUInt16(ch)) +            return false;          if (ch >= 0x0800) {              *dest++ = (uint8_t)(0xE0 | (ch >> 12));              *dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F)); @@ -142,6 +148,7 @@ void MtpStringBuffer::readFromPacket(MtpDataPacket* packet) {      *dest++ = 0;      mCharCount = count;      mByteCount = dest - mBuffer; +    return true;  }  void MtpStringBuffer::writeToPacket(MtpDataPacket* packet) const { diff --git a/media/mtp/MtpStringBuffer.h b/media/mtp/MtpStringBuffer.h index e5150df..85d91e8 100644 --- a/media/mtp/MtpStringBuffer.h +++ b/media/mtp/MtpStringBuffer.h @@ -46,7 +46,7 @@ public:      void            set(const char* src);      void            set(const uint16_t* src); -    void            readFromPacket(MtpDataPacket* packet); +    bool            readFromPacket(MtpDataPacket* packet);      void            writeToPacket(MtpDataPacket* packet) const;      inline int      getCharCount() const { return mCharCount; } diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk index 697fb37..f0196c6 100644 --- a/services/audioflinger/Android.mk +++ b/services/audioflinger/Android.mk @@ -19,7 +19,13 @@ LOCAL_SRC_FILES := \  # FIXME Move this library to frameworks/native  LOCAL_MODULE := libserviceutility -include $(BUILD_STATIC_LIBRARY) +LOCAL_SHARED_LIBRARIES := \ +    libcutils \ +    libutils \ +    liblog \ +    libbinder + +include $(BUILD_SHARED_LIBRARY)  include $(CLEAR_VARS) @@ -51,13 +57,13 @@ LOCAL_SHARED_LIBRARIES := \      libhardware \      libhardware_legacy \      libeffects \ -    libpowermanager +    libpowermanager \ +    libserviceutility  LOCAL_STATIC_LIBRARIES := \      libscheduling_policy \      libcpustats \ -    libmedia_helper \ -    libserviceutility +    libmedia_helper  LOCAL_MODULE:= libaudioflinger  LOCAL_32_BIT_ONLY := true diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 413ec3e..b4c9905 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -650,6 +650,7 @@ sp<IAudioTrack> AudioFlinger::createTrack(              }          } +        setAudioHwSyncForSession_l(thread, (audio_session_t)lSessionId);      }      if (lStatus != NO_ERROR) { @@ -898,6 +899,21 @@ bool AudioFlinger::masterMute_l() const      return mMasterMute;  } +status_t AudioFlinger::checkStreamType(audio_stream_type_t stream) const +{ +    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { +        ALOGW("setStreamVolume() invalid stream %d", stream); +        return BAD_VALUE; +    } +    pid_t caller = IPCThreadState::self()->getCallingPid(); +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT && caller != getpid_cached) { +        ALOGW("setStreamVolume() pid %d cannot use internal stream type %d", caller, stream); +        return PERMISSION_DENIED; +    } + +    return NO_ERROR; +} +  status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,          audio_io_handle_t output)  { @@ -906,10 +922,11 @@ status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,          return PERMISSION_DENIED;      } -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { -        ALOGE("setStreamVolume() invalid stream %d", stream); -        return BAD_VALUE; +    status_t status = checkStreamType(stream); +    if (status != NO_ERROR) { +        return status;      } +    ALOG_ASSERT(stream != AUDIO_STREAM_PATCH, "attempt to change AUDIO_STREAM_PATCH volume");      AutoMutex lock(mLock);      PlaybackThread *thread = NULL; @@ -940,8 +957,13 @@ status_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted)          return PERMISSION_DENIED;      } -    if (uint32_t(stream) >= AUDIO_STREAM_CNT || -        uint32_t(stream) == AUDIO_STREAM_ENFORCED_AUDIBLE) { +    status_t status = checkStreamType(stream); +    if (status != NO_ERROR) { +        return status; +    } +    ALOG_ASSERT(stream != AUDIO_STREAM_PATCH, "attempt to mute AUDIO_STREAM_PATCH"); + +    if (uint32_t(stream) == AUDIO_STREAM_ENFORCED_AUDIBLE) {          ALOGE("setStreamMute() invalid stream %d", stream);          return BAD_VALUE;      } @@ -956,7 +978,8 @@ status_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted)  float AudioFlinger::streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const  { -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { +    status_t status = checkStreamType(stream); +    if (status != NO_ERROR) {          return 0.0f;      } @@ -977,7 +1000,8 @@ float AudioFlinger::streamVolume(audio_stream_type_t stream, audio_io_handle_t o  bool AudioFlinger::streamMute(audio_stream_type_t stream) const  { -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { +    status_t status = checkStreamType(stream); +    if (status != NO_ERROR) {          return true;      } @@ -1417,13 +1441,6 @@ sp<IAudioRecord> AudioFlinger::openRecord(              goto Exit;          } -        if (deviceRequiresCaptureAudioOutputPermission(thread->inDevice()) -                && !captureAudioOutputAllowed()) { -            ALOGE("openRecord() permission denied: capture not allowed"); -            lStatus = PERMISSION_DENIED; -            goto Exit; -        } -          pid_t pid = IPCThreadState::self()->getCallingPid();          client = registerPid(pid); @@ -1612,22 +1629,69 @@ status_t AudioFlinger::setLowRamDevice(bool isLowRamDevice)  audio_hw_sync_t AudioFlinger::getAudioHwSyncForSession(audio_session_t sessionId)  {      Mutex::Autolock _l(mLock); + +    ssize_t index = mHwAvSyncIds.indexOfKey(sessionId); +    if (index >= 0) { +        ALOGV("getAudioHwSyncForSession found ID %d for session %d", +              mHwAvSyncIds.valueAt(index), sessionId); +        return mHwAvSyncIds.valueAt(index); +    } + +    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice(); +    if (dev == NULL) { +        return AUDIO_HW_SYNC_INVALID; +    } +    char *reply = dev->get_parameters(dev, AUDIO_PARAMETER_HW_AV_SYNC); +    AudioParameter param = AudioParameter(String8(reply)); +    free(reply); + +    int value; +    if (param.getInt(String8(AUDIO_PARAMETER_HW_AV_SYNC), value) != NO_ERROR) { +        ALOGW("getAudioHwSyncForSession error getting sync for session %d", sessionId); +        return AUDIO_HW_SYNC_INVALID; +    } + +    // allow only one session for a given HW A/V sync ID. +    for (size_t i = 0; i < mHwAvSyncIds.size(); i++) { +        if (mHwAvSyncIds.valueAt(i) == (audio_hw_sync_t)value) { +            ALOGV("getAudioHwSyncForSession removing ID %d for session %d", +                  value, mHwAvSyncIds.keyAt(i)); +            mHwAvSyncIds.removeItemsAt(i); +            break; +        } +    } + +    mHwAvSyncIds.add(sessionId, value); +      for (size_t i = 0; i < mPlaybackThreads.size(); i++) {          sp<PlaybackThread> thread = mPlaybackThreads.valueAt(i); -        if ((thread->hasAudioSession(sessionId) & ThreadBase::TRACK_SESSION) != 0) { -            // A session can only be on one thread, so exit after first match -            String8 reply = thread->getParameters(String8(AUDIO_PARAMETER_STREAM_HW_AV_SYNC)); -            AudioParameter param = AudioParameter(reply); -            int value; -            if (param.getInt(String8(AUDIO_PARAMETER_STREAM_HW_AV_SYNC), value) == NO_ERROR) { -                return value; -            } +        uint32_t sessions = thread->hasAudioSession(sessionId); +        if (sessions & PlaybackThread::TRACK_SESSION) { +            AudioParameter param = AudioParameter(); +            param.addInt(String8(AUDIO_PARAMETER_STREAM_HW_AV_SYNC), value); +            thread->setParameters(param.toString());              break;          }      } -    return AUDIO_HW_SYNC_INVALID; + +    ALOGV("getAudioHwSyncForSession adding ID %d for session %d", value, sessionId); +    return (audio_hw_sync_t)value; +} + +// setAudioHwSyncForSession_l() must be called with AudioFlinger::mLock held +void AudioFlinger::setAudioHwSyncForSession_l(PlaybackThread *thread, audio_session_t sessionId) +{ +    ssize_t index = mHwAvSyncIds.indexOfKey(sessionId); +    if (index >= 0) { +        audio_hw_sync_t syncId = mHwAvSyncIds.valueAt(index); +        ALOGV("setAudioHwSyncForSession_l found ID %d for session %d", syncId, sessionId); +        AudioParameter param = AudioParameter(); +        param.addInt(String8(AUDIO_PARAMETER_STREAM_HW_AV_SYNC), syncId); +        thread->setParameters(param.toString()); +    }  } +  // ---------------------------------------------------------------------------- @@ -1935,13 +1999,13 @@ sp<AudioFlinger::RecordThread> AudioFlinger::openInput_l(audio_module_handle_t m      status_t status = inHwHal->open_input_stream(inHwHal, *input, device, &halconfig,                                          &inStream, flags, address.string(), source);      ALOGV("openInput_l() openInputStream returned input %p, SamplingRate %d" -           ", Format %#x, Channels %x, flags %#x, status %d", +           ", Format %#x, Channels %x, flags %#x, status %d addr %s",              inStream,              halconfig.sample_rate,              halconfig.format,              halconfig.channel_mask,              flags, -            status); +            status, address.string());      // If the input could not be opened with the requested parameters and we can handle the      // conversion internally, try to open again with the proposed parameters. The AudioFlinger can diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 1003017..aa0af1f 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -733,6 +733,8 @@ private:                  // Effect chains without a valid thread                  DefaultKeyedVector< audio_session_t , sp<EffectChain> > mOrphanEffectChains; +                // list of sessions for which a valid HW A/V sync ID was retrieved from the HAL +                DefaultKeyedVector< audio_session_t , audio_hw_sync_t >mHwAvSyncIds;  private:      sp<Client>  registerPid(pid_t pid);    // always returns non-0 @@ -741,6 +743,9 @@ private:      void        closeOutputInternal_l(sp<PlaybackThread> thread);      status_t    closeInput_nonvirtual(audio_io_handle_t input);      void        closeInputInternal_l(sp<RecordThread> thread); +    void        setAudioHwSyncForSession_l(PlaybackThread *thread, audio_session_t sessionId); + +    status_t    checkStreamType(audio_stream_type_t stream) const;  #ifdef TEE_SINK      // all record threads serially share a common tee sink, which is re-created on format change diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp index 7544052..4f0c6b1 100644 --- a/services/audioflinger/PatchPanel.cpp +++ b/services/audioflinger/PatchPanel.cpp @@ -166,7 +166,9 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa              if (*handle == mPatches[index]->mHandle) {                  ALOGV("createAudioPatch() removing patch handle %d", *handle);                  halHandle = mPatches[index]->mHalHandle; +                Patch *removedPatch = mPatches[index];                  mPatches.removeAt(index); +                delete removedPatch;                  break;              }          } diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index b429cc2..5282ffe 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -1197,6 +1197,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge          mScreenState(AudioFlinger::mScreenState),          // index 0 is reserved for normal mixer's submix          mFastTrackAvailMask(((1 << FastMixerState::kMaxFastTracks) - 1) & ~1), +        mHwSupportsPause(false), mHwPaused(false), mFlushPending(false),          // mLatchD, mLatchQ,          mLatchDValid(false), mLatchQValid(false)  { @@ -1224,15 +1225,12 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge      readOutputParameters_l(); -    // mStreamTypes[AUDIO_STREAM_CNT] is initialized by stream_type_t default constructor -    // There is no AUDIO_STREAM_MIN, and ++ operator does not compile +    // ++ operator does not compile      for (audio_stream_type_t stream = AUDIO_STREAM_MIN; stream < AUDIO_STREAM_CNT;              stream = (audio_stream_type_t) (stream + 1)) {          mStreamTypes[stream].volume = mAudioFlinger->streamVolume_l(stream);          mStreamTypes[stream].mute = mAudioFlinger->streamMute_l(stream);      } -    // mStreamTypes[AUDIO_STREAM_CNT] exists but isn't explicitly initialized here, -    // because mAudioFlinger doesn't have one to copy from  }  AudioFlinger::PlaybackThread::~PlaybackThread() @@ -1625,13 +1623,15 @@ status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)          if (track->isExternalTrack()) {              TrackBase::track_state state = track->mState;              mLock.unlock(); -            status = AudioSystem::startOutput(mId, track->streamType(), track->sessionId()); +            status = AudioSystem::startOutput(mId, track->streamType(), +                                              (audio_session_t)track->sessionId());              mLock.lock();              // abort track was stopped/paused while we released the lock              if (state != track->mState) {                  if (status == NO_ERROR) {                      mLock.unlock(); -                    AudioSystem::stopOutput(mId, track->streamType(), track->sessionId()); +                    AudioSystem::stopOutput(mId, track->streamType(), +                                            (audio_session_t)track->sessionId());                      mLock.lock();                  }                  return INVALID_OPERATION; @@ -1848,6 +1848,19 @@ void AudioFlinger::PlaybackThread::readOutputParameters_l()          }      } +    mHwSupportsPause = false; +    if (mOutput->flags & AUDIO_OUTPUT_FLAG_DIRECT) { +        if (mOutput->stream->pause != NULL) { +            if (mOutput->stream->resume != NULL) { +                mHwSupportsPause = true; +            } else { +                ALOGW("direct output implements pause but not resume"); +            } +        } else if (mOutput->stream->resume != NULL) { +            ALOGW("direct output implements resume but not pause"); +        } +    } +      // Calculate size of normal sink buffer relative to the HAL output buffer size      double multiplier = 1.0;      if (mType == MIXER && (kUseFastMixer == FastMixer_Static || @@ -2060,13 +2073,15 @@ void AudioFlinger::PlaybackThread::threadLoop_removeTracks(          for (size_t i = 0 ; i < count ; i++) {              const sp<Track>& track = tracksToRemove.itemAt(i);              if (track->isExternalTrack()) { -                AudioSystem::stopOutput(mId, track->streamType(), track->sessionId()); +                AudioSystem::stopOutput(mId, track->streamType(), +                                        (audio_session_t)track->sessionId());  #ifdef ADD_BATTERY_DATA                  // to track the speaker usage                  addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop);  #endif                  if (track->isTerminated()) { -                    AudioSystem::releaseOutput(mId); +                    AudioSystem::releaseOutput(mId, track->streamType(), +                                               (audio_session_t)track->sessionId());                  }              }          } @@ -2179,7 +2194,13 @@ void AudioFlinger::PlaybackThread::threadLoop_drain()  void AudioFlinger::PlaybackThread::threadLoop_exit()  { -    // Default implementation has nothing to do +    { +        Mutex::Autolock _l(mLock); +        for (size_t i = 0; i < mTracks.size(); i++) { +            sp<Track> track = mTracks[i]; +            track->invalidate(); +        } +    }  }  /* @@ -2687,7 +2708,8 @@ status_t AudioFlinger::PlaybackThread::getTimestamp_l(AudioTimestamp& timestamp)      if (mNormalSink != 0) {          return mNormalSink->getTimestamp(timestamp);      } -    if ((mType == OFFLOAD || mType == DIRECT) && mOutput->stream->get_presentation_position) { +    if ((mType == OFFLOAD || mType == DIRECT) +            && mOutput != NULL && mOutput->stream->get_presentation_position) {          uint64_t position64;          int ret = mOutput->stream->get_presentation_position(                                                  mOutput->stream, &position64, ×tamp.mTime); @@ -3070,6 +3092,7 @@ void AudioFlinger::PlaybackThread::threadLoop_standby()          mCallbackThread->setWriteBlocked(mWriteAckSequence);          mCallbackThread->setDraining(mDrainSequence);      } +    mHwPaused = false;  }  void AudioFlinger::PlaybackThread::onAddNewTrack_l() @@ -3982,6 +4005,9 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep  {      size_t count = mActiveTracks.size();      mixer_state mixerStatus = MIXER_IDLE; +    bool doHwPause = false; +    bool doHwResume = false; +    bool flushPending = false;      // find out which tracks need to be processed      for (size_t i = 0; i < count; i++) { @@ -4000,10 +4026,37 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep          sp<Track> l = mLatestActiveTrack.promote();          bool last = l.get() == track; +        if (mHwSupportsPause && track->isPausing()) { +            track->setPaused(); +            if (last && !mHwPaused) { +                doHwPause = true; +                mHwPaused = true; +            } +            tracksToRemove->add(track); +        } else if (track->isFlushPending()) { +            track->flushAck(); +            if (last) { +                flushPending = true; +            } +        } else if (mHwSupportsPause && track->isResumePending()){ +            track->resumeAck(); +            if (last) { +                if (mHwPaused) { +                    doHwResume = true; +                    mHwPaused = false; +                } +            } +        } +          // The first time a track is added we wait -        // for all its buffers to be filled before processing it +        // for all its buffers to be filled before processing it. +        // Allow draining the buffer in case the client +        // app does not call stop() and relies on underrun to stop: +        // hence the test on (track->mRetryCount > 1). +        // If retryCount<=1 then track is about to underrun and be removed.          uint32_t minFrames; -        if ((track->sharedBuffer() == 0) && !track->isStopping_1() && !track->isPausing()) { +        if ((track->sharedBuffer() == 0) && !track->isStopping_1() && !track->isPausing() +            && (track->mRetryCount > 1)) {              minFrames = mNormalFrameCount;          } else {              minFrames = 1; @@ -4018,8 +4071,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep                  track->mFillingUpStatus = Track::FS_ACTIVE;                  // make sure processVolume_l() will apply new volume even if 0                  mLeftVolFloat = mRightVolFloat = -1.0; -                if (track->mState == TrackBase::RESUMING) { -                    track->mState = TrackBase::ACTIVE; +                if (!mHwSupportsPause) { +                    track->resumeAck();                  }              } @@ -4030,6 +4083,10 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep                  track->mRetryCount = kMaxTrackRetriesDirect;                  mActiveTrack = t;                  mixerStatus = MIXER_TRACKS_READY; +                if (usesHwAvSync() && mHwPaused) { +                    doHwResume = true; +                    mHwPaused = false; +                }              }          } else {              // clear effect chain input buffer if the last active track started underruns @@ -4058,9 +4115,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep                          track->mState = TrackBase::STOPPED;                      }                      if (track->isStopped()) { -                        if (track->mState == TrackBase::FLUSHED) { -                            flushHw_l(); -                        }                          track->reset();                      }                      tracksToRemove->add(track); @@ -4077,11 +4131,39 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep                      android_atomic_or(CBLK_DISABLED, &cblk->mFlags);                  } else if (last) {                      mixerStatus = MIXER_TRACKS_ENABLED; +                    if (usesHwAvSync() && !mHwPaused && !mStandby) { +                        doHwPause = true; +                        mHwPaused = true; +                    }                  }              }          }      } +    // if an active track did not command a flush, check for pending flush on stopped tracks +    if (!flushPending) { +        for (size_t i = 0; i < mTracks.size(); i++) { +            if (mTracks[i]->isFlushPending()) { +                mTracks[i]->flushAck(); +                flushPending = true; +            } +        } +    } + +    // make sure the pause/flush/resume sequence is executed in the right order. +    // If a flush is pending and a track is active but the HW is not paused, force a HW pause +    // before flush and then resume HW. This can happen in case of pause/flush/resume +    // if resume is received before pause is executed. +    if (mHwSupportsPause && !mStandby && +            (doHwPause || (flushPending && !mHwPaused && (count != 0)))) { +        mOutput->stream->pause(mOutput->stream); +    } +    if (flushPending) { +        flushHw_l(); +    } +    if (mHwSupportsPause && !mStandby && doHwResume) { +        mOutput->stream->resume(mOutput->stream); +    }      // remove all the tracks that need to be...      removeTracks_l(*tracksToRemove); @@ -4114,6 +4196,11 @@ void AudioFlinger::DirectOutputThread::threadLoop_mix()  void AudioFlinger::DirectOutputThread::threadLoop_sleepTime()  { +    // do not write to HAL when paused +    if (mHwPaused || (usesHwAvSync() && mStandby)) { +        sleepTime = idleSleepTime; +        return; +    }      if (sleepTime == 0) {          if (mMixerStatus == MIXER_TRACKS_ENABLED) {              sleepTime = activeSleepTime; @@ -4126,6 +4213,38 @@ void AudioFlinger::DirectOutputThread::threadLoop_sleepTime()      }  } +void AudioFlinger::DirectOutputThread::threadLoop_exit() +{ +    { +        Mutex::Autolock _l(mLock); +        bool flushPending = false; +        for (size_t i = 0; i < mTracks.size(); i++) { +            if (mTracks[i]->isFlushPending()) { +                mTracks[i]->flushAck(); +                flushPending = true; +            } +        } +        if (flushPending) { +            flushHw_l(); +        } +    } +    PlaybackThread::threadLoop_exit(); +} + +// must be called with thread mutex locked +bool AudioFlinger::DirectOutputThread::shouldStandby_l() +{ +    bool trackPaused = false; + +    // do not put the HAL in standby when paused. AwesomePlayer clear the offloaded AudioTrack +    // after a timeout and we will enter standby then. +    if (mTracks.size() > 0) { +        trackPaused = mTracks[mTracks.size() - 1]->isPaused(); +    } + +    return !mStandby && !(trackPaused || (usesHwAvSync() && mHwPaused)); +} +  // getTrackName_l() must be called with ThreadBase::mLock held  int AudioFlinger::DirectOutputThread::getTrackName_l(audio_channel_mask_t channelMask __unused,          audio_format_t format __unused, int sessionId __unused) @@ -4235,8 +4354,10 @@ void AudioFlinger::DirectOutputThread::cacheParameters_l()  void AudioFlinger::DirectOutputThread::flushHw_l()  { -    if (mOutput->stream->flush != NULL) +    if (mOutput->stream->flush != NULL) {          mOutput->stream->flush(mOutput->stream); +    } +    mHwPaused = false;  }  // ---------------------------------------------------------------------------- @@ -4345,8 +4466,6 @@ void AudioFlinger::AsyncCallbackThread::resetDraining()  AudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger,          AudioStreamOut* output, audio_io_handle_t id, uint32_t device)      :   DirectOutputThread(audioFlinger, output, id, device, OFFLOAD), -        mHwPaused(false), -        mFlushPending(false),          mPausedBytesRemaining(0)  {      //FIXME: mStandby should be set to true by ThreadBase constructor @@ -4583,21 +4702,6 @@ bool AudioFlinger::OffloadThread::waitingAsyncCallback_l()      return false;  } -// must be called with thread mutex locked -bool AudioFlinger::OffloadThread::shouldStandby_l() -{ -    bool trackPaused = false; - -    // do not put the HAL in standby when paused. AwesomePlayer clear the offloaded AudioTrack -    // after a timeout and we will enter standby then. -    if (mTracks.size() > 0) { -        trackPaused = mTracks[mTracks.size() - 1]->isPaused(); -    } - -    return !mStandby && !trackPaused; -} - -  bool AudioFlinger::OffloadThread::waitingAsyncCallback()  {      Mutex::Autolock _l(mLock); @@ -4612,7 +4716,6 @@ void AudioFlinger::OffloadThread::flushHw_l()      mBytesRemaining = 0;      mPausedWriteLength = 0;      mPausedBytesRemaining = 0; -    mHwPaused = false;      if (mUseAsyncWrite) {          // discard any pending drain or write ack by incrementing sequence @@ -4694,15 +4797,15 @@ void AudioFlinger::DuplicatingThread::threadLoop_sleepTime()  ssize_t AudioFlinger::DuplicatingThread::threadLoop_write()  { +    // We convert the duplicating thread format to AUDIO_FORMAT_PCM_16_BIT +    // for delivery downstream as needed. This in-place conversion is safe as +    // AUDIO_FORMAT_PCM_16_BIT is smaller than any other supported format +    // (AUDIO_FORMAT_PCM_8_BIT is not allowed here). +    if (mFormat != AUDIO_FORMAT_PCM_16_BIT) { +        memcpy_by_audio_format(mSinkBuffer, AUDIO_FORMAT_PCM_16_BIT, +                               mSinkBuffer, mFormat, writeFrames * mChannelCount); +    }      for (size_t i = 0; i < outputTracks.size(); i++) { -        // We convert the duplicating thread format to AUDIO_FORMAT_PCM_16_BIT -        // for delivery downstream as needed. This in-place conversion is safe as -        // AUDIO_FORMAT_PCM_16_BIT is smaller than any other supported format -        // (AUDIO_FORMAT_PCM_8_BIT is not allowed here). -        if (mFormat != AUDIO_FORMAT_PCM_16_BIT) { -            memcpy_by_audio_format(mSinkBuffer, AUDIO_FORMAT_PCM_16_BIT, -                    mSinkBuffer, mFormat, writeFrames * mChannelCount); -        }          outputTracks[i]->write(reinterpret_cast<int16_t*>(mSinkBuffer), writeFrames);      }      mStandby = false; @@ -4746,7 +4849,7 @@ void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)                                              frameCount,                                              IPCThreadState::self()->getCallingUid());      if (outputTrack->cblk() != NULL) { -        thread->setStreamVolume(AUDIO_STREAM_CNT, 1.0f); +        thread->setStreamVolume(AUDIO_STREAM_PATCH, 1.0f);          mOutputTracks.add(outputTrack);          ALOGV("addOutputTrack() track %p, on thread %p", outputTrack, thread);          updateWaitTime_l(); diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index ecb8e4e..56a42a8 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -712,6 +712,9 @@ protected:                                     audio_patch_handle_t *handle);      virtual     status_t    releaseAudioPatch_l(const audio_patch_handle_t handle); +                bool        usesHwAvSync() const { return (mType == DIRECT) && (mOutput != NULL) && +                                                (mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC); } +  private:      friend class AudioFlinger;      // for numerous @@ -729,9 +732,7 @@ private:      void        dumpTracks(int fd, const Vector<String16>& args);      SortedVector< sp<Track> >       mTracks; -    // mStreamTypes[] uses 1 additional stream type internally for the OutputTrack used by -    // DuplicatingThread -    stream_type_t                   mStreamTypes[AUDIO_STREAM_CNT + 1]; +    stream_type_t                   mStreamTypes[AUDIO_STREAM_CNT];      AudioStreamOut                  *mOutput;      float                           mMasterVolume; @@ -813,7 +814,9 @@ public:  protected:                  // accessed by both binder threads and within threadLoop(), lock on mutex needed                  unsigned    mFastTrackAvailMask;    // bit i set if fast track [i] is available - +                bool        mHwSupportsPause; +                bool        mHwPaused; +                bool        mFlushPending;  private:      // timestamp latch:      //  D input is written by threadLoop_write while mutex is unlocked, and read while locked @@ -914,6 +917,8 @@ protected:      virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);      virtual     void        threadLoop_mix();      virtual     void        threadLoop_sleepTime(); +    virtual     void        threadLoop_exit(); +    virtual     bool        shouldStandby_l();      // volumes last sent to audio HAL with stream->set_volume()      float mLeftVolFloat; @@ -944,12 +949,9 @@ protected:      virtual     bool        waitingAsyncCallback();      virtual     bool        waitingAsyncCallback_l(); -    virtual     bool        shouldStandby_l();      virtual     void        onAddNewTrack_l();  private: -    bool        mHwPaused; -    bool        mFlushPending;      size_t      mPausedWriteLength;     // length in bytes of write interrupted by pause      size_t      mPausedBytesRemaining;  // bytes still waiting in mixbuffer after resume      wp<Track>   mPreviousTrack;         // used to detect track switch diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp index b9308fa..e970036 100644 --- a/services/audioflinger/Tracks.cpp +++ b/services/audioflinger/Tracks.cpp @@ -491,7 +491,7 @@ void AudioFlinger::PlaybackThread::Track::destroy()              wasActive = playbackThread->destroyTrack_l(this);          }          if (isExternalTrack() && !wasActive) { -            AudioSystem::releaseOutput(mThreadIoHandle); +            AudioSystem::releaseOutput(mThreadIoHandle, mStreamType, (audio_session_t)mSessionId);          }      }  } @@ -611,15 +611,16 @@ status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(  // ExtendedAudioBufferProvider interface -// Note that framesReady() takes a mutex on the control block using tryLock(). -// This could result in priority inversion if framesReady() is called by the normal mixer, -// as the normal mixer thread runs at lower -// priority than the client's callback thread:  there is a short window within framesReady() -// during which the normal mixer could be preempted, and the client callback would block. -// Another problem can occur if framesReady() is called by the fast mixer: -// the tryLock() could block for up to 1 ms, and a sequence of these could delay fast mixer. -// FIXME Replace AudioTrackShared control block implementation by a non-blocking FIFO queue. +// framesReady() may return an approximation of the number of frames if called +// from a different thread than the one calling Proxy->obtainBuffer() and +// Proxy->releaseBuffer(). Also note there is no mutual exclusion in the +// AudioTrackServerProxy so be especially careful calling with FastTracks.  size_t AudioFlinger::PlaybackThread::Track::framesReady() const { +    if (mSharedBuffer != 0 && (isStopped() || isStopping())) { +        // Static tracks return zero frames immediately upon stopping (for FastTracks). +        // The remainder of the buffer is not drained. +        return 0; +    }      return mAudioTrackServerProxy->framesReady();  } @@ -822,12 +823,11 @@ void AudioFlinger::PlaybackThread::Track::flush()              // this will be done by prepareTracks_l() when the track is stopped.              // prepareTracks_l() will see mState == FLUSHED, then              // remove from active track list, reset(), and trigger presentation complete +            if (isDirect()) { +                mFlushHwPending = true; +            }              if (playbackThread->mActiveTracks.indexOf(this) < 0) {                  reset(); -                if (thread->type() == ThreadBase::DIRECT) { -                    DirectOutputThread *t = (DirectOutputThread *)playbackThread; -                    t->flushHw_l(); -                }              }          }          // Prevent flush being lost if the track is flushed and then resumed @@ -840,7 +840,7 @@ void AudioFlinger::PlaybackThread::Track::flush()  // must be called with thread lock held  void AudioFlinger::PlaybackThread::Track::flushAck()  { -    if (!isOffloaded()) +    if (!isOffloaded() && !isDirect())          return;      mFlushHwPending = false; @@ -1656,8 +1656,9 @@ AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(              audio_channel_mask_t channelMask,              size_t frameCount,              int uid) -    :   Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount, -                NULL, 0, 0, uid, IAudioFlinger::TRACK_DEFAULT, TYPE_OUTPUT), +    :   Track(playbackThread, NULL, AUDIO_STREAM_PATCH, +              sampleRate, format, channelMask, frameCount, +              NULL, 0, 0, uid, IAudioFlinger::TRACK_DEFAULT, TYPE_OUTPUT),      mActive(false), mSourceThread(sourceThread), mClientProxy(NULL)  { @@ -1872,7 +1873,8 @@ AudioFlinger::PlaybackThread::PatchTrack::PatchTrack(PlaybackThread *playbackThr                                                       size_t frameCount,                                                       void *buffer,                                                       IAudioFlinger::track_flags_t flags) -    :   Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount, +    :   Track(playbackThread, NULL, AUDIO_STREAM_PATCH, +              sampleRate, format, channelMask, frameCount,                buffer, 0, 0, getuid(), flags, TYPE_PATCH),                mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true))  { diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk index 6512c38..188fc89 100644 --- a/services/audiopolicy/Android.mk +++ b/services/audiopolicy/Android.mk @@ -30,7 +30,8 @@ LOCAL_SHARED_LIBRARIES := \      libbinder \      libmedia \      libhardware \ -    libhardware_legacy +    libhardware_legacy \ +    libserviceutility  ifneq ($(USE_LEGACY_AUDIO_POLICY), 1)  LOCAL_SHARED_LIBRARIES += \ @@ -38,8 +39,7 @@ LOCAL_SHARED_LIBRARIES += \  endif  LOCAL_STATIC_LIBRARIES := \ -    libmedia_helper \ -    libserviceutility +    libmedia_helper  LOCAL_MODULE:= libaudiopolicyservice diff --git a/services/audiopolicy/AudioPolicyClientImplLegacy.cpp b/services/audiopolicy/AudioPolicyClientImplLegacy.cpp index 97719da..a79f8ae 100644 --- a/services/audiopolicy/AudioPolicyClientImplLegacy.cpp +++ b/services/audiopolicy/AudioPolicyClientImplLegacy.cpp @@ -188,6 +188,13 @@ static audio_io_handle_t open_input(audio_module_handle_t module,      if (pSamplingRate == NULL || pFormat == NULL || pChannelMask == NULL || pDevices == NULL) {          return AUDIO_IO_HANDLE_NONE;      } + +    if (((*pDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) == AUDIO_DEVICE_IN_REMOTE_SUBMIX) +            && !captureAudioOutputAllowed()) { +        ALOGE("open_input() permission denied: capture not allowed"); +        return AUDIO_IO_HANDLE_NONE; +    } +      audio_config_t config = AUDIO_CONFIG_INITIALIZER;;      config.sample_rate = *pSamplingRate;      config.format = *pFormat; diff --git a/services/audiopolicy/AudioPolicyEffects.cpp b/services/audiopolicy/AudioPolicyEffects.cpp index e7e1b36..e6ace20 100644 --- a/services/audiopolicy/AudioPolicyEffects.cpp +++ b/services/audiopolicy/AudioPolicyEffects.cpp @@ -226,6 +226,11 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,      Mutex::Autolock _l(mLock);      // create audio processors according to stream +    // FIXME: should we have specific post processing settings for internal streams? +    // default to media for now. +    if (stream >= AUDIO_STREAM_PUBLIC_CNT) { +        stream = AUDIO_STREAM_MUSIC; +    }      ssize_t index = mOutputStreams.indexOfKey(stream);      if (index < 0) {          ALOGV("addOutputSessionEffects(): no output processing needed for this stream"); @@ -335,7 +340,7 @@ void AudioPolicyEffects::EffectVector::setProcessorEnabled(bool enabled)      return (audio_source_t)i;  } -const char *AudioPolicyEffects::kStreamNames[AUDIO_STREAM_CNT+1] = { +const char *AudioPolicyEffects::kStreamNames[AUDIO_STREAM_PUBLIC_CNT+1] = {      AUDIO_STREAM_DEFAULT_TAG,      AUDIO_STREAM_VOICE_CALL_TAG,      AUDIO_STREAM_SYSTEM_TAG, @@ -350,11 +355,11 @@ const char *AudioPolicyEffects::kStreamNames[AUDIO_STREAM_CNT+1] = {  };  // returns the audio_stream_t enum corresponding to the output stream name or -// AUDIO_STREAM_CNT is no match found +// AUDIO_STREAM_PUBLIC_CNT is no match found  audio_stream_type_t AudioPolicyEffects::streamNameToEnum(const char *name)  {      int i; -    for (i = AUDIO_STREAM_DEFAULT; i < AUDIO_STREAM_CNT; i++) { +    for (i = AUDIO_STREAM_DEFAULT; i < AUDIO_STREAM_PUBLIC_CNT; i++) {          if (strcmp(name, kStreamNames[i - AUDIO_STREAM_DEFAULT]) == 0) {              ALOGV("streamNameToEnum found stream %s %d", name, i);              break; @@ -585,7 +590,7 @@ status_t AudioPolicyEffects::loadStreamEffectConfigurations(cnode *root,      node = node->first_child;      while (node) {          audio_stream_type_t stream = streamNameToEnum(node->name); -        if (stream == AUDIO_STREAM_CNT) { +        if (stream == AUDIO_STREAM_PUBLIC_CNT) {              ALOGW("loadStreamEffectConfigurations() invalid output stream %s", node->name);              node = node->next;              continue; @@ -653,6 +658,10 @@ status_t AudioPolicyEffects::loadAudioEffectConfig(const char *path)      loadInputEffectConfigurations(root, effects);      loadStreamEffectConfigurations(root, effects); +    for (size_t i = 0; i < effects.size(); i++) { +        delete effects[i]; +    } +      config_free(root);      free(root);      free(data); diff --git a/services/audiopolicy/AudioPolicyEffects.h b/services/audiopolicy/AudioPolicyEffects.h index 6b0d538..3dec437 100644 --- a/services/audiopolicy/AudioPolicyEffects.h +++ b/services/audiopolicy/AudioPolicyEffects.h @@ -151,7 +151,7 @@ private:      static const char * const kInputSourceNames[AUDIO_SOURCE_CNT -1];      static audio_source_t inputSourceNameToEnum(const char *name); -    static const char *kStreamNames[AUDIO_STREAM_CNT+1]; //+1 required as streams start from -1 +    static const char *kStreamNames[AUDIO_STREAM_PUBLIC_CNT+1]; //+1 required as streams start from -1      audio_stream_type_t streamNameToEnum(const char *name);      // Parse audio_effects.conf diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h index 5524463..4508fa7 100644 --- a/services/audiopolicy/AudioPolicyInterface.h +++ b/services/audiopolicy/AudioPolicyInterface.h @@ -18,6 +18,7 @@  #define ANDROID_AUDIOPOLICY_INTERFACE_H  #include <media/AudioSystem.h> +#include <media/AudioPolicy.h>  #include <utils/String8.h>  #include <hardware/audio_policy.h> @@ -56,6 +57,16 @@ class AudioPolicyInterface  {  public: +    typedef enum { +        API_INPUT_INVALID = -1, +        API_INPUT_LEGACY  = 0,// e.g. audio recording from a microphone +        API_INPUT_MIX_CAPTURE,// used for "remote submix", capture of the media to play it remotely +        API_INPUT_MIX_EXT_POLICY_REROUTE,// used for platform audio rerouting, where mixes are +                                         // handled by external and dynamically installed +                                         // policies which reroute audio mixes +    } input_type_t; + +public:      virtual ~AudioPolicyInterface() {}      //      // configuration functions @@ -90,30 +101,37 @@ public:                                          audio_channel_mask_t channelMask,                                          audio_output_flags_t flags,                                          const audio_offload_info_t *offloadInfo) = 0; -    virtual audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr, -                                                uint32_t samplingRate, -                                                audio_format_t format, -                                                audio_channel_mask_t channelMask, -                                                audio_output_flags_t flags, -                                                const audio_offload_info_t *offloadInfo) = 0; +    virtual 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, +                                        audio_format_t format, +                                        audio_channel_mask_t channelMask, +                                        audio_output_flags_t flags, +                                        const audio_offload_info_t *offloadInfo) = 0;      // indicates to the audio policy manager that the output starts being used by corresponding stream.      virtual status_t startOutput(audio_io_handle_t output,                                   audio_stream_type_t stream, -                                 int session = 0) = 0; +                                 audio_session_t session) = 0;      // indicates to the audio policy manager that the output stops being used by corresponding stream.      virtual status_t stopOutput(audio_io_handle_t output,                                  audio_stream_type_t stream, -                                int session = 0) = 0; +                                audio_session_t session) = 0;      // releases the output. -    virtual void releaseOutput(audio_io_handle_t output) = 0; +    virtual void releaseOutput(audio_io_handle_t output, +                               audio_stream_type_t stream, +                               audio_session_t session) = 0;      // request an input appropriate for record from the supplied device with supplied parameters. -    virtual audio_io_handle_t getInput(audio_source_t inputSource, -                                    uint32_t samplingRate, -                                    audio_format_t format, -                                    audio_channel_mask_t channelMask, -                                    audio_session_t session, -                                    audio_input_flags_t flags) = 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, +                                     input_type_t *inputType) = 0;      // indicates to the audio policy manager that the input starts being used.      virtual status_t startInput(audio_io_handle_t input,                                  audio_session_t session) = 0; @@ -195,6 +213,9 @@ public:                                             audio_devices_t *device) = 0;      virtual status_t releaseSoundTriggerSession(audio_session_t session) = 0; + +    virtual status_t registerPolicyMixes(Vector<AudioMix> mixes) = 0; +    virtual status_t unregisterPolicyMixes(Vector<AudioMix> mixes) = 0;  }; diff --git a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp index be3c5ad..a45dbb3 100644 --- a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp @@ -129,11 +129,11 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,                                      audio_output_flags_t flags,                                      const audio_offload_info_t *offloadInfo)  { -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { -        return BAD_VALUE; +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) { +        return AUDIO_IO_HANDLE_NONE;      }      if (mAudioPolicyManager == NULL) { -        return 0; +        return AUDIO_IO_HANDLE_NONE;      }      ALOGV("getOutput()");      Mutex::Autolock _l(mLock); @@ -141,25 +141,28 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,                                      format, channelMask, flags, offloadInfo);  } -audio_io_handle_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, -                                    uint32_t samplingRate, -                                    audio_format_t format, -                                    audio_channel_mask_t channelMask, -                                    audio_output_flags_t flags, -                                    const audio_offload_info_t *offloadInfo) +status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, +                                              audio_io_handle_t *output, +                                              audio_session_t session, +                                              audio_stream_type_t *stream, +                                              uint32_t samplingRate, +                                              audio_format_t format, +                                              audio_channel_mask_t channelMask, +                                              audio_output_flags_t flags, +                                              const audio_offload_info_t *offloadInfo)  {      if (mAudioPolicyManager == NULL) { -        return 0; +        return NO_INIT;      }      ALOGV("getOutput()");      Mutex::Autolock _l(mLock); -    return mAudioPolicyManager->getOutputForAttr(attr, samplingRate, +    return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, samplingRate,                                      format, channelMask, flags, offloadInfo);  }  status_t AudioPolicyService::startOutput(audio_io_handle_t output,                                           audio_stream_type_t stream, -                                         int session) +                                         audio_session_t session)  {      if (uint32_t(stream) >= AUDIO_STREAM_CNT) {          return BAD_VALUE; @@ -186,7 +189,7 @@ status_t AudioPolicyService::startOutput(audio_io_handle_t output,  status_t AudioPolicyService::stopOutput(audio_io_handle_t output,                                          audio_stream_type_t stream, -                                        int session) +                                        audio_session_t session)  {      if (uint32_t(stream) >= AUDIO_STREAM_CNT) {          return BAD_VALUE; @@ -201,7 +204,7 @@ status_t AudioPolicyService::stopOutput(audio_io_handle_t output,  status_t  AudioPolicyService::doStopOutput(audio_io_handle_t output,                                        audio_stream_type_t stream, -                                      int session) +                                      audio_session_t session)  {      ALOGV("doStopOutput from tid %d", gettid());      sp<AudioPolicyEffects>audioPolicyEffects; @@ -220,63 +223,98 @@ status_t  AudioPolicyService::doStopOutput(audio_io_handle_t output,      return mAudioPolicyManager->stopOutput(output, stream, session);  } -void AudioPolicyService::releaseOutput(audio_io_handle_t output) +void AudioPolicyService::releaseOutput(audio_io_handle_t output, +                                       audio_stream_type_t stream, +                                       audio_session_t session)  {      if (mAudioPolicyManager == NULL) {          return;      }      ALOGV("releaseOutput()"); -    mOutputCommandThread->releaseOutputCommand(output); +    mOutputCommandThread->releaseOutputCommand(output, stream, session);  } -void AudioPolicyService::doReleaseOutput(audio_io_handle_t output) +void AudioPolicyService::doReleaseOutput(audio_io_handle_t output, +                                         audio_stream_type_t stream, +                                         audio_session_t session)  {      ALOGV("doReleaseOutput from tid %d", gettid());      Mutex::Autolock _l(mLock); -    mAudioPolicyManager->releaseOutput(output); +    mAudioPolicyManager->releaseOutput(output, stream, session);  } -audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource, -                                    uint32_t samplingRate, -                                    audio_format_t format, -                                    audio_channel_mask_t channelMask, -                                    int audioSession, -                                    audio_input_flags_t flags) +status_t AudioPolicyService::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)  {      if (mAudioPolicyManager == NULL) { -        return 0; +        return NO_INIT;      }      // already checked by client, but double-check in case the client wrapper is bypassed -    if (inputSource >= AUDIO_SOURCE_CNT && inputSource != AUDIO_SOURCE_HOTWORD && -        inputSource != AUDIO_SOURCE_FM_TUNER) { -        return 0; +    if (attr->source >= AUDIO_SOURCE_CNT && attr->source != AUDIO_SOURCE_HOTWORD && +        attr->source != AUDIO_SOURCE_FM_TUNER) { +        return BAD_VALUE;      } -    if (((inputSource == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) || -        ((inputSource == AUDIO_SOURCE_FM_TUNER) && !captureFmTunerAllowed())) { -        return 0; +    if (((attr->source == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) || +        ((attr->source == AUDIO_SOURCE_FM_TUNER) && !captureFmTunerAllowed())) { +        return BAD_VALUE;      } -    audio_io_handle_t input;      sp<AudioPolicyEffects>audioPolicyEffects; +    status_t status; +    AudioPolicyInterface::input_type_t inputType;      {          Mutex::Autolock _l(mLock);          // the audio_in_acoustics_t parameter is ignored by get_input() -        input = mAudioPolicyManager->getInput(inputSource, samplingRate, -                                                       format, channelMask, -                                                       (audio_session_t)audioSession, flags); +        status = mAudioPolicyManager->getInputForAttr(attr, input, session, +                                                     samplingRate, format, channelMask, +                                                     flags, &inputType);          audioPolicyEffects = mAudioPolicyEffects; + +        if (status == NO_ERROR) { +            // enforce permission (if any) required for each type of input +            switch (inputType) { +            case AudioPolicyInterface::API_INPUT_LEGACY: +                break; +            case AudioPolicyInterface::API_INPUT_MIX_CAPTURE: +                if (!captureAudioOutputAllowed()) { +                    ALOGE("getInputForAttr() permission denied: capture not allowed"); +                    status = PERMISSION_DENIED; +                } +                break; +            case AudioPolicyInterface::API_INPUT_MIX_EXT_POLICY_REROUTE: +                if (!modifyAudioRoutingAllowed()) { +                    ALOGE("getInputForAttr() permission denied: modify audio routing not allowed"); +                    status = PERMISSION_DENIED; +                } +                break; +            case AudioPolicyInterface::API_INPUT_INVALID: +            default: +                LOG_ALWAYS_FATAL("getInputForAttr() encountered an invalid input type %d", +                        (int)inputType); +            } +        } + +        if (status != NO_ERROR) { +            if (status == PERMISSION_DENIED) { +                mAudioPolicyManager->releaseInput(*input, session); +            } +            return status; +        }      } -    if (input == 0) { -        return input; -    } +      if (audioPolicyEffects != 0) {          // create audio pre processors according to input source -        status_t status = audioPolicyEffects->addInputEffects(input, inputSource, audioSession); +        status_t status = audioPolicyEffects->addInputEffects(*input, attr->source, session);          if (status != NO_ERROR && status != ALREADY_EXISTS) { -            ALOGW("Failed to add effects on input %d", input); +            ALOGW("Failed to add effects on input %d", *input);          }      } -    return input; +    return NO_ERROR;  }  status_t AudioPolicyService::startInput(audio_io_handle_t input, @@ -332,7 +370,7 @@ status_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,      if (!settingsAllowed()) {          return PERMISSION_DENIED;      } -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {          return BAD_VALUE;      }      Mutex::Autolock _l(mLock); @@ -350,7 +388,7 @@ status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,      if (!settingsAllowed()) {          return PERMISSION_DENIED;      } -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {          return BAD_VALUE;      }      Mutex::Autolock _l(mLock); @@ -366,7 +404,7 @@ status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,      if (mAudioPolicyManager == NULL) {          return NO_INIT;      } -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {          return BAD_VALUE;      }      Mutex::Autolock _l(mLock); @@ -377,8 +415,8 @@ status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,  uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)  { -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { -        return BAD_VALUE; +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) { +        return 0;      }      if (mAudioPolicyManager == NULL) {          return 0; @@ -390,11 +428,11 @@ uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)  audio_devices_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)  { -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { -        return BAD_VALUE; +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) { +        return AUDIO_DEVICE_NONE;      }      if (mAudioPolicyManager == NULL) { -        return (audio_devices_t)0; +        return AUDIO_DEVICE_NONE;      }      return mAudioPolicyManager->getDevicesForStream(stream);  } @@ -439,11 +477,11 @@ status_t AudioPolicyService::setEffectEnabled(int id, bool enabled)  bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const  { -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { -        return BAD_VALUE; +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) { +        return false;      }      if (mAudioPolicyManager == NULL) { -        return 0; +        return false;      }      Mutex::Autolock _l(mLock);      return mAudioPolicyManager->isStreamActive(stream, inPastMs); @@ -451,11 +489,11 @@ bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inP  bool AudioPolicyService::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const  { -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { -        return BAD_VALUE; +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) { +        return false;      }      if (mAudioPolicyManager == NULL) { -        return 0; +        return false;      }      Mutex::Autolock _l(mLock);      return mAudioPolicyManager->isStreamActiveRemotely(stream, inPastMs); @@ -606,4 +644,20 @@ status_t AudioPolicyService::releaseSoundTriggerSession(audio_session_t session)      return mAudioPolicyManager->releaseSoundTriggerSession(session);  } +status_t AudioPolicyService::registerPolicyMixes(Vector<AudioMix> mixes, bool registration) +{ +    Mutex::Autolock _l(mLock); +    if(!modifyAudioRoutingAllowed()) { +        return PERMISSION_DENIED; +    } +    if (mAudioPolicyManager == NULL) { +        return NO_INIT; +    } +    if (registration) { +        return mAudioPolicyManager->registerPolicyMixes(mixes); +    } else { +        return mAudioPolicyManager->unregisterPolicyMixes(mixes); +    } +} +  }; // namespace android diff --git a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp index 3700246..b8846c6 100644 --- a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp +++ b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp @@ -134,11 +134,11 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,                                      audio_output_flags_t flags,                                      const audio_offload_info_t *offloadInfo)  { -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { -        return BAD_VALUE; +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) { +        return AUDIO_IO_HANDLE_NONE;      }      if (mpAudioPolicy == NULL) { -        return 0; +        return AUDIO_IO_HANDLE_NONE;      }      ALOGV("getOutput()");      Mutex::Autolock _l(mLock); @@ -148,9 +148,9 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,  status_t AudioPolicyService::startOutput(audio_io_handle_t output,                                           audio_stream_type_t stream, -                                         int session) +                                         audio_session_t session)  { -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {          return BAD_VALUE;      }      if (mpAudioPolicy == NULL) { @@ -176,9 +176,9 @@ status_t AudioPolicyService::startOutput(audio_io_handle_t output,  status_t AudioPolicyService::stopOutput(audio_io_handle_t output,                                          audio_stream_type_t stream, -                                        int session) +                                        audio_session_t session)  { -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {          return BAD_VALUE;      }      if (mpAudioPolicy == NULL) { @@ -191,7 +191,7 @@ status_t AudioPolicyService::stopOutput(audio_io_handle_t output,  status_t  AudioPolicyService::doStopOutput(audio_io_handle_t output,                                        audio_stream_type_t stream, -                                      int session) +                                      audio_session_t session)  {      ALOGV("doStopOutput from tid %d", gettid());      // release audio processors from the stream @@ -210,64 +210,75 @@ status_t  AudioPolicyService::doStopOutput(audio_io_handle_t output,      return mpAudioPolicy->stop_output(mpAudioPolicy, output, stream, session);  } -void AudioPolicyService::releaseOutput(audio_io_handle_t output) +void AudioPolicyService::releaseOutput(audio_io_handle_t output, +                                       audio_stream_type_t stream, +                                       audio_session_t session)  {      if (mpAudioPolicy == NULL) {          return;      }      ALOGV("releaseOutput()"); -    mOutputCommandThread->releaseOutputCommand(output); +    mOutputCommandThread->releaseOutputCommand(output, stream, session);  } -void AudioPolicyService::doReleaseOutput(audio_io_handle_t output) +void AudioPolicyService::doReleaseOutput(audio_io_handle_t output, +                                         audio_stream_type_t stream __unused, +                                         audio_session_t session __unused)  {      ALOGV("doReleaseOutput from tid %d", gettid());      Mutex::Autolock _l(mLock);      mpAudioPolicy->release_output(mpAudioPolicy, output);  } -audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource, -                                    uint32_t samplingRate, -                                    audio_format_t format, -                                    audio_channel_mask_t channelMask, -                                    int audioSession, -                                    audio_input_flags_t flags __unused) +status_t AudioPolicyService::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 __unused)  {      if (mpAudioPolicy == NULL) { -        return 0; +        return NO_INIT;      } + +    audio_source_t inputSource = attr->source; +      // already checked by client, but double-check in case the client wrapper is bypassed      if (inputSource >= AUDIO_SOURCE_CNT && inputSource != AUDIO_SOURCE_HOTWORD &&          inputSource != AUDIO_SOURCE_FM_TUNER) { -        return 0; +        return BAD_VALUE; +    } + +    if (inputSource == AUDIO_SOURCE_DEFAULT) { +        inputSource = AUDIO_SOURCE_MIC;      }      if (((inputSource == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) ||          ((inputSource == AUDIO_SOURCE_FM_TUNER) && !captureFmTunerAllowed())) { -        return 0; +        return BAD_VALUE;      } -    audio_io_handle_t input;      sp<AudioPolicyEffects>audioPolicyEffects;      {          Mutex::Autolock _l(mLock);          // the audio_in_acoustics_t parameter is ignored by get_input() -        input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate, +        *input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,                                               format, channelMask, (audio_in_acoustics_t) 0);          audioPolicyEffects = mAudioPolicyEffects;      } -    if (input == 0) { -        return input; +    if (*input == AUDIO_IO_HANDLE_NONE) { +        return INVALID_OPERATION;      }      if (audioPolicyEffects != 0) {          // create audio pre processors according to input source -        status_t status = audioPolicyEffects->addInputEffects(input, inputSource, audioSession); +        status_t status = audioPolicyEffects->addInputEffects(*input, inputSource, session);          if (status != NO_ERROR && status != ALREADY_EXISTS) {              ALOGW("Failed to add effects on input %d", input);          }      } -    return input; +    return NO_ERROR;  }  status_t AudioPolicyService::startInput(audio_io_handle_t input, @@ -324,7 +335,7 @@ status_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,      if (!settingsAllowed()) {          return PERMISSION_DENIED;      } -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {          return BAD_VALUE;      }      Mutex::Autolock _l(mLock); @@ -342,7 +353,7 @@ status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,      if (!settingsAllowed()) {          return PERMISSION_DENIED;      } -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {          return BAD_VALUE;      }      Mutex::Autolock _l(mLock); @@ -363,7 +374,7 @@ status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,      if (mpAudioPolicy == NULL) {          return NO_INIT;      } -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {          return BAD_VALUE;      }      Mutex::Autolock _l(mLock); @@ -379,8 +390,8 @@ status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,  uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)  { -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { -        return BAD_VALUE; +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) { +        return 0;      }      if (mpAudioPolicy == NULL) {          return 0; @@ -392,11 +403,11 @@ uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)  audio_devices_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)  { -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { -        return BAD_VALUE; +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) { +        return AUDIO_DEVICE_NONE;      }      if (mpAudioPolicy == NULL) { -        return (audio_devices_t)0; +        return AUDIO_DEVICE_NONE;      }      return mpAudioPolicy->get_devices_for_stream(mpAudioPolicy, stream);  } @@ -441,11 +452,11 @@ status_t AudioPolicyService::setEffectEnabled(int id, bool enabled)  bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const  { -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { -        return BAD_VALUE; +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) { +        return false;      }      if (mpAudioPolicy == NULL) { -        return 0; +        return false;      }      Mutex::Autolock _l(mLock);      return mpAudioPolicy->is_stream_active(mpAudioPolicy, stream, inPastMs); @@ -453,11 +464,11 @@ bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inP  bool AudioPolicyService::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const  { -    if (uint32_t(stream) >= AUDIO_STREAM_CNT) { -        return BAD_VALUE; +    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) { +        return false;      }      if (mpAudioPolicy == NULL) { -        return 0; +        return false;      }      Mutex::Autolock _l(mLock);      return mpAudioPolicy->is_stream_active_remotely(mpAudioPolicy, stream, inPastMs); @@ -549,26 +560,45 @@ status_t AudioPolicyService::setAudioPortConfig(const struct audio_port_config *      return INVALID_OPERATION;  } -audio_io_handle_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, -                                    uint32_t samplingRate, -                                    audio_format_t format, -                                    audio_channel_mask_t channelMask, -                                    audio_output_flags_t flags, -                                    const audio_offload_info_t *offloadInfo) +status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr, +                                              audio_io_handle_t *output, +                                              audio_session_t session __unused, +                                              audio_stream_type_t *stream, +                                              uint32_t samplingRate, +                                              audio_format_t format, +                                              audio_channel_mask_t channelMask, +                                              audio_output_flags_t flags, +                                              const audio_offload_info_t *offloadInfo)  { -    audio_stream_type_t stream = audio_attributes_to_stream_type(attr); +    if (attr != NULL) { +        *stream = audio_attributes_to_stream_type(attr); +    } else { +        if (*stream == AUDIO_STREAM_DEFAULT) { +            return BAD_VALUE; +        } +    } +    *output = getOutput(*stream, samplingRate, format, channelMask, +                                          flags, offloadInfo); +    if (*output == AUDIO_IO_HANDLE_NONE) { +        return INVALID_OPERATION; +    } +    return NO_ERROR; +} -    return getOutput(stream, samplingRate, format, channelMask, flags, offloadInfo); +status_t AudioPolicyService::acquireSoundTriggerSession(audio_session_t *session __unused, +                                       audio_io_handle_t *ioHandle __unused, +                                       audio_devices_t *device __unused) +{ +    return INVALID_OPERATION;  } -status_t AudioPolicyService::acquireSoundTriggerSession(audio_session_t *session, -                                       audio_io_handle_t *ioHandle, -                                       audio_devices_t *device) +status_t AudioPolicyService::releaseSoundTriggerSession(audio_session_t session __unused)  {      return INVALID_OPERATION;  } -status_t AudioPolicyService::releaseSoundTriggerSession(audio_session_t session) +status_t AudioPolicyService::registerPolicyMixes(Vector<AudioMix> mixes __unused, +                                                 bool registration __unused)  {      return INVALID_OPERATION;  } diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp index c437551..6ebd0ed 100644 --- a/services/audiopolicy/AudioPolicyManager.cpp +++ b/services/audiopolicy/AudioPolicyManager.cpp @@ -43,6 +43,7 @@  #include <hardware/audio.h>  #include <hardware/audio_effect.h>  #include <media/AudioParameter.h> +#include <media/AudioPolicyHelper.h>  #include <soundtrigger/SoundTrigger.h>  #include "AudioPolicyManager.h"  #include "audio_policy_conf.h" @@ -210,25 +211,29 @@ bool AudioPolicyManager::stringToBool(const char *value)  // AudioPolicyInterface implementation  // ---------------------------------------------------------------------------- -  status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,                                                            audio_policy_dev_state_t state,                                                    const char *device_address)  { -    String8 address = (device_address == NULL) ? String8("") : String8(device_address); +    return setDeviceConnectionStateInt(device, state, device_address); +} +status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device, +                                                         audio_policy_dev_state_t state, +                                                         const char *device_address) +{      ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", -            device, state, address.string()); +            device, state, device_address != NULL ? device_address : "");      // connect/disconnect only 1 device at a time      if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE; +    sp<DeviceDescriptor> devDesc = getDeviceDescriptor(device, device_address); +      // handle output devices      if (audio_is_output_device(device)) {          SortedVector <audio_io_handle_t> outputs; -        sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); -        devDesc->mAddress = address;          ssize_t index = mAvailableOutputDevices.indexOf(devDesc);          // save a copy of the opened output descriptors before any output is opened or closed @@ -237,7 +242,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,          switch (state)          {          // handle output device connection -        case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: +        case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {              if (index >= 0) {                  ALOGW("setDeviceConnectionState() device already connected: %x", device);                  return INVALID_OPERATION; @@ -260,7 +265,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,                  return NO_MEMORY;              } -            if (checkOutputsForDevice(devDesc, state, outputs, address) != NO_ERROR) { +            if (checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress) != NO_ERROR) {                  mAvailableOutputDevices.remove(devDesc);                  return INVALID_OPERATION;              } @@ -269,7 +274,14 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,                      "checkOutputsForDevice() returned no outputs but status OK");              ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",                    outputs.size()); -            break; + + +            // Set connect to HALs +            AudioParameter param = AudioParameter(devDesc->mAddress); +            param.addInt(String8(AUDIO_PARAMETER_DEVICE_CONNECT), device); +            mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString()); + +            } break;          // handle output device disconnection          case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {              if (index < 0) { @@ -280,14 +292,14 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,              ALOGV("setDeviceConnectionState() disconnecting output device %x", device);              // Set Disconnect to HALs -            AudioParameter param = AudioParameter(address); +            AudioParameter param = AudioParameter(devDesc->mAddress);              param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device);              mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());              // remove device from available output devices              mAvailableOutputDevices.remove(devDesc); -            checkOutputsForDevice(devDesc, state, outputs, address); +            checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress);              } break;          default: @@ -344,8 +356,6 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,      if (audio_is_input_device(device)) {          SortedVector <audio_io_handle_t> inputs; -        sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); -        devDesc->mAddress = address;          ssize_t index = mAvailableInputDevices.indexOf(devDesc);          switch (state)          { @@ -361,7 +371,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,                        device);                  return INVALID_OPERATION;              } -            if (checkInputsForDevice(device, state, inputs, address) != NO_ERROR) { +            if (checkInputsForDevice(device, state, inputs, devDesc->mAddress) != NO_ERROR) {                  return INVALID_OPERATION;              } @@ -372,6 +382,12 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,              } else {                  return NO_MEMORY;              } + +            // Set connect to HALs +            AudioParameter param = AudioParameter(devDesc->mAddress); +            param.addInt(String8(AUDIO_PARAMETER_DEVICE_CONNECT), device); +            mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString()); +          } break;          // handle input device disconnection @@ -384,11 +400,11 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,              ALOGV("setDeviceConnectionState() disconnecting input device %x", device);              // Set Disconnect to HALs -            AudioParameter param = AudioParameter(address); +            AudioParameter param = AudioParameter(devDesc->mAddress);              param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device);              mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString()); -            checkInputsForDevice(device, state, inputs, address); +            checkInputsForDevice(device, state, inputs, devDesc->mAddress);              mAvailableInputDevices.remove(devDesc);          } break; @@ -416,10 +432,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,  audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,                                                    const char *device_address)  { -    audio_policy_dev_state_t state = AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; -    sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); -    devDesc->mAddress = (device_address == NULL) ? String8("") : String8(device_address); -    ssize_t index; +    sp<DeviceDescriptor> devDesc = getDeviceDescriptor(device, device_address);      DeviceVector *deviceVector;      if (audio_is_output_device(device)) { @@ -431,7 +444,7 @@ audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devi          return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;      } -    index = deviceVector->indexOf(devDesc); +    ssize_t index = deviceVector->indexOf(devDesc);      if (index >= 0) {          return AUDIO_POLICY_DEVICE_STATE_AVAILABLE;      } else { @@ -439,6 +452,36 @@ audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devi      }  } +sp<AudioPolicyManager::DeviceDescriptor>  AudioPolicyManager::getDeviceDescriptor( +                                                                    const audio_devices_t device, +                                                                    const char *device_address) +{ +    String8 address = (device_address == NULL) ? String8("") : String8(device_address); +    // handle legacy remote submix case where the address was not always specified +    if (deviceDistinguishesOnAddress(device) && (address.length() == 0)) { +        address = String8("0"); +    } + +    for (size_t i = 0; i < mHwModules.size(); i++) { +        if (mHwModules[i]->mHandle == 0) { +            continue; +        } +        DeviceVector deviceList = +                mHwModules[i]->mDeclaredDevices.getDevicesFromTypeAddr(device, address); +        if (!deviceList.isEmpty()) { +            return deviceList.itemAt(0); +        } +        deviceList = mHwModules[i]->mDeclaredDevices.getDevicesFromType(device); +        if (!deviceList.isEmpty()) { +            return deviceList.itemAt(0); +        } +    } + +    sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); +    devDesc->mAddress = address; +    return devDesc; +} +  void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs)  {      bool createTxPatch = false; @@ -449,7 +492,7 @@ void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs      audio_patch_handle_t afPatchHandle;      DeviceVector deviceList; -    audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION); +    audio_devices_t txDevice = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);      ALOGV("updateCallRouting device rxDevice %08x txDevice %08x", rxDevice, txDevice);      // release existing RX patch if any @@ -576,8 +619,14 @@ void AudioPolicyManager::setPhoneState(audio_mode_t state)      if (isInCall()) {          ALOGV("setPhoneState() in call state management: new state is %d", state);          for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { +            if (stream == AUDIO_STREAM_PATCH) { +                continue; +            }              handleIncallSonification((audio_stream_type_t)stream, false, true);          } + +        // force reevaluating accessibility routing when call starts +        mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);      }      // store previous phone state for management of sonification strategy below @@ -673,6 +722,9 @@ void AudioPolicyManager::setPhoneState(audio_mode_t state)      if (isStateInCall(state)) {          ALOGV("setPhoneState() in call state management: new state is %d", state);          for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { +            if (stream == AUDIO_STREAM_PATCH) { +                continue; +            }              handleIncallSonification((audio_stream_type_t)stream, true, true);          }      } @@ -803,7 +855,7 @@ sp<AudioPolicyManager::IOProfile> AudioPolicyManager::getProfileForDirectOutput(          }          for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {              sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j]; -            bool found = profile->isCompatibleProfile(device, samplingRate, +            bool found = profile->isCompatibleProfile(device, String8(""), samplingRate,                      NULL /*updatedSamplingRate*/, format, channelMask,                      flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD ?                          AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD : AUDIO_OUTPUT_FLAG_DIRECT); @@ -822,48 +874,113 @@ audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream,                                      audio_output_flags_t flags,                                      const audio_offload_info_t *offloadInfo)  { -      routing_strategy strategy = getStrategy(stream);      audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);      ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x",            device, stream, samplingRate, format, channelMask, flags); -    return getOutputForDevice(device, stream, samplingRate,format, channelMask, flags, -            offloadInfo); -} +    return getOutputForDevice(device, AUDIO_SESSION_ALLOCATE, +                              stream, samplingRate,format, channelMask, +                              flags, offloadInfo); +} + +status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr, +                                              audio_io_handle_t *output, +                                              audio_session_t session, +                                              audio_stream_type_t *stream, +                                              uint32_t samplingRate, +                                              audio_format_t format, +                                              audio_channel_mask_t channelMask, +                                              audio_output_flags_t flags, +                                              const audio_offload_info_t *offloadInfo) +{ +    audio_attributes_t attributes; +    if (attr != NULL) { +        if (!isValidAttributes(attr)) { +            ALOGE("getOutputForAttr() invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]", +                  attr->usage, attr->content_type, attr->flags, +                  attr->tags); +            return BAD_VALUE; +        } +        attributes = *attr; +    } else { +        if (*stream < AUDIO_STREAM_MIN || *stream >= AUDIO_STREAM_PUBLIC_CNT) { +            ALOGE("getOutputForAttr():  invalid stream type"); +            return BAD_VALUE; +        } +        stream_type_to_audio_attributes(*stream, &attributes); +    } -audio_io_handle_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr, -                                    uint32_t samplingRate, -                                    audio_format_t format, -                                    audio_channel_mask_t channelMask, -                                    audio_output_flags_t flags, -                                    const audio_offload_info_t *offloadInfo) -{ -    if (attr == NULL) { -        ALOGE("getOutputForAttr() called with NULL audio attributes"); -        return 0; +    for (size_t i = 0; i < mPolicyMixes.size(); i++) { +        sp<AudioOutputDescriptor> desc; +        if (mPolicyMixes[i]->mMix.mMixType == MIX_TYPE_PLAYERS) { +            for (size_t j = 0; j < mPolicyMixes[i]->mMix.mCriteria.size(); j++) { +                if ((RULE_MATCH_ATTRIBUTE_USAGE == mPolicyMixes[i]->mMix.mCriteria[j].mRule && +                        mPolicyMixes[i]->mMix.mCriteria[j].mAttr.mUsage == attributes.usage) || +                    (RULE_EXCLUDE_ATTRIBUTE_USAGE == mPolicyMixes[i]->mMix.mCriteria[j].mRule && +                        mPolicyMixes[i]->mMix.mCriteria[j].mAttr.mUsage != attributes.usage)) { +                    desc = mPolicyMixes[i]->mOutput; +                    break; +                } +                if (strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 && +                        strncmp(attributes.tags + strlen("addr="), +                                mPolicyMixes[i]->mMix.mRegistrationId.string(), +                                AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) { +                    desc = mPolicyMixes[i]->mOutput; +                    break; +                } +            } +        } else if (mPolicyMixes[i]->mMix.mMixType == MIX_TYPE_RECORDERS) { +            if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE && +                    strncmp(attributes.tags, "addr=", strlen("addr=")) == 0 && +                    strncmp(attributes.tags + strlen("addr="), +                            mPolicyMixes[i]->mMix.mRegistrationId.string(), +                            AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) { +                desc = mPolicyMixes[i]->mOutput; +            } +        } +        if (desc != 0) { +            if (!audio_is_linear_pcm(format)) { +                return BAD_VALUE; +            } +            desc->mPolicyMix = &mPolicyMixes[i]->mMix; +            *stream = streamTypefromAttributesInt(&attributes); +            *output = desc->mIoHandle; +            ALOGV("getOutputForAttr() returns output %d", *output); +            return NO_ERROR; +        } +    } +    if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE) { +        ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE"); +        return BAD_VALUE;      } +      ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x", -            attr->usage, attr->content_type, attr->tags, attr->flags); +            attributes.usage, attributes.content_type, attributes.tags, attributes.flags); -    // TODO this is where filtering for custom policies (rerouting, dynamic sources) will go -    routing_strategy strategy = (routing_strategy) getStrategyForAttr(attr); +    routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes);      audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); -    if ((attr->flags & AUDIO_FLAG_HW_AV_SYNC) != 0) { +    if ((attributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {          flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);      } -    ALOGV("getOutputForAttr() device %d, samplingRate %d, format %x, channelMask %x, flags %x", +    ALOGV("getOutputForAttr() device 0x%x, samplingRate %d, format %x, channelMask %x, flags %x",            device, samplingRate, format, channelMask, flags); -    audio_stream_type_t stream = streamTypefromAttributesInt(attr); -    return getOutputForDevice(device, stream, samplingRate, format, channelMask, flags, -                offloadInfo); +    *stream = streamTypefromAttributesInt(&attributes); +    *output = getOutputForDevice(device, session, *stream, +                                 samplingRate, format, channelMask, +                                 flags, offloadInfo); +    if (*output == AUDIO_IO_HANDLE_NONE) { +        return INVALID_OPERATION; +    } +    return NO_ERROR;  }  audio_io_handle_t AudioPolicyManager::getOutputForDevice(          audio_devices_t device, +        audio_session_t session __unused,          audio_stream_type_t stream,          uint32_t samplingRate,          audio_format_t format, @@ -926,6 +1043,10 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(      if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {          flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);      } +    // only allow deep buffering for music stream type +    if (stream != AUDIO_STREAM_MUSIC) { +        flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER); +    }      sp<IOProfile> profile; @@ -1005,6 +1126,10 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(              if (output != AUDIO_IO_HANDLE_NONE) {                  mpClientInterface->closeOutput(output);              } +            // fall back to mixer output if possible when the direct output could not be open +            if (audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE) { +                goto non_direct_output; +            }              return AUDIO_IO_HANDLE_NONE;          }          outputDesc->mSamplingRate = config.sample_rate; @@ -1110,7 +1235,7 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_h  status_t AudioPolicyManager::startOutput(audio_io_handle_t output,                                               audio_stream_type_t stream, -                                             int session) +                                             audio_session_t session)  {      ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session);      ssize_t index = mOutputs.indexOfKey(output); @@ -1119,6 +1244,20 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,          return BAD_VALUE;      } +    // cannot start playback of STREAM_TTS if any other output is being used +    uint32_t beaconMuteLatency = 0; +    if (stream == AUDIO_STREAM_TTS) { +        ALOGV("\t found BEACON stream"); +        if (isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) { +            return INVALID_OPERATION; +        } else { +            beaconMuteLatency = handleEventForBeacon(STARTING_BEACON); +        } +    } else { +        // some playback other than beacon starts +        beaconMuteLatency = handleEventForBeacon(STARTING_OUTPUT); +    } +      sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);      // increment usage count for this stream on the requested output: @@ -1127,11 +1266,18 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,      outputDesc->changeRefCount(stream, 1);      if (outputDesc->mRefCount[stream] == 1) { -        audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/); +        // starting an output being rerouted? +        audio_devices_t newDevice; +        if (outputDesc->mPolicyMix != NULL) { +            newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX; +        } else { +            newDevice = getNewOutputDevice(output, false /*fromCache*/); +        }          routing_strategy strategy = getStrategy(stream);          bool shouldWait = (strategy == STRATEGY_SONIFICATION) || -                            (strategy == STRATEGY_SONIFICATION_RESPECTFUL); -        uint32_t waitMs = 0; +                            (strategy == STRATEGY_SONIFICATION_RESPECTFUL) || +                            (beaconMuteLatency > 0); +        uint32_t waitMs = beaconMuteLatency;          bool force = false;          for (size_t i = 0; i < mOutputs.size(); i++) {              sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); @@ -1145,7 +1291,8 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,                      force = true;                  }                  // wait for audio on other active outputs to be presented when starting -                // a notification so that audio focus effect can propagate. +                // a notification so that audio focus effect can propagate, or that a mute/unmute +                // event occurred for beacon                  uint32_t latency = desc->latency();                  if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) {                      waitMs = latency; @@ -1168,6 +1315,21 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,          // update the outputs if starting an output with a stream that can affect notification          // routing          handleNotificationRoutingForStream(stream); + +        // Automatically enable the remote submix input when output is started on a re routing mix +        // of type MIX_TYPE_RECORDERS +        if (audio_is_remote_submix_device(newDevice) && outputDesc->mPolicyMix != NULL && +                outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) { +                setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX, +                        AUDIO_POLICY_DEVICE_STATE_AVAILABLE, +                        outputDesc->mPolicyMix->mRegistrationId); +        } + +        // force reevaluating accessibility routing when ringtone or alarm starts +        if (strategy == STRATEGY_SONIFICATION) { +            mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY); +        } +          if (waitMs > muteWaitMs) {              usleep((waitMs - muteWaitMs) * 2 * 1000);          } @@ -1178,7 +1340,7 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,  status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,                                              audio_stream_type_t stream, -                                            int session) +                                            audio_session_t session)  {      ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);      ssize_t index = mOutputs.indexOfKey(output); @@ -1189,6 +1351,9 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,      sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); +    // always handle stream stop, check which stream type is stopping +    handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT); +      // handle special case for sonification while in call      if (isInCall()) {          handleIncallSonification(stream, false, false); @@ -1199,6 +1364,16 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,          outputDesc->changeRefCount(stream, -1);          // store time at which the stream was stopped - see isStreamActive()          if (outputDesc->mRefCount[stream] == 0) { +            // Automatically disable the remote submix input when output is stopped on a +            // re routing mix of type MIX_TYPE_RECORDERS +            if (audio_is_remote_submix_device(outputDesc->mDevice) && +                    outputDesc->mPolicyMix != NULL && +                    outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) { +                setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX, +                        AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, +                        outputDesc->mPolicyMix->mRegistrationId); +            } +              outputDesc->mStopTime[stream] = systemTime();              audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/);              // delay the device switch by twice the latency because stopOutput() is executed when @@ -1233,7 +1408,9 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,      }  } -void AudioPolicyManager::releaseOutput(audio_io_handle_t output) +void AudioPolicyManager::releaseOutput(audio_io_handle_t output, +                                       audio_stream_type_t stream __unused, +                                       audio_session_t session __unused)  {      ALOGV("releaseOutput() %d", output);      ssize_t index = mOutputs.indexOfKey(output); @@ -1276,79 +1453,121 @@ void AudioPolicyManager::releaseOutput(audio_io_handle_t output)  } -audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource, -                                    uint32_t samplingRate, -                                    audio_format_t format, -                                    audio_channel_mask_t channelMask, -                                    audio_session_t session, -                                    audio_input_flags_t flags) +status_t AudioPolicyManager::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, +                                             input_type_t *inputType)  { -    ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, session %d, " -          "flags %#x", -          inputSource, samplingRate, format, channelMask, session, flags); +    ALOGV("getInputForAttr() source %d, samplingRate %d, format %d, channelMask %x," +            "session %d, flags %#x", +          attr->source, samplingRate, format, channelMask, session, flags); -    audio_devices_t device = getDeviceForInputSource(inputSource); - -    if (device == AUDIO_DEVICE_NONE) { -        ALOGW("getInput() could not find device for inputSource %d", inputSource); -        return AUDIO_IO_HANDLE_NONE; -    } +    *input = AUDIO_IO_HANDLE_NONE; +    *inputType = API_INPUT_INVALID; +    audio_devices_t device; +    // handle legacy remote submix case where the address was not always specified +    String8 address = String8(""); +    bool isSoundTrigger = false; +    audio_source_t inputSource = attr->source; +    audio_source_t halInputSource; +    AudioMix *policyMix = NULL; -    // adapt channel selection to input source -    switch (inputSource) { -    case AUDIO_SOURCE_VOICE_UPLINK: -        channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK; -        break; -    case AUDIO_SOURCE_VOICE_DOWNLINK: -        channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK; -        break; -    case AUDIO_SOURCE_VOICE_CALL: -        channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK; -        break; -    default: -        break; +    if (inputSource == AUDIO_SOURCE_DEFAULT) { +        inputSource = AUDIO_SOURCE_MIC;      } +    halInputSource = inputSource; -    audio_io_handle_t input = AUDIO_IO_HANDLE_NONE; -    bool isSoundTrigger = false; -    audio_source_t halInputSource = inputSource; -    if (inputSource == AUDIO_SOURCE_HOTWORD) { -        ssize_t index = mSoundTriggerSessions.indexOfKey(session); -        if (index >= 0) { -            input = mSoundTriggerSessions.valueFor(session); -            isSoundTrigger = true; -            flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_HW_HOTWORD); -            ALOGV("SoundTrigger capture on session %d input %d", session, input); +    if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX && +            strncmp(attr->tags, "addr=", strlen("addr=")) == 0) { +        device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; +        address = String8(attr->tags + strlen("addr=")); +        ssize_t index = mPolicyMixes.indexOfKey(address); +        if (index < 0) { +            ALOGW("getInputForAttr() no policy for address %s", address.string()); +            return BAD_VALUE; +        } +        if (mPolicyMixes[index]->mMix.mMixType != MIX_TYPE_PLAYERS) { +            ALOGW("getInputForAttr() bad policy mix type for address %s", address.string()); +            return BAD_VALUE; +        } +        policyMix = &mPolicyMixes[index]->mMix; +        *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE; +    } else { +        device = getDeviceAndMixForInputSource(inputSource, &policyMix); +        if (device == AUDIO_DEVICE_NONE) { +            ALOGW("getInputForAttr() could not find device for source %d", inputSource); +            return BAD_VALUE; +        } +        if (policyMix != NULL) { +            address = policyMix->mRegistrationId; +            if (policyMix->mMixType == MIX_TYPE_RECORDERS) { +                // there is an external policy, but this input is attached to a mix of recorders, +                // meaning it receives audio injected into the framework, so the recorder doesn't +                // know about it and is therefore considered "legacy" +                *inputType = API_INPUT_LEGACY; +            } else { +                // recording a mix of players defined by an external policy, we're rerouting for +                // an external policy +                *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE; +            } +        } else if (audio_is_remote_submix_device(device)) { +            address = String8("0"); +            *inputType = API_INPUT_MIX_CAPTURE;          } else { -            halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION; +            *inputType = API_INPUT_LEGACY; +        } +        // adapt channel selection to input source +        switch (inputSource) { +        case AUDIO_SOURCE_VOICE_UPLINK: +            channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK; +            break; +        case AUDIO_SOURCE_VOICE_DOWNLINK: +            channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK; +            break; +        case AUDIO_SOURCE_VOICE_CALL: +            channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK; +            break; +        default: +            break; +        } +        if (inputSource == AUDIO_SOURCE_HOTWORD) { +            ssize_t index = mSoundTriggerSessions.indexOfKey(session); +            if (index >= 0) { +                *input = mSoundTriggerSessions.valueFor(session); +                isSoundTrigger = true; +                flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_HW_HOTWORD); +                ALOGV("SoundTrigger capture on session %d input %d", session, *input); +            } else { +                halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION; +            }          }      } -    sp<IOProfile> profile = getInputProfile(device, -                                         samplingRate, -                                         format, -                                         channelMask, -                                         flags); +    sp<IOProfile> profile = getInputProfile(device, address, +                                            samplingRate, format, channelMask, +                                            flags);      if (profile == 0) {          //retry without flags          audio_input_flags_t log_flags = flags;          flags = AUDIO_INPUT_FLAG_NONE; -        profile = getInputProfile(device, -                                 samplingRate, -                                 format, -                                 channelMask, -                                 flags); +        profile = getInputProfile(device, address, +                                  samplingRate, format, channelMask, +                                  flags);          if (profile == 0) { -            ALOGW("getInput() could not find profile for device 0x%X, samplingRate %u, format %#x, " -                    "channelMask 0x%X, flags %#x", +            ALOGW("getInputForAttr() could not find profile for device 0x%X, samplingRate %u," +                    "format %#x, channelMask 0x%X, flags %#x",                      device, samplingRate, format, channelMask, log_flags); -            return AUDIO_IO_HANDLE_NONE; +            return BAD_VALUE;          }      }      if (profile->mModule->mHandle == 0) { -        ALOGE("getInput(): HW module %s not opened", profile->mModule->mName); -        return AUDIO_IO_HANDLE_NONE; +        ALOGE("getInputForAttr(): HW module %s not opened", profile->mModule->mName); +        return NO_INIT;      }      audio_config_t config = AUDIO_CONFIG_INITIALIZER; @@ -1357,24 +1576,24 @@ audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource,      config.format = format;      status_t status = mpClientInterface->openInput(profile->mModule->mHandle, -                                                   &input, +                                                   input,                                                     &config,                                                     &device, -                                                   String8(""), +                                                   address,                                                     halInputSource,                                                     flags);      // only accept input with the exact requested set of parameters -    if (status != NO_ERROR || +    if (status != NO_ERROR || *input == AUDIO_IO_HANDLE_NONE ||          (samplingRate != config.sample_rate) ||          (format != config.format) ||          (channelMask != config.channel_mask)) { -        ALOGW("getInput() failed opening input: samplingRate %d, format %d, channelMask %x", +        ALOGW("getInputForAttr() failed opening input: samplingRate %d, format %d, channelMask %x",                  samplingRate, format, channelMask); -        if (input != AUDIO_IO_HANDLE_NONE) { -            mpClientInterface->closeInput(input); +        if (*input != AUDIO_IO_HANDLE_NONE) { +            mpClientInterface->closeInput(*input);          } -        return AUDIO_IO_HANDLE_NONE; +        return BAD_VALUE;      }      sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile); @@ -1387,10 +1606,13 @@ audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource,      inputDesc->mDevice = device;      inputDesc->mSessions.add(session);      inputDesc->mIsSoundTrigger = isSoundTrigger; +    inputDesc->mPolicyMix = policyMix; + +    ALOGV("getInputForAttr() returns input type = %d", inputType); -    addInput(input, inputDesc); +    addInput(*input, inputDesc);      mpClientInterface->onAudioPortListUpdate(); -    return input; +    return NO_ERROR;  }  status_t AudioPolicyManager::startInput(audio_io_handle_t input, @@ -1437,11 +1659,21 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input,          }          setInputDevice(input, getNewInputDevice(input), true /* force */); -        // Automatically enable the remote submix output when input is started. +        // automatically enable the remote submix output when input is started if not +        // used by a policy mix of type MIX_TYPE_RECORDERS          // For remote submix (a virtual device), we open only one input per capture request.          if (audio_is_remote_submix_device(inputDesc->mDevice)) { -            setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, -                    AUDIO_POLICY_DEVICE_STATE_AVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); +            String8 address = String8(""); +            if (inputDesc->mPolicyMix == NULL) { +                address = String8("0"); +            } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) { +                address = inputDesc->mPolicyMix->mRegistrationId; +            } +            if (address != "") { +                setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, +                        AUDIO_POLICY_DEVICE_STATE_AVAILABLE, +                        address); +            }          }      } @@ -1476,10 +1708,20 @@ status_t AudioPolicyManager::stopInput(audio_io_handle_t input,      inputDesc->mRefCount--;      if (inputDesc->mRefCount == 0) { -        // automatically disable the remote submix output when input is stopped +        // automatically disable the remote submix output when input is stopped if not +        // used by a policy mix of type MIX_TYPE_RECORDERS          if (audio_is_remote_submix_device(inputDesc->mDevice)) { -            setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, -                    AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); +            String8 address = String8(""); +            if (inputDesc->mPolicyMix == NULL) { +                address = String8("0"); +            } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) { +                address = inputDesc->mPolicyMix->mRegistrationId; +            } +            if (address != "") { +                setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, +                                         AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, +                                         address); +            }          }          resetInputDevice(input); @@ -1557,6 +1799,11 @@ void AudioPolicyManager::initStreamVolume(audio_stream_type_t stream,      }      mStreams[stream].mIndexMin = indexMin;      mStreams[stream].mIndexMax = indexMax; +    //FIXME: AUDIO_STREAM_ACCESSIBILITY volume follows AUDIO_STREAM_MUSIC for now +    if (stream == AUDIO_STREAM_MUSIC) { +        mStreams[AUDIO_STREAM_ACCESSIBILITY].mIndexMin = indexMin; +        mStreams[AUDIO_STREAM_ACCESSIBILITY].mIndexMax = indexMax; +    }  }  status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream, @@ -1584,17 +1831,35 @@ status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,      }      mStreams[stream].mIndexCur.add(device, index); -    // compute and apply stream volume on all outputs according to connected device +    // update volume on all outputs whose current device is also selected by the same +    // strategy as the device specified by the caller +    audio_devices_t strategyDevice = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/); + + +    //FIXME: AUDIO_STREAM_ACCESSIBILITY volume follows AUDIO_STREAM_MUSIC for now +    audio_devices_t accessibilityDevice = AUDIO_DEVICE_NONE; +    if (stream == AUDIO_STREAM_MUSIC) { +        mStreams[AUDIO_STREAM_ACCESSIBILITY].mIndexCur.add(device, index); +        accessibilityDevice = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, true /*fromCache*/); +    } +    if ((device != AUDIO_DEVICE_OUT_DEFAULT) && +            (device & (strategyDevice | accessibilityDevice)) == 0) { +        return NO_ERROR; +    }      status_t status = NO_ERROR;      for (size_t i = 0; i < mOutputs.size(); i++) {          audio_devices_t curDevice =                  getDeviceForVolume(mOutputs.valueAt(i)->device()); -        if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) { +        if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & strategyDevice) != 0)) {              status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);              if (volStatus != NO_ERROR) {                  status = volStatus;              }          } +        if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & accessibilityDevice) != 0)) { +            status_t volStatus = checkAndSetVolume(AUDIO_STREAM_ACCESSIBILITY, +                                                   index, mOutputs.keyAt(i), curDevice); +        }      }      return status;  } @@ -1814,7 +2079,11 @@ bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream,          const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);          if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&                  outputDesc->isStreamActive(stream, inPastMs, sysTime)) { -            return true; +            // do not consider re routing (when the output is going to a dynamic policy) +            // as "remote playback" +            if (outputDesc->mPolicyMix == NULL) { +                return true; +            }          }      }      return false; @@ -1824,16 +2093,148 @@ bool AudioPolicyManager::isSourceActive(audio_source_t source) const  {      for (size_t i = 0; i < mInputs.size(); i++) {          const sp<AudioInputDescriptor>  inputDescriptor = mInputs.valueAt(i); -        if ((inputDescriptor->mInputSource == (int)source || -                (source == AUDIO_SOURCE_VOICE_RECOGNITION && -                 inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD)) -             && (inputDescriptor->mRefCount > 0)) { +        if (inputDescriptor->mRefCount == 0) { +            continue; +        } +        if (inputDescriptor->mInputSource == (int)source) {              return true;          } +        // AUDIO_SOURCE_HOTWORD is equivalent to AUDIO_SOURCE_VOICE_RECOGNITION only if it +        // corresponds to an active capture triggered by a hardware hotword recognition +        if ((source == AUDIO_SOURCE_VOICE_RECOGNITION) && +                 (inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD)) { +            // FIXME: we should not assume that the first session is the active one and keep +            // activity count per session. Same in startInput(). +            ssize_t index = mSoundTriggerSessions.indexOfKey(inputDescriptor->mSessions.itemAt(0)); +            if (index >= 0) { +                return true; +            } +        }      }      return false;  } +// Register a list of custom mixes with their attributes and format. +// When a mix is registered, corresponding input and output profiles are +// added to the remote submix hw module. The profile contains only the +// parameters (sampling rate, format...) specified by the mix. +// The corresponding input remote submix device is also connected. +// +// When a remote submix device is connected, the address is checked to select the +// appropriate profile and the corresponding input or output stream is opened. +// +// When capture starts, getInputForAttr() will: +//  - 1 look for a mix matching the address passed in attribtutes tags if any +//  - 2 if none found, getDeviceForInputSource() will: +//     - 2.1 look for a mix matching the attributes source +//     - 2.2 if none found, default to device selection by policy rules +// At this time, the corresponding output remote submix device is also connected +// and active playback use cases can be transferred to this mix if needed when reconnecting +// after AudioTracks are invalidated +// +// When playback starts, getOutputForAttr() will: +//  - 1 look for a mix matching the address passed in attribtutes tags if any +//  - 2 if none found, look for a mix matching the attributes usage +//  - 3 if none found, default to device and output selection by policy rules. + +status_t AudioPolicyManager::registerPolicyMixes(Vector<AudioMix> mixes) +{ +    sp<HwModule> module; +    for (size_t i = 0; i < mHwModules.size(); i++) { +        if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[i]->mName) == 0 && +                mHwModules[i]->mHandle != 0) { +            module = mHwModules[i]; +            break; +        } +    } + +    if (module == 0) { +        return INVALID_OPERATION; +    } + +    ALOGV("registerPolicyMixes() num mixes %d", mixes.size()); + +    for (size_t i = 0; i < mixes.size(); i++) { +        String8 address = mixes[i].mRegistrationId; +        ssize_t index = mPolicyMixes.indexOfKey(address); +        if (index >= 0) { +            ALOGE("registerPolicyMixes(): mix for address %s already registered", address.string()); +            continue; +        } +        audio_config_t outputConfig = mixes[i].mFormat; +        audio_config_t inputConfig = mixes[i].mFormat; +        // NOTE: audio flinger mixer does not support mono output: configure remote submix HAL in +        // stereo and let audio flinger do the channel conversion if needed. +        outputConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO; +        inputConfig.channel_mask = AUDIO_CHANNEL_IN_STEREO; +        module->addOutputProfile(address, &outputConfig, +                                 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address); +        module->addInputProfile(address, &inputConfig, +                                 AUDIO_DEVICE_IN_REMOTE_SUBMIX, address); +        sp<AudioPolicyMix> policyMix = new AudioPolicyMix(); +        policyMix->mMix = mixes[i]; +        mPolicyMixes.add(address, policyMix); +        if (mixes[i].mMixType == MIX_TYPE_PLAYERS) { +            setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX, +                                     AUDIO_POLICY_DEVICE_STATE_AVAILABLE, +                                     address.string()); +        } else { +            setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, +                                     AUDIO_POLICY_DEVICE_STATE_AVAILABLE, +                                     address.string()); +        } +    } +    return NO_ERROR; +} + +status_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes) +{ +    sp<HwModule> module; +    for (size_t i = 0; i < mHwModules.size(); i++) { +        if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[i]->mName) == 0 && +                mHwModules[i]->mHandle != 0) { +            module = mHwModules[i]; +            break; +        } +    } + +    if (module == 0) { +        return INVALID_OPERATION; +    } + +    ALOGV("unregisterPolicyMixes() num mixes %d", mixes.size()); + +    for (size_t i = 0; i < mixes.size(); i++) { +        String8 address = mixes[i].mRegistrationId; +        ssize_t index = mPolicyMixes.indexOfKey(address); +        if (index < 0) { +            ALOGE("unregisterPolicyMixes(): mix for address %s not registered", address.string()); +            continue; +        } + +        mPolicyMixes.removeItemsAt(index); + +        if (getDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, address.string()) == +                                             AUDIO_POLICY_DEVICE_STATE_AVAILABLE) +        { +            setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX, +                                     AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, +                                     address.string()); +        } + +        if (getDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address.string()) == +                                             AUDIO_POLICY_DEVICE_STATE_AVAILABLE) +        { +            setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, +                                     AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, +                                     address.string()); +        } +        module->removeOutputProfile(address); +        module->removeInputProfile(address); +    } +    return NO_ERROR; +} +  status_t AudioPolicyManager::dump(int fd)  { @@ -2234,6 +2635,7 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch,              }              if (!outputDesc->mProfile->isCompatibleProfile(devDesc->mDeviceType, +                                                           devDesc->mAddress,                                                             patch->sources[0].sample_rate,                                                           NULL,  // updatedSamplingRate                                                           patch->sources[0].format, @@ -2288,13 +2690,14 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch,              }              if (!inputDesc->mProfile->isCompatibleProfile(devDesc->mDeviceType, -                                                         patch->sinks[0].sample_rate, -                                                         NULL, /*updatedSampleRate*/ -                                                         patch->sinks[0].format, -                                                         patch->sinks[0].channel_mask, -                                                         // FIXME for the parameter type, -                                                         // and the NONE -                                                         (audio_output_flags_t) +                                                          devDesc->mAddress, +                                                          patch->sinks[0].sample_rate, +                                                          NULL, /*updatedSampleRate*/ +                                                          patch->sinks[0].format, +                                                          patch->sinks[0].channel_mask, +                                                          // FIXME for the parameter type, +                                                          // and the NONE +                                                          (audio_output_flags_t)                                                              AUDIO_INPUT_FLAG_NONE)) {                  return INVALID_OPERATION;              } @@ -2561,13 +2964,10 @@ status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *  void AudioPolicyManager::clearAudioPatches(uid_t uid)  { -    for (ssize_t i = 0; i < (ssize_t)mAudioPatches.size(); i++)  { +    for (ssize_t i = (ssize_t)mAudioPatches.size() - 1; i >= 0; i--)  {          sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i);          if (patchDesc->mUid == uid) { -            // releaseAudioPatch() removes the patch from mAudioPatches -            if (releaseAudioPatch(mAudioPatches.keyAt(i), uid) == NO_ERROR) { -                i--; -            } +            releaseAudioPatch(mAudioPatches.keyAt(i), uid);          }      }  } @@ -2578,7 +2978,7 @@ status_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session  {      *session = (audio_session_t)mpClientInterface->newAudioUniqueId();      *ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId(); -    *device = getDeviceForInputSource(AUDIO_SOURCE_HOTWORD); +    *device = getDeviceAndMixForInputSource(AUDIO_SOURCE_HOTWORD);      mSoundTriggerSessions.add(*session, *ioHandle); @@ -2653,7 +3053,10 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa      mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0),      mA2dpSuspended(false),      mSpeakerDrcEnabled(false), mNextUniqueId(1), -    mAudioPortGeneration(1) +    mAudioPortGeneration(1), +    mBeaconMuteRefCount(0), +    mBeaconPlayingRefCount(0), +    mBeaconMuted(false)  {      mUidCached = getuid();      mpClientInterface = clientInterface; @@ -2787,6 +3190,14 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa              inputDesc->mInputSource = AUDIO_SOURCE_MIC;              inputDesc->mDevice = profileType; +            // find the address +            DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType); +            //   the inputs vector must be of size 1, but we don't want to crash here +            String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress +                    : String8(""); +            ALOGV("  for input device 0x%x using address %s", profileType, address.string()); +            ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!"); +              audio_config_t config = AUDIO_CONFIG_INITIALIZER;              config.sample_rate = inputDesc->mSamplingRate;              config.channel_mask = inputDesc->mChannelMask; @@ -2796,7 +3207,7 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa                                                             &input,                                                             &config,                                                             &inputDesc->mDevice, -                                                           String8(""), +                                                           address,                                                             AUDIO_SOURCE_MIC,                                                             AUDIO_INPUT_FLAG_NONE); @@ -3069,29 +3480,15 @@ void AudioPolicyManager::addInput(audio_io_handle_t input, sp<AudioInputDescript  }  void AudioPolicyManager::findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/, +        const audio_devices_t device /*in*/,          const String8 address /*in*/,          SortedVector<audio_io_handle_t>& outputs /*out*/) { -    // look for a match on the given address on the addresses of the outputs: -    // find the address by finding the patch that maps to this output -    ssize_t patchIdx = mAudioPatches.indexOfKey(desc->mPatchHandle); -    //ALOGV("    inspecting output %d (patch %d) for supported device=0x%x", -    //        outputIdx, patchIdx,  desc->mProfile->mSupportedDevices.types()); -    if (patchIdx >= 0) { -        const sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patchIdx); -        const int numSinks = patchDesc->mPatch.num_sinks; -        for (ssize_t j=0; j < numSinks; j++) { -            if (patchDesc->mPatch.sinks[j].type == AUDIO_PORT_TYPE_DEVICE) { -                const char* patchAddr = -                        patchDesc->mPatch.sinks[j].ext.device.address; -                if (strncmp(patchAddr, -                        address.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) { -                    ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s", -                            desc->mIoHandle,  patchDesc->mPatch.sinks[j].ext.device.address); -                    outputs.add(desc->mIoHandle); -                    break; -                } -            } -        } +    sp<DeviceDescriptor> devDesc = +        desc->mProfile->mSupportedDevices.getDevice(device, address); +    if (devDesc != 0) { +        ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s", +              desc->mIoHandle, address.string()); +        outputs.add(desc->mIoHandle);      }  } @@ -3115,7 +3512,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> de                      outputs.add(mOutputs.keyAt(i));                  } else {                      ALOGV("  checking address match due to device 0x%x", device); -                    findIoHandlesByAddress(desc, address, outputs); +                    findIoHandlesByAddress(desc, device, address, outputs);                  }              }          } @@ -3128,9 +3525,13 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> de              }              for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)              { -                if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) { -                    ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i); -                    profiles.add(mHwModules[i]->mOutputProfiles[j]); +                sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j]; +                if (profile->mSupportedDevices.types() & device) { +                    if (!deviceDistinguishesOnAddress(device) || +                            address == profile->mSupportedDevices[0]->mAddress) { +                        profiles.add(profile); +                        ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i); +                    }                  }              }          } @@ -3262,7 +3663,18 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> de                  if (output != AUDIO_IO_HANDLE_NONE) {                      addOutput(output, desc); -                    if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) { +                    if (deviceDistinguishesOnAddress(device) && address != "0") { +                        ssize_t index = mPolicyMixes.indexOfKey(address); +                        if (index >= 0) { +                            mPolicyMixes[index]->mOutput = desc; +                            desc->mPolicyMix = &mPolicyMixes[index]->mMix; +                        } else { +                            ALOGE("checkOutputsForDevice() cannot find policy for address %s", +                                  address.string()); +                        } +                    } else if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) { +                        // no duplicated output for direct outputs and +                        // outputs used by dynamic policy mixes                          audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;                          // set initial stream volume for device @@ -3325,15 +3737,15 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> de          for (size_t i = 0; i < mOutputs.size(); i++) {              desc = mOutputs.valueAt(i);              if (!desc->isDuplicated()) { -                if  (!(desc->mProfile->mSupportedDevices.types() +                // exact match on device +                if (deviceDistinguishesOnAddress(device) && +                        (desc->mProfile->mSupportedDevices.types() == device)) { +                    findIoHandlesByAddress(desc, device, address, outputs); +                } else if (!(desc->mProfile->mSupportedDevices.types()                          & mAvailableOutputDevices.types())) {                      ALOGV("checkOutputsForDevice(): disconnecting adding output %d",                              mOutputs.keyAt(i));                      outputs.add(mOutputs.keyAt(i)); -                } else if (deviceDistinguishesOnAddress(device) && -                        // exact match on device -                        (desc->mProfile->mSupportedDevices.types() == device)) { -                    findIoHandlesByAddress(desc, address, outputs);                  }              }          } @@ -3395,11 +3807,15 @@ status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device,                   profile_index < mHwModules[module_idx]->mInputProfiles.size();                   profile_index++)              { -                if (mHwModules[module_idx]->mInputProfiles[profile_index]->mSupportedDevices.types() -                        & (device & ~AUDIO_DEVICE_BIT_IN)) { -                    ALOGV("checkInputsForDevice(): adding profile %zu from module %zu", -                          profile_index, module_idx); -                    profiles.add(mHwModules[module_idx]->mInputProfiles[profile_index]); +                sp<IOProfile> profile = mHwModules[module_idx]->mInputProfiles[profile_index]; + +                if (profile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) { +                    if (!deviceDistinguishesOnAddress(device) || +                            address == profile->mSupportedDevices[0]->mAddress) { +                        profiles.add(profile); +                        ALOGV("checkInputsForDevice(): adding profile %zu from module %zu", +                              profile_index, module_idx); +                    }                  }              }          } @@ -3517,7 +3933,8 @@ status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device,          // check if one opened input is not needed any more after disconnecting one device          for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {              desc = mInputs.valueAt(input_index); -            if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types())) { +            if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types() & +                    ~AUDIO_DEVICE_BIT_IN)) {                  ALOGV("checkInputsForDevice(): disconnecting adding input %d",                        mInputs.keyAt(input_index));                  inputs.add(mInputs.keyAt(input_index)); @@ -3532,7 +3949,7 @@ status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device,                   profile_index < mHwModules[module_index]->mInputProfiles.size();                   profile_index++) {                  sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index]; -                if (profile->mSupportedDevices.types() & device) { +                if (profile->mSupportedDevices.types() & device & ~AUDIO_DEVICE_BIT_IN) {                      ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %zu",                            profile_index, module_index);                      if (profile->mSamplingRates[0] == 0) { @@ -3566,6 +3983,12 @@ void AudioPolicyManager::closeOutput(audio_io_handle_t output)          return;      } +    for (size_t i = 0; i < mPolicyMixes.size(); i++) { +        if (mPolicyMixes[i]->mOutput == outputDesc) { +            mPolicyMixes[i]->mOutput.clear(); +        } +    } +      // look for duplicated outputs connected to the output being removed.      for (size_t i = 0; i < mOutputs.size(); i++) {          sp<AudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i); @@ -3675,6 +4098,24 @@ void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)      SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs);      SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs); +    // also take into account external policy-related changes: add all outputs which are +    // associated with policies in the "before" and "after" output vectors +    ALOGVV("checkOutputForStrategy(): policy related outputs"); +    for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) { +        const sp<AudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i); +        if (desc != 0 && desc->mPolicyMix != NULL) { +            srcOutputs.add(desc->mIoHandle); +            ALOGVV(" previous outputs: adding %d", desc->mIoHandle); +        } +    } +    for (size_t i = 0 ; i < mOutputs.size() ; i++) { +        const sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); +        if (desc != 0 && desc->mPolicyMix != NULL) { +            dstOutputs.add(desc->mIoHandle); +            ALOGVV(" new outputs: adding %d", desc->mIoHandle); +        } +    } +      if (!vectorsEqual(srcOutputs,dstOutputs)) {          ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",                strategy, srcOutputs[0], dstOutputs[0]); @@ -3708,6 +4149,9 @@ void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)          }          // Move tracks associated to this strategy from previous output to new output          for (int i = 0; i < AUDIO_STREAM_CNT; i++) { +            if (i == AUDIO_STREAM_PATCH) { +                continue; +            }              if (getStrategy((audio_stream_type_t)i) == strategy) {                  mpClientInterface->invalidateStream((audio_stream_type_t)i);              } @@ -3724,8 +4168,10 @@ void AudioPolicyManager::checkOutputForAllStrategies()          checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);      checkOutputForStrategy(STRATEGY_SONIFICATION);      checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL); +    checkOutputForStrategy(STRATEGY_ACCESSIBILITY);      checkOutputForStrategy(STRATEGY_MEDIA);      checkOutputForStrategy(STRATEGY_DTMF); +    checkOutputForStrategy(STRATEGY_REROUTING);  }  audio_io_handle_t AudioPolicyManager::getA2dpOutput() @@ -3749,7 +4195,9 @@ void AudioPolicyManager::checkA2dpSuspend()      }      bool isScoConnected = -            (mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) != 0; +            ((mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET & +                    ~AUDIO_DEVICE_BIT_IN) != 0) || +            ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_ALL_SCO) != 0);      // suspend A2DP output if:      //      (NOT already suspended) &&      //      ((SCO device is connected && @@ -3812,10 +4260,14 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output,      //      use device for strategy sonification      // 5: the strategy "respectful" sonification is active on the output:      //      use device for strategy "respectful" sonification -    // 6: the strategy media is active on the output: +    // 6: the strategy accessibility is active on the output: +    //      use device for strategy accessibility +    // 7: the strategy media is active on the output:      //      use device for strategy media -    // 7: the strategy DTMF is active on the output: +    // 8: the strategy DTMF is active on the output:      //      use device for strategy DTMF +    // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output: +    //      use device for strategy t-t-s      if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE) &&          mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {          device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); @@ -3828,10 +4280,16 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output,          device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);      } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) {          device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); +    } else if (outputDesc->isStrategyActive(STRATEGY_ACCESSIBILITY)) { +        device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache);      } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) {          device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);      } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) {          device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); +    } else if (outputDesc->isStrategyActive(STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) { +        device = getDeviceForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache); +    } else if (outputDesc->isStrategyActive(STRATEGY_REROUTING)) { +        device = getDeviceForStrategy(STRATEGY_REROUTING, fromCache);      }      ALOGV("getNewOutputDevice() selected device %x", device); @@ -3852,7 +4310,7 @@ audio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input)          }      } -    audio_devices_t device = getDeviceForInputSource(inputDesc->mInputSource); +    audio_devices_t device = getDeviceAndMixForInputSource(inputDesc->mInputSource);      ALOGV("getNewInputDevice() selected device %x", device);      return device; @@ -3866,7 +4324,7 @@ audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stre      // By checking the range of stream before calling getStrategy, we avoid      // getStrategy's behavior for invalid streams.  getStrategy would do a ALOGE      // and then return STRATEGY_MEDIA, but we want to return the empty set. -    if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_CNT) { +    if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) {          return AUDIO_DEVICE_NONE;      }      audio_devices_t devices; @@ -3893,6 +4351,9 @@ audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stre  AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy(          audio_stream_type_t stream) { + +    ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH"); +      // stream to strategy mapping      switch (stream) {      case AUDIO_STREAM_VOICE_CALL: @@ -3906,29 +4367,45 @@ AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy(      case AUDIO_STREAM_DTMF:          return STRATEGY_DTMF;      default: -        ALOGE("unknown stream type"); +        ALOGE("unknown stream type %d", stream);      case AUDIO_STREAM_SYSTEM:          // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs          // while key clicks are played produces a poor result -    case AUDIO_STREAM_TTS:      case AUDIO_STREAM_MUSIC:          return STRATEGY_MEDIA;      case AUDIO_STREAM_ENFORCED_AUDIBLE:          return STRATEGY_ENFORCED_AUDIBLE; +    case AUDIO_STREAM_TTS: +        return STRATEGY_TRANSMITTED_THROUGH_SPEAKER; +    case AUDIO_STREAM_ACCESSIBILITY: +        return STRATEGY_ACCESSIBILITY; +    case AUDIO_STREAM_REROUTING: +        return STRATEGY_REROUTING;      }  }  uint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) {      // flags to strategy mapping +    if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) { +        return (uint32_t) STRATEGY_TRANSMITTED_THROUGH_SPEAKER; +    }      if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {          return (uint32_t) STRATEGY_ENFORCED_AUDIBLE;      }      // usage to strategy mapping      switch (attr->usage) { +    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: +        if (isStreamActive(AUDIO_STREAM_RING) || isStreamActive(AUDIO_STREAM_ALARM)) { +            return (uint32_t) STRATEGY_SONIFICATION; +        } +        if (isInCall()) { +            return (uint32_t) STRATEGY_PHONE; +        } +        return (uint32_t) STRATEGY_ACCESSIBILITY; +      case AUDIO_USAGE_MEDIA:      case AUDIO_USAGE_GAME: -    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:      case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:      case AUDIO_USAGE_ASSISTANCE_SONIFICATION:          return (uint32_t) STRATEGY_MEDIA; @@ -3967,6 +4444,74 @@ void AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t      }  } +bool AudioPolicyManager::isAnyOutputActive(audio_stream_type_t streamToIgnore) { +    for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { +        if (s == (size_t) streamToIgnore) { +            continue; +        } +        for (size_t i = 0; i < mOutputs.size(); i++) { +            const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i); +            if (outputDesc->mRefCount[s] != 0) { +                return true; +            } +        } +    } +    return false; +} + +uint32_t AudioPolicyManager::handleEventForBeacon(int event) { +    switch(event) { +    case STARTING_OUTPUT: +        mBeaconMuteRefCount++; +        break; +    case STOPPING_OUTPUT: +        if (mBeaconMuteRefCount > 0) { +            mBeaconMuteRefCount--; +        } +        break; +    case STARTING_BEACON: +        mBeaconPlayingRefCount++; +        break; +    case STOPPING_BEACON: +        if (mBeaconPlayingRefCount > 0) { +            mBeaconPlayingRefCount--; +        } +        break; +    } + +    if (mBeaconMuteRefCount > 0) { +        // any playback causes beacon to be muted +        return setBeaconMute(true); +    } else { +        // no other playback: unmute when beacon starts playing, mute when it stops +        return setBeaconMute(mBeaconPlayingRefCount == 0); +    } +} + +uint32_t AudioPolicyManager::setBeaconMute(bool mute) { +    ALOGV("setBeaconMute(%d) mBeaconMuteRefCount=%d mBeaconPlayingRefCount=%d", +            mute, mBeaconMuteRefCount, mBeaconPlayingRefCount); +    // keep track of muted state to avoid repeating mute/unmute operations +    if (mBeaconMuted != mute) { +        // mute/unmute AUDIO_STREAM_TTS on all outputs +        ALOGV("\t muting %d", mute); +        uint32_t maxLatency = 0; +        for (size_t i = 0; i < mOutputs.size(); i++) { +            sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); +            setStreamMute(AUDIO_STREAM_TTS, mute/*on*/, +                    desc->mIoHandle, +                    0 /*delay*/, AUDIO_DEVICE_NONE); +            const uint32_t latency = desc->latency() * 2; +            if (latency > maxLatency) { +                maxLatency = latency; +            } +        } +        mBeaconMuted = mute; +        return maxLatency; +    } +    return 0; +} +  audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,                                                               bool fromCache)  { @@ -3980,6 +4525,14 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate      audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();      switch (strategy) { +    case STRATEGY_TRANSMITTED_THROUGH_SPEAKER: +        device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; +        if (!device) { +            ALOGE("getDeviceForStrategy() no device found for "\ +                    "STRATEGY_TRANSMITTED_THROUGH_SPEAKER"); +        } +        break; +      case STRATEGY_SONIFICATION_RESPECTFUL:          if (isInCall()) {              device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); @@ -4023,7 +4576,8 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate          //   - cannot route from voice call RX OR          //   - audio HAL version is < 3.0 and TX device is on the primary HW module          if (mPhoneState == AUDIO_MODE_IN_CALL) { -            audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION); +            audio_devices_t txDevice = +                    getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);              sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);              if (((mAvailableInputDevices.types() &                      AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) || @@ -4052,7 +4606,7 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate              // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP              if (!isInCall() &&                      (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && -                    (getA2dpOutput() != 0) && !mA2dpSuspended) { +                    (getA2dpOutput() != 0)) {                  device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;                  if (device) break;                  device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; @@ -4087,11 +4641,11 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate              // A2DP speaker when forcing to speaker output              if (!isInCall() &&                      (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && -                    (getA2dpOutput() != 0) && !mA2dpSuspended) { +                    (getA2dpOutput() != 0)) {                  device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;                  if (device) break;              } -            if (mPhoneState != AUDIO_MODE_IN_CALL) { +            if (!isInCall()) {                  device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;                  if (device) break;                  device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE; @@ -4141,15 +4695,35 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate          // The second device used for sonification is the same as the device used by media strategy          // FALL THROUGH +    // FIXME: STRATEGY_ACCESSIBILITY and STRATEGY_REROUTING follow STRATEGY_MEDIA for now +    case STRATEGY_ACCESSIBILITY: +        if (strategy == STRATEGY_ACCESSIBILITY) { +            // do not route accessibility prompts to a digital output currently configured with a +            // compressed format as they would likely not be mixed and dropped. +            for (size_t i = 0; i < mOutputs.size(); i++) { +                sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i); +                audio_devices_t devices = desc->device() & +                    (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC); +                if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) && +                        devices != AUDIO_DEVICE_NONE) { +                    availableOutputDeviceTypes = availableOutputDeviceTypes & ~devices; +                } +            } +        } +        // FALL THROUGH + +    case STRATEGY_REROUTING:      case STRATEGY_MEDIA: {          uint32_t device2 = AUDIO_DEVICE_NONE;          if (strategy != STRATEGY_SONIFICATION) {              // no sonification on remote submix (e.g. WFD) -            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; +            if (mAvailableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) { +                device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; +            }          }          if ((device2 == AUDIO_DEVICE_NONE) &&                  (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && -                (getA2dpOutput() != 0) && !mA2dpSuspended) { +                (getA2dpOutput() != 0)) {              device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;              if (device2 == AUDIO_DEVICE_NONE) {                  device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; @@ -4252,6 +4826,7 @@ uint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp<AudioOutputDescriptor>      for (size_t i = 0; i < NUM_STRATEGIES; i++) {          audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); +        curDevice = curDevice & outputDesc->mProfile->mSupportedDevices.types();          bool mute = shouldMute && (curDevice & device) && (curDevice != device);          bool doMute = false; @@ -4352,11 +4927,15 @@ uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output,      muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);      // Do not change the routing if: -    //  - the requested device is AUDIO_DEVICE_NONE -    //  - the requested device is the same as current device and force is not specified. +    //      the requested device is AUDIO_DEVICE_NONE +    //      OR the requested device is the same as current device +    //  AND force is not specified +    //  AND the output is connected by a valid audio patch.      // Doing this check here allows the caller to call setOutputDevice() without conditions -    if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force) { -        ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output); +    if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force && +            outputDesc->mPatchHandle != 0) { +        ALOGV("setOutputDevice() setting same device %04x or null device for output %d", +              device, output);          return muteWaitMs;      } @@ -4550,6 +5129,7 @@ status_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input,  }  sp<AudioPolicyManager::IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device, +                                                   String8 address,                                                     uint32_t& samplingRate,                                                     audio_format_t format,                                                     audio_channel_mask_t channelMask, @@ -4567,9 +5147,10 @@ sp<AudioPolicyManager::IOProfile> AudioPolicyManager::getInputProfile(audio_devi          {              sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j];              // profile->log(); -            if (profile->isCompatibleProfile(device, samplingRate, +            if (profile->isCompatibleProfile(device, address, samplingRate,                                               &samplingRate /*updatedSamplingRate*/,                                               format, channelMask, (audio_output_flags_t) flags)) { +                  return profile;              }          } @@ -4577,11 +5158,42 @@ sp<AudioPolicyManager::IOProfile> AudioPolicyManager::getInputProfile(audio_devi      return NULL;  } + +audio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t inputSource, +                                                            AudioMix **policyMix) +{ +    audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & +                                            ~AUDIO_DEVICE_BIT_IN; + +    for (size_t i = 0; i < mPolicyMixes.size(); i++) { +        if (mPolicyMixes[i]->mMix.mMixType != MIX_TYPE_RECORDERS) { +            continue; +        } +        for (size_t j = 0; j < mPolicyMixes[i]->mMix.mCriteria.size(); j++) { +            if ((RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET == mPolicyMixes[i]->mMix.mCriteria[j].mRule && +                    mPolicyMixes[i]->mMix.mCriteria[j].mAttr.mSource == inputSource) || +               (RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET == mPolicyMixes[i]->mMix.mCriteria[j].mRule && +                    mPolicyMixes[i]->mMix.mCriteria[j].mAttr.mSource != inputSource)) { +                if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { +                    if (policyMix != NULL) { +                        *policyMix = &mPolicyMixes[i]->mMix; +                    } +                    return AUDIO_DEVICE_IN_REMOTE_SUBMIX; +                } +                break; +            } +        } +    } + +    return getDeviceForInputSource(inputSource); +} +  audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)  {      uint32_t device = AUDIO_DEVICE_NONE;      audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() &                                              ~AUDIO_DEVICE_BIT_IN; +      switch (inputSource) {      case AUDIO_SOURCE_VOICE_UPLINK:        if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) { @@ -4594,6 +5206,9 @@ audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t input      case AUDIO_SOURCE_MIC:      if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {          device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP; +    } else if ((mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO) && +        (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) { +        device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;      } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {          device = AUDIO_DEVICE_IN_WIRED_HEADSET;      } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { @@ -4695,7 +5310,7 @@ bool AudioPolicyManager::isVirtualInputDevice(audio_devices_t device)  }  bool AudioPolicyManager::deviceDistinguishesOnAddress(audio_devices_t device) { -    return ((device & APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL) != 0); +    return ((device & APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL & ~AUDIO_DEVICE_BIT_IN) != 0);  }  audio_io_handle_t AudioPolicyManager::getActiveInput(bool ignoreVirtualInputs) @@ -4716,7 +5331,7 @@ uint32_t AudioPolicyManager::activeInputsCount() const      for (size_t i = 0; i < mInputs.size(); i++) {          const sp<AudioInputDescriptor>  desc = mInputs.valueAt(i);          if (desc->mRefCount > 0) { -            return count++; +            count++;          }      }      return count; @@ -4787,6 +5402,7 @@ AudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_      }  } +/* static */  float AudioPolicyManager::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,          int indexInUi)  { @@ -4900,6 +5516,21 @@ const AudioPolicyManager::VolumeCurvePoint  };  const AudioPolicyManager::VolumeCurvePoint +    AudioPolicyManager::sLinearVolumeCurve[AudioPolicyManager::VOLCNT] = { +    {0, -96.0f}, {33, -68.0f}, {66, -34.0f}, {100, 0.0f} +}; + +const AudioPolicyManager::VolumeCurvePoint +    AudioPolicyManager::sSilentVolumeCurve[AudioPolicyManager::VOLCNT] = { +    {0, -96.0f}, {1, -96.0f}, {2, -96.0f}, {100, -96.0f} +}; + +const AudioPolicyManager::VolumeCurvePoint +    AudioPolicyManager::sFullScaleVolumeCurve[AudioPolicyManager::VOLCNT] = { +    {0, 0.0f}, {1, 0.0f}, {2, 0.0f}, {100, 0.0f} +}; + +const AudioPolicyManager::VolumeCurvePoint              *AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT]                                                     [AudioPolicyManager::DEVICE_CATEGORY_CNT] = {      { // AUDIO_STREAM_VOICE_CALL @@ -4957,11 +5588,30 @@ const AudioPolicyManager::VolumeCurvePoint          sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA      },      { // AUDIO_STREAM_TTS +      // "Transmitted Through Speaker": always silent except on DEVICE_CATEGORY_SPEAKER +        sSilentVolumeCurve, // DEVICE_CATEGORY_HEADSET +        sLinearVolumeCurve, // DEVICE_CATEGORY_SPEAKER +        sSilentVolumeCurve, // DEVICE_CATEGORY_EARPIECE +        sSilentVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA +    }, +    { // AUDIO_STREAM_ACCESSIBILITY          sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET          sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER          sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE          sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA      }, +    { // AUDIO_STREAM_REROUTING +        sFullScaleVolumeCurve, // DEVICE_CATEGORY_HEADSET +        sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER +        sFullScaleVolumeCurve, // DEVICE_CATEGORY_EARPIECE +        sFullScaleVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA +    }, +    { // AUDIO_STREAM_PATCH +        sFullScaleVolumeCurve, // DEVICE_CATEGORY_HEADSET +        sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER +        sFullScaleVolumeCurve, // DEVICE_CATEGORY_EARPIECE +        sFullScaleVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA +    },  };  void AudioPolicyManager::initializeVolumeCurves() @@ -4985,6 +5635,8 @@ void AudioPolicyManager::initializeVolumeCurves()                  sSpeakerSonificationVolumeCurveDrc;          mStreams[AUDIO_STREAM_MUSIC].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =                  sSpeakerMediaVolumeCurveDrc; +        mStreams[AUDIO_STREAM_ACCESSIBILITY].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] = +                sSpeakerMediaVolumeCurveDrc;      }  } @@ -5068,6 +5720,18 @@ status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,      }      float volume = computeVolume(stream, index, output, device); +    // unit gain if rerouting to external policy +    if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) { +        ssize_t index = mOutputs.indexOfKey(output); +        if (index >= 0) { +            sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index); +            if (outputDesc->mPolicyMix != NULL) { +                ALOGV("max gain when rerouting for output=%d", output); +                volume = 1.0f; +            } +        } + +    }      // We actually change the volume if:      // - the float value returned by computeVolume() changed      // - the force flag is set @@ -5110,6 +5774,9 @@ void AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output,      ALOGVV("applyStreamVolumes() for output %d and device %x", output, device);      for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { +        if (stream == AUDIO_STREAM_PATCH) { +            continue; +        }          checkAndSetVolume((audio_stream_type_t)stream,                            mStreams[stream].getVolumeIndex(device),                            output, @@ -5127,6 +5794,9 @@ void AudioPolicyManager::setStrategyMute(routing_strategy strategy,  {      ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);      for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { +        if (stream == AUDIO_STREAM_PATCH) { +            continue; +        }          if (getStrategy((audio_stream_type_t)stream) == strategy) {              setStreamMute((audio_stream_type_t)stream, on, output, delayMs, device);          } @@ -5244,7 +5914,8 @@ uint32_t AudioPolicyManager::getMaxEffectsMemory()  AudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor(          const sp<IOProfile>& profile)      : mId(0), mIoHandle(0), mLatency(0), -    mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), +    mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL), +    mPatchHandle(0),      mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0)  {      // clear usage count for all stream types @@ -5338,6 +6009,9 @@ bool AudioPolicyManager::AudioOutputDescriptor::isStrategyActive(routing_strateg          sysTime = systemTime();      }      for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { +        if (i == AUDIO_STREAM_PATCH) { +            continue; +        }          if (((getStrategy((audio_stream_type_t)i) == strategy) ||                  (NUM_STRATEGIES == strategy)) &&                  isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) { @@ -5436,7 +6110,7 @@ status_t AudioPolicyManager::AudioOutputDescriptor::dump(int fd)  AudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile)      : mId(0), mIoHandle(0), -      mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), mRefCount(0), +      mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL), mPatchHandle(0), mRefCount(0),        mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile), mIsSoundTrigger(false)  {      if (profile != NULL) { @@ -5726,6 +6400,69 @@ status_t AudioPolicyManager::HwModule::loadDevice(cnode *root)      return NO_ERROR;  } +status_t AudioPolicyManager::HwModule::addOutputProfile(String8 name, const audio_config_t *config, +                                                  audio_devices_t device, String8 address) +{ +    sp<IOProfile> profile = new IOProfile(name, AUDIO_PORT_ROLE_SOURCE, this); + +    profile->mSamplingRates.add(config->sample_rate); +    profile->mChannelMasks.add(config->channel_mask); +    profile->mFormats.add(config->format); + +    sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); +    devDesc->mAddress = address; +    profile->mSupportedDevices.add(devDesc); + +    mOutputProfiles.add(profile); + +    return NO_ERROR; +} + +status_t AudioPolicyManager::HwModule::removeOutputProfile(String8 name) +{ +    for (size_t i = 0; i < mOutputProfiles.size(); i++) { +        if (mOutputProfiles[i]->mName == name) { +            mOutputProfiles.removeAt(i); +            break; +        } +    } + +    return NO_ERROR; +} + +status_t AudioPolicyManager::HwModule::addInputProfile(String8 name, const audio_config_t *config, +                                                  audio_devices_t device, String8 address) +{ +    sp<IOProfile> profile = new IOProfile(name, AUDIO_PORT_ROLE_SINK, this); + +    profile->mSamplingRates.add(config->sample_rate); +    profile->mChannelMasks.add(config->channel_mask); +    profile->mFormats.add(config->format); + +    sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device); +    devDesc->mAddress = address; +    profile->mSupportedDevices.add(devDesc); + +    ALOGV("addInputProfile() name %s rate %d mask 0x08", name.string(), config->sample_rate, config->channel_mask); + +    mInputProfiles.add(profile); + +    return NO_ERROR; +} + +status_t AudioPolicyManager::HwModule::removeInputProfile(String8 name) +{ +    for (size_t i = 0; i < mInputProfiles.size(); i++) { +        if (mInputProfiles[i]->mName == name) { +            mInputProfiles.removeAt(i); +            break; +        } +    } + +    return NO_ERROR; +} + +  void AudioPolicyManager::HwModule::dump(int fd)  {      const size_t SIZE = 256; @@ -6043,6 +6780,10 @@ void AudioPolicyManager::AudioPort::loadGains(cnode *root)  status_t AudioPolicyManager::AudioPort::checkExactSamplingRate(uint32_t samplingRate) const  { +    if (mSamplingRates.isEmpty()) { +        return NO_ERROR; +    } +      for (size_t i = 0; i < mSamplingRates.size(); i ++) {          if (mSamplingRates[i] == samplingRate) {              return NO_ERROR; @@ -6054,6 +6795,10 @@ status_t AudioPolicyManager::AudioPort::checkExactSamplingRate(uint32_t sampling  status_t AudioPolicyManager::AudioPort::checkCompatibleSamplingRate(uint32_t samplingRate,          uint32_t *updatedSamplingRate) const  { +    if (mSamplingRates.isEmpty()) { +        return NO_ERROR; +    } +      // Search for the closest supported sampling rate that is above (preferred)      // or below (acceptable) the desired sampling rate, within a permitted ratio.      // The sampling rates do not need to be sorted in ascending order. @@ -6112,6 +6857,10 @@ status_t AudioPolicyManager::AudioPort::checkCompatibleSamplingRate(uint32_t sam  status_t AudioPolicyManager::AudioPort::checkExactChannelMask(audio_channel_mask_t channelMask) const  { +    if (mChannelMasks.isEmpty()) { +        return NO_ERROR; +    } +      for (size_t i = 0; i < mChannelMasks.size(); i++) {          if (mChannelMasks[i] == channelMask) {              return NO_ERROR; @@ -6123,6 +6872,10 @@ status_t AudioPolicyManager::AudioPort::checkExactChannelMask(audio_channel_mask  status_t AudioPolicyManager::AudioPort::checkCompatibleChannelMask(audio_channel_mask_t channelMask)          const  { +    if (mChannelMasks.isEmpty()) { +        return NO_ERROR; +    } +      const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK;      for (size_t i = 0; i < mChannelMasks.size(); i ++) {          // FIXME Does not handle multi-channel automatic conversions yet @@ -6146,6 +6899,10 @@ status_t AudioPolicyManager::AudioPort::checkCompatibleChannelMask(audio_channel  status_t AudioPolicyManager::AudioPort::checkFormat(audio_format_t format) const  { +    if (mFormats.isEmpty()) { +        return NO_ERROR; +    } +      for (size_t i = 0; i < mFormats.size(); i ++) {          if (mFormats[i] == format) {              return NO_ERROR; @@ -6612,17 +7369,18 @@ AudioPolicyManager::IOProfile::~IOProfile()  // Sampling rate, format and channel mask must be specified in order to  // get a valid a match  bool AudioPolicyManager::IOProfile::isCompatibleProfile(audio_devices_t device, -                                                            uint32_t samplingRate, -                                                            uint32_t *updatedSamplingRate, -                                                            audio_format_t format, -                                                            audio_channel_mask_t channelMask, -                                                            uint32_t flags) const +                                                        String8 address, +                                                        uint32_t samplingRate, +                                                        uint32_t *updatedSamplingRate, +                                                        audio_format_t format, +                                                        audio_channel_mask_t channelMask, +                                                        uint32_t flags) const  {      const bool isPlaybackThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SOURCE;      const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK;      ALOG_ASSERT(isPlaybackThread != isRecordThread); -    if ((mSupportedDevices.types() & device) != device) { +    if (device != AUDIO_DEVICE_NONE && mSupportedDevices.getDevice(device, address) == 0) {          return false;      } @@ -6723,9 +7481,6 @@ AudioPolicyManager::DeviceDescriptor::DeviceDescriptor(const String8& name, audi                               NULL),                       mDeviceType(type), mAddress(""), mId(0)  { -    if (mGains.size() > 0) { -        mGains[0]->getDefaultConfig(&mGain); -    }  }  bool AudioPolicyManager::DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const @@ -6740,6 +7495,15 @@ bool AudioPolicyManager::DeviceDescriptor::equals(const sp<DeviceDescriptor>& ot                  mChannelMask == other->mChannelMask);  } +void AudioPolicyManager::DeviceDescriptor::loadGains(cnode *root) +{ +    AudioPort::loadGains(root); +    if (mGains.size() > 0) { +        mGains[0]->getDefaultConfig(&mGain); +    } +} + +  void AudioPolicyManager::DeviceVector::refreshTypes()  {      mDeviceTypes = AUDIO_DEVICE_NONE; @@ -6816,7 +7580,12 @@ void AudioPolicyManager::DeviceVector::loadDevicesFromName(char *name,                                   ARRAY_SIZE(sDeviceNameToEnumTable),                                   devName);              if (type != AUDIO_DEVICE_NONE) { -                add(new DeviceDescriptor(String8(""), type)); +                sp<DeviceDescriptor> dev = new DeviceDescriptor(String8(""), type); +                if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX || +                        type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) { +                    dev->mAddress = String8("0"); +                } +                add(dev);              } else {                  sp<DeviceDescriptor> deviceDesc =                          declaredDevices.getDeviceFromName(String8(devName)); @@ -6825,7 +7594,7 @@ void AudioPolicyManager::DeviceVector::loadDevicesFromName(char *name,                  }              }           } -        devName = strtok(NULL, "|"); +         devName = strtok(NULL, "|");       }  } @@ -6835,13 +7604,15 @@ sp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDe      sp<DeviceDescriptor> device;      for (size_t i = 0; i < size(); i++) {          if (itemAt(i)->mDeviceType == type) { -            device = itemAt(i); -            if (itemAt(i)->mAddress = address) { -                break; +            if (address == "" || itemAt(i)->mAddress == address) { +                device = itemAt(i); +                if (itemAt(i)->mAddress == address) { +                    break; +                }              }          }      } -    ALOGV("DeviceVector::getDevice() for type %d address %s found %p", +    ALOGV("DeviceVector::getDevice() for type %08x address %s found %p",            type, address.string(), device.get());      return device;  } @@ -6864,10 +7635,14 @@ AudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFro                                                                          audio_devices_t type) const  {      DeviceVector devices; +    bool isOutput = audio_is_output_devices(type); +    type &= ~AUDIO_DEVICE_BIT_IN;      for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) { -        if (itemAt(i)->mDeviceType & type & ~AUDIO_DEVICE_BIT_IN) { +        bool curIsOutput = audio_is_output_devices(itemAt(i)->mDeviceType); +        audio_devices_t curType = itemAt(i)->mDeviceType & ~AUDIO_DEVICE_BIT_IN; +        if ((isOutput == curIsOutput) && ((type & curType) != 0)) {              devices.add(itemAt(i)); -            type &= ~itemAt(i)->mDeviceType; +            type &= ~curType;              ALOGV("DeviceVector::getDevicesFromType() for type %x found %p",                    itemAt(i)->mDeviceType, itemAt(i).get());          } @@ -6879,13 +7654,9 @@ AudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFro          audio_devices_t type, String8 address) const  {      DeviceVector devices; -    //ALOGV("   looking for device=%x, addr=%s", type, address.string());      for (size_t i = 0; i < size(); i++) { -        //ALOGV("     at i=%d: device=%x, addr=%s", -        //        i, itemAt(i)->mDeviceType, itemAt(i)->mAddress.string());          if (itemAt(i)->mDeviceType == type) {              if (itemAt(i)->mAddress == address) { -                //ALOGV("      found matching address %s", address.string());                  devices.add(itemAt(i));              }          } @@ -7246,14 +8017,27 @@ audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_      if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {          return AUDIO_STREAM_BLUETOOTH_SCO;      } +    if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) { +        return AUDIO_STREAM_TTS; +    }      // usage to stream type mapping      switch (attr->usage) {      case AUDIO_USAGE_MEDIA:      case AUDIO_USAGE_GAME: -    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:      case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:          return AUDIO_STREAM_MUSIC; +    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: +        if (isStreamActive(AUDIO_STREAM_ALARM)) { +            return AUDIO_STREAM_ALARM; +        } +        if (isStreamActive(AUDIO_STREAM_RING)) { +            return AUDIO_STREAM_RING; +        } +        if (isInCall()) { +            return AUDIO_STREAM_VOICE_CALL; +        } +        return AUDIO_STREAM_ACCESSIBILITY;      case AUDIO_USAGE_ASSISTANCE_SONIFICATION:          return AUDIO_STREAM_SYSTEM;      case AUDIO_USAGE_VOICE_COMMUNICATION: @@ -7279,4 +8063,36 @@ audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_          return AUDIO_STREAM_MUSIC;      }  } + +bool AudioPolicyManager::isValidAttributes(const audio_attributes_t *paa) { +    // has flags that map to a strategy? +    if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) { +        return true; +    } + +    // has known usage? +    switch (paa->usage) { +    case AUDIO_USAGE_UNKNOWN: +    case AUDIO_USAGE_MEDIA: +    case AUDIO_USAGE_VOICE_COMMUNICATION: +    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: +    case AUDIO_USAGE_ALARM: +    case AUDIO_USAGE_NOTIFICATION: +    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: +    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: +    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: +    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: +    case AUDIO_USAGE_NOTIFICATION_EVENT: +    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: +    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: +    case AUDIO_USAGE_ASSISTANCE_SONIFICATION: +    case AUDIO_USAGE_GAME: +    case AUDIO_USAGE_VIRTUAL_SOURCE: +        break; +    default: +        return false; +    } +    return true; +} +  }; // namespace android diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h index 7dbd73f..cbdafa6 100644 --- a/services/audiopolicy/AudioPolicyManager.h +++ b/services/audiopolicy/AudioPolicyManager.h @@ -23,6 +23,7 @@  #include <utils/Errors.h>  #include <utils/KeyedVector.h>  #include <utils/SortedVector.h> +#include <media/AudioPolicy.h>  #include "AudioPolicyInterface.h" @@ -87,25 +88,32 @@ public:                                              audio_channel_mask_t channelMask,                                              audio_output_flags_t flags,                                              const audio_offload_info_t *offloadInfo); -        virtual audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr, -                                            uint32_t samplingRate, -                                            audio_format_t format, -                                            audio_channel_mask_t channelMask, -                                            audio_output_flags_t flags, -                                            const audio_offload_info_t *offloadInfo); +        virtual 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, +                                          audio_format_t format, +                                          audio_channel_mask_t channelMask, +                                          audio_output_flags_t flags, +                                          const audio_offload_info_t *offloadInfo);          virtual status_t startOutput(audio_io_handle_t output,                                       audio_stream_type_t stream, -                                     int session = 0); +                                     audio_session_t session);          virtual status_t stopOutput(audio_io_handle_t output,                                      audio_stream_type_t stream, -                                    int session = 0); -        virtual void releaseOutput(audio_io_handle_t output); -        virtual audio_io_handle_t getInput(audio_source_t inputSource, -                                            uint32_t samplingRate, -                                            audio_format_t format, -                                            audio_channel_mask_t channelMask, -                                            audio_session_t session, -                                            audio_input_flags_t flags); +                                    audio_session_t session); +        virtual void releaseOutput(audio_io_handle_t output, +                                   audio_stream_type_t stream, +                                   audio_session_t session); +        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, +                                         input_type_t *inputType);          // indicates to the audio policy manager that the input starts being used.          virtual status_t startInput(audio_io_handle_t input, @@ -148,6 +156,8 @@ public:          // return whether a stream is playing remotely, override to change the definition of          //   local/remote playback, used for instance by notification manager to not make          //   media players lose audio focus when not playing locally +        //   For the base implementation, "remotely" means playing during screen mirroring which +        //   uses an output for playback with a non-empty, non "0" address.          virtual bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0) const;          virtual bool isSourceActive(audio_source_t source) const; @@ -178,6 +188,9 @@ public:          virtual status_t releaseSoundTriggerSession(audio_session_t session); +        virtual status_t registerPolicyMixes(Vector<AudioMix> mixes); +        virtual status_t unregisterPolicyMixes(Vector<AudioMix> mixes); +  protected:          enum routing_strategy { @@ -187,6 +200,9 @@ protected:              STRATEGY_SONIFICATION_RESPECTFUL,              STRATEGY_DTMF,              STRATEGY_ENFORCED_AUDIBLE, +            STRATEGY_TRANSMITTED_THROUGH_SPEAKER, +            STRATEGY_ACCESSIBILITY, +            STRATEGY_REROUTING,              NUM_STRATEGIES          }; @@ -248,7 +264,7 @@ protected:              audio_gain_mode_t loadGainMode(char *name);              void loadGain(cnode *root, int index); -            void loadGains(cnode *root); +            virtual void loadGains(cnode *root);              // searches for an exact match              status_t checkExactSamplingRate(uint32_t samplingRate) const; @@ -328,10 +344,14 @@ protected:              virtual ~DeviceDescriptor() {}              bool equals(const sp<DeviceDescriptor>& other) const; + +            // AudioPortConfig +            virtual sp<AudioPort> getAudioPort() const { return (AudioPort*) this; }              virtual void toAudioPortConfig(struct audio_port_config *dstConfig,                                     const struct audio_port_config *srcConfig = NULL) const; -            virtual sp<AudioPort> getAudioPort() const { return (AudioPort*) this; } +            // AudioPort +            virtual void loadGains(cnode *root);              virtual void toAudioPort(struct audio_port *port) const;              status_t dump(int fd, int spaces, int index) const; @@ -383,6 +403,7 @@ protected:              // For input, flags is interpreted as audio_input_flags_t.              // TODO: merge audio_output_flags_t and audio_input_flags_t.              bool isCompatibleProfile(audio_devices_t device, +                                     String8 address,                                       uint32_t samplingRate,                                       uint32_t *updatedSamplingRate,                                       audio_format_t format, @@ -406,6 +427,13 @@ protected:              status_t loadInput(cnode *root);              status_t loadDevice(cnode *root); +            status_t addOutputProfile(String8 name, const audio_config_t *config, +                                      audio_devices_t device, String8 address); +            status_t removeOutputProfile(String8 name); +            status_t addInputProfile(String8 name, const audio_config_t *config, +                                      audio_devices_t device, String8 address); +            status_t removeInputProfile(String8 name); +              void dump(int fd);              const char *const        mName; // base name of the audio HW module (primary, a2dp ...) @@ -434,6 +462,9 @@ protected:          static const VolumeCurvePoint sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT];          static const VolumeCurvePoint sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT];          static const VolumeCurvePoint sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT]; +        static const VolumeCurvePoint sLinearVolumeCurve[AudioPolicyManager::VOLCNT]; +        static const VolumeCurvePoint sSilentVolumeCurve[AudioPolicyManager::VOLCNT]; +        static const VolumeCurvePoint sFullScaleVolumeCurve[AudioPolicyManager::VOLCNT];          // default volume curves per stream and device category. See initializeVolumeCurves()          static const VolumeCurvePoint *sVolumeProfiles[AUDIO_STREAM_CNT][DEVICE_CATEGORY_CNT]; @@ -471,6 +502,7 @@ protected:              uint32_t mLatency;                  //              audio_output_flags_t mFlags;   //              audio_devices_t mDevice;                   // current device this output is routed to +            AudioMix *mPolicyMix;             // non NULL when used by a dynamic policy              audio_patch_handle_t mPatchHandle;              uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output              nsecs_t mStopTime[AUDIO_STREAM_CNT]; @@ -496,6 +528,7 @@ protected:              audio_port_handle_t           mId;              audio_io_handle_t             mIoHandle;       // input handle              audio_devices_t               mDevice;         // current device this input is routed to +            AudioMix                      *mPolicyMix;     // non NULL when used by a dynamic policy              audio_patch_handle_t          mPatchHandle;              uint32_t                      mRefCount;       // number of AudioRecord clients using                                                             // this input @@ -565,7 +598,7 @@ protected:          // change the route of the specified output. Returns the number of ms we have slept to          // allow new routing to take effect in certain cases. -        uint32_t setOutputDevice(audio_io_handle_t output, +        virtual uint32_t setOutputDevice(audio_io_handle_t output,                               audio_devices_t device,                               bool force = false,                               int delayMs = 0, @@ -710,7 +743,7 @@ protected:          // if muting, wait for the audio in pcm buffer to be drained before proceeding          // if unmuting, unmute only after the specified delay          // Returns the number of ms waited -        uint32_t  checkDeviceMuteStrategies(sp<AudioOutputDescriptor> outputDesc, +        virtual uint32_t  checkDeviceMuteStrategies(sp<AudioOutputDescriptor> outputDesc,                                              audio_devices_t prevDevice,                                              uint32_t delayMs); @@ -719,10 +752,11 @@ protected:                                         audio_format_t format);          // samplingRate parameter is an in/out and so may be modified          sp<IOProfile> getInputProfile(audio_devices_t device, -                                   uint32_t& samplingRate, -                                   audio_format_t format, -                                   audio_channel_mask_t channelMask, -                                   audio_input_flags_t flags); +                                      String8 address, +                                      uint32_t& samplingRate, +                                      audio_format_t format, +                                      audio_channel_mask_t channelMask, +                                      audio_input_flags_t flags);          sp<IOProfile> getProfileForDirectOutput(audio_devices_t device,                                                         uint32_t samplingRate,                                                         audio_format_t format, @@ -733,9 +767,9 @@ protected:          bool isNonOffloadableEffectEnabled(); -        status_t addAudioPatch(audio_patch_handle_t handle, +        virtual status_t addAudioPatch(audio_patch_handle_t handle,                                 const sp<AudioPatch>& patch); -        status_t removeAudioPatch(audio_patch_handle_t handle); +        virtual status_t removeAudioPatch(audio_patch_handle_t handle);          sp<AudioOutputDescriptor> getOutputFromId(audio_port_handle_t id) const;          sp<AudioInputDescriptor> getInputFromId(audio_port_handle_t id) const; @@ -808,6 +842,29 @@ protected:          sp<AudioPatch> mCallTxPatch;          sp<AudioPatch> mCallRxPatch; +        // for supporting "beacon" streams, i.e. streams that only play on speaker, and never +        // when something other than STREAM_TTS (a.k.a. "Transmitted Through Speaker") is playing +        enum { +            STARTING_OUTPUT, +            STARTING_BEACON, +            STOPPING_OUTPUT, +            STOPPING_BEACON +        }; +        uint32_t mBeaconMuteRefCount;   // ref count for stream that would mute beacon +        uint32_t mBeaconPlayingRefCount;// ref count for the playing beacon streams +        bool mBeaconMuted;              // has STREAM_TTS been muted + +        // custom mix entry in mPolicyMixes +        class AudioPolicyMix : public RefBase { +        public: +            AudioPolicyMix() {} + +            AudioMix    mMix;                   // Audio policy mix descriptor +            sp<AudioOutputDescriptor> mOutput;  // Corresponding output stream +        }; +        DefaultKeyedVector<String8, sp<AudioPolicyMix> > mPolicyMixes; // list of registered mixes + +  #ifdef AUDIO_POLICY_TEST          Mutex   mLock;          Condition mWaitWorkCV; @@ -824,11 +881,13 @@ protected:  #endif //AUDIO_POLICY_TEST          static float volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,                  int indexInUi); +        static bool isVirtualInputDevice(audio_devices_t device); +        uint32_t nextUniqueId(); +        uint32_t nextAudioPortGeneration();  private:          // updates device caching and output for streams that can influence the          //    routing of notifications          void handleNotificationRoutingForStream(audio_stream_type_t stream); -        static bool isVirtualInputDevice(audio_devices_t device);          static bool deviceDistinguishesOnAddress(audio_devices_t device);          // find the outputs on a given output descriptor that have the given address.          // to be called on an AudioOutputDescriptor whose supported devices (as defined @@ -836,14 +895,14 @@ private:          // see deviceDistinguishesOnAddress(audio_devices_t) for whether the device type is one          //   where addresses are used to distinguish between one connected device and another.          void findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/, +                const audio_devices_t device /*in*/,                  const String8 address /*in*/,                  SortedVector<audio_io_handle_t>& outputs /*out*/); -        uint32_t nextUniqueId(); -        uint32_t nextAudioPortGeneration();          uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; }          // internal method to return the output handle for the given device and format          audio_io_handle_t getOutputForDevice(                  audio_devices_t device, +                audio_session_t session,                  audio_stream_type_t stream,                  uint32_t samplingRate,                  audio_format_t format, @@ -852,6 +911,27 @@ private:                  const audio_offload_info_t *offloadInfo);          // internal function to derive a stream type value from audio attributes          audio_stream_type_t streamTypefromAttributesInt(const audio_attributes_t *attr); +        // return true if any output is playing anything besides the stream to ignore +        bool isAnyOutputActive(audio_stream_type_t streamToIgnore); +        // event is one of STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON +        // returns 0 if no mute/unmute event happened, the largest latency of the device where +        //   the mute/unmute happened +        uint32_t handleEventForBeacon(int event); +        uint32_t setBeaconMute(bool mute); +        bool     isValidAttributes(const audio_attributes_t *paa); + +        // select input device corresponding to requested audio source and return associated policy +        // mix if any. Calls getDeviceForInputSource(). +        audio_devices_t getDeviceAndMixForInputSource(audio_source_t inputSource, +                                                        AudioMix **policyMix = NULL); + +        // Called by setDeviceConnectionState(). +        status_t setDeviceConnectionStateInt(audio_devices_t device, +                                                          audio_policy_dev_state_t state, +                                                          const char *device_address); +        sp<DeviceDescriptor>  getDeviceDescriptor(const audio_devices_t device, +                                                  const char *device_address); +  };  }; diff --git a/services/audiopolicy/AudioPolicyService.cpp b/services/audiopolicy/AudioPolicyService.cpp index dd4067f..0955e10 100644 --- a/services/audiopolicy/AudioPolicyService.cpp +++ b/services/audiopolicy/AudioPolicyService.cpp @@ -149,7 +149,7 @@ AudioPolicyService::~AudioPolicyService()  void AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client)  { -    Mutex::Autolock _l(mLock); +    Mutex::Autolock _l(mNotificationClientsLock);      uid_t uid = IPCThreadState::self()->getCallingUid();      if (mNotificationClients.indexOfKey(uid) < 0) { @@ -168,14 +168,17 @@ void AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& cli  // removeNotificationClient() is called when the client process dies.  void AudioPolicyService::removeNotificationClient(uid_t uid)  { -    Mutex::Autolock _l(mLock); - -    mNotificationClients.removeItem(uid); - +    { +        Mutex::Autolock _l(mNotificationClientsLock); +        mNotificationClients.removeItem(uid); +    }  #ifndef USE_LEGACY_AUDIO_POLICY +    { +        Mutex::Autolock _l(mLock);          if (mAudioPolicyManager) {              mAudioPolicyManager->clearAudioPatches(uid);          } +    }  #endif  } @@ -186,7 +189,7 @@ void AudioPolicyService::onAudioPortListUpdate()  void AudioPolicyService::doOnAudioPortListUpdate()  { -    Mutex::Autolock _l(mLock); +    Mutex::Autolock _l(mNotificationClientsLock);      for (size_t i = 0; i < mNotificationClients.size(); i++) {          mNotificationClients.valueAt(i)->onAudioPortListUpdate();      } @@ -212,7 +215,7 @@ status_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle  void AudioPolicyService::doOnAudioPatchListUpdate()  { -    Mutex::Autolock _l(mLock); +    Mutex::Autolock _l(mNotificationClientsLock);      for (size_t i = 0; i < mNotificationClients.size(); i++) {          mNotificationClients.valueAt(i)->onAudioPatchListUpdate();      } @@ -454,7 +457,7 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()                          break;                      }                      mLock.unlock(); -                    svc->doReleaseOutput(data->mIO); +                    svc->doReleaseOutput(data->mIO, data->mStream, data->mSession);                      mLock.lock();                      }break;                  case CREATE_AUDIO_PATCH: { @@ -651,7 +654,7 @@ status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume  void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output,                                                                 audio_stream_type_t stream, -                                                               int session) +                                                               audio_session_t session)  {      sp<AudioCommand> command = new AudioCommand();      command->mCommand = STOP_OUTPUT; @@ -664,12 +667,16 @@ void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t      sendCommand(command);  } -void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output) +void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output, +                                                                  audio_stream_type_t stream, +                                                                  audio_session_t session)  {      sp<AudioCommand> command = new AudioCommand();      command->mCommand = RELEASE_OUTPUT;      sp<ReleaseOutputData> data = new ReleaseOutputData();      data->mIO = output; +    data->mStream = stream; +    data->mSession = session;      command->mParam = data;      ALOGV("AudioCommandThread() adding release output %d", output);      sendCommand(command); @@ -900,8 +907,10 @@ void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& c      }      removedCommands.clear(); -    // Disable wait for status if delay is not 0 -    if (delayMs != 0) { +    // Disable wait for status if delay is not 0. +    // Except for create audio patch command because the returned patch handle +    // is needed by audio policy manager +    if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) {          command->mWaitStatus = false;      } diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h index 4e68ab1..09375cf 100644 --- a/services/audiopolicy/AudioPolicyService.h +++ b/services/audiopolicy/AudioPolicyService.h @@ -30,6 +30,7 @@  #include <media/IAudioPolicyService.h>  #include <media/ToneGenerator.h>  #include <media/AudioEffect.h> +#include <media/AudioPolicy.h>  #include <hardware_legacy/AudioPolicyInterface.h>  #include "AudioPolicyEffects.h"  #include "AudioPolicyManager.h" @@ -72,25 +73,31 @@ public:                                          audio_output_flags_t flags =                                                  AUDIO_OUTPUT_FLAG_NONE,                                          const audio_offload_info_t *offloadInfo = NULL); -    virtual audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr, -                                            uint32_t samplingRate = 0, -                                            audio_format_t format = AUDIO_FORMAT_DEFAULT, -                                            audio_channel_mask_t channelMask = 0, -                                            audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, -                                            const audio_offload_info_t *offloadInfo = NULL); +    virtual 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 = 0, +                                      audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, +                                      const audio_offload_info_t *offloadInfo = NULL);      virtual status_t startOutput(audio_io_handle_t output,                                   audio_stream_type_t stream, -                                 int session = 0); +                                 audio_session_t session);      virtual status_t stopOutput(audio_io_handle_t output,                                  audio_stream_type_t stream, -                                int session = 0); -    virtual void releaseOutput(audio_io_handle_t output); -    virtual audio_io_handle_t getInput(audio_source_t inputSource, -                                    uint32_t samplingRate, -                                    audio_format_t format, -                                    audio_channel_mask_t channelMask, -                                    int audioSession, -                                    audio_input_flags_t flags); +                                audio_session_t session); +    virtual void releaseOutput(audio_io_handle_t output, +                               audio_stream_type_t stream, +                               audio_session_t session); +    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);      virtual status_t startInput(audio_io_handle_t input,                                  audio_session_t session);      virtual status_t stopInput(audio_io_handle_t input, @@ -179,10 +186,14 @@ public:      virtual audio_mode_t getPhoneState(); +    virtual status_t registerPolicyMixes(Vector<AudioMix> mixes, bool registration); +              status_t doStopOutput(audio_io_handle_t output,                                    audio_stream_type_t stream, -                                  int session = 0); -            void doReleaseOutput(audio_io_handle_t output); +                                  audio_session_t session); +            void doReleaseOutput(audio_io_handle_t output, +                                 audio_stream_type_t stream, +                                 audio_session_t session);              status_t clientCreateAudioPatch(const struct audio_patch *patch,                                        audio_patch_handle_t *handle, @@ -250,8 +261,10 @@ private:                      status_t    voiceVolumeCommand(float volume, int delayMs = 0);                      void        stopOutputCommand(audio_io_handle_t output,                                                    audio_stream_type_t stream, -                                                  int session); -                    void        releaseOutputCommand(audio_io_handle_t output); +                                                  audio_session_t session); +                    void        releaseOutputCommand(audio_io_handle_t output, +                                                     audio_stream_type_t stream, +                                                     audio_session_t session);                      status_t    sendCommand(sp<AudioCommand>& command, int delayMs = 0);                      void        insertCommand_l(sp<AudioCommand>& command, int delayMs = 0);                      status_t    createAudioPatchCommand(const struct audio_patch *patch, @@ -321,12 +334,14 @@ private:          public:              audio_io_handle_t mIO;              audio_stream_type_t mStream; -            int mSession; +            audio_session_t mSession;          };          class ReleaseOutputData : public AudioCommandData {          public:              audio_io_handle_t mIO; +            audio_stream_type_t mStream; +            audio_session_t mSession;          };          class CreateAudioPatchData : public AudioCommandData { @@ -495,7 +510,7 @@ private:      AudioPolicyClient *mAudioPolicyClient;      DefaultKeyedVector< uid_t, sp<NotificationClient> >    mNotificationClients; - +    Mutex mNotificationClientsLock;  // protects mNotificationClients      // Manage all effects configured in audio_effects.conf      sp<AudioPolicyEffects> mAudioPolicyEffects;      audio_mode_t mPhoneState; diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index fd5a426..76428da 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -850,6 +850,7 @@ status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,                                              const sp<IBinder>& remoteCallback) {      status_t status = client->initialize(mModule);      if (status != OK) { +        ALOGE("%s: Could not initialize client from HAL module.", __FUNCTION__);          return status;      }      if (remoteCallback != NULL) { diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp index f3a88a1..dcab4ad 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.cpp +++ b/services/camera/libcameraservice/api1/Camera2Client.cpp @@ -917,6 +917,15 @@ void Camera2Client::stopPreviewL() {                  ALOGE("%s: Camera %d: Can't stop streaming: %s (%d)",                          __FUNCTION__, mCameraId, strerror(-res), res);              } + +            // Flush all in-process captures and buffer in order to stop +            // preview faster. +            res = mDevice->flush(); +            if (res != OK) { +                ALOGE("%s: Camera %d: Unable to flush pending requests: %s (%d)", +                        __FUNCTION__, mCameraId, strerror(-res), res); +            } +              res = mDevice->waitUntilDrained();              if (res != OK) {                  ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)", @@ -929,13 +938,6 @@ void Camera2Client::stopPreviewL() {                          "stop preview: %s (%d)",                          __FUNCTION__, mCameraId, strerror(-res), res);              } -            { -                // Ideally we should recover the override after recording stopped, but -                // right now recording stream will live until here, so we are forced to -                // recover here. TODO: find a better way to handle that (b/17495165) -                SharedParameters::Lock l(mParameters); -                l.mParameters.recoverOverriddenJpegSize(); -            }              // no break          case Parameters::WAITING_FOR_PREVIEW_WINDOW: {              SharedParameters::Lock l(mParameters); @@ -1206,6 +1208,28 @@ void Camera2Client::stopRecording() {      mCameraService->playSound(CameraService::SOUND_RECORDING); +    // Remove recording stream to prevent it from slowing down takePicture later +    if (!l.mParameters.recordingHint && l.mParameters.isJpegSizeOverridden()) { +        res = stopStream(); +        if (res != OK) { +            ALOGE("%s: Camera %d: Can't stop streaming: %s (%d)", +                    __FUNCTION__, mCameraId, strerror(-res), res); +        } +        res = mDevice->waitUntilDrained(); +        if (res != OK) { +            ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)", +                    __FUNCTION__, mCameraId, strerror(-res), res); +        } +        // Clean up recording stream +        res = mStreamingProcessor->deleteRecordingStream(); +        if (res != OK) { +            ALOGE("%s: Camera %d: Unable to delete recording stream before " +                    "stop preview: %s (%d)", +                    __FUNCTION__, mCameraId, strerror(-res), res); +        } +        l.mParameters.recoverOverriddenJpegSize(); +    } +      res = startPreviewL(l.mParameters, true);      if (res != OK) {          ALOGE("%s: Camera %d: Unable to return to preview", @@ -1388,6 +1412,34 @@ status_t Camera2Client::takePicture(int msgType) {                      return res;                  }                  l.mParameters.state = Parameters::STILL_CAPTURE; + +                // Remove recording stream to prevent video snapshot jpeg logic kicking in +                if (l.mParameters.isJpegSizeOverridden() && +                        mStreamingProcessor->getRecordingStreamId() != NO_STREAM) { +                    res = mStreamingProcessor->togglePauseStream(/*pause*/true); +                    if (res != OK) { +                        ALOGE("%s: Camera %d: Can't pause streaming: %s (%d)", +                                __FUNCTION__, mCameraId, strerror(-res), res); +                    } +                    res = mDevice->waitUntilDrained(); +                    if (res != OK) { +                        ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)", +                                __FUNCTION__, mCameraId, strerror(-res), res); +                    } +                    // Clean up recording stream +                    res = mStreamingProcessor->deleteRecordingStream(); +                    if (res != OK) { +                        ALOGE("%s: Camera %d: Unable to delete recording stream before " +                                "stop preview: %s (%d)", +                                __FUNCTION__, mCameraId, strerror(-res), res); +                    } +                    res = mStreamingProcessor->togglePauseStream(/*pause*/false); +                    if (res != OK) { +                        ALOGE("%s: Camera %d: Can't unpause streaming: %s (%d)", +                                __FUNCTION__, mCameraId, strerror(-res), res); +                    } +                    l.mParameters.recoverOverriddenJpegSize(); +                }                  break;              case Parameters::RECORD:                  // Good to go for video snapshot diff --git a/services/camera/libcameraservice/api1/client2/BurstCapture.cpp b/services/camera/libcameraservice/api1/client2/BurstCapture.cpp index 0bfdfd4..5502dcb 100644 --- a/services/camera/libcameraservice/api1/client2/BurstCapture.cpp +++ b/services/camera/libcameraservice/api1/client2/BurstCapture.cpp @@ -44,7 +44,7 @@ status_t BurstCapture::start(Vector<CameraMetadata> &/*metadatas*/,      return INVALID_OPERATION;  } -void BurstCapture::onFrameAvailable() { +void BurstCapture::onFrameAvailable(const BufferItem &/*item*/) {      ALOGV("%s", __FUNCTION__);      Mutex::Autolock l(mInputMutex);      if(!mInputChanged) { diff --git a/services/camera/libcameraservice/api1/client2/BurstCapture.h b/services/camera/libcameraservice/api1/client2/BurstCapture.h index ea321fd..c3b7722 100644 --- a/services/camera/libcameraservice/api1/client2/BurstCapture.h +++ b/services/camera/libcameraservice/api1/client2/BurstCapture.h @@ -39,7 +39,7 @@ public:      BurstCapture(wp<Camera2Client> client, wp<CaptureSequencer> sequencer);      virtual ~BurstCapture(); -    virtual void onFrameAvailable(); +    virtual void onFrameAvailable(const BufferItem& item);      virtual status_t start(Vector<CameraMetadata> &metadatas, int32_t firstCaptureId);  protected: diff --git a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp index bf3318e..eadaa00 100644 --- a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp @@ -46,7 +46,7 @@ CallbackProcessor::~CallbackProcessor() {      deleteStream();  } -void CallbackProcessor::onFrameAvailable() { +void CallbackProcessor::onFrameAvailable(const BufferItem& /*item*/) {      Mutex::Autolock l(mInputMutex);      if (!mCallbackAvailable) {          mCallbackAvailable = true; diff --git a/services/camera/libcameraservice/api1/client2/CallbackProcessor.h b/services/camera/libcameraservice/api1/client2/CallbackProcessor.h index 613f5be..7fdc329 100644 --- a/services/camera/libcameraservice/api1/client2/CallbackProcessor.h +++ b/services/camera/libcameraservice/api1/client2/CallbackProcessor.h @@ -44,7 +44,7 @@ class CallbackProcessor:      CallbackProcessor(sp<Camera2Client> client);      ~CallbackProcessor(); -    void onFrameAvailable(); +    void onFrameAvailable(const BufferItem& item);      // Set to NULL to disable the direct-to-app callback window      status_t setCallbackWindow(sp<ANativeWindow> callbackWindow); diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp index 312a78c..40d53b3 100644 --- a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp @@ -168,6 +168,19 @@ status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame,              faceIds = entry.data.i32;          } +        entry = frame.find(ANDROID_SCALER_CROP_REGION); +        if (entry.count < 4) { +            ALOGE("%s: Camera %d: Unable to read crop region (count = %d)", +                    __FUNCTION__, client->getCameraId(), entry.count); +            return res; +        } + +        Parameters::CropRegion scalerCrop = { +            static_cast<float>(entry.data.i32[0]), +            static_cast<float>(entry.data.i32[1]), +            static_cast<float>(entry.data.i32[2]), +            static_cast<float>(entry.data.i32[3])}; +          faces.setCapacity(metadata.number_of_faces);          size_t maxFaces = metadata.number_of_faces; @@ -183,26 +196,30 @@ status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame,              camera_face_t face; -            face.rect[0] = l.mParameters.arrayXToNormalized(faceRects[i*4 + 0]); -            face.rect[1] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 1]); -            face.rect[2] = l.mParameters.arrayXToNormalized(faceRects[i*4 + 2]); -            face.rect[3] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 3]); +            face.rect[0] = l.mParameters.arrayXToNormalizedWithCrop( +                                faceRects[i*4 + 0], scalerCrop); +            face.rect[1] = l.mParameters.arrayYToNormalizedWithCrop( +                                faceRects[i*4 + 1], scalerCrop); +            face.rect[2] = l.mParameters.arrayXToNormalizedWithCrop( +                                faceRects[i*4 + 2], scalerCrop); +            face.rect[3] = l.mParameters.arrayYToNormalizedWithCrop( +                                faceRects[i*4 + 3], scalerCrop);              face.score = faceScores[i];              if (faceDetectMode == ANDROID_STATISTICS_FACE_DETECT_MODE_FULL) {                  face.id = faceIds[i]; -                face.left_eye[0] = -                    l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 0]); -                face.left_eye[1] = -                    l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 1]); -                face.right_eye[0] = -                    l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 2]); -                face.right_eye[1] = -                    l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 3]); -                face.mouth[0] = -                    l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 4]); -                face.mouth[1] = -                    l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 5]); +                face.left_eye[0] = l.mParameters.arrayXToNormalizedWithCrop( +                        faceLandmarks[i*6 + 0], scalerCrop); +                face.left_eye[1] = l.mParameters.arrayYToNormalizedWithCrop( +                        faceLandmarks[i*6 + 1], scalerCrop); +                face.right_eye[0] = l.mParameters.arrayXToNormalizedWithCrop( +                        faceLandmarks[i*6 + 2], scalerCrop); +                face.right_eye[1] = l.mParameters.arrayYToNormalizedWithCrop( +                        faceLandmarks[i*6 + 3], scalerCrop); +                face.mouth[0] = l.mParameters.arrayXToNormalizedWithCrop( +                        faceLandmarks[i*6 + 4], scalerCrop); +                face.mouth[1] = l.mParameters.arrayYToNormalizedWithCrop( +                        faceLandmarks[i*6 + 5], scalerCrop);              } else {                  face.id = 0;                  face.left_eye[0] = face.left_eye[1] = -2000; diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp index b433781..2772267 100644 --- a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp @@ -51,7 +51,7 @@ JpegProcessor::~JpegProcessor() {      deleteStream();  } -void JpegProcessor::onFrameAvailable() { +void JpegProcessor::onFrameAvailable(const BufferItem& /*item*/) {      Mutex::Autolock l(mInputMutex);      if (!mCaptureAvailable) {          mCaptureAvailable = true; diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.h b/services/camera/libcameraservice/api1/client2/JpegProcessor.h index b2c05df..2040b30 100644 --- a/services/camera/libcameraservice/api1/client2/JpegProcessor.h +++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.h @@ -47,7 +47,7 @@ class JpegProcessor:      ~JpegProcessor();      // CpuConsumer listener implementation -    void onFrameAvailable(); +    void onFrameAvailable(const BufferItem& item);      status_t updateStream(const Parameters ¶ms);      status_t deleteStream(); diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp index 7b90d28..4f4cfb0 100644 --- a/services/camera/libcameraservice/api1/client2/Parameters.cpp +++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp @@ -596,6 +596,10 @@ status_t Parameters::initialize(const CameraMetadata *info, int deviceVersion) {                      supportedSceneModes +=                          CameraParameters::SCENE_MODE_BARCODE;                      break; +                case ANDROID_CONTROL_SCENE_MODE_HDR: +                    supportedSceneModes += +                        CameraParameters::SCENE_MODE_HDR; +                    break;                  default:                      ALOGW("%s: Camera %d: Unknown scene mode value: %d",                          __FUNCTION__, cameraId, @@ -2203,6 +2207,10 @@ status_t Parameters::recoverOverriddenJpegSize() {      return OK;  } +bool Parameters::isJpegSizeOverridden() { +    return pictureSizeOverriden; +} +  const char* Parameters::getStateName(State state) {  #define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;      switch(state) { @@ -2382,6 +2390,8 @@ int Parameters::sceneModeStringToEnum(const char *sceneMode) {              ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :          !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?              ANDROID_CONTROL_SCENE_MODE_BARCODE: +        !strcmp(sceneMode, CameraParameters::SCENE_MODE_HDR) ? +            ANDROID_CONTROL_SCENE_MODE_HDR:          -1;  } @@ -2619,75 +2629,71 @@ int Parameters::normalizedYToCrop(int y) const {      return (y + 1000) * (previewCrop.height - 1) / 2000;  } -int Parameters::arrayXToCrop(int x) const { -    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); -    return x - previewCrop.left; -} - -int Parameters::arrayYToCrop(int y) const { -    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); -    return y - previewCrop.top; -} +int Parameters::normalizedXToArray(int x) const { -int Parameters::cropXToNormalized(int x) const { -    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); -    return x * 2000 / (previewCrop.width - 1) - 1000; -} +    // Work-around for HAL pre-scaling the coordinates themselves +    if (quirks.meteringCropRegion) { +        return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000; +    } -int Parameters::cropYToNormalized(int y) const { -    CropRegion previewCrop = calculateCropRegion(CropRegion::OUTPUT_PREVIEW); -    return y * 2000 / (previewCrop.height - 1) - 1000; +    return cropXToArray(normalizedXToCrop(x));  } -int Parameters::arrayXToNormalized(int width) const { -    int ret = cropXToNormalized(arrayXToCrop(width)); - -    ALOG_ASSERT(ret >= -1000, "Calculated normalized value out of " -        "lower bounds %d", ret); -    ALOG_ASSERT(ret <= 1000, "Calculated normalized value out of " -        "upper bounds %d", ret); - +int Parameters::normalizedYToArray(int y) const {      // Work-around for HAL pre-scaling the coordinates themselves      if (quirks.meteringCropRegion) { -        return width * 2000 / (fastInfo.arrayWidth - 1) - 1000; +        return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000;      } -    return ret; +    return cropYToArray(normalizedYToCrop(y));  } -int Parameters::arrayYToNormalized(int height) const { -    int ret = cropYToNormalized(arrayYToCrop(height)); -    ALOG_ASSERT(ret >= -1000, "Calculated normalized value out of lower bounds" -        " %d", ret); -    ALOG_ASSERT(ret <= 1000, "Calculated normalized value out of upper bounds" -        " %d", ret); +Parameters::CropRegion Parameters::calculatePreviewCrop( +        const CropRegion &scalerCrop) const { +    float left, top, width, height; +    float previewAspect = static_cast<float>(previewWidth) / previewHeight; +    float cropAspect = scalerCrop.width / scalerCrop.height; -    // Work-around for HAL pre-scaling the coordinates themselves -    if (quirks.meteringCropRegion) { -        return height * 2000 / (fastInfo.arrayHeight - 1) - 1000; +    if (previewAspect > cropAspect) { +        width = scalerCrop.width; +        height = cropAspect * scalerCrop.height / previewAspect; + +        left = scalerCrop.left; +        top = scalerCrop.top + (scalerCrop.height - height) / 2; +    } else { +        width = previewAspect * scalerCrop.width / cropAspect; +        height = scalerCrop.height; + +        left = scalerCrop.left + (scalerCrop.width - width) / 2; +        top = scalerCrop.top;      } -    return ret; -} +    CropRegion previewCrop = {left, top, width, height}; -int Parameters::normalizedXToArray(int x) const { +    return previewCrop; +} +int Parameters::arrayXToNormalizedWithCrop(int x, +        const CropRegion &scalerCrop) const {      // Work-around for HAL pre-scaling the coordinates themselves      if (quirks.meteringCropRegion) { -        return (x + 1000) * (fastInfo.arrayWidth - 1) / 2000; +        return x * 2000 / (fastInfo.arrayWidth - 1) - 1000; +    } else { +        CropRegion previewCrop = calculatePreviewCrop(scalerCrop); +        return (x - previewCrop.left) * 2000 / (previewCrop.width - 1) - 1000;      } - -    return cropXToArray(normalizedXToCrop(x));  } -int Parameters::normalizedYToArray(int y) const { +int Parameters::arrayYToNormalizedWithCrop(int y, +        const CropRegion &scalerCrop) const {      // Work-around for HAL pre-scaling the coordinates themselves      if (quirks.meteringCropRegion) { -        return (y + 1000) * (fastInfo.arrayHeight - 1) / 2000; +        return y * 2000 / (fastInfo.arrayHeight - 1) - 1000; +    } else { +        CropRegion previewCrop = calculatePreviewCrop(scalerCrop); +        return (y - previewCrop.top) * 2000 / (previewCrop.height - 1) - 1000;      } - -    return cropYToArray(normalizedYToCrop(y));  }  status_t Parameters::getFilteredSizes(Size limit, Vector<Size> *sizes) { @@ -2954,6 +2960,10 @@ status_t Parameters::calculatePictureFovs(float *horizFov, float *vertFov)              staticInfo(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, 2, 2);      if (!sensorSize.count) return NO_INIT; +    camera_metadata_ro_entry_t pixelArraySize = +            staticInfo(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, 2, 2); +    if (!pixelArraySize.count) return NO_INIT; +      float arrayAspect = static_cast<float>(fastInfo.arrayWidth) /              fastInfo.arrayHeight;      float stillAspect = static_cast<float>(pictureWidth) / pictureHeight; @@ -3003,6 +3013,16 @@ status_t Parameters::calculatePictureFovs(float *horizFov, float *vertFov)          vertCropFactor = (arrayAspect < stillAspect) ?                  (arrayAspect / stillAspect) : 1.f;      } + +    /** +     * Convert the crop factors w.r.t the active array size to the crop factors +     * w.r.t the pixel array size. +     */ +    horizCropFactor *= (static_cast<float>(fastInfo.arrayWidth) / +                            pixelArraySize.data.i32[0]); +    vertCropFactor *= (static_cast<float>(fastInfo.arrayHeight) / +                            pixelArraySize.data.i32[1]); +      ALOGV("Horiz crop factor: %f, vert crop fact: %f",              horizCropFactor, vertCropFactor);      /** diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h index 815cc55..7e5be84 100644 --- a/services/camera/libcameraservice/api1/client2/Parameters.h +++ b/services/camera/libcameraservice/api1/client2/Parameters.h @@ -266,6 +266,8 @@ struct Parameters {      status_t overrideJpegSizeByVideoSize();      // Recover overridden jpeg size.  Called during stopRecording.      status_t recoverOverriddenJpegSize(); +    // if video snapshot size is currently overridden +    bool isJpegSizeOverridden();      // Calculate the crop region rectangle based on current stream sizes      struct CropRegion { @@ -325,13 +327,17 @@ struct Parameters {      // Note that this doesn't apply to the (deprecated) single FPS value.      static const int kFpsToApiScale = 1000; -    // Transform between (-1000,-1000)-(1000,1000) normalized coords from camera -    // API and HAL2 (0,0)-(activePixelArray.width/height) coordinates -    int arrayXToNormalized(int width) const; -    int arrayYToNormalized(int height) const; +    // Transform from (-1000,-1000)-(1000,1000) normalized coords from camera +    // API to HAL2 (0,0)-(activePixelArray.width/height) coordinates      int normalizedXToArray(int x) const;      int normalizedYToArray(int y) const; +    // Transform from HAL3 (0,0)-(activePixelArray.width/height) coordinates to +    // (-1000,-1000)-(1000,1000) normalized coordinates given a scaler crop +    // region. +    int arrayXToNormalizedWithCrop(int x, const CropRegion &scalerCrop) const; +    int arrayYToNormalizedWithCrop(int y, const CropRegion &scalerCrop) const; +      struct Range {          int min;          int max; @@ -341,20 +347,20 @@ struct Parameters {  private: -    // Convert between HAL2 sensor array coordinates and -    // viewfinder crop-region relative array coordinates +    // Convert from viewfinder crop-region relative array coordinates +    // to HAL2 sensor array coordinates      int cropXToArray(int x) const;      int cropYToArray(int y) const; -    int arrayXToCrop(int x) const; -    int arrayYToCrop(int y) const; -    // Convert between viewfinder crop-region relative array coordinates -    // and camera API (-1000,1000)-(1000,1000) normalized coords -    int cropXToNormalized(int x) const; -    int cropYToNormalized(int y) const; +    // Convert from camera API (-1000,1000)-(1000,1000) normalized coords +    // to viewfinder crop-region relative array coordinates      int normalizedXToCrop(int x) const;      int normalizedYToCrop(int y) const; +    // Given a scaler crop region, calculate preview crop region based on +    // preview aspect ratio. +    CropRegion calculatePreviewCrop(const CropRegion &scalerCrop) const; +      Vector<Size> availablePreviewSizes;      Vector<Size> availableVideoSizes;      // Get size list (that are no larger than limit) from static metadata. diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp index 9e7fff8..470624b 100644 --- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp @@ -635,7 +635,7 @@ status_t StreamingProcessor::incrementStreamingIds() {      return OK;  } -void StreamingProcessor::onFrameAvailable() { +void StreamingProcessor::onFrameAvailable(const BufferItem& /*item*/) {      ATRACE_CALL();      Mutex::Autolock l(mMutex);      if (!mRecordingFrameAvailable) { diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.h b/services/camera/libcameraservice/api1/client2/StreamingProcessor.h index 8466af4..1d679a4 100644 --- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.h +++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.h @@ -80,7 +80,7 @@ class StreamingProcessor:      status_t incrementStreamingIds();      // Callback for new recording frames from HAL -    virtual void onFrameAvailable(); +    virtual void onFrameAvailable(const BufferItem& item);      // Callback from stagefright which returns used recording frames      void releaseRecordingFrame(const sp<IMemory>& mem); diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp index 8f78103..8b7e4b4 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp @@ -66,7 +66,7 @@ ZslProcessor::~ZslProcessor() {      disconnect();  } -void ZslProcessor::onFrameAvailable() { +void ZslProcessor::onFrameAvailable(const BufferItem& /*item*/) {      Mutex::Autolock l(mInputMutex);      if (!mZslBufferAvailable) {          mZslBufferAvailable = true; diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.h b/services/camera/libcameraservice/api1/client2/ZslProcessor.h index b6533cf..2099c38 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor.h +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.h @@ -53,7 +53,7 @@ class ZslProcessor:      ~ZslProcessor();      // From mZslConsumer -    virtual void onFrameAvailable(); +    virtual void onFrameAvailable(const BufferItem& item);      // From FrameProcessor      virtual void onResultAvailable(const CaptureResult &result); diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp index f110b66..470a6d6 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp @@ -592,7 +592,7 @@ nsecs_t ZslProcessor3::getCandidateTimestampLocked(size_t* metadataIdx) const {                      if (afState != ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED &&                              afState != ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED &&                              afState != ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) { -                        ALOGW("%s: ZSL queue frame AF state is %d is not good for capture, skip it", +                        ALOGVV("%s: ZSL queue frame AF state is %d is not good for capture, skip it",                                  __FUNCTION__, afState);                          continue;                      } diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index e3301aa..e6865bb 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -353,6 +353,14 @@ status_t CameraDeviceClient::createStream(int width, int height, int format,          useAsync = true;      } +    int32_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER | +                              GRALLOC_USAGE_RENDERSCRIPT; +    int32_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK | +                           GraphicBuffer::USAGE_HW_TEXTURE | +                           GraphicBuffer::USAGE_HW_COMPOSER; +    bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 && +            (consumerUsage & allowedFlags) != 0; +      sp<IBinder> binder;      sp<ANativeWindow> anw;      if (bufferProducer != 0) { @@ -382,14 +390,18 @@ status_t CameraDeviceClient::createStream(int width, int height, int format,      //       IMPLEMENTATION_DEFINED. b/9487482      if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&          format <= HAL_PIXEL_FORMAT_BGRA_8888) { -        ALOGW("%s: Camera %d: Overriding format 0x%x to IMPLEMENTATION_DEFINED", +        ALOGW("%s: Camera %d: Overriding format %#x to IMPLEMENTATION_DEFINED",                __FUNCTION__, mCameraId, format);          format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;      } -    // TODO: add startConfigure/stopConfigure call to CameraDeviceBase -    // this will make it so Camera3Device doesn't call configure_streams -    // after each call, but only once we are done with all. +    // Round dimensions to the nearest dimensions available for this format +    if (flexibleConsumer && !CameraDeviceClient::roundBufferDimensionNearest(width, height, +            format, mDevice->info(), /*out*/&width, /*out*/&height)) { +        ALOGE("%s: No stream configurations with the format %#x defined, failed to create stream.", +                __FUNCTION__, format); +        return BAD_VALUE; +    }      int streamId = -1;      res = mDevice->createStream(anw, width, height, format, &streamId); @@ -425,6 +437,62 @@ status_t CameraDeviceClient::createStream(int width, int height, int format,      return res;  } + +bool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height, +        int32_t format, const CameraMetadata& info, +        /*out*/int32_t* outWidth, /*out*/int32_t* outHeight) { + +    camera_metadata_ro_entry streamConfigs = +            info.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); + +    int32_t bestWidth = -1; +    int32_t bestHeight = -1; + +    // Iterate through listed stream configurations and find the one with the smallest euclidean +    // distance from the given dimensions for the given format. +    for (size_t i = 0; i < streamConfigs.count; i += 4) { +        int32_t fmt = streamConfigs.data.i32[i]; +        int32_t w = streamConfigs.data.i32[i + 1]; +        int32_t h = streamConfigs.data.i32[i + 2]; + +        // Ignore input/output type for now +        if (fmt == format) { +            if (w == width && h == height) { +                bestWidth = width; +                bestHeight = height; +                break; +            } else if (w <= ROUNDING_WIDTH_CAP && (bestWidth == -1 || +                    CameraDeviceClient::euclidDistSquare(w, h, width, height) < +                    CameraDeviceClient::euclidDistSquare(bestWidth, bestHeight, width, height))) { +                bestWidth = w; +                bestHeight = h; +            } +        } +    } + +    if (bestWidth == -1) { +        // Return false if no configurations for this format were listed +        return false; +    } + +    // Set the outputs to the closet width/height +    if (outWidth != NULL) { +        *outWidth = bestWidth; +    } +    if (outHeight != NULL) { +        *outHeight = bestHeight; +    } + +    // Return true if at least one configuration for this format was listed +    return true; +} + +int64_t CameraDeviceClient::euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1) { +    int64_t d0 = x0 - x1; +    int64_t d1 = y0 - y1; +    return d0 * d0 + d1 * d1; +} +  // Create a request object from a template.  status_t CameraDeviceClient::createDefaultRequest(int templateId,                                                    /*out*/ diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h index 9981dfe..84e46b7 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.h +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h @@ -154,6 +154,15 @@ private:      /** Utility members */      bool enforceRequestPermissions(CameraMetadata& metadata); +    // Find the square of the euclidean distance between two points +    static int64_t euclidDistSquare(int32_t x0, int32_t y0, int32_t x1, int32_t y1); + +    // Find the closest dimensions for a given format in available stream configurations with +    // a width <= ROUNDING_WIDTH_CAP +    static const int32_t ROUNDING_WIDTH_CAP = 1080; +    static bool roundBufferDimensionNearest(int32_t width, int32_t height, int32_t format, +            const CameraMetadata& info, /*out*/int32_t* outWidth, /*out*/int32_t* outHeight); +      // IGraphicsBufferProducer binder -> Stream ID      KeyedVector<sp<IBinder>, int> mStreamMap; diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp index 8caadd6..d1158d6 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.cpp +++ b/services/camera/libcameraservice/device2/Camera2Device.cpp @@ -793,11 +793,6 @@ status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)          mStreamSlotCount = 0;          return OK;      } -    camera_metadata_t *buf2 = clone_camera_metadata(buf); -    if (!buf2) { -        ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__); -        return NO_MEMORY; -    }      if (mStreamSlotCount > 1) {          List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin(); @@ -806,9 +801,9 @@ status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)      }      if (mStreamSlotCount == 1) {          free_camera_metadata( *(mStreamSlot.begin()) ); -        *(mStreamSlot.begin()) = buf2; +        *(mStreamSlot.begin()) = buf;      } else { -        mStreamSlot.push_front(buf2); +        mStreamSlot.push_front(buf);          mStreamSlotCount = 1;      }      return signalConsumerLocked(); @@ -827,12 +822,7 @@ status_t Camera2Device::MetadataQueue::setStreamSlot(      mStreamSlotCount = 0;      for (List<camera_metadata_t*>::const_iterator r = bufs.begin();           r != bufs.end(); r++) { -        camera_metadata_t *r2 = clone_camera_metadata(*r); -        if (!r2) { -            ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__); -            return NO_MEMORY; -        } -        mStreamSlot.push_back(r2); +        mStreamSlot.push_back(*r);          mStreamSlotCount++;      }      return signalConsumerLocked(); diff --git a/services/camera/libcameraservice/device2/Camera2Device.h b/services/camera/libcameraservice/device2/Camera2Device.h index 2a3f1d9..4def8ae 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.h +++ b/services/camera/libcameraservice/device2/Camera2Device.h @@ -124,8 +124,8 @@ class Camera2Device: public CameraDeviceBase {          // Set repeating buffer(s); if the queue is empty on a dequeue call, the          // queue copies the contents of the stream slot into the queue, and then -        // dequeues the first new entry. The metadata buffers passed in are -        // copied. +        // dequeues the first new entry. The methods take the ownership of the +        // metadata buffers passed in.          status_t setStreamSlot(camera_metadata_t *buf);          status_t setStreamSlot(const List<camera_metadata_t*> &bufs); diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 6a7f9e7..53e6fa9 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -361,16 +361,15 @@ ssize_t Camera3Device::getJpegBufferSize(uint32_t width, uint32_t height) const          return BAD_VALUE;      }      maxJpegBufferSize = jpegBufMaxSize.data.i32[0]; +    assert(kMinJpegBufferSize < maxJpegBufferSize);      // Calculate final jpeg buffer size for the given resolution.      float scaleFactor = ((float) (width * height)) /              (maxJpegResolution.width * maxJpegResolution.height); -    ssize_t jpegBufferSize = scaleFactor * maxJpegBufferSize; -    // Bound the buffer size to [MIN_JPEG_BUFFER_SIZE, maxJpegBufferSize]. +    ssize_t jpegBufferSize = scaleFactor * (maxJpegBufferSize - kMinJpegBufferSize) + +            kMinJpegBufferSize;      if (jpegBufferSize > maxJpegBufferSize) {          jpegBufferSize = maxJpegBufferSize; -    } else if (jpegBufferSize < kMinJpegBufferSize) { -        jpegBufferSize = kMinJpegBufferSize;      }      return jpegBufferSize; @@ -427,7 +426,7 @@ status_t Camera3Device::dump(int fd, const Vector<String16> &args) {              InFlightRequest r = mInFlightMap.valueAt(i);              lines.appendFormat("      Frame %d |  Timestamp: %" PRId64 ", metadata"                      " arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i), -                    r.captureTimestamp, r.haveResultMetadata ? "true" : "false", +                    r.shutterTimestamp, r.haveResultMetadata ? "true" : "false",                      r.numBuffersLeft);          }      } @@ -1880,6 +1879,131 @@ bool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag,      return true;  } + +void Camera3Device::returnOutputBuffers( +        const camera3_stream_buffer_t *outputBuffers, size_t numBuffers, +        nsecs_t timestamp) { +    for (size_t i = 0; i < numBuffers; i++) +    { +        Camera3Stream *stream = Camera3Stream::cast(outputBuffers[i].stream); +        status_t res = stream->returnBuffer(outputBuffers[i], timestamp); +        // Note: stream may be deallocated at this point, if this buffer was +        // the last reference to it. +        if (res != OK) { +            ALOGE("Can't return buffer to its stream: %s (%d)", +                strerror(-res), res); +        } +    } +} + + +void Camera3Device::removeInFlightRequestIfReadyLocked(int idx) { + +    const InFlightRequest &request = mInFlightMap.valueAt(idx); +    const uint32_t frameNumber = mInFlightMap.keyAt(idx); + +    nsecs_t sensorTimestamp = request.sensorTimestamp; +    nsecs_t shutterTimestamp = request.shutterTimestamp; + +    // Check if it's okay to remove the request from InFlightMap: +    // In the case of a successful request: +    //      all input and output buffers, all result metadata, shutter callback +    //      arrived. +    // In the case of a unsuccessful request: +    //      all input and output buffers arrived. +    if (request.numBuffersLeft == 0 && +            (request.requestStatus != OK || +            (request.haveResultMetadata && shutterTimestamp != 0))) { +        ATRACE_ASYNC_END("frame capture", frameNumber); + +        // Sanity check - if sensor timestamp matches shutter timestamp +        if (request.requestStatus == OK && +                sensorTimestamp != shutterTimestamp) { +            SET_ERR("sensor timestamp (%" PRId64 +                ") for frame %d doesn't match shutter timestamp (%" PRId64 ")", +                sensorTimestamp, frameNumber, shutterTimestamp); +        } + +        // for an unsuccessful request, it may have pending output buffers to +        // return. +        assert(request.requestStatus != OK || +               request.pendingOutputBuffers.size() == 0); +        returnOutputBuffers(request.pendingOutputBuffers.array(), +            request.pendingOutputBuffers.size(), 0); + +        mInFlightMap.removeItemsAt(idx, 1); + +        ALOGVV("%s: removed frame %d from InFlightMap", __FUNCTION__, frameNumber); +     } + +    // Sanity check - if we have too many in-flight frames, something has +    // likely gone wrong +    if (mInFlightMap.size() > kInFlightWarnLimit) { +        CLOGE("In-flight list too large: %zu", mInFlightMap.size()); +    } +} + + +void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata, +        CaptureResultExtras &resultExtras, +        CameraMetadata &collectedPartialResult, +        uint32_t frameNumber) { +    if (pendingMetadata.isEmpty()) +        return; + +    Mutex::Autolock l(mOutputLock); + +    // TODO: need to track errors for tighter bounds on expected frame number +    if (frameNumber < mNextResultFrameNumber) { +        SET_ERR("Out-of-order capture result metadata submitted! " +                "(got frame number %d, expecting %d)", +                frameNumber, mNextResultFrameNumber); +        return; +    } +    mNextResultFrameNumber = frameNumber + 1; + +    CaptureResult captureResult; +    captureResult.mResultExtras = resultExtras; +    captureResult.mMetadata = pendingMetadata; + +    if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT, +            (int32_t*)&frameNumber, 1) != OK) { +        SET_ERR("Failed to set frame# in metadata (%d)", +                frameNumber); +        return; +    } else { +        ALOGVV("%s: Camera %d: Set frame# in metadata (%d)", +                __FUNCTION__, mId, frameNumber); +    } + +    // Append any previous partials to form a complete result +    if (mUsePartialResult && !collectedPartialResult.isEmpty()) { +        captureResult.mMetadata.append(collectedPartialResult); +    } + +    captureResult.mMetadata.sort(); + +    // Check that there's a timestamp in the result metadata +    camera_metadata_entry entry = +            captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP); +    if (entry.count == 0) { +        SET_ERR("No timestamp provided by HAL for frame %d!", +                frameNumber); +        return; +    } + +    // Valid result, insert into queue +    List<CaptureResult>::iterator queuedResult = +            mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult)); +    ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64 +           ", burstId = %" PRId32, __FUNCTION__, +           queuedResult->mResultExtras.requestId, +           queuedResult->mResultExtras.frameNumber, +           queuedResult->mResultExtras.burstId); + +    mResultSignal.signal(); +} +  /**   * Camera HAL device callback methods   */ @@ -1914,11 +2038,14 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) {      CaptureResultExtras resultExtras;      bool hasInputBufferInRequest = false; -    // Get capture timestamp and resultExtras from list of in-flight requests, -    // where it was added by the shutter notification for this frame. -    // Then update the in-flight status and remove the in-flight entry if -    // all result data has been received. -    nsecs_t timestamp = 0; +    // Get shutter timestamp and resultExtras from list of in-flight requests, +    // where it was added by the shutter notification for this frame. If the +    // shutter timestamp isn't received yet, append the output buffers to the +    // in-flight request and they will be returned when the shutter timestamp +    // arrives. Update the in-flight status and remove the in-flight entry if +    // all result data and shutter timestamp have been received. +    nsecs_t shutterTimestamp = 0; +      {          Mutex::Autolock l(mInFlightLock);          ssize_t idx = mInFlightMap.indexOfKey(frameNumber); @@ -1928,13 +2055,17 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) {              return;          }          InFlightRequest &request = mInFlightMap.editValueAt(idx); -        ALOGVV("%s: got InFlightRequest requestId = %" PRId32 ", frameNumber = %" PRId64 -                ", burstId = %" PRId32, -                __FUNCTION__, request.resultExtras.requestId, request.resultExtras.frameNumber, -                request.resultExtras.burstId); -        // Always update the partial count to the latest one. When framework aggregates adjacent -        // partial results into one, the latest partial count will be used. -        request.resultExtras.partialResultCount = result->partial_result; +        ALOGVV("%s: got InFlightRequest requestId = %" PRId32 +                ", frameNumber = %" PRId64 ", burstId = %" PRId32 +                ", partialResultCount = %d", +                __FUNCTION__, request.resultExtras.requestId, +                request.resultExtras.frameNumber, request.resultExtras.burstId, +                result->partial_result); +        // Always update the partial count to the latest one if it's not 0 +        // (buffers only). When framework aggregates adjacent partial results +        // into one, the latest partial count will be used. +        if (result->partial_result != 0) +            request.resultExtras.partialResultCount = result->partial_result;          // Check if this result carries only partial metadata          if (mUsePartialResult && result->result != NULL) { @@ -1978,22 +2109,9 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) {              }          } -        timestamp = request.captureTimestamp; -        resultExtras = request.resultExtras; +        shutterTimestamp = request.shutterTimestamp;          hasInputBufferInRequest = request.hasInputBuffer; -        /** -         * One of the following must happen before it's legal to call process_capture_result, -         * unless partial metadata is being provided: -         * - CAMERA3_MSG_SHUTTER (expected during normal operation) -         * - CAMERA3_MSG_ERROR (expected during flush) -         */ -        if (request.requestStatus == OK && timestamp == 0 && !isPartialResult) { -            SET_ERR("Called before shutter notify for frame %d", -                    frameNumber); -            return; -        } -          // Did we get the (final) result metadata for this capture?          if (result->result != NULL && !isPartialResult) {              if (request.haveResultMetadata) { @@ -2026,99 +2144,38 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) {              return;          } -        // Check if everything has arrived for this result (buffers and metadata), remove it from -        // InFlightMap if both arrived or HAL reports error for this request (i.e. during flush). -        if ((request.requestStatus != OK) || -                (request.haveResultMetadata && request.numBuffersLeft == 0)) { -            ATRACE_ASYNC_END("frame capture", frameNumber); -            mInFlightMap.removeItemsAt(idx, 1); +        camera_metadata_ro_entry_t entry; +        res = find_camera_metadata_ro_entry(result->result, +                ANDROID_SENSOR_TIMESTAMP, &entry); +        if (res == OK && entry.count == 1) { +            request.sensorTimestamp = entry.data.i64[0];          } -        // Sanity check - if we have too many in-flight frames, something has -        // likely gone wrong -        if (mInFlightMap.size() > kInFlightWarnLimit) { -            CLOGE("In-flight list too large: %zu", mInFlightMap.size()); -        } - -    } - -    // Process the result metadata, if provided -    bool gotResult = false; -    if (result->result != NULL && !isPartialResult) { -        Mutex::Autolock l(mOutputLock); - -        gotResult = true; - -        // TODO: need to track errors for tighter bounds on expected frame number -        if (frameNumber < mNextResultFrameNumber) { -            SET_ERR("Out-of-order capture result metadata submitted! " -                    "(got frame number %d, expecting %d)", -                    frameNumber, mNextResultFrameNumber); -            return; -        } -        mNextResultFrameNumber = frameNumber + 1; - -        CaptureResult captureResult; -        captureResult.mResultExtras = resultExtras; -        captureResult.mMetadata = result->result; - -        if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT, -                (int32_t*)&frameNumber, 1) != OK) { -            SET_ERR("Failed to set frame# in metadata (%d)", -                    frameNumber); -            gotResult = false; +        // If shutter event isn't received yet, append the output buffers to +        // the in-flight request. Otherwise, return the output buffers to +        // streams. +        if (shutterTimestamp == 0) { +            request.pendingOutputBuffers.appendArray(result->output_buffers, +                result->num_output_buffers);          } else { -            ALOGVV("%s: Camera %d: Set frame# in metadata (%d)", -                    __FUNCTION__, mId, frameNumber); +            returnOutputBuffers(result->output_buffers, +                result->num_output_buffers, shutterTimestamp);          } -        // Append any previous partials to form a complete result -        if (mUsePartialResult && !collectedPartialResult.isEmpty()) { -            captureResult.mMetadata.append(collectedPartialResult); -        } - -        captureResult.mMetadata.sort(); - -        // Check that there's a timestamp in the result metadata - -        camera_metadata_entry entry = -                captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP); -        if (entry.count == 0) { -            SET_ERR("No timestamp provided by HAL for frame %d!", -                    frameNumber); -            gotResult = false; -        } else if (timestamp != entry.data.i64[0]) { -            SET_ERR("Timestamp mismatch between shutter notify and result" -                    " metadata for frame %d (%" PRId64 " vs %" PRId64 " respectively)", -                    frameNumber, timestamp, entry.data.i64[0]); -            gotResult = false; -        } - -        if (gotResult) { -            // Valid result, insert into queue -            List<CaptureResult>::iterator queuedResult = -                    mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult)); -            ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64 -                   ", burstId = %" PRId32, __FUNCTION__, -                   queuedResult->mResultExtras.requestId, -                   queuedResult->mResultExtras.frameNumber, -                   queuedResult->mResultExtras.burstId); +        if (result->result != NULL && !isPartialResult) { +            if (shutterTimestamp == 0) { +                request.pendingMetadata = result->result; +                request.partialResult.collectedResult = collectedPartialResult; +            } else { +                CameraMetadata metadata; +                metadata = result->result; +                sendCaptureResult(metadata, request.resultExtras, +                    collectedPartialResult, frameNumber); +            }          } -    } // scope for mOutputLock - -    // Return completed buffers to their streams with the timestamp -    for (size_t i = 0; i < result->num_output_buffers; i++) { -        Camera3Stream *stream = -                Camera3Stream::cast(result->output_buffers[i].stream); -        res = stream->returnBuffer(result->output_buffers[i], timestamp); -        // Note: stream may be deallocated at this point, if this buffer was the -        // last reference to it. -        if (res != OK) { -            ALOGE("Can't return buffer %zu for frame %d to its stream: " -                    " %s (%d)", i, frameNumber, strerror(-res), res); -        } -    } +        removeInFlightRequestIfReadyLocked(idx); +    } // scope for mInFlightLock      if (result->input_buffer != NULL) {          if (hasInputBufferInRequest) { @@ -2138,13 +2195,6 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) {                      __FUNCTION__);          }      } - -    // Finally, signal any waiters for new frames - -    if (gotResult) { -        mResultSignal.signal(); -    } -  }  void Camera3Device::notify(const camera3_notify_msg *msg) { @@ -2262,8 +2312,6 @@ void Camera3Device::notifyShutter(const camera3_shutter_msg_t &msg,          mNextShutterFrameNumber = msg.frame_number + 1;      } -    CaptureResultExtras resultExtras; -      // Set timestamp for the request in the in-flight tracking      // and get the request ID to send upstream      { @@ -2271,21 +2319,30 @@ void Camera3Device::notifyShutter(const camera3_shutter_msg_t &msg,          idx = mInFlightMap.indexOfKey(msg.frame_number);          if (idx >= 0) {              InFlightRequest &r = mInFlightMap.editValueAt(idx); -            r.captureTimestamp = msg.timestamp; -            resultExtras = r.resultExtras; + +            ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64, +                    mId, __FUNCTION__, +                    msg.frame_number, r.resultExtras.requestId, msg.timestamp); +            // Call listener, if any +            if (listener != NULL) { +                listener->notifyShutter(r.resultExtras, msg.timestamp); +            } + +            r.shutterTimestamp = msg.timestamp; + +            // send pending result and buffers +            sendCaptureResult(r.pendingMetadata, r.resultExtras, +                r.partialResult.collectedResult, msg.frame_number); +            returnOutputBuffers(r.pendingOutputBuffers.array(), +                r.pendingOutputBuffers.size(), r.shutterTimestamp); +            r.pendingOutputBuffers.clear(); + +            removeInFlightRequestIfReadyLocked(idx);          }      }      if (idx < 0) {          SET_ERR("Shutter notification for non-existent frame number %d",                  msg.frame_number); -        return; -    } -    ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64, -            mId, __FUNCTION__, -            msg.frame_number, resultExtras.requestId, msg.timestamp); -    // Call listener, if any -    if (listener != NULL) { -        listener->notifyShutter(resultExtras, msg.timestamp);      }  } diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index ec6bba1..ec8dc10 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -521,7 +521,9 @@ class Camera3Device :      struct InFlightRequest {          // Set by notify() SHUTTER call. -        nsecs_t captureTimestamp; +        nsecs_t shutterTimestamp; +        // Set by process_capture_result(). +        nsecs_t sensorTimestamp;          int     requestStatus;          // Set by process_capture_result call with valid metadata          bool    haveResultMetadata; @@ -532,6 +534,21 @@ class Camera3Device :          // If this request has any input buffer          bool hasInputBuffer; + +        // The last metadata that framework receives from HAL and +        // not yet send out because the shutter event hasn't arrived. +        // It's added by process_capture_result and sent when framework +        // receives the shutter event. +        CameraMetadata pendingMetadata; + +        // Buffers are added by process_capture_result when output buffers +        // return from HAL but framework has not yet received the shutter +        // event. They will be returned to the streams when framework receives +        // the shutter event. +        Vector<camera3_stream_buffer_t> pendingOutputBuffers; + + +          // Fields used by the partial result only          struct PartialResultInFlight {              // Set by process_capture_result once 3A has been sent to clients @@ -546,7 +563,8 @@ class Camera3Device :          // Default constructor needed by KeyedVector          InFlightRequest() : -                captureTimestamp(0), +                shutterTimestamp(0), +                sensorTimestamp(0),                  requestStatus(OK),                  haveResultMetadata(false),                  numBuffersLeft(0), @@ -554,7 +572,8 @@ class Camera3Device :          }          InFlightRequest(int numBuffers) : -                captureTimestamp(0), +                shutterTimestamp(0), +                sensorTimestamp(0),                  requestStatus(OK),                  haveResultMetadata(false),                  numBuffersLeft(numBuffers), @@ -562,7 +581,8 @@ class Camera3Device :          }          InFlightRequest(int numBuffers, CaptureResultExtras extras) : -                captureTimestamp(0), +                shutterTimestamp(0), +                sensorTimestamp(0),                  requestStatus(OK),                  haveResultMetadata(false),                  numBuffersLeft(numBuffers), @@ -571,7 +591,8 @@ class Camera3Device :          }          InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput) : -                captureTimestamp(0), +                shutterTimestamp(0), +                sensorTimestamp(0),                  requestStatus(OK),                  haveResultMetadata(false),                  numBuffersLeft(numBuffers), @@ -639,6 +660,24 @@ class Camera3Device :      void notifyShutter(const camera3_shutter_msg_t &msg,              NotificationListener *listener); +    // helper function to return the output buffers to the streams. +    void returnOutputBuffers(const camera3_stream_buffer_t *outputBuffers, +            size_t numBuffers, nsecs_t timestamp); + +    // Insert the capture result given the pending metadata, result extras, +    // partial results, and the frame number to the result queue. +    void sendCaptureResult(CameraMetadata &pendingMetadata, +            CaptureResultExtras &resultExtras, +            CameraMetadata &collectedPartialResult, uint32_t frameNumber); + +    /**** Scope for mInFlightLock ****/ + +    // Remove the in-flight request of the given index from mInFlightMap +    // if it's no longer needed. It must only be called with mInFlightLock held. +    void removeInFlightRequestIfReadyLocked(int idx); + +    /**** End scope for mInFlightLock ****/ +      /**       * Static callback forwarding methods from HAL to instance       */ diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp index f8562ec..d0f29de 100644 --- a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp +++ b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp @@ -268,7 +268,7 @@ status_t RingBufferConsumer::releaseOldestBufferLocked(size_t* pinnedFrames) {      return OK;  } -void RingBufferConsumer::onFrameAvailable() { +void RingBufferConsumer::onFrameAvailable(const android::BufferItem& item) {      status_t err;      { @@ -321,7 +321,7 @@ void RingBufferConsumer::onFrameAvailable() {          item.mGraphicBuffer = mSlots[item.mBuf].mGraphicBuffer;      } // end of mMutex lock -    ConsumerBase::onFrameAvailable(); +    ConsumerBase::onFrameAvailable(item);  }  void RingBufferConsumer::unpinBuffer(const BufferItem& item) { diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.h b/services/camera/libcameraservice/gui/RingBufferConsumer.h index da97a11..90fd734 100644 --- a/services/camera/libcameraservice/gui/RingBufferConsumer.h +++ b/services/camera/libcameraservice/gui/RingBufferConsumer.h @@ -165,7 +165,7 @@ class RingBufferConsumer : public ConsumerBase,    private:      // Override ConsumerBase::onFrameAvailable -    virtual void onFrameAvailable(); +    virtual void onFrameAvailable(const android::BufferItem& item);      void pinBufferLocked(const BufferItem& item);      void unpinBuffer(const BufferItem& item); diff --git a/services/soundtrigger/Android.mk b/services/soundtrigger/Android.mk index 572ae56..ecc49ae 100644 --- a/services/soundtrigger/Android.mk +++ b/services/soundtrigger/Android.mk @@ -32,9 +32,7 @@ LOCAL_SHARED_LIBRARIES:= \      libcutils \      libhardware \      libsoundtrigger \ -    libmedia - -LOCAL_STATIC_LIBRARIES := \ +    libmedia \      libserviceutility  LOCAL_C_INCLUDES += \ diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp index b5aaee3..d3b67f6 100644 --- a/services/soundtrigger/SoundTriggerHwService.cpp +++ b/services/soundtrigger/SoundTriggerHwService.cpp @@ -535,6 +535,16 @@ status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelM              (struct sound_trigger_sound_model *)modelMemory->pointer();      AutoMutex lock(mLock); + +    if (mModels.size() >= mDescriptor.properties.max_sound_models) { +        if (mModels.size() == 0) { +            return INVALID_OPERATION; +        } +        ALOGW("loadSoundModel() max number of models exceeded %d making room for a new one", +              mDescriptor.properties.max_sound_models); +        unloadSoundModel_l(mModels.valueAt(0)->mHandle); +    } +      status_t status = mHwDevice->load_sound_model(mHwDevice,                                                    sound_model,                                                    SoundTriggerHwService::soundModelCallback, @@ -566,6 +576,11 @@ status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t ha      }      AutoMutex lock(mLock); +    return unloadSoundModel_l(handle); +} + +status_t SoundTriggerHwService::Module::unloadSoundModel_l(sound_model_handle_t handle) +{      ssize_t index = mModels.indexOfKey(handle);      if (index < 0) {          return BAD_VALUE; @@ -574,6 +589,7 @@ status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t ha      mModels.removeItem(handle);      if (model->mState == Model::STATE_ACTIVE) {          mHwDevice->stop_recognition(mHwDevice, model->mHandle); +        model->mState = Model::STATE_IDLE;      }      AudioSystem::releaseSoundTriggerSession(model->mCaptureSession);      return mHwDevice->unload_sound_model(mHwDevice, handle); diff --git a/services/soundtrigger/SoundTriggerHwService.h b/services/soundtrigger/SoundTriggerHwService.h index d05dacd..2619a5f 100644 --- a/services/soundtrigger/SoundTriggerHwService.h +++ b/services/soundtrigger/SoundTriggerHwService.h @@ -141,6 +141,9 @@ public:      private: +       status_t unloadSoundModel_l(sound_model_handle_t handle); + +          Mutex                                  mLock;          wp<SoundTriggerHwService>              mService;          struct sound_trigger_hw_device*        mHwDevice;  | 
