Merge "VT: Rx side of CVO implementation to CCodec."
diff --git a/camera/CameraSessionStats.cpp b/camera/CameraSessionStats.cpp
index 818b4d0..28e037f 100644
--- a/camera/CameraSessionStats.cpp
+++ b/camera/CameraSessionStats.cpp
@@ -94,6 +94,24 @@
return err;
}
+ int histogramType = HISTOGRAM_TYPE_UNKNOWN;
+ if ((err = parcel->readInt32(&histogramType)) != OK) {
+ ALOGE("%s: Failed to read histogram type from parcel", __FUNCTION__);
+ return err;
+ }
+
+ std::vector<float> histogramBins;
+ if ((err = parcel->readFloatVector(&histogramBins)) != OK) {
+ ALOGE("%s: Failed to read histogram bins from parcel", __FUNCTION__);
+ return err;
+ }
+
+ std::vector<int64_t> histogramCounts;
+ if ((err = parcel->readInt64Vector(&histogramCounts)) != OK) {
+ ALOGE("%s: Failed to read histogram counts from parcel", __FUNCTION__);
+ return err;
+ }
+
mWidth = width;
mHeight = height;
mFormat = format;
@@ -104,6 +122,9 @@
mStartLatencyMs = startLatencyMs;
mMaxHalBuffers = maxHalBuffers;
mMaxAppBuffers = maxAppBuffers;
+ mHistogramType = histogramType;
+ mHistogramBins = std::move(histogramBins);
+ mHistogramCounts = std::move(histogramCounts);
return OK;
}
@@ -166,6 +187,21 @@
return err;
}
+ if ((err = parcel->writeInt32(mHistogramType)) != OK) {
+ ALOGE("%s: Failed to write histogram type", __FUNCTION__);
+ return err;
+ }
+
+ if ((err = parcel->writeFloatVector(mHistogramBins)) != OK) {
+ ALOGE("%s: Failed to write histogram bins!", __FUNCTION__);
+ return err;
+ }
+
+ if ((err = parcel->writeInt64Vector(mHistogramCounts)) != OK) {
+ ALOGE("%s: Failed to write histogram counts!", __FUNCTION__);
+ return err;
+ }
+
return OK;
}
diff --git a/camera/include/camera/CameraSessionStats.h b/camera/include/camera/CameraSessionStats.h
index 27a756f..c398aca 100644
--- a/camera/include/camera/CameraSessionStats.h
+++ b/camera/include/camera/CameraSessionStats.h
@@ -27,6 +27,11 @@
*/
class CameraStreamStats : public android::Parcelable {
public:
+ enum HistogramType {
+ HISTOGRAM_TYPE_UNKNOWN = 0,
+ HISTOGRAM_TYPE_CAPTURE_LATENCY = 1,
+ };
+
int mWidth;
int mHeight;
int mFormat;
@@ -45,15 +50,26 @@
int mMaxHalBuffers;
int mMaxAppBuffers;
+ // Histogram type. So far only capture latency histogram is supported.
+ int mHistogramType;
+ // The bounary values separating adjacent histogram bins.
+ // A vector of {h1, h2, h3} represents bins of [0, h1), [h1, h2), [h2, h3),
+ // and [h3, infinity)
+ std::vector<float> mHistogramBins;
+ // The counts for all histogram bins.
+ // size(mHistogramBins) + 1 = size(mHistogramCounts)
+ std::vector<int64_t> mHistogramCounts;
+
CameraStreamStats() :
mWidth(0), mHeight(0), mFormat(0), mDataSpace(0), mUsage(0),
mRequestCount(0), mErrorCount(0), mStartLatencyMs(0),
- mMaxHalBuffers(0), mMaxAppBuffers(0) {}
+ mMaxHalBuffers(0), mMaxAppBuffers(0), mHistogramType(HISTOGRAM_TYPE_UNKNOWN) {}
CameraStreamStats(int width, int height, int format, int dataSpace, int64_t usage,
int maxHalBuffers, int maxAppBuffers)
: mWidth(width), mHeight(height), mFormat(format), mDataSpace(dataSpace),
mUsage(usage), mRequestCount(0), mErrorCount(0), mStartLatencyMs(0),
- mMaxHalBuffers(maxHalBuffers), mMaxAppBuffers(maxAppBuffers) {}
+ mMaxHalBuffers(maxHalBuffers), mMaxAppBuffers(maxAppBuffers),
+ mHistogramType(HISTOGRAM_TYPE_UNKNOWN) {}
virtual status_t readFromParcel(const android::Parcel* parcel) override;
virtual status_t writeToParcel(android::Parcel* parcel) const override;
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 55a32ae..b49ec75 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -51,6 +51,7 @@
"android.hardware.drm@1.1",
"android.hardware.drm@1.2",
"android.hardware.drm@1.3",
+ "android.hardware.drm@1.4",
"libhidlallocatorutils",
"libhidlbase",
],
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index f218041..295c459 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -387,6 +387,7 @@
mPlugin.clear();
mPluginV1_1.clear();
mPluginV1_2.clear();
+ mPluginV1_4.clear();
}
std::vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
@@ -622,6 +623,7 @@
mPlugin = plugin;
mPluginV1_1 = drm::V1_1::IDrmPlugin::castFrom(mPlugin);
mPluginV1_2 = drm::V1_2::IDrmPlugin::castFrom(mPlugin);
+ mPluginV1_4 = drm::V1_4::IDrmPlugin::castFrom(mPlugin);
break;
}
}
@@ -642,6 +644,7 @@
mPlugin.clear();
mPluginV1_1.clear();
mPluginV1_2.clear();
+ mPluginV1_4.clear();
}
}
@@ -1564,4 +1567,22 @@
}
}
+bool DrmHal::requiresSecureDecoder(const char *mime) const {
+ Mutex::Autolock autoLock(mLock);
+ if (mPluginV1_4 == NULL) {
+ return false;
+ }
+ return mPluginV1_4->requiresSecureDecoderDefault(hidl_string(mime));
+}
+
+bool DrmHal::requiresSecureDecoder(const char *mime,
+ DrmPlugin::SecurityLevel securityLevel) const {
+ Mutex::Autolock autoLock(mLock);
+ if (mPluginV1_4 == NULL) {
+ return false;
+ }
+ auto hLevel = toHidlSecurityLevel(securityLevel);
+ return mPluginV1_4->requiresSecureDecoder(hidl_string(mime), hLevel);
+}
+
} // namespace android
diff --git a/drm/libmediadrm/fuzzer/Android.bp b/drm/libmediadrm/fuzzer/Android.bp
index 6f2d054..5e389b4 100644
--- a/drm/libmediadrm/fuzzer/Android.bp
+++ b/drm/libmediadrm/fuzzer/Android.bp
@@ -47,6 +47,7 @@
"android.hardware.drm@1.1",
"android.hardware.drm@1.2",
"android.hardware.drm@1.3",
+ "android.hardware.drm@1.4",
"libhidlallocatorutils",
"libhidlbase",
],
diff --git a/drm/libmediadrm/include/mediadrm/DrmHal.h b/drm/libmediadrm/include/mediadrm/DrmHal.h
index 3b4639b..4705de0 100644
--- a/drm/libmediadrm/include/mediadrm/DrmHal.h
+++ b/drm/libmediadrm/include/mediadrm/DrmHal.h
@@ -25,7 +25,9 @@
#include <android/hardware/drm/1.2/IDrmFactory.h>
#include <android/hardware/drm/1.2/IDrmPlugin.h>
#include <android/hardware/drm/1.2/IDrmPluginListener.h>
+#include <android/hardware/drm/1.4/IDrmPlugin.h>
+#include <media/drm/DrmAPI.h>
#include <mediadrm/DrmMetrics.h>
#include <mediadrm/DrmSessionManager.h>
#include <mediadrm/IDrm.h>
@@ -176,6 +178,12 @@
virtual status_t setListener(const sp<IDrmClient>& listener);
+ virtual bool requiresSecureDecoder(const char *mime) const;
+
+ virtual bool requiresSecureDecoder(
+ const char *mime,
+ DrmPlugin::SecurityLevel securityLevel) const;
+
// Methods of IDrmPluginListener
Return<void> sendEvent(EventType eventType,
const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data);
@@ -202,6 +210,7 @@
sp<IDrmPlugin> mPlugin;
sp<drm::V1_1::IDrmPlugin> mPluginV1_1;
sp<drm::V1_2::IDrmPlugin> mPluginV1_2;
+ sp<drm::V1_4::IDrmPlugin> mPluginV1_4;
String8 mAppPackageName;
// Mutable to allow modification within GetPropertyByteArray.
diff --git a/drm/libmediadrm/include/mediadrm/IDrm.h b/drm/libmediadrm/include/mediadrm/IDrm.h
index 0177c24..c117cec 100644
--- a/drm/libmediadrm/include/mediadrm/IDrm.h
+++ b/drm/libmediadrm/include/mediadrm/IDrm.h
@@ -145,6 +145,13 @@
virtual status_t setListener(const sp<IDrmClient>& listener) = 0;
+ virtual bool requiresSecureDecoder(
+ const char *mime) const = 0;
+
+ virtual bool requiresSecureDecoder(
+ const char *mime,
+ DrmPlugin::SecurityLevel securityLevel) const = 0;
+
protected:
IDrm() {}
diff --git a/media/codec2/components/aac/C2SoftAacDec.cpp b/media/codec2/components/aac/C2SoftAacDec.cpp
index 677f316..f3341ab 100644
--- a/media/codec2/components/aac/C2SoftAacDec.cpp
+++ b/media/codec2/components/aac/C2SoftAacDec.cpp
@@ -1061,11 +1061,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftAacDecFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/aac/C2SoftAacEnc.cpp b/media/codec2/components/aac/C2SoftAacEnc.cpp
index 2e85915..ea76cbb 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.cpp
+++ b/media/codec2/components/aac/C2SoftAacEnc.cpp
@@ -692,11 +692,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftAacEncFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp b/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp
index f7943be..c08e02b 100644
--- a/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrDec.cpp
@@ -420,11 +420,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftAMRDecFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp b/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp
index e2d8cb6..bb63e1f 100644
--- a/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrNbEnc.cpp
@@ -337,11 +337,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftAmrNbEncFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp b/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp
index 84ae4b7..84728ae 100644
--- a/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp
+++ b/media/codec2/components/amr_nb_wb/C2SoftAmrWbEnc.cpp
@@ -411,11 +411,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftAmrWbEncFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/aom/C2SoftAomDec.cpp b/media/codec2/components/aom/C2SoftAomDec.cpp
index 9ba3b697..c08cd59 100644
--- a/media/codec2/components/aom/C2SoftAomDec.cpp
+++ b/media/codec2/components/aom/C2SoftAomDec.cpp
@@ -800,11 +800,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftAomFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/avc/Android.bp b/media/codec2/components/avc/Android.bp
index 6b0e363..9f8bc68 100644
--- a/media/codec2/components/avc/Android.bp
+++ b/media/codec2/components/avc/Android.bp
@@ -3,7 +3,8 @@
defaults: [
"libcodec2_soft-defaults",
"libcodec2_soft_sanitize_signed-defaults",
- ],
+ "libcodec2_soft_sanitize_cfi-defaults",
+ ],
static_libs: ["libavcdec"],
@@ -20,7 +21,8 @@
defaults: [
"libcodec2_soft-defaults",
"libcodec2_soft_sanitize_signed-defaults",
- ],
+ "libcodec2_soft_sanitize_cfi-defaults",
+ ],
static_libs: ["libavcenc"],
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index 3afd670..0207311 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -1049,11 +1049,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftAvcDecFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index ab93ce3..cfaeb66 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -1756,11 +1756,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftAvcEncFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/base/Android.bp b/media/codec2/components/base/Android.bp
index 3712564..cfdb9e7 100644
--- a/media/codec2/components/base/Android.bp
+++ b/media/codec2/components/base/Android.bp
@@ -20,7 +20,7 @@
shared_libs: [
"libcutils", // for properties
- "liblog", // for ALOG
+ "liblog", // for ALOG
"libsfplugin_ccodec_utils", // for ImageCopy
"libstagefright_foundation", // for Mutexed
],
@@ -38,7 +38,7 @@
filegroup {
name: "codec2_soft_exports",
- srcs: [ "exports.lds" ],
+ srcs: ["exports.lds"],
}
// public dependency for software codec implementation
@@ -91,7 +91,17 @@
misc_undefined: [
"signed-integer-overflow",
],
+ },
+}
+
+cc_defaults {
+ name: "libcodec2_soft_sanitize_cfi-defaults",
+
+ sanitize: {
cfi: true,
+ config: {
+ cfi_assembly_support: true,
+ },
},
}
@@ -131,4 +141,3 @@
ldflags: ["-Wl,-Bsymbolic"],
}
-
diff --git a/media/codec2/components/flac/C2SoftFlacDec.cpp b/media/codec2/components/flac/C2SoftFlacDec.cpp
index 4039b9b..e70c289 100644
--- a/media/codec2/components/flac/C2SoftFlacDec.cpp
+++ b/media/codec2/components/flac/C2SoftFlacDec.cpp
@@ -367,11 +367,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftFlacDecFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/flac/C2SoftFlacEnc.cpp b/media/codec2/components/flac/C2SoftFlacEnc.cpp
index 72910c5..6fead3a 100644
--- a/media/codec2/components/flac/C2SoftFlacEnc.cpp
+++ b/media/codec2/components/flac/C2SoftFlacEnc.cpp
@@ -482,11 +482,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftFlacEncFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/g711/C2SoftG711Dec.cpp b/media/codec2/components/g711/C2SoftG711Dec.cpp
index 7f9c34e..f9299af 100644
--- a/media/codec2/components/g711/C2SoftG711Dec.cpp
+++ b/media/codec2/components/g711/C2SoftG711Dec.cpp
@@ -259,11 +259,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftG711DecFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index a1929e7..76345ae 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -770,11 +770,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory *CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftGav1Factory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory *factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/gsm/C2SoftGsmDec.cpp b/media/codec2/components/gsm/C2SoftGsmDec.cpp
index 287cfc6..977677d 100644
--- a/media/codec2/components/gsm/C2SoftGsmDec.cpp
+++ b/media/codec2/components/gsm/C2SoftGsmDec.cpp
@@ -294,11 +294,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftGSMDecFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/hevc/Android.bp b/media/codec2/components/hevc/Android.bp
index 2858212..1be0cfc 100644
--- a/media/codec2/components/hevc/Android.bp
+++ b/media/codec2/components/hevc/Android.bp
@@ -3,6 +3,7 @@
defaults: [
"libcodec2_soft-defaults",
"libcodec2_soft_sanitize_signed-defaults",
+ "libcodec2_soft_sanitize_cfi-defaults",
],
srcs: ["C2SoftHevcDec.cpp"],
@@ -16,6 +17,7 @@
defaults: [
"libcodec2_soft-defaults",
"libcodec2_soft_sanitize_signed-defaults",
+ "libcodec2_soft_sanitize_cfi-defaults",
],
srcs: ["C2SoftHevcEnc.cpp"],
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
index 23104dc..56dd26b 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -1048,11 +1048,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftHevcDecFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index c2d2540..436a2c4 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -1078,11 +1078,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftHevcEncFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/mp3/C2SoftMp3Dec.cpp b/media/codec2/components/mp3/C2SoftMp3Dec.cpp
index 5ba7e3d..7137767 100644
--- a/media/codec2/components/mp3/C2SoftMp3Dec.cpp
+++ b/media/codec2/components/mp3/C2SoftMp3Dec.cpp
@@ -539,11 +539,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftMp3DecFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
index 55dd475..82c061a 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
@@ -1113,11 +1113,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftMpeg2DecFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
index 13cc0ec..a7cc037 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp
@@ -747,11 +747,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftMpeg4DecFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
index 54c8c47..e1cc6b3 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
@@ -652,11 +652,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftMpeg4EncFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/opus/C2SoftOpusDec.cpp b/media/codec2/components/opus/C2SoftOpusDec.cpp
index b7c1556..d4987c0 100644
--- a/media/codec2/components/opus/C2SoftOpusDec.cpp
+++ b/media/codec2/components/opus/C2SoftOpusDec.cpp
@@ -473,11 +473,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftOpusDecFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.cpp b/media/codec2/components/opus/C2SoftOpusEnc.cpp
index 70d1965..b47275f 100644
--- a/media/codec2/components/opus/C2SoftOpusEnc.cpp
+++ b/media/codec2/components/opus/C2SoftOpusEnc.cpp
@@ -626,11 +626,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftOpusEncFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/raw/C2SoftRawDec.cpp b/media/codec2/components/raw/C2SoftRawDec.cpp
index 7b6f21a..31ca705 100644
--- a/media/codec2/components/raw/C2SoftRawDec.cpp
+++ b/media/codec2/components/raw/C2SoftRawDec.cpp
@@ -215,11 +215,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftRawDecFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/vorbis/C2SoftVorbisDec.cpp b/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
index d3b6e31..899fe9b 100644
--- a/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
+++ b/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
@@ -359,10 +359,6 @@
}
memcpy(&numPageFrames, data + inSize - sizeof(numPageFrames), sizeof(numPageFrames));
inSize -= sizeof(numPageFrames);
- if (inSize == 0) {
- // empty buffer, ignore
- return;
- }
if (numPageFrames >= 0) {
mNumFramesLeftOnPage = numPageFrames;
}
@@ -413,7 +409,7 @@
mState, reinterpret_cast<int16_t *> (wView.data()),
kMaxNumSamplesPerChannel);
if (numFrames < 0) {
- ALOGD("vorbis_dsp_pcmout returned %d frames", numFrames);
+ ALOGD("vorbis_dsp_pcmout returned %d", numFrames);
numFrames = 0;
}
}
@@ -481,11 +477,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftVorbisDecFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/vpx/C2SoftVp8Enc.cpp b/media/codec2/components/vpx/C2SoftVp8Enc.cpp
index f18f5d0..049ec38 100644
--- a/media/codec2/components/vpx/C2SoftVp8Enc.cpp
+++ b/media/codec2/components/vpx/C2SoftVp8Enc.cpp
@@ -101,11 +101,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftVp8EncFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/vpx/C2SoftVp9Enc.cpp b/media/codec2/components/vpx/C2SoftVp9Enc.cpp
index 740dbda..6401521 100644
--- a/media/codec2/components/vpx/C2SoftVp9Enc.cpp
+++ b/media/codec2/components/vpx/C2SoftVp9Enc.cpp
@@ -131,11 +131,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftVp9EncFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.cpp b/media/codec2/components/vpx/C2SoftVpxDec.cpp
index 91238e8..2953d90 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxDec.cpp
@@ -948,11 +948,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftVpxFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/components/xaac/Android.bp b/media/codec2/components/xaac/Android.bp
index 4889d78..9b7e2de 100644
--- a/media/codec2/components/xaac/Android.bp
+++ b/media/codec2/components/xaac/Android.bp
@@ -3,6 +3,7 @@
defaults: [
"libcodec2_soft-defaults",
"libcodec2_soft_sanitize_all-defaults",
+ "libcodec2_soft_sanitize_cfi-defaults",
],
srcs: ["C2SoftXaacDec.cpp"],
diff --git a/media/codec2/components/xaac/C2SoftXaacDec.cpp b/media/codec2/components/xaac/C2SoftXaacDec.cpp
index 951d058..6deafda 100644
--- a/media/codec2/components/xaac/C2SoftXaacDec.cpp
+++ b/media/codec2/components/xaac/C2SoftXaacDec.cpp
@@ -1600,11 +1600,13 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
ALOGV("in %s", __func__);
return new ::android::C2SoftXaacDecFactory();
}
+__attribute__((cfi_canonical_jump_table))
extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
ALOGV("in %s", __func__);
delete factory;
diff --git a/media/codec2/fuzzer/Android.bp b/media/codec2/fuzzer/Android.bp
new file mode 100644
index 0000000..2de400d
--- /dev/null
+++ b/media/codec2/fuzzer/Android.bp
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_defaults {
+ name: "C2Fuzzer-defaults",
+
+ srcs: [
+ "C2Fuzzer.cpp",
+ ],
+
+ static_libs: [
+ "liblog",
+ "libion",
+ "libfmq",
+ "libbase",
+ "libutils",
+ "libcutils",
+ "libcodec2",
+ "libhidlbase",
+ "libdmabufheap",
+ "libcodec2_vndk",
+ "libnativewindow",
+ "libcodec2_soft_common",
+ "libsfplugin_ccodec_utils",
+ "libstagefright_foundation",
+ "libstagefright_bufferpool@2.0.1",
+ "android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@3.0",
+ "android.hardware.media.bufferpool@2.0",
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.allocator@3.0",
+ "android.hardware.graphics.bufferqueue@2.0",
+ ],
+
+ shared_libs: [
+ "libui",
+ "libdl",
+ "libbinder",
+ "libhardware",
+ "libvndksupport",
+ "libprocessgroup",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerAvcDec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.avc.decoder\"",
+ ],
+
+ static_libs: [
+ "libavcdec",
+ "libcodec2_soft_avcdec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerHevcDec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.hevc.decoder\"",
+ ],
+
+ static_libs: [
+ "libhevcdec",
+ "libcodec2_soft_hevcdec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerMpeg2Dec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.mpeg2.decoder\"",
+ ],
+
+ static_libs: [
+ "libmpeg2dec",
+ "libcodec2_soft_mpeg2dec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerMpeg4Dec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.mpeg4.decoder\"",
+ ],
+
+ static_libs: [
+ "libstagefright_m4vh263dec",
+ "libcodec2_soft_mpeg4dec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerH263Dec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.h263.decoder\"",
+ ],
+
+ static_libs: [
+ "libstagefright_m4vh263dec",
+ "libcodec2_soft_h263dec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerVp8Dec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.vp8.decoder\"",
+ ],
+
+ static_libs: [
+ "libvpx",
+ "libcodec2_soft_vp8dec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerVp9Dec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.vp9.decoder\"",
+ ],
+
+ static_libs: [
+ "libvpx",
+ "libcodec2_soft_vp9dec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerAacDec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.aac.decoder\"",
+ ],
+
+ static_libs: [
+ "libFraunhoferAAC",
+ "libcodec2_soft_aacdec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerAmrnbDec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.amrnb.decoder\"",
+ ],
+
+ static_libs: [
+ "libstagefright_amrnbdec",
+ "libstagefright_amrwbdec",
+ "libstagefright_amrnb_common",
+ "libcodec2_soft_amrnbdec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerAmrwbDec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.amrwb.decoder\"",
+ ],
+
+ static_libs: [
+ "libstagefright_amrnbdec",
+ "libstagefright_amrwbdec",
+ "libstagefright_amrnb_common",
+ "libcodec2_soft_amrwbdec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerFlacDec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.flac.decoder\"",
+ ],
+
+ static_libs: [
+ "libFLAC",
+ "libstagefright_flacdec",
+ "libcodec2_soft_flacdec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerG711AlawDec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.g711.alaw.decoder\"",
+ ],
+
+ static_libs: [
+ "codecs_g711dec",
+ "libcodec2_soft_g711alawdec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerG711MlawDec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.g711.mlaw.decoder\"",
+ ],
+
+ static_libs: [
+ "codecs_g711dec",
+ "libcodec2_soft_g711mlawdec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerGsmDec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.gsm.decoder\"",
+ ],
+
+ static_libs: [
+ "libgsm",
+ "libcodec2_soft_gsmdec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerMp3Dec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.mp3.decoder\"",
+ ],
+
+ static_libs: [
+ "libstagefright_mp3dec",
+ "libcodec2_soft_mp3dec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerOpusDec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.opus.decoder\"",
+ ],
+
+ static_libs: [
+ "libopus",
+ "libcodec2_soft_opusdec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerRawDec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.raw.decoder\"",
+ ],
+
+ static_libs: [
+ "libcodec2_soft_rawdec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerVorbisDec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.vorbis.decoder\"",
+ ],
+
+ static_libs: [
+ "libvorbisidec",
+ "libcodec2_soft_vorbisdec",
+ ],
+}
+
+cc_fuzz {
+ name: "C2FuzzerXaacDec",
+ defaults: ["C2Fuzzer-defaults"],
+
+ cflags: [
+ "-DC2COMPONENTNAME=\"c2.android.xaac.decoder\"",
+ ],
+
+ static_libs: [
+ "libxaacdec",
+ "libcodec2_soft_xaacdec",
+ ],
+}
diff --git a/media/codec2/fuzzer/C2Fuzzer.cpp b/media/codec2/fuzzer/C2Fuzzer.cpp
new file mode 100644
index 0000000..71956a2
--- /dev/null
+++ b/media/codec2/fuzzer/C2Fuzzer.cpp
@@ -0,0 +1,318 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#include <stdio.h>
+
+#include <C2Fuzzer.h>
+
+using namespace android;
+
+class LinearBuffer : public C2Buffer {
+ public:
+ explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block)
+ : C2Buffer({block->share(block->offset(), block->size(), ::C2Fence())}) {}
+
+ explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block, size_t size)
+ : C2Buffer({block->share(block->offset(), size, ::C2Fence())}) {}
+};
+
+/**
+ * Handle Callback functions onWorkDone_nb(), onTripped_nb(), onError_nb() for C2 Components
+ */
+struct CodecListener : public C2Component::Listener {
+ public:
+ CodecListener(const std::function<void(std::weak_ptr<C2Component> comp,
+ std::list<std::unique_ptr<C2Work>>& workItems)>
+ fn = nullptr)
+ : callBack(fn) {}
+ virtual void onWorkDone_nb(const std::weak_ptr<C2Component> comp,
+ std::list<std::unique_ptr<C2Work>> workItems) {
+ if (callBack) {
+ callBack(comp, workItems);
+ }
+ }
+
+ virtual void onTripped_nb(const std::weak_ptr<C2Component> comp,
+ const std::vector<std::shared_ptr<C2SettingResult>> settingResults) {
+ (void)comp;
+ (void)settingResults;
+ }
+
+ virtual void onError_nb(const std::weak_ptr<C2Component> comp, uint32_t errorCode) {
+ (void)comp;
+ (void)errorCode;
+ }
+
+ std::function<void(std::weak_ptr<C2Component> comp,
+ std::list<std::unique_ptr<C2Work>>& workItems)> callBack;
+};
+
+/**
+ * Buffer source implementations to identify a frame and its size
+ */
+bool Codec2Fuzzer::BufferSource::searchForMarker() {
+ while (true) {
+ if (isMarker()) {
+ return true;
+ }
+ --mReadIndex;
+ if (mReadIndex > mSize) {
+ break;
+ }
+ }
+ return false;
+}
+
+void Codec2Fuzzer::BufferSource::parse() {
+ bool isFrameAvailable = true;
+ size_t bytesRemaining = mSize;
+ while (isFrameAvailable) {
+ isFrameAvailable = searchForMarker();
+ if (isFrameAvailable) {
+ size_t location = mReadIndex + kMarkerSize;
+ bool isCSD = isCSDMarker(location);
+ location += kMarkerSuffixSize;
+ uint8_t* framePtr = const_cast<uint8_t*>(&mData[location]);
+ size_t frameSize = bytesRemaining - location;
+ uint32_t flags = 0;
+ if (mFrameList.empty()) {
+ flags |= C2FrameData::FLAG_END_OF_STREAM;
+ } else if (isCSD) {
+ flags |= C2FrameData::FLAG_CODEC_CONFIG;
+ }
+ mFrameList.emplace_back(std::make_tuple(framePtr, frameSize, flags));
+ bytesRemaining -= (frameSize + kMarkerSize + kMarkerSuffixSize);
+ --mReadIndex;
+ }
+ }
+ if (mFrameList.empty()) {
+ /**
+ * Scenario where input data does not contain the custom frame markers.
+ * Hence feed the entire data as single frame.
+ */
+ mFrameList.emplace_back(
+ std::make_tuple(const_cast<uint8_t*>(mData), 0, C2FrameData::FLAG_END_OF_STREAM));
+ mFrameList.emplace_back(
+ std::make_tuple(const_cast<uint8_t*>(mData), mSize, C2FrameData::FLAG_CODEC_CONFIG));
+ }
+}
+
+FrameData Codec2Fuzzer::BufferSource::getFrame() {
+ FrameData frame = mFrameList.back();
+ mFrameList.pop_back();
+ return frame;
+}
+
+void Codec2Fuzzer::handleWorkDone(std::weak_ptr<C2Component> comp,
+ std::list<std::unique_ptr<C2Work>>& workItems) {
+ (void)comp;
+ for (std::unique_ptr<C2Work>& work : workItems) {
+ if (!work->worklets.empty()) {
+ if (work->worklets.front()->output.flags != C2FrameData::FLAG_INCOMPLETE) {
+ mEos = (work->worklets.front()->output.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
+ work->input.buffers.clear();
+ work->worklets.clear();
+ {
+ std::unique_lock<std::mutex> lock(mQueueLock);
+ mWorkQueue.push_back(std::move(work));
+ mQueueCondition.notify_all();
+ }
+ if (mEos) {
+ {
+ std::lock_guard<std::mutex> waitForDecodeComplete(mDecodeCompleteMutex);
+ }
+ mConditionalVariable.notify_one();
+ }
+ }
+ }
+ }
+}
+
+bool Codec2Fuzzer::initDecoder() {
+ std::vector<std::tuple<C2String, C2ComponentFactory::CreateCodec2FactoryFunc,
+ C2ComponentFactory::DestroyCodec2FactoryFunc>> codec2FactoryFunc;
+
+ codec2FactoryFunc.emplace_back(std::make_tuple(C2COMPONENTNAME,
+ &CreateCodec2Factory,
+ &DestroyCodec2Factory));
+
+ std::shared_ptr<C2ComponentStore> componentStore = GetTestComponentStore(codec2FactoryFunc);
+ if (!componentStore) {
+ return false;
+ }
+
+ std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
+ if (!allocatorStore) {
+ return false;
+ }
+
+ c2_status_t status =
+ allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mLinearAllocator);
+ if (status != C2_OK) {
+ return false;
+ }
+
+ mLinearPool = std::make_shared<C2PooledBlockPool>(mLinearAllocator, ++mBlockPoolId);
+ if (!mLinearPool) {
+ return false;
+ }
+
+ for (int32_t i = 0; i < kNumberOfC2WorkItems; ++i) {
+ mWorkQueue.emplace_back(new C2Work);
+ }
+
+ status = componentStore->createComponent(C2COMPONENTNAME, &mComponent);
+ if (status != C2_OK) {
+ return false;
+ }
+
+ status = componentStore->createInterface(C2COMPONENTNAME, &mInterface);
+ if (status != C2_OK) {
+ return false;
+ }
+
+ C2ComponentKindSetting kind;
+ C2ComponentDomainSetting domain;
+ status = mInterface->query_vb({&kind, &domain}, {}, C2_MAY_BLOCK, nullptr);
+ if (status != C2_OK) {
+ return false;
+ }
+
+ std::vector<C2Param*> configParams;
+ if (domain.value == DOMAIN_VIDEO) {
+ C2StreamPictureSizeInfo::input inputSize(0u, kWidthOfVideo, kHeightOfVideo);
+ configParams.push_back(&inputSize);
+ } else if (domain.value == DOMAIN_AUDIO) {
+ C2StreamSampleRateInfo::output sampleRateInfo(0u, kSamplingRateOfAudio);
+ C2StreamChannelCountInfo::output channelCountInfo(0u, kChannelsOfAudio);
+ configParams.push_back(&sampleRateInfo);
+ configParams.push_back(&channelCountInfo);
+ }
+
+ mListener.reset(new CodecListener(
+ [this](std::weak_ptr<C2Component> comp, std::list<std::unique_ptr<C2Work>>& workItems) {
+ handleWorkDone(comp, workItems);
+ }));
+ if (!mListener) {
+ return false;
+ }
+
+ status = mComponent->setListener_vb(mListener, C2_DONT_BLOCK);
+ if (status != C2_OK) {
+ return false;
+ }
+
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ componentStore->config_sm(configParams, &failures);
+ if (failures.size() != 0) {
+ return false;
+ }
+
+ status = mComponent->start();
+ if (status != C2_OK) {
+ return false;
+ }
+
+ return true;
+}
+
+void Codec2Fuzzer::deInitDecoder() {
+ mComponent->stop();
+ mComponent->reset();
+ mComponent->release();
+ mComponent = nullptr;
+}
+
+void Codec2Fuzzer::decodeFrames(const uint8_t* data, size_t size) {
+ mBufferSource = new BufferSource(data, size);
+ if (!mBufferSource) {
+ return;
+ }
+ mBufferSource->parse();
+ c2_status_t status = C2_OK;
+ size_t numFrames = 0;
+ while (!mBufferSource->isEos()) {
+ uint8_t* frame = nullptr;
+ size_t frameSize = 0;
+ FrameData frameData = mBufferSource->getFrame();
+ frame = std::get<0>(frameData);
+ frameSize = std::get<1>(frameData);
+
+ std::unique_ptr<C2Work> work;
+ {
+ std::unique_lock<std::mutex> lock(mQueueLock);
+ if (mWorkQueue.empty()) mQueueCondition.wait_for(lock, kC2FuzzerTimeOut);
+ if (!mWorkQueue.empty()) {
+ work.swap(mWorkQueue.front());
+ mWorkQueue.pop_front();
+ } else {
+ return;
+ }
+ }
+
+ work->input.flags = (C2FrameData::flags_t)std::get<2>(frameData);
+ work->input.ordinal.timestamp = 0;
+ work->input.ordinal.frameIndex = ++numFrames;
+ work->input.buffers.clear();
+ int32_t alignedSize = C2FUZZER_ALIGN(frameSize, PAGE_SIZE);
+
+ std::shared_ptr<C2LinearBlock> block;
+ status = mLinearPool->fetchLinearBlock(
+ alignedSize, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block);
+ if (status != C2_OK || block == nullptr) {
+ return;
+ }
+
+ C2WriteView view = block->map().get();
+ if (view.error() != C2_OK) {
+ return;
+ }
+ memcpy(view.base(), frame, frameSize);
+ work->input.buffers.emplace_back(new LinearBuffer(block, frameSize));
+ work->worklets.clear();
+ work->worklets.emplace_back(new C2Worklet);
+
+ std::list<std::unique_ptr<C2Work>> items;
+ items.push_back(std::move(work));
+ status = mComponent->queue_nb(&items);
+ if (status != C2_OK) {
+ return;
+ }
+ }
+ std::unique_lock<std::mutex> waitForDecodeComplete(mDecodeCompleteMutex);
+ mConditionalVariable.wait_for(waitForDecodeComplete, kC2FuzzerTimeOut, [this] { return mEos; });
+ std::list<std::unique_ptr<C2Work>> c2flushedWorks;
+ mComponent->flush_sm(C2Component::FLUSH_COMPONENT, &c2flushedWorks);
+ delete mBufferSource;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if (size < 1) {
+ return 0;
+ }
+ Codec2Fuzzer* codec = new Codec2Fuzzer();
+ if (!codec) {
+ return 0;
+ }
+ if (codec->initDecoder()) {
+ codec->decodeFrames(data, size);
+ }
+ delete codec;
+ return 0;
+}
diff --git a/media/codec2/fuzzer/C2Fuzzer.h b/media/codec2/fuzzer/C2Fuzzer.h
new file mode 100644
index 0000000..2efad50
--- /dev/null
+++ b/media/codec2/fuzzer/C2Fuzzer.h
@@ -0,0 +1,114 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#ifndef __C2FUZZER_H__
+#define __C2FUZZER_H__
+
+#include <C2AllocatorIon.h>
+#include <C2Buffer.h>
+#include <C2BufferPriv.h>
+#include <C2Component.h>
+#include <C2Config.h>
+#include <C2PlatformSupport.h>
+
+using namespace std::chrono_literals;
+
+extern "C" ::C2ComponentFactory* CreateCodec2Factory();
+extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory);
+
+namespace android {
+
+#define C2FUZZER_ALIGN(_sz, _align) (((_sz) + ((_align)-1)) & ~((_align)-1))
+
+constexpr std::chrono::milliseconds kC2FuzzerTimeOut = 5000ms;
+constexpr int32_t kNumberOfC2WorkItems = 8;
+constexpr uint32_t kWidthOfVideo = 3840;
+constexpr uint32_t kHeightOfVideo = 2160;
+constexpr uint32_t kSamplingRateOfAudio = 48000;
+constexpr uint32_t kChannelsOfAudio = 8;
+
+typedef std::tuple<uint8_t*, size_t, uint32_t> FrameData;
+
+class Codec2Fuzzer {
+ public:
+ Codec2Fuzzer() = default;
+ ~Codec2Fuzzer() { deInitDecoder(); }
+ bool initDecoder();
+ void deInitDecoder();
+ void decodeFrames(const uint8_t* data, size_t size);
+
+ void handleWorkDone(std::weak_ptr<C2Component> comp,
+ std::list<std::unique_ptr<C2Work>>& workItems);
+
+ private:
+ class BufferSource {
+ public:
+ BufferSource(const uint8_t* data, size_t size)
+ : mData(data), mSize(size), mReadIndex(size - kMarkerSize) {}
+ ~BufferSource() {
+ mData = nullptr;
+ mSize = 0;
+ mReadIndex = 0;
+ mFrameList.clear();
+ }
+ bool isEos() { return mFrameList.empty(); }
+ void parse();
+ FrameData getFrame();
+
+ private:
+ bool isMarker() { return (memcmp(&mData[mReadIndex], kMarker, kMarkerSize) == 0); }
+
+ bool isCSDMarker(size_t position) {
+ return (memcmp(&mData[position], kCsdMarkerSuffix, kMarkerSuffixSize) == 0);
+ }
+
+ bool searchForMarker();
+
+ const uint8_t* mData = nullptr;
+ size_t mSize = 0;
+ size_t mReadIndex = 0;
+ std::vector<FrameData> mFrameList;
+ static constexpr uint8_t kMarker[] = "_MARK";
+ static constexpr uint8_t kCsdMarkerSuffix[] = "_H_";
+ static constexpr uint8_t kFrameMarkerSuffix[] = "_F_";
+ // All markers should be 5 bytes long ( sizeof '_MARK' which is 5)
+ static constexpr size_t kMarkerSize = (sizeof(kMarker) - 1);
+ // All marker types should be 3 bytes long ('_H_', '_F_')
+ static constexpr size_t kMarkerSuffixSize = 3;
+ };
+
+ BufferSource* mBufferSource;
+ bool mEos = false;
+ C2BlockPool::local_id_t mBlockPoolId;
+
+ std::shared_ptr<C2BlockPool> mLinearPool;
+ std::shared_ptr<C2Allocator> mLinearAllocator;
+ std::shared_ptr<C2Component::Listener> mListener;
+ std::shared_ptr<C2Component> mComponent;
+ std::shared_ptr<C2ComponentInterface> mInterface;
+ std::mutex mQueueLock;
+ std::condition_variable mQueueCondition;
+ std::list<std::unique_ptr<C2Work>> mWorkQueue;
+ std::mutex mDecodeCompleteMutex;
+ std::condition_variable mConditionalVariable;
+};
+
+} // namespace android
+
+#endif // __C2FUZZER_H__
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index a9c72fb..c697b80 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -1316,54 +1316,30 @@
return a.capacity < b.capacity;
});
- {
- Mutexed<std::list<sp<ABuffer>>>::Locked configs(mFlushedConfigs);
- if (!configs->empty()) {
- while (!configs->empty()) {
- sp<ABuffer> config = configs->front();
- configs->pop_front();
- // Find the smallest input buffer that can fit the config.
- auto i = std::find_if(
- clientInputBuffers.begin(),
- clientInputBuffers.end(),
- [cfgSize = config->size()](const ClientInputBuffer& b) {
- return b.capacity >= cfgSize;
- });
- if (i == clientInputBuffers.end()) {
- ALOGW("[%s] no input buffer large enough for the config "
- "(%zu bytes)",
- mName, config->size());
- return NO_MEMORY;
- }
- sp<MediaCodecBuffer> buffer = i->buffer;
- memcpy(buffer->base(), config->data(), config->size());
- buffer->setRange(0, config->size());
- buffer->meta()->clear();
- buffer->meta()->setInt64("timeUs", 0);
- buffer->meta()->setInt32("csd", 1);
- if (queueInputBufferInternal(buffer) != OK) {
- ALOGW("[%s] Error while queueing a flushed config",
- mName);
- return UNKNOWN_ERROR;
- }
- clientInputBuffers.erase(i);
- }
- } else if (oStreamFormat.value == C2BufferData::LINEAR &&
- (!prepend || prepend.value == PREPEND_HEADER_TO_NONE)) {
- sp<MediaCodecBuffer> buffer = clientInputBuffers.front().buffer;
- // WORKAROUND: Some apps expect CSD available without queueing
- // any input. Queue an empty buffer to get the CSD.
- buffer->setRange(0, 0);
- buffer->meta()->clear();
- buffer->meta()->setInt64("timeUs", 0);
- if (queueInputBufferInternal(buffer) != OK) {
- ALOGW("[%s] Error while queueing an empty buffer to get CSD",
- mName);
- return UNKNOWN_ERROR;
- }
- clientInputBuffers.pop_front();
+ std::list<std::unique_ptr<C2Work>> flushedConfigs;
+ mFlushedConfigs.lock()->swap(flushedConfigs);
+ if (!flushedConfigs.empty()) {
+ err = mComponent->queue(&flushedConfigs);
+ if (err != C2_OK) {
+ ALOGW("[%s] Error while queueing a flushed config", mName);
+ return UNKNOWN_ERROR;
}
}
+ if (oStreamFormat.value == C2BufferData::LINEAR &&
+ (!prepend || prepend.value == PREPEND_HEADER_TO_NONE)) {
+ sp<MediaCodecBuffer> buffer = clientInputBuffers.front().buffer;
+ // WORKAROUND: Some apps expect CSD available without queueing
+ // any input. Queue an empty buffer to get the CSD.
+ buffer->setRange(0, 0);
+ buffer->meta()->clear();
+ buffer->meta()->setInt64("timeUs", 0);
+ if (queueInputBufferInternal(buffer) != OK) {
+ ALOGW("[%s] Error while queueing an empty buffer to get CSD",
+ mName);
+ return UNKNOWN_ERROR;
+ }
+ clientInputBuffers.pop_front();
+ }
for (const ClientInputBuffer& clientInputBuffer: clientInputBuffers) {
mCallback->onInputBufferAvailable(
@@ -1412,28 +1388,36 @@
void CCodecBufferChannel::flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) {
ALOGV("[%s] flush", mName);
- {
- Mutexed<std::list<sp<ABuffer>>>::Locked configs(mFlushedConfigs);
- for (const std::unique_ptr<C2Work> &work : flushedWork) {
- if (!(work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) {
- continue;
- }
- if (work->input.buffers.empty()
- || work->input.buffers.front() == nullptr
- || work->input.buffers.front()->data().linearBlocks().empty()) {
- ALOGD("[%s] no linear codec config data found", mName);
- continue;
- }
- C2ReadView view =
- work->input.buffers.front()->data().linearBlocks().front().map().get();
- if (view.error() != C2_OK) {
- ALOGD("[%s] failed to map flushed codec config data: %d", mName, view.error());
- continue;
- }
- configs->push_back(ABuffer::CreateAsCopy(view.data(), view.capacity()));
- ALOGV("[%s] stashed flushed codec config data (size=%u)", mName, view.capacity());
+ std::list<std::unique_ptr<C2Work>> configs;
+ for (const std::unique_ptr<C2Work> &work : flushedWork) {
+ if (!(work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) {
+ continue;
}
+ if (work->input.buffers.empty()
+ || work->input.buffers.front() == nullptr
+ || work->input.buffers.front()->data().linearBlocks().empty()) {
+ ALOGD("[%s] no linear codec config data found", mName);
+ continue;
+ }
+ std::unique_ptr<C2Work> copy(new C2Work);
+ copy->input.flags = C2FrameData::flags_t(work->input.flags | C2FrameData::FLAG_DROP_FRAME);
+ copy->input.ordinal = work->input.ordinal;
+ copy->input.buffers.insert(
+ copy->input.buffers.begin(),
+ work->input.buffers.begin(),
+ work->input.buffers.end());
+ for (const std::unique_ptr<C2Param> ¶m : work->input.configUpdate) {
+ copy->input.configUpdate.push_back(C2Param::Copy(*param));
+ }
+ copy->input.infoBuffers.insert(
+ copy->input.infoBuffers.begin(),
+ work->input.infoBuffers.begin(),
+ work->input.infoBuffers.end());
+ copy->worklets.emplace_back(new C2Worklet);
+ configs.push_back(std::move(copy));
+ ALOGV("[%s] stashed flushed codec config data", mName);
}
+ mFlushedConfigs.lock()->swap(configs);
{
Mutexed<Input>::Locked input(mInput);
input->buffers->flush();
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index 8356a59..1ef21aa 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -277,7 +277,7 @@
uint32_t outputDelay;
};
Mutexed<Output> mOutput;
- Mutexed<std::list<sp<ABuffer>>> mFlushedConfigs;
+ Mutexed<std::list<std::unique_ptr<C2Work>>> mFlushedConfigs;
std::atomic_uint64_t mFrameIndex;
std::atomic_uint64_t mFirstValidFrameIndex;
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index 19414a0..5072323 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "Codec2Buffer"
#include <utils/Log.h>
+#include <android-base/properties.h>
#include <android/hardware/cas/native/1.0/types.h>
#include <android/hardware/drm/1.0/types.h>
#include <hidlmemory/FrameworkUtils.h>
@@ -580,7 +581,23 @@
}
std::shared_ptr<C2Buffer> GraphicMetadataBuffer::asC2Buffer() {
-#ifndef __LP64__
+#ifdef __LP64__
+ static std::once_flag s_checkOnce;
+ static bool s_64bitonly {false};
+ std::call_once(s_checkOnce, [&](){
+ const std::string abi32list =
+ ::android::base::GetProperty("ro.product.cpu.abilist32", "");
+ if (abi32list.empty()) {
+ s_64bitonly = true;
+ }
+ });
+
+ if (!s_64bitonly) {
+ ALOGE("GraphicMetadataBuffer does not work in 32+64 system if compiled as 64-bit object");
+ return nullptr;
+ }
+#endif
+
VideoNativeMetadata *meta = (VideoNativeMetadata *)base();
ANativeWindowBuffer *buffer = (ANativeWindowBuffer *)meta->pBuffer;
if (buffer == nullptr) {
@@ -613,10 +630,6 @@
}
return C2Buffer::CreateGraphicBuffer(
block->share(C2Rect(buffer->width, buffer->height), C2Fence()));
-#else
- ALOGE("GraphicMetadataBuffer does not work on 64-bit arch");
- return nullptr;
-#endif
}
// ConstGraphicBlockBuffer
diff --git a/media/codec2/vndk/C2DmaBufAllocator.cpp b/media/codec2/vndk/C2DmaBufAllocator.cpp
index 59e82e2..750aa31 100644
--- a/media/codec2/vndk/C2DmaBufAllocator.cpp
+++ b/media/codec2/vndk/C2DmaBufAllocator.cpp
@@ -315,8 +315,8 @@
if (mUsageMapper) {
res = mUsageMapper(usage, capacity, heap_name, flags);
} else {
- // No system-uncached yet, so disabled for now
- if (0 && !(usage.expected & (C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE)))
+ if (C2DmaBufAllocator::system_uncached_supported() &&
+ !(usage.expected & (C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE)))
*heap_name = "system-uncached";
else
*heap_name = "system";
diff --git a/media/codec2/vndk/C2Store.cpp b/media/codec2/vndk/C2Store.cpp
index 1e907c1..dee3bf6 100644
--- a/media/codec2/vndk/C2Store.cpp
+++ b/media/codec2/vndk/C2Store.cpp
@@ -622,6 +622,12 @@
std::vector<std::unique_ptr<C2SettingResult>> *const failures) override;
C2PlatformComponentStore();
+ // For testing only
+ C2PlatformComponentStore(
+ std::vector<std::tuple<C2String,
+ C2ComponentFactory::CreateCodec2FactoryFunc,
+ C2ComponentFactory::DestroyCodec2FactoryFunc>>);
+
virtual ~C2PlatformComponentStore() override = default;
private:
@@ -662,6 +668,24 @@
}
/**
+ * Creates an uninitialized component module.
+ * NOTE: For testing only
+ *
+ * \param name[in] component name.
+ *
+ * \note Only used by ComponentLoader.
+ */
+ ComponentModule(
+ C2ComponentFactory::CreateCodec2FactoryFunc createFactory,
+ C2ComponentFactory::DestroyCodec2FactoryFunc destroyFactory)
+ : mInit(C2_NO_INIT),
+ mLibHandle(nullptr),
+ createFactory(createFactory),
+ destroyFactory(destroyFactory),
+ mComponentFactory(nullptr) {
+ }
+
+ /**
* Initializes a component module with a given library path. Must be called exactly once.
*
* \note Only used by ComponentLoader.
@@ -717,7 +741,13 @@
std::lock_guard<std::mutex> lock(mMutex);
std::shared_ptr<ComponentModule> localModule = mModule.lock();
if (localModule == nullptr) {
- localModule = std::make_shared<ComponentModule>();
+ if(mCreateFactory) {
+ // For testing only
+ localModule = std::make_shared<ComponentModule>(mCreateFactory,
+ mDestroyFactory);
+ } else {
+ localModule = std::make_shared<ComponentModule>();
+ }
res = localModule->init(mLibPath);
if (res == C2_OK) {
mModule = localModule;
@@ -733,10 +763,22 @@
ComponentLoader(std::string libPath)
: mLibPath(libPath) {}
+ // For testing only
+ ComponentLoader(std::tuple<C2String,
+ C2ComponentFactory::CreateCodec2FactoryFunc,
+ C2ComponentFactory::DestroyCodec2FactoryFunc> func)
+ : mLibPath(std::get<0>(func)),
+ mCreateFactory(std::get<1>(func)),
+ mDestroyFactory(std::get<2>(func)) {}
+
private:
std::mutex mMutex; ///< mutex guarding the module
std::weak_ptr<ComponentModule> mModule; ///< weak reference to the loaded module
std::string mLibPath; ///< library path
+
+ // For testing only
+ C2ComponentFactory::CreateCodec2FactoryFunc mCreateFactory = nullptr;
+ C2ComponentFactory::DestroyCodec2FactoryFunc mDestroyFactory = nullptr;
};
struct Interface : public C2InterfaceHelper {
@@ -780,7 +822,13 @@
};
static C2R setDmaBufUsage(bool /* mayBlock */, C2P<C2StoreDmaBufUsageInfo> &me) {
- strncpy(me.set().m.heapName, "system", me.v.flexCount());
+ long long usage = (long long)me.get().m.usage;
+ if (C2DmaBufAllocator::system_uncached_supported() &&
+ !(usage & (C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE))) {
+ strncpy(me.set().m.heapName, "system-uncached", me.v.flexCount());
+ } else {
+ strncpy(me.set().m.heapName, "system", me.v.flexCount());
+ }
me.set().m.allocFlags = 0;
return C2R::Ok();
};
@@ -846,25 +894,33 @@
std::shared_ptr<C2ReflectorHelper> mReflector;
Interface mInterface;
+
+ // For testing only
+ std::vector<std::tuple<C2String,
+ C2ComponentFactory::CreateCodec2FactoryFunc,
+ C2ComponentFactory::DestroyCodec2FactoryFunc>> mCodec2FactoryFuncs;
};
c2_status_t C2PlatformComponentStore::ComponentModule::init(
std::string libPath) {
ALOGV("in %s", __func__);
ALOGV("loading dll");
- mLibHandle = dlopen(libPath.c_str(), RTLD_NOW|RTLD_NODELETE);
- LOG_ALWAYS_FATAL_IF(mLibHandle == nullptr,
- "could not dlopen %s: %s", libPath.c_str(), dlerror());
- createFactory =
- (C2ComponentFactory::CreateCodec2FactoryFunc)dlsym(mLibHandle, "CreateCodec2Factory");
- LOG_ALWAYS_FATAL_IF(createFactory == nullptr,
- "createFactory is null in %s", libPath.c_str());
+ if(!createFactory) {
+ mLibHandle = dlopen(libPath.c_str(), RTLD_NOW|RTLD_NODELETE);
+ LOG_ALWAYS_FATAL_IF(mLibHandle == nullptr,
+ "could not dlopen %s: %s", libPath.c_str(), dlerror());
- destroyFactory =
- (C2ComponentFactory::DestroyCodec2FactoryFunc)dlsym(mLibHandle, "DestroyCodec2Factory");
- LOG_ALWAYS_FATAL_IF(destroyFactory == nullptr,
- "destroyFactory is null in %s", libPath.c_str());
+ createFactory =
+ (C2ComponentFactory::CreateCodec2FactoryFunc)dlsym(mLibHandle, "CreateCodec2Factory");
+ LOG_ALWAYS_FATAL_IF(createFactory == nullptr,
+ "createFactory is null in %s", libPath.c_str());
+
+ destroyFactory =
+ (C2ComponentFactory::DestroyCodec2FactoryFunc)dlsym(mLibHandle, "DestroyCodec2Factory");
+ LOG_ALWAYS_FATAL_IF(destroyFactory == nullptr,
+ "destroyFactory is null in %s", libPath.c_str());
+ }
mComponentFactory = createFactory();
if (mComponentFactory == nullptr) {
@@ -1065,6 +1121,22 @@
emplace("libcodec2_soft_vp8enc.so");
emplace("libcodec2_soft_vp9dec.so");
emplace("libcodec2_soft_vp9enc.so");
+
+}
+
+// For testing only
+C2PlatformComponentStore::C2PlatformComponentStore(
+ std::vector<std::tuple<C2String,
+ C2ComponentFactory::CreateCodec2FactoryFunc,
+ C2ComponentFactory::DestroyCodec2FactoryFunc>> funcs)
+ : mVisited(false),
+ mReflector(std::make_shared<C2ReflectorHelper>()),
+ mInterface(mReflector),
+ mCodec2FactoryFuncs(funcs) {
+
+ for(auto const& func: mCodec2FactoryFuncs) {
+ mComponents.emplace(std::get<0>(func), func);
+ }
}
c2_status_t C2PlatformComponentStore::copyBuffer(
@@ -1184,4 +1256,11 @@
return store;
}
+// For testing only
+std::shared_ptr<C2ComponentStore> GetTestComponentStore(
+ std::vector<std::tuple<C2String,
+ C2ComponentFactory::CreateCodec2FactoryFunc,
+ C2ComponentFactory::DestroyCodec2FactoryFunc>> funcs) {
+ return std::shared_ptr<C2ComponentStore>(new C2PlatformComponentStore(funcs));
+}
} // namespace android
diff --git a/media/codec2/vndk/include/C2DmaBufAllocator.h b/media/codec2/vndk/include/C2DmaBufAllocator.h
index abb8307..d84c8c6 100644
--- a/media/codec2/vndk/include/C2DmaBufAllocator.h
+++ b/media/codec2/vndk/include/C2DmaBufAllocator.h
@@ -84,6 +84,16 @@
void setUsageMapper(const UsageMapperFn& mapper, uint64_t minUsage, uint64_t maxUsage,
uint64_t blockSize);
+ static bool system_uncached_supported(void) {
+ static int cached_result = -1;
+
+ if (cached_result == -1) {
+ struct stat buffer;
+ cached_result = (stat("/dev/dma_heap/system-uncached", &buffer) == 0);
+ }
+ return (cached_result == 1);
+ };
+
private:
c2_status_t mInit;
BufferAllocator mBufferAllocator;
diff --git a/media/codec2/vndk/include/C2PlatformSupport.h b/media/codec2/vndk/include/C2PlatformSupport.h
index 4814494..6d351c2 100644
--- a/media/codec2/vndk/include/C2PlatformSupport.h
+++ b/media/codec2/vndk/include/C2PlatformSupport.h
@@ -144,6 +144,15 @@
std::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore();
/**
+ * Returns the platform component store.
+ * NOTE: For testing only
+ * \retval nullptr if the platform component store could not be obtained
+ */
+std::shared_ptr<C2ComponentStore> GetTestComponentStore(
+ std::vector<std::tuple<C2String, C2ComponentFactory::CreateCodec2FactoryFunc,
+ C2ComponentFactory::DestroyCodec2FactoryFunc>>);
+
+/**
* Sets the preferred component store in this process for the sole purpose of accessing its
* interface. If this is not called, the default IComponentStore HAL (if exists) is the preferred
* store for this purpose. If the default IComponentStore HAL is not present, the platform
diff --git a/media/codecs/amrwb/dec/src/wb_syn_filt.cpp b/media/codecs/amrwb/dec/src/wb_syn_filt.cpp
index d960322..f12828d 100644
--- a/media/codecs/amrwb/dec/src/wb_syn_filt.cpp
+++ b/media/codecs/amrwb/dec/src/wb_syn_filt.cpp
@@ -181,12 +181,14 @@
L_tmp4 = fxp_mac_16by16(yy[(i<<2)+3 - j], a[j], L_tmp4);
L_tmp1 = shl_int32(L_tmp1, 4);
+ L_tmp1 = L_tmp1 == INT32_MIN ? INT32_MIN + 1 : L_tmp1;
y[(i<<2)] = yy[(i<<2)] = amr_wb_round(-L_tmp1);
L_tmp2 = fxp_mac_16by16(yy[(i<<2)], a[1], L_tmp2);
L_tmp2 = shl_int32(L_tmp2, 4);
+ L_tmp2 = L_tmp2 == INT32_MIN ? INT32_MIN + 1 : L_tmp2;
y[(i<<2)+1] = yy[(i<<2)+1] = amr_wb_round(-L_tmp2);
@@ -197,12 +199,14 @@
L_tmp3 = fxp_mac_16by16(yy[(i<<2) + 1], a[1], L_tmp3);
L_tmp3 = shl_int32(L_tmp3, 4);
+ L_tmp3 = L_tmp3 == INT32_MIN ? INT32_MIN + 1 : L_tmp3;
y[(i<<2)+2] = yy[(i<<2)+2] = amr_wb_round(-L_tmp3);
L_tmp4 = fxp_mac_16by16(yy[(i<<2)+2], a[1], L_tmp4);
L_tmp4 = shl_int32(L_tmp4, 4);
+ L_tmp4 = L_tmp4 == INT32_MIN ? INT32_MIN + 1 : L_tmp4;
y[(i<<2)+3] = yy[(i<<2)+3] = amr_wb_round(-L_tmp4);
}
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index 62f0808..eb2246d 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -43,9 +43,6 @@
long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op);
}
-static constexpr int OGG_PAGE_FLAG_CONTINUED_PACKET = 1;
-static constexpr int OGG_PAGE_FLAG_END_OF_STREAM = 4;
-
namespace android {
struct OggSource : public MediaTrackHelper {
@@ -300,8 +297,7 @@
AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
*out = packet;
- ALOGV("returning buffer %p, size %zu, length %zu",
- packet, packet->size(), packet->range_length());
+ ALOGV("returning buffer %p", packet);
return AMEDIA_OK;
}
@@ -362,10 +358,10 @@
if (!memcmp(signature, "OggS", 4)) {
if (*pageOffset > startOffset) {
- ALOGV("skipped %lld bytes of junk at %lld to reach next frame",
- (long long)(*pageOffset - startOffset), (long long)(startOffset));
+ ALOGV("skipped %lld bytes of junk to reach next frame",
+ (long long)(*pageOffset - startOffset));
}
- ALOGV("found frame at %lld", (long long)(*pageOffset));
+
return OK;
}
@@ -633,8 +629,7 @@
// Calculate timestamps by accumulating durations starting from the first sample of a page;
// We assume that we only seek to page boundaries.
AMediaFormat *meta = (*out)->meta_data();
- if (AMediaFormat_getInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, ¤tPageSamples) &&
- (mCurrentPage.mFlags & OGG_PAGE_FLAG_END_OF_STREAM)) {
+ if (AMediaFormat_getInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, ¤tPageSamples)) {
// first packet in page
if (mOffset == mFirstDataOffset) {
currentPageSamples -= mStartGranulePosition;
@@ -817,7 +812,6 @@
}
buffer = tmp;
- ALOGV("reading %zu bytes @ %zu", packetSize, size_t(dataOffset));
ssize_t n = mSource->readAt(
dataOffset,
(uint8_t *)buffer->data() + buffer->range_length(),
@@ -836,9 +830,8 @@
if (gotFullPacket) {
// We've just read the entire packet.
- ALOGV("got full packet, size %zu", fullSize);
- if (mFirstPacketInPage && (mCurrentPage.mFlags & OGG_PAGE_FLAG_END_OF_STREAM)) {
+ if (mFirstPacketInPage) {
AMediaFormat *meta = buffer->meta_data();
AMediaFormat_setInt32(
meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples);
@@ -871,9 +864,6 @@
}
// fall through, the buffer now contains the start of the packet.
- ALOGV("have start of packet, getting rest");
- } else {
- ALOGV("moving to next page");
}
CHECK_EQ(mNextLaceIndex, mCurrentPage.mNumSegments);
@@ -909,10 +899,9 @@
mNextLaceIndex = 0;
if (buffer != NULL) {
- if ((mCurrentPage.mFlags & OGG_PAGE_FLAG_CONTINUED_PACKET) == 0) {
+ if ((mCurrentPage.mFlags & 1) == 0) {
// This page does not continue the packet, i.e. the packet
// is already complete.
- ALOGV("packet was already complete?!");
if (timeUs >= 0) {
AMediaFormat *meta = buffer->meta_data();
@@ -920,10 +909,8 @@
}
AMediaFormat *meta = buffer->meta_data();
- if (mCurrentPage.mFlags & OGG_PAGE_FLAG_END_OF_STREAM) {
- AMediaFormat_setInt32(
- meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples);
- }
+ AMediaFormat_setInt32(
+ meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples);
mFirstPacketInPage = false;
*out = buffer;
@@ -942,7 +929,6 @@
for (size_t i = 0; i < mNumHeaders; ++i) {
// ignore timestamp for configuration packets
if ((err = _readNextPacket(&packet, /* calcVorbisTimestamp = */ false)) != AMEDIA_OK) {
- ALOGV("readNextPacket failed");
return err;
}
ALOGV("read packet of size %zu\n", packet->range_length());
@@ -1022,10 +1008,6 @@
size_t size = buffer->range_length();
- if (size == 0) {
- return 0;
- }
-
ogg_buffer buf;
buf.data = (uint8_t *)data;
buf.size = size;
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 81394cb..aa740a7 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -61,7 +61,7 @@
header_libs: ["libaudioclient_headers"],
}
-cc_library_shared {
+cc_library {
name: "libaudioclient",
aidl: {
diff --git a/media/libaudioclient/AudioPolicy.cpp b/media/libaudioclient/AudioPolicy.cpp
index 0522099..c2f7229 100644
--- a/media/libaudioclient/AudioPolicy.cpp
+++ b/media/libaudioclient/AudioPolicy.cpp
@@ -85,7 +85,7 @@
mDeviceType = (audio_devices_t) parcel->readInt32();
mDeviceAddress = parcel->readString8();
mCbFlags = (uint32_t)parcel->readInt32();
- mAllowPrivilegedPlaybackCapture = parcel->readBool();
+ mAllowPrivilegedMediaPlaybackCapture = parcel->readBool();
mVoiceCommunicationCaptureAllowed = parcel->readBool();
size_t size = (size_t)parcel->readInt32();
if (size > MAX_CRITERIA_PER_MIX) {
@@ -110,7 +110,7 @@
parcel->writeInt32(mDeviceType);
parcel->writeString8(mDeviceAddress);
parcel->writeInt32(mCbFlags);
- parcel->writeBool(mAllowPrivilegedPlaybackCapture);
+ parcel->writeBool(mAllowPrivilegedMediaPlaybackCapture);
parcel->writeBool(mVoiceCommunicationCaptureAllowed);
size_t size = mCriteria.size();
if (size > MAX_CRITERIA_PER_MIX) {
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index 00fe278..08b3da1 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -120,7 +120,7 @@
String8 mDeviceAddress;
uint32_t mCbFlags; // flags indicating which callbacks to use, see kCbFlag*
/** Ignore the AUDIO_FLAG_NO_MEDIA_PROJECTION */
- bool mAllowPrivilegedPlaybackCapture = false;
+ bool mAllowPrivilegedMediaPlaybackCapture = false;
/** Indicates if the caller can capture voice communication output */
bool mVoiceCommunicationCaptureAllowed = false;
};
diff --git a/media/libaudiofoundation/AudioProfile.cpp b/media/libaudiofoundation/AudioProfile.cpp
index 3b47fed..65f7388 100644
--- a/media/libaudiofoundation/AudioProfile.cpp
+++ b/media/libaudiofoundation/AudioProfile.cpp
@@ -355,4 +355,31 @@
return convertContainer<std::vector<media::AudioProfile>>(legacy, legacy2aidl_AudioProfile);
}
+AudioProfileVector intersectAudioProfiles(const AudioProfileVector& profiles1,
+ const AudioProfileVector& profiles2)
+{
+ std::map<audio_format_t, std::pair<ChannelMaskSet, SampleRateSet>> infos2;
+ for (const auto& profile : profiles2) {
+ infos2.emplace(profile->getFormat(),
+ std::make_pair(profile->getChannels(), profile->getSampleRates()));
+ }
+ AudioProfileVector profiles;
+ for (const auto& profile : profiles1) {
+ const auto it = infos2.find(profile->getFormat());
+ if (it == infos2.end()) {
+ continue;
+ }
+ ChannelMaskSet channelMasks = SetIntersection(profile->getChannels(), it->second.first);
+ if (channelMasks.empty()) {
+ continue;
+ }
+ SampleRateSet sampleRates = SetIntersection(profile->getSampleRates(), it->second.second);
+ if (sampleRates.empty()) {
+ continue;
+ }
+ profiles.push_back(new AudioProfile(profile->getFormat(), channelMasks, sampleRates));
+ }
+ return profiles;
+}
+
} // namespace android
diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
index a3e9589..5cfea81 100644
--- a/media/libaudiofoundation/DeviceDescriptorBase.cpp
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -122,9 +122,9 @@
spaces, "", ::android::toString(mDeviceTypeAddr.mType).c_str()));
dst->append(base::StringPrintf(
- "%*s- supported encapsulation modes: %u", spaces, "", mEncapsulationModes));
+ "%*s- supported encapsulation modes: %u\n", spaces, "", mEncapsulationModes));
dst->append(base::StringPrintf(
- "%*s- supported encapsulation metadata types: %u",
+ "%*s- supported encapsulation metadata types: %u\n",
spaces, "", mEncapsulationMetadataTypes));
if (mDeviceTypeAddr.address().size() != 0) {
diff --git a/media/libaudiofoundation/include/media/AudioContainers.h b/media/libaudiofoundation/include/media/AudioContainers.h
index aa7ca69..204b365 100644
--- a/media/libaudiofoundation/include/media/AudioContainers.h
+++ b/media/libaudiofoundation/include/media/AudioContainers.h
@@ -50,6 +50,15 @@
return intersection;
}
+template<typename T>
+static std::set<T> SetIntersection(const std::set<T>& a, const std::set<T> b) {
+ std::set<T> intersection;
+ std::set_intersection(a.begin(), a.end(),
+ b.begin(), b.end(),
+ std::inserter(intersection, intersection.begin()));
+ return intersection;
+}
+
static inline ChannelMaskSet asInMask(const ChannelMaskSet& channelMasks) {
ChannelMaskSet inMaskSet;
for (const auto &channel : channelMasks) {
diff --git a/media/libaudiofoundation/include/media/AudioProfile.h b/media/libaudiofoundation/include/media/AudioProfile.h
index 57592bc..5051233 100644
--- a/media/libaudiofoundation/include/media/AudioProfile.h
+++ b/media/libaudiofoundation/include/media/AudioProfile.h
@@ -137,5 +137,7 @@
ConversionResult<std::vector<media::AudioProfile>>
legacy2aidl_AudioProfileVector(const AudioProfileVector& legacy);
+AudioProfileVector intersectAudioProfiles(const AudioProfileVector& profiles1,
+ const AudioProfileVector& profiles2);
} // namespace android
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index 482f40e..d9a7804 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -31,6 +31,7 @@
header_libs: [
"libaudiohal_headers",
"libbase_headers",
+ "libmediautils_headers",
]
}
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 09a7c1c..3a1fce8 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -62,7 +62,9 @@
}
StreamHalHidl::~StreamHalHidl() {
- mStream = nullptr;
+ // The last step is to flush all binder commands so that the deletion
+ // of IStreamIn / IStreamOut (mStream) is issued with less delay. See b/35394629.
+ hardware::IPCThreadState::self()->flushCommands();
}
status_t StreamHalHidl::getSampleRate(uint32_t *rate) {
@@ -286,7 +288,7 @@
}
private:
- wp<StreamOutHalHidl> mStream;
+ const wp<StreamOutHalHidl> mStream;
};
} // namespace
@@ -297,21 +299,19 @@
StreamOutHalHidl::~StreamOutHalHidl() {
if (mStream != 0) {
- if (mCallback.unsafe_get()) {
+ if (mCallback.load().unsafe_get()) {
processReturn("clearCallback", mStream->clearCallback());
}
#if MAJOR_VERSION >= 6
- if (mEventCallback.unsafe_get() != nullptr) {
+ if (mEventCallback.load().unsafe_get() != nullptr) {
processReturn("setEventCallback",
mStream->setEventCallback(nullptr));
}
#endif
processReturn("close", mStream->close());
- mStream.clear();
}
- mCallback.clear();
- mEventCallback.clear();
- hardware::IPCThreadState::self()->flushCommands();
+ mCallback = nullptr;
+ mEventCallback = nullptr;
if (mEfGroup) {
EventFlag::deleteEventFlag(&mEfGroup);
}
@@ -364,7 +364,7 @@
if (bytes == 0 && !mDataMQ) {
// Can't determine the size for the MQ buffer. Wait for a non-empty write request.
- ALOGW_IF(mCallback.unsafe_get(), "First call to async write with 0 bytes");
+ ALOGW_IF(mCallback.load().unsafe_get(), "First call to async write with 0 bytes");
return OK;
}
@@ -680,28 +680,28 @@
#endif
void StreamOutHalHidl::onWriteReady() {
- sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
+ sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
if (callback == 0) return;
ALOGV("asyncCallback onWriteReady");
callback->onWriteReady();
}
void StreamOutHalHidl::onDrainReady() {
- sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
+ sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
if (callback == 0) return;
ALOGV("asyncCallback onDrainReady");
callback->onDrainReady();
}
void StreamOutHalHidl::onError() {
- sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
+ sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
if (callback == 0) return;
ALOGV("asyncCallback onError");
callback->onError();
}
void StreamOutHalHidl::onCodecFormatChanged(const std::basic_string<uint8_t>& metadataBs) {
- sp<StreamOutHalInterfaceEventCallback> callback = mEventCallback.promote();
+ sp<StreamOutHalInterfaceEventCallback> callback = mEventCallback.load().promote();
if (callback == nullptr) return;
ALOGV("asyncCodecFormatCallback %s", __func__);
callback->onCodecFormatChanged(metadataBs);
@@ -715,8 +715,6 @@
StreamInHalHidl::~StreamInHalHidl() {
if (mStream != 0) {
processReturn("close", mStream->close());
- mStream.clear();
- hardware::IPCThreadState::self()->flushCommands();
}
if (mEfGroup) {
EventFlag::deleteEventFlag(&mEfGroup);
diff --git a/media/libaudiohal/impl/StreamHalHidl.h b/media/libaudiohal/impl/StreamHalHidl.h
index 88f8587..95855fe 100644
--- a/media/libaudiohal/impl/StreamHalHidl.h
+++ b/media/libaudiohal/impl/StreamHalHidl.h
@@ -25,6 +25,7 @@
#include <fmq/EventFlag.h>
#include <fmq/MessageQueue.h>
#include <media/audiohal/StreamHalInterface.h>
+#include <mediautils/Synchronization.h>
#include "ConversionHelperHidl.h"
#include "StreamPowerLog.h"
@@ -100,8 +101,7 @@
// Subclasses can not be constructed directly by clients.
explicit StreamHalHidl(IStream *stream);
- // The destructor automatically closes the stream.
- virtual ~StreamHalHidl();
+ ~StreamHalHidl() override;
status_t getCachedBufferSize(size_t *size);
@@ -112,7 +112,7 @@
private:
const int HAL_THREAD_PRIORITY_DEFAULT = -1;
- IStream *mStream;
+ IStream * const mStream;
int mHalThreadPriority;
size_t mCachedBufferSize;
};
@@ -184,9 +184,9 @@
typedef MessageQueue<uint8_t, hardware::kSynchronizedReadWrite> DataMQ;
typedef MessageQueue<WriteStatus, hardware::kSynchronizedReadWrite> StatusMQ;
- wp<StreamOutHalInterfaceCallback> mCallback;
- wp<StreamOutHalInterfaceEventCallback> mEventCallback;
- sp<IStreamOut> mStream;
+ mediautils::atomic_wp<StreamOutHalInterfaceCallback> mCallback;
+ mediautils::atomic_wp<StreamOutHalInterfaceEventCallback> mEventCallback;
+ const sp<IStreamOut> mStream;
std::unique_ptr<CommandMQ> mCommandMQ;
std::unique_ptr<DataMQ> mDataMQ;
std::unique_ptr<StatusMQ> mStatusMQ;
@@ -242,7 +242,7 @@
typedef MessageQueue<uint8_t, hardware::kSynchronizedReadWrite> DataMQ;
typedef MessageQueue<ReadStatus, hardware::kSynchronizedReadWrite> StatusMQ;
- sp<IStreamIn> mStream;
+ const sp<IStreamIn> mStream;
std::unique_ptr<CommandMQ> mCommandMQ;
std::unique_ptr<DataMQ> mDataMQ;
std::unique_ptr<StatusMQ> mStatusMQ;
diff --git a/media/libeffects/lvm/lib/Android.bp b/media/libeffects/lvm/lib/Android.bp
index 34cad1f..8d248a3 100644
--- a/media/libeffects/lvm/lib/Android.bp
+++ b/media/libeffects/lvm/lib/Android.bp
@@ -69,28 +69,19 @@
"Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp",
"Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.cpp",
"Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Init.cpp",
- "Common/src/Int16LShiftToInt32_16x32.cpp",
- "Common/src/From2iToMono_16.cpp",
"Common/src/Copy_16.cpp",
- "Common/src/MonoTo2I_16.cpp",
"Common/src/MonoTo2I_32.cpp",
- "Common/src/LoadConst_16.cpp",
"Common/src/LoadConst_32.cpp",
"Common/src/dB_to_Lin32.cpp",
"Common/src/Shift_Sat_v16xv16.cpp",
"Common/src/Shift_Sat_v32xv32.cpp",
- "Common/src/Abs_32.cpp",
- "Common/src/Int32RShiftToInt16_Sat_32x16.cpp",
"Common/src/From2iToMono_32.cpp",
- "Common/src/mult3s_16x16.cpp",
"Common/src/Mult3s_32x16.cpp",
"Common/src/NonLinComp_D16.cpp",
"Common/src/DelayMix_16x16.cpp",
"Common/src/MSTo2i_Sat_16x16.cpp",
"Common/src/From2iToMS_16x16.cpp",
- "Common/src/Mac3s_Sat_16x16.cpp",
"Common/src/Mac3s_Sat_32x16.cpp",
- "Common/src/Add2_Sat_16x16.cpp",
"Common/src/Add2_Sat_32x32.cpp",
"Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp",
"Common/src/LVC_MixSoft_1St_D16C31_SAT.cpp",
@@ -166,18 +157,14 @@
"Reverb/src/LVREV_Process.cpp",
"Reverb/src/LVREV_SetControlParameters.cpp",
"Reverb/src/LVREV_Tables.cpp",
- "Common/src/Abs_32.cpp",
"Common/src/InstAlloc.cpp",
- "Common/src/LoadConst_16.cpp",
"Common/src/LoadConst_32.cpp",
"Common/src/From2iToMono_32.cpp",
"Common/src/Mult3s_32x16.cpp",
"Common/src/FO_1I_D32F32C31_TRC_WRA_01.cpp",
"Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.cpp",
- "Common/src/DelayAllPass_Sat_32x16To32.cpp",
"Common/src/Copy_16.cpp",
"Common/src/Mac3s_Sat_32x16.cpp",
- "Common/src/DelayWrite_32.cpp",
"Common/src/Shift_Sat_v32xv32.cpp",
"Common/src/Add2_Sat_32x32.cpp",
"Common/src/JoinTo2i_32x32.cpp",
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp
index 4a72834..e8541fd 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Process.cpp
@@ -167,15 +167,6 @@
pScratch, /* Destination */
NrFrames, /* Number of frames */
NrChannels); /* Number of channels */
-
- for (LVM_INT32 ii = 0; ii < NrSamples; ++ii) {
- // TODO: replace with existing clamping function
- if (pScratch[ii] < -1.0) {
- pScratch[ii] = -1.0;
- } else if (pScratch[ii] > 1.0) {
- pScratch[ii] = 1.0;
- }
- }
} else {
// clear DBE processed path
memset(pScratch, 0, sizeof(*pScratch) * NrSamples);
diff --git a/media/libeffects/lvm/lib/Common/lib/AGC.h b/media/libeffects/lvm/lib/Common/lib/AGC.h
index c20b49a..31c8200 100644
--- a/media/libeffects/lvm/lib/Common/lib/AGC.h
+++ b/media/libeffects/lvm/lib/Common/lib/AGC.h
@@ -48,11 +48,6 @@
/* Function Prototypes */
/* */
/**********************************************************************************/
-void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t* pInstance, /* Instance pointer */
- const LVM_FLOAT* pStSrc, /* Stereo source */
- const LVM_FLOAT* pMonoSrc, /* Mono source */
- LVM_FLOAT* pDst, /* Stereo destination */
- LVM_UINT16 n); /* Number of samples */
void AGC_MIX_VOL_Mc1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t* pInstance, /* Instance pointer */
const LVM_FLOAT* pStSrc, /* Source */
const LVM_FLOAT* pMonoSrc, /* Mono source */
diff --git a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
index b38e9fb..08772e1 100644
--- a/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
+++ b/media/libeffects/lvm/lib/Common/lib/BIQUAD.h
@@ -72,6 +72,7 @@
LVM_FLOAT G; /* Gain */
} PK_FLOAT_Coefs_t;
+#ifndef BIQUAD_OPT
/**********************************************************************************
TAPS TYPE DEFINITIONS
***********************************************************************************/
@@ -100,6 +101,7 @@
#define BQ_2I_D32F32Cll_TRC_WRA_01_Init Init_BQ_2I_D32F32Cll_TRC_WRA_01
#define BP_1I_D32F32C30_TRC_WRA_02 TWO_BP_1I_D32F32C30_TRC_WRA_02
+
/**********************************************************************************
FUNCTION PROTOTYPES: BIQUAD FILTERS
***********************************************************************************/
@@ -161,8 +163,6 @@
Biquad_2I_Order1_FLOAT_Taps_t* pTaps,
FO_FLOAT_LShx_Coefs_t* pCoef);
-void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
- LVM_FLOAT* pDataOut, LVM_INT16 NrSamples);
/*** 32 bit data path *************************************************************/
void FO_1I_D32F32Cll_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t* pInstance,
Biquad_1I_Order1_FLOAT_Taps_t* pTaps, FO_FLOAT_Coefs_t* pCoef);
@@ -170,6 +170,7 @@
LVM_FLOAT* pDataOut, LVM_INT16 NrSamples);
void FO_Mc_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
LVM_FLOAT* pDataOut, LVM_INT16 NrFrames, LVM_INT16 NrChannels);
+
/**********************************************************************************
FUNCTION PROTOTYPES: BAND PASS FILTERS
***********************************************************************************/
@@ -183,6 +184,7 @@
Biquad_1I_Order2_FLOAT_Taps_t* pTaps, BP_FLOAT_Coefs_t* pCoef);
void BP_1I_D16F32C30_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
LVM_FLOAT* pDataOut, LVM_INT16 NrSamples);
+
/*** 32 bit data path *************************************************************/
void BP_1I_D32F32Cll_TRC_WRA_02_Init(Biquad_FLOAT_Instance_t* pInstance,
Biquad_1I_Order2_FLOAT_Taps_t* pTaps, BP_FLOAT_Coefs_t* pCoef);
@@ -193,10 +195,9 @@
void PK_2I_D32F32CssGss_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t* pInstance,
Biquad_2I_Order2_FLOAT_Taps_t* pTaps,
PK_FLOAT_Coefs_t* pCoef);
-void PK_2I_D32F32C14G11_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
- LVM_FLOAT* pDataOut, LVM_INT16 NrSamples);
void PK_Mc_D32F32C14G11_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
LVM_FLOAT* pDataOut, LVM_INT16 NrFrames, LVM_INT16 NrChannels);
+#endif
/**********************************************************************************
FUNCTION PROTOTYPES: DC REMOVAL FILTERS
diff --git a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
index fb797be..b95d076 100644
--- a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
+++ b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
@@ -26,7 +26,7 @@
#define LVM_TYPES_H
#include <stdint.h>
-
+#include <system/audio.h>
/****************************************************************************************/
/* */
/* definitions */
@@ -82,7 +82,7 @@
#define EFFECT_BUFFER_FORMAT AUDIO_FORMAT_PCM_FLOAT
typedef float effect_buffer_t;
-#define LVM_MAX_CHANNELS 8 // FCC_8
+#define LVM_MAX_CHANNELS FCC_24
/****************************************************************************************/
/* */
diff --git a/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h b/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
index 04b180c..36c4cd2 100644
--- a/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/ScalarArithmetic.h
@@ -21,7 +21,7 @@
/*######################################################################################*/
/* Include files */
/*######################################################################################*/
-
+#include <math.h>
#include "LVM_Types.h"
/*######################################################################################*/
@@ -30,7 +30,13 @@
/* Absolute value including the corner case for the extreme negative value */
-LVM_FLOAT Abs_Float(LVM_FLOAT input);
+static inline LVM_FLOAT Abs_Float(LVM_FLOAT input) {
+ return fabs(input);
+}
+
+static inline LVM_FLOAT LVM_Clamp(LVM_FLOAT val) {
+ return fmin(fmax(val, -1.0f), 1.0f);
+}
/****************************************************************************************
* Name : dB_to_Lin32()
diff --git a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
index 66e3e79..281d941 100644
--- a/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
+++ b/media/libeffects/lvm/lib/Common/lib/VectorArithmetic.h
@@ -32,45 +32,16 @@
void Copy_Float_Stereo_Mc(const LVM_FLOAT* src, LVM_FLOAT* StereoOut, LVM_FLOAT* dst,
LVM_INT16 NrFrames, LVM_INT32 NrChannels);
-/*********************************************************************************
- * note: In Mult3s_16x16() saturation of result is not taken care when *
- * overflow occurs. *
- * For example when *src = 0x8000, val = *0x8000 *
- * The function gives the output as 0x8000 instead of 0x7fff *
- * This is the only case which will give wrong result. *
- * For more information refer to Vector_Arithmetic.doc in /doc folder *
- *********************************************************************************/
void Mult3s_Float(const LVM_FLOAT* src, const LVM_FLOAT val, LVM_FLOAT* dst, LVM_INT16 n);
-/*********************************************************************************
- * note: In Mult3s_32x16() saturation of result is not taken care when *
- * overflow occurs. *
- * For example when *src = 0x8000000, val = *0x8000 *
- * The function gives the output as 0x8000000 instead of 0x7fffffff *
- * This is the only extreme condition which is giving unexpected result *
- * For more information refer to Vector_Arithmetic.doc in /doc folder *
- *********************************************************************************/
-void Mult3s_32x16(const LVM_INT32* src, const LVM_INT16 val, LVM_INT32* dst, LVM_INT16 n);
void DelayMix_Float(const LVM_FLOAT* src, /* Source 1, to be delayed */
LVM_FLOAT* delay, /* Delay buffer */
LVM_INT16 size, /* Delay size */
LVM_FLOAT* dst, /* Source/destination */
LVM_INT16* pOffset, /* Delay offset */
LVM_INT16 n); /* Number of stereo samples */
-void DelayWrite_32(const LVM_INT32* src, /* Source 1, to be delayed */
- LVM_INT32* delay, /* Delay buffer */
- LVM_UINT16 size, /* Delay size */
- LVM_UINT16* pOffset, /* Delay offset */
- LVM_INT16 n);
void Add2_Sat_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n);
void Mac3s_Sat_Float(const LVM_FLOAT* src, const LVM_FLOAT val, LVM_FLOAT* dst, LVM_INT16 n);
-void DelayAllPass_Sat_32x16To32(LVM_INT32* delay, /* Delay buffer */
- LVM_UINT16 size, /* Delay size */
- LVM_INT16 coeff, /* All pass filter coefficient */
- LVM_UINT16 DelayOffset, /* Simple delay offset */
- LVM_UINT16* pAllPassOffset, /* All pass filter delay offset */
- LVM_INT32* dst, /* Source/destination */
- LVM_INT16 n);
/**********************************************************************************
SHIFT FUNCTIONS
@@ -87,15 +58,6 @@
void From2iToMS_Float(const LVM_FLOAT* src, LVM_FLOAT* dstM, LVM_FLOAT* dstS, LVM_INT16 n);
void JoinTo2i_Float(const LVM_FLOAT* srcL, const LVM_FLOAT* srcR, LVM_FLOAT* dst, LVM_INT16 n);
-/**********************************************************************************
- DATA TYPE CONVERSION FUNCTIONS
-***********************************************************************************/
-
-void Int16LShiftToInt32_16x32(const LVM_INT16* src, LVM_INT32* dst, LVM_INT16 n, LVM_INT16 shift);
-
-void Int32RShiftToInt16_Sat_32x16(const LVM_INT32* src, LVM_INT16* dst, LVM_INT16 n,
- LVM_INT16 shift);
-
/**********************************************************************************/
#endif /* _VECTOR_ARITHMETIC_H_ */
diff --git a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp
index ae8cdad..78f329e 100644
--- a/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp
+++ b/media/libeffects/lvm/lib/Common/src/AGC_MIX_VOL_2St1Mon_D32_WRA.cpp
@@ -20,7 +20,6 @@
/* Includes */
/* */
/****************************************************************************************/
-
#include "AGC.h"
#include "ScalarArithmetic.h"
@@ -37,135 +36,6 @@
/****************************************************************************************/
/* */
-/* FUNCTION: AGC_MIX_VOL_2St1Mon_D32_WRA */
-/* */
-/* DESCRIPTION: */
-/* Apply AGC and mix signals */
-/* */
-/* */
-/* StSrc ------------------| */
-/* | */
-/* ______ _|_ ________ */
-/* | | | | | | */
-/* MonoSrc -->| AGC |---->| + |----->| Volume |------------------------------+---> */
-/* | Gain | |___| | Gain | | */
-/* |______| |________| | */
-/* /|\ __________ ________ | */
-/* | | | | | | */
-/* |-------------------------------| AGC Gain |<--| Peak |<--| */
-/* | Update | | Detect | */
-/* |__________| |________| */
-/* */
-/* */
-/* PARAMETERS: */
-/* pInstance Instance pointer */
-/* pStereoIn Stereo source */
-/* pMonoIn Mono band pass source */
-/* pStereoOut Stereo destination */
-/* */
-/* RETURNS: */
-/* Void */
-/* */
-/* NOTES: */
-/* */
-/****************************************************************************************/
-void AGC_MIX_VOL_2St1Mon_D32_WRA(AGC_MIX_VOL_2St1Mon_FLOAT_t* pInstance, /* Instance pointer */
- const LVM_FLOAT* pStSrc, /* Stereo source */
- const LVM_FLOAT* pMonoSrc, /* Mono source */
- LVM_FLOAT* pDst, /* Stereo destination */
- LVM_UINT16 NumSamples) /* Number of samples */
-{
- /*
- * General variables
- */
- LVM_UINT16 i; /* Sample index */
- LVM_FLOAT Left; /* Left sample */
- LVM_FLOAT Right; /* Right sample */
- LVM_FLOAT Mono; /* Mono sample */
- LVM_FLOAT AbsPeak; /* Absolute peak signal */
- LVM_FLOAT AGC_Mult; /* Short AGC gain */
- LVM_FLOAT Vol_Mult; /* Short volume */
-
- /*
- * Instance control variables
- */
- LVM_FLOAT AGC_Gain = pInstance->AGC_Gain; /* Get the current AGC gain */
- LVM_FLOAT AGC_MaxGain = pInstance->AGC_MaxGain; /* Get maximum AGC gain */
- LVM_FLOAT AGC_Attack = pInstance->AGC_Attack; /* Attack scaler */
- LVM_FLOAT AGC_Decay = (pInstance->AGC_Decay * (1 << (DECAY_SHIFT))); /* Decay scaler */
- LVM_FLOAT AGC_Target = pInstance->AGC_Target; /* Get the target level */
- LVM_FLOAT Vol_Current = pInstance->Volume; /* Actual volume setting */
- LVM_FLOAT Vol_Target = pInstance->Target; /* Target volume setting */
- LVM_FLOAT Vol_TC = pInstance->VolumeTC; /* Time constant */
-
- /*
- * Process on a sample by sample basis
- */
- for (i = 0; i < NumSamples; i++) /* For each sample */
- {
- /*
- * Get the short scalers
- */
- AGC_Mult = (LVM_FLOAT)(AGC_Gain); /* Get the short AGC gain */
- Vol_Mult = (LVM_FLOAT)(Vol_Current); /* Get the short volume gain */
-
- /*
- * Get the input samples
- */
- Left = *pStSrc++; /* Get the left sample */
- Right = *pStSrc++; /* Get the right sample */
- Mono = *pMonoSrc++; /* Get the mono sample */
-
- /*
- * Apply the AGC gain to the mono input and mix with the stereo signal
- */
- Left += (Mono * AGC_Mult); /* Mix in the mono signal */
- Right += (Mono * AGC_Mult);
-
- /*
- * Apply the volume and write to the output stream
- */
- Left = Left * Vol_Mult;
- Right = Right * Vol_Mult;
- *pDst++ = Left; /* Save the results */
- *pDst++ = Right;
-
- /*
- * Update the AGC gain
- */
- AbsPeak = Abs_Float(Left) > Abs_Float(Right) ? Abs_Float(Left) : Abs_Float(Right);
- if (AbsPeak > AGC_Target) {
- /*
- * The signal is too large so decrease the gain
- */
- AGC_Gain = AGC_Gain * AGC_Attack;
- } else {
- /*
- * The signal is too small so increase the gain
- */
- if (AGC_Gain > AGC_MaxGain) {
- AGC_Gain -= (AGC_Decay);
- } else {
- AGC_Gain += (AGC_Decay);
- }
- }
-
- /*
- * Update the gain
- */
- Vol_Current += (Vol_Target - Vol_Current) * ((LVM_FLOAT)Vol_TC / VOL_TC_FLOAT);
- }
-
- /*
- * Update the parameters
- */
- pInstance->Volume = Vol_Current; /* Actual volume setting */
- pInstance->AGC_Gain = AGC_Gain;
-
- return;
-}
-/****************************************************************************************/
-/* */
/* FUNCTION: AGC_MIX_VOL_Mc1Mon_D32_WRA */
/* */
/* DESCRIPTION: */
@@ -255,7 +125,7 @@
*/
SampleVal = SampleVal * Vol_Mult;
- *pDst++ = SampleVal; /* Save the results */
+ *pDst++ = LVM_Clamp(SampleVal); /* Save the results */
/*
* Update the AGC gain
diff --git a/media/libeffects/lvm/lib/Common/src/Abs_32.cpp b/media/libeffects/lvm/lib/Common/src/Abs_32.cpp
deleted file mode 100644
index 3e37d89..0000000
--- a/media/libeffects/lvm/lib/Common/src/Abs_32.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * 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.
- */
-
-/*######################################################################################*/
-/* Include files */
-/*######################################################################################*/
-
-#include "ScalarArithmetic.h"
-
-/****************************************************************************************
- * Name : Abs_32()
- * Input : Signed 32-bit integer
- * Output :
- * Returns : Absolute value
- * Description : Absolute value with maximum negative value corner case
- * Remarks :
- ****************************************************************************************/
-
-LVM_INT32 Abs_32(LVM_INT32 input) {
- if (input < 0) {
- if (input == (LVM_INT32)(0x80000000U)) {
- /* The corner case, so set to the maximum positive value */
- input = (LVM_INT32)0x7fffffff;
- } else {
- /* Negative input, so invert */
- input = (LVM_INT32)(-input);
- }
- }
- return input;
-}
-LVM_FLOAT Abs_Float(LVM_FLOAT input) {
- if (input < 0) {
- /* Negative input, so invert */
- input = (LVM_FLOAT)(-input);
- }
- return input;
-}
diff --git a/media/libeffects/lvm/lib/Common/src/Add2_Sat_16x16.cpp b/media/libeffects/lvm/lib/Common/src/Add2_Sat_16x16.cpp
deleted file mode 100644
index be20521..0000000
--- a/media/libeffects/lvm/lib/Common/src/Add2_Sat_16x16.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * 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.
- */
-
-/**********************************************************************************
- INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
- FUNCTION ADD2_SAT_16X16
-***********************************************************************************/
-
-void Add2_Sat_16x16(const LVM_INT16* src, LVM_INT16* dst, LVM_INT16 n) {
- LVM_INT32 Temp;
- LVM_INT16 ii;
- for (ii = n; ii != 0; ii--) {
- Temp = ((LVM_INT32)*src) + ((LVM_INT32)*dst);
- src++;
-
- if (Temp > 0x00007FFF) {
- *dst = 0x7FFF;
- } else if (Temp < -0x00008000) {
- *dst = -0x8000;
- } else {
- *dst = (LVM_INT16)Temp;
- }
- dst++;
- }
- return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.cpp b/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.cpp
index 420f93e..1981edd 100644
--- a/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Add2_Sat_32x32.cpp
@@ -18,53 +18,15 @@
/**********************************************************************************
INCLUDE FILES
***********************************************************************************/
-
+#include "ScalarArithmetic.h"
#include "VectorArithmetic.h"
-/**********************************************************************************
- FUNCTION ADD2_SAT_32X32
-***********************************************************************************/
-
-void Add2_Sat_32x32(const LVM_INT32* src, LVM_INT32* dst, LVM_INT16 n) {
- LVM_INT32 a, b, c;
- LVM_INT16 ii;
- for (ii = n; ii != 0; ii--) {
- a = *src;
- src++;
-
- b = *dst;
- c = a + b;
- if ((((c ^ a) & (c ^ b)) >> 31) != 0) /* overflow / underflow */
- {
- if (a < 0) {
- c = 0x80000000L;
- } else {
- c = 0x7FFFFFFFL;
- }
- }
-
- *dst = c;
- dst++;
- }
- return;
-}
-
void Add2_Sat_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n) {
LVM_FLOAT Temp;
LVM_INT16 ii;
for (ii = n; ii != 0; ii--) {
- Temp = ((LVM_FLOAT)*src) + ((LVM_FLOAT)*dst);
- src++;
-
- if (Temp > 1.000000f) {
- *dst = 1.000000f;
- } else if (Temp < -1.000000f) {
- *dst = -1.000000f;
- } else {
- *dst = Temp;
- }
- dst++;
+ Temp = *src++ + *dst;
+ *dst++ = LVM_Clamp(Temp);
}
return;
}
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.cpp
index 198a6a1..bc9a2c5 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16C14_TRC_WRA_01.cpp
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BP_1I_D16F16Css_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
@@ -67,3 +67,4 @@
*pDataOut++ = ynL; // Write Left output
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.cpp
index 6d36302..571676b 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Init.cpp
@@ -16,6 +16,7 @@
*/
/*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BP_1I_D16F16Css_TRC_WRA_01_Private.h"
@@ -47,5 +48,6 @@
pBiquadState->coefs[1] = pCoef->B2;
pBiquadState->coefs[2] = pCoef->B1;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: BP_1I_D16F16Css_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
index a41c855..c19e2f4 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#ifndef _BP_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
#define _BP_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
@@ -32,3 +33,4 @@
} Filter_State_FLOAT;
typedef Filter_State_FLOAT* PFilter_State_FLOAT;
#endif /*_BP_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_*/
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.cpp
index d4d4eb1..ff3221a 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32C30_TRC_WRA_01.cpp
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BP_1I_D16F32Cll_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
@@ -68,3 +68,4 @@
*pDataOut++ = (ynL); // Write Left output
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.cpp
index d322a8e..26a4793 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Init.cpp
@@ -16,6 +16,7 @@
*/
/*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BP_1I_D16F32Cll_TRC_WRA_01_Private.h"
@@ -57,5 +58,6 @@
pBiquadState->coefs[1] = pCoef->B2;
pBiquadState->coefs[2] = pCoef->B1;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: BP_1I_D16F32Cll_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
index 0603256..ae52cf2 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D16F32Cll_TRC_WRA_01_Private.h
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#ifndef _BP_1I_D16F32CLL_TRC_WRA_01_PRIVATE_H_
#define _BP_1I_D16F32CLL_TRC_WRA_01_PRIVATE_H_
@@ -31,3 +32,4 @@
} Filter_State_Float;
typedef Filter_State_Float* PFilter_State_FLOAT;
#endif /*_BP_1I_D16F32CLL_TRC_WRA_01_PRIVATE_H_*/
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.cpp b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.cpp
index 0670334..6462092 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32C30_TRC_WRA_02.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BP_1I_D32F32Cll_TRC_WRA_02_Private.h"
#include "LVM_Macros.h"
@@ -68,3 +69,4 @@
*pDataOut++ = ynL; // Write Left output in Q0
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.cpp b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.cpp
index 146cc63..9b4cccc 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Init.cpp
@@ -16,6 +16,7 @@
*/
/*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BP_1I_D32F32Cll_TRC_WRA_02_Private.h"
@@ -49,5 +50,6 @@
pBiquadState->coefs[2] = pCoef->B1;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: BP_1I_D32F32Cll_TRC_WRA_02_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
index ea83c0b..93a7bfd 100644
--- a/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BP_1I_D32F32Cll_TRC_WRA_02_Private.h
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#ifndef _BP_1I_D32F32CLL_TRC_WRA_02_PRIVATE_H_
#define _BP_1I_D32F32CLL_TRC_WRA_02_PRIVATE_H_
@@ -32,3 +33,4 @@
typedef Filter_State_Float* PFilter_State_FLOAT;
#endif /*_BP_1I_D32F32CLL_TRC_WRA_02_PRIVATE_H_*/
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.cpp
index a46b1ef..85a7453 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16C15_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BQ_1I_D16F16Css_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
@@ -71,3 +72,4 @@
*pDataOut++ = (LVM_FLOAT)ynL; // Write Left output in Q0
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.cpp
index e8bfcd8..7ad0793 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Init.cpp
@@ -16,6 +16,7 @@
*/
/*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BQ_1I_D16F16Css_TRC_WRA_01_Private.h"
@@ -54,5 +55,6 @@
temp = pCoef->B1;
pBiquadState->coefs[4] = temp;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: BQ_1I_D16F16Css_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
index ac2819e..9d1a3b6 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#ifndef _BQ_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
#define _BQ_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
@@ -33,3 +34,4 @@
} Filter_State_FLOAT;
typedef Filter_State_FLOAT* PFilter_State_FLOAT;
#endif /*_BQ_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.cpp
index c60dcf8..58320f7 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32C14_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BQ_1I_D16F32Css_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
@@ -71,3 +72,4 @@
*pDataOut++ = (LVM_FLOAT)(ynL); // Write Left output
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
index af0efc8..3293b2e 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_Private.h
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#ifndef _BQ_1I_D16F32CSS_TRC_WRA_01_PRIVATE_H_
#define _BQ_1I_D16F32CSS_TRC_WRA_01_PRIVATE_H_
@@ -33,3 +34,4 @@
} Filter_State_FLOAT;
typedef Filter_State_FLOAT* PFilter_State_FLOAT;
#endif /*_BQ_1I_D16F32CSS_TRC_WRA_01_PRIVATE_H_*/
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.cpp b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.cpp
index ecf44ca..0d36e67 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_1I_D16F32Css_TRC_WRA_01_init.cpp
@@ -16,6 +16,7 @@
*/
/*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BQ_1I_D16F32Css_TRC_WRA_01_Private.h"
@@ -55,5 +56,6 @@
temp = pCoef->B1;
pBiquadState->coefs[4] = temp;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: BQ_1I_D16F32Css_TRC_WRA_01_Init */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.cpp
index d047e91..9ec9046 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C14_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BQ_2I_D16F16Css_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
@@ -98,3 +99,4 @@
*pDataOut++ = (LVM_FLOAT)ynR; // Write Right output
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.cpp
index 399b5ec..2478016 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16C15_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BQ_2I_D16F16Css_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
@@ -98,3 +99,4 @@
*pDataOut++ = (LVM_FLOAT)ynR; // Write Right output
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.cpp
index e0cd934..8b2de31 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Init.cpp
@@ -16,6 +16,7 @@
*/
/*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BQ_2I_D16F16Css_TRC_WRA_01_Private.h"
@@ -57,3 +58,4 @@
}
/*-------------------------------------------------------------------------*/
/* End Of File: BQ_2I_D16F16Css_TRC_WRA_01_Init.c */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
index 94cc794..f9a31a6 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F16Css_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#ifndef _BQ_2I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
#define _BQ_2I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
@@ -35,3 +36,4 @@
typedef Filter_State_FLOAT* PFilter_State_FLOAT;
#endif /* _BQ_2I_D16F16CSS_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.cpp
index 3b7eb5e..7a66bf9 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C13_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BQ_2I_D16F32Css_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
@@ -102,3 +103,4 @@
pDataOut++;
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.cpp
index 8c43430..db57150 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C14_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BQ_2I_D16F32Css_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
@@ -102,3 +103,4 @@
pDataOut++;
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.cpp
index 84fbadf..bc9e2df 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32C15_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BQ_2I_D16F32Css_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
@@ -102,3 +103,4 @@
pDataOut++;
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
index 1cc7618..de06cb1 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#ifndef _BQ_2I_D16F32CSS_TRC_WRA_01_PRIVATE_H_
#define _BQ_2I_D16F32CSS_TRC_WRA_01_PRIVATE_H_
@@ -35,3 +36,4 @@
typedef Filter_State_FLOAT* PFilter_State_FLOAT;
#endif /* _BQ_2I_D16F32CSS_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.cpp
index 6817d9f..0b9fb5a 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D16F32Css_TRC_WRA_01_init.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BQ_2I_D16F32Css_TRC_WRA_01_Private.h"
@@ -55,3 +56,4 @@
}
/*-------------------------------------------------------------------------*/
/* End Of File: BQ_2I_D16F32Css_TRC_WRA_01_Init */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.cpp
index 4eeaaa8..2097c4f 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32C30_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BQ_2I_D32F32Cll_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
@@ -184,3 +185,4 @@
}
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.cpp
index 1e27391..2d2a61f 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Init.cpp
@@ -16,6 +16,7 @@
*/
/*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "BQ_2I_D32F32Cll_TRC_WRA_01_Private.h"
@@ -54,5 +55,6 @@
temp = pCoef->B1;
pBiquadState->coefs[4] = temp;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: BQ_2I_D32F32C32_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
index 4a2149d..029c89d 100644
--- a/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/BQ_2I_D32F32Cll_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#ifndef _BQ_2I_D32F32CLL_TRC_WRA_01_PRIVATE_H_
#define _BQ_2I_D32F32CLL_TRC_WRA_01_PRIVATE_H_
@@ -35,3 +36,4 @@
typedef Filter_State_FLOAT* PFilter_State_FLOAT;
#endif /* _BQ_2I_D32F32CLL_TRC_WRA_01_PRIVATE_H_*/
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/Copy_16.cpp b/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
index 7bcb7d7..7046a94 100644
--- a/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Copy_16.cpp
@@ -21,31 +21,6 @@
#include <string.h>
#include "VectorArithmetic.h"
-/**********************************************************************************
- FUNCTION COPY_16
-***********************************************************************************/
-
-void Copy_16(const LVM_INT16* src, LVM_INT16* dst, LVM_INT16 n) {
- LVM_INT16 ii;
-
- if (src > dst) {
- for (ii = n; ii != 0; ii--) {
- *dst = *src;
- dst++;
- src++;
- }
- } else {
- src += n - 1;
- dst += n - 1;
- for (ii = n; ii != 0; ii--) {
- *dst = *src;
- dst--;
- src--;
- }
- }
-
- return;
-}
void Copy_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n) {
memmove(dst, src, n * sizeof(LVM_FLOAT));
return;
diff --git a/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.cpp
index be9e49b..b7f4b55 100644
--- a/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Core_MixInSoft_D32C31_SAT.cpp
@@ -18,9 +18,9 @@
/**********************************************************************************
INCLUDE FILES
***********************************************************************************/
-
#include "Mixer_private.h"
#include "LVM_Macros.h"
+#include "ScalarArithmetic.h"
/**********************************************************************************
FUNCTION CORE_MIXSOFT_1ST_D32C31_WRA
@@ -52,14 +52,7 @@
Temp2 = *dst;
Temp3 = Temp1 * (pInstance->Current);
- Temp1 = Temp2 + Temp3;
-
- if (Temp1 > 1.0f)
- Temp1 = 1.0f;
- else if (Temp1 < -1.0f)
- Temp1 = -1.0f;
-
- *dst++ = Temp1;
+ *dst++ = LVM_Clamp(Temp2 + Temp3);
}
}
@@ -72,13 +65,7 @@
Temp2 = *dst;
Temp3 = Temp1 * (pInstance->Current);
- Temp1 = Temp2 + Temp3;
-
- if (Temp1 > 1.0f)
- Temp1 = 1.0f;
- else if (Temp1 < -1.0f)
- Temp1 = -1.0f;
- *dst++ = Temp1;
+ *dst++ = LVM_Clamp(Temp2 + Temp3);
}
}
}
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp
index 2861be6..6e859f4 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01.cpp
@@ -14,51 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
#include "BIQUAD.h"
#include "DC_2I_D16_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
-void DC_2I_D16_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
- LVM_FLOAT* pDataOut, LVM_INT16 NrSamples) {
- LVM_FLOAT LeftDC, RightDC;
- LVM_FLOAT Diff;
- LVM_INT32 j;
- PFilter_FLOAT_State pBiquadState = (PFilter_FLOAT_State)pInstance;
-
- LeftDC = pBiquadState->LeftDC;
- RightDC = pBiquadState->RightDC;
- for (j = NrSamples - 1; j >= 0; j--) {
- /* Subtract DC and saturate */
- Diff = *(pDataIn++) - (LeftDC);
- if (Diff > 1.0f) {
- Diff = 1.0f;
- } else if (Diff < -1.0f) {
- Diff = -1.0f;
- }
- *(pDataOut++) = (LVM_FLOAT)Diff;
- if (Diff < 0) {
- LeftDC -= DC_FLOAT_STEP;
- } else {
- LeftDC += DC_FLOAT_STEP;
- }
-
- /* Subtract DC an saturate */
- Diff = *(pDataIn++) - (RightDC);
- if (Diff > 1.0f) {
- Diff = 1.0f;
- } else if (Diff < -1.0f) {
- Diff = -1.0f;
- }
- *(pDataOut++) = (LVM_FLOAT)Diff;
- if (Diff < 0) {
- RightDC -= DC_FLOAT_STEP;
- } else {
- RightDC += DC_FLOAT_STEP;
- }
- }
- pBiquadState->LeftDC = LeftDC;
- pBiquadState->RightDC = RightDC;
-}
+#include "ScalarArithmetic.h"
/*
* FUNCTION: DC_Mc_D16_TRC_WRA_01
*
@@ -89,12 +48,7 @@
/* Subtract DC and saturate */
for (i = NrChannels - 1; i >= 0; i--) {
Diff = *(pDataIn++) - (ChDC[i]);
- if (Diff > 1.0f) {
- Diff = 1.0f;
- } else if (Diff < -1.0f) {
- Diff = -1.0f;
- }
- *(pDataOut++) = (LVM_FLOAT)Diff;
+ *(pDataOut++) = LVM_Clamp(Diff);
if (Diff < 0) {
ChDC[i] -= DC_FLOAT_STEP;
} else {
diff --git a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp
index 2828cb3..c16718c 100644
--- a/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/DC_2I_D16_TRC_WRA_01_Init.cpp
@@ -17,11 +17,6 @@
#include "BIQUAD.h"
#include "DC_2I_D16_TRC_WRA_01_Private.h"
-void DC_2I_D16_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t* pInstance) {
- PFilter_FLOAT_State pBiquadState = (PFilter_FLOAT_State)pInstance;
- pBiquadState->LeftDC = 0.0f;
- pBiquadState->RightDC = 0.0f;
-}
void DC_Mc_D16_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t* pInstance) {
PFilter_FLOAT_State_Mc pBiquadState = (PFilter_FLOAT_State_Mc)pInstance;
LVM_INT32 i;
diff --git a/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.cpp b/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.cpp
deleted file mode 100644
index 5daef59..0000000
--- a/media/libeffects/lvm/lib/Common/src/DelayAllPass_Sat_32x16To32.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * 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.
- */
-
-/**********************************************************************************
- INCLUDE FILES
-***********************************************************************************/
-
-#include "LVM_Types.h"
-#include "LVM_Macros.h"
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
- FUNCTION DelayAllPass_32x32
-***********************************************************************************/
-
-void DelayAllPass_Sat_32x16To32(LVM_INT32* delay, /* Delay buffer */
- LVM_UINT16 size, /* Delay size */
- LVM_INT16 coeff, /* All pass filter coefficient */
- LVM_UINT16 DelayOffset, /* Simple delay offset */
- LVM_UINT16* pAllPassOffset, /* All pass filter delay offset */
- LVM_INT32* dst, /* Source/destination */
- LVM_INT16 n) /* Number of samples */
-{
- LVM_INT16 i;
- LVM_UINT16 AllPassOffset = *pAllPassOffset;
- LVM_INT32 temp;
- LVM_INT32 a, b, c;
-
- for (i = 0; i < n; i++) {
- MUL32x16INTO32(delay[AllPassOffset], coeff, temp, 15) a = temp;
- b = delay[DelayOffset];
- DelayOffset++;
-
- c = a + b;
- if ((((c ^ a) & (c ^ b)) >> 31) != 0) /* overflow / underflow */
- {
- if (a < 0) {
- c = 0x80000000L;
- } else {
- c = 0x7FFFFFFFL;
- }
- }
- *dst = c;
- dst++;
-
- MUL32x16INTO32(c, -coeff, temp, 15) a = temp;
- b = delay[AllPassOffset];
- c = a + b;
- if ((((c ^ a) & (c ^ b)) >> 31) != 0) /* overflow / underflow */
- {
- if (a < 0) {
- c = 0x80000000L;
- } else {
- c = 0x7FFFFFFFL;
- }
- }
- delay[AllPassOffset] = c;
- AllPassOffset++;
-
- /* Make the delay buffer a circular buffer */
- if (DelayOffset >= size) {
- DelayOffset = 0;
- }
-
- if (AllPassOffset >= size) {
- AllPassOffset = 0;
- }
- }
-
- /* Update the offset */
- *pAllPassOffset = AllPassOffset;
-
- return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.cpp b/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.cpp
index da75982..d2537eb 100644
--- a/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/DelayMix_16x16.cpp
@@ -21,51 +21,6 @@
#include "VectorArithmetic.h"
-/**********************************************************************************
- FUNCTION DelayMix_16x16
-***********************************************************************************/
-
-void DelayMix_16x16(const LVM_INT16* src, /* Source 1, to be delayed */
- LVM_INT16* delay, /* Delay buffer */
- LVM_INT16 size, /* Delay size */
- LVM_INT16* dst, /* Source/destination */
- LVM_INT16* pOffset, /* Delay offset */
- LVM_INT16 n) /* Number of stereo samples */
-{
- LVM_INT16 i;
- LVM_INT16 Offset = *pOffset;
- LVM_INT16 temp;
-
- for (i = 0; i < n; i++) {
- /* Left channel */
- temp = (LVM_INT16)((LVM_UINT32)((LVM_INT32)(*dst) + (LVM_INT32)delay[Offset]) >> 1);
- *dst = temp;
- dst++;
-
- delay[Offset] = *src;
- Offset++;
- src++;
-
- /* Right channel */
- temp = (LVM_INT16)((LVM_UINT32)((LVM_INT32)(*dst) - (LVM_INT32)delay[Offset]) >> 1);
- *dst = temp;
- dst++;
-
- delay[Offset] = *src;
- Offset++;
- src++;
-
- /* Make the reverb delay buffer a circular buffer */
- if (Offset >= size) {
- Offset = 0;
- }
- }
-
- /* Update the offset */
- *pOffset = Offset;
-
- return;
-}
void DelayMix_Float(const LVM_FLOAT* src, /* Source 1, to be delayed */
LVM_FLOAT* delay, /* Delay buffer */
LVM_INT16 size, /* Delay size */
@@ -107,4 +62,3 @@
return;
}
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/DelayWrite_32.cpp b/media/libeffects/lvm/lib/Common/src/DelayWrite_32.cpp
deleted file mode 100644
index 47cffbf..0000000
--- a/media/libeffects/lvm/lib/Common/src/DelayWrite_32.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * 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.
- */
-
-/**********************************************************************************
- INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
- FUNCTION DelayMix_16x16
-***********************************************************************************/
-
-void DelayWrite_32(const LVM_INT32* src, /* Source 1, to be delayed */
- LVM_INT32* delay, /* Delay buffer */
- LVM_UINT16 size, /* Delay size */
- LVM_UINT16* pOffset, /* Delay offset */
- LVM_INT16 n) /* Number of samples */
-{
- LVM_INT16 i;
- LVM_INT16 Offset = (LVM_INT16)*pOffset;
-
- for (i = 0; i < n; i++) {
- delay[Offset] = *src;
- Offset++;
- src++;
-
- /* Make the delay buffer a circular buffer */
- if (Offset >= size) {
- Offset = 0;
- }
- }
-
- /* Update the offset */
- *pOffset = (LVM_UINT16)Offset;
-
- return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.cpp
index df8fadc..c85dfb6 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16C15_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "FO_1I_D16F16Css_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
@@ -62,3 +63,4 @@
*pDataOut++ = (LVM_FLOAT)ynL; // Write Left output
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.cpp
index 10604bf..0cff849 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Init.cpp
@@ -16,6 +16,7 @@
*/
/*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "FO_1I_D16F16Css_TRC_WRA_01_Private.h"
@@ -52,3 +53,4 @@
}
/*------------------------------------------------*/
/* End Of File: FO_1I_D16F16Css_TRC_WRA_01_Init.c */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
index d1819fc..50b09b6 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D16F16Css_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#ifndef _FO_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
#define _FO_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_
@@ -35,3 +36,4 @@
typedef Filter_State_FLOAT* PFilter_State_FLOAT;
#endif /* _FO_1I_D16F16CSS_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.cpp
index 4c75e04..dac090f 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32C31_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "FO_1I_D32F32Cll_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
@@ -63,3 +64,4 @@
*pDataOut++ = (LVM_FLOAT)ynL; // Write Left output in Q0
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.cpp
index bf2e5e1..efd6bc0 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Init.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "FO_1I_D32F32Cll_TRC_WRA_01_Private.h"
@@ -50,5 +51,6 @@
temp = pCoef->B1;
pBiquadState->coefs[2] = temp;
}
+#endif
/*------------------------------------------------*/
/* End Of File: FO_1I_D32F32Cll_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
index 8645593..95705be 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_1I_D32F32Cll_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#ifndef _FO_1I_D32F32CLL_TRC_WRA_01_PRIVATE_H_
#define _FO_1I_D32F32CLL_TRC_WRA_01_PRIVATE_H_
@@ -34,3 +35,4 @@
typedef Filter_State_FLOAT* PFilter_State_FLOAT;
#endif /* _FO_1I_D32F32CLL_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp
index dad070b..1e3f1e8 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32C15_LShx_TRC_WRA_01.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
@@ -24,86 +25,6 @@
COEFS-
pBiquadState->coefs[0] is A1,
pBiquadState->coefs[1] is A0,
-pBiquadState->coefs[2] is -B1, these are in Q15 format
-pBiquadState->Shift is Shift value
-DELAYS-
-pBiquadState->pDelays[0] is x(n-1)L in Q15 format
-pBiquadState->pDelays[1] is y(n-1)L in Q30 format
-pBiquadState->pDelays[2] is x(n-1)R in Q15 format
-pBiquadState->pDelays[3] is y(n-1)R in Q30 format
-***************************************************************************/
-void FO_2I_D16F32C15_LShx_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
- LVM_FLOAT* pDataOut, LVM_INT16 NrSamples) {
- LVM_FLOAT ynL, ynR;
- LVM_FLOAT Temp;
- LVM_FLOAT NegSatValue;
- LVM_INT16 ii;
-
- PFilter_Float_State pBiquadState = (PFilter_Float_State)pInstance;
-
- NegSatValue = -1.0f;
-
- for (ii = NrSamples; ii != 0; ii--) {
- /**************************************************************************
- PROCESSING OF THE LEFT CHANNEL
- ***************************************************************************/
-
- // ynL =A1 * x(n-1)L
- ynL = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[0];
- // ynR =A1 * x(n-1)R
- ynR = (LVM_FLOAT)pBiquadState->coefs[0] * pBiquadState->pDelays[2];
-
- // ynL+=A0 * x(n)L
- ynL += (LVM_FLOAT)pBiquadState->coefs[1] * (*pDataIn);
- // ynR+=A0 * x(n)L
- ynR += (LVM_FLOAT)pBiquadState->coefs[1] * (*(pDataIn + 1));
-
- // ynL += (-B1 * y(n-1)L )
- Temp = pBiquadState->pDelays[1] * pBiquadState->coefs[2];
- ynL += Temp;
- // ynR += (-B1 * y(n-1)R ) )
- Temp = pBiquadState->pDelays[3] * pBiquadState->coefs[2];
- ynR += Temp;
-
- /**************************************************************************
- UPDATING THE DELAYS
- ***************************************************************************/
- pBiquadState->pDelays[1] = ynL; // Update y(n-1)L
- pBiquadState->pDelays[0] = (*pDataIn++); // Update x(n-1)L
-
- pBiquadState->pDelays[3] = ynR; // Update y(n-1)R
- pBiquadState->pDelays[2] = (*pDataIn++); // Update x(n-1)R
-
- /**************************************************************************
- WRITING THE OUTPUT
- ***************************************************************************/
-
- /*Saturate results*/
- if (ynL > 1.0f) {
- ynL = 1.0f;
- } else {
- if (ynL < NegSatValue) {
- ynL = NegSatValue;
- }
- }
-
- if (ynR > 1.0f) {
- ynR = 1.0f;
- } else {
- if (ynR < NegSatValue) {
- ynR = NegSatValue;
- }
- }
-
- *pDataOut++ = (LVM_FLOAT)ynL;
- *pDataOut++ = (LVM_FLOAT)ynR;
- }
-}
-/**************************************************************************
-ASSUMPTIONS:
-COEFS-
-pBiquadState->coefs[0] is A1,
-pBiquadState->coefs[1] is A0,
pBiquadState->coefs[2] is -B1,
DELAYS-
pBiquadState->pDelays[2*ch + 0] is x(n-1) of the 'ch' - channel
@@ -173,3 +94,4 @@
pDelays -= NrChannels * 2;
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.cpp
index 552aeda..54fbe4a 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.cpp
@@ -16,6 +16,7 @@
*/
/*-------------------------------------------------------------------------*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h"
@@ -51,5 +52,6 @@
temp = pCoef->B1;
pBiquadState->coefs[2] = temp;
}
+#endif
/*-------------------------------------------------------------------------*/
/* End Of File: FO_2I_D16F32Css_LShx_TRC_WRA_01_Init.c */
diff --git a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
index 0103328..a71fa32 100644
--- a/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/FO_2I_D16F32Css_LShx_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#ifndef _FO_2I_D16F32CSS_LSHX_TRC_WRA_01_PRIVATE_H_
#define _FO_2I_D16F32CSS_LSHX_TRC_WRA_01_PRIVATE_H_
@@ -27,3 +28,4 @@
typedef Filter_Float_State* PFilter_Float_State;
#endif /* _FO_2I_D16F32CSS_LSHX_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.cpp b/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.cpp
index b050267..e2f8c67 100644
--- a/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMS_16x16.cpp
@@ -21,33 +21,6 @@
#include "VectorArithmetic.h"
-/**********************************************************************************
- FUNCTION From2iToMS_16x16
-***********************************************************************************/
-
-void From2iToMS_16x16(const LVM_INT16* src, LVM_INT16* dstM, LVM_INT16* dstS, LVM_INT16 n) {
- LVM_INT32 temp1, left, right;
- LVM_INT16 ii;
- for (ii = n; ii != 0; ii--) {
- left = (LVM_INT32)*src;
- src++;
-
- right = (LVM_INT32)*src;
- src++;
-
- /* Compute M signal*/
- temp1 = (left + right) >> 1;
- *dstM = (LVM_INT16)temp1;
- dstM++;
-
- /* Compute S signal*/
- temp1 = (left - right) >> 1;
- *dstS = (LVM_INT16)temp1;
- dstS++;
- }
-
- return;
-}
void From2iToMS_Float(const LVM_FLOAT* src, LVM_FLOAT* dstM, LVM_FLOAT* dstS, LVM_INT16 n) {
LVM_FLOAT temp1, left, right;
LVM_INT16 ii;
@@ -71,4 +44,3 @@
return;
}
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMono_16.cpp b/media/libeffects/lvm/lib/Common/src/From2iToMono_16.cpp
deleted file mode 100644
index 9a54ee4..0000000
--- a/media/libeffects/lvm/lib/Common/src/From2iToMono_16.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * 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.
- */
-
-/**********************************************************************************
- INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
- FUNCTION From2iToMono_16
-***********************************************************************************/
-
-void From2iToMono_16(const LVM_INT16* src, LVM_INT16* dst, LVM_INT16 n) {
- LVM_INT16 ii;
- LVM_INT32 Temp;
- for (ii = n; ii != 0; ii--) {
- Temp = (LVM_INT32)*src;
- src++;
-
- Temp += (LVM_INT32)*src;
- src++;
-
- *dst = (LVM_INT16)(Temp >> 1);
- dst++;
- }
-
- return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp
index 6ede958..039ee14 100644
--- a/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp
+++ b/media/libeffects/lvm/lib/Common/src/From2iToMono_32.cpp
@@ -21,27 +21,6 @@
#include "VectorArithmetic.h"
-/**********************************************************************************
- FUNCTION From2iToMono_32
-***********************************************************************************/
-
-void From2iToMono_32(const LVM_INT32* src, LVM_INT32* dst, LVM_INT16 n) {
- LVM_INT16 ii;
- LVM_INT32 Temp;
-
- for (ii = n; ii != 0; ii--) {
- Temp = (*src >> 1);
- src++;
-
- Temp += (*src >> 1);
- src++;
-
- *dst = Temp;
- dst++;
- }
-
- return;
-}
void From2iToMono_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n) {
LVM_INT16 ii;
LVM_FLOAT Temp;
@@ -93,5 +72,3 @@
return;
}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Int16LShiftToInt32_16x32.cpp b/media/libeffects/lvm/lib/Common/src/Int16LShiftToInt32_16x32.cpp
deleted file mode 100644
index 9ddcbe4..0000000
--- a/media/libeffects/lvm/lib/Common/src/Int16LShiftToInt32_16x32.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * 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.
- */
-
-/**********************************************************************************
- INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
- FUNCTION INT16LSHIFTTOINT32_16X32
-***********************************************************************************/
-
-void Int16LShiftToInt32_16x32(const LVM_INT16* src, LVM_INT32* dst, LVM_INT16 n, LVM_INT16 shift) {
- LVM_INT16 ii;
-
- src += n - 1;
- dst += n - 1;
-
- for (ii = n; ii != 0; ii--) {
- *dst = (((LVM_INT32)*src) << shift);
- src--;
- dst--;
- }
-
- return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Int32RShiftToInt16_Sat_32x16.cpp b/media/libeffects/lvm/lib/Common/src/Int32RShiftToInt16_Sat_32x16.cpp
deleted file mode 100644
index 2584117..0000000
--- a/media/libeffects/lvm/lib/Common/src/Int32RShiftToInt16_Sat_32x16.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * 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.
- */
-
-/**********************************************************************************
- INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
- FUNCTION INT32RSHIFTTOINT16_SAT_32X16
-***********************************************************************************/
-
-void Int32RShiftToInt16_Sat_32x16(const LVM_INT32* src, LVM_INT16* dst, LVM_INT16 n,
- LVM_INT16 shift) {
- LVM_INT32 temp;
- LVM_INT16 ii;
-
- for (ii = n; ii != 0; ii--) {
- temp = *src >> shift;
- src++;
-
- if (temp > 0x00007FFF) {
- *dst = 0x7FFF;
- } else if (temp < -0x00008000) {
- *dst = -0x8000;
- } else {
- *dst = (LVM_INT16)temp;
- }
-
- dst++;
- }
-
- return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.cpp b/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.cpp
index 0721b76..6c7c8ae 100644
--- a/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.cpp
+++ b/media/libeffects/lvm/lib/Common/src/JoinTo2i_32x32.cpp
@@ -21,29 +21,6 @@
#include "VectorArithmetic.h"
-/**********************************************************************************
- FUNCTION JoinTo2i_32x32
-***********************************************************************************/
-
-void JoinTo2i_32x32(const LVM_INT32* srcL, const LVM_INT32* srcR, LVM_INT32* dst, LVM_INT16 n) {
- LVM_INT16 ii;
-
- srcL += n - 1;
- srcR += n - 1;
- dst += ((2 * n) - 1);
-
- for (ii = n; ii != 0; ii--) {
- *dst = *srcR;
- dst--;
- srcR--;
-
- *dst = *srcL;
- dst--;
- srcL--;
- }
-
- return;
-}
void JoinTo2i_Float(const LVM_FLOAT* srcL, const LVM_FLOAT* srcR, LVM_FLOAT* dst, LVM_INT16 n) {
LVM_INT16 ii;
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp
index 8b00925..d670b3d 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_1St_2i_D16C31_SAT.cpp
@@ -18,39 +18,10 @@
/**********************************************************************************
INCLUDE FILES
***********************************************************************************/
-
#include "LVC_Mixer_Private.h"
#include "LVM_Macros.h"
#include "ScalarArithmetic.h"
-/**********************************************************************************
- FUNCTION LVC_Core_MixHard_1St_2i_D16C31_SAT
-***********************************************************************************/
-void LVC_Core_MixHard_1St_2i_D16C31_SAT(LVMixer3_FLOAT_st* ptrInstance1,
- LVMixer3_FLOAT_st* ptrInstance2, const LVM_FLOAT* src,
- LVM_FLOAT* dst, LVM_INT16 n) {
- LVM_FLOAT Temp;
- LVM_INT16 ii;
- Mix_Private_FLOAT_st* pInstance1 = (Mix_Private_FLOAT_st*)(ptrInstance1->PrivateParams);
- Mix_Private_FLOAT_st* pInstance2 = (Mix_Private_FLOAT_st*)(ptrInstance2->PrivateParams);
- for (ii = n; ii != 0; ii--) {
- Temp = ((LVM_FLOAT) * (src++) * (LVM_FLOAT)pInstance1->Current);
- if (Temp > 1.0f)
- *dst++ = 1.0f;
- else if (Temp < -1.0f)
- *dst++ = -1.0f;
- else
- *dst++ = (LVM_FLOAT)Temp;
-
- Temp = ((LVM_FLOAT) * (src++) * (LVM_FLOAT)pInstance2->Current);
- if (Temp > 1.0f)
- *dst++ = 1.0f;
- else if (Temp < -1.0f)
- *dst++ = -1.0f;
- else
- *dst++ = (LVM_FLOAT)Temp;
- }
-}
void LVC_Core_MixHard_1St_MC_float_SAT(Mix_Private_FLOAT_st** ptrInstance, const LVM_FLOAT* src,
LVM_FLOAT* dst, LVM_INT16 NrFrames, LVM_INT16 NrChannels) {
LVM_FLOAT Temp;
@@ -58,14 +29,8 @@
for (ii = NrFrames; ii != 0; ii--) {
for (jj = 0; jj < NrChannels; jj++) {
Mix_Private_FLOAT_st* pInstance1 = (Mix_Private_FLOAT_st*)(ptrInstance[jj]);
- Temp = ((LVM_FLOAT) * (src++) * (LVM_FLOAT)pInstance1->Current);
- if (Temp > 1.0f)
- *dst++ = 1.0f;
- else if (Temp < -1.0f)
- *dst++ = -1.0f;
- else
- *dst++ = (LVM_FLOAT)Temp;
+ Temp = *src++ * pInstance1->Current;
+ *dst++ = LVM_Clamp(Temp);
}
}
}
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.cpp
index 31cd805..417c1f0 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixHard_2St_D16C31_SAT.cpp
@@ -18,8 +18,8 @@
/**********************************************************************************
INCLUDE FILES
***********************************************************************************/
-
#include "LVC_Mixer_Private.h"
+#include "ScalarArithmetic.h"
/**********************************************************************************
FUNCTION LVCore_MIXHARD_2ST_D16C31_SAT
@@ -34,18 +34,12 @@
Mix_Private_FLOAT_st* pInstance1 = (Mix_Private_FLOAT_st*)(ptrInstance1->PrivateParams);
Mix_Private_FLOAT_st* pInstance2 = (Mix_Private_FLOAT_st*)(ptrInstance2->PrivateParams);
- Current1 = (pInstance1->Current);
- Current2 = (pInstance2->Current);
+ Current1 = pInstance1->Current;
+ Current2 = pInstance2->Current;
for (ii = n; ii != 0; ii--) {
- Temp = (((LVM_FLOAT) * (src1++) * (LVM_FLOAT)Current1)) +
- (((LVM_FLOAT) * (src2++) * (LVM_FLOAT)Current2));
- if (Temp > 1.0f)
- *dst++ = 1.0f;
- else if (Temp < -1.0f)
- *dst++ = -1.0f;
- else
- *dst++ = Temp;
+ Temp = *src1++ * Current1 + *src2++ * Current2;
+ *dst++ = LVM_Clamp(Temp);
}
}
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.cpp
index b7865d9..d8c25c9 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixInSoft_D16C31_SAT.cpp
@@ -18,9 +18,9 @@
/**********************************************************************************
INCLUDE FILES
***********************************************************************************/
-
#include "LVC_Mixer_Private.h"
#include "LVM_Macros.h"
+#include "ScalarArithmetic.h"
/**********************************************************************************
FUNCTION LVCore_MIXSOFT_1ST_D16C31_WRA
@@ -46,13 +46,8 @@
if (Current > Target) Current = Target;
for (ii = OutLoop; ii != 0; ii--) {
- Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT) * (src++) * Current));
- if (Temp > 1.0f)
- *dst++ = 1.0f;
- else if (Temp < -1.0f)
- *dst++ = -1.0f;
- else
- *dst++ = (LVM_FLOAT)Temp;
+ Temp = *dst + *src++ * Current;
+ *dst++ = LVM_Clamp(Temp);
}
}
@@ -62,13 +57,8 @@
if (Current > Target) Current = Target;
for (jj = 4; jj != 0; jj--) {
- Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT) * (src++) * Current));
- if (Temp > 1.0f)
- *dst++ = 1.0f;
- else if (Temp < -1.0f)
- *dst++ = -1.0f;
- else
- *dst++ = (LVM_FLOAT)Temp;
+ Temp = *dst + *src++ * Current;
+ *dst++ = LVM_Clamp(Temp);
}
}
} else {
@@ -77,13 +67,8 @@
if (Current < Target) Current = Target;
for (ii = OutLoop; ii != 0; ii--) {
- Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT) * (src++) * Current));
- if (Temp > 1.0f)
- *dst++ = 1.0f;
- else if (Temp < -1.0f)
- *dst++ = -1.0f;
- else
- *dst++ = (LVM_FLOAT)Temp;
+ Temp = *dst + *src++ * Current;
+ *dst++ = LVM_Clamp(Temp);
}
}
@@ -92,13 +77,8 @@
if (Current < Target) Current = Target;
for (jj = 4; jj != 0; jj--) {
- Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT) * (src++) * Current));
- if (Temp > 1.0f)
- *dst++ = 1.0f;
- else if (Temp < -1.0f)
- *dst++ = -1.0f;
- else
- *dst++ = (LVM_FLOAT)Temp;
+ Temp = *dst + *src++ * Current;
+ *dst++ = LVM_Clamp(Temp);
}
}
}
@@ -148,13 +128,8 @@
if (Current > Target) Current = Target;
for (ii = OutLoop * NrChannels; ii != 0; ii--) {
- Temp = (*dst) + (*(src++) * Current);
- if (Temp > 1.0f)
- *dst++ = 1.0f;
- else if (Temp < -1.0f)
- *dst++ = -1.0f;
- else
- *dst++ = Temp;
+ Temp = *dst + *src++ * Current;
+ *dst++ = LVM_Clamp(Temp);
}
}
@@ -164,21 +139,11 @@
if (Current > Target) Current = Target;
for (jj = NrChannels; jj != 0; jj--) {
- Temp = (*dst) + (*(src++) * Current);
- if (Temp > 1.0f)
- *dst++ = 1.0f;
- else if (Temp < -1.0f)
- *dst++ = -1.0f;
- else
- *dst++ = Temp;
+ Temp = *dst + *src++ * Current;
+ *dst++ = LVM_Clamp(Temp);
- Temp = (*dst) + (*(src++) * Current);
- if (Temp > 1.0f)
- *dst++ = 1.0f;
- else if (Temp < -1.0f)
- *dst++ = -1.0f;
- else
- *dst++ = Temp;
+ Temp = *dst + *src++ * Current;
+ *dst++ = LVM_Clamp(Temp);
}
}
} else {
@@ -187,13 +152,8 @@
if (Current < Target) Current = Target;
for (ii = OutLoop * NrChannels; ii != 0; ii--) {
- Temp = (*dst) + (*(src++) * Current);
- if (Temp > 1.0f)
- *dst++ = 1.0f;
- else if (Temp < -1.0f)
- *dst++ = -1.0f;
- else
- *dst++ = Temp;
+ Temp = *dst + *src++ * Current;
+ *dst++ = LVM_Clamp(Temp);
}
}
@@ -202,21 +162,11 @@
if (Current < Target) Current = Target;
for (jj = NrChannels; jj != 0; jj--) {
- Temp = (*dst) + (*(src++) * Current);
- if (Temp > 1.0f)
- *dst++ = 1.0f;
- else if (Temp < -1.0f)
- *dst++ = -1.0f;
- else
- *dst++ = Temp;
+ Temp = *dst + *src++ * Current;
+ *dst++ = LVM_Clamp(Temp);
- Temp = (*dst) + (*(src++) * Current);
- if (Temp > 1.0f)
- *dst++ = 1.0f;
- else if (Temp < -1.0f)
- *dst++ = -1.0f;
- else
- *dst++ = Temp;
+ Temp = *dst + *src++ * Current;
+ *dst++ = LVM_Clamp(Temp);
}
}
}
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp
index d45845a..0968cf8 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_2i_D16C31_WRA.cpp
@@ -18,107 +18,16 @@
/**********************************************************************************
INCLUDE FILES
***********************************************************************************/
-
#include "LVC_Mixer_Private.h"
-#include "ScalarArithmetic.h"
#include "LVM_Macros.h"
+#include "ScalarArithmetic.h"
-/**********************************************************************************
- FUNCTION LVC_Core_MixSoft_1St_2i_D16C31_WRA
-***********************************************************************************/
-static LVM_FLOAT ADD2_SAT_FLOAT(LVM_FLOAT a, LVM_FLOAT b, LVM_FLOAT c) {
- LVM_FLOAT temp;
- temp = a + b;
- if (temp < -1.0f)
- c = -1.0f;
- else if (temp > 1.0f)
- c = 1.0f;
- else
- c = temp;
- return c;
-}
-void LVC_Core_MixSoft_1St_2i_D16C31_WRA(LVMixer3_FLOAT_st* ptrInstance1,
- LVMixer3_FLOAT_st* ptrInstance2, const LVM_FLOAT* src,
- LVM_FLOAT* dst, LVM_INT16 n) {
- LVM_INT16 OutLoop;
- LVM_INT16 InLoop;
- LVM_INT32 ii;
- Mix_Private_FLOAT_st* pInstanceL = (Mix_Private_FLOAT_st*)(ptrInstance1->PrivateParams);
- Mix_Private_FLOAT_st* pInstanceR = (Mix_Private_FLOAT_st*)(ptrInstance2->PrivateParams);
-
- LVM_FLOAT DeltaL = pInstanceL->Delta;
- LVM_FLOAT CurrentL = pInstanceL->Current;
- LVM_FLOAT TargetL = pInstanceL->Target;
-
- LVM_FLOAT DeltaR = pInstanceR->Delta;
- LVM_FLOAT CurrentR = pInstanceR->Current;
- LVM_FLOAT TargetR = pInstanceR->Target;
-
- LVM_FLOAT Temp = 0;
-
- InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
- OutLoop = (LVM_INT16)(n - (InLoop << 2));
-
- if (OutLoop) {
- if (CurrentL < TargetL) {
- ADD2_SAT_FLOAT(CurrentL, DeltaL, Temp);
- CurrentL = Temp;
- if (CurrentL > TargetL) CurrentL = TargetL;
- } else {
- CurrentL -= DeltaL;
- if (CurrentL < TargetL) CurrentL = TargetL;
- }
-
- if (CurrentR < TargetR) {
- ADD2_SAT_FLOAT(CurrentR, DeltaR, Temp);
- CurrentR = Temp;
- if (CurrentR > TargetR) CurrentR = TargetR;
- } else {
- CurrentR -= DeltaR;
- if (CurrentR < TargetR) CurrentR = TargetR;
- }
-
- for (ii = OutLoop * 2; ii != 0; ii -= 2) {
- *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
- *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
- }
- }
-
- for (ii = InLoop * 2; ii != 0; ii -= 2) {
- if (CurrentL < TargetL) {
- ADD2_SAT_FLOAT(CurrentL, DeltaL, Temp);
- CurrentL = Temp;
- if (CurrentL > TargetL) CurrentL = TargetL;
- } else {
- CurrentL -= DeltaL;
- if (CurrentL < TargetL) CurrentL = TargetL;
- }
-
- if (CurrentR < TargetR) {
- ADD2_SAT_FLOAT(CurrentR, DeltaR, Temp);
- CurrentR = Temp;
- if (CurrentR > TargetR) CurrentR = TargetR;
- } else {
- CurrentR -= DeltaR;
- if (CurrentR < TargetR) CurrentR = TargetR;
- }
-
- *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
- *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
- *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
- *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
- *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
- *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
- *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentL));
- *(dst++) = (LVM_FLOAT)(((LVM_FLOAT) * (src++) * (LVM_FLOAT)CurrentR));
- }
- pInstanceL->Current = CurrentL;
- pInstanceR->Current = CurrentR;
+static inline LVM_FLOAT ADD2_SAT_FLOAT(LVM_FLOAT a, LVM_FLOAT b) {
+ return LVM_Clamp(a + b);
}
void LVC_Core_MixSoft_1St_MC_float_WRA(Mix_Private_FLOAT_st** ptrInstance, const LVM_FLOAT* src,
LVM_FLOAT* dst, LVM_INT16 NrFrames, LVM_INT16 NrChannels) {
LVM_INT32 ii, ch;
- LVM_FLOAT Temp = 0.0f;
LVM_FLOAT tempCurrent[NrChannels];
for (ch = 0; ch < NrChannels; ch++) {
tempCurrent[ch] = ptrInstance[ch]->Current;
@@ -130,8 +39,7 @@
LVM_FLOAT Current = tempCurrent[ch];
const LVM_FLOAT Target = pInstance->Target;
if (Current < Target) {
- ADD2_SAT_FLOAT(Current, Delta, Temp);
- Current = Temp;
+ Current = ADD2_SAT_FLOAT(Current, Delta);
if (Current > Target) Current = Target;
} else {
Current -= Delta;
@@ -145,4 +53,3 @@
ptrInstance[ch]->Current = tempCurrent[ch];
}
}
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.cpp b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.cpp
index f8c0a9d..fc464e6 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Core_MixSoft_1St_D16C31_WRA.cpp
@@ -18,7 +18,6 @@
/**********************************************************************************
INCLUDE FILES
***********************************************************************************/
-
#include "LVC_Mixer_Private.h"
#include "LVM_Macros.h"
#include "ScalarArithmetic.h"
@@ -35,20 +34,13 @@
LVM_FLOAT Delta = (LVM_FLOAT)pInstance->Delta;
LVM_FLOAT Current = (LVM_FLOAT)pInstance->Current;
LVM_FLOAT Target = (LVM_FLOAT)pInstance->Target;
- LVM_FLOAT Temp;
InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
OutLoop = (LVM_INT16)(n - (InLoop << 2));
if (Current < Target) {
if (OutLoop) {
- Temp = Current + Delta;
- if (Temp > 1.0f)
- Temp = 1.0f;
- else if (Temp < -1.0f)
- Temp = -1.0f;
-
- Current = Temp;
+ Current = LVM_Clamp(Current + Delta);
if (Current > Target) Current = Target;
for (ii = OutLoop; ii != 0; ii--) {
@@ -57,14 +49,8 @@
}
for (ii = InLoop; ii != 0; ii--) {
- Temp = Current + Delta;
+ Current = LVM_Clamp(Current + Delta);
- if (Temp > 1.0f)
- Temp = 1.0f;
- else if (Temp < -1.0f)
- Temp = -1.0f;
-
- Current = Temp;
if (Current > Target) Current = Target;
*(dst++) = (((LVM_FLOAT) * (src++) * Current));
@@ -121,7 +107,6 @@
LVM_FLOAT Delta = (LVM_FLOAT)pInstance->Delta;
LVM_FLOAT Current = (LVM_FLOAT)pInstance->Current;
LVM_FLOAT Target = (LVM_FLOAT)pInstance->Target;
- LVM_FLOAT Temp;
/*
* Same operation is performed on consecutive frames.
@@ -134,13 +119,7 @@
if (Current < Target) {
if (OutLoop) {
- Temp = Current + Delta;
- if (Temp > 1.0f)
- Temp = 1.0f;
- else if (Temp < -1.0f)
- Temp = -1.0f;
-
- Current = Temp;
+ Current = LVM_Clamp(Current + Delta);
if (Current > Target) Current = Target;
for (ii = OutLoop; ii != 0; ii--) {
@@ -151,14 +130,7 @@
}
for (ii = InLoop; ii != 0; ii--) {
- Temp = Current + Delta;
-
- if (Temp > 1.0f)
- Temp = 1.0f;
- else if (Temp < -1.0f)
- Temp = -1.0f;
-
- Current = Temp;
+ Current = LVM_Clamp(Current + Delta);
if (Current > Target) Current = Target;
for (jj = NrChannels; jj != 0; jj--) {
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp
index c74c8c6..58bc06e 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp
+++ b/media/libeffects/lvm/lib/Common/src/LVC_MixSoft_1St_2i_D16C31_SAT.cpp
@@ -35,7 +35,7 @@
#define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof(*(a))))
/**********************************************************************************
- FUNCTION LVC_MixSoft_1St_2i_D16C31_SAT
+ FUNCTION LVC_MixSoft_1St_MC_float_SAT
***********************************************************************************/
/* This threshold is used to decide on the processing to be applied on
* front center and back center channels
@@ -192,106 +192,3 @@
}
}
}
-void LVC_MixSoft_1St_2i_D16C31_SAT(LVMixer3_2St_FLOAT_st* ptrInstance, const LVM_FLOAT* src,
- LVM_FLOAT* dst, LVM_INT16 n) {
- char HardMixing = TRUE;
- LVM_FLOAT TargetGain;
- Mix_Private_FLOAT_st* pInstance1 =
- (Mix_Private_FLOAT_st*)(ptrInstance->MixerStream[0].PrivateParams);
- Mix_Private_FLOAT_st* pInstance2 =
- (Mix_Private_FLOAT_st*)(ptrInstance->MixerStream[1].PrivateParams);
-
- if (n <= 0) return;
-
- /******************************************************************************
- SOFT MIXING
- *******************************************************************************/
- if ((pInstance1->Current != pInstance1->Target) ||
- (pInstance2->Current != pInstance2->Target)) {
- if (pInstance1->Delta == 1.0f) {
- pInstance1->Current = pInstance1->Target;
- TargetGain = pInstance1->Target;
- LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
- } else if (Abs_Float(pInstance1->Current - pInstance1->Target) < pInstance1->Delta) {
- pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. \
- Make them equal. */
- TargetGain = pInstance1->Target;
- LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
- } else {
- /* Soft mixing has to be applied */
- HardMixing = FALSE;
- }
-
- if (HardMixing == TRUE) {
- if (pInstance2->Delta == 1.0f) {
- pInstance2->Current = pInstance2->Target;
- TargetGain = pInstance2->Target;
- LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]), TargetGain);
- } else if (Abs_Float(pInstance2->Current - pInstance2->Target) < pInstance2->Delta) {
- pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore.
- \ Make them equal. */
- TargetGain = pInstance2->Target;
- LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]), TargetGain);
- } else {
- /* Soft mixing has to be applied */
- HardMixing = FALSE;
- }
- }
-
- if (HardMixing == FALSE) {
- LVC_Core_MixSoft_1St_2i_D16C31_WRA(&(ptrInstance->MixerStream[0]),
- &(ptrInstance->MixerStream[1]), src, dst, n);
- }
- }
-
- /******************************************************************************
- HARD MIXING
- *******************************************************************************/
-
- if (HardMixing) {
- if ((pInstance1->Target == 1.0f) && (pInstance2->Target == 1.0f)) {
- if (src != dst) {
- Copy_Float(src, dst, n);
- }
- } else {
- LVC_Core_MixHard_1St_2i_D16C31_SAT(&(ptrInstance->MixerStream[0]),
- &(ptrInstance->MixerStream[1]), src, dst, n);
- }
- }
-
- /******************************************************************************
- CALL BACK
- *******************************************************************************/
-
- if (ptrInstance->MixerStream[0].CallbackSet) {
- if (Abs_Float(pInstance1->Current - pInstance1->Target) < pInstance1->Delta) {
- pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. \
- Make them equal. */
- TargetGain = pInstance1->Target;
- LVC_Mixer_SetTarget(&ptrInstance->MixerStream[0], TargetGain);
- ptrInstance->MixerStream[0].CallbackSet = FALSE;
- if (ptrInstance->MixerStream[0].pCallBack != 0) {
- (*ptrInstance->MixerStream[0].pCallBack)(
- ptrInstance->MixerStream[0].pCallbackHandle,
- ptrInstance->MixerStream[0].pGeneralPurpose,
- ptrInstance->MixerStream[0].CallbackParam);
- }
- }
- }
- if (ptrInstance->MixerStream[1].CallbackSet) {
- if (Abs_Float(pInstance2->Current - pInstance2->Target) < pInstance2->Delta) {
- pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore.
- Make them equal. */
- TargetGain = pInstance2->Target;
- LVC_Mixer_SetTarget(&ptrInstance->MixerStream[1], TargetGain);
- ptrInstance->MixerStream[1].CallbackSet = FALSE;
- if (ptrInstance->MixerStream[1].pCallBack != 0) {
- (*ptrInstance->MixerStream[1].pCallBack)(
- ptrInstance->MixerStream[1].pCallbackHandle,
- ptrInstance->MixerStream[1].pGeneralPurpose,
- ptrInstance->MixerStream[1].CallbackParam);
- }
- }
- }
-}
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
index 55255a6..1eb2dea 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer.h
@@ -101,9 +101,6 @@
void LVC_MixSoft_1St_MC_float_SAT(LVMixer3_2St_FLOAT_st* pInstance, const LVM_FLOAT* src,
LVM_FLOAT* dst, /* dst can be equal to src */
LVM_INT16 NrFrames, LVM_INT32 NrChannels, LVM_INT32 ChMask);
-void LVC_MixSoft_1St_2i_D16C31_SAT(LVMixer3_2St_FLOAT_st* pInstance, const LVM_FLOAT* src,
- LVM_FLOAT* dst, /* dst can be equal to src */
- LVM_INT16 n); /* Number of stereo samples */
/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
index 5f22d77..9206fae 100644
--- a/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/LVC_Mixer_Private.h
@@ -65,9 +65,6 @@
/**********************************************************************************/
void LVC_Core_MixSoft_1St_MC_float_WRA(Mix_Private_FLOAT_st** ptrInstance, const LVM_FLOAT* src,
LVM_FLOAT* dst, LVM_INT16 NrFrames, LVM_INT16 NrChannels);
-void LVC_Core_MixSoft_1St_2i_D16C31_WRA(LVMixer3_FLOAT_st* ptrInstance1,
- LVMixer3_FLOAT_st* ptrInstance2, const LVM_FLOAT* src,
- LVM_FLOAT* dst, LVM_INT16 n);
/**********************************************************************************/
/* For applying different gains to Left and right chennals */
@@ -77,11 +74,5 @@
/**********************************************************************************/
void LVC_Core_MixHard_1St_MC_float_SAT(Mix_Private_FLOAT_st** ptrInstance, const LVM_FLOAT* src,
LVM_FLOAT* dst, LVM_INT16 NrFrames, LVM_INT16 NrChannels);
-void LVC_Core_MixHard_1St_2i_D16C31_SAT(LVMixer3_FLOAT_st* ptrInstance1,
- LVMixer3_FLOAT_st* ptrInstance2, const LVM_FLOAT* src,
- LVM_FLOAT* dst, LVM_INT16 n);
-
-/*** 32 bit functions *************************************************************/
-/**********************************************************************************/
#endif //#ifndef __LVC_MIXER_PRIVATE_H__
diff --git a/media/libeffects/lvm/lib/Common/src/LoadConst_16.cpp b/media/libeffects/lvm/lib/Common/src/LoadConst_16.cpp
deleted file mode 100644
index a39fa2f..0000000
--- a/media/libeffects/lvm/lib/Common/src/LoadConst_16.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * 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.
- */
-
-/**********************************************************************************
- INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
- FUNCTION LoadConst_16
-***********************************************************************************/
-
-void LoadConst_16(const LVM_INT16 val, LVM_INT16* dst, LVM_INT16 n) {
- LVM_INT16 ii;
-
- for (ii = n; ii != 0; ii--) {
- *dst = val;
- dst++;
- }
-
- return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.cpp b/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.cpp
index a19e66f..e5c6f15 100644
--- a/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/MSTo2i_Sat_16x16.cpp
@@ -18,49 +18,9 @@
/**********************************************************************************
INCLUDE FILES
***********************************************************************************/
-
+#include "ScalarArithmetic.h"
#include "VectorArithmetic.h"
-/**********************************************************************************
- FUNCTION MSTO2I_SAT_16X16
-***********************************************************************************/
-
-void MSTo2i_Sat_16x16(const LVM_INT16* srcM, const LVM_INT16* srcS, LVM_INT16* dst, LVM_INT16 n) {
- LVM_INT32 temp, mVal, sVal;
- LVM_INT16 ii;
-
- for (ii = n; ii != 0; ii--) {
- mVal = (LVM_INT32)*srcM;
- srcM++;
-
- sVal = (LVM_INT32)*srcS;
- srcS++;
-
- temp = mVal + sVal;
-
- if (temp > 0x00007FFF) {
- *dst = 0x7FFF;
- } else if (temp < -0x00008000) {
- *dst = -0x8000;
- } else {
- *dst = (LVM_INT16)temp;
- }
- dst++;
-
- temp = mVal - sVal;
-
- if (temp > 0x00007FFF) {
- *dst = 0x7FFF;
- } else if (temp < -0x00008000) {
- *dst = -0x8000;
- } else {
- *dst = (LVM_INT16)temp;
- }
- dst++;
- }
-
- return;
-}
void MSTo2i_Sat_Float(const LVM_FLOAT* srcM, const LVM_FLOAT* srcS, LVM_FLOAT* dst, LVM_INT16 n) {
LVM_FLOAT temp, mVal, sVal;
LVM_INT16 ii;
@@ -73,28 +33,11 @@
srcS++;
temp = mVal + sVal;
-
- if (temp > 1.0f) {
- *dst = 1.0f;
- } else if (temp < -1.0f) {
- *dst = -1.0f;
- } else {
- *dst = (LVM_FLOAT)temp;
- }
- dst++;
+ *dst++ = LVM_Clamp(temp);
temp = mVal - sVal;
-
- if (temp > 1.0f) {
- *dst = 1.0f;
- } else if (temp < -1.0f) {
- *dst = -1.0f;
- } else {
- *dst = (LVM_FLOAT)temp;
- }
- dst++;
+ *dst++ = LVM_Clamp(temp);
}
return;
}
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_16x16.cpp b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_16x16.cpp
deleted file mode 100644
index 1d450b0..0000000
--- a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_16x16.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * 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.
- */
-
-/**********************************************************************************
-
- %created_by: sra % (CM/S)
- %name: Mac3s_Sat_16x16.c % (CM/S)
- %version: 1 % (CM/S)
- %date_created: Fri Nov 13 12:07:13 2009 % (CM/S)
-
-***********************************************************************************/
-
-/**********************************************************************************
- INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-#include "LVM_Macros.h"
-
-/**********************************************************************************
- FUNCTION Mac3S_16X16
-***********************************************************************************/
-
-void Mac3s_Sat_16x16(const LVM_INT16* src, const LVM_INT16 val, LVM_INT16* dst, LVM_INT16 n) {
- LVM_INT16 ii;
- LVM_INT16 srcval;
- LVM_INT32 Temp, dInVal;
-
- for (ii = n; ii != 0; ii--) {
- srcval = *src;
- src++;
-
- Temp = (srcval * val) >> 15;
-
- dInVal = (LVM_INT32)*dst;
-
- Temp = Temp + dInVal;
-
- if (Temp > 0x00007FFF) {
- *dst = 0x7FFF;
- } else if (Temp < -0x00008000) {
- *dst = -0x8000;
- } else {
- *dst = (LVM_INT16)Temp;
- }
-
- dst++;
- }
-
- return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.cpp b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.cpp
index 0fe9fef..24bdf3e 100644
--- a/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Mac3s_Sat_32x16.cpp
@@ -18,66 +18,19 @@
/**********************************************************************************
INCLUDE FILES
***********************************************************************************/
-
+#include "ScalarArithmetic.h"
#include "VectorArithmetic.h"
#include "LVM_Macros.h"
-/**********************************************************************************
- FUNCTION MAC3S_16X16
-***********************************************************************************/
-
-void Mac3s_Sat_32x16(const LVM_INT32* src, const LVM_INT16 val, LVM_INT32* dst, LVM_INT16 n) {
- LVM_INT16 ii;
- LVM_INT32 srcval, temp, dInVal, dOutVal;
-
- for (ii = n; ii != 0; ii--) {
- srcval = *src;
- src++;
-
- MUL32x16INTO32(srcval, val, temp, 15)
-
- dInVal = *dst;
- dOutVal = temp + dInVal;
-
- if ((((dOutVal ^ temp) & (dOutVal ^ dInVal)) >> 31) != 0) /* overflow / underflow */
- {
- if (temp < 0) {
- dOutVal = 0x80000000L;
- } else {
- dOutVal = 0x7FFFFFFFL;
- }
- }
-
- *dst = dOutVal;
- dst++;
- }
-
- return;
-}
void Mac3s_Sat_Float(const LVM_FLOAT* src, const LVM_FLOAT val, LVM_FLOAT* dst, LVM_INT16 n) {
LVM_INT16 ii;
- LVM_FLOAT srcval;
- LVM_FLOAT Temp, dInVal;
for (ii = n; ii != 0; ii--) {
- srcval = *src;
- src++;
+ LVM_FLOAT Temp = *src++ * val;
+ Temp += *dst;
- Temp = srcval * val;
-
- dInVal = (LVM_FLOAT)*dst;
- Temp = Temp + dInVal;
-
- if (Temp > 1.000000f) {
- *dst = 1.000000f;
- } else if (Temp < -1.000000f) {
- *dst = -1.000000f;
- } else {
- *dst = Temp;
- }
- dst++;
+ *dst++ = LVM_Clamp(Temp);
}
return;
}
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MonoTo2I_16.cpp b/media/libeffects/lvm/lib/Common/src/MonoTo2I_16.cpp
deleted file mode 100644
index 7ab5d49..0000000
--- a/media/libeffects/lvm/lib/Common/src/MonoTo2I_16.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * 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.
- */
-
-/**********************************************************************************
- INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
- FUNCTION MonoTo2I_16
-***********************************************************************************/
-
-void MonoTo2I_16(const LVM_INT16* src, LVM_INT16* dst, LVM_INT16 n) {
- LVM_INT16 ii;
- src += (n - 1);
- dst += ((n * 2) - 1);
-
- for (ii = n; ii != 0; ii--) {
- *dst = *src;
- dst--;
-
- *dst = *src;
- dst--;
- src--;
- }
-
- return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.cpp b/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.cpp
index 1ba669f..ef3e633 100644
--- a/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.cpp
+++ b/media/libeffects/lvm/lib/Common/src/MonoTo2I_32.cpp
@@ -21,26 +21,6 @@
#include "VectorArithmetic.h"
-/**********************************************************************************
- FUNCTION MonoTo2I_32
-***********************************************************************************/
-
-void MonoTo2I_32(const LVM_INT32* src, LVM_INT32* dst, LVM_INT16 n) {
- LVM_INT16 ii;
- src += (n - 1);
- dst += ((n * 2) - 1);
-
- for (ii = n; ii != 0; ii--) {
- *dst = *src;
- dst--;
-
- *dst = *src;
- dst--;
- src--;
- }
-
- return;
-}
void MonoTo2I_Float(const LVM_FLOAT* src, LVM_FLOAT* dst, LVM_INT16 n) {
LVM_INT16 ii;
src += (n - 1);
@@ -57,4 +37,3 @@
return;
}
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.cpp b/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.cpp
index 4589703..babfef3 100644
--- a/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/Mult3s_32x16.cpp
@@ -22,26 +22,6 @@
#include "VectorArithmetic.h"
#include "LVM_Macros.h"
-/**********************************************************************************
-FUNCTION MULT3S_16X16
-***********************************************************************************/
-
-void Mult3s_32x16(const LVM_INT32* src, const LVM_INT16 val, LVM_INT32* dst, LVM_INT16 n) {
- LVM_INT16 ii;
- LVM_INT32 srcval, temp;
-
- for (ii = n; ii != 0; ii--) {
- srcval = *src;
- src++;
-
- MUL32x16INTO32(srcval, val, temp, 15)
-
- * dst = temp;
- dst++;
- }
-
- return;
-}
void Mult3s_Float(const LVM_FLOAT* src, const LVM_FLOAT val, LVM_FLOAT* dst, LVM_INT16 n) {
LVM_INT16 ii;
LVM_FLOAT temp;
@@ -54,4 +34,3 @@
}
return;
}
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.cpp b/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.cpp
index fba0666..f3a1a67 100644
--- a/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.cpp
+++ b/media/libeffects/lvm/lib/Common/src/NonLinComp_D16.cpp
@@ -61,43 +61,6 @@
/* */
/****************************************************************************************/
-void NonLinComp_D16(LVM_INT16 Gain, LVM_INT16* pDataIn, LVM_INT16* pDataOut,
- LVM_INT32 BlockLength) {
- LVM_INT16 Sample; /* Input samples */
- LVM_INT32 SampleNo; /* Sample index */
- LVM_INT16 Temp;
-
- /*
- * Process a block of samples
- */
- for (SampleNo = 0; SampleNo < BlockLength; SampleNo++) {
- /*
- * Read the input
- */
- Sample = *pDataIn;
- pDataIn++;
-
- /*
- * Apply the compander, this compresses the signal at the expense of
- * harmonic distortion. The amount of compression is control by the
- * gain factor
- */
- if ((LVM_INT32)Sample != -32768) {
- Temp = (LVM_INT16)((Sample * Sample) >> 15);
- if (Sample > 0) {
- Sample = (LVM_INT16)(Sample + ((Gain * (Sample - Temp)) >> 15));
- } else {
- Sample = (LVM_INT16)(Sample + ((Gain * (Sample + Temp)) >> 15));
- }
- }
-
- /*
- * Save the output
- */
- *pDataOut = Sample;
- pDataOut++;
- }
-}
void NonLinComp_Float(LVM_FLOAT Gain, LVM_FLOAT* pDataIn, LVM_FLOAT* pDataOut,
LVM_INT32 BlockLength) {
LVM_FLOAT Sample; /* Input samples */
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp
index 0afaad2..2a5540e 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32C14G11_TRC_WRA_01.cpp
@@ -15,102 +15,12 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "PK_2I_D32F32CssGss_TRC_WRA_01_Private.h"
#include "LVM_Macros.h"
/**************************************************************************
- ASSUMPTIONS:
- COEFS-
- pBiquadState->coefs[0] is A0,
- pBiquadState->coefs[1] is -B2,
- pBiquadState->coefs[2] is -B1, these are in Q14 format
- pBiquadState->coefs[3] is Gain, in Q11 format
-
- DELAYS-
- pBiquadState->pDelays[0] is x(n-1)L in Q0 format
- pBiquadState->pDelays[1] is x(n-1)R in Q0 format
- pBiquadState->pDelays[2] is x(n-2)L in Q0 format
- pBiquadState->pDelays[3] is x(n-2)R in Q0 format
- pBiquadState->pDelays[4] is y(n-1)L in Q0 format
- pBiquadState->pDelays[5] is y(n-1)R in Q0 format
- pBiquadState->pDelays[6] is y(n-2)L in Q0 format
- pBiquadState->pDelays[7] is y(n-2)R in Q0 format
-***************************************************************************/
-void PK_2I_D32F32C14G11_TRC_WRA_01(Biquad_FLOAT_Instance_t* pInstance, LVM_FLOAT* pDataIn,
- LVM_FLOAT* pDataOut, LVM_INT16 NrSamples) {
- LVM_FLOAT ynL, ynR, ynLO, ynRO, templ;
- LVM_INT16 ii;
- PFilter_State_Float pBiquadState = (PFilter_State_Float)pInstance;
-
- for (ii = NrSamples; ii != 0; ii--) {
- /**************************************************************************
- PROCESSING OF THE LEFT CHANNEL
- ***************************************************************************/
- /* ynL= (A0 * (x(n)L - x(n-2)L ) )*/
- templ = (*pDataIn) - pBiquadState->pDelays[2];
- ynL = templ * pBiquadState->coefs[0];
-
- /* ynL+= ((-B2 * y(n-2)L )) */
- templ = pBiquadState->pDelays[6] * pBiquadState->coefs[1];
- ynL += templ;
-
- /* ynL+= ((-B1 * y(n-1)L ) ) */
- templ = pBiquadState->pDelays[4] * pBiquadState->coefs[2];
- ynL += templ;
-
- /* ynLO= ((Gain * ynL )) */
- ynLO = ynL * pBiquadState->coefs[3];
-
- /* ynLO=( ynLO + x(n)L )*/
- ynLO += (*pDataIn);
-
- /**************************************************************************
- PROCESSING OF THE RIGHT CHANNEL
- ***************************************************************************/
- /* ynR= (A0 * (x(n)R - x(n-2)R ) ) */
- templ = (*(pDataIn + 1)) - pBiquadState->pDelays[3];
- ynR = templ * pBiquadState->coefs[0];
-
- /* ynR+= ((-B2 * y(n-2)R ) ) */
- templ = pBiquadState->pDelays[7] * pBiquadState->coefs[1];
- ynR += templ;
-
- /* ynR+= ((-B1 * y(n-1)R ) ) */
- templ = pBiquadState->pDelays[5] * pBiquadState->coefs[2];
- ynR += templ;
-
- /* ynRO= ((Gain * ynR )) */
- ynRO = ynR * pBiquadState->coefs[3];
-
- /* ynRO=( ynRO + x(n)R )*/
- ynRO += (*(pDataIn + 1));
-
- /**************************************************************************
- UPDATING THE DELAYS
- ***************************************************************************/
- pBiquadState->pDelays[7] = pBiquadState->pDelays[5]; /* y(n-2)R=y(n-1)R*/
- pBiquadState->pDelays[6] = pBiquadState->pDelays[4]; /* y(n-2)L=y(n-1)L*/
- pBiquadState->pDelays[3] = pBiquadState->pDelays[1]; /* x(n-2)R=x(n-1)R*/
- pBiquadState->pDelays[2] = pBiquadState->pDelays[0]; /* x(n-2)L=x(n-1)L*/
- pBiquadState->pDelays[5] = ynR; /* Update y(n-1)R */
- pBiquadState->pDelays[4] = ynL; /* Update y(n-1)L */
- pBiquadState->pDelays[0] = (*pDataIn); /* Update x(n-1)L */
- pDataIn++;
- pBiquadState->pDelays[1] = (*pDataIn); /* Update x(n-1)R */
- pDataIn++;
-
- /**************************************************************************
- WRITING THE OUTPUT
- ***************************************************************************/
- *pDataOut = ynLO; /* Write Left output*/
- pDataOut++;
- *pDataOut = ynRO; /* Write Right output*/
- pDataOut++;
- }
-}
-
-/**************************************************************************
DELAYS-
pBiquadState->pDelays[0] to
pBiquadState->pDelays[NrChannels - 1] is x(n-1) for all NrChannels
@@ -173,3 +83,4 @@
}
}
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Private.h
index 3f5d332..7fcd33c 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CllGss_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#ifndef _PK_2I_D32F32CLLGSS_TRC_WRA_01_PRIVATE_H_
#define _PK_2I_D32F32CLLGSS_TRC_WRA_01_PRIVATE_H_
@@ -28,3 +29,4 @@
typedef Filter_State* PFilter_State;
#endif /* _PK_2I_D32F32CLLGSS_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.cpp b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.cpp
index 178d766..d782631 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.cpp
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Init.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#include "BIQUAD.h"
#include "PK_2I_D32F32CssGss_TRC_WRA_01_Private.h"
void PK_2I_D32F32CssGss_TRC_WRA_01_Init(Biquad_FLOAT_Instance_t* pInstance,
@@ -31,3 +32,4 @@
pBiquadState->coefs[3] = pCoef->G;
}
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
index 57a1c16..4c9f069 100644
--- a/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
+++ b/media/libeffects/lvm/lib/Common/src/PK_2I_D32F32CssGss_TRC_WRA_01_Private.h
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#ifndef BIQUAD_OPT
#ifndef _PK_2I_D32F32CSSGSS_TRC_WRA_01_PRIVATE_H_
#define _PK_2I_D32F32CSSGSS_TRC_WRA_01_PRIVATE_H_
@@ -35,3 +36,4 @@
typedef Filter_State* PFilter_State;
#endif /* _PK_2I_D32F32CSSGSS_TRC_WRA_01_PRIVATE_H_ */
+#endif
diff --git a/media/libeffects/lvm/lib/Common/src/mult3s_16x16.cpp b/media/libeffects/lvm/lib/Common/src/mult3s_16x16.cpp
deleted file mode 100644
index 66f9132..0000000
--- a/media/libeffects/lvm/lib/Common/src/mult3s_16x16.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2004-2010 NXP Software
- * 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.
- */
-
-/**********************************************************************************
- INCLUDE FILES
-***********************************************************************************/
-
-#include "VectorArithmetic.h"
-
-/**********************************************************************************
- FUNCTION MULT3S_16X16
-***********************************************************************************/
-
-void Mult3s_16x16(const LVM_INT16* src, const LVM_INT16 val, LVM_INT16* dst, LVM_INT16 n) {
- LVM_INT16 ii;
- LVM_INT32 temp;
-
- for (ii = n; ii != 0; ii--) {
- temp = (LVM_INT32)(*src) * (LVM_INT32)val;
- src++;
-
- *dst = (LVM_INT16)(temp >> 15);
- dst++;
- }
-
- return;
-}
-
-/**********************************************************************************/
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp
index be846eb..a744339 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ApplyNewSettings.cpp
@@ -148,10 +148,6 @@
LVM_INT16 i;
LVM_FLOAT ScaleTable[] = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4,
LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4};
- LVM_INT16 MaxT_Delay[] = {LVREV_MAX_T0_DELAY, LVREV_MAX_T1_DELAY, LVREV_MAX_T2_DELAY,
- LVREV_MAX_T3_DELAY};
- LVM_INT16 MaxAP_Delay[] = {LVREV_MAX_AP0_DELAY, LVREV_MAX_AP1_DELAY, LVREV_MAX_AP2_DELAY,
- LVREV_MAX_AP3_DELAY};
/*
* For each delay line
@@ -171,7 +167,7 @@
* Set the fixed delay
*/
- Temp = (MaxT_Delay[i] - MaxAP_Delay[i]) * Fs / 192000;
+ Temp = (LVREV_MAX_T_DELAY[i] - LVREV_MAX_AP_DELAY[i]) * Fs / 192000;
pPrivate->Delay_AP[i] = pPrivate->T[i] - Temp;
/*
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp
index f542a2b..61b3732 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_ClearAudioBuffers.cpp
@@ -63,45 +63,13 @@
LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->HPTaps, 2);
LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->LPTaps, 2);
#endif
- if ((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays == LVREV_DELAYLINES_4) {
+ for (size_t i = 0; i < pLVREV_Private->InstanceParams.NumDelays; i++) {
#ifdef BIQUAD_OPT
- for (int i = 0; i < LVREV_DELAYLINES_4; i++) {
- pLVREV_Private->revLPFBiquad[i]->clear();
- }
+ pLVREV_Private->revLPFBiquad[i]->clear();
#else
- LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[3], 2);
- LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[2], 2);
- LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
- LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
+ LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[i], 2);
#endif
-
- LoadConst_Float(0, pLVREV_Private->pDelay_T[3], LVREV_MAX_T3_DELAY);
- LoadConst_Float(0, pLVREV_Private->pDelay_T[2], LVREV_MAX_T2_DELAY);
- LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
- LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
- }
-
- if ((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays >= LVREV_DELAYLINES_2) {
-#ifdef BIQUAD_OPT
- for (int i = 0; i < LVREV_DELAYLINES_2; i++) {
- pLVREV_Private->revLPFBiquad[i]->clear();
- }
-#else
- LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[1], 2);
- LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
-#endif
-
- LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
- LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
- }
-
- if ((LVM_UINT16)pLVREV_Private->InstanceParams.NumDelays >= LVREV_DELAYLINES_1) {
-#ifdef BIQUAD_OPT
- pLVREV_Private->revLPFBiquad[0]->clear();
-#else
- LoadConst_Float(0, (LVM_FLOAT*)&pLVREV_Private->pFastData->RevLPTaps[0], 2);
-#endif
- LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[i], LVREV_MAX_T_DELAY[i]);
}
return LVREV_SUCCESS;
}
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp
index 6ed0605..fa96e52 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetInstanceHandle.cpp
@@ -120,11 +120,11 @@
pLVREV_Private->MemoryTable = *pMemoryTable;
if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
- MaxBlockSize = LVREV_MAX_AP3_DELAY;
+ MaxBlockSize = LVREV_MAX_AP_DELAY[3];
} else if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
- MaxBlockSize = LVREV_MAX_AP1_DELAY;
+ MaxBlockSize = LVREV_MAX_AP_DELAY[1];
} else {
- MaxBlockSize = LVREV_MAX_AP0_DELAY;
+ MaxBlockSize = LVREV_MAX_AP_DELAY[0];
}
if (MaxBlockSize > pInstanceParams->MaxBlockSize) {
@@ -139,61 +139,18 @@
pLVREV_Private->pFastData =
(LVREV_FastData_st*)InstAlloc_AddMember(&FastData, sizeof(LVREV_FastData_st));
#endif
- if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
- pLVREV_Private->pDelay_T[3] =
- (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * sizeof(LVM_FLOAT));
- pLVREV_Private->pDelay_T[2] =
- (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T2_DELAY * sizeof(LVM_FLOAT));
- pLVREV_Private->pDelay_T[1] =
- (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
- pLVREV_Private->pDelay_T[0] =
- (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
-
- for (i = 0; i < 4; i++) {
- /* Scratch for each delay line output */
- pLVREV_Private->pScratchDelayLine[i] =
- (LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
- }
-
- LoadConst_Float(0, pLVREV_Private->pDelay_T[3], LVREV_MAX_T3_DELAY);
- LoadConst_Float(0, pLVREV_Private->pDelay_T[2], LVREV_MAX_T2_DELAY);
- LoadConst_Float(0, pLVREV_Private->pDelay_T[1], LVREV_MAX_T1_DELAY);
- LoadConst_Float(0, pLVREV_Private->pDelay_T[0], LVREV_MAX_T0_DELAY);
- }
-
- if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
- pLVREV_Private->pDelay_T[1] =
- (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
- pLVREV_Private->pDelay_T[0] =
- (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
-
- for (i = 0; i < 2; i++) {
- /* Scratch for each delay line output */
- pLVREV_Private->pScratchDelayLine[i] =
- (LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
- }
-
- LoadConst_Float(0, pLVREV_Private->pDelay_T[1], (LVM_INT16)LVREV_MAX_T1_DELAY);
- LoadConst_Float(0, pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
- }
-
- if (pInstanceParams->NumDelays == LVREV_DELAYLINES_1) {
- pLVREV_Private->pDelay_T[0] =
- (LVM_FLOAT*)InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
-
- for (i = 0; i < 1; i++) {
- /* Scratch for each delay line output */
- pLVREV_Private->pScratchDelayLine[i] =
- (LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
- }
-
- LoadConst_Float(0, pLVREV_Private->pDelay_T[0], (LVM_INT16)LVREV_MAX_T0_DELAY);
+ for (size_t i = 0; i < pInstanceParams->NumDelays; i++) {
+ pLVREV_Private->pDelay_T[i] = (LVM_FLOAT*)InstAlloc_AddMember(
+ &FastData, LVREV_MAX_T_DELAY[i] * sizeof(LVM_FLOAT));
+ /* Scratch for each delay line output */
+ pLVREV_Private->pScratchDelayLine[i] =
+ (LVM_FLOAT*)InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
+ LoadConst_Float(0, pLVREV_Private->pDelay_T[i], LVREV_MAX_T_DELAY[i]);
}
/* All-pass delay buffer addresses and sizes */
- pLVREV_Private->T[0] = LVREV_MAX_T0_DELAY;
- pLVREV_Private->T[1] = LVREV_MAX_T1_DELAY;
- pLVREV_Private->T[2] = LVREV_MAX_T2_DELAY;
- pLVREV_Private->T[3] = LVREV_MAX_T3_DELAY;
+ for (size_t i = 0; i < LVREV_DELAYLINES_4; i++) {
+ pLVREV_Private->T[i] = LVREV_MAX_T_DELAY[i];
+ }
pLVREV_Private->AB_Selection = 1; /* Select smoothing A to B */
#ifndef BIQUAD_OPT
@@ -303,14 +260,10 @@
pLVREV_Private->FeedbackMixer[i].Target = 0;
}
/* Delay tap index */
- pLVREV_Private->A_DelaySize[0] = LVREV_MAX_AP0_DELAY;
- pLVREV_Private->B_DelaySize[0] = LVREV_MAX_AP0_DELAY;
- pLVREV_Private->A_DelaySize[1] = LVREV_MAX_AP1_DELAY;
- pLVREV_Private->B_DelaySize[1] = LVREV_MAX_AP1_DELAY;
- pLVREV_Private->A_DelaySize[2] = LVREV_MAX_AP2_DELAY;
- pLVREV_Private->B_DelaySize[2] = LVREV_MAX_AP2_DELAY;
- pLVREV_Private->A_DelaySize[3] = LVREV_MAX_AP3_DELAY;
- pLVREV_Private->B_DelaySize[3] = LVREV_MAX_AP3_DELAY;
+ for (size_t i = 0; i < LVREV_DELAYLINES_4; i++) {
+ pLVREV_Private->A_DelaySize[i] = LVREV_MAX_AP_DELAY[i];
+ pLVREV_Private->B_DelaySize[i] = LVREV_MAX_AP_DELAY[i];
+ }
#ifdef BIQUAD_OPT
pLVREV_Private->pRevHPFBiquad.reset(
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
index e8b2019..b344b20 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_GetMemoryTable.cpp
@@ -63,7 +63,6 @@
INST_ALLOC FastData;
INST_ALLOC FastCoef;
INST_ALLOC Temporary;
- LVM_INT16 i;
LVM_UINT16 MaxBlockSize;
/*
@@ -117,11 +116,11 @@
* Select the maximum internal block size
*/
if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
- MaxBlockSize = LVREV_MAX_AP3_DELAY;
+ MaxBlockSize = LVREV_MAX_AP_DELAY[3];
} else if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
- MaxBlockSize = LVREV_MAX_AP1_DELAY;
+ MaxBlockSize = LVREV_MAX_AP_DELAY[1];
} else {
- MaxBlockSize = LVREV_MAX_AP0_DELAY;
+ MaxBlockSize = LVREV_MAX_AP_DELAY[0];
}
if (MaxBlockSize > pInstanceParams->MaxBlockSize) {
@@ -142,20 +141,8 @@
#ifndef BIQUAD_OPT
InstAlloc_AddMember(&FastData, sizeof(LVREV_FastData_st));
#endif
- if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
- InstAlloc_AddMember(&FastData, LVREV_MAX_T3_DELAY * sizeof(LVM_FLOAT));
- InstAlloc_AddMember(&FastData, LVREV_MAX_T2_DELAY * sizeof(LVM_FLOAT));
- InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
- InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
- }
-
- if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
- InstAlloc_AddMember(&FastData, LVREV_MAX_T1_DELAY * sizeof(LVM_FLOAT));
- InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
- }
-
- if (pInstanceParams->NumDelays == LVREV_DELAYLINES_1) {
- InstAlloc_AddMember(&FastData, LVREV_MAX_T0_DELAY * sizeof(LVM_FLOAT));
+ for (size_t i = 0; i < pInstanceParams->NumDelays; i++) {
+ InstAlloc_AddMember(&FastData, LVREV_MAX_T_DELAY[i] * sizeof(LVM_FLOAT));
}
pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].Size = InstAlloc_GetTotal(&FastData);
@@ -179,25 +166,9 @@
InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
/* Mono->stereo input saved for end mix */
InstAlloc_AddMember(&Temporary, 2 * sizeof(LVM_FLOAT) * MaxBlockSize);
- if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
- for (i = 0; i < 4; i++) {
- /* A Scratch buffer for each delay line */
- InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
- }
- }
-
- if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
- for (i = 0; i < 2; i++) {
- /* A Scratch buffer for each delay line */
- InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
- }
- }
-
- if (pInstanceParams->NumDelays == LVREV_DELAYLINES_1) {
- for (i = 0; i < 1; i++) {
- /* A Scratch buffer for each delay line */
- InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
- }
+ for (size_t i = 0; i < pInstanceParams->NumDelays; i++) {
+ /* A Scratch buffer for each delay line */
+ InstAlloc_AddMember(&Temporary, sizeof(LVM_FLOAT) * MaxBlockSize);
}
pMemoryTable->Region[LVM_TEMPORARY_FAST].Size = InstAlloc_GetTotal(&Temporary);
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
index e52a1ca..c62ad1e 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
@@ -110,14 +110,15 @@
typedef struct {
Biquad_1I_Order1_FLOAT_Taps_t HPTaps; /* High pass filter taps */
Biquad_1I_Order1_FLOAT_Taps_t LPTaps; /* Low pass filter taps */
- Biquad_1I_Order1_FLOAT_Taps_t RevLPTaps[4]; /* Reverb low pass filters taps */
+ Biquad_1I_Order1_FLOAT_Taps_t RevLPTaps[LVREV_DELAYLINES_4]; /* Reverb low pass filters taps */
} LVREV_FastData_st;
/* Fast coefficient structure */
typedef struct {
Biquad_FLOAT_Instance_t HPCoefs; /* High pass filter coefficients */
Biquad_FLOAT_Instance_t LPCoefs; /* Low pass filter coefficients */
- Biquad_FLOAT_Instance_t RevLPCoefs[4]; /* Reverb low pass filters coefficients */
+ Biquad_FLOAT_Instance_t
+ RevLPCoefs[LVREV_DELAYLINES_4]; /* Reverb low pass filters coefficients */
} LVREV_FastCoef_st;
#endif
@@ -150,28 +151,28 @@
LVREV_FastData_st* pFastData; /* Fast data memory base address */
LVREV_FastCoef_st* pFastCoef; /* Fast coefficient memory base address */
#endif
- LVM_FLOAT* pScratchDelayLine[4]; /* Delay line scratch memory */
+ LVM_FLOAT* pScratchDelayLine[LVREV_DELAYLINES_4]; /* Delay line scratch memory */
LVM_FLOAT* pScratch; /* Multi ussge scratch */
LVM_FLOAT* pInputSave; /* Reverb block input save for dry/wet
mixing*/
/* Feedback matrix */
- Mix_1St_Cll_FLOAT_t FeedbackMixer[4]; /* Mixer for Pop and Click Suppression \
+ Mix_1St_Cll_FLOAT_t FeedbackMixer[LVREV_DELAYLINES_4]; /* Mixer for Pop and Click Suppression \
caused by feedback Gain */
/* All-Pass Filter */
- LVM_INT32 T[4]; /* Maximum delay size of buffer */
- LVM_FLOAT* pDelay_T[4]; /* Pointer to delay buffers */
- LVM_INT32 Delay_AP[4]; /* Offset to AP delay buffer start */
+ LVM_INT32 T[LVREV_DELAYLINES_4]; /* Maximum delay size of buffer */
+ LVM_FLOAT* pDelay_T[LVREV_DELAYLINES_4]; /* Pointer to delay buffers */
+ LVM_INT32 Delay_AP[LVREV_DELAYLINES_4]; /* Offset to AP delay buffer start */
LVM_INT16 AB_Selection; /* Smooth from tap A to B when 1 \
otherwise B to A */
- LVM_INT32 A_DelaySize[4]; /* A delay length in samples */
- LVM_INT32 B_DelaySize[4]; /* B delay length in samples */
- LVM_FLOAT* pOffsetA[4]; /* Offset for the A delay tap */
- LVM_FLOAT* pOffsetB[4]; /* Offset for the B delay tap */
- Mix_2St_Cll_FLOAT_t Mixer_APTaps[4]; /* Smoothed AP delay mixer */
- Mix_1St_Cll_FLOAT_t Mixer_SGFeedback[4]; /* Smoothed SAfeedback gain */
- Mix_1St_Cll_FLOAT_t Mixer_SGFeedforward[4]; /* Smoothed AP feedforward gain */
+ LVM_INT32 A_DelaySize[LVREV_DELAYLINES_4]; /* A delay length in samples */
+ LVM_INT32 B_DelaySize[LVREV_DELAYLINES_4]; /* B delay length in samples */
+ LVM_FLOAT* pOffsetA[LVREV_DELAYLINES_4]; /* Offset for the A delay tap */
+ LVM_FLOAT* pOffsetB[LVREV_DELAYLINES_4]; /* Offset for the B delay tap */
+ Mix_2St_Cll_FLOAT_t Mixer_APTaps[LVREV_DELAYLINES_4]; /* Smoothed AP delay mixer */
+ Mix_1St_Cll_FLOAT_t Mixer_SGFeedback[LVREV_DELAYLINES_4]; /* Smoothed SAfeedback gain */
+ Mix_1St_Cll_FLOAT_t Mixer_SGFeedforward[LVREV_DELAYLINES_4]; /* Smoothed AP feedforward gain */
/* Output gain */
Mix_2St_Cll_FLOAT_t BypassMixer; /* Dry/wet mixer */
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.cpp b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.cpp
index 35a6522..bb6cf12 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.cpp
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.cpp
@@ -29,6 +29,11 @@
/* */
/****************************************************************************************/
+const LVM_INT16 LVREV_MAX_T_DELAY[] = {LVREV_MAX_T0_DELAY, LVREV_MAX_T1_DELAY, LVREV_MAX_T2_DELAY,
+ LVREV_MAX_T3_DELAY};
+const LVM_INT16 LVREV_MAX_AP_DELAY[] = {LVREV_MAX_AP0_DELAY, LVREV_MAX_AP1_DELAY,
+ LVREV_MAX_AP2_DELAY, LVREV_MAX_AP3_DELAY};
+
/* Table with supported sampling rates. The table can be indexed using LVM_Fs_en */
const LVM_UINT32 LVM_FsTable[] = {8000, 11025, 12000, 16000, 22050, 24000, 32000,
44100, 48000, 88200, 96000, 176400, 192000};
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
index 4b0dcca..723d1ff 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.h
@@ -35,6 +35,8 @@
extern LVM_UINT32 LVM_GetFsFromTable(LVM_Fs_en FsIndex);
extern const LVM_FLOAT LVREV_GainPolyTable[24][5];
+extern const LVM_INT16 LVREV_MAX_T_DELAY[];
+extern const LVM_INT16 LVREV_MAX_AP_DELAY[];
#endif /** _LVREV_TABLES_H_ **/
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp
index 4e90a42..436e7cb 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Control.cpp
@@ -15,6 +15,9 @@
* limitations under the License.
*/
+#ifdef BIQUAD_OPT
+#include <system/audio.h>
+#endif
#include "LVPSA.h"
#include "LVPSA_Private.h"
#include "VectorArithmetic.h"
@@ -182,6 +185,13 @@
break;
}
}
+#ifdef BIQUAD_OPT
+ /*
+ * Create biquad instance
+ */
+ pInst->specBiquad.resize(pInst->nRelevantFilters,
+ android::audio_utils::BiquadFilter<LVM_FLOAT>(FCC_1));
+#endif
LVPSA_SetBPFiltersType(pInst, &Params);
LVPSA_SetBPFCoefficients(pInst, &Params);
LVPSA_SetQPFCoefficients(pInst, &Params);
@@ -302,8 +312,18 @@
/*
* Set the coefficients
*/
+#ifdef BIQUAD_OPT
+ const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+ Coefficients.A0, 0.0, -(Coefficients.A0), -(Coefficients.B1),
+ -(Coefficients.B2)};
+ pInst->specBiquad[ii]
+ .setCoefficients<
+ std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs>>(
+ coefs);
+#else
BP_1I_D16F32Cll_TRC_WRA_01_Init(&pInst->pBP_Instances[ii], &pInst->pBP_Taps[ii],
&Coefficients);
+#endif
break;
}
@@ -319,8 +339,18 @@
/*
* Set the coefficients
*/
+#ifdef BIQUAD_OPT
+ const std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs> coefs = {
+ Coefficients.A0, 0.0, -(Coefficients.A0), -(Coefficients.B1),
+ -(Coefficients.B2)};
+ pInst->specBiquad[ii]
+ .setCoefficients<
+ std::array<LVM_FLOAT, android::audio_utils::kBiquadNumCoefs>>(
+ coefs);
+#else
BP_1I_D16F16Css_TRC_WRA_01_Init(&pInst->pBP_Instances[ii], &pInst->pBP_Taps[ii],
&Coefficients);
+#endif
break;
}
}
@@ -604,6 +634,11 @@
/* */
/************************************************************************************/
LVPSA_RETURN LVPSA_ClearFilterHistory(LVPSA_InstancePr_t* pInst) {
+#ifdef BIQUAD_OPT
+ for (size_t i = 0; i < pInst->specBiquad.size(); i++) {
+ pInst->specBiquad[i].clear();
+ }
+#else
LVM_INT8* pTapAddress;
LVM_UINT32 i;
@@ -617,6 +652,7 @@
for (i = 0; i < pInst->nBands * sizeof(QPD_Taps_t); i++) {
pTapAddress[i] = 0;
}
+#endif
return (LVPSA_OK);
}
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp
index 9a2b29f..f77460b 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Init.cpp
@@ -108,21 +108,25 @@
if (pLVPSA_Inst->pBPFiltersPrecision == LVM_NULL) {
return LVPSA_ERROR_NULLADDRESS;
}
+#ifndef BIQUAD_OPT
pLVPSA_Inst->pBP_Instances = (Biquad_FLOAT_Instance_t*)calloc(
pInitParams->nBands, sizeof(*(pLVPSA_Inst->pBP_Instances)));
if (pLVPSA_Inst->pBP_Instances == LVM_NULL) {
return LVPSA_ERROR_NULLADDRESS;
}
+#endif
pLVPSA_Inst->pQPD_States =
(QPD_FLOAT_State_t*)calloc(pInitParams->nBands, sizeof(*(pLVPSA_Inst->pQPD_States)));
if (pLVPSA_Inst->pQPD_States == LVM_NULL) {
return LVPSA_ERROR_NULLADDRESS;
}
+#ifndef BIQUAD_OPT
pLVPSA_Inst->pBP_Taps = (Biquad_1I_Order2_FLOAT_Taps_t*)calloc(
pInitParams->nBands, sizeof(*(pLVPSA_Inst->pBP_Taps)));
if (pLVPSA_Inst->pBP_Taps == LVM_NULL) {
return LVPSA_ERROR_NULLADDRESS;
}
+#endif
pLVPSA_Inst->pQPD_Taps =
(QPD_FLOAT_Taps_t*)calloc(pInitParams->nBands, sizeof(*(pLVPSA_Inst->pQPD_Taps)));
if (pLVPSA_Inst->pQPD_Taps == LVM_NULL) {
@@ -193,18 +197,22 @@
free(pLVPSA_Inst->pBPFiltersPrecision);
pLVPSA_Inst->pBPFiltersPrecision = LVM_NULL;
}
+#ifndef BIQUAD_OPT
if (pLVPSA_Inst->pBP_Instances != LVM_NULL) {
free(pLVPSA_Inst->pBP_Instances);
pLVPSA_Inst->pBP_Instances = LVM_NULL;
}
+#endif
if (pLVPSA_Inst->pQPD_States != LVM_NULL) {
free(pLVPSA_Inst->pQPD_States);
pLVPSA_Inst->pQPD_States = LVM_NULL;
}
+#ifndef BIQUAD_OPT
if (pLVPSA_Inst->pBP_Taps != LVM_NULL) {
free(pLVPSA_Inst->pBP_Taps);
pLVPSA_Inst->pBP_Taps = LVM_NULL;
}
+#endif
if (pLVPSA_Inst->pQPD_Taps != LVM_NULL) {
free(pLVPSA_Inst->pQPD_Taps);
pLVPSA_Inst->pQPD_Taps = LVM_NULL;
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
index e00c11c..553156f 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
@@ -18,6 +18,9 @@
#ifndef _LVPSA_PRIVATE_H_
#define _LVPSA_PRIVATE_H_
+#ifdef BIQUAD_OPT
+#include <audio_utils/BiquadFilter.h>
+#endif
#include "LVPSA.h"
#include "BIQUAD.h"
#include "LVPSA_QPD.h"
@@ -82,9 +85,14 @@
LVPSA_BPFilterPrecision_en* pBPFiltersPrecision; /* Points a nBands elements array that contains
the filter precision for each band */
+#ifdef BIQUAD_OPT
+ std::vector<android::audio_utils::BiquadFilter<LVM_FLOAT>>
+ specBiquad; /* Biquad filter instances */
+#else
Biquad_FLOAT_Instance_t* pBP_Instances;
/* Points a nBands elements array that contains the band pass filter taps for each band */
Biquad_1I_Order2_FLOAT_Taps_t* pBP_Taps;
+#endif
/* Points a nBands elements array that contains the QPD filter instance for each band */
QPD_FLOAT_State_t* pQPD_States;
/* Points a nBands elements array that contains the QPD filter taps for each band */
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp
index 299dfd2..148b21f 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Process.cpp
@@ -96,13 +96,23 @@
for (ii = 0; ii < pLVPSA_Inst->nRelevantFilters; ii++) {
switch (pLVPSA_Inst->pBPFiltersPrecision[ii]) {
case LVPSA_SimplePrecisionFilter:
+#ifdef BIQUAD_OPT
+ pLVPSA_Inst->specBiquad[ii].process(pScratch + InputBlockSize, pScratch,
+ (LVM_INT16)InputBlockSize);
+#else
BP_1I_D16F16C14_TRC_WRA_01(&pLVPSA_Inst->pBP_Instances[ii], pScratch,
pScratch + InputBlockSize, (LVM_INT16)InputBlockSize);
+#endif
break;
case LVPSA_DoublePrecisionFilter:
+#ifdef BIQUAD_OPT
+ pLVPSA_Inst->specBiquad[ii].process(pScratch + InputBlockSize, pScratch,
+ (LVM_INT16)InputBlockSize);
+#else
BP_1I_D16F32C30_TRC_WRA_01(&pLVPSA_Inst->pBP_Instances[ii], pScratch,
pScratch + InputBlockSize, (LVM_INT16)InputBlockSize);
+#endif
break;
default:
break;
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
index c0d0950..18b350d 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Equaliser.h
@@ -23,12 +23,12 @@
/* Structures */
/* */
/************************************************************************************/
-
+#ifndef BIQUAD_OPT
/* Equaliser structure */
typedef struct {
void (*pBiquadCallBack)(Biquad_FLOAT_Instance_t*, LVM_FLOAT*, LVM_FLOAT*, LVM_INT16);
} LVCS_Equaliser_t;
-
+#endif
/************************************************************************************/
/* */
/* Function prototypes */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
index a150e90..605a204 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Private.h
@@ -113,7 +113,9 @@
/* Sub-block configurations */
LVCS_StereoEnhancer_t StereoEnhancer; /* Stereo enhancer configuration */
LVCS_ReverbGenerator_t Reverberation; /* Reverberation configuration */
+#ifndef BIQUAD_OPT
LVCS_Equaliser_t Equaliser; /* Equaliser configuration */
+#endif
LVCS_BypassMix_t BypassMix; /* Bypass mixer configuration */
/* Bypass variable */
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
index b666da3..a200267 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_ReverbGenerator.h
@@ -51,8 +51,10 @@
LVM_FLOAT StereoSamples[2 * LVCS_STEREODELAY_CS_MAX_VAL];
/* Reverb Level */
LVM_FLOAT ReverbLevel;
+#ifndef BIQUAD_OPT
/* Filter */
void (*pBiquadCallBack)(Biquad_FLOAT_Instance_t*, LVM_FLOAT*, LVM_FLOAT*, LVM_INT16);
+#endif
} LVCS_ReverbGenerator_t;
/************************************************************************************/
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
index c92f8a5..a083c47 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_StereoEnhancer.h
@@ -36,6 +36,7 @@
/* Stereo enhancer structure */
typedef struct {
+#ifndef BIQUAD_OPT
/*
* Middle filter
*/
@@ -45,6 +46,7 @@
* Side filter
*/
void (*pBiquadCallBack_Side)(Biquad_FLOAT_Instance_t*, LVM_FLOAT*, LVM_FLOAT*, LVM_INT16);
+#endif
LVM_FLOAT MidGain; /* Middle gain in mobile speaker mode */
} LVCS_StereoEnhancer_t;
diff --git a/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh b/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
index e96263c..7b0ff5e 100755
--- a/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
+++ b/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
@@ -91,7 +91,7 @@
do
for fs in ${fs_arr[*]}
do
- for chMask in {0..22}
+ for chMask in {0..38}
do
adb shell $testdir/lvmtest -i:$testdir/sinesweepraw.raw \
-o:$testdir/sinesweep_$((chMask))_$((fs)).raw -chMask:$chMask -fs:$fs $flags
diff --git a/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh b/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh
index 627af21..72b370e 100755
--- a/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh
+++ b/media/libeffects/lvm/tests/build_and_run_all_unit_tests_reverb.sh
@@ -59,7 +59,7 @@
do
for fs in ${fs_arr[*]}
do
- for chMask in {0..22}
+ for chMask in {0..38}
do
adb shell $testdir/reverb_test \
--input $testdir/sinesweepraw.raw \
diff --git a/media/libeffects/lvm/tests/lvmtest.cpp b/media/libeffects/lvm/tests/lvmtest.cpp
index 5c5f646..f107b18 100644
--- a/media/libeffects/lvm/tests/lvmtest.cpp
+++ b/media/libeffects/lvm/tests/lvmtest.cpp
@@ -109,6 +109,22 @@
AUDIO_CHANNEL_OUT_5POINT1POINT2,
AUDIO_CHANNEL_OUT_7POINT1,
AUDIO_CHANNEL_INDEX_MASK_8,
+ AUDIO_CHANNEL_INDEX_MASK_9,
+ AUDIO_CHANNEL_INDEX_MASK_10,
+ AUDIO_CHANNEL_INDEX_MASK_11,
+ AUDIO_CHANNEL_INDEX_MASK_12,
+ AUDIO_CHANNEL_INDEX_MASK_13,
+ AUDIO_CHANNEL_INDEX_MASK_14,
+ AUDIO_CHANNEL_INDEX_MASK_15,
+ AUDIO_CHANNEL_INDEX_MASK_16,
+ AUDIO_CHANNEL_INDEX_MASK_17,
+ AUDIO_CHANNEL_INDEX_MASK_18,
+ AUDIO_CHANNEL_INDEX_MASK_19,
+ AUDIO_CHANNEL_INDEX_MASK_20,
+ AUDIO_CHANNEL_INDEX_MASK_21,
+ AUDIO_CHANNEL_INDEX_MASK_22,
+ AUDIO_CHANNEL_INDEX_MASK_23,
+ AUDIO_CHANNEL_INDEX_MASK_24,
};
void printUsage() {
@@ -394,7 +410,7 @@
params->SourceFormat = LVM_MONO;
} else if (params->NrChannels == 2) {
params->SourceFormat = LVM_STEREO;
- } else if (params->NrChannels > 2 && params->NrChannels <= 8) { // FCC_2 FCC_8
+ } else if (params->NrChannels > FCC_2 && params->NrChannels <= FCC_24) {
params->SourceFormat = LVM_MULTICHANNEL;
} else {
return -EINVAL;
diff --git a/media/libeffects/lvm/tests/reverb_test.cpp b/media/libeffects/lvm/tests/reverb_test.cpp
index b7704ff..cecc975 100644
--- a/media/libeffects/lvm/tests/reverb_test.cpp
+++ b/media/libeffects/lvm/tests/reverb_test.cpp
@@ -94,6 +94,22 @@
AUDIO_CHANNEL_OUT_5POINT1POINT2,
AUDIO_CHANNEL_OUT_7POINT1,
AUDIO_CHANNEL_INDEX_MASK_8,
+ AUDIO_CHANNEL_INDEX_MASK_9,
+ AUDIO_CHANNEL_INDEX_MASK_10,
+ AUDIO_CHANNEL_INDEX_MASK_11,
+ AUDIO_CHANNEL_INDEX_MASK_12,
+ AUDIO_CHANNEL_INDEX_MASK_13,
+ AUDIO_CHANNEL_INDEX_MASK_14,
+ AUDIO_CHANNEL_INDEX_MASK_15,
+ AUDIO_CHANNEL_INDEX_MASK_16,
+ AUDIO_CHANNEL_INDEX_MASK_17,
+ AUDIO_CHANNEL_INDEX_MASK_18,
+ AUDIO_CHANNEL_INDEX_MASK_19,
+ AUDIO_CHANNEL_INDEX_MASK_20,
+ AUDIO_CHANNEL_INDEX_MASK_21,
+ AUDIO_CHANNEL_INDEX_MASK_22,
+ AUDIO_CHANNEL_INDEX_MASK_23,
+ AUDIO_CHANNEL_INDEX_MASK_24,
};
constexpr int kReverbConfigChMaskCount = std::size(kReverbConfigChMask);
diff --git a/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp b/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
index 5a52ea5..d08c66d 100644
--- a/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
+++ b/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
@@ -41,7 +41,7 @@
"libmediandk",
],
- compile_multilib: "32",
+ compile_multilib: "prefer32",
cflags: [
"-Werror",
diff --git a/media/libmediatranscoding/TranscodingClientManager.cpp b/media/libmediatranscoding/TranscodingClientManager.cpp
index c0cc862..09afb1f 100644
--- a/media/libmediatranscoding/TranscodingClientManager.cpp
+++ b/media/libmediatranscoding/TranscodingClientManager.cpp
@@ -302,11 +302,13 @@
}
int32_t result;
- if (APermissionManager_checkPermission("android.permission.WRITE_MEDIA_STORAGE", pid, uid,
- &result) == PERMISSION_MANAGER_STATUS_OK &&
- result == PERMISSION_MANAGER_PERMISSION_GRANTED) {
- mTrustedUids.insert(uid);
- return true;
+ if (__builtin_available(android 31, *)) {
+ if (APermissionManager_checkPermission("android.permission.WRITE_MEDIA_STORAGE", pid, uid,
+ &result) == PERMISSION_MANAGER_STATUS_OK &&
+ result == PERMISSION_MANAGER_PERMISSION_GRANTED) {
+ mTrustedUids.insert(uid);
+ return true;
+ }
}
return false;
diff --git a/media/libmediatranscoding/TranscodingUidPolicy.cpp b/media/libmediatranscoding/TranscodingUidPolicy.cpp
index a725387..b0fa545 100644
--- a/media/libmediatranscoding/TranscodingUidPolicy.cpp
+++ b/media/libmediatranscoding/TranscodingUidPolicy.cpp
@@ -48,8 +48,9 @@
}
void TranscodingUidPolicy::registerSelf() {
- mUidObserver = AActivityManager_addUidImportanceListener(
- &OnUidImportance, -1, (void*)this);
+ if (__builtin_available(android 31, *)) {
+ mUidObserver = AActivityManager_addUidImportanceListener(&OnUidImportance, -1, (void*)this);
+ }
if (mUidObserver == nullptr) {
ALOGE("Failed to register uid observer");
@@ -62,12 +63,16 @@
}
void TranscodingUidPolicy::unregisterSelf() {
- AActivityManager_removeUidImportanceListener(mUidObserver);
- mUidObserver = nullptr;
+ if (__builtin_available(android 31, *)) {
+ AActivityManager_removeUidImportanceListener(mUidObserver);
+ mUidObserver = nullptr;
- Mutex::Autolock _l(mUidLock);
- mRegistered = false;
- ALOGI("Unregistered uid observer");
+ Mutex::Autolock _l(mUidLock);
+ mRegistered = false;
+ ALOGI("Unregistered uid observer");
+ } else {
+ ALOGE("Failed to unregister uid observer");
+ }
}
void TranscodingUidPolicy::setCallback(const std::shared_ptr<UidPolicyCallbackInterface>& cb) {
@@ -86,8 +91,10 @@
}
int32_t state = IMPORTANCE_UNKNOWN;
- if (mRegistered && AActivityManager_isUidActive(uid)) {
- state = AActivityManager_getUidImportance(uid);
+ if (__builtin_available(android 31, *)) {
+ if (mRegistered && AActivityManager_isUidActive(uid)) {
+ state = AActivityManager_getUidImportance(uid);
+ }
}
ALOGV("%s: inserting new uid: %u, procState %d", __FUNCTION__, uid, state);
diff --git a/media/libmediatranscoding/tests/assets/TranscodingTestAssets/Video_4K_HEVC_10Frames_Audio.mp4 b/media/libmediatranscoding/tests/assets/TranscodingTestAssets/Video_4K_HEVC_10Frames_Audio.mp4
new file mode 100644
index 0000000..b652dd9
--- /dev/null
+++ b/media/libmediatranscoding/tests/assets/TranscodingTestAssets/Video_4K_HEVC_10Frames_Audio.mp4
Binary files differ
diff --git a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp b/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
index 0695bdb..21d60ea 100644
--- a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
+++ b/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
@@ -260,7 +260,12 @@
return AMEDIA_ERROR_INVALID_PARAMETER;
}
+#if !defined(__ANDROID_APEX__)
+ // TODO(jiyong): replace this #ifdef with a __builtin_available check.
AMediaCodec* encoder = AMediaCodec_createEncoderByTypeForClient(destinationMime, mPid, mUid);
+#else
+ AMediaCodec* encoder = AMediaCodec_createEncoderByType(destinationMime);
+#endif
if (encoder == nullptr) {
LOG(ERROR) << "Unable to create encoder for type " << destinationMime;
return AMEDIA_ERROR_UNSUPPORTED;
@@ -290,7 +295,12 @@
return AMEDIA_ERROR_INVALID_PARAMETER;
}
+#if !defined(__ANDROID_APEX__)
+ // TODO(jiyong): replace this #ifdef with a __builtin_available check.
mDecoder = AMediaCodec_createDecoderByTypeForClient(sourceMime, mPid, mUid);
+#else
+ mDecoder = AMediaCodec_createDecoderByType(sourceMime);
+#endif
if (mDecoder == nullptr) {
LOG(ERROR) << "Unable to create decoder for type " << sourceMime;
return AMEDIA_ERROR_UNSUPPORTED;
diff --git a/media/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h b/media/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h
index d2ffb01..e3f3f4f 100644
--- a/media/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h
+++ b/media/libmediatranscoding/transcoder/include/media/VideoTrackTranscoder.h
@@ -97,8 +97,12 @@
BlockingQueue<std::function<void()>> mCodecMessageQueue;
std::shared_ptr<AMediaFormat> mDestinationFormat;
std::shared_ptr<AMediaFormat> mActualOutputFormat;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-private-field"
+ // These could be unused on older platforms
pid_t mPid;
uid_t mUid;
+#pragma clang diagnostic pop
};
} // namespace android
diff --git a/media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp b/media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
index bfc1f3b..54d8b89 100644
--- a/media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
+++ b/media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp
@@ -334,6 +334,17 @@
testTranscodeVideo(srcPath, destPath, AMEDIA_MIMETYPE_VIDEO_AVC);
}
+TEST_F(MediaTranscoderTests, TestVideoTranscode_4K) {
+#if defined(__i386__) || defined(__x86_64__)
+ LOG(WARNING) << "Skipping 4K test on x86 as SW encoder does not support 4K.";
+ return;
+#else
+ const char* srcPath = "/data/local/tmp/TranscodingTestAssets/Video_4K_HEVC_10Frames_Audio.mp4";
+ const char* destPath = "/data/local/tmp/MediaTranscoder_4K.MP4";
+ testTranscodeVideo(srcPath, destPath, AMEDIA_MIMETYPE_VIDEO_AVC);
+#endif
+}
+
TEST_F(MediaTranscoderTests, TestPreserveBitrate) {
const char* srcPath = "/data/local/tmp/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4";
const char* destPath = "/data/local/tmp/MediaTranscoder_PreserveBitrate.MP4";
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index cfdaebf..358c5e3 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -19,6 +19,8 @@
#define LOG_TAG "MediaCodec"
#include <utils/Log.h>
+#include <set>
+
#include <inttypes.h>
#include <stdlib.h>
@@ -202,6 +204,10 @@
// implements DeathRecipient
static void BinderDiedCallback(void* cookie);
void binderDied();
+ static Mutex sLockCookies;
+ static std::set<void*> sCookies;
+ static void addCookie(void* cookie);
+ static void removeCookie(void* cookie);
void addResource(const MediaResourceParcel &resource);
void removeResource(const MediaResourceParcel &resource);
@@ -228,8 +234,15 @@
}
MediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
+
+ // remove the cookie, so any in-flight death notification will get dropped
+ // by our handler.
+ removeCookie(this);
+
+ Mutex::Autolock _l(mLock);
if (mService != nullptr) {
AIBinder_unlinkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
+ mService = nullptr;
}
}
@@ -241,16 +254,39 @@
return;
}
- AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
-
// Kill clients pending removal.
mService->reclaimResourcesFromClientsPendingRemoval(mPid);
+
+ // so our handler will process the death notifications
+ addCookie(this);
+
+ // after this, require mLock whenever using mService
+ AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
+}
+
+//static
+Mutex MediaCodec::ResourceManagerServiceProxy::sLockCookies;
+std::set<void*> MediaCodec::ResourceManagerServiceProxy::sCookies;
+
+//static
+void MediaCodec::ResourceManagerServiceProxy::addCookie(void* cookie) {
+ Mutex::Autolock _l(sLockCookies);
+ sCookies.insert(cookie);
+}
+
+//static
+void MediaCodec::ResourceManagerServiceProxy::removeCookie(void* cookie) {
+ Mutex::Autolock _l(sLockCookies);
+ sCookies.erase(cookie);
}
//static
void MediaCodec::ResourceManagerServiceProxy::BinderDiedCallback(void* cookie) {
- auto thiz = static_cast<ResourceManagerServiceProxy*>(cookie);
- thiz->binderDied();
+ Mutex::Autolock _l(sLockCookies);
+ if (sCookies.find(cookie) != sCookies.end()) {
+ auto thiz = static_cast<ResourceManagerServiceProxy*>(cookie);
+ thiz->binderDied();
+ }
}
void MediaCodec::ResourceManagerServiceProxy::binderDied() {
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index ac54fa1..799ca0d 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -209,9 +209,12 @@
ALOGD("ignored a null builder");
continue;
}
- mInitCheck = builder->buildMediaCodecList(&writer);
- if (mInitCheck != OK) {
- break;
+ auto currentCheck = builder->buildMediaCodecList(&writer);
+ if (currentCheck != OK) {
+ ALOGD("ignored failed builder");
+ continue;
+ } else {
+ mInitCheck = currentCheck;
}
}
writer.writeGlobalSettings(mGlobalSettings);
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 28a7a1e..92ec94f 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -1247,6 +1247,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
index 6e437cf..90421b9 100644
--- a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
@@ -732,6 +732,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
index cdfc03a..01da3f8 100644
--- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
@@ -576,6 +576,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
index 85ab64e..a1f6686 100644
--- a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
@@ -421,6 +421,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
index 7fb8a4c..657a5ce 100644
--- a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
+++ b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
@@ -476,6 +476,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/avcdec/Android.bp b/media/libstagefright/codecs/avcdec/Android.bp
index 0bb6bb0..7ee3119 100644
--- a/media/libstagefright/codecs/avcdec/Android.bp
+++ b/media/libstagefright/codecs/avcdec/Android.bp
@@ -16,6 +16,9 @@
"signed-integer-overflow",
],
cfi: true,
+ config: {
+ cfi_assembly_support: true,
+ },
},
ldflags: ["-Wl,-Bsymbolic"],
diff --git a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
index 5a4b2f8..3891f23 100644
--- a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
+++ b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
@@ -724,6 +724,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData,
OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/avcenc/Android.bp b/media/libstagefright/codecs/avcenc/Android.bp
index 980261c..94f214d 100644
--- a/media/libstagefright/codecs/avcenc/Android.bp
+++ b/media/libstagefright/codecs/avcenc/Android.bp
@@ -10,6 +10,9 @@
"signed-integer-overflow",
],
cfi: true,
+ config: {
+ cfi_assembly_support: true,
+ },
},
cflags: [
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
index 9db6465..01174c9 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
@@ -1507,6 +1507,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
index 842a7ce..d6448d3 100644
--- a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
+++ b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
@@ -491,6 +491,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
index 078c8e3..24216a2 100644
--- a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
+++ b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
@@ -592,6 +592,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.cpp b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
index 877cb5a..fe91510 100644
--- a/media/libstagefright/codecs/g711/dec/SoftG711.cpp
+++ b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
@@ -382,6 +382,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
index d777229..330cb8a 100644
--- a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
+++ b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
@@ -354,6 +354,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/hevcdec/Android.bp b/media/libstagefright/codecs/hevcdec/Android.bp
index ec436ce..ffad18c 100644
--- a/media/libstagefright/codecs/hevcdec/Android.bp
+++ b/media/libstagefright/codecs/hevcdec/Android.bp
@@ -17,6 +17,9 @@
"signed-integer-overflow",
],
cfi: true,
+ config: {
+ cfi_assembly_support: true,
+ },
},
// We need this because the current asm generates the following link error:
diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
index f6ae1f4..176da47 100644
--- a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
+++ b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
@@ -713,6 +713,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(const char *name,
const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData,
OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index 60750d9..a4b3e2f 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -412,6 +412,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index fa7db81..fb6c4e2 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -528,6 +528,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index 15cde20..07bb45a 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -498,6 +498,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
index 9d5f342..9f8001f 100644
--- a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
+++ b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
@@ -864,6 +864,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData,
OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
index 0f2ff17..bffc23a 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
@@ -355,6 +355,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
index d0cb071..e9b4341 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
@@ -775,6 +775,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
index 5bb1879..dcd8dda 100644
--- a/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
+++ b/media/libstagefright/codecs/opus/dec/SoftOpus.cpp
@@ -666,6 +666,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/raw/SoftRaw.cpp b/media/libstagefright/codecs/raw/SoftRaw.cpp
index 0e31804..82dd171 100644
--- a/media/libstagefright/codecs/raw/SoftRaw.cpp
+++ b/media/libstagefright/codecs/raw/SoftRaw.cpp
@@ -273,6 +273,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index 08e20cc..3daed10 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -636,6 +636,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent *createSoftOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
diff --git a/media/libstagefright/codecs/xaacdec/Android.bp b/media/libstagefright/codecs/xaacdec/Android.bp
index 5385dbc..2706665 100644
--- a/media/libstagefright/codecs/xaacdec/Android.bp
+++ b/media/libstagefright/codecs/xaacdec/Android.bp
@@ -14,6 +14,9 @@
// integer_overflow: true,
misc_undefined: [ "signed-integer-overflow", "unsigned-integer-overflow", ],
cfi: true,
+ config: {
+ cfi_assembly_support: true,
+ },
},
static_libs: ["libxaacdec"],
diff --git a/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp b/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
index 87e8fd4..a478642 100644
--- a/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
+++ b/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
@@ -1693,6 +1693,7 @@
} // namespace android
+__attribute__((cfi_canonical_jump_table))
android::SoftOMXComponent* createSoftOMXComponent(const char* name,
const OMX_CALLBACKTYPE* callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE** component) {
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index 4c97b4d..30bc44e 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -31,6 +31,7 @@
#include <OMX_Audio.h>
#include <hardware/gralloc.h>
#include <nativebase/nativebase.h>
+#include <android/hardware/graphics/common/1.2/types.h>
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
@@ -54,6 +55,7 @@
struct DescribeColorFormat2Params;
struct DataConverter;
+using android::hardware::graphics::common::V1_2::BufferUsage;
typedef hidl::allocator::V1_0::IAllocator TAllocator;
typedef hidl::memory::V1_0::IMemory TMemory;
@@ -165,7 +167,8 @@
enum {
kVideoGrallocUsage = (GRALLOC_USAGE_HW_TEXTURE
| GRALLOC_USAGE_HW_COMPOSER
- | GRALLOC_USAGE_EXTERNAL_DISP),
+ | GRALLOC_USAGE_EXTERNAL_DISP)
+ | static_cast<uint64_t>(BufferUsage::VIDEO_DECODER),
};
struct BufferInfo {
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecList.h b/media/libstagefright/include/media/stagefright/MediaCodecList.h
index e681d25..78d1005 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecList.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecList.h
@@ -88,7 +88,7 @@
static sp<IMediaCodecList> sCodecList;
static sp<IMediaCodecList> sRemoteList;
- status_t mInitCheck;
+ status_t mInitCheck{NO_INIT};
sp<AMessage> mGlobalSettings;
std::vector<sp<MediaCodecInfo> > mCodecInfos;
diff --git a/media/libstagefright/rtsp/AAVCAssembler.cpp b/media/libstagefright/rtsp/AAVCAssembler.cpp
index a0b66a7..cccb63a 100644
--- a/media/libstagefright/rtsp/AAVCAssembler.cpp
+++ b/media/libstagefright/rtsp/AAVCAssembler.cpp
@@ -25,6 +25,7 @@
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/avc_utils.h>
#include <media/stagefright/foundation/hexdump.h>
#include <stdint.h>
@@ -39,7 +40,9 @@
mNextExpectedSeqNo(0),
mAccessUnitDamaged(false),
mFirstIFrameProvided(false),
- mLastIFrameProvidedAtMs(0) {
+ mLastIFrameProvidedAtMs(0),
+ mWidth(0),
+ mHeight(0) {
}
AAVCAssembler::~AAVCAssembler() {
@@ -115,6 +118,8 @@
sp<ABuffer> buffer = *queue->begin();
uint32_t rtpTime;
CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
+ buffer->meta()->setObject("source", source);
+
int64_t startTime = source->mFirstSysTime / 1000;
int64_t nowTime = ALooper::GetNowUs() / 1000;
int64_t playedTime = nowTime - startTime;
@@ -224,6 +229,21 @@
}
}
+void AAVCAssembler::checkSpsUpdated(const sp<ABuffer> &buffer) {
+ const uint8_t *data = buffer->data();
+ unsigned nalType = data[0] & 0x1f;
+ if (nalType == 0x7) {
+ int32_t width = 0, height = 0;
+ FindAVCDimensions(buffer, &width, &height);
+ if (width != mWidth || height != mHeight) {
+ mFirstIFrameProvided = false;
+ mWidth = width;
+ mHeight = height;
+ ALOGD("found a new resolution (%u x %u)", mWidth, mHeight);
+ }
+ }
+}
+
void AAVCAssembler::checkIFrameProvided(const sp<ABuffer> &buffer) {
if (buffer->size() == 0) {
return;
@@ -231,26 +251,50 @@
const uint8_t *data = buffer->data();
unsigned nalType = data[0] & 0x1f;
if (nalType == 0x5) {
- mFirstIFrameProvided = true;
mLastIFrameProvidedAtMs = ALooper::GetNowUs() / 1000;
+ if (!mFirstIFrameProvided) {
+ mFirstIFrameProvided = true;
- uint32_t rtpTime;
- CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
- ALOGD("got First I-frame to be decoded. rtpTime=%u, size=%zu", rtpTime, buffer->size());
+ uint32_t rtpTime;
+ CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
+ ALOGD("got First I-frame to be decoded. rtpTime=%d, size=%zu", rtpTime, buffer->size());
+ }
}
}
+bool AAVCAssembler::dropFramesUntilIframe(const sp<ABuffer> &buffer) {
+ const uint8_t *data = buffer->data();
+ unsigned nalType = data[0] & 0x1f;
+ if (!mFirstIFrameProvided && nalType < 0x5) {
+ return true;
+ }
+
+ return false;
+}
+
void AAVCAssembler::addSingleNALUnit(const sp<ABuffer> &buffer) {
ALOGV("addSingleNALUnit of size %zu", buffer->size());
#if !LOG_NDEBUG
hexdump(buffer->data(), buffer->size());
#endif
+ checkSpsUpdated(buffer);
checkIFrameProvided(buffer);
uint32_t rtpTime;
CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
+ if (dropFramesUntilIframe(buffer)) {
+ sp<ARTPSource> source = nullptr;
+ buffer->meta()->findObject("source", (sp<android::RefBase>*)&source);
+ if (source != nullptr) {
+ ALOGD("Issued FIR to get the I-frame");
+ source->onIssueFIRByAssembler();
+ }
+ ALOGV("Dropping P-frame till I-frame provided. rtpTime %u", rtpTime);
+ return;
+ }
+
if (!mNALUnits.empty() && rtpTime != mAccessUnitRTPTime) {
submitAccessUnit();
}
@@ -431,6 +475,7 @@
size_t offset = 1;
int32_t cvo = -1;
+ sp<ARTPSource> source = nullptr;
List<sp<ABuffer> >::iterator it = queue->begin();
for (size_t i = 0; i < totalCount; ++i) {
const sp<ABuffer> &buffer = *it;
@@ -442,6 +487,7 @@
memcpy(unit->data() + offset, buffer->data() + 2, buffer->size() - 2);
+ buffer->meta()->findObject("source", (sp<android::RefBase>*)&source);
buffer->meta()->findInt32("cvo", &cvo);
offset += buffer->size() - 2;
@@ -453,6 +499,9 @@
if (cvo >= 0) {
unit->meta()->setInt32("cvo", cvo);
}
+ if (source != nullptr) {
+ unit->meta()->setObject("source", source);
+ }
addSingleNALUnit(unit);
diff --git a/media/libstagefright/rtsp/AAVCAssembler.h b/media/libstagefright/rtsp/AAVCAssembler.h
index 913a868..79fc7c2 100644
--- a/media/libstagefright/rtsp/AAVCAssembler.h
+++ b/media/libstagefright/rtsp/AAVCAssembler.h
@@ -48,10 +48,14 @@
bool mAccessUnitDamaged;
bool mFirstIFrameProvided;
uint64_t mLastIFrameProvidedAtMs;
+ int32_t mWidth;
+ int32_t mHeight;
List<sp<ABuffer> > mNALUnits;
int32_t addNack(const sp<ARTPSource> &source);
+ void checkSpsUpdated(const sp<ABuffer> &buffer);
void checkIFrameProvided(const sp<ABuffer> &buffer);
+ bool dropFramesUntilIframe(const sp<ABuffer> &buffer);
AssemblyStatus addNALUnit(const sp<ARTPSource> &source);
void addSingleNALUnit(const sp<ABuffer> &buffer);
AssemblyStatus addFragmentedNALUnit(List<sp<ABuffer> > *queue);
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 6303fc4..c611f6f 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -226,7 +226,7 @@
// Send it if last FIR is not sent within a sec.
send = true;
} else if (mIssueFIRRequests && (usecsSinceLastFIR > 5000000)) {
- // A FIR issued periodically reagardless packet loss.
+ // A FIR issued periodically regardless packet loss.
// Send it if last FIR is not sent within 5 secs.
send = true;
}
diff --git a/media/libstagefright/tests/Android.bp b/media/libstagefright/tests/Android.bp
index a7f94c1..5f3f72c 100644
--- a/media/libstagefright/tests/Android.bp
+++ b/media/libstagefright/tests/Android.bp
@@ -20,7 +20,7 @@
"frameworks/native/include/media/openmax",
],
- compile_multilib: "32",
+ compile_multilib: "prefer32",
cflags: [
"-Werror",
@@ -44,4 +44,4 @@
"-Werror",
"-Wall",
],
-}
\ No newline at end of file
+}
diff --git a/media/libstagefright/writer_fuzzers/Android.bp b/media/libstagefright/writer_fuzzers/Android.bp
new file mode 100644
index 0000000..224aeb3
--- /dev/null
+++ b/media/libstagefright/writer_fuzzers/Android.bp
@@ -0,0 +1,60 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+cc_defaults {
+ name: "writer-fuzzerbase-defaults",
+ local_include_dirs: [
+ "include",
+ ],
+ export_include_dirs: [
+ "include",
+ ],
+ static_libs: [
+ "liblog",
+ "libstagefright_foundation",
+ "libstagefright",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libcutils",
+ "libutils",
+ ],
+}
+
+cc_defaults {
+ name: "writer-fuzzer-defaults",
+ defaults: ["writer-fuzzerbase-defaults"],
+ static_libs: [
+ "libwriterfuzzerbase",
+ ],
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 155276,
+ },
+}
+
+cc_library_static {
+ name: "libwriterfuzzerbase",
+ defaults: ["writer-fuzzerbase-defaults"],
+ srcs: [
+ "WriterFuzzerBase.cpp",
+ ],
+}
diff --git a/media/libstagefright/writer_fuzzers/README.md b/media/libstagefright/writer_fuzzers/README.md
new file mode 100644
index 0000000..037236a
--- /dev/null
+++ b/media/libstagefright/writer_fuzzers/README.md
@@ -0,0 +1,46 @@
+# Fuzzer for writers
+
+## Table of contents
+ [libwriterfuzzerbase](#WriterFuzzerBase)
+
+# <a name="WriterFuzzerBase"></a> Fuzzer for libwriterfuzzerbase
+All the writers have a common API - creating a writer, adding a source for
+all the tracks, etc. These common APIs have been abstracted in a base class
+called `WriterFuzzerBase` to ensure code is reused between fuzzer plugins.
+
+## Plugin Design Considerations
+The fuzzer plugin for writers is designed based on the understanding of the
+writer and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzer.
+
+Fuzzer for writers supports the following parameters:
+1. Track Mime (parameter name: `mime`)
+2. Channel Count (parameter name: `channel-count`)
+3. Sample Rate (parameter name: `sample-rate`)
+4. Frame Height (parameter name: `height`)
+5. Frame Width (parameter name: `width`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `mime` | 0. `audio/3gpp` 1. `audio/amr-wb` 2. `audio/vorbis` 3. `audio/opus` 4. `audio/mp4a-latm` 5. `video/avc` 6. `video/hevc` 7. `video/mp4v-es` 8. `video/3gpp` 9. `video/x-vnd.on2.vp8` 10. `video/x-vnd.on2.vp9` | All the bits of 2nd byte of data for first track and 11th byte of data for second track (if present) modulus 10 |
+| `channel-count` | In the range `0 to INT32_MAX` | All the bits of 3rd byte to 6th bytes of data if first track is audio and 12th to 15th bytes of data if second track is audio |
+| `sample-rate` | In the range `1 to INT32_MAX` | All the bits of 7th byte to 10th bytes of data if first track is audio and 16th to 19th bytes of data if second track is audio |
+| `height` | In the range `0 to INT32_MAX` | All the bits of 3rd byte to 6th bytes of data if first track is video and 12th to 15th bytes of data if second track is video |
+| `width` | In the range `0 to INT32_MAX` | All the bits of 7th byte to 10th bytes of data if first track is video and 16th to 19th bytes of data if second track is video |
+
+This also ensures that the plugin is always deterministic for any given input.
+
+##### Maximize utilization of input data
+The plugin divides the entire input data into frames based on frame markers.
+If no frame marker is found then the entire input data is treated as single frame.
+
+This ensures that the plugin tolerates any kind of input (huge,
+malformed, etc) and thereby increasing the chance of identifying vulnerabilities.
+
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp b/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp
new file mode 100644
index 0000000..65593e7
--- /dev/null
+++ b/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2020 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 <utils/Log.h>
+
+#include "WriterFuzzerBase.h"
+
+using namespace android;
+
+/**
+ * Buffer source implementations to parse input file
+ */
+
+uint32_t WriterFuzzerBase::BufferSource::getNumTracks() {
+ uint32_t numTracks = 0;
+ if (mSize > sizeof(uint8_t)) {
+ numTracks = min(mData[0], kMaxTrackCount);
+ mReadIndex += sizeof(uint8_t);
+ }
+ return numTracks;
+}
+
+bool WriterFuzzerBase::BufferSource::searchForMarker(size_t startIndex) {
+ while (true) {
+ if (isMarker()) {
+ return true;
+ }
+ --mReadIndex;
+ if (mReadIndex < startIndex) {
+ break;
+ }
+ }
+ return false;
+}
+
+ConfigFormat WriterFuzzerBase::BufferSource::getConfigFormat(int32_t trackIndex) {
+ return mParams[trackIndex];
+}
+
+int32_t WriterFuzzerBase::BufferSource::getNumCsds(int32_t trackIndex) {
+ return mNumCsds[trackIndex];
+}
+
+vector<FrameData> WriterFuzzerBase::BufferSource::getFrameList(int32_t trackIndex) {
+ return mFrameList[trackIndex];
+}
+
+void WriterFuzzerBase::BufferSource::getFrameInfo() {
+ size_t readIndexStart = mReadIndex;
+ if (mSize - mReadIndex > kMarkerSize + kMarkerSuffixSize) {
+ bool isFrameAvailable = true;
+ size_t bytesRemaining = mSize;
+ mReadIndex = mSize - kMarkerSize;
+ while (isFrameAvailable) {
+ isFrameAvailable = searchForMarker(readIndexStart);
+ if (isFrameAvailable) {
+ size_t location = mReadIndex + kMarkerSize;
+ if (location + kMarkerSuffixSize >= bytesRemaining) {
+ break;
+ }
+ bool isCSD = isCSDMarker(location);
+ location += kMarkerSuffixSize;
+ uint8_t *framePtr = const_cast<uint8_t *>(&mData[location]);
+ size_t frameSize = bytesRemaining - location, bufferSize = 0;
+ uint8_t trackIndex = framePtr[0] % kMaxTrackCount;
+ ++framePtr;
+ uint8_t flags = 0;
+ int64_t pts = 0;
+ if (isCSD && frameSize > 1) {
+ flags |= kCodecConfigFlag;
+ pts = 0;
+ ++mNumCsds[trackIndex];
+ bufferSize = frameSize - 1;
+ } else if (frameSize > sizeof(uint8_t) + sizeof(int64_t) + 1) {
+ flags = flagTypes[framePtr[0] % size(flagTypes)];
+ ++framePtr;
+ copy(framePtr, framePtr + sizeof(int64_t), reinterpret_cast<uint8_t *>(&pts));
+ framePtr += sizeof(int64_t);
+ bufferSize = frameSize - (sizeof(uint8_t) + sizeof(int64_t)) - 1;
+ } else {
+ break;
+ }
+ mFrameList[trackIndex].insert(
+ mFrameList[trackIndex].begin(),
+ FrameData{static_cast<int32_t>(bufferSize), flags, pts, framePtr});
+ bytesRemaining -= (frameSize + kMarkerSize + kMarkerSuffixSize);
+ --mReadIndex;
+ }
+ }
+ }
+ if (mFrameList[0].empty() && mFrameList[1].empty()) {
+ /**
+ * Scenario where input data does not contain the custom frame markers.
+ * Hence feed the entire data as single frame.
+ */
+ mFrameList[0].emplace_back(
+ FrameData{static_cast<int32_t>(mSize - readIndexStart), 0, 0, mData + readIndexStart});
+ }
+}
+bool WriterFuzzerBase::BufferSource::getTrackInfo(int32_t trackIndex) {
+ if (mSize <= mReadIndex + 2 * sizeof(int) + sizeof(uint8_t)) {
+ return false;
+ }
+ size_t mimeTypeIdx = mData[mReadIndex] % kSupportedMimeTypes;
+ char *mime = (char *)supportedMimeTypes[mimeTypeIdx].c_str();
+ mParams[trackIndex].mime = mime;
+ ++mReadIndex;
+
+ if (!strncmp(mime, "audio/", 6)) {
+ copy(mData + mReadIndex, mData + mReadIndex + sizeof(int),
+ reinterpret_cast<char *>(&mParams[trackIndex].channelCount));
+ copy(mData + mReadIndex + sizeof(int), mData + mReadIndex + 2 * sizeof(int),
+ reinterpret_cast<char *>(&mParams[trackIndex].sampleRate));
+ } else {
+ copy(mData + mReadIndex, mData + mReadIndex + sizeof(int),
+ reinterpret_cast<char *>(&mParams[trackIndex].height));
+ copy(mData + mReadIndex + sizeof(int), mData + mReadIndex + 2 * sizeof(int),
+ reinterpret_cast<char *>(&mParams[trackIndex].width));
+ }
+ mReadIndex += 2 * sizeof(int);
+ return true;
+}
+
+void writeHeaderBuffers(vector<FrameData> &bufferInfo, sp<AMessage> &format, int32_t numCsds) {
+ char csdName[kMaxCSDStrlen];
+ for (int csdId = 0; csdId < numCsds; ++csdId) {
+ int32_t flags = bufferInfo[csdId].flags;
+ if (flags == kCodecConfigFlag) {
+ sp<ABuffer> csdBuffer =
+ ABuffer::CreateAsCopy((void *)bufferInfo[csdId].buf, bufferInfo[csdId].size);
+ if (csdBuffer.get() == nullptr || csdBuffer->base() == nullptr) {
+ return;
+ }
+ snprintf(csdName, sizeof(csdName), "csd-%d", csdId);
+ format->setBuffer(csdName, csdBuffer);
+ }
+ }
+}
+
+bool WriterFuzzerBase::createOutputFile() {
+ mFd = memfd_create(mOutputFileName.c_str(), MFD_ALLOW_SEALING);
+ if (mFd == -1) {
+ return false;
+ }
+ return true;
+}
+
+void WriterFuzzerBase::addWriterSource(int32_t trackIndex) {
+ ConfigFormat params = mBufferSource->getConfigFormat(trackIndex);
+ sp<AMessage> format = new AMessage;
+ format->setString("mime", params.mime);
+ if (!strncmp(params.mime, "audio/", 6)) {
+ if (!strncmp(params.mime, "audio/3gpp", 10)) {
+ params.channelCount = 1;
+ params.sampleRate = 8000;
+ } else if (!strncmp(params.mime, "audio/amr-wb", 12)) {
+ params.channelCount = 1;
+ params.sampleRate = 16000;
+ } else {
+ params.sampleRate = max(1, params.sampleRate);
+ }
+ format->setInt32("channel-count", params.channelCount);
+ format->setInt32("sample-rate", params.sampleRate);
+ } else {
+ format->setInt32("width", params.width);
+ format->setInt32("height", params.height);
+ }
+ int32_t numCsds = mBufferSource->getNumCsds(trackIndex);
+ if (numCsds) {
+ vector<FrameData> mFrames = mBufferSource->getFrameList(trackIndex);
+ writeHeaderBuffers(mFrames, format, numCsds);
+ }
+ sp<MetaData> trackMeta = new MetaData;
+ convertMessageToMetaData(format, trackMeta);
+ mCurrentTrack[trackIndex] = new MediaAdapter(trackMeta);
+ mWriter->addSource(mCurrentTrack[trackIndex]);
+}
+
+void WriterFuzzerBase::start() {
+ mFileMeta->setInt32(kKeyRealTimeRecording, false);
+ mWriter->start(mFileMeta.get());
+}
+
+void WriterFuzzerBase::sendBuffersToWriter(sp<MediaAdapter> ¤tTrack, int32_t trackIndex) {
+ int32_t numCsds = mBufferSource->getNumCsds(trackIndex);
+ vector<FrameData> bufferInfo = mBufferSource->getFrameList(trackIndex);
+ int32_t range = bufferInfo.size();
+ for (int idx = numCsds; idx < range; ++idx) {
+ sp<ABuffer> buffer = new ABuffer((void *)bufferInfo[idx].buf, bufferInfo[idx].size);
+ MediaBuffer *mediaBuffer = new MediaBuffer(buffer);
+
+ // Released in MediaAdapter::signalBufferReturned().
+ mediaBuffer->add_ref();
+ mediaBuffer->set_range(buffer->offset(), buffer->size());
+ MetaDataBase &sampleMetaData = mediaBuffer->meta_data();
+ sampleMetaData.setInt64(kKeyTime, bufferInfo[idx].timeUs);
+
+ // Just set the kKeyDecodingTime as the presentation time for now.
+ sampleMetaData.setInt64(kKeyDecodingTime, bufferInfo[idx].timeUs);
+ if (bufferInfo[idx].flags == 1) {
+ sampleMetaData.setInt32(kKeyIsSyncFrame, true);
+ }
+
+ // This pushBuffer will wait until the mediaBuffer is consumed.
+ currentTrack->pushBuffer(mediaBuffer);
+ }
+}
+
+void WriterFuzzerBase::processData(const uint8_t *data, size_t size) {
+ if (!createOutputFile()) {
+ return;
+ }
+ if (!createWriter()) {
+ return;
+ }
+ mBufferSource = new BufferSource(data, size);
+ if (!mBufferSource) {
+ return;
+ }
+ mNumTracks = mBufferSource->getNumTracks();
+ if (mNumTracks > 0) {
+ for (int32_t idx = 0; idx < mNumTracks; ++idx) {
+ if (!mBufferSource->getTrackInfo(idx)) {
+ if (idx == 0) {
+ delete mBufferSource;
+ return;
+ }
+ mNumTracks = idx;
+ break;
+ }
+ }
+ mBufferSource->getFrameInfo();
+ for (int32_t idx = 0; idx < mNumTracks; ++idx) {
+ addWriterSource(idx);
+ }
+ start();
+ for (int32_t idx = 0; idx < mNumTracks; ++idx) {
+ sendBuffersToWriter(mCurrentTrack[idx], idx);
+ }
+ for (int32_t idx = 0; idx < mNumTracks; ++idx) {
+ if (mCurrentTrack[idx]) {
+ mCurrentTrack[idx]->stop();
+ }
+ }
+ }
+ delete mBufferSource;
+ mWriter->stop();
+}
diff --git a/media/libstagefright/writer_fuzzers/include/WriterFuzzerBase.h b/media/libstagefright/writer_fuzzers/include/WriterFuzzerBase.h
new file mode 100644
index 0000000..d819d43
--- /dev/null
+++ b/media/libstagefright/writer_fuzzers/include/WriterFuzzerBase.h
@@ -0,0 +1,168 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#ifndef __WRITER_FUZZER_BASE_H__
+#define __WRITER_FUZZER_BASE_H__
+
+#include <media/stagefright/MediaAdapter.h>
+#include <media/stagefright/MediaWriter.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <algorithm>
+#include <cstring>
+#include <vector>
+
+using namespace std;
+
+constexpr uint32_t kMimeSize = 128;
+constexpr uint8_t kMaxTrackCount = 2;
+constexpr uint32_t kMaxCSDStrlen = 16;
+constexpr uint32_t kCodecConfigFlag = 32;
+
+namespace android {
+
+struct ConfigFormat {
+ char* mime;
+ int32_t width;
+ int32_t height;
+ int32_t sampleRate;
+ int32_t channelCount;
+};
+
+struct FrameData {
+ int32_t size;
+ uint8_t flags;
+ int64_t timeUs;
+ const uint8_t* buf;
+};
+
+static string supportedMimeTypes[] = {
+ "audio/3gpp", "audio/amr-wb", "audio/vorbis", "audio/opus",
+ "audio/mp4a-latm", "video/avc", "video/hevc", "video/mp4v-es",
+ "video/3gpp", "video/x-vnd.on2.vp8", "video/x-vnd.on2.vp9",
+};
+
+enum {
+ DEFAULT_FLAG = 0,
+ SYNC_FLAG = 1,
+ ENCRYPTED_FLAG = 2,
+};
+
+static uint8_t flagTypes[] = {DEFAULT_FLAG, SYNC_FLAG, ENCRYPTED_FLAG};
+
+class WriterFuzzerBase {
+ public:
+ WriterFuzzerBase() = default;
+ virtual ~WriterFuzzerBase() {
+ if (mFileMeta) {
+ mFileMeta.clear();
+ mFileMeta = nullptr;
+ }
+ if (mWriter) {
+ mWriter.clear();
+ mWriter = nullptr;
+ }
+ for (int32_t idx = 0; idx < kMaxTrackCount; ++idx) {
+ if (mCurrentTrack[idx]) {
+ mCurrentTrack[idx]->stop();
+ mCurrentTrack[idx].clear();
+ mCurrentTrack[idx] = nullptr;
+ }
+ }
+ close(mFd);
+ };
+
+ /** Function to create the media writer component.
+ * To be implemented by the derived class.
+ */
+ virtual bool createWriter() = 0;
+
+ /** Parent class functions to be reused by derived class.
+ * These are common for all media writer components.
+ */
+ bool createOutputFile();
+
+ void addWriterSource(int32_t trackIndex);
+
+ void start();
+
+ void sendBuffersToWriter(sp<MediaAdapter>& currentTrack, int32_t trackIndex);
+
+ void processData(const uint8_t* data, size_t size);
+
+ protected:
+ class BufferSource {
+ public:
+ BufferSource(const uint8_t* data, size_t size) : mData(data), mSize(size), mReadIndex(0) {}
+ ~BufferSource() {
+ mData = nullptr;
+ mSize = 0;
+ mReadIndex = 0;
+ for (int32_t idx = 0; idx < kMaxTrackCount; ++idx) {
+ mFrameList[idx].clear();
+ }
+ }
+ uint32_t getNumTracks();
+ bool getTrackInfo(int32_t trackIndex);
+ void getFrameInfo();
+ ConfigFormat getConfigFormat(int32_t trackIndex);
+ int32_t getNumCsds(int32_t trackIndex);
+ vector<FrameData> getFrameList(int32_t trackIndex);
+
+ private:
+ bool isMarker() { return (memcmp(&mData[mReadIndex], kMarker, kMarkerSize) == 0); }
+
+ bool isCSDMarker(size_t position) {
+ return (memcmp(&mData[position], kCsdMarkerSuffix, kMarkerSuffixSize) == 0);
+ }
+
+ bool searchForMarker(size_t startIndex);
+
+ const uint8_t* mData = nullptr;
+ size_t mSize = 0;
+ size_t mReadIndex = 0;
+ ConfigFormat mParams[kMaxTrackCount] = {};
+ int32_t mNumCsds[kMaxTrackCount] = {0};
+ vector<FrameData> mFrameList[kMaxTrackCount];
+
+ static constexpr int kSupportedMimeTypes = size(supportedMimeTypes);
+ static constexpr uint8_t kMarker[] = "_MARK";
+ static constexpr uint8_t kCsdMarkerSuffix[] = "_H_";
+ static constexpr uint8_t kFrameMarkerSuffix[] = "_F_";
+ // All markers should be 5 bytes long ( sizeof '_MARK' which is 5)
+ static constexpr size_t kMarkerSize = (sizeof(kMarker) - 1);
+ // All marker types should be 3 bytes long ('_H_', '_F_')
+ static constexpr size_t kMarkerSuffixSize = 3;
+ };
+
+ BufferSource* mBufferSource = nullptr;
+ int32_t mFd = -1;
+ uint32_t mNumTracks = 0;
+ string mOutputFileName = "writer.out";
+ sp<MediaWriter> mWriter = nullptr;
+ sp<MetaData> mFileMeta = nullptr;
+ sp<MediaAdapter> mCurrentTrack[kMaxTrackCount] = {};
+};
+
+} // namespace android
+
+#endif // __WRITER_FUZZER_BASE_H__
diff --git a/media/mtp/IMtpDatabase.h b/media/mtp/IMtpDatabase.h
index 81fa60c..3b9bbb0 100644
--- a/media/mtp/IMtpDatabase.h
+++ b/media/mtp/IMtpDatabase.h
@@ -39,7 +39,7 @@
// Called to report success or failure of the SendObject file transfer.
virtual void endSendObject(MtpObjectHandle handle,
bool succeeded) = 0;
-
+
// Called to rescan a file, such as after an edit.
virtual void rescanFile(const char* path,
MtpObjectHandle handle,
@@ -91,6 +91,8 @@
int64_t& outFileLength,
MtpObjectFormat& outFormat) = 0;
+ virtual int openFilePath(const char* path, bool transcode) = 0;
+
virtual MtpResponseCode beginDeleteObject(MtpObjectHandle handle) = 0;
virtual void endDeleteObject(MtpObjectHandle handle, bool succeeded) = 0;
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 8677b90..a92848c 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -790,11 +790,30 @@
auto start = std::chrono::steady_clock::now();
const char* filePath = (const char *)pathBuf;
- mtp_file_range mfr;
- mfr.fd = open(filePath, O_RDONLY);
- if (mfr.fd < 0) {
- return MTP_RESPONSE_GENERAL_ERROR;
+ mtp_file_range mfr;
+ struct stat sstat;
+ uint64_t finalsize;
+ bool transcode = android::base::GetBoolProperty("sys.fuse.transcode_mtp", true);
+ ALOGD("Mtp transcode = %d", transcode);
+ mfr.fd = mDatabase->openFilePath(filePath, transcode);
+ // Doing this here because we want to update fileLength only for this case and leave the
+ // regular path as unchanged as possible.
+ if (mfr.fd >= 0) {
+ fstat(mfr.fd, &sstat);
+ finalsize = sstat.st_size;
+ fileLength = finalsize;
+ } else {
+ ALOGW("Mtp open via IMtpDatabase failed for %s. Falling back to the original",
+ filePath);
+
+ mfr.fd = open(filePath, O_RDONLY);
+ if (mfr.fd < 0) {
+ return MTP_RESPONSE_GENERAL_ERROR;
+ }
+ fstat(mfr.fd, &sstat);
+ finalsize = sstat.st_size;
}
+
mfr.offset = 0;
mfr.length = fileLength;
mfr.command = mRequest.getOperationCode();
@@ -815,9 +834,6 @@
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> diff = end - start;
- struct stat sstat;
- fstat(mfr.fd, &sstat);
- uint64_t finalsize = sstat.st_size;
ALOGV("Sent a file over MTP. Time: %f s, Size: %" PRIu64 ", Rate: %f bytes/s",
diff.count(), finalsize, ((double) finalsize) / diff.count());
closeObjFd(mfr.fd, filePath);
diff --git a/media/mtp/tests/MtpFuzzer/MtpMockDatabase.cpp b/media/mtp/tests/MtpFuzzer/MtpMockDatabase.cpp
index 5d95aa2..8aafe33 100644
--- a/media/mtp/tests/MtpFuzzer/MtpMockDatabase.cpp
+++ b/media/mtp/tests/MtpFuzzer/MtpMockDatabase.cpp
@@ -252,6 +252,11 @@
return MTP_RESPONSE_OK;
}
+int MtpMockDatabase::openFilePath(const char* path, bool transcode) {
+ ALOGD("MockDatabase %s: filePath=%s transcode=%d\n", __func__, path, transcode);
+ return 0;
+}
+
MtpResponseCode MtpMockDatabase::beginDeleteObject(MtpObjectHandle handle) {
ALOGD("MockDatabase %s: ohandle=%u\n", __func__, handle);
return MTP_RESPONSE_OK;
diff --git a/media/mtp/tests/MtpFuzzer/MtpMockDatabase.h b/media/mtp/tests/MtpFuzzer/MtpMockDatabase.h
index 876719e..e9e6a64 100644
--- a/media/mtp/tests/MtpFuzzer/MtpMockDatabase.h
+++ b/media/mtp/tests/MtpFuzzer/MtpMockDatabase.h
@@ -90,6 +90,8 @@
MtpResponseCode getObjectFilePath(MtpObjectHandle handle, MtpStringBuffer& outFilePath,
int64_t& outFileLength, MtpObjectFormat& outFormat);
+ int openFilePath(const char* path, bool transcode);
+
MtpResponseCode beginDeleteObject(MtpObjectHandle handle);
void endDeleteObject(MtpObjectHandle handle, bool succeeded);
diff --git a/media/ndk/NdkImage.cpp b/media/ndk/NdkImage.cpp
index 1145b7b..5fdd45a 100644
--- a/media/ndk/NdkImage.cpp
+++ b/media/ndk/NdkImage.cpp
@@ -58,7 +58,7 @@
if (mIsClosed) {
return;
}
- if (!mReader->mIsClosed) {
+ if (mReader->mIsOpen) {
mReader->releaseImageLocked(this, releaseFenceFd);
}
// Should have been set to nullptr in releaseImageLocked
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index 5d8f0b8..b75901a 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -273,7 +273,7 @@
AImageReader::~AImageReader() {
Mutex::Autolock _l(mLock);
- LOG_FATAL_IF("AImageReader not closed before destruction", mIsClosed != true);
+ LOG_FATAL_IF(mIsOpen, "AImageReader not closed before destruction");
}
media_status_t
@@ -347,16 +347,16 @@
}
mHandler = new CallbackHandler(this);
mCbLooper->registerHandler(mHandler);
-
+ mIsOpen = true;
return AMEDIA_OK;
}
void AImageReader::close() {
Mutex::Autolock _l(mLock);
- if (mIsClosed) {
+ if (!mIsOpen) {
return;
}
- mIsClosed = true;
+ mIsOpen = false;
AImageReader_ImageListener nullListener = {nullptr, nullptr};
setImageListenerLocked(&nullListener);
diff --git a/media/ndk/NdkImageReaderPriv.h b/media/ndk/NdkImageReaderPriv.h
index 0779a71..37c606e 100644
--- a/media/ndk/NdkImageReaderPriv.h
+++ b/media/ndk/NdkImageReaderPriv.h
@@ -166,7 +166,7 @@
native_handle_t* mWindowHandle = nullptr;
List<AImage*> mAcquiredImages;
- bool mIsClosed = false;
+ bool mIsOpen = false;
Mutex mLock;
};
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index 237b66e..2b389fe 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -167,11 +167,11 @@
AMediaCodecCryptoInfo_setPattern; # introduced=24
AMediaCodec_configure;
AMediaCodec_createCodecByName;
- AMediaCodec_createCodecByNameForClient; # apex #introduced = 31
+ AMediaCodec_createCodecByNameForClient; # apex # introduced=31
AMediaCodec_createDecoderByType;
- AMediaCodec_createDecoderByTypeForClient; # apex #introduced = 31
+ AMediaCodec_createDecoderByTypeForClient; # apex # introduced=31
AMediaCodec_createEncoderByType;
- AMediaCodec_createEncoderByTypeForClient; # apex #introduced = 31
+ AMediaCodec_createEncoderByTypeForClient; # apex # introduced=31
AMediaCodec_delete;
AMediaCodec_dequeueInputBuffer;
AMediaCodec_dequeueOutputBuffer;
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index e3f1e44..952fe37 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -60,3 +60,10 @@
local_include_dirs: ["include"],
export_include_dirs: ["include"],
}
+
+cc_library_headers {
+ name: "libmediautils_headers",
+ vendor_available: true, // required for platform/hardware/interfaces
+
+ export_include_dirs: ["include"],
+}
diff --git a/media/utils/include/mediautils/Synchronization.h b/media/utils/include/mediautils/Synchronization.h
new file mode 100644
index 0000000..aef4967
--- /dev/null
+++ b/media/utils/include/mediautils/Synchronization.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2021, 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.
+ */
+
+#pragma once
+#include <mutex>
+#include <utils/RefBase.h>
+
+namespace android::mediautils {
+
+/**
+ * The LockItem class introduces a simple template which mimics atomic<T>
+ * for non-trivially copyable types. For trivially copyable types,
+ * the LockItem will statically assert that an atomic<T> should be used instead.
+ *
+ * The default lock mutex is std::mutex which is suitable for all but rare cases
+ * e.g. recursive constructors that might be found in tree construction,
+ * setters that might recurse onto the same object.
+ */
+
+template <typename T, typename L = std::mutex, int FLAGS = 0>
+class LockItem {
+protected:
+ mutable L mLock;
+ mutable T mT;
+
+public:
+ enum {
+ // Best practices for smart pointers and complex containers is to move to a temp
+ // and invoke destructor outside of lock. This reduces time under lock and in
+ // some cases eliminates deadlock.
+ FLAG_DTOR_OUT_OF_LOCK = 1,
+ };
+
+ // Check type, suggest std::atomic if possible.
+ static_assert(!std::is_trivially_copyable_v<T>,
+ "type is trivially copyable, please use std::atomic instead");
+
+ // Allow implicit conversions as expected for some types, e.g. sp -> wp.
+ template <typename... Args>
+ LockItem(Args&&... args) : mT(std::forward<Args>(args)...) {
+ }
+
+ // NOT copy or move / assignable or constructible.
+
+ // Do not enable this because it may lead to confusion because it returns
+ // a copy-value not a reference.
+ // operator T() const { return load(); }
+
+ // any conversion done under lock.
+ template <typename U>
+ void operator=(U&& u) {
+ store(std::forward<U>(u));
+ }
+
+ // returns a copy-value not a reference.
+ T load() const {
+ std::lock_guard lock(mLock);
+ return mT;
+ }
+
+ // any conversion done under lock.
+ template <typename U>
+ void store(U&& u) {
+ if constexpr ((FLAGS & FLAG_DTOR_OUT_OF_LOCK) != 0) {
+ std::unique_lock lock(mLock);
+ T temp = std::move(mT);
+ mT = std::forward<U>(u);
+ lock.unlock();
+ } else {
+ std::lock_guard lock(mLock);
+ mT = std::forward<U>(u);
+ }
+ }
+};
+
+/**
+ * atomic_wp<> and atomic_sp<> are used for concurrent access to Android
+ * sp<> and wp<> smart pointers, including their modifiers. We
+ * return a copy of the smart pointer with load().
+ *
+ * Historical: The importance of an atomic<std::shared_ptr<T>> class is described
+ * by Herb Sutter in the following ISO document https://isocpp.org/files/papers/N4162.pdf
+ * and is part of C++20. Lock free versions of atomic smart pointers are available
+ * publicly but usually require specialized smart pointer structs.
+ * See also https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic
+ * and https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic2
+ *
+ * We offer lock based atomic_wp<> and atomic_sp<> objects here. This is useful to
+ * copy the Android smart pointer to a different variable for subsequent local access,
+ * where the change of the original object after copy is acceptable.
+ *
+ * Note: Instead of atomics, it is often preferrable to create an explicit visible lock to
+ * ensure complete transaction consistency. For example, one might want to ensure
+ * that the method called from the smart pointer is also done under lock.
+ * This may not be possible for callbacks due to inverted lock ordering.
+ */
+
+template <typename T>
+using atomic_wp = LockItem<::android::wp<T>>;
+
+template <typename T>
+using atomic_sp = LockItem<
+ ::android::sp<T>, std::mutex, LockItem<::android::sp<T>>::FLAG_DTOR_OUT_OF_LOCK>;
+
+/**
+ * Defers a function to run in the RAII destructor.
+ * A C++ implementation of Go _defer_ https://golangr.com/defer/.
+ */
+class Defer {
+public:
+ template <typename U>
+ explicit Defer(U &&f) : mThunk(std::forward<U>(f)) {}
+ ~Defer() { mThunk(); }
+
+private:
+ const std::function<void()> mThunk;
+};
+
+} // namespace android::mediautils
+
diff --git a/media/utils/tests/Android.bp b/media/utils/tests/Android.bp
new file mode 100644
index 0000000..bb413c3
--- /dev/null
+++ b/media/utils/tests/Android.bp
@@ -0,0 +1,19 @@
+cc_test {
+ name: "media_synchronization_tests",
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+
+ shared_libs: [
+ "liblog",
+ "libmediautils",
+ "libutils",
+ ],
+
+ srcs: [
+ "media_synchronization_tests.cpp",
+ ],
+}
diff --git a/media/utils/tests/media_synchronization_tests.cpp b/media/utils/tests/media_synchronization_tests.cpp
new file mode 100644
index 0000000..169768e
--- /dev/null
+++ b/media/utils/tests/media_synchronization_tests.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2021 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 "media_synchronization_tests"
+
+#include <mediautils/Synchronization.h>
+
+#include <gtest/gtest.h>
+#include <utils/Log.h>
+
+using namespace android;
+using namespace android::mediautils;
+
+// Simple Test Class
+template <typename T>
+class MyObject : public RefBase {
+ T value_;
+ public:
+ MyObject(const T& value) : value_(value) {}
+ MyObject(const MyObject<T>& mo) : value_(mo.get()) {}
+ T get() const { return value_; }
+ void set(const T& value) { value_ = value; }
+};
+
+TEST(media_synchronization_tests, atomic_wp) {
+ sp<MyObject<int>> refobj = new MyObject<int>(20);
+ atomic_wp<MyObject<int>> wpobj = refobj;
+
+ // we can promote.
+ ASSERT_EQ(20, wpobj.load().promote()->get());
+
+ // same underlying object for sp and atomic_wp.
+ ASSERT_EQ(refobj.get(), wpobj.load().promote().get());
+
+ // behavior is consistent with same underlying object.
+ wpobj.load().promote()->set(10);
+ ASSERT_EQ(10, refobj->get());
+ refobj->set(5);
+ ASSERT_EQ(5, wpobj.load().promote()->get());
+
+ // we can clear our weak ptr.
+ wpobj = nullptr;
+ ASSERT_EQ(nullptr, wpobj.load().promote());
+
+ // didn't affect our original obj.
+ ASSERT_NE(nullptr, refobj.get());
+}
+
+TEST(media_synchronization_tests, atomic_sp) {
+ sp<MyObject<int>> refobj = new MyObject<int>(20);
+ atomic_sp<MyObject<int>> spobj = refobj;
+
+ // same underlying object for sp and atomic_sp.
+ ASSERT_EQ(refobj.get(), spobj.load().get());
+
+ // behavior is consistent with same underlying object.
+ ASSERT_EQ(20, spobj.load()->get());
+ spobj.load()->set(10);
+ ASSERT_EQ(10, refobj->get());
+ refobj->set(5);
+ ASSERT_EQ(5, spobj.load()->get());
+
+ // we can clear spobj.
+ spobj = nullptr;
+ ASSERT_EQ(nullptr, spobj.load().get());
+
+ // didn't affect our original obj.
+ ASSERT_NE(nullptr, refobj.get());
+}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index a6f0953..b8257d3 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -128,9 +128,6 @@
// we define a minimum time during which a global effect is considered enabled.
static const nsecs_t kMinGlobalEffectEnabletimeNs = seconds(7200);
-Mutex gLock;
-wp<AudioFlinger> gAudioFlinger;
-
// Keep a strong reference to media.log service around forever.
// The service is within our parent process so it can never die in a way that we could observe.
// These two variables are const after initialization.
@@ -268,7 +265,7 @@
mMode = AUDIO_MODE_NORMAL;
- gAudioFlinger = this;
+ gAudioFlinger = this; // we are already refcounted, store into atomic pointer.
mDevicesFactoryHalCallback = new DevicesFactoryHalCallbackImpl;
mDevicesFactoryHal->setCallbackOnce(mDevicesFactoryHalCallback);
@@ -325,11 +322,9 @@
sp<MmapStreamInterface>& interface,
audio_port_handle_t *handle)
{
- sp<AudioFlinger> af;
- {
- Mutex::Autolock _l(gLock);
- af = gAudioFlinger.promote();
- }
+ // TODO: Use ServiceManager to get IAudioFlinger instead of by atomic pointer.
+ // This allows moving oboeservice (AAudio) to a separate process in the future.
+ sp<AudioFlinger> af = AudioFlinger::gAudioFlinger.load(); // either nullptr or singleton AF.
status_t ret = NO_INIT;
if (af != 0) {
ret = af->openMmapStream(
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 1c6f57c..1d530a4 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -73,6 +73,7 @@
#include <media/ExtendedAudioBufferProvider.h>
#include <media/VolumeShaper.h>
#include <mediautils/ServiceUtilities.h>
+#include <mediautils/Synchronization.h>
#include <audio_utils/clock.h>
#include <audio_utils/FdToString.h>
@@ -305,6 +306,24 @@
Mutex mUnregisteredWritersLock;
public:
+ // Life cycle of gAudioFlinger and AudioFlinger:
+ //
+ // AudioFlinger is created once and survives until audioserver crashes
+ // irrespective of sp<> and wp<> as it is refcounted by ServiceManager and we
+ // don't issue a ServiceManager::tryUnregisterService().
+ //
+ // gAudioFlinger is an atomic pointer set on AudioFlinger::onFirstRef().
+ // After this is set, it is safe to obtain a wp<> or sp<> from it as the
+ // underlying object does not go away.
+ //
+ // Note: For most inner classes, it is acceptable to hold a reference to the outer
+ // AudioFlinger instance as creation requires AudioFlinger to exist in the first place.
+ //
+ // An atomic here ensures underlying writes have completed before setting
+ // the pointer. Access by memory_order_seq_cst.
+ //
+
+ static inline std::atomic<AudioFlinger *> gAudioFlinger = nullptr;
class SyncEvent;
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 3ab7737..56d32a6 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -2785,11 +2785,7 @@
const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId,
sp<EffectHalInterface> *effect) {
status_t status = NO_INIT;
- sp<AudioFlinger> af = mAudioFlinger.promote();
- if (af == nullptr) {
- return status;
- }
- sp<EffectsFactoryHalInterface> effectsFactory = af->getEffectsFactory();
+ sp<EffectsFactoryHalInterface> effectsFactory = mAudioFlinger.getEffectsFactory();
if (effectsFactory != 0) {
status = effectsFactory->createEffect(pEffectUuid, sessionId, io(), deviceId, effect);
}
@@ -2798,25 +2794,19 @@
bool AudioFlinger::EffectChain::EffectCallback::updateOrphanEffectChains(
const sp<AudioFlinger::EffectBase>& effect) {
- sp<AudioFlinger> af = mAudioFlinger.promote();
- if (af == nullptr) {
- return false;
- }
// in EffectChain context, an EffectBase is always from an EffectModule so static cast is safe
- return af->updateOrphanEffectChains(effect->asEffectModule());
+ return mAudioFlinger.updateOrphanEffectChains(effect->asEffectModule());
}
status_t AudioFlinger::EffectChain::EffectCallback::allocateHalBuffer(
size_t size, sp<EffectBufferHalInterface>* buffer) {
- sp<AudioFlinger> af = mAudioFlinger.promote();
- LOG_ALWAYS_FATAL_IF(af == nullptr, "allocateHalBuffer() could not retrieved audio flinger");
- return af->mEffectsFactoryHal->allocateBuffer(size, buffer);
+ return mAudioFlinger.mEffectsFactoryHal->allocateBuffer(size, buffer);
}
status_t AudioFlinger::EffectChain::EffectCallback::addEffectToHal(
sp<EffectHalInterface> effect) {
status_t result = NO_INIT;
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return result;
}
@@ -2832,7 +2822,7 @@
status_t AudioFlinger::EffectChain::EffectCallback::removeEffectFromHal(
sp<EffectHalInterface> effect) {
status_t result = NO_INIT;
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return result;
}
@@ -2846,7 +2836,7 @@
}
audio_io_handle_t AudioFlinger::EffectChain::EffectCallback::io() const {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return AUDIO_IO_HANDLE_NONE;
}
@@ -2854,7 +2844,7 @@
}
bool AudioFlinger::EffectChain::EffectCallback::isOutput() const {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return true;
}
@@ -2862,7 +2852,7 @@
}
bool AudioFlinger::EffectChain::EffectCallback::isOffload() const {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return false;
}
@@ -2870,7 +2860,7 @@
}
bool AudioFlinger::EffectChain::EffectCallback::isOffloadOrDirect() const {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return false;
}
@@ -2878,7 +2868,7 @@
}
bool AudioFlinger::EffectChain::EffectCallback::isOffloadOrMmap() const {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return false;
}
@@ -2886,7 +2876,7 @@
}
uint32_t AudioFlinger::EffectChain::EffectCallback::sampleRate() const {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return 0;
}
@@ -2894,7 +2884,7 @@
}
audio_channel_mask_t AudioFlinger::EffectChain::EffectCallback::channelMask() const {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return AUDIO_CHANNEL_NONE;
}
@@ -2902,7 +2892,7 @@
}
uint32_t AudioFlinger::EffectChain::EffectCallback::channelCount() const {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return 0;
}
@@ -2910,7 +2900,7 @@
}
audio_channel_mask_t AudioFlinger::EffectChain::EffectCallback::hapticChannelMask() const {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return AUDIO_CHANNEL_NONE;
}
@@ -2918,7 +2908,7 @@
}
size_t AudioFlinger::EffectChain::EffectCallback::frameCount() const {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return 0;
}
@@ -2926,7 +2916,7 @@
}
uint32_t AudioFlinger::EffectChain::EffectCallback::latency() const {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return 0;
}
@@ -2934,7 +2924,7 @@
}
void AudioFlinger::EffectChain::EffectCallback::setVolumeForOutput(float left, float right) const {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return;
}
@@ -2943,13 +2933,13 @@
void AudioFlinger::EffectChain::EffectCallback::checkSuspendOnEffectEnabled(
const sp<EffectBase>& effect, bool enabled, bool threadLocked) {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return;
}
t->checkSuspendOnEffectEnabled(enabled, effect->sessionId(), threadLocked);
- sp<EffectChain> c = mChain.promote();
+ sp<EffectChain> c = chain().promote();
if (c == nullptr) {
return;
}
@@ -2958,7 +2948,7 @@
}
void AudioFlinger::EffectChain::EffectCallback::onEffectEnable(const sp<EffectBase>& effect) {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return;
}
@@ -2969,7 +2959,7 @@
void AudioFlinger::EffectChain::EffectCallback::onEffectDisable(const sp<EffectBase>& effect) {
checkSuspendOnEffectEnabled(effect, false, false /*threadLocked*/);
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return;
}
@@ -2978,7 +2968,7 @@
bool AudioFlinger::EffectChain::EffectCallback::disconnectEffectHandle(EffectHandle *handle,
bool unpinIfLast) {
- sp<ThreadBase> t = mThread.promote();
+ sp<ThreadBase> t = thread().promote();
if (t == nullptr) {
return false;
}
@@ -2987,7 +2977,7 @@
}
void AudioFlinger::EffectChain::EffectCallback::resetVolume() {
- sp<EffectChain> c = mChain.promote();
+ sp<EffectChain> c = chain().promote();
if (c == nullptr) {
return;
}
@@ -2996,7 +2986,7 @@
}
uint32_t AudioFlinger::EffectChain::EffectCallback::strategy() const {
- sp<EffectChain> c = mChain.promote();
+ sp<EffectChain> c = chain().promote();
if (c == nullptr) {
return PRODUCT_STRATEGY_NONE;
}
@@ -3004,7 +2994,7 @@
}
int32_t AudioFlinger::EffectChain::EffectCallback::activeTrackCnt() const {
- sp<EffectChain> c = mChain.promote();
+ sp<EffectChain> c = chain().promote();
if (c == nullptr) {
return 0;
}
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 03bdc60..139c049 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -373,8 +373,8 @@
DISALLOW_COPY_AND_ASSIGN(EffectHandle);
Mutex mLock; // protects IEffect method calls
- wp<EffectBase> mEffect; // pointer to controlled EffectModule
- sp<media::IEffectClient> mEffectClient; // callback interface for client notifications
+ const wp<EffectBase> mEffect; // pointer to controlled EffectModule
+ const sp<media::IEffectClient> mEffectClient; // callback interface for client notifications
/*const*/ sp<Client> mClient; // client for shared memory allocation, see
// disconnect()
sp<IMemory> mCblkMemory; // shared memory for control block
@@ -512,14 +512,21 @@
private:
+ // For transaction consistency, please consider holding the EffectChain lock before
+ // calling the EffectChain::EffectCallback methods, excepting
+ // createEffectHal and allocateHalBuffer.
+ //
+ // This prevents migration of the EffectChain to another PlaybackThread
+ // for the purposes of the EffectCallback.
class EffectCallback : public EffectCallbackInterface {
public:
// Note: ctors taking a weak pointer to their owner must not promote it
// during construction (but may keep a reference for later promotion).
EffectCallback(const wp<EffectChain>& owner,
const wp<ThreadBase>& thread)
- : mChain(owner) {
- setThread(thread);
+ : mChain(owner)
+ , mThread(thread)
+ , mAudioFlinger(*gAudioFlinger) {
}
status_t createEffectHal(const effect_uuid_t *pEffectUuid,
@@ -556,18 +563,16 @@
wp<EffectChain> chain() const override { return mChain; }
- wp<ThreadBase> thread() { return mThread; }
+ wp<ThreadBase> thread() const { return mThread.load(); }
void setThread(const wp<ThreadBase>& thread) {
mThread = thread;
- sp<ThreadBase> p = thread.promote();
- mAudioFlinger = p ? p->mAudioFlinger : nullptr;
}
private:
- wp<EffectChain> mChain;
- wp<ThreadBase> mThread;
- wp<AudioFlinger> mAudioFlinger;
+ const wp<EffectChain> mChain;
+ mediautils::atomic_wp<ThreadBase> mThread;
+ AudioFlinger &mAudioFlinger; // implementation detail: outer instance always exists.
};
friend class AudioFlinger; // for mThread, mEffects
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 9d5a0a0..e52ad5e 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -133,8 +133,8 @@
virtual status_t startOutput(audio_port_handle_t portId) = 0;
// indicates to the audio policy manager that the output stops being used by corresponding stream.
virtual status_t stopOutput(audio_port_handle_t portId) = 0;
- // releases the output.
- virtual void releaseOutput(audio_port_handle_t portId) = 0;
+ // releases the output, return true if the output descriptor is reopened.
+ virtual bool releaseOutput(audio_port_handle_t portId) = 0;
// request an input appropriate for record from the supplied device with supplied parameters.
virtual status_t getInputForAttr(const audio_attributes_t *attr,
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 5153dce..1f9b535 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -338,6 +338,8 @@
bool sharesHwModuleWith(const sp<SwAudioOutputDescriptor>& outputDesc);
virtual DeviceVector supportedDevices() const;
virtual bool devicesSupportEncodedFormats(const DeviceTypeSet& deviceTypes);
+ virtual bool containsSingleDeviceSupportingEncodedFormats(
+ const sp<DeviceDescriptor>& device) const;
virtual uint32_t latency();
virtual bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
virtual bool isFixedVolume(const DeviceTypeSet& deviceTypes);
@@ -396,6 +398,14 @@
bool supportsAllDevices(const DeviceVector &devices) const;
/**
+ * @brief supportsDevicesForPlayback
+ * @param devices to be checked against
+ * @return true if the devices is a supported combo for playback
+ * false otherwise
+ */
+ bool supportsDevicesForPlayback(const DeviceVector &devices) const;
+
+ /**
* @brief filterSupportedDevices takes a vector of devices and filters them according to the
* device supported by this output (the profile from which this output derives from)
* @param devices reference device vector to be filtered
@@ -412,6 +422,7 @@
sp<SwAudioOutputDescriptor> mOutput2; // used by duplicated outputs: second output
uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
audio_session_t mDirectClientSession; // session id of the direct output client
+ bool mPendingReopenToQueryProfiles = false;
};
// Audio output driven by an input device directly.
diff --git a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
index 80afe9d..59876c6 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
@@ -198,10 +198,18 @@
~SourceClientDescriptor() override = default;
+ void connect(audio_patch_handle_t patchHandle, const sp<DeviceDescriptor>& sinkDevice) {
+ mPatchHandle = patchHandle;
+ mSinkDevice = sinkDevice;
+ }
+ void disconnect() {
+ mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+ mSinkDevice = nullptr;
+ }
+ bool isConnected() const { return mPatchHandle != AUDIO_PATCH_HANDLE_NONE; }
audio_patch_handle_t getPatchHandle() const { return mPatchHandle; }
- void setPatchHandle(audio_patch_handle_t patchHandle) { mPatchHandle = patchHandle; }
-
sp<DeviceDescriptor> srcDevice() const { return mSrcDevice; }
+ sp<DeviceDescriptor> sinkDevice() const { return mSinkDevice; }
wp<SwAudioOutputDescriptor> swOutput() const { return mSwOutput; }
void setSwOutput(const sp<SwAudioOutputDescriptor>& swOutput);
wp<HwAudioOutputDescriptor> hwOutput() const { return mHwOutput; }
@@ -213,6 +221,7 @@
private:
audio_patch_handle_t mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
const sp<DeviceDescriptor> mSrcDevice;
+ sp<DeviceDescriptor> mSinkDevice;
wp<SwAudioOutputDescriptor> mSwOutput;
wp<HwAudioOutputDescriptor> mHwOutput;
};
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index 7c712e3..3d338ea 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -265,6 +265,8 @@
return String8("");
}
+ const AudioProfileVector& getSupportedProfiles() { return mSupportedProfiles; }
+
// Return a string to describe the DeviceVector. The sensitive information will only be
// added to the string if `includeSensitiveInfo` is true.
std::string toString(bool includeSensitiveInfo = false) const;
@@ -273,7 +275,9 @@
private:
void refreshTypes();
+ void refreshAudioProfiles();
DeviceTypeSet mDeviceTypes;
+ AudioProfileVector mSupportedProfiles;
};
} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index 621c630..a5cd534 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -143,6 +143,8 @@
return false;
}
+ bool containsSingleDeviceSupportingEncodedFormats(const sp<DeviceDescriptor>& device) const;
+
void clearSupportedDevices() { mSupportedDevices.clear(); }
void addSupportedDevice(const sp<DeviceDescriptor> &device)
{
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index c4d7340..b872709 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -344,6 +344,13 @@
return supportedDevices().containsAllDevices(devices);
}
+bool SwAudioOutputDescriptor::supportsDevicesForPlayback(const DeviceVector &devices) const
+{
+ // No considering duplicated output
+ // TODO: need to verify if the profile supports the devices combo for playback.
+ return !isDuplicated() && supportsAllDevices(devices);
+}
+
DeviceVector SwAudioOutputDescriptor::filterSupportedDevices(const DeviceVector &devices) const
{
DeviceVector filteredDevices = supportedDevices();
@@ -360,6 +367,16 @@
}
}
+bool SwAudioOutputDescriptor::containsSingleDeviceSupportingEncodedFormats(
+ const sp<DeviceDescriptor>& device) const
+{
+ if (isDuplicated()) {
+ return (mOutput1->containsSingleDeviceSupportingEncodedFormats(device) &&
+ mOutput2->containsSingleDeviceSupportingEncodedFormats(device));
+ }
+ return mProfile->containsSingleDeviceSupportingEncodedFormats(device);
+}
+
uint32_t SwAudioOutputDescriptor::latency()
{
if (isDuplicated()) {
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index fc1d0e2..c024a85 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -208,24 +208,25 @@
// Loopback render mixes are created from a public API and thus restricted
// to non sensible audio that have not opted out.
if (is_mix_loopback_render(mix->mRouteFlags)) {
- auto hasFlag = [](auto flags, auto flag) { return (flags & flag) == flag; };
- if (hasFlag(attributes.flags, AUDIO_FLAG_NO_SYSTEM_CAPTURE)) {
- return MixMatchStatus::NO_MATCH;
- }
- if (!mix->mAllowPrivilegedPlaybackCapture &&
- hasFlag(attributes.flags, AUDIO_FLAG_NO_MEDIA_PROJECTION)) {
- return MixMatchStatus::NO_MATCH;
- }
- if (attributes.usage == AUDIO_USAGE_VOICE_COMMUNICATION &&
- !mix->mVoiceCommunicationCaptureAllowed) {
- return MixMatchStatus::NO_MATCH;
- }
if (!(attributes.usage == AUDIO_USAGE_UNKNOWN ||
attributes.usage == AUDIO_USAGE_MEDIA ||
attributes.usage == AUDIO_USAGE_GAME ||
attributes.usage == AUDIO_USAGE_VOICE_COMMUNICATION)) {
return MixMatchStatus::NO_MATCH;
}
+ auto hasFlag = [](auto flags, auto flag) { return (flags & flag) == flag; };
+ if (hasFlag(attributes.flags, AUDIO_FLAG_NO_SYSTEM_CAPTURE)) {
+ return MixMatchStatus::NO_MATCH;
+ }
+
+ if (attributes.usage == AUDIO_USAGE_VOICE_COMMUNICATION) {
+ if (!mix->mVoiceCommunicationCaptureAllowed) {
+ return MixMatchStatus::NO_MATCH;
+ }
+ } else if (!mix->mAllowPrivilegedMediaPlaybackCapture &&
+ hasFlag(attributes.flags, AUDIO_FLAG_NO_MEDIA_PROJECTION)) {
+ return MixMatchStatus::NO_MATCH;
+ }
}
int userId = (int) multiuser_get_user_id(uid);
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 30b739c..6c31b79 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -217,6 +217,18 @@
ALOGV("DeviceVector::refreshTypes() mDeviceTypes %s", dumpDeviceTypes(mDeviceTypes).c_str());
}
+void DeviceVector::refreshAudioProfiles() {
+ if (empty()) {
+ mSupportedProfiles.clear();
+ return;
+ }
+ mSupportedProfiles = itemAt(0)->getAudioProfiles();
+ for (size_t i = 1; i < size(); ++i) {
+ mSupportedProfiles = intersectAudioProfiles(
+ mSupportedProfiles, itemAt(i)->getAudioProfiles());
+ }
+}
+
ssize_t DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
{
for (size_t i = 0; i < size(); i++) {
@@ -238,6 +250,7 @@
}
if (added) {
refreshTypes();
+ refreshAudioProfiles();
}
}
@@ -250,6 +263,7 @@
ret = SortedVector::add(item);
if (ret >= 0) {
refreshTypes();
+ refreshAudioProfiles();
}
} else {
ALOGW("DeviceVector::add device %08x already in", item->type());
@@ -268,6 +282,7 @@
ret = SortedVector::removeAt(ret);
if (ret >= 0) {
refreshTypes();
+ refreshAudioProfiles();
}
}
return ret;
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index ae92b40..09b614d 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -105,6 +105,17 @@
return true;
}
+bool IOProfile::containsSingleDeviceSupportingEncodedFormats(
+ const sp<DeviceDescriptor>& device) const {
+ if (device == nullptr) {
+ return false;
+ }
+ DeviceVector deviceList = mSupportedDevices.getDevicesFromType(device->type());
+ return std::count_if(deviceList.begin(), deviceList.end(),
+ [&device](sp<DeviceDescriptor> deviceDesc) {
+ return device == deviceDesc && deviceDesc->hasCurrentEncodedFormat(); }) == 1;
+}
+
void IOProfile::dump(String8 *dst) const
{
std::string portStr;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index f15ed4b..65bae77 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -246,6 +246,7 @@
if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
(((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
(desc->mDirectOpenCount == 0))) {
+ clearAudioSourcesForOutput(output);
closeOutput(output);
}
}
@@ -265,7 +266,10 @@
DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
updateCallRouting(newDevices);
}
+ std::vector<audio_io_handle_t> outputsToReopen;
const DeviceVector msdOutDevices = getMsdAudioOutDevices();
+ const DeviceVector activeMediaDevices =
+ mEngine->getActiveMediaDevices(mAvailableOutputDevices);
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
@@ -280,6 +284,28 @@
|| (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
setOutputDevices(desc, newDevices, force, 0);
}
+ if (!desc->isDuplicated() && desc->mProfile->hasDynamicAudioProfile() &&
+ desc->devices() != activeMediaDevices &&
+ desc->supportsDevicesForPlayback(activeMediaDevices)) {
+ // Reopen the output to query the dynamic profiles when there is not active
+ // clients or all active clients will be rerouted. Otherwise, set the flag
+ // `mPendingReopenToQueryProfiles` in the SwOutputDescriptor so that the output
+ // can be reopened to query dynamic profiles when all clients are inactive.
+ if (areAllActiveTracksRerouted(desc)) {
+ outputsToReopen.push_back(mOutputs.keyAt(i));
+ } else {
+ desc->mPendingReopenToQueryProfiles = true;
+ }
+ }
+ if (!desc->supportsDevicesForPlayback(activeMediaDevices)) {
+ // Clear the flag that previously set for re-querying profiles.
+ desc->mPendingReopenToQueryProfiles = false;
+ }
+ }
+ for (const auto& output : outputsToReopen) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
+ closeOutput(output);
+ openOutputWithProfileAndDevice(desc->mProfile, activeMediaDevices);
}
if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
@@ -359,7 +385,11 @@
DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
updateCallRouting(newDevices);
}
-
+ // Reconnect Audio Source
+ for (const auto &strategy : mEngine->getOrderedProductStrategies()) {
+ auto attributes = mEngine->getAllAttributesForProductStrategy(strategy).front();
+ checkAudioSourceForAttributes(attributes);
+ }
if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
cleanUpForDevice(device);
}
@@ -444,7 +474,7 @@
// Case 1: A2DP active device switches from primary to primary
// module
// Case 2: A2DP device config changes on primary module.
- if (audio_is_a2dp_out_device(device)) {
+ if (audio_is_a2dp_out_device(device) && hasPrimaryOutput()) {
sp<HwModule> module = mHwModules.getModuleForDeviceType(device, encodedFormat);
audio_module_handle_t primaryHandle = mPrimaryOutput->getModuleHandle();
if (availablePrimaryOutputDevices().contains(devDesc) &&
@@ -538,11 +568,7 @@
ALOGV("updateCallRouting device rxDevice %s txDevice %s",
rxDevices.itemAt(0)->toString().c_str(), txSourceDevice->toString().c_str());
- // release existing RX patch if any
- if (mCallRxPatch != 0) {
- releaseAudioPatchInternal(mCallRxPatch->getHandle());
- mCallRxPatch.clear();
- }
+ disconnectTelephonyRxAudioSource();
// release TX patch if any
if (mCallTxPatch != 0) {
releaseAudioPatchInternal(mCallTxPatch->getHandle());
@@ -590,8 +616,7 @@
if (!createRxPatch) {
muteWaitMs = setOutputDevices(mPrimaryOutput, rxDevices, true, delayMs);
} else { // create RX path audio patch
- mCallRxPatch = createTelephonyPatch(true /*isRx*/, rxDevices.itemAt(0), delayMs);
-
+ connectTelephonyRxAudioSource();
// If the TX device is on the primary HW module but RX device is
// on other HW module, SinkMetaData of telephony input should handle it
// assuming the device uses audio HAL V5.0 and above
@@ -654,6 +679,24 @@
return false;
}
+void AudioPolicyManager::connectTelephonyRxAudioSource()
+{
+ disconnectTelephonyRxAudioSource();
+ const struct audio_port_config source = {
+ .role = AUDIO_PORT_ROLE_SOURCE, .type = AUDIO_PORT_TYPE_DEVICE,
+ .ext.device.type = AUDIO_DEVICE_IN_TELEPHONY_RX, .ext.device.address = ""
+ };
+ const auto aa = mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL);
+ status_t status = startAudioSource(&source, &aa, &mCallRxSourceClientPort, 0/*uid*/);
+ ALOGE_IF(status != NO_ERROR, "%s failed to start Telephony Rx AudioSource", __func__);
+}
+
+void AudioPolicyManager::disconnectTelephonyRxAudioSource()
+{
+ stopAudioSource(mCallRxSourceClientPort);
+ mCallRxSourceClientPort = AUDIO_PORT_HANDLE_NONE;
+}
+
void AudioPolicyManager::setPhoneState(audio_mode_t state)
{
ALOGV("setPhoneState() state %d", state);
@@ -721,10 +764,7 @@
if (state == AUDIO_MODE_IN_CALL) {
updateCallRouting(rxDevices, delayMs);
} else if (oldState == AUDIO_MODE_IN_CALL) {
- if (mCallRxPatch != 0) {
- releaseAudioPatchInternal(mCallRxPatch->getHandle());
- mCallRxPatch.clear();
- }
+ disconnectTelephonyRxAudioSource();
if (mCallTxPatch != 0) {
releaseAudioPatchInternal(mCallTxPatch->getHandle());
mCallTxPatch.clear();
@@ -1932,7 +1972,7 @@
}
}
-void AudioPolicyManager::releaseOutput(audio_port_handle_t portId)
+bool AudioPolicyManager::releaseOutput(audio_port_handle_t portId)
{
ALOGV("%s portId %d", __FUNCTION__, portId);
@@ -1945,7 +1985,7 @@
//
// Here we just log a warning, instead of a fatal error.
ALOGW("releaseOutput() no output for client %d", portId);
- return;
+ return false;
}
ALOGV("releaseOutput() %d", outputDesc->mIoHandle);
@@ -1960,7 +2000,7 @@
if (outputDesc->mDirectOpenCount <= 0) {
ALOGW("releaseOutput() invalid open count %d for output %d",
outputDesc->mDirectOpenCount, outputDesc->mIoHandle);
- return;
+ return false;
}
if (--outputDesc->mDirectOpenCount == 0) {
closeOutput(outputDesc->mIoHandle);
@@ -1969,6 +2009,18 @@
}
outputDesc->removeClient(portId);
+ if (outputDesc->mPendingReopenToQueryProfiles && outputDesc->getClientCount() == 0) {
+ // The output is pending reopened to query dynamic profiles and
+ // there is no active clients
+ closeOutput(outputDesc->mIoHandle);
+ sp<SwAudioOutputDescriptor> newOutputDesc = openOutputWithProfileAndDevice(
+ outputDesc->mProfile, mEngine->getActiveMediaDevices(mAvailableOutputDevices));
+ if (newOutputDesc == nullptr) {
+ ALOGE("%s failed to open output", __func__);
+ }
+ return true;
+ }
+ return false;
}
status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
@@ -3495,7 +3547,9 @@
offloadInfo.channel_mask,
AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD,
true /* directOnly */);
- ALOGV("%s: profile %sfound", __func__, profile != 0 ? "" : "NOT ");
+ ALOGV("%s: profile %sfound%s", __func__, profile != nullptr ? "" : "NOT ",
+ (profile != nullptr && (profile->getFlags() & AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD) != 0)
+ ? ", supports gapless" : "");
if (profile == nullptr) {
return AUDIO_OFFLOAD_NOT_SUPPORTED;
}
@@ -3821,6 +3875,41 @@
sinkDevice->toAudioPortConfig(&sinkPortConfig, &patch->sinks[i]);
patchBuilder.addSink(sinkPortConfig);
+ // Whatever Sw or Hw bridge, we do attach an SwOutput to an Audio Source for
+ // volume management purpose (tracking activity)
+ // In case of Hw bridge, it is a Work Around. The mixPort used is the one declared
+ // in config XML to reach the sink so that is can be declared as available.
+ audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
+ sp<SwAudioOutputDescriptor> outputDesc = nullptr;
+ if (sourceDesc != nullptr) {
+ // take care of dynamic routing for SwOutput selection,
+ audio_attributes_t attributes = sourceDesc->attributes();
+ audio_stream_type_t stream = sourceDesc->stream();
+ audio_attributes_t resultAttr;
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = sourceDesc->config().sample_rate;
+ config.channel_mask = sourceDesc->config().channel_mask;
+ config.format = sourceDesc->config().format;
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ bool isRequestedDeviceForExclusiveUse = false;
+ output_type_t outputType;
+ getOutputForAttrInt(&resultAttr, &output, AUDIO_SESSION_NONE, &attributes,
+ &stream, sourceDesc->uid(), &config, &flags,
+ &selectedDeviceId, &isRequestedDeviceForExclusiveUse,
+ nullptr, &outputType);
+ if (output == AUDIO_IO_HANDLE_NONE) {
+ ALOGV("%s no output for device %s",
+ __FUNCTION__, sinkDevice->toString().c_str());
+ return INVALID_OPERATION;
+ }
+ outputDesc = mOutputs.valueFor(output);
+ if (outputDesc->isDuplicated()) {
+ ALOGE("%s output is duplicated", __func__);
+ return INVALID_OPERATION;
+ }
+ sourceDesc->setSwOutput(outputDesc);
+ }
// create a software bridge in PatchPanel if:
// - source and sink devices are on different HW modules OR
// - audio HAL version is < 3.0
@@ -3836,49 +3925,25 @@
if (patch->num_sinks > 1) {
return INVALID_OPERATION;
}
- audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
- if (sourceDesc != nullptr) {
- // take care of dynamic routing for SwOutput selection,
- audio_attributes_t attributes = sourceDesc->attributes();
- audio_stream_type_t stream = sourceDesc->stream();
- audio_attributes_t resultAttr;
- audio_config_t config = AUDIO_CONFIG_INITIALIZER;
- config.sample_rate = sourceDesc->config().sample_rate;
- config.channel_mask = sourceDesc->config().channel_mask;
- config.format = sourceDesc->config().format;
- audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
- bool isRequestedDeviceForExclusiveUse = false;
- output_type_t outputType;
- getOutputForAttrInt(&resultAttr, &output, AUDIO_SESSION_NONE, &attributes,
- &stream, sourceDesc->uid(), &config, &flags,
- &selectedDeviceId, &isRequestedDeviceForExclusiveUse,
- nullptr, &outputType);
- if (output == AUDIO_IO_HANDLE_NONE) {
- ALOGV("%s no output for device %s",
- __FUNCTION__, sinkDevice->toString().c_str());
- return INVALID_OPERATION;
- }
- } else {
+ if (sourceDesc == nullptr) {
SortedVector<audio_io_handle_t> outputs =
getOutputsForDevices(DeviceVector(sinkDevice), mOutputs);
// if the sink device is reachable via an opened output stream, request to
// go via this output stream by adding a second source to the patch
// description
output = selectOutput(outputs);
- }
- if (output != AUDIO_IO_HANDLE_NONE) {
- sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
- if (outputDesc->isDuplicated()) {
- ALOGV("%s output for device %s is duplicated",
- __FUNCTION__, sinkDevice->toString().c_str());
- return INVALID_OPERATION;
+ if (output != AUDIO_IO_HANDLE_NONE) {
+ outputDesc = mOutputs.valueFor(output);
+ if (outputDesc->isDuplicated()) {
+ ALOGV("%s output for device %s is duplicated",
+ __FUNCTION__, sinkDevice->toString().c_str());
+ return INVALID_OPERATION;
+ }
}
+ }
+ if (outputDesc != nullptr) {
audio_port_config srcMixPortConfig = {};
outputDesc->toAudioPortConfig(&srcMixPortConfig, &patch->sources[0]);
- if (sourceDesc != nullptr) {
- sourceDesc->setSwOutput(outputDesc);
- }
// for volume control, we may need a valid stream
srcMixPortConfig.ext.mix.usecase.stream = sourceDesc != nullptr ?
sourceDesc->stream() : AUDIO_STREAM_PATCH;
@@ -3969,8 +4034,9 @@
sp<SwAudioOutputDescriptor> outputDesc =
mOutputs.getOutputFromId(patch->sources[1].id);
if (outputDesc == NULL) {
- ALOGE("%s output not found for id %d", __func__, patch->sources[0].id);
- return BAD_VALUE;
+ ALOGW("%s output not found for id %d", __func__, patch->sources[0].id);
+ // releaseOutput has already called closeOuput in case of direct output
+ return NO_ERROR;
}
if (patchDesc->getHandle() != outputDesc->getPatchHandle()) {
// force SwOutput patch removal as AF counter part patch has already gone.
@@ -4236,15 +4302,19 @@
disconnectAudioSource(sourceDesc);
audio_attributes_t attributes = sourceDesc->attributes();
- sp<DeviceDescriptor> srcDevice = sourceDesc->srcDevice();
-
+ // May the device (dynamic) have been disconnected/reconnected, id has changed.
+ sp<DeviceDescriptor> srcDevice = mAvailableInputDevices.getDevice(
+ sourceDesc->srcDevice()->type(),
+ String8(sourceDesc->srcDevice()->address().c_str()),
+ AUDIO_FORMAT_DEFAULT);
DeviceVector sinkDevices =
- mEngine->getOutputDevicesForAttributes(attributes, nullptr, true);
+ mEngine->getOutputDevicesForAttributes(attributes, nullptr, false /*fromCache*/);
ALOG_ASSERT(!sinkDevices.isEmpty(), "connectAudioSource(): no device found for attributes");
sp<DeviceDescriptor> sinkDevice = sinkDevices.itemAt(0);
- ALOG_ASSERT(mAvailableOutputDevices.contains(sinkDevice), "%s: Device %s not available",
- __FUNCTION__, sinkDevice->toString().c_str());
-
+ if (!mAvailableOutputDevices.contains(sinkDevice)) {
+ ALOGE("%s Device %s not available", __func__, sinkDevice->toString().c_str());
+ return INVALID_OPERATION;
+ }
PatchBuilder patchBuilder;
patchBuilder.addSink(sinkDevice).addSource(srcDevice);
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
@@ -4254,7 +4324,7 @@
ALOGW("%s patch panel could not connect device patch, error %d", __func__, status);
return INVALID_OPERATION;
}
- sourceDesc->setPatchHandle(handle);
+ sourceDesc->connect(handle, sinkDevice);
// SW Bridge? (@todo: HW bridge, keep track of HwOutput for device selection "reconsideration")
sp<SwAudioOutputDescriptor> swOutput = sourceDesc->swOutput().promote();
if (swOutput != 0) {
@@ -4551,13 +4621,21 @@
status_t AudioPolicyManager::disconnectAudioSource(const sp<SourceClientDescriptor>& sourceDesc)
{
ALOGV("%s port Id %d", __FUNCTION__, sourceDesc->portId());
+ if (!sourceDesc->isConnected()) {
+ ALOGV("%s port Id %d already disconnected", __FUNCTION__, sourceDesc->portId());
+ return NO_ERROR;
+ }
sp<SwAudioOutputDescriptor> swOutput = sourceDesc->swOutput().promote();
if (swOutput != 0) {
status_t status = stopSource(swOutput, sourceDesc);
if (status == NO_ERROR) {
swOutput->stop();
}
- releaseOutput(sourceDesc->portId());
+ if (releaseOutput(sourceDesc->portId())) {
+ // The output descriptor is reopened to query dynamic profiles. In that case, there is
+ // no need to release audio patch here but just return NO_ERROR.
+ return NO_ERROR;
+ }
} else {
sp<HwAudioOutputDescriptor> hwOutputDesc = sourceDesc->hwOutput().promote();
if (hwOutputDesc != 0) {
@@ -4566,7 +4644,9 @@
ALOGW("%s source has neither SW nor HW output", __FUNCTION__);
}
}
- return releaseAudioPatchInternal(sourceDesc->getPatchHandle());
+ status_t status = releaseAudioPatchInternal(sourceDesc->getPatchHandle());
+ sourceDesc->disconnect();
+ return status;
}
sp<SourceClientDescriptor> AudioPolicyManager::getSourceForAttributesOnOutput(
@@ -4657,6 +4737,9 @@
return status;
}
+ mCommunnicationStrategy = mEngine->getProductStrategyForAttributes(
+ mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL));
+
// after parsing the config, mOutputDevicesAll and mInputDevicesAll contain all known devices;
// open all output streams needed to access attached devices
onNewAudioModulesAvailableInt(nullptr /*newDevices*/);
@@ -4678,17 +4761,11 @@
}
}
- if (mPrimaryOutput == 0) {
- ALOGE("Failed to open primary output");
- status = NO_INIT;
- }
+ ALOGW_IF(mPrimaryOutput == nullptr, "The policy configuration does not declare a primary output");
// Silence ALOGV statements
property_set("log.tag." LOG_TAG, "D");
- mCommunnicationStrategy = mEngine->getProductStrategyForAttributes(
- mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL));
-
updateDevicesAndOutputs();
return status;
}
@@ -4794,7 +4871,7 @@
setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
}
}
- if (mPrimaryOutput == 0 &&
+ if (mPrimaryOutput == nullptr &&
outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
mPrimaryOutput = outputDesc;
}
@@ -4871,6 +4948,10 @@
void AudioPolicyManager::removeOutput(audio_io_handle_t output)
{
+ if (mPrimaryOutput != 0 && mPrimaryOutput == mOutputs.valueFor(output)) {
+ ALOGV("%s: removing primary output", __func__);
+ mPrimaryOutput = nullptr;
+ }
mOutputs.removeItem(output);
selectOutputForMusicEffects();
}
@@ -4964,82 +5045,8 @@
ALOGV("opening output for device %08x with params %s profile %p name %s",
deviceType, address.string(), profile.get(), profile->getName().c_str());
- desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
- audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
- status = desc->open(nullptr, DeviceVector(device),
- AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
-
- if (status == NO_ERROR) {
- // Here is where the out_set_parameters() for card & device gets called
- if (!address.isEmpty()) {
- char *param = audio_device_address_to_parameter(deviceType, address);
- mpClientInterface->setParameters(output, String8(param));
- free(param);
- }
- updateAudioProfiles(device, output, profile->getAudioProfiles());
- if (!profile->hasValidAudioProfile()) {
- ALOGW("checkOutputsForDevice() missing param");
- desc->close();
- output = AUDIO_IO_HANDLE_NONE;
- } else if (profile->hasDynamicAudioProfile()) {
- desc->close();
- output = AUDIO_IO_HANDLE_NONE;
- audio_config_t config = AUDIO_CONFIG_INITIALIZER;
- profile->pickAudioProfile(
- config.sample_rate, config.channel_mask, config.format);
- config.offload_info.sample_rate = config.sample_rate;
- config.offload_info.channel_mask = config.channel_mask;
- config.offload_info.format = config.format;
-
- status = desc->open(&config, DeviceVector(device),
- AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
- if (status != NO_ERROR) {
- output = AUDIO_IO_HANDLE_NONE;
- }
- }
-
- if (output != AUDIO_IO_HANDLE_NONE) {
- addOutput(output, desc);
- if (audio_is_remote_submix_device(deviceType) && address != "0") {
- sp<AudioPolicyMix> policyMix;
- if (mPolicyMixes.getAudioPolicyMix(deviceType, address, policyMix)
- == NO_ERROR) {
- policyMix->setOutput(desc);
- desc->mPolicyMix = policyMix;
- } else {
- ALOGW("checkOutputsForDevice() cannot find policy for address %s",
- address.string());
- }
-
- } else if (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
- hasPrimaryOutput()) {
- // no duplicated output for direct outputs and
- // outputs used by dynamic policy mixes
- audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
-
- //TODO: configure audio effect output stage here
-
- // open a duplicating output thread for the new output and the primary output
- sp<SwAudioOutputDescriptor> dupOutputDesc =
- new SwAudioOutputDescriptor(NULL, mpClientInterface);
- status = dupOutputDesc->openDuplicating(mPrimaryOutput, desc,
- &duplicatedOutput);
- if (status == NO_ERROR) {
- // add duplicated output descriptor
- addOutput(duplicatedOutput, dupOutputDesc);
- } else {
- ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
- mPrimaryOutput->mIoHandle, output);
- desc->close();
- removeOutput(output);
- nextAudioPortGeneration();
- output = AUDIO_IO_HANDLE_NONE;
- }
- }
- }
- } else {
- output = AUDIO_IO_HANDLE_NONE;
- }
+ desc = openOutputWithProfileAndDevice(profile, DeviceVector(device));
+ audio_io_handle_t output = desc == nullptr ? AUDIO_IO_HANDLE_NONE : desc->mIoHandle;
if (output == AUDIO_IO_HANDLE_NONE) {
ALOGW("checkOutputsForDevice() could not open output for device %x", deviceType);
profiles.removeAt(profile_index);
@@ -5048,6 +5055,8 @@
outputs.add(output);
// Load digital format info only for digital devices
if (audio_device_is_digital(deviceType)) {
+ // TODO: when getAudioPort is ready, it may not be needed to import the audio
+ // port but just pick audio profile
device->importAudioPortAndPickAudioProfile(profile);
}
@@ -5072,7 +5081,7 @@
if (!desc->isDuplicated()) {
// exact match on device
if (device_distinguishes_on_address(deviceType) && desc->supportsDevice(device)
- && desc->devicesSupportEncodedFormats({deviceType})) {
+ && desc->containsSingleDeviceSupportingEncodedFormats(device)) {
outputs.add(mOutputs.keyAt(i));
} else if (!mAvailableOutputDevices.containsAtLeastOne(desc->supportedDevices())) {
ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
@@ -5085,11 +5094,30 @@
for (const auto& hwModule : mHwModules) {
for (size_t j = 0; j < hwModule->getOutputProfiles().size(); j++) {
sp<IOProfile> profile = hwModule->getOutputProfiles()[j];
- if (profile->supportsDevice(device)) {
- ALOGV("checkOutputsForDevice(): "
- "clearing direct output profile %zu on module %s",
- j, hwModule->getName());
- profile->clearAudioProfiles();
+ if (!profile->supportsDevice(device)) {
+ continue;
+ }
+ ALOGV("checkOutputsForDevice(): "
+ "clearing direct output profile %zu on module %s",
+ j, hwModule->getName());
+ profile->clearAudioProfiles();
+ if (!profile->hasDynamicAudioProfile()) {
+ continue;
+ }
+ // When a device is disconnected, if there is an IOProfile that contains dynamic
+ // profiles and supports the disconnected device, call getAudioPort to repopulate
+ // the capabilities of the devices that is supported by the IOProfile.
+ for (const auto& supportedDevice : profile->getSupportedDevices()) {
+ if (supportedDevice == device ||
+ !mAvailableOutputDevices.contains(supportedDevice)) {
+ continue;
+ }
+ struct audio_port_v7 port;
+ supportedDevice->toAudioPort(&port);
+ status_t status = mpClientInterface->getAudioPort(&port);
+ if (status == NO_ERROR) {
+ supportedDevice->importAudioPort(port);
+ }
}
}
}
@@ -5372,6 +5400,29 @@
mEngine->getProductStrategyForAttributes(rAttr);
}
+void AudioPolicyManager::checkAudioSourceForAttributes(const audio_attributes_t &attr)
+{
+ for (size_t i = 0; i < mAudioSources.size(); i++) {
+ sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
+ if (sourceDesc != nullptr && followsSameRouting(attr, sourceDesc->attributes())
+ && sourceDesc->getPatchHandle() == AUDIO_PATCH_HANDLE_NONE
+ && !isCallRxAudioSource(sourceDesc)) {
+ connectAudioSource(sourceDesc);
+ }
+ }
+}
+
+void AudioPolicyManager::clearAudioSourcesForOutput(audio_io_handle_t output)
+{
+ for (size_t i = 0; i < mAudioSources.size(); i++) {
+ sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
+ if (sourceDesc != nullptr && sourceDesc->swOutput().promote() != nullptr
+ && sourceDesc->swOutput().promote()->mIoHandle == output) {
+ disconnectAudioSource(sourceDesc);
+ }
+ }
+}
+
void AudioPolicyManager::checkOutputForAttributes(const audio_attributes_t &attr)
{
auto psId = mEngine->getProductStrategyForAttributes(attr);
@@ -5468,7 +5519,7 @@
newDevices.types());
}
sp<SourceClientDescriptor> source = getSourceForAttributesOnOutput(srcOut, attr);
- if (source != 0){
+ if (source != nullptr && !isCallRxAudioSource(source)) {
connectAudioSource(source);
}
}
@@ -5491,6 +5542,7 @@
for (const auto &strategy : mEngine->getOrderedProductStrategies()) {
auto attributes = mEngine->getAllAttributesForProductStrategy(strategy).front();
checkOutputForAttributes(attributes);
+ checkAudioSourceForAttributes(attributes);
}
}
@@ -6462,9 +6514,10 @@
{
for (ssize_t i = (ssize_t)mAudioSources.size() - 1; i >= 0; i--) {
sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
- if (sourceDesc->srcDevice()->equals(deviceDesc)) {
- ALOGV("%s releasing audio source %d", __FUNCTION__, sourceDesc->portId());
- stopAudioSource(sourceDesc->portId());
+ if (sourceDesc->isConnected() && (sourceDesc->srcDevice()->equals(deviceDesc) ||
+ sourceDesc->sinkDevice()->equals(deviceDesc))
+ && !isCallRxAudioSource(sourceDesc)) {
+ disconnectAudioSource(sourceDesc);
}
}
@@ -6478,10 +6531,14 @@
release = true;
}
}
+ const char *address = deviceDesc->address().c_str();
for (size_t j = 0; j < patchDesc->mPatch.num_sinks && !release; j++) {
const struct audio_port_config *sink = &patchDesc->mPatch.sinks[j];
if (sink->type == AUDIO_PORT_TYPE_DEVICE &&
- sink->ext.device.type == deviceDesc->type()) {
+ sink->ext.device.type == deviceDesc->type() &&
+ (strnlen(address, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0
+ || strncmp(sink->ext.device.address, address,
+ AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
release = true;
}
}
@@ -6704,4 +6761,129 @@
return status;
}
+bool AudioPolicyManager::areAllActiveTracksRerouted(const sp<SwAudioOutputDescriptor>& output)
+{
+ const TrackClientVector activeClients = output->getActiveClients();
+ if (activeClients.empty()) {
+ return true;
+ }
+ ssize_t index = mAudioPatches.indexOfKey(output->getPatchHandle());
+ if (index < 0) {
+ ALOGE("%s, no audio patch found while there are active clients on output %d",
+ __func__, output->getId());
+ return false;
+ }
+ sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
+ DeviceVector routedDevices;
+ for (int i = 0; i < patchDesc->mPatch.num_sinks; ++i) {
+ sp<DeviceDescriptor> device = mAvailableOutputDevices.getDeviceFromId(
+ patchDesc->mPatch.sinks[i].id);
+ if (device == nullptr) {
+ ALOGE("%s, no audio device found with id(%d)",
+ __func__, patchDesc->mPatch.sinks[i].id);
+ return false;
+ }
+ routedDevices.add(device);
+ }
+ for (const auto& client : activeClients) {
+ // TODO: b/175343099 only travel the valid client
+ sp<DeviceDescriptor> preferredDevice =
+ mAvailableOutputDevices.getDeviceFromId(client->preferredDeviceId());
+ if (mEngine->getOutputDevicesForAttributes(
+ client->attributes(), preferredDevice, false) == routedDevices) {
+ return false;
+ }
+ }
+ return true;
+}
+
+sp<SwAudioOutputDescriptor> AudioPolicyManager::openOutputWithProfileAndDevice(
+ const sp<IOProfile>& profile, const DeviceVector& devices)
+{
+ for (const auto& device : devices) {
+ // TODO: This should be checking if the profile supports the device combo.
+ if (!profile->supportsDevice(device)) {
+ return nullptr;
+ }
+ }
+ sp<SwAudioOutputDescriptor> desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
+ audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
+ status_t status = desc->open(nullptr, devices,
+ AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
+ if (status != NO_ERROR) {
+ return nullptr;
+ }
+
+ // Here is where the out_set_parameters() for card & device gets called
+ sp<DeviceDescriptor> device = devices.getDeviceForOpening();
+ const audio_devices_t deviceType = device->type();
+ const String8 &address = String8(device->address().c_str());
+ if (!address.isEmpty()) {
+ char *param = audio_device_address_to_parameter(deviceType, address.c_str());
+ mpClientInterface->setParameters(output, String8(param));
+ free(param);
+ }
+ updateAudioProfiles(device, output, profile->getAudioProfiles());
+ if (!profile->hasValidAudioProfile()) {
+ ALOGW("%s() missing param", __func__);
+ desc->close();
+ return nullptr;
+ } else if (profile->hasDynamicAudioProfile()) {
+ desc->close();
+ output = AUDIO_IO_HANDLE_NONE;
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ profile->pickAudioProfile(
+ config.sample_rate, config.channel_mask, config.format);
+ config.offload_info.sample_rate = config.sample_rate;
+ config.offload_info.channel_mask = config.channel_mask;
+ config.offload_info.format = config.format;
+
+ status = desc->open(&config, devices,
+ AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
+ if (status != NO_ERROR) {
+ return nullptr;
+ }
+ }
+
+ addOutput(output, desc);
+ if (audio_is_remote_submix_device(deviceType) && address != "0") {
+ sp<AudioPolicyMix> policyMix;
+ if (mPolicyMixes.getAudioPolicyMix(deviceType, address, policyMix) == NO_ERROR) {
+ policyMix->setOutput(desc);
+ desc->mPolicyMix = policyMix;
+ } else {
+ ALOGW("checkOutputsForDevice() cannot find policy for address %s",
+ address.string());
+ }
+
+ } else if (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) && hasPrimaryOutput()) {
+ // no duplicated output for direct outputs and
+ // outputs used by dynamic policy mixes
+ audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
+
+ //TODO: configure audio effect output stage here
+
+ // open a duplicating output thread for the new output and the primary output
+ sp<SwAudioOutputDescriptor> dupOutputDesc =
+ new SwAudioOutputDescriptor(nullptr, mpClientInterface);
+ status = dupOutputDesc->openDuplicating(mPrimaryOutput, desc, &duplicatedOutput);
+ if (status == NO_ERROR) {
+ // add duplicated output descriptor
+ addOutput(duplicatedOutput, dupOutputDesc);
+ } else {
+ ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
+ mPrimaryOutput->mIoHandle, output);
+ desc->close();
+ removeOutput(output);
+ nextAudioPortGeneration();
+ return nullptr;
+ }
+ }
+ if (mPrimaryOutput == nullptr && profile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
+ ALOGV("%s(): re-assigning mPrimaryOutput", __func__);
+ mPrimaryOutput = desc;
+ }
+ return desc;
+}
+
} // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 4e745bd..eba0c44 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -125,7 +125,7 @@
output_type_t *outputType) override;
virtual status_t startOutput(audio_port_handle_t portId);
virtual status_t stopOutput(audio_port_handle_t portId);
- virtual void releaseOutput(audio_port_handle_t portId);
+ virtual bool releaseOutput(audio_port_handle_t portId);
virtual status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_unique_id_t riid,
@@ -556,6 +556,15 @@
*/
void updateCallAndOutputRouting(bool forceVolumeReeval = true, uint32_t delayMs = 0);
+ bool isCallRxAudioSource(const sp<SourceClientDescriptor> &source) {
+ return mCallRxSourceClientPort != AUDIO_PORT_HANDLE_NONE
+ && source == mAudioSources.valueFor(mCallRxSourceClientPort);
+ }
+
+ void connectTelephonyRxAudioSource();
+
+ void disconnectTelephonyRxAudioSource();
+
/**
* @brief updates routing for all inputs.
*/
@@ -571,6 +580,16 @@
*/
void checkOutputForAttributes(const audio_attributes_t &attr);
+ /**
+ * @brief checkAudioSourceForAttributes checks if any AudioSource following the same routing
+ * as the given audio attributes is not routed and try to connect it.
+ * It must be called once checkOutputForAttributes has been called for orphans AudioSource,
+ * aka AudioSource not attached to any Audio Output (e.g. AudioSource connected to direct
+ * Output which has been disconnected (and output closed) due to sink device unavailable).
+ * @param attr to be considered
+ */
+ void checkAudioSourceForAttributes(const audio_attributes_t &attr);
+
bool followsSameRouting(const audio_attributes_t &lAttr,
const audio_attributes_t &rAttr) const;
@@ -740,6 +759,7 @@
sp<SourceClientDescriptor> getSourceForAttributesOnOutput(audio_io_handle_t output,
const audio_attributes_t &attr);
+ void clearAudioSourcesForOutput(audio_io_handle_t output);
void cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc);
@@ -786,7 +806,6 @@
SoundTriggerSessionCollection mSoundTriggerSessions;
sp<AudioPatch> mCallTxPatch;
- sp<AudioPatch> mCallRxPatch;
HwAudioOutputCollection mHwOutputs;
SourceClientCollection mAudioSources;
@@ -825,6 +844,10 @@
// Cached product strategy ID corresponding to legacy strategy STRATEGY_PHONE
product_strategy_t mCommunnicationStrategy;
+ // The port handle of the hardware audio source created internally for the Call RX audio
+ // end point.
+ audio_port_handle_t mCallRxSourceClientPort = AUDIO_PORT_HANDLE_NONE;
+
private:
void onNewAudioModulesAvailableInt(DeviceVector *newDevices);
@@ -981,6 +1004,12 @@
const char* context);
bool isScoRequestedForComm() const;
+
+ bool areAllActiveTracksRerouted(const sp<SwAudioOutputDescriptor>& output);
+
+ sp<SwAudioOutputDescriptor> openOutputWithProfileAndDevice(const sp<IOProfile>& profile,
+ const DeviceVector& devices);
+
};
};
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 10bf707..66f9fbd 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1241,7 +1241,7 @@
return mix.mVoiceCommunicationCaptureAllowed; });
bool needCaptureMediaOutput = std::any_of(mixes.begin(), mixes.end(), [](auto& mix) {
- return mix.mAllowPrivilegedPlaybackCapture; });
+ return mix.mAllowPrivilegedMediaPlaybackCapture; });
const uid_t callingUid = IPCThreadState::self()->getCallingUid();
const pid_t callingPid = IPCThreadState::self()->getCallingPid();
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index a898dff..80022c8 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -529,6 +529,11 @@
for (size_t i =0; i < mAudioRecordClients.size(); i++) {
sp<AudioRecordClient> current = mAudioRecordClients[i];
+ if (!isVirtualSource(current->attributes.source)
+ && isUserSensorPrivacyEnabledForUid(current->uid)) {
+ setAppState_l(current->portId, APP_STATE_IDLE);
+ continue;
+ }
if (!current->active) {
continue;
}
@@ -978,6 +983,16 @@
return NO_INIT;
}
+bool AudioPolicyService::isUserSensorPrivacyEnabledForUid(uid_t uid) {
+ userid_t userId = multiuser_get_user_id(uid);
+ if (mMicrophoneSensorPrivacyPolicies.find(userId) == mMicrophoneSensorPrivacyPolicies.end()) {
+ sp<SensorPrivacyPolicy> userPolicy = new SensorPrivacyPolicy(this);
+ userPolicy->registerSelfForMicrophoneOnly(userId);
+ mMicrophoneSensorPrivacyPolicies[userId] = userPolicy;
+ }
+ return mMicrophoneSensorPrivacyPolicies[userId]->isSensorPrivacyEnabled();
+}
+
status_t AudioPolicyService::printHelp(int out) {
return dprintf(out, "Audio policy service commands:\n"
" get-uid-state <PACKAGE> [--user USER_ID] gets the uid state\n"
@@ -1211,6 +1226,14 @@
spm.addSensorPrivacyListener(this);
}
+void AudioPolicyService::SensorPrivacyPolicy::registerSelfForMicrophoneOnly(int userId) {
+ SensorPrivacyManager spm;
+ mSensorPrivacyEnabled = spm.isIndividualSensorPrivacyEnabled(userId,
+ SensorPrivacyManager::INDIVIDUAL_SENSOR_MICROPHONE);
+ spm.addIndividualSensorPrivacyListener(userId,
+ SensorPrivacyManager::INDIVIDUAL_SENSOR_MICROPHONE, this);
+}
+
void AudioPolicyService::SensorPrivacyPolicy::unregisterSelf() {
SensorPrivacyManager spm;
spm.removeSensorPrivacyListener(this);
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index db84d54..2cb8759 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -304,6 +304,8 @@
virtual status_t setRttEnabled(bool enabled);
+ virtual bool isUserSensorPrivacyEnabledForUid(uid_t uid);
+
bool isCallScreenModeSupported() override;
void doOnNewAudioModulesAvailable();
@@ -466,6 +468,7 @@
: mService(service) {}
void registerSelf();
+ void registerSelfForMicrophoneOnly(int userId);
void unregisterSelf();
bool isSensorPrivacyEnabled();
@@ -939,6 +942,8 @@
MediaPackageManager mPackageManager; // To check allowPlaybackCapture
CaptureStateNotifier mCaptureStateNotifier;
+
+ std::map<userid_t, sp<SensorPrivacyPolicy>> mMicrophoneSensorPrivacyPolicies;
};
} // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 92c8e30..e80404b 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2161,6 +2161,14 @@
streamStats[i].mRequestCount = stats->second.mRequestedFrameCount;
streamStats[i].mErrorCount = stats->second.mDroppedFrameCount;
streamStats[i].mStartLatencyMs = stats->second.mStartLatencyMs;
+ streamStats[i].mHistogramType =
+ hardware::CameraStreamStats::HISTOGRAM_TYPE_CAPTURE_LATENCY;
+ streamStats[i].mHistogramBins.assign(
+ stats->second.mCaptureLatencyBins.begin(),
+ stats->second.mCaptureLatencyBins.end());
+ streamStats[i].mHistogramCounts.assign(
+ stats->second.mCaptureLatencyHistogram.begin(),
+ stats->second.mCaptureLatencyHistogram.end());
}
}
listener->notifyIdle(requestCount, resultErrorCount, deviceError, streamStats);
diff --git a/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp b/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp
index 83965c4..7a7707c 100644
--- a/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp
+++ b/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp
@@ -18,12 +18,21 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
+#include <numeric>
+
+#include <inttypes.h>
#include <utils/Log.h>
#include "SessionStatsBuilder.h"
namespace android {
+// Bins for capture latency: [0, 100], [100, 200], [200, 300], ...
+// [1300, 2100], [2100, inf].
+// Capture latency is in the unit of millisecond.
+const std::array<int32_t, StreamStats::LATENCY_BIN_COUNT-1> StreamStats::mCaptureLatencyBins {
+ { 100, 200, 300, 400, 500, 700, 900, 1300, 2100 } };
+
status_t SessionStatsBuilder::addStream(int id) {
std::lock_guard<std::mutex> l(mLock);
StreamStats stats;
@@ -52,10 +61,14 @@
mCounterStopped = false;
mDeviceError = false;
for (auto& streamStats : mStatsMap) {
- streamStats.second.mRequestedFrameCount = 0;
- streamStats.second.mDroppedFrameCount = 0;
- streamStats.second.mCounterStopped = false;
- streamStats.second.mStartLatencyMs = 0;
+ StreamStats& streamStat = streamStats.second;
+ streamStat.mRequestedFrameCount = 0;
+ streamStat.mDroppedFrameCount = 0;
+ streamStat.mCounterStopped = false;
+ streamStat.mStartLatencyMs = 0;
+
+ std::fill(streamStat.mCaptureLatencyHistogram.begin(),
+ streamStat.mCaptureLatencyHistogram.end(), 0);
}
}
@@ -66,23 +79,28 @@
void SessionStatsBuilder::stopCounter(int id) {
std::lock_guard<std::mutex> l(mLock);
- mStatsMap[id].mCounterStopped = true;
+ StreamStats& streamStat = mStatsMap[id];
+ streamStat.mCounterStopped = true;
}
void SessionStatsBuilder::incCounter(int id, bool dropped, int32_t captureLatencyMs) {
std::lock_guard<std::mutex> l(mLock);
+
auto it = mStatsMap.find(id);
- if (it != mStatsMap.end()) {
- if (!it->second.mCounterStopped) {
- it->second.mRequestedFrameCount++;
- if (dropped) {
- it->second.mDroppedFrameCount++;
- } else if (it->second.mRequestedFrameCount == 1) {
- // The capture latency for the first request.
- it->second.mStartLatencyMs = captureLatencyMs;
- }
- }
+ if (it == mStatsMap.end()) return;
+
+ StreamStats& streamStat = it->second;
+ if (streamStat.mCounterStopped) return;
+
+ streamStat.mRequestedFrameCount++;
+ if (dropped) {
+ streamStat.mDroppedFrameCount++;
+ } else if (streamStat.mRequestedFrameCount - streamStat.mDroppedFrameCount == 1) {
+ // The capture latency for the first request.
+ streamStat.mStartLatencyMs = captureLatencyMs;
}
+
+ streamStat.updateLatencyHistogram(captureLatencyMs);
}
void SessionStatsBuilder::stopCounter() {
@@ -95,10 +113,10 @@
void SessionStatsBuilder::incResultCounter(bool dropped) {
std::lock_guard<std::mutex> l(mLock);
- if (!mCounterStopped) {
- mRequestCount ++;
- if (dropped) mErrorResultCount++;
- }
+ if (mCounterStopped) return;
+
+ mRequestCount++;
+ if (dropped) mErrorResultCount++;
}
void SessionStatsBuilder::onDeviceError() {
@@ -106,4 +124,18 @@
mDeviceError = true;
}
+void StreamStats::updateLatencyHistogram(int32_t latencyMs) {
+ size_t i;
+ for (i = 0; i < mCaptureLatencyBins.size(); i++) {
+ if (latencyMs < mCaptureLatencyBins[i]) {
+ mCaptureLatencyHistogram[i] ++;
+ break;
+ }
+ }
+
+ if (i == mCaptureLatencyBins.size()) {
+ mCaptureLatencyHistogram[i]++;
+ }
+}
+
}; // namespace android
diff --git a/services/camera/libcameraservice/utils/SessionStatsBuilder.h b/services/camera/libcameraservice/utils/SessionStatsBuilder.h
index 7943637..c23abb6 100644
--- a/services/camera/libcameraservice/utils/SessionStatsBuilder.h
+++ b/services/camera/libcameraservice/utils/SessionStatsBuilder.h
@@ -19,22 +19,38 @@
#include <utils/Errors.h>
-#include <mutex>
+#include <array>
#include <map>
+#include <mutex>
namespace android {
// Helper class to build stream stats
struct StreamStats {
+ // Fields for buffer drop
int64_t mRequestedFrameCount;
int64_t mDroppedFrameCount;
bool mCounterStopped;
+
+ // Fields for stream startup latency
int32_t mStartLatencyMs;
+ // Fields for capture latency measurement
+ const static int LATENCY_BIN_COUNT = 10;
+ // Boundary values separating between adjacent bins, excluding 0 and
+ // infinity.
+ const static std::array<int32_t, LATENCY_BIN_COUNT-1> mCaptureLatencyBins;
+ // Counter values for all histogram bins. One more entry than mCaptureLatencyBins.
+ std::array<int64_t, LATENCY_BIN_COUNT> mCaptureLatencyHistogram;
+
StreamStats() : mRequestedFrameCount(0),
mDroppedFrameCount(0),
mCounterStopped(false),
- mStartLatencyMs(0) {}
+ mStartLatencyMs(0),
+ mCaptureLatencyHistogram{}
+ {}
+
+ void updateLatencyHistogram(int32_t latencyMs);
};
// Helper class to build session stats
diff --git a/services/mediacodec/seccomp_policy/mediacodec-x86.policy b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
index a9d32d6..4bcc077 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-x86.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
@@ -27,6 +27,7 @@
mmap: 1
fstat64: 1
fstat: 1
+stat: 1
stat64: 1
statfs64: 1
madvise: 1
diff --git a/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy b/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy
index a9d32d6..4bcc077 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-x86_64.policy
@@ -27,6 +27,7 @@
mmap: 1
fstat64: 1
fstat: 1
+stat: 1
stat64: 1
statfs64: 1
madvise: 1
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy b/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy
index eb71e28..9bafe7b 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-x86.policy
@@ -27,6 +27,7 @@
mmap: 1
fstat64: 1
fstat: 1
+stat: 1
stat64: 1
statfs64: 1
madvise: 1
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy b/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy
index e72d4db..b0ed040 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-x86_64.policy
@@ -27,6 +27,7 @@
mmap: 1
fstat64: 1
fstat: 1
+stat: 1
stat64: 1
statfs64: 1
madvise: 1
diff --git a/services/mediaextractor/main_extractorservice.cpp b/services/mediaextractor/main_extractorservice.cpp
index b7b51a6..10b8135 100644
--- a/services/mediaextractor/main_extractorservice.cpp
+++ b/services/mediaextractor/main_extractorservice.cpp
@@ -15,6 +15,9 @@
** limitations under the License.
*/
+//#define LOG_NDEBUG 0
+#define LOG_TAG "main_extractorservice"
+
#include <fcntl.h>
#include <sys/prctl.h>
#include <sys/wait.h>
@@ -26,6 +29,7 @@
#include <android-base/logging.h>
#include <android-base/properties.h>
+#include <utils/Log.h>
#include <utils/misc.h>
// from LOCAL_C_INCLUDES
@@ -41,10 +45,16 @@
int main(int argc __unused, char** argv)
{
+
+#if __has_feature(hwaddress_sanitizer)
+ ALOGI("disable media.extractor memory limits (hwasan enabled)");
+#else
+ ALOGI("enable media.extractor memory limits");
limitProcessMemory(
"ro.media.maxmem", /* property that defines limit */
SIZE_MAX, /* upper limit in bytes */
20 /* upper limit as percentage of physical RAM */);
+#endif
signal(SIGPIPE, SIG_IGN);
diff --git a/services/mediatranscoding/MediaTranscodingService.cpp b/services/mediatranscoding/MediaTranscodingService.cpp
index 64def5e..74477a8 100644
--- a/services/mediatranscoding/MediaTranscodingService.cpp
+++ b/services/mediatranscoding/MediaTranscodingService.cpp
@@ -62,16 +62,18 @@
uid_t callingUid = AIBinder_getCallingUid();
pid_t callingPid = AIBinder_getCallingPid();
- int32_t permissionResult;
- if (APermissionManager_checkPermission("android.permission.DUMP", callingPid, callingUid,
- &permissionResult) != PERMISSION_MANAGER_STATUS_OK ||
- permissionResult != PERMISSION_MANAGER_PERMISSION_GRANTED) {
- result.format(
- "Permission Denial: "
- "can't dump MediaTranscodingService from pid=%d, uid=%d\n",
- AIBinder_getCallingPid(), AIBinder_getCallingUid());
- write(fd, result.string(), result.size());
- return PERMISSION_DENIED;
+ if (__builtin_available(android 31, *)) {
+ int32_t permissionResult;
+ if (APermissionManager_checkPermission("android.permission.DUMP", callingPid, callingUid,
+ &permissionResult) != PERMISSION_MANAGER_STATUS_OK ||
+ permissionResult != PERMISSION_MANAGER_PERMISSION_GRANTED) {
+ result.format(
+ "Permission Denial: "
+ "can't dump MediaTranscodingService from pid=%d, uid=%d\n",
+ AIBinder_getCallingPid(), AIBinder_getCallingUid());
+ write(fd, result.string(), result.size());
+ return PERMISSION_DENIED;
+ }
}
const size_t SIZE = 256;
diff --git a/services/tuner/Android.bp b/services/tuner/Android.bp
index 5327289..1379090 100644
--- a/services/tuner/Android.bp
+++ b/services/tuner/Android.bp
@@ -1,34 +1,16 @@
filegroup {
name: "tv_tuner_aidl",
srcs: [
- "aidl/android/media/tv/tuner/ITunerFrontend.aidl",
- "aidl/android/media/tv/tuner/ITunerFrontendCallback.aidl",
- "aidl/android/media/tv/tuner/ITunerService.aidl",
- "aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendAnalogCapabilities.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendAtscCapabilities.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendAtsc3Capabilities.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendCableCapabilities.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendCapabilities.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendDvbsCapabilities.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendDvbtCapabilities.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendIsdbsCapabilities.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendIsdbs3Capabilities.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendIsdbtCapabilities.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendAnalogSettings.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendAtsc3PlpSettings.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendAtsc3Settings.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendAtscSettings.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendCableSettings.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendDvbsCodeRate.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendDvbsSettings.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendDvbtSettings.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendIsdbs3Settings.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendIsdbsSettings.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendIsdbtSettings.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendSettings.aidl",
- "aidl/android/media/tv/tuner/TunerFrontendStatus.aidl",
- "aidl/android/media/tv/tuner/TunerServiceFrontendInfo.aidl",
+ "aidl/android/media/tv/tuner/*.aidl",
+ ],
+ path: "aidl",
+}
+
+filegroup {
+ name: "tv_tuner_frontend_info",
+ srcs: [
+ "aidl/android/media/tv/tuner/TunerFrontendInfo.aidl",
+ "aidl/android/media/tv/tuner/TunerFrontend*Capabilities.aidl",
],
path: "aidl",
}
@@ -57,16 +39,37 @@
},
}
+aidl_interface {
+ name: "tv_tuner_frontend_info_aidl_interface",
+ unstable: true,
+ local_include_dir: "aidl",
+ srcs: [
+ ":tv_tuner_frontend_info",
+ ],
+
+ backend: {
+ java: {
+ enabled: true,
+ },
+ cpp: {
+ enabled: true,
+ },
+ ndk: {
+ enabled: true,
+ },
+ },
+}
+
cc_library {
name: "libtunerservice",
srcs: [
- "TunerService.cpp",
- "TunerFrontend.cpp"
+ "Tuner*.cpp"
],
shared_libs: [
"android.hardware.tv.tuner@1.0",
+ "android.hardware.tv.tuner@1.1",
"libbase",
"libbinder_ndk",
"libcutils",
diff --git a/services/tuner/TunerFrontend.cpp b/services/tuner/TunerFrontend.cpp
index ba4553b..e92489d 100644
--- a/services/tuner/TunerFrontend.cpp
+++ b/services/tuner/TunerFrontend.cpp
@@ -17,10 +17,9 @@
#define LOG_TAG "TunerFrontend"
#include "TunerFrontend.h"
-#include "TunerService.h"
-using ::aidl::android::media::tv::tuner::TunerAtsc3PlpInfo;
using ::aidl::android::media::tv::tuner::TunerFrontendAtsc3PlpSettings;
+using ::aidl::android::media::tv::tuner::TunerFrontendScanAtsc3PlpInfo;
using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSifStandard;
using ::android::hardware::tv::tuner::V1_0::FrontendAnalogType;
using ::android::hardware::tv::tuner::V1_0::FrontendAtscModulation;
@@ -69,29 +68,23 @@
using ::android::hardware::tv::tuner::V1_0::FrontendScanType;
using ::android::hardware::tv::tuner::V1_0::FrontendSettings;;
using ::android::hardware::tv::tuner::V1_0::Result;
+using ::android::hardware::tv::tuner::V1_1::FrontendModulation;
namespace android {
-TunerFrontend::TunerFrontend(sp<ITuner> tuner, int frontendHandle) {
- mTuner = tuner;
- mId = TunerService::getResourceIdFromHandle(frontendHandle);
-
- if (mTuner != NULL) {
- Result status;
- mTuner->openFrontendById(mId, [&](Result result, const sp<IFrontend>& frontend) {
- mFrontend = frontend;
- status = result;
- });
- if (status != Result::SUCCESS) {
- mFrontend = NULL;
- }
- }
+TunerFrontend::TunerFrontend(sp<IFrontend> frontend, int id) {
+ mFrontend = frontend;
+ mFrontend_1_1 = ::android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend);
+ mId = id;
}
-TunerFrontend::~TunerFrontend() {}
+TunerFrontend::~TunerFrontend() {
+ mFrontend = NULL;
+ mId = -1;
+}
Status TunerFrontend::setCallback(
- const std::shared_ptr<ITunerFrontendCallback>& tunerFrontendCallback) {
+ const shared_ptr<ITunerFrontendCallback>& tunerFrontendCallback) {
if (mFrontend == NULL) {
ALOGE("IFrontend is not initialized");
return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
@@ -124,6 +117,7 @@
return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
}
+ // TODO: extend TunerFrontendSettings to use 1.1 types
FrontendSettings frontendSettings;
switch (settings.getTag()) {
case TunerFrontendSettings::analog:
@@ -307,8 +301,13 @@
return Status::ok();
}
-Status TunerFrontend::getStatus(const std::vector<int32_t>& /*statusTypes*/,
- std::vector<TunerFrontendStatus>* /*_aidl_return*/) {
+Status TunerFrontend::getStatus(const vector<int32_t>& /*statusTypes*/,
+ vector<TunerFrontendStatus>* /*_aidl_return*/) {
+ return Status::ok();
+}
+
+Status TunerFrontend::getFrontendId(int* _aidl_return) {
+ *_aidl_return = mId;
return Status::ok();
}
@@ -323,59 +322,56 @@
Return<void> TunerFrontend::FrontendCallback::onScanMessage(
FrontendScanMessageType type, const FrontendScanMessage& message) {
ALOGD("FrontendCallback::onScanMessage, type=%d", type);
+ TunerFrontendScanMessage scanMessage;
switch(type) {
case FrontendScanMessageType::LOCKED: {
- if (message.isLocked()) {
- mTunerFrontendCallback->onLocked();
- }
+ scanMessage.set<TunerFrontendScanMessage::isLocked>(message.isLocked());
break;
}
case FrontendScanMessageType::END: {
- if (message.isEnd()) {
- mTunerFrontendCallback->onScanStopped();
- }
+ scanMessage.set<TunerFrontendScanMessage::isEnd>(message.isEnd());
break;
}
case FrontendScanMessageType::PROGRESS_PERCENT: {
- mTunerFrontendCallback->onProgress((int)message.progressPercent());
+ scanMessage.set<TunerFrontendScanMessage::progressPercent>(message.progressPercent());
break;
}
case FrontendScanMessageType::FREQUENCY: {
auto f = message.frequencies();
- std::vector<int32_t> frequencies(std::begin(f), std::end(f));
- mTunerFrontendCallback->onFrequenciesReport(frequencies);
+ vector<int> frequencies(begin(f), end(f));
+ scanMessage.set<TunerFrontendScanMessage::frequencies>(frequencies);
break;
}
case FrontendScanMessageType::SYMBOL_RATE: {
auto s = message.symbolRates();
- std::vector<int32_t> symbolRates(std::begin(s), std::end(s));
- mTunerFrontendCallback->onSymbolRates(symbolRates);
+ vector<int> symbolRates(begin(s), end(s));
+ scanMessage.set<TunerFrontendScanMessage::symbolRates>(symbolRates);
break;
}
case FrontendScanMessageType::HIERARCHY: {
- mTunerFrontendCallback->onHierarchy((int)message.hierarchy());
+ scanMessage.set<TunerFrontendScanMessage::hierarchy>((int)message.hierarchy());
break;
}
case FrontendScanMessageType::ANALOG_TYPE: {
- mTunerFrontendCallback->onSignalType((int)message.analogType());
+ scanMessage.set<TunerFrontendScanMessage::analogType>((int)message.analogType());
break;
}
case FrontendScanMessageType::PLP_IDS: {
auto p = message.plpIds();
- std::vector<int32_t> plpIds(std::begin(p), std::end(p));
- mTunerFrontendCallback->onPlpIds(plpIds);
+ vector<uint8_t> plpIds(begin(p), end(p));
+ scanMessage.set<TunerFrontendScanMessage::plpIds>(plpIds);
break;
}
case FrontendScanMessageType::GROUP_IDS: {
auto g = message.groupIds();
- std::vector<int32_t> groupIds(std::begin(g), std::end(g));
- mTunerFrontendCallback->onGroupIds(groupIds);
+ vector<uint8_t> groupIds(begin(g), end(g));
+ scanMessage.set<TunerFrontendScanMessage::groupIds>(groupIds);
break;
}
case FrontendScanMessageType::INPUT_STREAM_IDS: {
auto i = message.inputStreamIds();
- std::vector<int32_t> streamIds(std::begin(i), std::end(i));
- mTunerFrontendCallback->onInputStreamIds(streamIds);
+ vector<char16_t> streamIds(begin(i), end(i));
+ scanMessage.set<TunerFrontendScanMessage::inputStreamIds>(streamIds);
break;
}
case FrontendScanMessageType::STANDARD: {
@@ -383,41 +379,85 @@
int standard;
if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::sStd) {
standard = (int) std.sStd();
- mTunerFrontendCallback->onDvbsStandard(standard);
} else if (std.getDiscriminator() ==
FrontendScanMessage::Standard::hidl_discriminator::tStd) {
standard = (int) std.tStd();
- mTunerFrontendCallback->onDvbsStandard(standard);
} else if (std.getDiscriminator() ==
FrontendScanMessage::Standard::hidl_discriminator::sifStd) {
standard = (int) std.sifStd();
- mTunerFrontendCallback->onAnalogSifStandard(standard);
}
+ scanMessage.set<TunerFrontendScanMessage::std>(standard);
break;
}
case FrontendScanMessageType::ATSC3_PLP_INFO: {
- std::vector<FrontendScanAtsc3PlpInfo> plpInfos = message.atsc3PlpInfos();
- std::vector<TunerAtsc3PlpInfo> tunerPlpInfos;
+ vector<FrontendScanAtsc3PlpInfo> plpInfos = message.atsc3PlpInfos();
+ vector<TunerFrontendScanAtsc3PlpInfo> tunerPlpInfos;
for (int i = 0; i < plpInfos.size(); i++) {
auto info = plpInfos[i];
int plpId = (int) info.plpId;
bool lls = (bool) info.bLlsFlag;
- TunerAtsc3PlpInfo plpInfo{
+ TunerFrontendScanAtsc3PlpInfo plpInfo{
.plpId = plpId,
.llsFlag = lls,
};
tunerPlpInfos.push_back(plpInfo);
}
- mTunerFrontendCallback->onAtsc3PlpInfos(tunerPlpInfos);
+ scanMessage.set<TunerFrontendScanMessage::atsc3PlpInfos>(tunerPlpInfos);
break;
}
default:
break;
}
+ mTunerFrontendCallback->onScanMessage((int)type, scanMessage);
return Void();
}
-////////////////////////////////////////////////////////////////////////////////
+Return<void> TunerFrontend::FrontendCallback::onScanMessageExt1_1(
+ FrontendScanMessageTypeExt1_1 type, const FrontendScanMessageExt1_1& message) {
+ ALOGD("onScanMessageExt1_1::onScanMessage, type=%d", type);
+ TunerFrontendScanMessage scanMessage;
+ switch(type) {
+ case FrontendScanMessageTypeExt1_1::MODULATION: {
+ FrontendModulation m = message.modulation();
+ int modulation;
+ if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::dvbc) {
+ modulation = (int) m.dvbc();
+ } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::dvbt) {
+ modulation = (int) m.dvbt();
+ } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::dvbs) {
+ modulation = (int) m.dvbs();
+ } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::isdbs) {
+ modulation = (int) m.isdbs();
+ } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::isdbs3) {
+ modulation = (int) m.isdbs3();
+ } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::isdbt) {
+ modulation = (int) m.isdbt();
+ } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::atsc) {
+ modulation = (int) m.atsc();
+ } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::atsc3) {
+ modulation = (int) m.atsc3();
+ } else if (m.getDiscriminator() == FrontendModulation::hidl_discriminator::dtmb) {
+ modulation = (int) m.dtmb();
+ }
+ scanMessage.set<TunerFrontendScanMessage::modulation>(modulation);
+ break;
+ }
+ case FrontendScanMessageTypeExt1_1::DVBC_ANNEX: {
+ scanMessage.set<TunerFrontendScanMessage::annex>((int)message.annex());
+ break;
+ }
+ case FrontendScanMessageTypeExt1_1::HIGH_PRIORITY: {
+ scanMessage.set<TunerFrontendScanMessage::isHighPriority>(message.isHighPriority());
+ break;
+ }
+ default:
+ break;
+ }
+ mTunerFrontendCallback->onScanMessage((int)type, scanMessage);
+ return Void();
+}
+
+/////////////// TunerFrontend Helper Methods ///////////////////////
hidl_vec<FrontendAtsc3PlpSettings> TunerFrontend::getAtsc3PlpSettings(
const TunerFrontendAtsc3Settings& settings) {
diff --git a/services/tuner/TunerFrontend.h b/services/tuner/TunerFrontend.h
index c7d3ddd..99cdcdf 100644
--- a/services/tuner/TunerFrontend.h
+++ b/services/tuner/TunerFrontend.h
@@ -19,6 +19,8 @@
#include <aidl/android/media/tv/tuner/BnTunerFrontend.h>
#include <android/hardware/tv/tuner/1.0/ITuner.h>
+#include <android/hardware/tv/tuner/1.1/IFrontend.h>
+#include <android/hardware/tv/tuner/1.1/IFrontendCallback.h>
#include <media/stagefright/foundation/ADebug.h>
#include <utils/Log.h>
@@ -27,6 +29,7 @@
using ::aidl::android::media::tv::tuner::ITunerFrontendCallback;
using ::aidl::android::media::tv::tuner::TunerFrontendAtsc3Settings;
using ::aidl::android::media::tv::tuner::TunerFrontendDvbsCodeRate;
+using ::aidl::android::media::tv::tuner::TunerFrontendScanMessage;
using ::aidl::android::media::tv::tuner::TunerFrontendSettings;
using ::aidl::android::media::tv::tuner::TunerFrontendStatus;
using ::android::hardware::Return;
@@ -39,19 +42,21 @@
using ::android::hardware::tv::tuner::V1_0::FrontendScanMessage;
using ::android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
using ::android::hardware::tv::tuner::V1_0::IFrontend;
-using ::android::hardware::tv::tuner::V1_0::IFrontendCallback;
-using ::android::hardware::tv::tuner::V1_0::ITuner;
+using ::android::hardware::tv::tuner::V1_1::IFrontendCallback;
+using ::android::hardware::tv::tuner::V1_1::FrontendScanMessageExt1_1;
+using ::android::hardware::tv::tuner::V1_1::FrontendScanMessageTypeExt1_1;
+using namespace std;
namespace android {
class TunerFrontend : public BnTunerFrontend {
public:
- TunerFrontend(sp<ITuner> tuner, int frontendHandle);
+ TunerFrontend(sp<IFrontend> frontend, int id);
virtual ~TunerFrontend();
Status setCallback(
- const std::shared_ptr<ITunerFrontendCallback>& tunerFrontendCallback) override;
+ const shared_ptr<ITunerFrontendCallback>& tunerFrontendCallback) override;
Status tune(const TunerFrontendSettings& settings) override;
Status stopTune() override;
Status scan(const TunerFrontendSettings& settings, int frontendScanType) override;
@@ -59,27 +64,31 @@
Status setLnb(int lnbHandle) override;
Status setLna(bool bEnable) override;
Status close() override;
- Status getStatus(const std::vector<int32_t>& statusTypes,
- std::vector<TunerFrontendStatus>* _aidl_return) override;
+ Status getStatus(const vector<int32_t>& statusTypes,
+ vector<TunerFrontendStatus>* _aidl_return) override;
+ Status getFrontendId(int* _aidl_return) override;
struct FrontendCallback : public IFrontendCallback {
- FrontendCallback(const std::shared_ptr<ITunerFrontendCallback> tunerFrontendCallback)
+ FrontendCallback(const shared_ptr<ITunerFrontendCallback> tunerFrontendCallback)
: mTunerFrontendCallback(tunerFrontendCallback) {};
virtual Return<void> onEvent(FrontendEventType frontendEventType);
virtual Return<void> onScanMessage(
FrontendScanMessageType type, const FrontendScanMessage& message);
+ virtual Return<void> onScanMessageExt1_1(
+ FrontendScanMessageTypeExt1_1 type, const FrontendScanMessageExt1_1& message);
- std::shared_ptr<ITunerFrontendCallback> mTunerFrontendCallback;
+ shared_ptr<ITunerFrontendCallback> mTunerFrontendCallback;
};
private:
hidl_vec<FrontendAtsc3PlpSettings> getAtsc3PlpSettings(
const TunerFrontendAtsc3Settings& settings);
FrontendDvbsCodeRate getDvbsCodeRate(const TunerFrontendDvbsCodeRate& codeRate);
+
int mId;
- sp<ITuner> mTuner;
sp<IFrontend> mFrontend;
+ sp<::android::hardware::tv::tuner::V1_1::IFrontend> mFrontend_1_1;
};
} // namespace android
diff --git a/services/tuner/TunerLnb.cpp b/services/tuner/TunerLnb.cpp
new file mode 100644
index 0000000..0bfa3fd
--- /dev/null
+++ b/services/tuner/TunerLnb.cpp
@@ -0,0 +1,120 @@
+/**
+ * Copyright 2021, 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 "TunerLnb"
+
+#include "TunerLnb.h"
+
+using ::android::hardware::tv::tuner::V1_0::LnbPosition;
+using ::android::hardware::tv::tuner::V1_0::LnbTone;
+using ::android::hardware::tv::tuner::V1_0::LnbVoltage;
+using ::android::hardware::tv::tuner::V1_0::Result;
+
+namespace android {
+
+TunerLnb::TunerLnb(sp<ILnb> lnb, int id) {
+ mLnb = lnb;
+ mId = id;
+}
+
+TunerLnb::~TunerLnb() {
+ mLnb = NULL;
+ mId = -1;
+}
+
+Status TunerLnb::setCallback(
+ const shared_ptr<ITunerLnbCallback>& tunerLnbCallback) {
+ if (mLnb == NULL) {
+ ALOGE("ILnb is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ if (tunerLnbCallback == NULL) {
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_ARGUMENT));
+ }
+
+ sp<ILnbCallback> lnbCallback = new LnbCallback(tunerLnbCallback);
+ Result status = mLnb->setCallback(lnbCallback);
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+}
+
+Status TunerLnb::setVoltage(int voltage) {
+ if (mLnb == NULL) {
+ ALOGE("ILnb is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result status = mLnb->setVoltage(static_cast<LnbVoltage>(voltage));
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+}
+
+Status TunerLnb::setTone(int tone) {
+ if (mLnb == NULL) {
+ ALOGE("ILnb is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result status = mLnb->setTone(static_cast<LnbTone>(tone));
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+}
+
+Status TunerLnb::setSatellitePosition(int position) {
+ if (mLnb == NULL) {
+ ALOGE("ILnb is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result status = mLnb->setSatellitePosition(static_cast<LnbPosition>(position));
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+}
+
+Status TunerLnb::sendDiseqcMessage(const vector<uint8_t>& diseqcMessage) {
+ if (mLnb == NULL) {
+ ALOGE("ILnb is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result status = mLnb->sendDiseqcMessage(diseqcMessage);
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+}
+
+Status TunerLnb::close() {
+ if (mLnb == NULL) {
+ ALOGE("ILnb is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result status = mLnb->close();
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+}
+
+/////////////// ILnbCallback ///////////////////////
+
+Return<void> TunerLnb::LnbCallback::onEvent(const LnbEventType lnbEventType) {
+ if (mTunerLnbCallback != NULL) {
+ mTunerLnbCallback->onEvent((int)lnbEventType);
+ }
+ return Void();
+}
+
+Return<void> TunerLnb::LnbCallback::onDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage) {
+ if (mTunerLnbCallback != NULL && diseqcMessage != NULL) {
+ vector<uint8_t> msg(begin(diseqcMessage), end(diseqcMessage));
+ mTunerLnbCallback->onDiseqcMessage(msg);
+ }
+ return Void();
+}
+} // namespace android
diff --git a/services/tuner/TunerLnb.h b/services/tuner/TunerLnb.h
new file mode 100644
index 0000000..e80b97e
--- /dev/null
+++ b/services/tuner/TunerLnb.h
@@ -0,0 +1,69 @@
+/**
+ * Copyright 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIA_TUNERFLNB_H
+#define ANDROID_MEDIA_TUNERFLNB_H
+
+#include <aidl/android/media/tv/tuner/BnTunerLnb.h>
+#include <android/hardware/tv/tuner/1.0/ILnb.h>
+#include <android/hardware/tv/tuner/1.0/ILnbCallback.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <utils/Log.h>
+
+using Status = ::ndk::ScopedAStatus;
+using ::aidl::android::media::tv::tuner::BnTunerLnb;
+using ::aidl::android::media::tv::tuner::ITunerLnbCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::tv::tuner::V1_0::ILnb;
+using ::android::hardware::tv::tuner::V1_0::ILnbCallback;
+using ::android::hardware::tv::tuner::V1_0::LnbEventType;
+
+using namespace std;
+
+namespace android {
+
+class TunerLnb : public BnTunerLnb {
+
+public:
+ TunerLnb(sp<ILnb> lnb, int id);
+ virtual ~TunerLnb();
+ Status setCallback(const shared_ptr<ITunerLnbCallback>& tunerLnbCallback) override;
+ Status setVoltage(int voltage) override;
+ Status setTone(int tone) override;
+ Status setSatellitePosition(int position) override;
+ Status sendDiseqcMessage(const vector<uint8_t>& diseqcMessage) override;
+ Status close() override;
+
+ struct LnbCallback : public ILnbCallback {
+ LnbCallback(const shared_ptr<ITunerLnbCallback> tunerLnbCallback)
+ : mTunerLnbCallback(tunerLnbCallback) {};
+
+ virtual Return<void> onEvent(const LnbEventType lnbEventType);
+ virtual Return<void> onDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage);
+
+ shared_ptr<ITunerLnbCallback> mTunerLnbCallback;
+ };
+
+private:
+ int mId;
+ sp<ILnb> mLnb;
+};
+
+} // namespace android
+
+#endif // ANDROID_MEDIA_TUNERFLNB_H
diff --git a/services/tuner/TunerService.cpp b/services/tuner/TunerService.cpp
index 56cb34c..ef3d1f2 100644
--- a/services/tuner/TunerService.cpp
+++ b/services/tuner/TunerService.cpp
@@ -18,8 +18,9 @@
#include <android/binder_manager.h>
#include <utils/Log.h>
-#include "TunerFrontend.h"
#include "TunerService.h"
+#include "TunerFrontend.h"
+#include "TunerLnb.h"
using ::aidl::android::media::tv::tuner::TunerFrontendAnalogCapabilities;
using ::aidl::android::media::tv::tuner::TunerFrontendAtsc3Capabilities;
@@ -39,6 +40,9 @@
using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
using ::android::hardware::tv::tuner::V1_0::FrontendId;
using ::android::hardware::tv::tuner::V1_0::FrontendType;
+using ::android::hardware::tv::tuner::V1_0::IFrontend;
+using ::android::hardware::tv::tuner::V1_0::ILnb;
+using ::android::hardware::tv::tuner::V1_0::LnbId;
using ::android::hardware::tv::tuner::V1_0::Result;
namespace android {
@@ -47,7 +51,7 @@
TunerService::~TunerService() {}
void TunerService::instantiate() {
- std::shared_ptr<TunerService> service =
+ shared_ptr<TunerService> service =
::ndk::SharedRefBase::make<TunerService>();
AServiceManager_addService(service->asBinder().get(), getServiceName());
}
@@ -61,8 +65,8 @@
static_assert(sizeof(HidlPayload) == sizeof(AidlPayload), "Payload types are incompatible");
static_assert(
has_typedef_fixed_size<AidlPayload>::value == true ||
- std::is_fundamental<AidlPayload>::value ||
- std::is_enum<AidlPayload>::value,
+ is_fundamental<AidlPayload>::value ||
+ is_enum<AidlPayload>::value,
"Only fundamental types, enums, and AIDL parcelables annotated with @FixedSize "
"and built for the NDK backend are supported as AIDL payload types.");
aidlDesc->fileDescriptor = ndk::ScopedFileDescriptor(dup(hidlDesc.handle()->data[0]));
@@ -192,7 +196,7 @@
if (getQueueDescResult == Result::SUCCESS) {
unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, SynchronizedReadWrite>(
mFilterMQDesc, &mAidlMQDesc);
- mAidlMq = new (std::nothrow) AidlMessageQueue(mAidlMQDesc);
+ mAidlMq = new (nothrow) AidlMessageQueue(mAidlMQDesc);
EventFlag::createEventFlag(mAidlMq->getEventFlagWord(), &mEventFlag);
} else {
ALOGD("get MQDesc failed, res = %d", getQueueDescResult);
@@ -200,9 +204,9 @@
return getQueueDescResult;
}
-Status TunerService::getFrontendIds(std::vector<int32_t>* ids, int32_t* /* _aidl_return */) {
+Status TunerService::getFrontendIds(vector<int32_t>* ids, int32_t* /* _aidl_return */) {
if (!getITuner()) {
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ return Status::fromServiceSpecificError(
static_cast<int32_t>(Result::NOT_INITIALIZED));
}
hidl_vec<FrontendId> feIds;
@@ -212,16 +216,16 @@
res = r;
});
if (res != Result::SUCCESS) {
- return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
+ return Status::fromServiceSpecificError(static_cast<int32_t>(res));
}
ids->resize(feIds.size());
- std::copy(feIds.begin(), feIds.end(), ids->begin());
+ copy(feIds.begin(), feIds.end(), ids->begin());
return Status::ok();
}
Status TunerService::getFrontendInfo(
- int32_t frontendHandle, TunerServiceFrontendInfo* _aidl_return) {
+ int32_t frontendHandle, TunerFrontendInfo* _aidl_return) {
if (mTuner == nullptr) {
ALOGE("ITuner service is not init.");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -230,7 +234,7 @@
Result res;
FrontendInfo info;
- int feId = getResourceIdFromHandle(frontendHandle);
+ int feId = getResourceIdFromHandle(frontendHandle, FRONTEND);
mTuner->getFrontendInfo(feId, [&](Result r, const FrontendInfo& feInfo) {
info = feInfo;
res = r;
@@ -239,26 +243,96 @@
return Status::fromServiceSpecificError(static_cast<int32_t>(res));
}
- TunerServiceFrontendInfo tunerInfo = convertToAidlFrontendInfo(feId, info);
+ TunerFrontendInfo tunerInfo = convertToAidlFrontendInfo(info);
*_aidl_return = tunerInfo;
return Status::ok();
}
Status TunerService::openFrontend(
- int32_t frontendHandle, std::shared_ptr<ITunerFrontend>* _aidl_return) {
+ int32_t frontendHandle, shared_ptr<ITunerFrontend>* _aidl_return) {
if (mTuner == nullptr) {
ALOGE("ITuner service is not init.");
- return ::ndk::ScopedAStatus::fromServiceSpecificError(
- static_cast<int32_t>(Result::UNAVAILABLE));
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
}
- *_aidl_return = ::ndk::SharedRefBase::make<TunerFrontend>(mTuner, frontendHandle);
+ Result status;
+ sp<IFrontend> frontend;
+ int id = getResourceIdFromHandle(frontendHandle, FRONTEND);
+ mTuner->openFrontendById(id, [&](Result result, const sp<IFrontend>& fe) {
+ frontend = fe;
+ status = result;
+ });
+ if (status != Result::SUCCESS) {
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+ }
+ *_aidl_return = ::ndk::SharedRefBase::make<TunerFrontend>(frontend, id);
return Status::ok();
}
-TunerServiceFrontendInfo TunerService::convertToAidlFrontendInfo(int feId, FrontendInfo halInfo) {
- TunerServiceFrontendInfo info{
- .id = feId,
+Status TunerService::getFmqSyncReadWrite(
+ MQDescriptor<int8_t, SynchronizedReadWrite>* mqDesc, bool* _aidl_return) {
+ ALOGD("getFmqSyncReadWrite");
+ // TODO: put the following methods AIDL, and should be called from clients.
+ openDemux();
+ openFilter();
+ configFilter();
+ mFilter->start();
+ if (mqDesc == nullptr) {
+ ALOGD("getFmqSyncReadWrite null MQDescriptor.");
+ *_aidl_return = false;
+ } else {
+ ALOGD("getFmqSyncReadWrite true");
+ *_aidl_return = true;
+ *mqDesc = move(mAidlMQDesc);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+Status TunerService::openLnb(int lnbHandle, shared_ptr<ITunerLnb>* _aidl_return) {
+ if (mTuner == nullptr) {
+ ALOGE("ITuner service is not init.");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result status;
+ sp<ILnb> lnb;
+ int id = getResourceIdFromHandle(lnbHandle, LNB);
+ mTuner->openLnbById(id, [&](Result result, const sp<ILnb>& lnbSp){
+ lnb = lnbSp;
+ status = result;
+ });
+ if (status != Result::SUCCESS) {
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+ }
+
+ *_aidl_return = ::ndk::SharedRefBase::make<TunerLnb>(lnb, id);
+ return Status::ok();
+}
+
+Status TunerService::openLnbByName(const string& lnbName, shared_ptr<ITunerLnb>* _aidl_return) {
+ if (mTuner == nullptr) {
+ ALOGE("ITuner service is not init.");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ int lnbId;
+ Result status;
+ sp<ILnb> lnb;
+ mTuner->openLnbByName(lnbName, [&](Result r, LnbId id, const sp<ILnb>& lnbSp) {
+ status = r;
+ lnb = lnbSp;
+ lnbId = (int)id;
+ });
+ if (status != Result::SUCCESS) {
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+ }
+
+ *_aidl_return = ::ndk::SharedRefBase::make<TunerLnb>(lnb, lnbId);
+ return Status::ok();
+}
+
+TunerFrontendInfo TunerService::convertToAidlFrontendInfo(FrontendInfo halInfo) {
+ TunerFrontendInfo info{
.type = (int)halInfo.type,
.minFrequency = (int)halInfo.minFrequency,
.maxFrequency = (int)halInfo.maxFrequency,
@@ -367,24 +441,4 @@
info.caps = caps;
return info;
}
-
-Status TunerService::getFmqSyncReadWrite(
- MQDescriptor<int8_t, SynchronizedReadWrite>* mqDesc, bool* _aidl_return) {
- ALOGD("getFmqSyncReadWrite");
- // TODO: put the following methods AIDL, and should be called from clients.
- openDemux();
- openFilter();
- configFilter();
- mFilter->start();
- if (mqDesc == nullptr) {
- ALOGD("getFmqSyncReadWrite null MQDescriptor.");
- *_aidl_return = false;
- } else {
- ALOGD("getFmqSyncReadWrite true");
- *_aidl_return = true;
- *mqDesc = std::move(mAidlMQDesc);
- }
- return ndk::ScopedAStatus::ok();
-}
-
} // namespace android
diff --git a/services/tuner/TunerService.h b/services/tuner/TunerService.h
index 26591ab..82b6fcd 100644
--- a/services/tuner/TunerService.h
+++ b/services/tuner/TunerService.h
@@ -18,7 +18,6 @@
#define ANDROID_MEDIA_TUNERSERVICE_H
#include <aidl/android/media/tv/tuner/BnTunerService.h>
-#include <aidl/android/media/tv/tuner/TunerServiceFrontendInfo.h>
#include <android/hardware/tv/tuner/1.0/ITuner.h>
#include <fmq/AidlMessageQueue.h>
#include <fmq/EventFlag.h>
@@ -29,7 +28,8 @@
using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
using ::aidl::android::media::tv::tuner::BnTunerService;
using ::aidl::android::media::tv::tuner::ITunerFrontend;
-using ::aidl::android::media::tv::tuner::TunerServiceFrontendInfo;
+using ::aidl::android::media::tv::tuner::ITunerLnb;
+using ::aidl::android::media::tv::tuner::TunerFrontendInfo;
using ::android::hardware::details::logError;
using ::android::hardware::EventFlag;
@@ -56,8 +56,16 @@
using Status = ::ndk::ScopedAStatus;
+using namespace std;
+
namespace android {
+typedef enum {
+ FRONTEND,
+ LNB,
+ DEMUX,
+ DESCRAMBLER,
+} TunerResourceType;
struct FilterCallback : public IFilterCallback {
~FilterCallback() {}
@@ -80,16 +88,19 @@
TunerService();
virtual ~TunerService();
- static int getResourceIdFromHandle(int resourceHandle) {
+ // TODO: create a map between resource id and handles.
+ static int getResourceIdFromHandle(int resourceHandle, int /*type*/) {
return (resourceHandle & 0x00ff0000) >> 16;
}
- Status getFrontendIds(std::vector<int32_t>* ids, int32_t* _aidl_return) override;
- Status getFrontendInfo(int32_t frontendHandle, TunerServiceFrontendInfo* _aidl_return) override;
+ Status getFrontendIds(vector<int32_t>* ids, int32_t* _aidl_return) override;
+ Status getFrontendInfo(int32_t frontendHandle, TunerFrontendInfo* _aidl_return) override;
Status openFrontend(
- int32_t frontendHandle, std::shared_ptr<ITunerFrontend>* _aidl_return) override;
+ int32_t frontendHandle, shared_ptr<ITunerFrontend>* _aidl_return) override;
Status getFmqSyncReadWrite(
MQDescriptor<int8_t, SynchronizedReadWrite>* mqDesc, bool* _aidl_return) override;
+ Status openLnb(int lnbHandle, shared_ptr<ITunerLnb>* _aidl_return) override;
+ Status openLnbByName(const string& lnbName, shared_ptr<ITunerLnb>* _aidl_return) override;
private:
template <typename HidlPayload, typename AidlPayload, typename AidlFlavor>
@@ -109,7 +120,7 @@
MQDescriptorSync<uint8_t> mFilterMQDesc;
AidlMQDesc mAidlMQDesc;
EventFlag* mEventFlag;
- TunerServiceFrontendInfo convertToAidlFrontendInfo(int feId, FrontendInfo halInfo);
+ TunerFrontendInfo convertToAidlFrontendInfo(FrontendInfo halInfo);
};
} // namespace android
diff --git a/services/tuner/TunerTimeFilter.cpp b/services/tuner/TunerTimeFilter.cpp
new file mode 100644
index 0000000..dce76d2
--- /dev/null
+++ b/services/tuner/TunerTimeFilter.cpp
@@ -0,0 +1,50 @@
+/**
+ * Copyright 2021, 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 "TunerTimeFilter"
+
+#include "TunerTimeFilter.h"
+
+namespace android {
+
+TunerTimeFilter::TunerTimeFilter(sp<ITimeFilter> timeFilter) {
+ mTimeFilter = timeFilter;
+}
+
+TunerTimeFilter::~TunerTimeFilter() {
+ mTimeFilter = NULL;
+}
+
+Status TunerTimeFilter::setTimeStamp(int64_t /*timeStamp*/) {
+ return Status::ok();
+}
+
+Status TunerTimeFilter::clearTimeStamp() {
+ return Status::ok();
+}
+
+Status TunerTimeFilter::getSourceTime(int64_t* /*_aidl_return*/) {
+ return Status::ok();
+}
+
+Status TunerTimeFilter::getTimeStamp(int64_t* /*_aidl_return*/) {
+ return Status::ok();
+}
+
+Status TunerTimeFilter::close() {
+ return Status::ok();
+}
+} // namespace android
diff --git a/services/tuner/TunerTimeFilter.h b/services/tuner/TunerTimeFilter.h
new file mode 100644
index 0000000..50b8f54
--- /dev/null
+++ b/services/tuner/TunerTimeFilter.h
@@ -0,0 +1,53 @@
+/**
+ * Copyright 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIA_TUNERFTIMEFILTER_H
+#define ANDROID_MEDIA_TUNERFTIMEFILTER_H
+
+#include <aidl/android/media/tv/tuner/BnTunerTimeFilter.h>
+#include <android/hardware/tv/tuner/1.0/ITimeFilter.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <utils/Log.h>
+
+using Status = ::ndk::ScopedAStatus;
+using ::aidl::android::media::tv::tuner::BnTunerTimeFilter;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::tv::tuner::V1_0::ITimeFilter;
+
+using namespace std;
+
+namespace android {
+
+class TunerTimeFilter : public BnTunerTimeFilter {
+
+public:
+ TunerTimeFilter(sp<ITimeFilter> timeFilter);
+ virtual ~TunerTimeFilter();
+ Status setTimeStamp(int64_t timeStamp) override;
+ Status clearTimeStamp() override;
+ Status getSourceTime(int64_t* _aidl_return) override;
+ Status getTimeStamp(int64_t* _aidl_return) override;
+ Status close() override;
+
+private:
+ sp<ITimeFilter> mTimeFilter;
+};
+
+} // namespace android
+
+#endif // ANDROID_MEDIA_TUNERFTIMEFILTER_H
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl
index 08d20a9..bfc3e30 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl
@@ -19,10 +19,9 @@
import android.media.tv.tuner.ITunerFrontendCallback;
import android.media.tv.tuner.TunerFrontendSettings;
import android.media.tv.tuner.TunerFrontendStatus;
-import android.media.tv.tuner.TunerServiceFrontendInfo;
/**
- * Tuner Frontend interface handles tuner related operations.
+ * Tuner Frontend interface handles frontend related operations.
*
* {@hide}
*/
@@ -82,4 +81,9 @@
* Gets the statuses of the frontend.
*/
TunerFrontendStatus[] getStatus(in int[] statusTypes);
+
+ /**
+ * Gets the id of the frontend.
+ */
+ int getFrontendId();
}
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFrontendCallback.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontendCallback.aidl
index ae62c15..c92f5ee 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerFrontendCallback.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontendCallback.aidl
@@ -16,7 +16,7 @@
package android.media.tv.tuner;
-import android.media.tv.tuner.TunerAtsc3PlpInfo;
+import android.media.tv.tuner.TunerFrontendScanMessage;
/**
* TunerFrontendCallback interface handles tuner frontend related callbacks.
@@ -24,73 +24,13 @@
* {@hide}
*/
interface ITunerFrontendCallback {
- /**
+ /**
* Notify the client that a new event happened on the frontend.
*/
void onEvent(in int frontendEventType);
/**
- * notify locked message to client from the ongoing scan.
+ * notify the client of scan messages.
*/
- void onLocked();
-
- /**
- * notify scan stopped message to client from the ongoing scan.
- */
- void onScanStopped();
-
- /**
- * notify progress message to client from the ongoing scan.
- */
- void onProgress(in int percent);
-
- /**
- * notify Frequencies message to client from the ongoing scan.
- */
- void onFrequenciesReport(in int[] frequency);
-
- /**
- * notify SymbolRates message to client from the ongoing scan.
- */
- void onSymbolRates(in int[] rates);
-
- /**
- * notify Hierarchy message to client from the ongoing scan.
- */
- void onHierarchy(in int hierarchy);
-
- /**
- * notify SignalType message to client from the ongoing scan.
- */
- void onSignalType(in int signalType);
-
- /**
- * notify PlpIds message to client from the ongoing scan.
- */
- void onPlpIds(in int[] plpIds);
-
- /**
- * notify GroupIds message to client from the ongoing scan.
- */
- void onGroupIds(in int[] groupIds);
-
- /**
- * notify InputStreamIds message to client from the ongoing scan.
- */
- void onInputStreamIds(in int[] inputStreamIds);
-
- /**
- * notify DvbsStandard message to client from the ongoing scan.
- */
- void onDvbsStandard(in int dvbsStandandard);
-
- /**
- * notify AnalogSifStandard message to client from the ongoing scan.
- */
- void onAnalogSifStandard(in int sifStandandard);
-
- /**
- * notify Atsc3PlpInfos message to client from the ongoing scan.
- */
- void onAtsc3PlpInfos(in TunerAtsc3PlpInfo[] atsc3PlpInfos);
+ void onScanMessage(in int messageType, in TunerFrontendScanMessage message);
}
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerLnb.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerLnb.aidl
new file mode 100644
index 0000000..d62145e
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerLnb.aidl
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2021, 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.
+ */
+
+package android.media.tv.tuner;
+
+import android.media.tv.tuner.ITunerLnbCallback;
+
+/**
+ * Tuner Lnb interface handles Lnb related operations.
+ *
+ * {@hide}
+ */
+interface ITunerLnb {
+ /**
+ * Set the lnb callback.
+ */
+ void setCallback(in ITunerLnbCallback tunerLnbCallback);
+
+ /**
+ * Set the lnb's power voltage.
+ */
+ void setVoltage(in int voltage);
+
+ /**
+ * Set the lnb's tone mode.
+ */
+ void setTone(in int tone);
+
+ /**
+ * Select the lnb's position.
+ */
+ void setSatellitePosition(in int position);
+
+ /**
+ * Sends DiSEqC (Digital Satellite Equipment Control) message.
+ */
+ void sendDiseqcMessage(in byte[] diseqcMessage);
+
+ /**
+ * Releases the LNB instance.
+ */
+ void close();
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerLnbCallback.aidl
similarity index 62%
copy from services/tuner/aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl
copy to services/tuner/aidl/android/media/tv/tuner/ITunerLnbCallback.aidl
index a0648a5..117352f 100644
--- a/services/tuner/aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerLnbCallback.aidl
@@ -1,5 +1,5 @@
/**
- * Copyright 2020, The Android Open Source Project
+ * Copyright 2021, 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.
@@ -17,12 +17,18 @@
package android.media.tv.tuner;
/**
- * Atsc3 Frontend Physical Layer Pipe Info.
+ * TuneLnbCallback interface handles tuner lnb related callbacks.
*
* {@hide}
*/
-parcelable TunerAtsc3PlpInfo {
- int plpId;
+interface ITunerLnbCallback {
+ /**
+ * Notify the client that a new event happened on the Lnb.
+ */
+ void onEvent(in int lnbEventType);
- boolean llsFlag;
+ /**
+ * notify the client of new DiSEqC message.
+ */
+ void onDiseqcMessage(in byte[] diseqcMessage);
}
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
index 5c1bce7..5b60685 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
@@ -20,7 +20,8 @@
import android.hardware.common.fmq.SynchronizedReadWrite;
import android.hardware.common.fmq.UnsynchronizedWrite;
import android.media.tv.tuner.ITunerFrontend;
-import android.media.tv.tuner.TunerServiceFrontendInfo;
+import android.media.tv.tuner.ITunerLnb;
+import android.media.tv.tuner.TunerFrontendInfo;
/**
* TunerService interface handles tuner related operations.
@@ -43,7 +44,7 @@
* @param frontendHandle the handle of the frontend granted by TRM.
* @return the information of the frontend.
*/
- TunerServiceFrontendInfo getFrontendInfo(in int frontendHandle);
+ TunerFrontendInfo getFrontendInfo(in int frontendHandle);
/**
* Open a Tuner Frontend interface.
@@ -59,4 +60,21 @@
* @return true if succeeds, false otherwise.
*/
boolean getFmqSyncReadWrite(out MQDescriptor<byte, SynchronizedReadWrite> mqDesc);
+
+ /**
+ * Open a new interface of ITunerLnb given a lnbHandle.
+ *
+ * @param lnbHandle the handle of the LNB granted by TRM.
+ * @return a newly created ITunerLnb interface.
+ */
+ ITunerLnb openLnb(in int lnbHandle);
+
+ /**
+ * Open a new interface of ITunerLnb given a LNB name.
+ *
+ * @param lnbName the name for an external LNB to be opened.
+ * @return a newly created ITunerLnb interface.
+ */
+ ITunerLnb openLnbByName(in String lnbName);
+
}
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerTimeFilter.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerTimeFilter.aidl
new file mode 100644
index 0000000..f84b9bf
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerTimeFilter.aidl
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2021, 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Tuner Time Filter interface handles time filter related operations.
+ *
+ * {@hide}
+ */
+interface ITunerTimeFilter {
+ /**
+ * Set time stamp for time based filter.
+ */
+ void setTimeStamp(in long timeStamp);
+
+ /**
+ * Clear the time stamp in the time filter.
+ */
+ void clearTimeStamp();
+
+ /**
+ * Get the time from the beginning of current data source.
+ */
+ long getSourceTime();
+
+ /**
+ * Get the current time in the time filter.
+ */
+ long getTimeStamp();
+
+ /**
+ * Close the Time Filter instance.
+ */
+ void close();
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerServiceFrontendInfo.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendInfo.aidl
similarity index 89%
rename from services/tuner/aidl/android/media/tv/tuner/TunerServiceFrontendInfo.aidl
rename to services/tuner/aidl/android/media/tv/tuner/TunerFrontendInfo.aidl
index ddcbcdc..4bccd56 100644
--- a/services/tuner/aidl/android/media/tv/tuner/TunerServiceFrontendInfo.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendInfo.aidl
@@ -21,13 +21,16 @@
/**
* FrontendInfo interface that carries tuner frontend information.
*
+ * <p>This is used to update the TunerResourceManager and pass Frontend
+ * information from HAL to the client side.
+ *
* {@hide}
*/
-parcelable TunerServiceFrontendInfo {
+parcelable TunerFrontendInfo {
/**
- * Frontend Id
+ * Frontend Handle
*/
- int id;
+ int handle;
/**
* Frontend Type
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendScanAtsc3PlpInfo.aidl
similarity index 94%
rename from services/tuner/aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl
rename to services/tuner/aidl/android/media/tv/tuner/TunerFrontendScanAtsc3PlpInfo.aidl
index a0648a5..ca4a9af 100644
--- a/services/tuner/aidl/android/media/tv/tuner/TunerAtsc3PlpInfo.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendScanAtsc3PlpInfo.aidl
@@ -21,7 +21,7 @@
*
* {@hide}
*/
-parcelable TunerAtsc3PlpInfo {
+parcelable TunerFrontendScanAtsc3PlpInfo {
int plpId;
boolean llsFlag;
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendScanMessage.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendScanMessage.aidl
new file mode 100644
index 0000000..9921ca1
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendScanMessage.aidl
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2021, 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.
+ */
+
+package android.media.tv.tuner;
+
+import android.media.tv.tuner.TunerFrontendScanAtsc3PlpInfo;
+
+/**
+ * Tuner Frontend Scan Message interface.
+ *
+ * {@hide}
+ */
+union TunerFrontendScanMessage {
+ boolean isLocked;
+
+ boolean isEnd;
+
+ byte progressPercent;
+
+ int[] frequencies;
+
+ int[] symbolRates;
+
+ int hierarchy;
+
+ int analogType;
+
+ byte[] plpIds;
+
+ byte[] groupIds;
+
+ char[] inputStreamIds;
+
+ int std;
+
+ TunerFrontendScanAtsc3PlpInfo[] atsc3PlpInfos;
+
+ int modulation;
+
+ int annex;
+
+ boolean isHighPriority;
+}