From 4dd0a8a3d66c2853faf2834565b3c5df4f68734d Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Wed, 6 Nov 2013 21:04:34 -0800 Subject: WA: Queue extra buffers on output port during reconfig if input EOS-ed Some codecs may return input buffers before having them processed. This causes a halt if we already signaled an EOS on the input port. For now keep submitting output meta buffers one at a time if the input EOS-ed, but the output not yet. Normally, we submit an output buffer for each input buffer that is with the component (waiting to be processed). Change-Id: I8a1251bfb504f40f1e4085a1e220bf9a4d0b05d9 Signed-off-by: Lajos Molnar Bug: 11433909 --- include/media/stagefright/ACodec.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index e796ab3..7395055 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -116,6 +116,7 @@ private: kWhatStart = 'star', kWhatRequestIDRFrame = 'ridr', kWhatSetParameters = 'setP', + kWhatSubmitOutputMetaDataBufferIfEOS = 'subm', }; enum { @@ -212,6 +213,7 @@ private: OMX_U32 *nMinUndequeuedBuffers); status_t allocateOutputMetaDataBuffers(); status_t submitOutputMetaDataBuffer(); + void signalSubmitOutputMetaDataBufferIfEOS_workaround(); status_t allocateOutputBuffersFromNativeWindow(); status_t cancelBufferToNativeWindow(BufferInfo *info); status_t freeOutputBuffersNotOwnedByComponent(); -- cgit v1.1 From 85b3013e06e8fe7802fe6259ecac80261e834332 Mon Sep 17 00:00:00 2001 From: jpadmana Date: Thu, 14 Nov 2013 17:20:52 +0530 Subject: fix deadlock issues that arise when there are simultaneous effect control interface calls to proxy and to non sub-effect wrappers(eg., bundlewrapper) from audioflinger Also, return NO_ERROR when CMD_OFFLOAD succeeds Whenever there are parallel calls to proxy and non sub-effects wrappers, some of the calls are not completed. This is due to deadlock arsing out of Proxy waiting for the subeffect call to return and subeffect waiting for proxy to release lock. The call flow is changed to a cleaner and simple one - Proxy gets the aeli(effect library info) of subeffects during the EffectGetSubEffects() call. Therby, proxy will manage the sub effects by itself rather than going through effects factory. Change-Id: If4b259da5776f151c1e81a78a0239d342046d923 Signed-off-by: jpadmana Bug: 12424044 --- include/media/EffectsFactoryApi.h | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'include') diff --git a/include/media/EffectsFactoryApi.h b/include/media/EffectsFactoryApi.h index b1143b9..b1ed7b0 100644 --- a/include/media/EffectsFactoryApi.h +++ b/include/media/EffectsFactoryApi.h @@ -171,30 +171,6 @@ int EffectGetDescriptor(const effect_uuid_t *pEffectUuid, effect_descriptor_t *p //////////////////////////////////////////////////////////////////////////////// int EffectIsNullUuid(const effect_uuid_t *pEffectUuid); -//////////////////////////////////////////////////////////////////////////////// -// -// Function: EffectGetSubEffects -// -// Description: Returns the descriptors of the sub effects of the effect -// whose uuid is pointed to by first argument. -// -// Input: -// pEffectUuid: pointer to the effect uuid. -// size: size of the buffer pointed by pDescriptor. -// -// Input/Output: -// pDescriptor: address where to return the sub effect descriptors. -// -// Output: -// returned value: 0 successful operation. -// -ENODEV factory failed to initialize -// -EINVAL invalid pEffectUuid or pDescriptor -// -ENOENT no effect with this uuid found -// *pDescriptor: updated with the sub effect descriptors. -// -//////////////////////////////////////////////////////////////////////////////// -int EffectGetSubEffects(const effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptors, size_t size); - #if __cplusplus } // extern "C" #endif -- cgit v1.1 From d0115d8c4db2f337030dea706bc0a434c4a03ed6 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Fri, 26 Jul 2013 17:16:50 -0700 Subject: update offloaded audio track sampling rate AudioPlayer must read the sampling rate from offloaded audio sinks whenever a new time position is computed as the decoder can update the sampling rate on the fly. Bug: 12823955. Change-Id: I997e5248cfd4017aeceb4e11689324ded2a5bc88 --- include/media/AudioTrack.h | 2 +- include/media/MediaPlayerInterface.h | 1 + include/media/stagefright/AudioPlayer.h | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index f379ee5..f6646ab 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -661,7 +661,7 @@ protected: sp mAudioTrackThread; float mVolume[2]; float mSendLevel; - uint32_t mSampleRate; + mutable uint32_t mSampleRate; // mutable because getSampleRate() can update it. size_t mFrameCount; // corresponds to current IAudioTrack size_t mReqFrameCount; // frame count to request the next time a new // IAudioTrack is needed diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index cc244f0..26d8729 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -100,6 +100,7 @@ public: virtual status_t getFramesWritten(uint32_t *frameswritten) const = 0; virtual int getSessionId() const = 0; virtual audio_stream_type_t getAudioStreamType() const = 0; + virtual uint32_t getSampleRate() const = 0; // If no callback is specified, use the "write" API below to submit // audio data. diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h index 912a43c..14afb85 100644 --- a/include/media/stagefright/AudioPlayer.h +++ b/include/media/stagefright/AudioPlayer.h @@ -129,7 +129,7 @@ private: void reset(); uint32_t getNumFramesPendingPlayout() const; - int64_t getOutputPlayPositionUs_l() const; + int64_t getOutputPlayPositionUs_l(); bool allowDeepBuffering() const { return (mCreateFlags & ALLOW_DEEP_BUFFERING) != 0; } bool useOffload() const { return (mCreateFlags & USE_OFFLOAD) != 0; } -- cgit v1.1 From f590f948e6c0fe3c54008dd7802fd513f127792d Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Fri, 6 Dec 2013 11:51:42 -0800 Subject: stagefright: do not offload LD-AAC decoding For now, do not offload LD and ELD AAC decoding because there is no way to know if it is supported by the audio DSP implementation. The longer term fix will be to have mapMimeToAudioFormat() use the audio object type in track metadata to refine the AAC format and the audio HAL list supported AAC profiles. Bug: 11697128. Change-Id: Iaa88ecf3f4ae42ad48c1b42a9b007dd80eb88147 --- include/media/stagefright/MetaData.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h index de3fc36..3a87474 100644 --- a/include/media/stagefright/MetaData.h +++ b/include/media/stagefright/MetaData.h @@ -134,6 +134,7 @@ enum { kKeyRequiresSecureBuffers = 'secu', // bool (int32_t) kKeyIsADTS = 'adts', // bool (int32_t) + kKeyAACAOT = 'aaot', // int32_t // If a MediaBuffer's data represents (at least partially) encrypted // data, the following fields aid in decryption. -- cgit v1.1 From 933a4d3339ebbcd34a7f97b9e7350ec74b5ec29c Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Thu, 23 Jan 2014 15:26:43 -0800 Subject: Added support to query ACodec whether adaptive playback is enabled. Bug: 11854054 Change-Id: I6b0308aa8550c643706959277e46dad586c37297 --- include/media/stagefright/ACodec.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index 7395055..510c482 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -67,6 +67,8 @@ struct ACodec : public AHierarchicalStateMachine { void signalRequestIDRFrame(); + bool isConfiguredForAdaptivePlayback() { return mIsConfiguredForAdaptivePlayback; } + struct PortDescription : public RefBase { size_t countBuffers(); IOMX::buffer_id bufferIDAt(size_t index) const; @@ -187,6 +189,7 @@ private: bool mIsEncoder; bool mUseMetadataOnEncoderOutput; bool mShutdownInProgress; + bool mIsConfiguredForAdaptivePlayback; // If "mKeepComponentAllocated" we only transition back to Loaded state // and do not release the component instance. -- cgit v1.1 From 2048c2292c0466b184fb8f67c91f4d0ab9f5c3f3 Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Wed, 8 Jan 2014 13:59:53 -0800 Subject: AudioTrack: When paused, return cached playback position An offload output can be re-used between two audio tracks having the same configuration. A timestamp query for a paused track while the other is running would return an incorrect time. To fix this, cache the playback position on a pause() and return this time when requested until the track is resumed. Bug: 12826612. Change-Id: Ia42b8b8fd2ba8993dfcc9abca72da48d71d78d74 --- include/media/AudioTrack.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index f6646ab..4736369 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -740,6 +740,7 @@ protected: bool mInUnderrun; // whether track is currently in underrun state String8 mName; // server's name for this IAudioTrack + uint32_t mPausedPosition; private: class DeathNotifier : public IBinder::DeathRecipient { -- cgit v1.1 From 8bd4d16aa5636e98522c07ae31236420788aa749 Mon Sep 17 00:00:00 2001 From: Chong Zhang Date: Fri, 10 Jan 2014 17:36:57 -0800 Subject: Cap pts gap between adjacent frames to specified value - In the scenario of cast mirroring, encoding could be suspended for prolonged periods. Limiting the pts gap to workaround the problem where encoder's rate control logic produces huge frames after a long period of suspension. - Repeat last frame a couple more times to get better quality on static scenes. - Fix the timestamp on repeat frames (it was not set) Bug: 11971963 Change-Id: I1d68ab3d269874bf3921aa429a985c5f63e428c7 (cherry picked from commit 94ee4b708acfa941581160b267afb79192b1d816) --- include/media/IOMX.h | 1 + include/media/stagefright/ACodec.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include') diff --git a/include/media/IOMX.h b/include/media/IOMX.h index 9c8451c..6643736 100644 --- a/include/media/IOMX.h +++ b/include/media/IOMX.h @@ -142,6 +142,7 @@ public: enum InternalOptionType { INTERNAL_OPTION_SUSPEND, // data is a bool INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY, // data is an int64_t + INTERNAL_OPTION_MAX_TIMESTAMP_GAP, // data is int64_t }; virtual status_t setInternalOption( node_id node, diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index 510c482..bf3a998 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -205,6 +205,7 @@ private: int32_t mMetaDataBuffersToSubmit; int64_t mRepeatFrameDelayUs; + int64_t mMaxPtsGapUs; status_t setCyclicIntraMacroblockRefresh(const sp &msg, int32_t mode); status_t allocateBuffersOnPort(OMX_U32 portIndex); -- cgit v1.1 From b635b0e66b257ab442e230bca96afd5105cf6829 Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Thu, 13 Feb 2014 15:29:49 -0800 Subject: mediaplayer: keep more buffers with the BufferQueue Change OMX buffer allocation policy to allocate nBufferCountMin + what is required for the BQ. For the BQ, try to allocate 2 additional buffers than the minimum undequeued count. Also account for the fact that BQ may return one less than the actual minimum undequeued count. In most cases the resulting number of buffers ends up being the same as with the previous policy, but we keep more buffers with the BQ. Change-Id: I826db8bf7dd333b620299dba60bf1b81b228275d Bug: 13170236 --- include/media/stagefright/ACodec.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index bf3a998..46c62dc 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -203,6 +203,7 @@ private: unsigned mDequeueCounter; bool mStoreMetaDataInOutputBuffers; int32_t mMetaDataBuffersToSubmit; + size_t mNumUndequeuedBuffers; int64_t mRepeatFrameDelayUs; int64_t mMaxPtsGapUs; -- cgit v1.1 From 0370be96e33ea0c8fb4069e704deccce43b7403c Mon Sep 17 00:00:00 2001 From: Igor Murashkin Date: Tue, 18 Mar 2014 18:15:23 -0700 Subject: DO NOT MERGE: camera: Fix setParameters for Preview FPS single/range values As a workaround, duplicate CameraParameters into CameraParameters2 to prevent ABI break for some camera HALs that directly link into CameraParameters. CameraParameters2 implements the real fixes needed in the framework, while CameraParameters is left in to satisfy older camera HALs. Bug: 12609188 Change-Id: I82ea6f5de2183dd046d4bf5683600c97f37ab4da --- include/camera/CameraParameters2.h | 203 +++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 include/camera/CameraParameters2.h (limited to 'include') diff --git a/include/camera/CameraParameters2.h b/include/camera/CameraParameters2.h new file mode 100644 index 0000000..88ad812 --- /dev/null +++ b/include/camera/CameraParameters2.h @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_CAMERA_PARAMETERS2_H +#define ANDROID_HARDWARE_CAMERA_PARAMETERS2_H + +#include +#include +#include "CameraParameters.h" + +namespace android { + +/** + * A copy of CameraParameters plus ABI-breaking changes. Needed + * because some camera HALs directly link to CameraParameters and cannot + * tolerate an ABI change. + */ +class CameraParameters2 +{ +public: + CameraParameters2(); + CameraParameters2(const String8 ¶ms) { unflatten(params); } + ~CameraParameters2(); + + String8 flatten() const; + void unflatten(const String8 ¶ms); + + void set(const char *key, const char *value); + void set(const char *key, int value); + void setFloat(const char *key, float value); + // Look up string value by key. + // -- The string remains valid until the next set/remove of the same key, + // or until the map gets cleared. + const char *get(const char *key) const; + int getInt(const char *key) const; + float getFloat(const char *key) const; + + // Compare the order that key1 was set vs the order that key2 was set. + // + // Sets the order parameter to an integer less than, equal to, or greater + // than zero if key1's set order was respectively, to be less than, to + // match, or to be greater than key2's set order. + // + // Error codes: + // * NAME_NOT_FOUND - if either key has not been set previously + // * BAD_VALUE - if any of the parameters are NULL + status_t compareSetOrder(const char *key1, const char *key2, + /*out*/ + int *order) const; + + void remove(const char *key); + + void setPreviewSize(int width, int height); + void getPreviewSize(int *width, int *height) const; + void getSupportedPreviewSizes(Vector &sizes) const; + + // Set the dimensions in pixels to the given width and height + // for video frames. The given width and height must be one + // of the supported dimensions returned from + // getSupportedVideoSizes(). Must not be called if + // getSupportedVideoSizes() returns an empty Vector of Size. + void setVideoSize(int width, int height); + // Retrieve the current dimensions (width and height) + // in pixels for video frames, which must be one of the + // supported dimensions returned from getSupportedVideoSizes(). + // Must not be called if getSupportedVideoSizes() returns an + // empty Vector of Size. + void getVideoSize(int *width, int *height) const; + // Retrieve a Vector of supported dimensions (width and height) + // in pixels for video frames. If sizes returned from the method + // is empty, the camera does not support calls to setVideoSize() + // or getVideoSize(). In adddition, it also indicates that + // the camera only has a single output, and does not have + // separate output for video frames and preview frame. + void getSupportedVideoSizes(Vector &sizes) const; + // Retrieve the preferred preview size (width and height) in pixels + // for video recording. The given width and height must be one of + // supported preview sizes returned from getSupportedPreviewSizes(). + // Must not be called if getSupportedVideoSizes() returns an empty + // Vector of Size. If getSupportedVideoSizes() returns an empty + // Vector of Size, the width and height returned from this method + // is invalid, and is "-1x-1". + void getPreferredPreviewSizeForVideo(int *width, int *height) const; + + void setPreviewFrameRate(int fps); + int getPreviewFrameRate() const; + void getPreviewFpsRange(int *min_fps, int *max_fps) const; + void setPreviewFpsRange(int min_fps, int max_fps); + void setPreviewFormat(const char *format); + const char *getPreviewFormat() const; + void setPictureSize(int width, int height); + void getPictureSize(int *width, int *height) const; + void getSupportedPictureSizes(Vector &sizes) const; + void setPictureFormat(const char *format); + const char *getPictureFormat() const; + + void dump() const; + status_t dump(int fd, const Vector& args) const; + +private: + + // Quick and dirty map that maintains insertion order + template + struct OrderedKeyedVector { + + ssize_t add(const KeyT& key, const ValueT& value) { + return mList.add(Pair(key, value)); + } + + size_t size() const { + return mList.size(); + } + + const KeyT& keyAt(size_t idx) const { + return mList[idx].mKey; + } + + const ValueT& valueAt(size_t idx) const { + return mList[idx].mValue; + } + + const ValueT& valueFor(const KeyT& key) const { + ssize_t i = indexOfKey(key); + LOG_ALWAYS_FATAL_IF(i<0, "%s: key not found", __PRETTY_FUNCTION__); + + return valueAt(i); + } + + ssize_t indexOfKey(const KeyT& key) const { + size_t vectorIdx = 0; + for (; vectorIdx < mList.size(); ++vectorIdx) { + if (mList[vectorIdx].mKey == key) { + return (ssize_t) vectorIdx; + } + } + + return NAME_NOT_FOUND; + } + + ssize_t removeItem(const KeyT& key) { + size_t vectorIdx = (size_t) indexOfKey(key); + + if (vectorIdx < 0) { + return vectorIdx; + } + + return mList.removeAt(vectorIdx); + } + + void clear() { + mList.clear(); + } + + // Same as removing and re-adding. The key's index changes to max. + ssize_t replaceValueFor(const KeyT& key, const ValueT& value) { + removeItem(key); + return add(key, value); + } + + private: + + struct Pair { + Pair() : mKey(), mValue() {} + Pair(const KeyT& key, const ValueT& value) : + mKey(key), + mValue(value) {} + KeyT mKey; + ValueT mValue; + }; + + Vector mList; + }; + + /** + * Order matters: Keys that are set() later are stored later in the map. + * + * If two keys have meaning that conflict, then the later-set key + * wins. + * + * For example, preview FPS and preview FPS range conflict since only + * we only want to use the FPS range if that's the last thing that was set. + * So in that case, only use preview FPS range if it was set later than + * the preview FPS. + */ + OrderedKeyedVector mMap; +}; + +}; // namespace android + +#endif -- cgit v1.1