Loading camera/ndk/include/camera/NdkCameraMetadataTags.h +1 −1 Original line number Diff line number Diff line Loading @@ -5384,7 +5384,7 @@ typedef enum acamera_metadata_tag { * </ul></p> * * <p>Since optical image stabilization generally involves motion much faster than the duration * of individualq image exposure, multiple OIS samples can be included for a single capture * of individual image exposure, multiple OIS samples can be included for a single capture * result. For example, if the OIS reporting operates at 200 Hz, a typical camera operating * at 30fps may have 6-7 OIS samples per capture result. This information can be combined * with the rolling shutter skew to account for lens motion during image exposure in Loading include/private/media/AudioTrackShared.h +3 −0 Original line number Diff line number Diff line Loading @@ -182,6 +182,7 @@ private: // This is set by AudioTrack.setBufferSizeInFrames(). // A write will not fill the buffer above this limit. volatile uint32_t mBufferSizeInFrames; // effective size of the buffer volatile uint32_t mStartThresholdInFrames; // min frames in buffer to start streaming public: Loading Loading @@ -216,6 +217,8 @@ public: }; size_t frameCount() const { return mFrameCount; } uint32_t getStartThresholdInFrames() const; uint32_t setStartThresholdInFrames(uint32_t startThresholdInFrames); protected: // These refer to shared memory, and are virtual addresses with respect to the current process. Loading media/codec2/sfplugin/Codec2InfoBuilder.cpp +53 −0 Original line number Diff line number Diff line Loading @@ -338,6 +338,59 @@ status_t Codec2InfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) { // parse default XML files parser.parseXmlFilesInSearchDirs(); // The mainline modules for media may optionally include some codec shaping information. // Based on vendor partition SDK, and the brand/product/device information // (expect to be empty in almost always) // { // get build info so we know what file to search // ro.vendor.build.fingerprint std::string fingerprint = base::GetProperty("ro.vendor.build.fingerprint", "brand/product/device:"); ALOGV("property_get for ro.vendor.build.fingerprint == '%s'", fingerprint.c_str()); // ro.vendor.build.version.sdk std::string sdk = base::GetProperty("ro.vendor.build.version.sdk", "0"); ALOGV("property_get for ro.vendor.build.version.sdk == '%s'", sdk.c_str()); std::string brand; std::string product; std::string device; size_t pos1; pos1 = fingerprint.find('/'); if (pos1 != std::string::npos) { brand = fingerprint.substr(0, pos1); size_t pos2 = fingerprint.find('/', pos1+1); if (pos2 != std::string::npos) { product = fingerprint.substr(pos1+1, pos2 - pos1 - 1); size_t pos3 = fingerprint.find('/', pos2+1); if (pos3 != std::string::npos) { device = fingerprint.substr(pos2+1, pos3 - pos2 - 1); size_t pos4 = device.find(':'); if (pos4 != std::string::npos) { device.resize(pos4); } } } } ALOGV("parsed: sdk '%s' brand '%s' product '%s' device '%s'", sdk.c_str(), brand.c_str(), product.c_str(), device.c_str()); std::string base = "/apex/com.android.media/etc/formatshaper"; // looking in these directories within the apex const std::vector<std::string> modulePathnames = { base + "/" + sdk + "/" + brand + "/" + product + "/" + device, base + "/" + sdk + "/" + brand + "/" + product, base + "/" + sdk + "/" + brand, base + "/" + sdk, base }; parser.parseXmlFilesInSearchDirs( { "media_codecs_shaping.xml" }, modulePathnames); } if (parser.getParsingStatus() != OK) { ALOGD("XML parser no good"); return OK; Loading media/libaudioclient/AudioTrack.cpp +56 −0 Original line number Diff line number Diff line Loading @@ -1283,6 +1283,46 @@ ssize_t AudioTrack::setBufferSizeInFrames(size_t bufferSizeInFrames) return finalBufferSize; } ssize_t AudioTrack::getStartThresholdInFrames() const { AutoMutex lock(mLock); if (mOutput == AUDIO_IO_HANDLE_NONE || mProxy.get() == 0) { return NO_INIT; } return (ssize_t) mProxy->getStartThresholdInFrames(); } ssize_t AudioTrack::setStartThresholdInFrames(size_t startThresholdInFrames) { if (startThresholdInFrames > INT32_MAX || startThresholdInFrames == 0) { // contractually we could simply return the current threshold in frames // to indicate the request was ignored, but we return an error here. return BAD_VALUE; } AutoMutex lock(mLock); // We do not permit calling setStartThresholdInFrames() between the AudioTrack // default ctor AudioTrack() and set(...) but rather fail such an attempt. // (To do so would require a cached mOrigStartThresholdInFrames and we may // not have proper validation for the actual set value). if (mOutput == AUDIO_IO_HANDLE_NONE || mProxy.get() == 0) { return NO_INIT; } const uint32_t original = mProxy->getStartThresholdInFrames(); const uint32_t final = mProxy->setStartThresholdInFrames(startThresholdInFrames); if (original != final) { android::mediametrics::LogItem(mMetricsId) .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_SETSTARTTHRESHOLD) .set(AMEDIAMETRICS_PROP_STARTTHRESHOLDFRAMES, (int32_t)final) .record(); if (original > final) { // restart track if it was disabled by audioflinger due to previous underrun // and we reduced the number of frames for the threshold. restartIfDisabled(); } } return final; } status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount) { if (mSharedBuffer == 0 || isOffloadedOrDirect()) { Loading Loading @@ -2602,6 +2642,10 @@ status_t AudioTrack::restoreTrack_l(const char *from) staticPosition = mStaticProxy->getPosition().unsignedValue(); } // save the old startThreshold and framecount const uint32_t originalStartThresholdInFrames = mProxy->getStartThresholdInFrames(); const uint32_t originalFrameCount = mProxy->frameCount(); // See b/74409267. Connecting to a BT A2DP device supporting multiple codecs // causes a lot of churn on the service side, and it can reject starting // playback of a previously created track. May also apply to other cases. Loading Loading @@ -2662,6 +2706,18 @@ retry: return status; }); // restore the original start threshold if different than frameCount. if (originalStartThresholdInFrames != originalFrameCount) { // Note: mProxy->setStartThresholdInFrames() call is in the Proxy // and does not trigger a restart. // (Also CBLK_DISABLED is not set, buffers are empty after track recreation). // Any start would be triggered on the mState == ACTIVE check below. const uint32_t currentThreshold = mProxy->setStartThresholdInFrames(originalStartThresholdInFrames); ALOGD_IF(originalStartThresholdInFrames != currentThreshold, "%s(%d) startThresholdInFrames changing from %u to %u", __func__, mPortId, originalStartThresholdInFrames, currentThreshold); } if (mState == STATE_ACTIVE) { mAudioTrack->start(&result); } Loading media/libaudioclient/AudioTrackShared.cpp +38 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #define LOG_TAG "AudioTrackShared" //#define LOG_NDEBUG 0 #include <atomic> #include <android-base/macros.h> #include <private/media/AudioTrackShared.h> #include <utils/Log.h> Loading @@ -33,6 +34,21 @@ size_t clampToSize(T x) { return sizeof(T) > sizeof(size_t) && x > (T) SIZE_MAX ? SIZE_MAX : x < 0 ? 0 : (size_t) x; } // compile-time safe atomics. TODO: update all methods to use it template <typename T> T android_atomic_load(const volatile T* addr) { static_assert(sizeof(T) == sizeof(std::atomic<T>)); // no extra sync data required. static_assert(std::atomic<T>::is_always_lock_free); // no hash lock somewhere. return atomic_load((std::atomic<T>*)addr); // memory_order_seq_cst } template <typename T> void android_atomic_store(const volatile T* addr, T value) { static_assert(sizeof(T) == sizeof(std::atomic<T>)); // no extra sync data required. static_assert(std::atomic<T>::is_always_lock_free); // no hash lock somewhere. atomic_store((std::atomic<T>*)addr, value); // memory_order_seq_cst } // incrementSequence is used to determine the next sequence value // for the loop and position sequence counters. It should return // a value between "other" + 1 and "other" + INT32_MAX, the choice of Loading @@ -51,6 +67,7 @@ audio_track_cblk_t::audio_track_cblk_t() : mServer(0), mFutex(0), mMinimum(0) , mVolumeLR(GAIN_MINIFLOAT_PACKED_UNITY), mSampleRate(0), mSendLevel(0) , mBufferSizeInFrames(0) , mStartThresholdInFrames(0) // filled in by the server. , mFlags(0) { memset(&u, 0, sizeof(u)); Loading @@ -66,6 +83,26 @@ Proxy::Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t { } uint32_t Proxy::getStartThresholdInFrames() const { const uint32_t startThresholdInFrames = android_atomic_load(&mCblk->mStartThresholdInFrames); if (startThresholdInFrames == 0 || startThresholdInFrames > mFrameCount) { ALOGD("%s: startThresholdInFrames %u not between 1 and frameCount %zu, " "setting to frameCount", __func__, startThresholdInFrames, mFrameCount); return mFrameCount; } return startThresholdInFrames; } uint32_t Proxy::setStartThresholdInFrames(uint32_t startThresholdInFrames) { const uint32_t actual = std::min((size_t)startThresholdInFrames, frameCount()); android_atomic_store(&mCblk->mStartThresholdInFrames, actual); return actual; } // --------------------------------------------------------------------------- ClientProxy::ClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, Loading Loading @@ -663,6 +700,7 @@ ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCo , mTimestampMutator(&cblk->mExtendedTimestampQueue) { cblk->mBufferSizeInFrames = frameCount; cblk->mStartThresholdInFrames = frameCount; } __attribute__((no_sanitize("integer"))) Loading Loading
camera/ndk/include/camera/NdkCameraMetadataTags.h +1 −1 Original line number Diff line number Diff line Loading @@ -5384,7 +5384,7 @@ typedef enum acamera_metadata_tag { * </ul></p> * * <p>Since optical image stabilization generally involves motion much faster than the duration * of individualq image exposure, multiple OIS samples can be included for a single capture * of individual image exposure, multiple OIS samples can be included for a single capture * result. For example, if the OIS reporting operates at 200 Hz, a typical camera operating * at 30fps may have 6-7 OIS samples per capture result. This information can be combined * with the rolling shutter skew to account for lens motion during image exposure in Loading
include/private/media/AudioTrackShared.h +3 −0 Original line number Diff line number Diff line Loading @@ -182,6 +182,7 @@ private: // This is set by AudioTrack.setBufferSizeInFrames(). // A write will not fill the buffer above this limit. volatile uint32_t mBufferSizeInFrames; // effective size of the buffer volatile uint32_t mStartThresholdInFrames; // min frames in buffer to start streaming public: Loading Loading @@ -216,6 +217,8 @@ public: }; size_t frameCount() const { return mFrameCount; } uint32_t getStartThresholdInFrames() const; uint32_t setStartThresholdInFrames(uint32_t startThresholdInFrames); protected: // These refer to shared memory, and are virtual addresses with respect to the current process. Loading
media/codec2/sfplugin/Codec2InfoBuilder.cpp +53 −0 Original line number Diff line number Diff line Loading @@ -338,6 +338,59 @@ status_t Codec2InfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) { // parse default XML files parser.parseXmlFilesInSearchDirs(); // The mainline modules for media may optionally include some codec shaping information. // Based on vendor partition SDK, and the brand/product/device information // (expect to be empty in almost always) // { // get build info so we know what file to search // ro.vendor.build.fingerprint std::string fingerprint = base::GetProperty("ro.vendor.build.fingerprint", "brand/product/device:"); ALOGV("property_get for ro.vendor.build.fingerprint == '%s'", fingerprint.c_str()); // ro.vendor.build.version.sdk std::string sdk = base::GetProperty("ro.vendor.build.version.sdk", "0"); ALOGV("property_get for ro.vendor.build.version.sdk == '%s'", sdk.c_str()); std::string brand; std::string product; std::string device; size_t pos1; pos1 = fingerprint.find('/'); if (pos1 != std::string::npos) { brand = fingerprint.substr(0, pos1); size_t pos2 = fingerprint.find('/', pos1+1); if (pos2 != std::string::npos) { product = fingerprint.substr(pos1+1, pos2 - pos1 - 1); size_t pos3 = fingerprint.find('/', pos2+1); if (pos3 != std::string::npos) { device = fingerprint.substr(pos2+1, pos3 - pos2 - 1); size_t pos4 = device.find(':'); if (pos4 != std::string::npos) { device.resize(pos4); } } } } ALOGV("parsed: sdk '%s' brand '%s' product '%s' device '%s'", sdk.c_str(), brand.c_str(), product.c_str(), device.c_str()); std::string base = "/apex/com.android.media/etc/formatshaper"; // looking in these directories within the apex const std::vector<std::string> modulePathnames = { base + "/" + sdk + "/" + brand + "/" + product + "/" + device, base + "/" + sdk + "/" + brand + "/" + product, base + "/" + sdk + "/" + brand, base + "/" + sdk, base }; parser.parseXmlFilesInSearchDirs( { "media_codecs_shaping.xml" }, modulePathnames); } if (parser.getParsingStatus() != OK) { ALOGD("XML parser no good"); return OK; Loading
media/libaudioclient/AudioTrack.cpp +56 −0 Original line number Diff line number Diff line Loading @@ -1283,6 +1283,46 @@ ssize_t AudioTrack::setBufferSizeInFrames(size_t bufferSizeInFrames) return finalBufferSize; } ssize_t AudioTrack::getStartThresholdInFrames() const { AutoMutex lock(mLock); if (mOutput == AUDIO_IO_HANDLE_NONE || mProxy.get() == 0) { return NO_INIT; } return (ssize_t) mProxy->getStartThresholdInFrames(); } ssize_t AudioTrack::setStartThresholdInFrames(size_t startThresholdInFrames) { if (startThresholdInFrames > INT32_MAX || startThresholdInFrames == 0) { // contractually we could simply return the current threshold in frames // to indicate the request was ignored, but we return an error here. return BAD_VALUE; } AutoMutex lock(mLock); // We do not permit calling setStartThresholdInFrames() between the AudioTrack // default ctor AudioTrack() and set(...) but rather fail such an attempt. // (To do so would require a cached mOrigStartThresholdInFrames and we may // not have proper validation for the actual set value). if (mOutput == AUDIO_IO_HANDLE_NONE || mProxy.get() == 0) { return NO_INIT; } const uint32_t original = mProxy->getStartThresholdInFrames(); const uint32_t final = mProxy->setStartThresholdInFrames(startThresholdInFrames); if (original != final) { android::mediametrics::LogItem(mMetricsId) .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_SETSTARTTHRESHOLD) .set(AMEDIAMETRICS_PROP_STARTTHRESHOLDFRAMES, (int32_t)final) .record(); if (original > final) { // restart track if it was disabled by audioflinger due to previous underrun // and we reduced the number of frames for the threshold. restartIfDisabled(); } } return final; } status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount) { if (mSharedBuffer == 0 || isOffloadedOrDirect()) { Loading Loading @@ -2602,6 +2642,10 @@ status_t AudioTrack::restoreTrack_l(const char *from) staticPosition = mStaticProxy->getPosition().unsignedValue(); } // save the old startThreshold and framecount const uint32_t originalStartThresholdInFrames = mProxy->getStartThresholdInFrames(); const uint32_t originalFrameCount = mProxy->frameCount(); // See b/74409267. Connecting to a BT A2DP device supporting multiple codecs // causes a lot of churn on the service side, and it can reject starting // playback of a previously created track. May also apply to other cases. Loading Loading @@ -2662,6 +2706,18 @@ retry: return status; }); // restore the original start threshold if different than frameCount. if (originalStartThresholdInFrames != originalFrameCount) { // Note: mProxy->setStartThresholdInFrames() call is in the Proxy // and does not trigger a restart. // (Also CBLK_DISABLED is not set, buffers are empty after track recreation). // Any start would be triggered on the mState == ACTIVE check below. const uint32_t currentThreshold = mProxy->setStartThresholdInFrames(originalStartThresholdInFrames); ALOGD_IF(originalStartThresholdInFrames != currentThreshold, "%s(%d) startThresholdInFrames changing from %u to %u", __func__, mPortId, originalStartThresholdInFrames, currentThreshold); } if (mState == STATE_ACTIVE) { mAudioTrack->start(&result); } Loading
media/libaudioclient/AudioTrackShared.cpp +38 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #define LOG_TAG "AudioTrackShared" //#define LOG_NDEBUG 0 #include <atomic> #include <android-base/macros.h> #include <private/media/AudioTrackShared.h> #include <utils/Log.h> Loading @@ -33,6 +34,21 @@ size_t clampToSize(T x) { return sizeof(T) > sizeof(size_t) && x > (T) SIZE_MAX ? SIZE_MAX : x < 0 ? 0 : (size_t) x; } // compile-time safe atomics. TODO: update all methods to use it template <typename T> T android_atomic_load(const volatile T* addr) { static_assert(sizeof(T) == sizeof(std::atomic<T>)); // no extra sync data required. static_assert(std::atomic<T>::is_always_lock_free); // no hash lock somewhere. return atomic_load((std::atomic<T>*)addr); // memory_order_seq_cst } template <typename T> void android_atomic_store(const volatile T* addr, T value) { static_assert(sizeof(T) == sizeof(std::atomic<T>)); // no extra sync data required. static_assert(std::atomic<T>::is_always_lock_free); // no hash lock somewhere. atomic_store((std::atomic<T>*)addr, value); // memory_order_seq_cst } // incrementSequence is used to determine the next sequence value // for the loop and position sequence counters. It should return // a value between "other" + 1 and "other" + INT32_MAX, the choice of Loading @@ -51,6 +67,7 @@ audio_track_cblk_t::audio_track_cblk_t() : mServer(0), mFutex(0), mMinimum(0) , mVolumeLR(GAIN_MINIFLOAT_PACKED_UNITY), mSampleRate(0), mSendLevel(0) , mBufferSizeInFrames(0) , mStartThresholdInFrames(0) // filled in by the server. , mFlags(0) { memset(&u, 0, sizeof(u)); Loading @@ -66,6 +83,26 @@ Proxy::Proxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, size_t { } uint32_t Proxy::getStartThresholdInFrames() const { const uint32_t startThresholdInFrames = android_atomic_load(&mCblk->mStartThresholdInFrames); if (startThresholdInFrames == 0 || startThresholdInFrames > mFrameCount) { ALOGD("%s: startThresholdInFrames %u not between 1 and frameCount %zu, " "setting to frameCount", __func__, startThresholdInFrames, mFrameCount); return mFrameCount; } return startThresholdInFrames; } uint32_t Proxy::setStartThresholdInFrames(uint32_t startThresholdInFrames) { const uint32_t actual = std::min((size_t)startThresholdInFrames, frameCount()); android_atomic_store(&mCblk->mStartThresholdInFrames, actual); return actual; } // --------------------------------------------------------------------------- ClientProxy::ClientProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount, Loading Loading @@ -663,6 +700,7 @@ ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCo , mTimestampMutator(&cblk->mExtendedTimestampQueue) { cblk->mBufferSizeInFrames = frameCount; cblk->mStartThresholdInFrames = frameCount; } __attribute__((no_sanitize("integer"))) Loading