Merge "audio policy: workaround for call signalling tones with hearing aids" into tm-dev
diff --git a/camera/CameraSessionStats.cpp b/camera/CameraSessionStats.cpp
index 05341bf..8088d06 100644
--- a/camera/CameraSessionStats.cpp
+++ b/camera/CameraSessionStats.cpp
@@ -375,6 +375,12 @@
return err;
}
+ String16 userTag;
+ if ((err = parcel->readString16(&userTag)) != OK) {
+ ALOGE("%s: Failed to read user tag!", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
mCameraId = id;
mFacing = facing;
mNewCameraState = newCameraState;
@@ -389,6 +395,7 @@
mResultErrorCount = resultErrorCount;
mDeviceError = deviceError;
mStreamStats = std::move(streamStats);
+ mUserTag = userTag;
return OK;
}
@@ -471,6 +478,10 @@
return err;
}
+ if ((err = parcel->writeString16(mUserTag)) != OK) {
+ ALOGE("%s: Failed to write user tag!", __FUNCTION__);
+ return err;
+ }
return OK;
}
diff --git a/camera/camera2/CaptureRequest.cpp b/camera/camera2/CaptureRequest.cpp
index ebc09d7..7a8a4ba 100644
--- a/camera/camera2/CaptureRequest.cpp
+++ b/camera/camera2/CaptureRequest.cpp
@@ -146,6 +146,20 @@
mSurfaceIdxList.push_back(surfaceIdx);
}
+ int32_t hasUserTag;
+ if ((err = parcel->readInt32(&hasUserTag)) != OK) {
+ ALOGE("%s: Failed to read user tag availability flag", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ if (hasUserTag) {
+ String16 userTag;
+ if ((err = parcel->readString16(&userTag)) != OK) {
+ ALOGE("%s: Failed to read user tag!", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ mUserTag = String8(userTag).c_str();
+ }
+
return OK;
}
@@ -213,6 +227,14 @@
return err;
}
}
+
+ if (mUserTag.empty()) {
+ parcel->writeInt32(0);
+ } else {
+ parcel->writeInt32(1);
+ parcel->writeString16(String16(mUserTag.c_str()));
+ }
+
return OK;
}
diff --git a/camera/include/camera/CameraSessionStats.h b/camera/include/camera/CameraSessionStats.h
index 15f5622..e1ec6cf 100644
--- a/camera/include/camera/CameraSessionStats.h
+++ b/camera/include/camera/CameraSessionStats.h
@@ -136,6 +136,7 @@
// Whether the device runs into an error state
bool mDeviceError;
std::vector<CameraStreamStats> mStreamStats;
+ String16 mUserTag;
// Constructors
CameraSessionStats();
diff --git a/camera/include/camera/camera2/CaptureRequest.h b/camera/include/camera/camera2/CaptureRequest.h
index 506abab..28dbc7c 100644
--- a/camera/include/camera/camera2/CaptureRequest.h
+++ b/camera/include/camera/camera2/CaptureRequest.h
@@ -63,6 +63,8 @@
void* mContext; // arbitrary user context from NDK apps, null for java apps
+ std::string mUserTag; // The string representation of object passed into setTag.
+
/**
* Keep impl up-to-date with CaptureRequest.java in frameworks/base
*/
diff --git a/media/codec2/components/aom/C2SoftAomDec.cpp b/media/codec2/components/aom/C2SoftAomDec.cpp
index c7985ca..3b0e949 100644
--- a/media/codec2/components/aom/C2SoftAomDec.cpp
+++ b/media/codec2/components/aom/C2SoftAomDec.cpp
@@ -261,8 +261,7 @@
CREATE_DUMP_FILE(mInFile);
CREATE_DUMP_FILE(mOutFile);
- gettimeofday(&mTimeStart, nullptr);
- gettimeofday(&mTimeEnd, nullptr);
+ mTimeStart = mTimeEnd = systemTime();
}
C2SoftAomDec::~C2SoftAomDec() {
@@ -463,19 +462,17 @@
int64_t frameIndex = work->input.ordinal.frameIndex.peekll();
if (inSize) {
uint8_t* bitstream = const_cast<uint8_t*>(rView.data() + inOffset);
- int32_t decodeTime = 0;
- int32_t delay = 0;
DUMP_TO_FILE(mOutFile, bitstream, inSize);
- GETTIME(&mTimeStart, nullptr);
- TIME_DIFF(mTimeEnd, mTimeStart, delay);
+ mTimeStart = systemTime();
+ nsecs_t delay = mTimeStart - mTimeEnd;
aom_codec_err_t err =
aom_codec_decode(mCodecCtx, bitstream, inSize, &frameIndex);
- GETTIME(&mTimeEnd, nullptr);
- TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
- ALOGV("decodeTime=%4d delay=%4d\n", decodeTime, delay);
+ mTimeEnd = systemTime();
+ nsecs_t decodeTime = mTimeEnd - mTimeStart;
+ ALOGV("decodeTime=%4" PRId64 " delay=%4" PRId64 "\n", decodeTime, delay);
if (err != AOM_CODEC_OK) {
ALOGE("av1 decoder failed to decode frame err: %d", err);
diff --git a/media/codec2/components/aom/C2SoftAomDec.h b/media/codec2/components/aom/C2SoftAomDec.h
index 4c82647..8b953fe 100644
--- a/media/codec2/components/aom/C2SoftAomDec.h
+++ b/media/codec2/components/aom/C2SoftAomDec.h
@@ -17,15 +17,12 @@
#ifndef ANDROID_C2_SOFT_AV1_DEC_H_
#define ANDROID_C2_SOFT_AV1_DEC_H_
+#include <inttypes.h>
+
#include <SimpleC2Component.h>
#include "aom/aom_decoder.h"
#include "aom/aomdx.h"
-#define GETTIME(a, b) gettimeofday(a, b);
-#define TIME_DIFF(start, end, diff) \
- diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
- ((end).tv_usec - (start).tv_usec);
-
namespace android {
struct C2SoftAomDec : public SimpleC2Component {
@@ -60,8 +57,8 @@
char mOutFile[200];
#endif /* FILE_DUMP_ENABLE */
- struct timeval mTimeStart; // Time at the start of decode()
- struct timeval mTimeEnd; // Time at the end of decode()
+ nsecs_t mTimeStart = 0; // Time at the start of decode()
+ nsecs_t mTimeEnd = 0; // Time at the end of decode()
status_t initDecoder();
status_t destroyDecoder();
@@ -85,14 +82,13 @@
#define OUTPUT_DUMP_EXT "av1"
#define GENERATE_FILE_NAMES() \
{ \
- GETTIME(&mTimeStart, NULL); \
- strcpy(mInFile, ""); \
+ nsecs_t now = systemTime(); \
ALOGD("GENERATE_FILE_NAMES"); \
- sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH, mTimeStart.tv_sec, \
- mTimeStart.tv_usec, INPUT_DUMP_EXT); \
+ sprintf(mInFile, "%s_%" PRId64 ".%s", INPUT_DUMP_PATH, \
+ now, INPUT_DUMP_EXT); \
strcpy(mOutFile, ""); \
- sprintf(mOutFile, "%s_%ld.%ld.%s", OUTPUT_DUMP_PATH, \
- mTimeStart.tv_sec, mTimeStart.tv_usec, OUTPUT_DUMP_EXT); \
+ sprintf(mOutFile, "%s_%" PRId64 ".%s", OUTPUT_DUMP_PATH, \
+ now, OUTPUT_DUMP_EXT); \
}
#define CREATE_DUMP_FILE(m_filename) \
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index cc4517d..953afc5 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -670,8 +670,7 @@
void C2SoftAvcDec::resetPlugin() {
mSignalledOutputEos = false;
- gettimeofday(&mTimeStart, nullptr);
- gettimeofday(&mTimeEnd, nullptr);
+ mTimeStart = mTimeEnd = systemTime();
}
status_t C2SoftAvcDec::deleteDecoder() {
@@ -866,14 +865,13 @@
setParams(mStride, IVD_DECODE_HEADER);
}
- WORD32 delay;
- GETTIME(&mTimeStart, nullptr);
- TIME_DIFF(mTimeEnd, mTimeStart, delay);
+ mTimeStart = systemTime();
+ nsecs_t delay = mTimeStart - mTimeEnd;
(void) ivdec_api_function(mDecHandle, &s_h264d_decode_ip, &s_h264d_decode_op);
- WORD32 decodeTime;
- GETTIME(&mTimeEnd, nullptr);
- TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
- ALOGV("decodeTime=%6d delay=%6d numBytes=%6d", decodeTime, delay,
+
+ mTimeEnd = systemTime();
+ nsecs_t decodeTime = mTimeEnd - mTimeStart;
+ ALOGV("decodeTime=%" PRId64 " delay=%" PRId64 " numBytes=%6d", decodeTime, delay,
ps_decode_op->u4_num_bytes_consumed);
}
if (IVD_MEM_ALLOC_FAILED == (ps_decode_op->u4_error_code & IVD_ERROR_MASK)) {
diff --git a/media/codec2/components/avc/C2SoftAvcDec.h b/media/codec2/components/avc/C2SoftAvcDec.h
index 59d5184..36a463e 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.h
+++ b/media/codec2/components/avc/C2SoftAvcDec.h
@@ -18,6 +18,7 @@
#define ANDROID_C2_SOFT_AVC_DEC_H_
#include <sys/time.h>
+#include <inttypes.h>
#include <media/stagefright/foundation/ColorUtils.h>
@@ -43,19 +44,15 @@
#define IVDEXT_CMD_CTL_SET_NUM_CORES \
(IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define GETTIME(a, b) gettimeofday(a, b);
-#define TIME_DIFF(start, end, diff) \
- diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
- ((end).tv_usec - (start).tv_usec);
#ifdef FILE_DUMP_ENABLE
#define INPUT_DUMP_PATH "/sdcard/clips/avcd_input"
#define INPUT_DUMP_EXT "h264"
#define GENERATE_FILE_NAMES() { \
- GETTIME(&mTimeStart, NULL); \
+ nsecs_t now = systemTime(); \
strcpy(mInFile, ""); \
- sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH, \
- mTimeStart.tv_sec, mTimeStart.tv_usec, \
+ sprintf(mInFile, "%s_%" PRId64 "d.%s", \
+ INPUT_DUMP_PATH, now, \
INPUT_DUMP_EXT); \
}
#define CREATE_DUMP_FILE(m_filename) { \
@@ -183,8 +180,8 @@
} mBitstreamColorAspects;
// profile
- struct timeval mTimeStart;
- struct timeval mTimeEnd;
+ nsecs_t mTimeStart = 0;
+ nsecs_t mTimeEnd = 0;
#ifdef FILE_DUMP_ENABLE
char mInFile[200];
#endif /* FILE_DUMP_ENABLE */
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index d65ffa5..4ffcd59 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -656,8 +656,7 @@
mEntropyMode = DEFAULT_ENTROPY_MODE;
mBframes = DEFAULT_B_FRAMES;
- gettimeofday(&mTimeStart, nullptr);
- gettimeofday(&mTimeEnd, nullptr);
+ mTimeStart = mTimeEnd = systemTime();
}
c2_status_t C2SoftAvcEnc::setDimensions() {
@@ -1650,8 +1649,7 @@
work->worklets.front()->output.flags = work->input.flags;
IV_STATUS_T status;
- WORD32 timeDelay = 0;
- WORD32 timeTaken = 0;
+ nsecs_t timeDelay = 0;
uint64_t workIndex = work->input.ordinal.frameIndex.peekull();
// Initialize encoder if not already initialized
@@ -1817,10 +1815,10 @@
// mInFile, s_encode_ip.s_inp_buf.apv_bufs[0],
// (mHeight * mStride * 3 / 2));
- GETTIME(&mTimeStart, nullptr);
/* Compute time elapsed between end of previous decode()
* to start of current decode() */
- TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);
+ mTimeStart = systemTime();
+ timeDelay = mTimeStart - mTimeEnd;
status = ive_api_function(mCodecCtx, &s_video_encode_ip, &s_video_encode_op);
if (IV_SUCCESS != status) {
@@ -1844,11 +1842,11 @@
mBuffers[ps_encode_ip->s_inp_buf.apv_bufs[0]] = inputBuffer;
}
- GETTIME(&mTimeEnd, nullptr);
/* Compute time taken for decode() */
- TIME_DIFF(mTimeStart, mTimeEnd, timeTaken);
+ mTimeEnd = systemTime();
+ nsecs_t timeTaken = mTimeEnd - mTimeStart;
- ALOGV("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay,
+ ALOGV("timeTaken=%" PRId64 "d delay=%" PRId64 " numBytes=%6d", timeTaken, timeDelay,
ps_encode_op->s_out_buf.u4_bytes);
void *freed = ps_encode_op->s_inp_buf.apv_bufs[0];
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.h b/media/codec2/components/avc/C2SoftAvcEnc.h
index 1fecd9e..293867d 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.h
+++ b/media/codec2/components/avc/C2SoftAvcEnc.h
@@ -18,6 +18,7 @@
#define ANDROID_C2_SOFT_AVC_ENC_H__
#include <map>
+#include <inttypes.h>
#include <utils/Vector.h>
@@ -115,14 +116,6 @@
/** Used to remove warnings about unused parameters */
#define UNUSED(x) ((void)(x))
-/** Get time */
-#define GETTIME(a, b) gettimeofday(a, b);
-
-/** Compute difference between start and end */
-#define TIME_DIFF(start, end, diff) \
- diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
- ((end).tv_usec - (start).tv_usec);
-
#define ive_aligned_malloc(alignment, size) memalign(alignment, size)
#define ive_aligned_free(buf) free(buf)
@@ -148,6 +141,7 @@
virtual ~C2SoftAvcEnc();
private:
+ // RBE What does OMX have to do with the c2 plugin?
// OMX input buffer's timestamp and flags
typedef struct {
int64_t mTimeUs;
@@ -158,8 +152,8 @@
int32_t mStride;
- struct timeval mTimeStart; // Time at the start of decode()
- struct timeval mTimeEnd; // Time at the end of decode()
+ nsecs_t mTimeStart = 0; // Time at the start of decode()
+ nsecs_t mTimeEnd = 0; // Time at the end of decode()
#ifdef FILE_DUMP_ENABLE
char mInFile[200];
@@ -259,14 +253,14 @@
#define OUTPUT_DUMP_EXT "h264"
#define GENERATE_FILE_NAMES() { \
- GETTIME(&mTimeStart, NULL); \
+ nsecs_t now = systemTime(); \
strcpy(mInFile, ""); \
- sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH, \
- mTimeStart.tv_sec, mTimeStart.tv_usec, \
+ sprintf(mInFile, "%s_%" PRId64 "d.%s", \
+ INPUT_DUMP_PATH, now, \
INPUT_DUMP_EXT); \
strcpy(mOutFile, ""); \
- sprintf(mOutFile, "%s_%ld.%ld.%s", OUTPUT_DUMP_PATH,\
- mTimeStart.tv_sec, mTimeStart.tv_usec, \
+ sprintf(mOutFile, "%s_%" PRId64 "d.%s", \
+ OUTPUT_DUMP_PATH, now, \
OUTPUT_DUMP_EXT); \
}
diff --git a/media/codec2/components/base/SimpleC2Component.cpp b/media/codec2/components/base/SimpleC2Component.cpp
index 5295822..b30eed5 100644
--- a/media/codec2/components/base/SimpleC2Component.cpp
+++ b/media/codec2/components/base/SimpleC2Component.cpp
@@ -32,6 +32,13 @@
constexpr uint8_t kNeutralUVBitDepth8 = 128;
constexpr uint16_t kNeutralUVBitDepth10 = 512;
+bool isAtLeastT() {
+ char deviceCodeName[PROP_VALUE_MAX];
+ __system_property_get("ro.build.version.codename", deviceCodeName);
+ return android_get_device_api_level() >= __ANDROID_API_T__ ||
+ !strcmp(deviceCodeName, "Tiramisu");
+}
+
void convertYUV420Planar8ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint8_t *srcY,
const uint8_t *srcU, const uint8_t *srcV, size_t srcYStride,
size_t srcUStride, size_t srcVStride, size_t dstYStride,
@@ -767,9 +774,9 @@
// Save supported hal pixel formats for bit depth of 10, the first time this is called
if (!mBitDepth10HalPixelFormats.size()) {
std::vector<int> halPixelFormats;
- // TODO(b/178229371) Enable HAL_PIXEL_FORMAT_YCBCR_P010 once framework supports it
- // halPixelFormats.push_back(HAL_PIXEL_FORMAT_YCBCR_P010);
-
+ if (isAtLeastT()) {
+ halPixelFormats.push_back(HAL_PIXEL_FORMAT_YCBCR_P010);
+ }
// since allowRGBA1010102 can chance in each call, but mBitDepth10HalPixelFormats
// is populated only once, allowRGBA1010102 is not considered at this stage.
halPixelFormats.push_back(HAL_PIXEL_FORMAT_RGBA_1010102);
diff --git a/media/codec2/components/base/include/SimpleC2Component.h b/media/codec2/components/base/include/SimpleC2Component.h
index d244f45..52ae3b8 100644
--- a/media/codec2/components/base/include/SimpleC2Component.h
+++ b/media/codec2/components/base/include/SimpleC2Component.h
@@ -27,7 +27,7 @@
#include <media/stagefright/foundation/Mutexed.h>
namespace android {
-
+bool isAtLeastT();
void convertYUV420Planar8ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint8_t *srcY,
const uint8_t *srcU, const uint8_t *srcV, size_t srcYStride,
size_t srcUStride, size_t srcVStride, size_t dstYStride,
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index e5fbe99..f5c8138 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -190,11 +190,18 @@
.withSetter(ColorAspectsSetter, mDefaultColorAspects, mCodedColorAspects)
.build());
+ std::vector<uint32_t> pixelFormats = {HAL_PIXEL_FORMAT_YCBCR_420_888};
+ if (isAtLeastT()) {
+ pixelFormats.push_back(HAL_PIXEL_FORMAT_YCBCR_P010);
+ }
// TODO: support more formats?
- addParameter(DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
- .withConstValue(new C2StreamPixelFormatInfo::output(
- 0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
- .build());
+ addParameter(
+ DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
+ .withDefault(new C2StreamPixelFormatInfo::output(
+ 0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
+ .withFields({C2F(mPixelFormat, value).oneOf(pixelFormats)})
+ .withSetter((Setter<decltype(*mPixelFormat)>::StrictValueWithNoDeps))
+ .build());
}
static C2R SizeSetter(bool mayBlock,
@@ -335,8 +342,7 @@
std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
mIntf(intfImpl),
mCodecCtx(nullptr) {
- gettimeofday(&mTimeStart, nullptr);
- gettimeofday(&mTimeEnd, nullptr);
+ mTimeStart = mTimeEnd = systemTime();
}
C2SoftGav1Dec::~C2SoftGav1Dec() { onRelease(); }
@@ -403,6 +409,7 @@
bool C2SoftGav1Dec::initDecoder() {
mSignalledError = false;
mSignalledOutputEos = false;
+ mHalPixelFormat = HAL_PIXEL_FORMAT_YV12;
mCodecCtx.reset(new libgav1::Decoder());
if (mCodecCtx == nullptr) {
@@ -506,19 +513,17 @@
int64_t frameIndex = work->input.ordinal.frameIndex.peekll();
if (inSize) {
uint8_t *bitstream = const_cast<uint8_t *>(rView.data() + inOffset);
- int32_t decodeTime = 0;
- int32_t delay = 0;
- GETTIME(&mTimeStart, nullptr);
- TIME_DIFF(mTimeEnd, mTimeStart, delay);
+ mTimeStart = systemTime();
+ nsecs_t delay = mTimeStart - mTimeEnd;
const Libgav1StatusCode status =
mCodecCtx->EnqueueFrame(bitstream, inSize, frameIndex,
/*buffer_private_data=*/nullptr);
- GETTIME(&mTimeEnd, nullptr);
- TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
- ALOGV("decodeTime=%4d delay=%4d\n", decodeTime, delay);
+ mTimeEnd = systemTime();
+ nsecs_t decodeTime = mTimeEnd - mTimeStart;
+ ALOGV("decodeTime=%4" PRId64 " delay=%4" PRId64 "\n", decodeTime, delay);
if (status != kLibgav1StatusOk) {
ALOGE("av1 decoder failed to decode frame. status: %d.", status);
@@ -648,6 +653,24 @@
return false;
}
}
+
+ if (mHalPixelFormat != format) {
+ C2StreamPixelFormatInfo::output pixelFormat(0u, format);
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ c2_status_t err = mIntf->config({&pixelFormat }, C2_MAY_BLOCK, &failures);
+ if (err == C2_OK) {
+ work->worklets.front()->output.configUpdate.push_back(
+ C2Param::Copy(pixelFormat));
+ } else {
+ ALOGE("Config update pixelFormat failed");
+ mSignalledError = true;
+ work->workletsProcessed = 1u;
+ work->result = C2_CORRUPTED;
+ return UNKNOWN_ERROR;
+ }
+ mHalPixelFormat = format;
+ }
+
C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
// We always create a graphic block that is width aligned to 16 and height
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.h b/media/codec2/components/gav1/C2SoftGav1Dec.h
index 134fa0d..4b13fef 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.h
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_C2_SOFT_GAV1_DEC_H_
#define ANDROID_C2_SOFT_GAV1_DEC_H_
+#include <inttypes.h>
+
#include <media/stagefright/foundation/ColorUtils.h>
#include <SimpleC2Component.h>
@@ -24,11 +26,6 @@
#include "libgav1/src/gav1/decoder.h"
#include "libgav1/src/gav1/decoder_settings.h"
-#define GETTIME(a, b) gettimeofday(a, b);
-#define TIME_DIFF(start, end, diff) \
- diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
- ((end).tv_usec - (start).tv_usec);
-
namespace android {
struct C2SoftGav1Dec : public SimpleC2Component {
@@ -54,6 +51,7 @@
std::shared_ptr<IntfImpl> mIntf;
std::unique_ptr<libgav1::Decoder> mCodecCtx;
+ uint32_t mHalPixelFormat;
uint32_t mWidth;
uint32_t mHeight;
bool mSignalledOutputEos;
@@ -80,8 +78,8 @@
}
} mBitstreamColorAspects;
- struct timeval mTimeStart; // Time at the start of decode()
- struct timeval mTimeEnd; // Time at the end of decode()
+ nsecs_t mTimeStart = 0; // Time at the start of decode()
+ nsecs_t mTimeEnd = 0; // Time at the end of decode()
bool initDecoder();
void getVuiParams(const libgav1::DecoderBuffer *buffer);
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
index 2a6adca..5a660c5 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -663,8 +663,7 @@
void C2SoftHevcDec::resetPlugin() {
mSignalledOutputEos = false;
- gettimeofday(&mTimeStart, nullptr);
- gettimeofday(&mTimeEnd, nullptr);
+ mTimeStart = mTimeEnd = systemTime();
}
status_t C2SoftHevcDec::deleteDecoder() {
@@ -858,14 +857,13 @@
/* Decode header and get dimensions */
setParams(mStride, IVD_DECODE_HEADER);
}
- WORD32 delay;
- GETTIME(&mTimeStart, nullptr);
- TIME_DIFF(mTimeEnd, mTimeStart, delay);
+
+ mTimeStart = systemTime();
+ nsecs_t delay = mTimeStart - mTimeEnd;
(void) ivdec_api_function(mDecHandle, ps_decode_ip, ps_decode_op);
- WORD32 decodeTime;
- GETTIME(&mTimeEnd, nullptr);
- TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
- ALOGV("decodeTime=%6d delay=%6d numBytes=%6d", decodeTime, delay,
+ mTimeEnd = systemTime();
+ nsecs_t decodeTime = mTimeEnd - mTimeStart;
+ ALOGV("decodeTime=%6" PRId64 " delay=%6" PRId64 " numBytes=%6d", decodeTime, delay,
ps_decode_op->u4_num_bytes_consumed);
if (IVD_MEM_ALLOC_FAILED == (ps_decode_op->u4_error_code & IVD_ERROR_MASK)) {
ALOGE("allocation failure in decoder");
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.h b/media/codec2/components/hevc/C2SoftHevcDec.h
index b9296e9..6abf69e 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.h
+++ b/media/codec2/components/hevc/C2SoftHevcDec.h
@@ -20,6 +20,7 @@
#include <media/stagefright/foundation/ColorUtils.h>
#include <atomic>
+#include <inttypes.h>
#include <SimpleC2Component.h>
#include "ihevc_typedefs.h"
@@ -41,10 +42,6 @@
#define IVDEXT_CMD_CTL_SET_NUM_CORES \
(IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define GETTIME(a, b) gettimeofday(a, b);
-#define TIME_DIFF(start, end, diff) \
- diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
- ((end).tv_usec - (start).tv_usec);
struct C2SoftHevcDec : public SimpleC2Component {
@@ -142,8 +139,8 @@
} mBitstreamColorAspects;
// profile
- struct timeval mTimeStart;
- struct timeval mTimeEnd;
+ nsecs_t mTimeStart = 0;
+ nsecs_t mTimeEnd = 0;
C2_DO_NOT_COPY(C2SoftHevcDec);
};
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index 4f5caec..947e387 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -591,8 +591,7 @@
CREATE_DUMP_FILE(mInFile);
CREATE_DUMP_FILE(mOutFile);
- gettimeofday(&mTimeStart, nullptr);
- gettimeofday(&mTimeEnd, nullptr);
+ mTimeStart = mTimeEnd = systemTime();
}
C2SoftHevcEnc::~C2SoftHevcEnc() {
@@ -1203,11 +1202,11 @@
}
}
- uint64_t timeDelay = 0;
- uint64_t timeTaken = 0;
+ nsecs_t timeDelay = 0;
+ nsecs_t timeTaken = 0;
memset(&s_encode_op, 0, sizeof(s_encode_op));
- GETTIME(&mTimeStart, nullptr);
- TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);
+ mTimeStart = systemTime();
+ timeDelay = mTimeStart - mTimeEnd;
if (inputBuffer) {
err = ihevce_encode(mCodecCtx, &s_encode_ip, &s_encode_op);
@@ -1222,12 +1221,12 @@
fillEmptyWork(work);
}
- GETTIME(&mTimeEnd, nullptr);
/* Compute time taken for decode() */
- TIME_DIFF(mTimeStart, mTimeEnd, timeTaken);
+ mTimeEnd = systemTime();
+ timeTaken = mTimeEnd - mTimeStart;
- ALOGV("timeTaken=%6d delay=%6d numBytes=%6d", (int)timeTaken,
- (int)timeDelay, s_encode_op.i4_bytes_generated);
+ ALOGV("timeTaken=%6" PRId64 " delay=%6" PRId64 " numBytes=%6d", timeTaken,
+ timeDelay, s_encode_op.i4_bytes_generated);
if (s_encode_op.i4_bytes_generated) {
finishWork(s_encode_op.u8_pts, work, pool, &s_encode_op);
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.h b/media/codec2/components/hevc/C2SoftHevcEnc.h
index 4217a8b..ce9cec8 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.h
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.h
@@ -19,6 +19,7 @@
#include <SimpleC2Component.h>
#include <algorithm>
+#include <inttypes.h>
#include <map>
#include <media/stagefright/foundation/ColorUtils.h>
#include <utils/Vector.h>
@@ -27,14 +28,6 @@
namespace android {
-/** Get time */
-#define GETTIME(a, b) gettimeofday(a, b)
-
-/** Compute difference between start and end */
-#define TIME_DIFF(start, end, diff) \
- diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
- ((end).tv_usec - (start).tv_usec);
-
#define CODEC_MAX_CORES 4
#define MAX_B_FRAMES 1
#define MAX_RC_LOOKAHEAD 1
@@ -102,8 +95,8 @@
#endif /* FILE_DUMP_ENABLE */
// profile
- struct timeval mTimeStart;
- struct timeval mTimeEnd;
+ nsecs_t mTimeStart = 0;
+ nsecs_t mTimeEnd = 0;
c2_status_t initEncParams();
c2_status_t initEncoder();
@@ -127,14 +120,12 @@
#define OUTPUT_DUMP_EXT "h265"
#define GENERATE_FILE_NAMES() \
{ \
- GETTIME(&mTimeStart, NULL); \
- strcpy(mInFile, ""); \
+ nsecs_t now = systemTime(); \
ALOGD("GENERATE_FILE_NAMES"); \
- sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH, mTimeStart.tv_sec, \
- mTimeStart.tv_usec, INPUT_DUMP_EXT); \
- strcpy(mOutFile, ""); \
- sprintf(mOutFile, "%s_%ld.%ld.%s", OUTPUT_DUMP_PATH, \
- mTimeStart.tv_sec, mTimeStart.tv_usec, OUTPUT_DUMP_EXT); \
+ sprintf(mInFile, "%s_%" PRId64 ".%s", INPUT_DUMP_PATH, \
+ mTimeStart, INPUT_DUMP_EXT); \
+ sprintf(mutFile, "%s_%" PRId64 ".%s", OUTPUT_DUMP_PATH, \
+ mTimeStart, OUTPUT_DUMP_EXT); \
}
#define CREATE_DUMP_FILE(m_filename) \
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
index 5f9b30b..9a41910 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
@@ -731,8 +731,7 @@
void C2SoftMpeg2Dec::resetPlugin() {
mSignalledOutputEos = false;
- gettimeofday(&mTimeStart, nullptr);
- gettimeofday(&mTimeEnd, nullptr);
+ mTimeStart = mTimeEnd = systemTime();
}
status_t C2SoftMpeg2Dec::deleteDecoder() {
@@ -929,14 +928,12 @@
}
// If input dump is enabled, then write to file
DUMP_TO_FILE(mInFile, s_decode_ip.pv_stream_buffer, s_decode_ip.u4_num_Bytes);
- WORD32 delay;
- GETTIME(&mTimeStart, nullptr);
- TIME_DIFF(mTimeEnd, mTimeStart, delay);
+ nsecs_t delay = mTimeStart - mTimeEnd;
(void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
- WORD32 decodeTime;
- GETTIME(&mTimeEnd, nullptr);
- TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
- ALOGV("decodeTime=%6d delay=%6d numBytes=%6d ", decodeTime, delay,
+
+ mTimeEnd = systemTime();
+ nsecs_t decodeTime = mTimeEnd - mTimeStart;
+ ALOGV("decodeTime=%" PRId64 " delay=%" PRId64 " numBytes=%6d ", decodeTime, delay,
s_decode_op.u4_num_bytes_consumed);
if (IMPEG2D_UNSUPPORTED_DIMENSIONS == s_decode_op.u4_error_code) {
ALOGV("unsupported resolution : %dx%d", s_decode_op.u4_pic_wd, s_decode_op.u4_pic_ht);
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
index 8a29c14..f370f5e 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
@@ -18,6 +18,7 @@
#define ANDROID_C2_SOFT_MPEG2_DEC_H_
#include <atomic>
+#include <inttypes.h>
#include <SimpleC2Component.h>
#include <media/stagefright/foundation/ColorUtils.h>
@@ -42,19 +43,14 @@
#define IVDEXT_CMD_CTL_SET_NUM_CORES \
(IVD_CONTROL_API_COMMAND_TYPE_T)IMPEG2D_CMD_CTL_SET_NUM_CORES
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define GETTIME(a, b) gettimeofday(a, b);
-#define TIME_DIFF(start, end, diff) \
- diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
- ((end).tv_usec - (start).tv_usec);
#ifdef FILE_DUMP_ENABLE
#define INPUT_DUMP_PATH "/sdcard/clips/mpeg2d_input"
#define INPUT_DUMP_EXT "m2v"
#define GENERATE_FILE_NAMES() { \
- GETTIME(&mTimeStart, NULL); \
- strcpy(mInFile, ""); \
- sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH, \
- mTimeStart.tv_sec, mTimeStart.tv_usec, \
+ nsecs_t now = systemTime(); \
+ sprintf(mInFile, "%s_%" PRId64 ".%s",
+ INPUT_DUMP_PATH, now, \
INPUT_DUMP_EXT); \
}
#define CREATE_DUMP_FILE(m_filename) { \
@@ -183,8 +179,8 @@
} mBitstreamColorAspects;
// profile
- struct timeval mTimeStart;
- struct timeval mTimeEnd;
+ nsecs_t mTimeStart = 0;
+ nsecs_t mTimeEnd = 0;
#ifdef FILE_DUMP_ENABLE
char mInFile[200];
#endif /* FILE_DUMP_ENABLE */
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.cpp b/media/codec2/components/vpx/C2SoftVpxDec.cpp
index 5fc89be..e81f044 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxDec.cpp
@@ -19,7 +19,6 @@
#include <log/log.h>
#include <algorithm>
-
#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/foundation/MediaDefs.h>
@@ -218,11 +217,20 @@
.build());
// TODO: support more formats?
+ std::vector<uint32_t> pixelFormats = {HAL_PIXEL_FORMAT_YCBCR_420_888};
+#ifdef VP9
+ if (isAtLeastT()) {
+ pixelFormats.push_back(HAL_PIXEL_FORMAT_YCBCR_P010);
+ }
+#endif
addParameter(
DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
- .withConstValue(new C2StreamPixelFormatInfo::output(
- 0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
+ .withDefault(new C2StreamPixelFormatInfo::output(
+ 0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
+ .withFields({C2F(mPixelFormat, value).oneOf(pixelFormats)})
+ .withSetter((Setter<decltype(*mPixelFormat)>::StrictValueWithNoDeps))
.build());
+
}
static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::output> &oldMe,
@@ -424,7 +432,7 @@
#else
mMode = MODE_VP8;
#endif
-
+ mHalPixelFormat = HAL_PIXEL_FORMAT_YV12;
mWidth = 320;
mHeight = 240;
mFrameParallelMode = false;
@@ -690,6 +698,24 @@
}
format = getHalPixelFormatForBitDepth10(allowRGBA1010102);
}
+
+ if (mHalPixelFormat != format) {
+ C2StreamPixelFormatInfo::output pixelFormat(0u, format);
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ c2_status_t err = mIntf->config({&pixelFormat }, C2_MAY_BLOCK, &failures);
+ if (err == C2_OK) {
+ work->worklets.front()->output.configUpdate.push_back(
+ C2Param::Copy(pixelFormat));
+ } else {
+ ALOGE("Config update pixelFormat failed");
+ mSignalledError = true;
+ work->workletsProcessed = 1u;
+ work->result = C2_CORRUPTED;
+ return UNKNOWN_ERROR;
+ }
+ mHalPixelFormat = format;
+ }
+
C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16), mHeight, format, usage, &block);
if (err != C2_OK) {
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.h b/media/codec2/components/vpx/C2SoftVpxDec.h
index 2065165..5564766 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.h
+++ b/media/codec2/components/vpx/C2SoftVpxDec.h
@@ -67,6 +67,7 @@
vpx_codec_ctx_t *mCodecCtx;
bool mFrameParallelMode; // Frame parallel is only supported by VP9 decoder.
+ uint32_t mHalPixelFormat;
uint32_t mWidth;
uint32_t mHeight;
bool mSignalledOutputEos;
diff --git a/media/codec2/fuzzer/Android.bp b/media/codec2/fuzzer/Android.bp
index 3adc212..147a52e 100644
--- a/media/codec2/fuzzer/Android.bp
+++ b/media/codec2/fuzzer/Android.bp
@@ -38,6 +38,12 @@
"-Wall",
"-Werror",
],
+
+ fuzz_config: {
+ cc: [
+ "wonsik@google.com",
+ ],
+ },
}
cc_fuzz {
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 2b9ec7d..cb362c9 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1526,6 +1526,9 @@
using namespace android::hardware::graphics::bufferqueue::V1_0::utils;
typedef android::hardware::media::omx::V1_0::Status OmxStatus;
android::sp<IOmx> omx = IOmx::getService();
+ if (omx == nullptr) {
+ return nullptr;
+ }
typedef android::hardware::graphics::bufferqueue::V1_0::
IGraphicBufferProducer HGraphicBufferProducer;
typedef android::hardware::media::omx::V1_0::
@@ -1803,9 +1806,16 @@
if (tryAndReportOnError(setRunning) != OK) {
return;
}
+
+ err2 = mChannel->requestInitialInputBuffers();
+
+ if (err2 != OK) {
+ ALOGE("Initial request for Input Buffers failed");
+ mCallback->onError(err2,ACTION_CODE_FATAL);
+ return;
+ }
mCallback->onStartCompleted();
- (void)mChannel->requestInitialInputBuffers();
}
void CCodec::initiateShutdown(bool keepComponentAllocated) {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 870660e..674714f 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -16,7 +16,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "CCodecBufferChannel"
+#define ATRACE_TAG ATRACE_TAG_VIDEO
#include <utils/Log.h>
+#include <utils/Trace.h>
#include <algorithm>
#include <atomic>
@@ -326,6 +328,8 @@
}
c2_status_t err = C2_OK;
if (!items.empty()) {
+ ScopedTrace trace(ATRACE_TAG, android::base::StringPrintf(
+ "CCodecBufferChannel::queue(%s@ts=%lld)", mName, (long long)timeUs).c_str());
{
Mutexed<PipelineWatcher>::Locked watcher(mPipelineWatcher);
PipelineWatcher::Clock::time_point now = PipelineWatcher::Clock::now();
@@ -923,6 +927,11 @@
hdr.validTypes |= HdrMetadata::CTA861_3;
hdr.cta8613 = cta861_meta;
}
+
+ // does not have valid info
+ if (!(hdr.validTypes & (HdrMetadata::SMPTE2086 | HdrMetadata::CTA861_3))) {
+ hdrStaticInfo.reset();
+ }
}
if (hdrDynamicInfo
&& hdrDynamicInfo->m.type_ == C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40) {
@@ -1908,6 +1917,8 @@
// When using input surface we need to restore the original input timestamp.
timestamp = work->input.ordinal.customOrdinal;
}
+ ScopedTrace trace(ATRACE_TAG, android::base::StringPrintf(
+ "CCodecBufferChannel::onWorkDone(%s@ts=%lld)", mName, timestamp.peekll()).c_str());
ALOGV("[%s] onWorkDone: input %lld, codec %lld => output %lld => %lld",
mName,
work->input.ordinal.customOrdinal.peekll(),
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index 2d3c70a..c2405e8 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -16,7 +16,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "Codec2Buffer"
+#define ATRACE_TAG ATRACE_TAG_VIDEO
#include <utils/Log.h>
+#include <utils/Trace.h>
#include <aidl/android/hardware/graphics/common/Cta861_3.h>
#include <aidl/android/hardware/graphics/common/Smpte2086.h>
@@ -229,6 +231,7 @@
mAllocatedDepth(0),
mBackBufferSize(0),
mMediaImage(new ABuffer(sizeof(MediaImage2))) {
+ ATRACE_CALL();
if (!format->findInt32(KEY_COLOR_FORMAT, &mClientColorFormat)) {
mClientColorFormat = COLOR_FormatYUV420Flexible;
}
@@ -581,6 +584,7 @@
* Copy C2GraphicView to MediaImage2.
*/
status_t copyToMediaImage() {
+ ATRACE_CALL();
if (mInitCheck != OK) {
return mInitCheck;
}
@@ -619,7 +623,9 @@
const sp<AMessage> &format,
const std::shared_ptr<C2GraphicBlock> &block,
std::function<sp<ABuffer>(size_t)> alloc) {
+ ATRACE_BEGIN("GraphicBlockBuffer::Allocate block->map()");
C2GraphicView view(block->map().get());
+ ATRACE_END();
if (view.error() != C2_OK) {
ALOGD("C2GraphicBlock::map failed: %d", view.error());
return nullptr;
@@ -664,6 +670,7 @@
}
std::shared_ptr<C2Buffer> GraphicBlockBuffer::asC2Buffer() {
+ ATRACE_CALL();
uint32_t width = mView.width();
uint32_t height = mView.height();
if (!mWrapped) {
@@ -752,8 +759,10 @@
ALOGD("C2Buffer precond fail");
return nullptr;
}
+ ATRACE_BEGIN("ConstGraphicBlockBuffer::Allocate block->map()");
std::unique_ptr<const C2GraphicView> view(std::make_unique<const C2GraphicView>(
buffer->data().graphicBlocks()[0].map().get()));
+ ATRACE_END();
std::unique_ptr<const C2GraphicView> holder;
GraphicView2MediaImageConverter converter(*view, format, false /* copy */);
@@ -854,11 +863,13 @@
return false;
}
+ ATRACE_BEGIN("ConstGraphicBlockBuffer::canCopy block->map()");
GraphicView2MediaImageConverter converter(
buffer->data().graphicBlocks()[0].map().get(),
// FIXME: format() is not const, but we cannot change it, so do a const cast here
const_cast<ConstGraphicBlockBuffer *>(this)->format(),
true /* copy */);
+ ATRACE_END();
if (converter.initCheck() != OK) {
ALOGD("ConstGraphicBlockBuffer::canCopy: converter init failed: %d", converter.initCheck());
return false;
@@ -973,16 +984,47 @@
return sMapper;
}
-class NativeHandleDeleter {
+class Gralloc4Buffer {
public:
- explicit NativeHandleDeleter(native_handle_t *handle) : mHandle(handle) {}
- ~NativeHandleDeleter() {
- if (mHandle) {
- native_handle_delete(mHandle);
+ Gralloc4Buffer(const C2Handle *const handle) : mBuffer(nullptr) {
+ sp<IMapper4> mapper = GetMapper4();
+ if (!mapper) {
+ return;
+ }
+ // Unwrap raw buffer handle from the C2Handle
+ native_handle_t *nh = UnwrapNativeCodec2GrallocHandle(handle);
+ if (!nh) {
+ return;
+ }
+ // Import the raw handle so IMapper can use the buffer. The imported
+ // handle must be freed when the client is done with the buffer.
+ mapper->importBuffer(
+ hardware::hidl_handle(nh),
+ [&](const Error4 &error, void *buffer) {
+ if (error == Error4::NONE) {
+ mBuffer = buffer;
+ }
+ });
+
+ // TRICKY: UnwrapNativeCodec2GrallocHandle creates a new handle but
+ // does not clone the fds. Thus we need to delete the handle
+ // without closing it.
+ native_handle_delete(nh);
+ }
+
+ ~Gralloc4Buffer() {
+ sp<IMapper4> mapper = GetMapper4();
+ if (mapper && mBuffer) {
+ // Free the imported buffer handle. This does not release the
+ // underlying buffer itself.
+ mapper->freeBuffer(mBuffer);
}
}
+
+ void *get() const { return mBuffer; }
+ operator bool() const { return (mBuffer != nullptr); }
private:
- native_handle_t *mHandle;
+ void *mBuffer;
};
} // namspace
@@ -992,24 +1034,15 @@
std::shared_ptr<C2StreamHdrStaticMetadataInfo::input> *staticInfo,
std::shared_ptr<C2StreamHdrDynamicMetadataInfo::input> *dynamicInfo) {
c2_status_t err = C2_OK;
- native_handle_t *nativeHandle = UnwrapNativeCodec2GrallocHandle(handle);
- if (nativeHandle == nullptr) {
- // Nothing to do
- return err;
- }
- // TRICKY: UnwrapNativeCodec2GrallocHandle creates a new handle but
- // does not clone the fds. Thus we need to delete the handle
- // without closing it when going out of scope.
- // NativeHandle cannot solve this problem, as it would close and
- // delete the handle, while we need delete only.
- NativeHandleDeleter nhd(nativeHandle);
sp<IMapper4> mapper = GetMapper4();
- if (!mapper) {
+ Gralloc4Buffer buffer(handle);
+ if (!mapper || !buffer) {
// Gralloc4 not supported; nothing to do
return err;
}
Error4 mapperErr = Error4::NONE;
if (staticInfo) {
+ ALOGV("Grabbing static HDR info from gralloc4 metadata");
staticInfo->reset(new C2StreamHdrStaticMetadataInfo::input(0u));
memset(&(*staticInfo)->mastering, 0, sizeof((*staticInfo)->mastering));
(*staticInfo)->maxCll = 0;
@@ -1038,7 +1071,7 @@
mapperErr = Error4::BAD_VALUE;
}
};
- Return<void> ret = mapper->get(nativeHandle, MetadataType_Smpte2086, cb);
+ Return<void> ret = mapper->get(buffer.get(), MetadataType_Smpte2086, cb);
if (!ret.isOk()) {
err = C2_REFUSED;
} else if (mapperErr != Error4::NONE) {
@@ -1059,7 +1092,7 @@
mapperErr = Error4::BAD_VALUE;
}
};
- ret = mapper->get(nativeHandle, MetadataType_Cta861_3, cb);
+ ret = mapper->get(buffer.get(), MetadataType_Cta861_3, cb);
if (!ret.isOk()) {
err = C2_REFUSED;
} else if (mapperErr != Error4::NONE) {
@@ -1067,6 +1100,7 @@
}
}
if (dynamicInfo) {
+ ALOGV("Grabbing dynamic HDR info from gralloc4 metadata");
dynamicInfo->reset();
IMapper4::get_cb cb = [&mapperErr, dynamicInfo](Error4 err, const hidl_vec<uint8_t> &vec) {
mapperErr = err;
@@ -1080,7 +1114,7 @@
vec.size(), 0u, C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_40);
memcpy((*dynamicInfo)->m.data, vec.data(), vec.size());
};
- Return<void> ret = mapper->get(nativeHandle, MetadataType_Smpte2094_40, cb);
+ Return<void> ret = mapper->get(buffer.get(), MetadataType_Smpte2094_40, cb);
if (!ret.isOk() || mapperErr != Error4::NONE) {
dynamicInfo->reset();
}
@@ -1094,21 +1128,14 @@
const std::shared_ptr<const C2StreamHdrDynamicMetadataInfo::output> &dynamicInfo,
const C2Handle *const handle) {
c2_status_t err = C2_OK;
- native_handle_t *nativeHandle = UnwrapNativeCodec2GrallocHandle(handle);
- if (nativeHandle == nullptr) {
- // Nothing to do
- return err;
- }
- // TRICKY: UnwrapNativeCodec2GrallocHandle creates a new handle but
- // does not clone the fds. Thus we need to delete the handle
- // without closing it when going out of scope.
- NativeHandleDeleter nhd(nativeHandle);
sp<IMapper4> mapper = GetMapper4();
- if (!mapper) {
+ Gralloc4Buffer buffer(handle);
+ if (!mapper || !buffer) {
// Gralloc4 not supported; nothing to do
return err;
}
if (staticInfo && *staticInfo) {
+ ALOGV("Setting static HDR info as gralloc4 metadata");
std::optional<Smpte2086> smpte2086 = Smpte2086{
{staticInfo->mastering.red.x, staticInfo->mastering.red.y},
{staticInfo->mastering.green.x, staticInfo->mastering.green.y},
@@ -1118,8 +1145,17 @@
staticInfo->mastering.minLuminance,
};
hidl_vec<uint8_t> vec;
- if (gralloc4::encodeSmpte2086(smpte2086, &vec) == OK) {
- Return<Error4> ret = mapper->set(nativeHandle, MetadataType_Smpte2086, vec);
+ if (0.0 <= smpte2086->primaryRed.x && smpte2086->primaryRed.x <= 1.0
+ && 0.0 <= smpte2086->primaryRed.y && smpte2086->primaryRed.y <= 1.0
+ && 0.0 <= smpte2086->primaryGreen.x && smpte2086->primaryGreen.x <= 1.0
+ && 0.0 <= smpte2086->primaryGreen.y && smpte2086->primaryGreen.y <= 1.0
+ && 0.0 <= smpte2086->primaryBlue.x && smpte2086->primaryBlue.x <= 1.0
+ && 0.0 <= smpte2086->primaryBlue.y && smpte2086->primaryBlue.y <= 1.0
+ && 0.0 <= smpte2086->whitePoint.x && smpte2086->whitePoint.x <= 1.0
+ && 0.0 <= smpte2086->whitePoint.y && smpte2086->whitePoint.y <= 1.0
+ && 0.0 <= smpte2086->maxLuminance && 0.0 <= smpte2086->minLuminance
+ && gralloc4::encodeSmpte2086(smpte2086, &vec) == OK) {
+ Return<Error4> ret = mapper->set(buffer.get(), MetadataType_Smpte2086, vec);
if (!ret.isOk()) {
err = C2_REFUSED;
} else if (ret != Error4::NONE) {
@@ -1130,8 +1166,9 @@
staticInfo->maxCll,
staticInfo->maxFall,
};
- if (gralloc4::encodeCta861_3(cta861_3, &vec) == OK) {
- Return<Error4> ret = mapper->set(nativeHandle, MetadataType_Cta861_3, vec);
+ if (0.0 <= cta861_3->maxContentLightLevel && 0.0 <= cta861_3->maxFrameAverageLightLevel
+ && gralloc4::encodeCta861_3(cta861_3, &vec) == OK) {
+ Return<Error4> ret = mapper->set(buffer.get(), MetadataType_Cta861_3, vec);
if (!ret.isOk()) {
err = C2_REFUSED;
} else if (ret != Error4::NONE) {
@@ -1139,7 +1176,8 @@
}
}
}
- if (dynamicInfo && *dynamicInfo) {
+ if (dynamicInfo && *dynamicInfo && dynamicInfo->flexCount() > 0) {
+ ALOGV("Setting dynamic HDR info as gralloc4 metadata");
hidl_vec<uint8_t> vec;
vec.resize(dynamicInfo->flexCount());
memcpy(vec.data(), dynamicInfo->m.data, dynamicInfo->flexCount());
@@ -1153,7 +1191,7 @@
break;
}
if (metadataType) {
- Return<Error4> ret = mapper->set(nativeHandle, *metadataType, vec);
+ Return<Error4> ret = mapper->set(buffer.get(), *metadataType, vec);
if (!ret.isOk()) {
err = C2_REFUSED;
} else if (ret != Error4::NONE) {
diff --git a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
index bff9db5..7fc4c27 100644
--- a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
+++ b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
@@ -16,7 +16,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "Codec2BufferUtils"
+#define ATRACE_TAG ATRACE_TAG_VIDEO
#include <utils/Log.h>
+#include <utils/Trace.h>
#include <libyuv.h>
@@ -36,8 +38,8 @@
namespace {
/**
- * A flippable, optimizable memcpy. Constructs such as (from ? src : dst) do not work as the results are
- * always const.
+ * A flippable, optimizable memcpy. Constructs such as (from ? src : dst)
+ * do not work as the results are always const.
*/
template<bool ToA, size_t S>
struct MemCopier {
@@ -139,15 +141,18 @@
if (IsNV12(view)) {
if (IsNV12(img)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: NV12->NV12");
libyuv::CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
libyuv::CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, width, height / 2);
return OK;
} else if (IsNV21(img)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: NV12->NV21");
if (!libyuv::NV21ToNV12(src_y, src_stride_y, src_u, src_stride_u,
dst_y, dst_stride_y, dst_v, dst_stride_v, width, height)) {
return OK;
}
} else if (IsI420(img)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: NV12->I420");
if (!libyuv::NV12ToI420(src_y, src_stride_y, src_u, src_stride_u, dst_y, dst_stride_y,
dst_u, dst_stride_u, dst_v, dst_stride_v, width, height)) {
return OK;
@@ -155,15 +160,18 @@
}
} else if (IsNV21(view)) {
if (IsNV12(img)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: NV21->NV12");
if (!libyuv::NV21ToNV12(src_y, src_stride_y, src_v, src_stride_v,
dst_y, dst_stride_y, dst_u, dst_stride_u, width, height)) {
return OK;
}
} else if (IsNV21(img)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: NV21->NV21");
libyuv::CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
libyuv::CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, width, height / 2);
return OK;
} else if (IsI420(img)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: NV21->I420");
if (!libyuv::NV21ToI420(src_y, src_stride_y, src_v, src_stride_v, dst_y, dst_stride_y,
dst_u, dst_stride_u, dst_v, dst_stride_v, width, height)) {
return OK;
@@ -171,22 +179,26 @@
}
} else if (IsI420(view)) {
if (IsNV12(img)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: I420->NV12");
if (!libyuv::I420ToNV12(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
dst_y, dst_stride_y, dst_u, dst_stride_u, width, height)) {
return OK;
}
} else if (IsNV21(img)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: I420->NV21");
if (!libyuv::I420ToNV21(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
dst_y, dst_stride_y, dst_v, dst_stride_v, width, height)) {
return OK;
}
} else if (IsI420(img)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: I420->I420");
libyuv::CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
libyuv::CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, width / 2, height / 2);
libyuv::CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, width / 2, height / 2);
return OK;
}
}
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: generic");
return _ImageCopy<true>(view, img, imgBase);
}
@@ -210,15 +222,18 @@
int height = view.crop().height;
if (IsNV12(img)) {
if (IsNV12(view)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: NV12->NV12");
libyuv::CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
libyuv::CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, width, height / 2);
return OK;
} else if (IsNV21(view)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: NV12->NV21");
if (!libyuv::NV21ToNV12(src_y, src_stride_y, src_u, src_stride_u,
dst_y, dst_stride_y, dst_v, dst_stride_v, width, height)) {
return OK;
}
} else if (IsI420(view)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: NV12->I420");
if (!libyuv::NV12ToI420(src_y, src_stride_y, src_u, src_stride_u, dst_y, dst_stride_y,
dst_u, dst_stride_u, dst_v, dst_stride_v, width, height)) {
return OK;
@@ -226,15 +241,18 @@
}
} else if (IsNV21(img)) {
if (IsNV12(view)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: NV21->NV12");
if (!libyuv::NV21ToNV12(src_y, src_stride_y, src_v, src_stride_v,
dst_y, dst_stride_y, dst_u, dst_stride_u, width, height)) {
return OK;
}
} else if (IsNV21(view)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: NV21->NV21");
libyuv::CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
libyuv::CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, width, height / 2);
return OK;
} else if (IsI420(view)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: NV21->I420");
if (!libyuv::NV21ToI420(src_y, src_stride_y, src_v, src_stride_v, dst_y, dst_stride_y,
dst_u, dst_stride_u, dst_v, dst_stride_v, width, height)) {
return OK;
@@ -242,22 +260,26 @@
}
} else if (IsI420(img)) {
if (IsNV12(view)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: I420->NV12");
if (!libyuv::I420ToNV12(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
dst_y, dst_stride_y, dst_u, dst_stride_u, width, height)) {
return OK;
}
} else if (IsNV21(view)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: I420->NV21");
if (!libyuv::I420ToNV21(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
dst_y, dst_stride_y, dst_v, dst_stride_v, width, height)) {
return OK;
}
} else if (IsI420(view)) {
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: I420->I420");
libyuv::CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
libyuv::CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, width / 2, height / 2);
libyuv::CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, width / 2, height / 2);
return OK;
}
}
+ ScopedTrace trace(ATRACE_TAG, "ImageCopy: generic");
return _ImageCopy<false>(view, img, imgBase);
}
diff --git a/media/codec2/vndk/C2AllocatorIon.cpp b/media/codec2/vndk/C2AllocatorIon.cpp
index 7b593ee..a6a733e 100644
--- a/media/codec2/vndk/C2AllocatorIon.cpp
+++ b/media/codec2/vndk/C2AllocatorIon.cpp
@@ -31,6 +31,7 @@
#include <C2HandleIonInternal.h>
#include <android-base/properties.h>
+#include <media/stagefright/foundation/Mutexed.h>
namespace android {
@@ -180,7 +181,7 @@
c2_status_t map(size_t offset, size_t size, C2MemoryUsage usage, C2Fence *fence, void **addr) {
(void)fence; // TODO: wait for fence
*addr = nullptr;
- if (!mMappings.empty()) {
+ if (!mMappings.lock()->empty()) {
ALOGV("multiple map");
// TODO: technically we should return DUPLICATE here, but our block views don't
// actually unmap, so we end up remapping an ion buffer multiple times.
@@ -207,47 +208,44 @@
c2_status_t err = mapInternal(mapSize, mapOffset, alignmentBytes, prot, flags, &(map.addr), addr);
if (map.addr) {
- std::lock_guard<std::mutex> guard(mMutexMappings);
- mMappings.push_back(map);
+ mMappings.lock()->push_back(map);
}
return err;
}
c2_status_t unmap(void *addr, size_t size, C2Fence *fence) {
- if (mMappings.empty()) {
+ Mutexed<std::list<Mapping>>::Locked mappings(mMappings);
+ if (mappings->empty()) {
ALOGD("tried to unmap unmapped buffer");
return C2_NOT_FOUND;
}
- { // Scope for the lock_guard of mMutexMappings.
- std::lock_guard<std::mutex> guard(mMutexMappings);
- for (auto it = mMappings.begin(); it != mMappings.end(); ++it) {
- if (addr != (uint8_t *)it->addr + it->alignmentBytes ||
- size + it->alignmentBytes != it->size) {
- continue;
- }
- int err = munmap(it->addr, it->size);
- if (err != 0) {
- ALOGD("munmap failed");
- return c2_map_errno<EINVAL>(errno);
- }
- if (fence) {
- *fence = C2Fence(); // not using fences
- }
- (void)mMappings.erase(it);
- ALOGV("successfully unmapped: addr=%p size=%zu fd=%d", addr, size,
- mHandle.bufferFd());
- return C2_OK;
+ for (auto it = mappings->begin(); it != mappings->end(); ++it) {
+ if (addr != (uint8_t *)it->addr + it->alignmentBytes ||
+ size + it->alignmentBytes != it->size) {
+ continue;
}
+ int err = munmap(it->addr, it->size);
+ if (err != 0) {
+ ALOGD("munmap failed");
+ return c2_map_errno<EINVAL>(errno);
+ }
+ if (fence) {
+ *fence = C2Fence(); // not using fences
+ }
+ (void)mappings->erase(it);
+ ALOGV("successfully unmapped: addr=%p size=%zu fd=%d", addr, size,
+ mHandle.bufferFd());
+ return C2_OK;
}
ALOGD("unmap failed to find specified map");
return C2_BAD_VALUE;
}
virtual ~Impl() {
- if (!mMappings.empty()) {
+ Mutexed<std::list<Mapping>>::Locked mappings(mMappings);
+ if (!mappings->empty()) {
ALOGD("Dangling mappings!");
- std::lock_guard<std::mutex> guard(mMutexMappings);
- for (const Mapping &map : mMappings) {
+ for (const Mapping &map : *mappings) {
(void)munmap(map.addr, map.size);
}
}
@@ -325,8 +323,7 @@
size_t alignmentBytes;
size_t size;
};
- std::list<Mapping> mMappings;
- std::mutex mMutexMappings;
+ Mutexed<std::list<Mapping>> mMappings;
};
class C2AllocationIon::ImplV2 : public C2AllocationIon::Impl {
diff --git a/media/codec2/vndk/C2DmaBufAllocator.cpp b/media/codec2/vndk/C2DmaBufAllocator.cpp
index 1aa3d69..c470171 100644
--- a/media/codec2/vndk/C2DmaBufAllocator.cpp
+++ b/media/codec2/vndk/C2DmaBufAllocator.cpp
@@ -31,6 +31,7 @@
#include <list>
#include <android-base/properties.h>
+#include <media/stagefright/foundation/Mutexed.h>
namespace android {
@@ -161,7 +162,7 @@
size_t alignmentBytes;
size_t size;
};
- std::list<Mapping> mMappings;
+ Mutexed<std::list<Mapping>> mMappings;
// TODO: we could make this encapsulate shared_ptr and copiable
C2_DO_NOT_COPY(C2DmaBufAllocation);
@@ -171,7 +172,7 @@
void** addr) {
(void)fence; // TODO: wait for fence
*addr = nullptr;
- if (!mMappings.empty()) {
+ if (!mMappings.lock()->empty()) {
ALOGV("multiple map");
// TODO: technically we should return DUPLICATE here, but our block views
// don't actually unmap, so we end up remapping the buffer multiple times.
@@ -199,17 +200,18 @@
c2_status_t err =
mapInternal(mapSize, mapOffset, alignmentBytes, prot, flags, &(map.addr), addr);
if (map.addr) {
- mMappings.push_back(map);
+ mMappings.lock()->push_back(map);
}
return err;
}
c2_status_t C2DmaBufAllocation::unmap(void* addr, size_t size, C2Fence* fence) {
- if (mMappings.empty()) {
+ Mutexed<std::list<Mapping>>::Locked mappings(mMappings);
+ if (mappings->empty()) {
ALOGD("tried to unmap unmapped buffer");
return C2_NOT_FOUND;
}
- for (auto it = mMappings.begin(); it != mMappings.end(); ++it) {
+ for (auto it = mappings->begin(); it != mappings->end(); ++it) {
if (addr != (uint8_t*)it->addr + it->alignmentBytes ||
size + it->alignmentBytes != it->size) {
continue;
@@ -222,7 +224,7 @@
if (fence) {
*fence = C2Fence(); // not using fences
}
- (void)mMappings.erase(it);
+ (void)mappings->erase(it);
ALOGV("successfully unmapped: %d", mHandle.bufferFd());
return C2_OK;
}
@@ -253,9 +255,10 @@
}
C2DmaBufAllocation::~C2DmaBufAllocation() {
- if (!mMappings.empty()) {
+ Mutexed<std::list<Mapping>>::Locked mappings(mMappings);
+ if (!mappings->empty()) {
ALOGD("Dangling mappings!");
- for (const Mapping& map : mMappings) {
+ for (const Mapping& map : *mappings) {
int err = munmap(map.addr, map.size);
if (err) ALOGD("munmap failed");
}
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index f50b53a..363d219 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -93,7 +93,6 @@
"-Wno-unused-parameter",
"-Wall",
"-Werror",
-
// By default, all symbols are hidden.
// "-fvisibility=hidden",
// AAUDIO_API is used to explicitly export a function or a variable as a visible symbol.
@@ -261,7 +260,7 @@
"binding/aidl/aaudio/IAAudioService.aidl",
],
imports: [
- "android.media.audio.common.types",
+ "android.media.audio.common.types-V1",
"audioclient-types-aidl",
"shared-file-region-aidl",
"framework-permission-aidl",
diff --git a/media/libaaudio/src/client/AAudioFlowGraph.cpp b/media/libaaudio/src/client/AAudioFlowGraph.cpp
index d0c3238..2ed3e3c 100644
--- a/media/libaaudio/src/client/AAudioFlowGraph.cpp
+++ b/media/libaaudio/src/client/AAudioFlowGraph.cpp
@@ -35,7 +35,7 @@
#include <flowgraph/SourceI24.h>
#include <flowgraph/SourceI32.h>
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
aaudio_result_t AAudioFlowGraph::configure(audio_format_t sourceFormat,
int32_t sourceChannelCount,
diff --git a/media/libaaudio/src/client/AAudioFlowGraph.h b/media/libaaudio/src/client/AAudioFlowGraph.h
index 00b6575..602c17f 100644
--- a/media/libaaudio/src/client/AAudioFlowGraph.h
+++ b/media/libaaudio/src/client/AAudioFlowGraph.h
@@ -72,17 +72,19 @@
void setRampLengthInFrames(int32_t numFrames);
private:
- std::unique_ptr<flowgraph::FlowGraphSourceBuffered> mSource;
- std::unique_ptr<flowgraph::MonoBlend> mMonoBlend;
- std::unique_ptr<flowgraph::ClipToRange> mClipper;
- std::unique_ptr<flowgraph::MonoToMultiConverter> mChannelConverter;
- std::unique_ptr<flowgraph::ManyToMultiConverter> mManyToMultiConverter;
- std::unique_ptr<flowgraph::MultiToManyConverter> mMultiToManyConverter;
- std::vector<std::unique_ptr<flowgraph::RampLinear>> mVolumeRamps;
- std::vector<float> mPanningVolumes;
- float mTargetVolume = 1.0f;
- android::audio_utils::Balance mBalance;
- std::unique_ptr<flowgraph::FlowGraphSink> mSink;
+ std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::FlowGraphSourceBuffered> mSource;
+ std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::MonoBlend> mMonoBlend;
+ std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::ClipToRange> mClipper;
+ std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::MonoToMultiConverter> mChannelConverter;
+ std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::ManyToMultiConverter>
+ mManyToMultiConverter;
+ std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::MultiToManyConverter>
+ mMultiToManyConverter;
+ std::vector<std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::RampLinear>> mVolumeRamps;
+ std::vector<float> mPanningVolumes;
+ float mTargetVolume = 1.0f;
+ android::audio_utils::Balance mBalance;
+ std::unique_ptr<FLOWGRAPH_OUTER_NAMESPACE::flowgraph::FlowGraphSink> mSink;
};
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 450d390..7c7a969 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -202,10 +202,18 @@
break;
case AAUDIO_STREAM_STATE_STARTED:
{
- // Sleep until the readCounter catches up and we only have
- // the getBufferSize() frames of data sitting in the buffer.
- int64_t nextReadPosition = mAudioEndpoint->getDataWriteCounter() - getBufferSize();
- wakeTime = mClockModel.convertPositionToTime(nextReadPosition);
+ // Calculate when there will be room available to write to the buffer.
+ // If the appBufferSize is smaller than the endpointBufferSize then
+ // we will have room to write data beyond the appBufferSize.
+ // That is a technique used to reduce glitches without adding latency.
+ const int32_t appBufferSize = getBufferSize();
+ // The endpoint buffer size is set to the maximum that can be written.
+ // If we use it then we must carve out some room to write data when we wake up.
+ const int32_t endBufferSize = mAudioEndpoint->getBufferSizeInFrames()
+ - getFramesPerBurst();
+ const int32_t bestBufferSize = std::min(appBufferSize, endBufferSize);
+ int64_t targetReadPosition = mAudioEndpoint->getDataWriteCounter() - bestBufferSize;
+ wakeTime = mClockModel.convertPositionToTime(targetReadPosition);
}
break;
default:
diff --git a/media/libaaudio/src/flowgraph/ChannelCountConverter.cpp b/media/libaaudio/src/flowgraph/ChannelCountConverter.cpp
index 351def2..dc80427 100644
--- a/media/libaaudio/src/flowgraph/ChannelCountConverter.cpp
+++ b/media/libaaudio/src/flowgraph/ChannelCountConverter.cpp
@@ -18,7 +18,7 @@
#include "FlowGraphNode.h"
#include "ChannelCountConverter.h"
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
ChannelCountConverter::ChannelCountConverter(
int32_t inputChannelCount,
diff --git a/media/libaaudio/src/flowgraph/ChannelCountConverter.h b/media/libaaudio/src/flowgraph/ChannelCountConverter.h
index e4b6f4e..858f4d4 100644
--- a/media/libaaudio/src/flowgraph/ChannelCountConverter.h
+++ b/media/libaaudio/src/flowgraph/ChannelCountConverter.h
@@ -22,7 +22,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
/**
* Change the number of number of channels without mixing.
@@ -47,6 +47,6 @@
FlowGraphPortFloatOutput output;
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_CHANNEL_COUNT_CONVERTER_H
diff --git a/media/libaaudio/src/flowgraph/ClipToRange.cpp b/media/libaaudio/src/flowgraph/ClipToRange.cpp
index d2f8a02..c6ad0b0 100644
--- a/media/libaaudio/src/flowgraph/ClipToRange.cpp
+++ b/media/libaaudio/src/flowgraph/ClipToRange.cpp
@@ -19,7 +19,7 @@
#include "FlowGraphNode.h"
#include "ClipToRange.h"
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
ClipToRange::ClipToRange(int32_t channelCount)
: FlowGraphFilter(channelCount) {
diff --git a/media/libaaudio/src/flowgraph/ClipToRange.h b/media/libaaudio/src/flowgraph/ClipToRange.h
index 22b7804..2fddeee 100644
--- a/media/libaaudio/src/flowgraph/ClipToRange.h
+++ b/media/libaaudio/src/flowgraph/ClipToRange.h
@@ -23,7 +23,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
// This is 3 dB, (10^(3/20)), to match the maximum headroom in AudioTrack for float data.
// It is designed to allow occasional transient peaks.
@@ -63,6 +63,6 @@
float mMaximum = kDefaultMaxHeadroom;
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_CLIP_TO_RANGE_H
diff --git a/media/libaaudio/src/flowgraph/FlowGraphNode.cpp b/media/libaaudio/src/flowgraph/FlowGraphNode.cpp
index 4c76e77..012abe7 100644
--- a/media/libaaudio/src/flowgraph/FlowGraphNode.cpp
+++ b/media/libaaudio/src/flowgraph/FlowGraphNode.cpp
@@ -19,7 +19,7 @@
#include <sys/types.h>
#include "FlowGraphNode.h"
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
/***************************************************************************/
int32_t FlowGraphNode::pullData(int32_t numFrames, int64_t callCount) {
@@ -68,7 +68,7 @@
: FlowGraphPort(parent, samplesPerFrame)
, mFramesPerBuffer(framesPerBuffer)
, mBuffer(nullptr) {
- size_t numFloats = framesPerBuffer * getSamplesPerFrame();
+ size_t numFloats = static_cast<size_t>(framesPerBuffer) * getSamplesPerFrame();
mBuffer = std::make_unique<float[]>(numFloats);
}
diff --git a/media/libaaudio/src/flowgraph/FlowGraphNode.h b/media/libaaudio/src/flowgraph/FlowGraphNode.h
index 69c83dd..2884c08 100644
--- a/media/libaaudio/src/flowgraph/FlowGraphNode.h
+++ b/media/libaaudio/src/flowgraph/FlowGraphNode.h
@@ -38,13 +38,26 @@
// TODO Review use of raw pointers for connect(). Maybe use smart pointers but need to avoid
// run-time deallocation in audio thread.
-// Set this to 1 if using it inside the Android framework.
-// This code is kept here so that it can be moved easily between Oboe and AAudio.
-#ifndef FLOWGRAPH_ANDROID_INTERNAL
-#define FLOWGRAPH_ANDROID_INTERNAL 0
-#endif
+// Set flags FLOWGRAPH_ANDROID_INTERNAL and FLOWGRAPH_OUTER_NAMESPACE based on whether compiler
+// flag __ANDROID_NDK__ is defined. __ANDROID_NDK__ should be defined in oboe and not aaudio.
-namespace flowgraph {
+#ifndef FLOWGRAPH_ANDROID_INTERNAL
+#ifdef __ANDROID_NDK__
+#define FLOWGRAPH_ANDROID_INTERNAL 0
+#else
+#define FLOWGRAPH_ANDROID_INTERNAL 1
+#endif // __ANDROID_NDK__
+#endif // FLOWGRAPH_ANDROID_INTERNAL
+
+#ifndef FLOWGRAPH_OUTER_NAMESPACE
+#ifdef __ANDROID_NDK__
+#define FLOWGRAPH_OUTER_NAMESPACE oboe
+#else
+#define FLOWGRAPH_OUTER_NAMESPACE aaudio
+#endif // __ANDROID_NDK__
+#endif // FLOWGRAPH_OUTER_NAMESPACE
+
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
// Default block size that can be overridden when the FlowGraphPortFloat is created.
// If it is too small then we will have too much overhead from switching between nodes.
@@ -432,6 +445,6 @@
FlowGraphPortFloatOutput output;
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif /* FLOWGRAPH_FLOW_GRAPH_NODE_H */
diff --git a/media/libaaudio/src/flowgraph/FlowgraphUtilities.h b/media/libaaudio/src/flowgraph/FlowgraphUtilities.h
index b750410..ce2bc82 100644
--- a/media/libaaudio/src/flowgraph/FlowgraphUtilities.h
+++ b/media/libaaudio/src/flowgraph/FlowgraphUtilities.h
@@ -19,7 +19,7 @@
#include <unistd.h>
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
class FlowgraphUtilities {
public:
diff --git a/media/libaaudio/src/flowgraph/ManyToMultiConverter.cpp b/media/libaaudio/src/flowgraph/ManyToMultiConverter.cpp
index 879685e..4f973bc 100644
--- a/media/libaaudio/src/flowgraph/ManyToMultiConverter.cpp
+++ b/media/libaaudio/src/flowgraph/ManyToMultiConverter.cpp
@@ -18,7 +18,7 @@
#include "ManyToMultiConverter.h"
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
ManyToMultiConverter::ManyToMultiConverter(int32_t channelCount)
: inputs(channelCount)
diff --git a/media/libaaudio/src/flowgraph/ManyToMultiConverter.h b/media/libaaudio/src/flowgraph/ManyToMultiConverter.h
index c7460ff..50644cf 100644
--- a/media/libaaudio/src/flowgraph/ManyToMultiConverter.h
+++ b/media/libaaudio/src/flowgraph/ManyToMultiConverter.h
@@ -23,7 +23,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
/**
* Combine multiple mono inputs into one interleaved multi-channel output.
@@ -48,6 +48,6 @@
private:
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_MANY_TO_MULTI_CONVERTER_H
diff --git a/media/libaaudio/src/flowgraph/MonoBlend.cpp b/media/libaaudio/src/flowgraph/MonoBlend.cpp
index 62e2809..4fd75e1 100644
--- a/media/libaaudio/src/flowgraph/MonoBlend.cpp
+++ b/media/libaaudio/src/flowgraph/MonoBlend.cpp
@@ -18,7 +18,7 @@
#include "MonoBlend.h"
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
MonoBlend::MonoBlend(int32_t channelCount)
: FlowGraphFilter(channelCount)
@@ -43,4 +43,4 @@
}
return numFrames;
-}
\ No newline at end of file
+}
diff --git a/media/libaaudio/src/flowgraph/MonoBlend.h b/media/libaaudio/src/flowgraph/MonoBlend.h
index 7e3c35b..f8d44ff 100644
--- a/media/libaaudio/src/flowgraph/MonoBlend.h
+++ b/media/libaaudio/src/flowgraph/MonoBlend.h
@@ -22,7 +22,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
/**
* Combine data between multiple channels so each channel is an average
@@ -43,6 +43,6 @@
const float mInvChannelCount;
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_MONO_BLEND
diff --git a/media/libaaudio/src/flowgraph/MonoToMultiConverter.cpp b/media/libaaudio/src/flowgraph/MonoToMultiConverter.cpp
index c8d60b9..33eed52 100644
--- a/media/libaaudio/src/flowgraph/MonoToMultiConverter.cpp
+++ b/media/libaaudio/src/flowgraph/MonoToMultiConverter.cpp
@@ -18,7 +18,7 @@
#include "FlowGraphNode.h"
#include "MonoToMultiConverter.h"
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
MonoToMultiConverter::MonoToMultiConverter(int32_t outputChannelCount)
: input(*this, 1)
diff --git a/media/libaaudio/src/flowgraph/MonoToMultiConverter.h b/media/libaaudio/src/flowgraph/MonoToMultiConverter.h
index 6e87ccb..762edb0 100644
--- a/media/libaaudio/src/flowgraph/MonoToMultiConverter.h
+++ b/media/libaaudio/src/flowgraph/MonoToMultiConverter.h
@@ -22,7 +22,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
/**
* Convert a monophonic stream to a multi-channel interleaved stream
@@ -44,6 +44,6 @@
FlowGraphPortFloatOutput output;
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_MONO_TO_MULTI_CONVERTER_H
diff --git a/media/libaaudio/src/flowgraph/MultiToManyConverter.cpp b/media/libaaudio/src/flowgraph/MultiToManyConverter.cpp
index f074364..5cdf594 100644
--- a/media/libaaudio/src/flowgraph/MultiToManyConverter.cpp
+++ b/media/libaaudio/src/flowgraph/MultiToManyConverter.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 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.
@@ -18,7 +18,7 @@
#include "FlowGraphNode.h"
#include "MultiToManyConverter.h"
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
MultiToManyConverter::MultiToManyConverter(int32_t channelCount)
: outputs(channelCount)
@@ -45,4 +45,3 @@
return numFrames;
}
-
diff --git a/media/libaaudio/src/flowgraph/MultiToManyConverter.h b/media/libaaudio/src/flowgraph/MultiToManyConverter.h
index de31475..dee40a2 100644
--- a/media/libaaudio/src/flowgraph/MultiToManyConverter.h
+++ b/media/libaaudio/src/flowgraph/MultiToManyConverter.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 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.
@@ -22,7 +22,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
/**
* Convert a multi-channel interleaved stream to multiple mono-channel
@@ -44,6 +44,6 @@
flowgraph::FlowGraphPortFloatInput input;
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
-#endif //FLOWGRAPH_MULTI_TO_MANY_CONVERTER_H
+#endif //FLOWGRAPH_MULTI_TO_MANY_CONVERTER_H
\ No newline at end of file
diff --git a/media/libaaudio/src/flowgraph/MultiToMonoConverter.cpp b/media/libaaudio/src/flowgraph/MultiToMonoConverter.cpp
index c745108..467f95e 100644
--- a/media/libaaudio/src/flowgraph/MultiToMonoConverter.cpp
+++ b/media/libaaudio/src/flowgraph/MultiToMonoConverter.cpp
@@ -18,7 +18,7 @@
#include "FlowGraphNode.h"
#include "MultiToMonoConverter.h"
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
MultiToMonoConverter::MultiToMonoConverter(int32_t inputChannelCount)
: input(*this, inputChannelCount)
diff --git a/media/libaaudio/src/flowgraph/MultiToMonoConverter.h b/media/libaaudio/src/flowgraph/MultiToMonoConverter.h
index 37c53bd..bf5b7b6 100644
--- a/media/libaaudio/src/flowgraph/MultiToMonoConverter.h
+++ b/media/libaaudio/src/flowgraph/MultiToMonoConverter.h
@@ -22,7 +22,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
/**
* Convert a multi-channel interleaved stream to a monophonic stream
@@ -44,6 +44,6 @@
FlowGraphPortFloatOutput output;
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_MULTI_TO_MONO_CONVERTER_H
diff --git a/media/libaaudio/src/flowgraph/RampLinear.cpp b/media/libaaudio/src/flowgraph/RampLinear.cpp
index 905ae07..80ac72a 100644
--- a/media/libaaudio/src/flowgraph/RampLinear.cpp
+++ b/media/libaaudio/src/flowgraph/RampLinear.cpp
@@ -19,7 +19,7 @@
#include "FlowGraphNode.h"
#include "RampLinear.h"
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
RampLinear::RampLinear(int32_t channelCount)
: FlowGraphFilter(channelCount) {
diff --git a/media/libaaudio/src/flowgraph/RampLinear.h b/media/libaaudio/src/flowgraph/RampLinear.h
index f285704..3839d6e 100644
--- a/media/libaaudio/src/flowgraph/RampLinear.h
+++ b/media/libaaudio/src/flowgraph/RampLinear.h
@@ -23,7 +23,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
/**
* When the target is modified then the output will ramp smoothly
@@ -91,6 +91,6 @@
float mLevelTo = 0.0f;
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_RAMP_LINEAR_H
diff --git a/media/libaaudio/src/flowgraph/SampleRateConverter.cpp b/media/libaaudio/src/flowgraph/SampleRateConverter.cpp
index 5c3ed1f..a15fcb8 100644
--- a/media/libaaudio/src/flowgraph/SampleRateConverter.cpp
+++ b/media/libaaudio/src/flowgraph/SampleRateConverter.cpp
@@ -16,10 +16,11 @@
#include "SampleRateConverter.h"
-using namespace flowgraph;
-using namespace resampler;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
+using namespace RESAMPLER_OUTER_NAMESPACE::resampler;
-SampleRateConverter::SampleRateConverter(int32_t channelCount, MultiChannelResampler &resampler)
+SampleRateConverter::SampleRateConverter(int32_t channelCount,
+ MultiChannelResampler &resampler)
: FlowGraphFilter(channelCount)
, mResampler(resampler) {
setDataPulledAutomatically(false);
diff --git a/media/libaaudio/src/flowgraph/SampleRateConverter.h b/media/libaaudio/src/flowgraph/SampleRateConverter.h
index 57d76a4..f883e6c 100644
--- a/media/libaaudio/src/flowgraph/SampleRateConverter.h
+++ b/media/libaaudio/src/flowgraph/SampleRateConverter.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef OBOE_SAMPLE_RATE_CONVERTER_H
-#define OBOE_SAMPLE_RATE_CONVERTER_H
+#ifndef FLOWGRAPH_SAMPLE_RATE_CONVERTER_H
+#define FLOWGRAPH_SAMPLE_RATE_CONVERTER_H
#include <unistd.h>
#include <sys/types.h>
@@ -23,7 +23,7 @@
#include "FlowGraphNode.h"
#include "resampler/MultiChannelResampler.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
class SampleRateConverter : public FlowGraphFilter {
public:
@@ -58,6 +58,6 @@
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
-#endif //OBOE_SAMPLE_RATE_CONVERTER_H
+#endif //FLOWGRAPH_SAMPLE_RATE_CONVERTER_H
diff --git a/media/libaaudio/src/flowgraph/SinkFloat.cpp b/media/libaaudio/src/flowgraph/SinkFloat.cpp
index 0588848..940a66b 100644
--- a/media/libaaudio/src/flowgraph/SinkFloat.cpp
+++ b/media/libaaudio/src/flowgraph/SinkFloat.cpp
@@ -19,7 +19,7 @@
#include "FlowGraphNode.h"
#include "SinkFloat.h"
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
SinkFloat::SinkFloat(int32_t channelCount)
: FlowGraphSink(channelCount) {
diff --git a/media/libaaudio/src/flowgraph/SinkFloat.h b/media/libaaudio/src/flowgraph/SinkFloat.h
index c812373..3be3f5d 100644
--- a/media/libaaudio/src/flowgraph/SinkFloat.h
+++ b/media/libaaudio/src/flowgraph/SinkFloat.h
@@ -23,7 +23,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
/**
* AudioSink that lets you read data as 32-bit floats.
@@ -40,6 +40,6 @@
}
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_SINK_FLOAT_H
diff --git a/media/libaaudio/src/flowgraph/SinkI16.cpp b/media/libaaudio/src/flowgraph/SinkI16.cpp
index da7fd6b..690431c 100644
--- a/media/libaaudio/src/flowgraph/SinkI16.cpp
+++ b/media/libaaudio/src/flowgraph/SinkI16.cpp
@@ -23,7 +23,7 @@
#include <audio_utils/primitives.h>
#endif
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
SinkI16::SinkI16(int32_t channelCount)
: FlowGraphSink(channelCount) {}
diff --git a/media/libaaudio/src/flowgraph/SinkI16.h b/media/libaaudio/src/flowgraph/SinkI16.h
index 1e1ce3a..bf124f5 100644
--- a/media/libaaudio/src/flowgraph/SinkI16.h
+++ b/media/libaaudio/src/flowgraph/SinkI16.h
@@ -22,7 +22,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
/**
* AudioSink that lets you read data as 16-bit signed integers.
@@ -38,6 +38,6 @@
}
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_SINK_I16_H
diff --git a/media/libaaudio/src/flowgraph/SinkI24.cpp b/media/libaaudio/src/flowgraph/SinkI24.cpp
index a9fb5d2..d4f68b6 100644
--- a/media/libaaudio/src/flowgraph/SinkI24.cpp
+++ b/media/libaaudio/src/flowgraph/SinkI24.cpp
@@ -25,7 +25,7 @@
#include <audio_utils/primitives.h>
#endif
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
SinkI24::SinkI24(int32_t channelCount)
: FlowGraphSink(channelCount) {}
diff --git a/media/libaaudio/src/flowgraph/SinkI24.h b/media/libaaudio/src/flowgraph/SinkI24.h
index 44078a9..6b4135e 100644
--- a/media/libaaudio/src/flowgraph/SinkI24.h
+++ b/media/libaaudio/src/flowgraph/SinkI24.h
@@ -22,7 +22,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
/**
* AudioSink that lets you read data as packed 24-bit signed integers.
@@ -39,6 +39,6 @@
}
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_SINK_I24_H
diff --git a/media/libaaudio/src/flowgraph/SinkI32.cpp b/media/libaaudio/src/flowgraph/SinkI32.cpp
index 9fd4e96..b14b3d2 100644
--- a/media/libaaudio/src/flowgraph/SinkI32.cpp
+++ b/media/libaaudio/src/flowgraph/SinkI32.cpp
@@ -14,15 +14,15 @@
* limitations under the License.
*/
-#if FLOWGRAPH_ANDROID_INTERNAL
-#include <audio_utils/primitives.h>
-#endif
-
#include "FlowGraphNode.h"
#include "FlowgraphUtilities.h"
#include "SinkI32.h"
-using namespace flowgraph;
+#if FLOWGRAPH_ANDROID_INTERNAL
+#include <audio_utils/primitives.h>
+#endif
+
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
SinkI32::SinkI32(int32_t channelCount)
: FlowGraphSink(channelCount) {}
diff --git a/media/libaaudio/src/flowgraph/SinkI32.h b/media/libaaudio/src/flowgraph/SinkI32.h
index 7456d5f..35507ea 100644
--- a/media/libaaudio/src/flowgraph/SinkI32.h
+++ b/media/libaaudio/src/flowgraph/SinkI32.h
@@ -21,7 +21,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
class SinkI32 : public FlowGraphSink {
public:
@@ -35,6 +35,6 @@
}
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_SINK_I32_H
diff --git a/media/libaaudio/src/flowgraph/SourceFloat.cpp b/media/libaaudio/src/flowgraph/SourceFloat.cpp
index 1b3daf1..a0c8827 100644
--- a/media/libaaudio/src/flowgraph/SourceFloat.cpp
+++ b/media/libaaudio/src/flowgraph/SourceFloat.cpp
@@ -19,7 +19,7 @@
#include "FlowGraphNode.h"
#include "SourceFloat.h"
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
SourceFloat::SourceFloat(int32_t channelCount)
: FlowGraphSourceBuffered(channelCount) {
diff --git a/media/libaaudio/src/flowgraph/SourceFloat.h b/media/libaaudio/src/flowgraph/SourceFloat.h
index 4719669..78053e5 100644
--- a/media/libaaudio/src/flowgraph/SourceFloat.h
+++ b/media/libaaudio/src/flowgraph/SourceFloat.h
@@ -22,7 +22,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
/**
* AudioSource that reads a block of pre-defined float data.
@@ -39,6 +39,6 @@
}
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_SOURCE_FLOAT_H
diff --git a/media/libaaudio/src/flowgraph/SourceI16.cpp b/media/libaaudio/src/flowgraph/SourceI16.cpp
index 8813023..16cd2b3 100644
--- a/media/libaaudio/src/flowgraph/SourceI16.cpp
+++ b/media/libaaudio/src/flowgraph/SourceI16.cpp
@@ -24,7 +24,7 @@
#include <audio_utils/primitives.h>
#endif
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
SourceI16::SourceI16(int32_t channelCount)
: FlowGraphSourceBuffered(channelCount) {
diff --git a/media/libaaudio/src/flowgraph/SourceI16.h b/media/libaaudio/src/flowgraph/SourceI16.h
index fe440b2..923890c 100644
--- a/media/libaaudio/src/flowgraph/SourceI16.h
+++ b/media/libaaudio/src/flowgraph/SourceI16.h
@@ -22,7 +22,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
/**
* AudioSource that reads a block of pre-defined 16-bit integer data.
*/
@@ -37,6 +37,6 @@
}
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_SOURCE_I16_H
diff --git a/media/libaaudio/src/flowgraph/SourceI24.cpp b/media/libaaudio/src/flowgraph/SourceI24.cpp
index 1975878..d54b958 100644
--- a/media/libaaudio/src/flowgraph/SourceI24.cpp
+++ b/media/libaaudio/src/flowgraph/SourceI24.cpp
@@ -17,14 +17,14 @@
#include <algorithm>
#include <unistd.h>
+#include "FlowGraphNode.h"
+#include "SourceI24.h"
+
#if FLOWGRAPH_ANDROID_INTERNAL
#include <audio_utils/primitives.h>
#endif
-#include "FlowGraphNode.h"
-#include "SourceI24.h"
-
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
constexpr int kBytesPerI24Packed = 3;
diff --git a/media/libaaudio/src/flowgraph/SourceI24.h b/media/libaaudio/src/flowgraph/SourceI24.h
index 3779534..fb66d4a 100644
--- a/media/libaaudio/src/flowgraph/SourceI24.h
+++ b/media/libaaudio/src/flowgraph/SourceI24.h
@@ -22,7 +22,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
/**
* AudioSource that reads a block of pre-defined 24-bit packed integer data.
@@ -38,6 +38,6 @@
}
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_SOURCE_I24_H
diff --git a/media/libaaudio/src/flowgraph/SourceI32.cpp b/media/libaaudio/src/flowgraph/SourceI32.cpp
index 4b2e8c4..b1c8f75 100644
--- a/media/libaaudio/src/flowgraph/SourceI32.cpp
+++ b/media/libaaudio/src/flowgraph/SourceI32.cpp
@@ -17,14 +17,14 @@
#include <algorithm>
#include <unistd.h>
+#include "FlowGraphNode.h"
+#include "SourceI32.h"
+
#if FLOWGRAPH_ANDROID_INTERNAL
#include <audio_utils/primitives.h>
#endif
-#include "FlowGraphNode.h"
-#include "SourceI32.h"
-
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
SourceI32::SourceI32(int32_t channelCount)
: FlowGraphSourceBuffered(channelCount) {
diff --git a/media/libaaudio/src/flowgraph/SourceI32.h b/media/libaaudio/src/flowgraph/SourceI32.h
index b4e0d7b..7109469 100644
--- a/media/libaaudio/src/flowgraph/SourceI32.h
+++ b/media/libaaudio/src/flowgraph/SourceI32.h
@@ -21,7 +21,7 @@
#include "FlowGraphNode.h"
-namespace flowgraph {
+namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph {
class SourceI32 : public FlowGraphSourceBuffered {
public:
@@ -37,6 +37,6 @@
static constexpr float kScale = 1.0 / (1UL << 31);
};
-} /* namespace flowgraph */
+} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */
#endif //FLOWGRAPH_SOURCE_I32_H
diff --git a/media/libaaudio/src/flowgraph/resampler/HyperbolicCosineWindow.h b/media/libaaudio/src/flowgraph/resampler/HyperbolicCosineWindow.h
index f6479ae..76ec0e7 100644
--- a/media/libaaudio/src/flowgraph/resampler/HyperbolicCosineWindow.h
+++ b/media/libaaudio/src/flowgraph/resampler/HyperbolicCosineWindow.h
@@ -19,7 +19,9 @@
#include <math.h>
-namespace resampler {
+#include "ResamplerDefinitions.h"
+
+namespace RESAMPLER_OUTER_NAMESPACE::resampler {
/**
* Calculate a HyperbolicCosineWindow window centered at 0.
@@ -64,5 +66,6 @@
double mInverseCoshAlpha = 1.0;
};
-} // namespace resampler
+} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */
+
#endif //RESAMPLER_HYPERBOLIC_COSINE_WINDOW_H
diff --git a/media/libaaudio/src/flowgraph/resampler/IntegerRatio.cpp b/media/libaaudio/src/flowgraph/resampler/IntegerRatio.cpp
index 4bd75b3..39e9b24 100644
--- a/media/libaaudio/src/flowgraph/resampler/IntegerRatio.cpp
+++ b/media/libaaudio/src/flowgraph/resampler/IntegerRatio.cpp
@@ -16,7 +16,7 @@
#include "IntegerRatio.h"
-using namespace resampler;
+using namespace RESAMPLER_OUTER_NAMESPACE::resampler;
// Enough primes to cover the common sample rates.
static const int kPrimes[] = {
diff --git a/media/libaaudio/src/flowgraph/resampler/IntegerRatio.h b/media/libaaudio/src/flowgraph/resampler/IntegerRatio.h
index 8c044d8..a6b524c 100644
--- a/media/libaaudio/src/flowgraph/resampler/IntegerRatio.h
+++ b/media/libaaudio/src/flowgraph/resampler/IntegerRatio.h
@@ -14,12 +14,14 @@
* limitations under the License.
*/
-#ifndef OBOE_INTEGER_RATIO_H
-#define OBOE_INTEGER_RATIO_H
+#ifndef RESAMPLER_INTEGER_RATIO_H
+#define RESAMPLER_INTEGER_RATIO_H
#include <sys/types.h>
-namespace resampler {
+#include "ResamplerDefinitions.h"
+
+namespace RESAMPLER_OUTER_NAMESPACE::resampler {
/**
* Represent the ratio of two integers.
@@ -47,6 +49,6 @@
int32_t mDenominator;
};
-} // namespace resampler
+} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */
-#endif //OBOE_INTEGER_RATIO_H
+#endif //RESAMPLER_INTEGER_RATIO_H
diff --git a/media/libaaudio/src/flowgraph/resampler/KaiserWindow.h b/media/libaaudio/src/flowgraph/resampler/KaiserWindow.h
index 73dbc41..f99f9b4 100644
--- a/media/libaaudio/src/flowgraph/resampler/KaiserWindow.h
+++ b/media/libaaudio/src/flowgraph/resampler/KaiserWindow.h
@@ -19,7 +19,9 @@
#include <math.h>
-namespace resampler {
+#include "ResamplerDefinitions.h"
+
+namespace RESAMPLER_OUTER_NAMESPACE::resampler {
/**
* Calculate a Kaiser window centered at 0.
@@ -83,5 +85,6 @@
double mInverseBesselBeta = 1.0;
};
-} // namespace resampler
+} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */
+
#endif //RESAMPLER_KAISER_WINDOW_H
diff --git a/media/libaaudio/src/flowgraph/resampler/LinearResampler.cpp b/media/libaaudio/src/flowgraph/resampler/LinearResampler.cpp
index a7748c1..cb4932a 100644
--- a/media/libaaudio/src/flowgraph/resampler/LinearResampler.cpp
+++ b/media/libaaudio/src/flowgraph/resampler/LinearResampler.cpp
@@ -16,7 +16,7 @@
#include "LinearResampler.h"
-using namespace resampler;
+using namespace RESAMPLER_OUTER_NAMESPACE::resampler;
LinearResampler::LinearResampler(const MultiChannelResampler::Builder &builder)
: MultiChannelResampler(builder) {
diff --git a/media/libaaudio/src/flowgraph/resampler/LinearResampler.h b/media/libaaudio/src/flowgraph/resampler/LinearResampler.h
index 6bde81d..5434379 100644
--- a/media/libaaudio/src/flowgraph/resampler/LinearResampler.h
+++ b/media/libaaudio/src/flowgraph/resampler/LinearResampler.h
@@ -14,15 +14,17 @@
* limitations under the License.
*/
-#ifndef OBOE_LINEAR_RESAMPLER_H
-#define OBOE_LINEAR_RESAMPLER_H
+#ifndef RESAMPLER_LINEAR_RESAMPLER_H
+#define RESAMPLER_LINEAR_RESAMPLER_H
#include <memory>
#include <sys/types.h>
#include <unistd.h>
-#include "MultiChannelResampler.h"
-namespace resampler {
+#include "MultiChannelResampler.h"
+#include "ResamplerDefinitions.h"
+
+namespace RESAMPLER_OUTER_NAMESPACE::resampler {
/**
* Simple resampler that uses bi-linear interpolation.
@@ -40,5 +42,6 @@
std::unique_ptr<float[]> mCurrentFrame;
};
-} // namespace resampler
-#endif //OBOE_LINEAR_RESAMPLER_H
+} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */
+
+#endif //RESAMPLER_LINEAR_RESAMPLER_H
diff --git a/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.cpp b/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.cpp
index d630520..7193ff3 100644
--- a/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.cpp
+++ b/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.cpp
@@ -25,11 +25,12 @@
#include "SincResampler.h"
#include "SincResamplerStereo.h"
-using namespace resampler;
+using namespace RESAMPLER_OUTER_NAMESPACE::resampler;
MultiChannelResampler::MultiChannelResampler(const MultiChannelResampler::Builder &builder)
: mNumTaps(builder.getNumTaps())
- , mX(builder.getChannelCount() * builder.getNumTaps() * 2)
+ , mX(static_cast<size_t>(builder.getChannelCount())
+ * static_cast<size_t>(builder.getNumTaps()) * 2)
, mSingleFrame(builder.getChannelCount())
, mChannelCount(builder.getChannelCount())
{
@@ -110,7 +111,7 @@
if (--mCursor < 0) {
mCursor = getNumTaps() - 1;
}
- float *dest = &mX[mCursor * getChannelCount()];
+ float *dest = &mX[static_cast<size_t>(mCursor) * static_cast<size_t>(getChannelCount())];
int offset = getNumTaps() * getChannelCount();
for (int channel = 0; channel < getChannelCount(); channel++) {
// Write twice so we avoid having to wrap when reading.
@@ -130,7 +131,7 @@
int32_t numRows,
double phaseIncrement,
float normalizedCutoff) {
- mCoefficients.resize(getNumTaps() * numRows);
+ mCoefficients.resize(static_cast<size_t>(getNumTaps()) * static_cast<size_t>(numRows));
int coefficientIndex = 0;
double phase = 0.0; // ranges from 0.0 to 1.0, fraction between samples
// Stretch the sinc function for low pass filtering.
@@ -150,7 +151,7 @@
#if MCR_USE_KAISER
float window = mKaiserWindow(tapPhase * numTapsHalfInverse);
#else
- float window = mCoshWindow(tapPhase * numTapsHalfInverse);
+ float window = mCoshWindow(static_cast<double>(tapPhase) * numTapsHalfInverse);
#endif
float coefficient = sinc(radians * cutoffScaler) * window;
mCoefficients.at(coefficientIndex++) = coefficient;
diff --git a/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.h b/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.h
index da79cad..717f3fd 100644
--- a/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.h
+++ b/media/libaaudio/src/flowgraph/resampler/MultiChannelResampler.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef OBOE_MULTICHANNEL_RESAMPLER_H
-#define OBOE_MULTICHANNEL_RESAMPLER_H
+#ifndef RESAMPLER_MULTICHANNEL_RESAMPLER_H
+#define RESAMPLER_MULTICHANNEL_RESAMPLER_H
#include <memory>
#include <vector>
@@ -34,7 +34,9 @@
#include "HyperbolicCosineWindow.h"
#endif
-namespace resampler {
+#include "ResamplerDefinitions.h"
+
+namespace RESAMPLER_OUTER_NAMESPACE::resampler {
class MultiChannelResampler {
@@ -267,5 +269,6 @@
const int mChannelCount;
};
-} // namespace resampler
-#endif //OBOE_MULTICHANNEL_RESAMPLER_H
+} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */
+
+#endif //RESAMPLER_MULTICHANNEL_RESAMPLER_H
diff --git a/media/libaaudio/src/flowgraph/resampler/PolyphaseResampler.cpp b/media/libaaudio/src/flowgraph/resampler/PolyphaseResampler.cpp
index aa4ffd9..e47ee8e 100644
--- a/media/libaaudio/src/flowgraph/resampler/PolyphaseResampler.cpp
+++ b/media/libaaudio/src/flowgraph/resampler/PolyphaseResampler.cpp
@@ -19,7 +19,7 @@
#include "IntegerRatio.h"
#include "PolyphaseResampler.h"
-using namespace resampler;
+using namespace RESAMPLER_OUTER_NAMESPACE::resampler;
PolyphaseResampler::PolyphaseResampler(const MultiChannelResampler::Builder &builder)
: MultiChannelResampler(builder)
@@ -42,7 +42,7 @@
// Multiply input times windowed sinc function.
float *coefficients = &mCoefficients[mCoefficientCursor];
- float *xFrame = &mX[mCursor * getChannelCount()];
+ float *xFrame = &mX[static_cast<size_t>(mCursor) * static_cast<size_t>(getChannelCount())];
for (int i = 0; i < mNumTaps; i++) {
float coefficient = *coefficients++;
for (int channel = 0; channel < getChannelCount(); channel++) {
diff --git a/media/libaaudio/src/flowgraph/resampler/PolyphaseResampler.h b/media/libaaudio/src/flowgraph/resampler/PolyphaseResampler.h
index 1aeb680..3642fce 100644
--- a/media/libaaudio/src/flowgraph/resampler/PolyphaseResampler.h
+++ b/media/libaaudio/src/flowgraph/resampler/PolyphaseResampler.h
@@ -14,16 +14,18 @@
* limitations under the License.
*/
-#ifndef OBOE_POLYPHASE_RESAMPLER_H
-#define OBOE_POLYPHASE_RESAMPLER_H
+#ifndef RESAMPLER_POLYPHASE_RESAMPLER_H
+#define RESAMPLER_POLYPHASE_RESAMPLER_H
#include <memory>
#include <vector>
#include <sys/types.h>
#include <unistd.h>
-#include "MultiChannelResampler.h"
-namespace resampler {
+#include "MultiChannelResampler.h"
+#include "ResamplerDefinitions.h"
+
+namespace RESAMPLER_OUTER_NAMESPACE::resampler {
/**
* Resampler that is optimized for a reduced ratio of sample rates.
* All of the coefficients for each possible phase value are pre-calculated.
@@ -46,6 +48,6 @@
};
-} // namespace resampler
+} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */
-#endif //OBOE_POLYPHASE_RESAMPLER_H
+#endif //RESAMPLER_POLYPHASE_RESAMPLER_H
diff --git a/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerMono.cpp b/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerMono.cpp
index c0e29b7..fdaf13e 100644
--- a/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerMono.cpp
+++ b/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerMono.cpp
@@ -17,7 +17,7 @@
#include <cassert>
#include "PolyphaseResamplerMono.h"
-using namespace resampler;
+using namespace RESAMPLER_OUTER_NAMESPACE::resampler;
#define MONO 1
diff --git a/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerMono.h b/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerMono.h
index 0a691a3..fe020b5 100644
--- a/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerMono.h
+++ b/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerMono.h
@@ -14,14 +14,16 @@
* limitations under the License.
*/
-#ifndef OBOE_POLYPHASE_RESAMPLER_MONO_H
-#define OBOE_POLYPHASE_RESAMPLER_MONO_H
+#ifndef RESAMPLER_POLYPHASE_RESAMPLER_MONO_H
+#define RESAMPLER_POLYPHASE_RESAMPLER_MONO_H
#include <sys/types.h>
#include <unistd.h>
-#include "PolyphaseResampler.h"
-namespace resampler {
+#include "PolyphaseResampler.h"
+#include "ResamplerDefinitions.h"
+
+namespace RESAMPLER_OUTER_NAMESPACE::resampler {
class PolyphaseResamplerMono : public PolyphaseResampler {
public:
@@ -34,6 +36,6 @@
void readFrame(float *frame) override;
};
-} // namespace resampler
+} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */
-#endif //OBOE_POLYPHASE_RESAMPLER_MONO_H
+#endif //RESAMPLER_POLYPHASE_RESAMPLER_MONO_H
diff --git a/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp b/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp
index e4bef74..b381851 100644
--- a/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp
+++ b/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp
@@ -17,7 +17,7 @@
#include <cassert>
#include "PolyphaseResamplerStereo.h"
-using namespace resampler;
+using namespace RESAMPLER_OUTER_NAMESPACE::resampler;
#define STEREO 2
diff --git a/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerStereo.h b/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerStereo.h
index e608483..ee4caba 100644
--- a/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerStereo.h
+++ b/media/libaaudio/src/flowgraph/resampler/PolyphaseResamplerStereo.h
@@ -14,14 +14,16 @@
* limitations under the License.
*/
-#ifndef OBOE_POLYPHASE_RESAMPLER_STEREO_H
-#define OBOE_POLYPHASE_RESAMPLER_STEREO_H
+#ifndef RESAMPLER_POLYPHASE_RESAMPLER_STEREO_H
+#define RESAMPLER_POLYPHASE_RESAMPLER_STEREO_H
#include <sys/types.h>
#include <unistd.h>
-#include "PolyphaseResampler.h"
-namespace resampler {
+#include "PolyphaseResampler.h"
+#include "ResamplerDefinitions.h"
+
+namespace RESAMPLER_OUTER_NAMESPACE::resampler {
class PolyphaseResamplerStereo : public PolyphaseResampler {
public:
@@ -34,6 +36,6 @@
void readFrame(float *frame) override;
};
-} // namespace resampler
+} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */
-#endif //OBOE_POLYPHASE_RESAMPLER_STEREO_H
+#endif //RESAMPLER_POLYPHASE_RESAMPLER_STEREO_H
diff --git a/media/libaaudio/src/flowgraph/resampler/README.md b/media/libaaudio/src/flowgraph/resampler/README.md
index 05d8a89..ea319c7 100644
--- a/media/libaaudio/src/flowgraph/resampler/README.md
+++ b/media/libaaudio/src/flowgraph/resampler/README.md
@@ -5,6 +5,17 @@
The converter is based on a sinc function that has been windowed by a hyperbolic cosine.
We found this had fewer artifacts than the more traditional Kaiser window.
+## Building the Resampler
+
+It is part of [Oboe](https://github.com/google/oboe) but has no dependencies on Oboe.
+So the contents of this folder can be used outside of Oboe.
+
+To build it for use outside of Oboe:
+
+1. Copy the "resampler" folder to a folder in your project that is in the include path.
+2. Add all of the \*.cpp files in the resampler folder to your project IDE or Makefile.
+3. In ResamplerDefinitions.h, define RESAMPLER_OUTER_NAMESPACE with your own project name. Alternatively, use -DRESAMPLER_OUTER_NAMESPACE=mynamespace when compiling to avoid modifying the resampler code.
+
## Creating a Resampler
Include the [main header](MultiChannelResampler.h) for the resampler.
@@ -88,4 +99,3 @@
When you are done, you should delete the Resampler to avoid a memory leak.
delete resampler;
-
diff --git a/media/libaaudio/src/flowgraph/resampler/ResamplerDefinitions.h b/media/libaaudio/src/flowgraph/resampler/ResamplerDefinitions.h
new file mode 100644
index 0000000..c6791ec
--- /dev/null
+++ b/media/libaaudio/src/flowgraph/resampler/ResamplerDefinitions.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2022 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.
+ */
+
+// Set flag RESAMPLER_OUTER_NAMESPACE based on whether compiler flag
+// __ANDROID_NDK__ is defined. __ANDROID_NDK__ should be defined in oboe
+// but not in android.
+
+#ifndef RESAMPLER_OUTER_NAMESPACE
+#ifdef __ANDROID_NDK__
+#define RESAMPLER_OUTER_NAMESPACE oboe
+#else
+#define RESAMPLER_OUTER_NAMESPACE aaudio
+#endif // __ANDROID_NDK__
+#endif // RESAMPLER_OUTER_NAMESPACE
diff --git a/media/libaaudio/src/flowgraph/resampler/SincResampler.cpp b/media/libaaudio/src/flowgraph/resampler/SincResampler.cpp
index 5e8a9e0..42d0ca2 100644
--- a/media/libaaudio/src/flowgraph/resampler/SincResampler.cpp
+++ b/media/libaaudio/src/flowgraph/resampler/SincResampler.cpp
@@ -18,7 +18,7 @@
#include <math.h>
#include "SincResampler.h"
-using namespace resampler;
+using namespace RESAMPLER_OUTER_NAMESPACE::resampler;
SincResampler::SincResampler(const MultiChannelResampler::Builder &builder)
: MultiChannelResampler(builder)
@@ -52,10 +52,12 @@
index2 -= mNumRows;
}
- float *coefficients1 = &mCoefficients[index1 * getNumTaps()];
- float *coefficients2 = &mCoefficients[index2 * getNumTaps()];
+ float *coefficients1 = &mCoefficients[static_cast<size_t>(index1)
+ * static_cast<size_t>(getNumTaps())];
+ float *coefficients2 = &mCoefficients[static_cast<size_t>(index2)
+ * static_cast<size_t>(getNumTaps())];
- float *xFrame = &mX[mCursor * getChannelCount()];
+ float *xFrame = &mX[static_cast<size_t>(mCursor) * static_cast<size_t>(getChannelCount())];
for (int i = 0; i < mNumTaps; i++) {
float coefficient1 = *coefficients1++;
float coefficient2 = *coefficients2++;
diff --git a/media/libaaudio/src/flowgraph/resampler/SincResampler.h b/media/libaaudio/src/flowgraph/resampler/SincResampler.h
index b235188..05ff092 100644
--- a/media/libaaudio/src/flowgraph/resampler/SincResampler.h
+++ b/media/libaaudio/src/flowgraph/resampler/SincResampler.h
@@ -14,15 +14,17 @@
* limitations under the License.
*/
-#ifndef OBOE_SINC_RESAMPLER_H
-#define OBOE_SINC_RESAMPLER_H
+#ifndef RESAMPLER_SINC_RESAMPLER_H
+#define RESAMPLER_SINC_RESAMPLER_H
#include <memory>
#include <sys/types.h>
#include <unistd.h>
-#include "MultiChannelResampler.h"
-namespace resampler {
+#include "MultiChannelResampler.h"
+#include "ResamplerDefinitions.h"
+
+namespace RESAMPLER_OUTER_NAMESPACE::resampler {
/**
* Resampler that can interpolate between coefficients.
@@ -43,5 +45,6 @@
double mPhaseScaler = 1.0;
};
-} // namespace resampler
-#endif //OBOE_SINC_RESAMPLER_H
+} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */
+
+#endif //RESAMPLER_SINC_RESAMPLER_H
diff --git a/media/libaaudio/src/flowgraph/resampler/SincResamplerStereo.cpp b/media/libaaudio/src/flowgraph/resampler/SincResamplerStereo.cpp
index ce00302..432137e 100644
--- a/media/libaaudio/src/flowgraph/resampler/SincResamplerStereo.cpp
+++ b/media/libaaudio/src/flowgraph/resampler/SincResamplerStereo.cpp
@@ -19,7 +19,7 @@
#include "SincResamplerStereo.h"
-using namespace resampler;
+using namespace RESAMPLER_OUTER_NAMESPACE::resampler;
#define STEREO 2
@@ -54,13 +54,15 @@
// Determine indices into coefficients table.
double tablePhase = getIntegerPhase() * mPhaseScaler;
int index1 = static_cast<int>(floor(tablePhase));
- float *coefficients1 = &mCoefficients[index1 * getNumTaps()];
+ float *coefficients1 = &mCoefficients[static_cast<size_t>(index1)
+ * static_cast<size_t>(getNumTaps())];
int index2 = (index1 + 1);
if (index2 >= mNumRows) { // no guard row needed because we wrap the indices
index2 = 0;
}
- float *coefficients2 = &mCoefficients[index2 * getNumTaps()];
- float *xFrame = &mX[mCursor * getChannelCount()];
+ float *coefficients2 = &mCoefficients[static_cast<size_t>(index2)
+ * static_cast<size_t>(getNumTaps())];
+ float *xFrame = &mX[static_cast<size_t>(mCursor) * static_cast<size_t>(getChannelCount())];
for (int i = 0; i < mNumTaps; i++) {
float coefficient1 = *coefficients1++;
float coefficient2 = *coefficients2++;
diff --git a/media/libaaudio/src/flowgraph/resampler/SincResamplerStereo.h b/media/libaaudio/src/flowgraph/resampler/SincResamplerStereo.h
index 7d49ec7..d5576d1 100644
--- a/media/libaaudio/src/flowgraph/resampler/SincResamplerStereo.h
+++ b/media/libaaudio/src/flowgraph/resampler/SincResamplerStereo.h
@@ -14,14 +14,16 @@
* limitations under the License.
*/
-#ifndef OBOE_SINC_RESAMPLER_STEREO_H
-#define OBOE_SINC_RESAMPLER_STEREO_H
+#ifndef RESAMPLER_SINC_RESAMPLER_STEREO_H
+#define RESAMPLER_SINC_RESAMPLER_STEREO_H
#include <sys/types.h>
#include <unistd.h>
-#include "SincResampler.h"
-namespace resampler {
+#include "SincResampler.h"
+#include "ResamplerDefinitions.h"
+
+namespace RESAMPLER_OUTER_NAMESPACE::resampler {
class SincResamplerStereo : public SincResampler {
public:
@@ -35,5 +37,6 @@
};
-} // namespace resampler
-#endif //OBOE_SINC_RESAMPLER_STEREO_H
+} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */
+
+#endif //RESAMPLER_SINC_RESAMPLER_STEREO_H
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index 4b42203..872faca 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -562,7 +562,9 @@
int32_t AAudioProperty_getMinimumSleepMicros() {
const int32_t minMicros = 1; // arbitrary
// Higher values can increase latency for moderate workloads.
- const int32_t defaultMicros = 1; // arbitrary
+ // Short values can cause the CPU to short cycle if there is a bug in
+ // calculating the wakeup times.
+ const int32_t defaultMicros = 100; // arbitrary
const int32_t maxMicros = 200; // arbitrary
int32_t prop = property_get_int32(AAUDIO_PROP_MINIMUM_SLEEP_USEC, defaultMicros);
if (prop < minMicros) {
diff --git a/media/libaaudio/tests/test_flowgraph.cpp b/media/libaaudio/tests/test_flowgraph.cpp
index e322791..913feb0 100644
--- a/media/libaaudio/tests/test_flowgraph.cpp
+++ b/media/libaaudio/tests/test_flowgraph.cpp
@@ -33,7 +33,7 @@
#include "flowgraph/SourceI16.h"
#include "flowgraph/SourceI24.h"
-using namespace flowgraph;
+using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph;
constexpr int kBytesPerI24Packed = 3;
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index e890e97..69a9c68 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -345,7 +345,7 @@
"aidl/android/media/TrackSecondaryOutputInfo.aidl",
],
imports: [
- "android.media.audio.common.types",
+ "android.media.audio.common.types-V1",
"framework-permission-aidl",
],
backend: {
@@ -389,7 +389,7 @@
"aidl/android/media/SpatializerHeadTrackingMode.aidl",
],
imports: [
- "android.media.audio.common.types",
+ "android.media.audio.common.types-V1",
"audioclient-types-aidl",
],
backend: {
@@ -432,7 +432,7 @@
"aidl/android/media/IAudioTrackCallback.aidl",
],
imports: [
- "android.media.audio.common.types",
+ "android.media.audio.common.types-V1",
"audioclient-types-aidl",
"av-types-aidl",
"effect-aidl",
@@ -469,7 +469,7 @@
"aidl/android/media/IAudioPolicyServiceClient.aidl",
],
imports: [
- "android.media.audio.common.types",
+ "android.media.audio.common.types-V1",
"audioclient-types-aidl",
"audiopolicy-types-aidl",
"capture_state_listener-aidl",
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 50a3f0d..2a75342 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1460,9 +1460,14 @@
if (mDomain == DOMAIN_VIDEO) {
// video codec needs dedicated looper
if (mCodecLooper == NULL) {
+ status_t err = OK;
mCodecLooper = new ALooper;
mCodecLooper->setName("CodecLooper");
- mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
+ err = mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
+ if (OK != err) {
+ ALOGE("Codec Looper failed to start");
+ return err;
+ }
}
mCodecLooper->registerHandler(mCodec);
@@ -3048,8 +3053,9 @@
CHECK(msg->findInt32("err", &err));
CHECK(msg->findInt32("actionCode", &actionCode));
- ALOGE("Codec reported err %#x, actionCode %d, while in state %d/%s",
- err, actionCode, mState, stateString(mState).c_str());
+ ALOGE("Codec reported err %#x/%s, actionCode %d, while in state %d/%s",
+ err, StrMediaError(err).c_str(), actionCode,
+ mState, stateString(mState).c_str());
if (err == DEAD_OBJECT) {
mFlags |= kFlagSawMediaServerDie;
mFlags &= ~kFlagIsComponentAllocated;
diff --git a/media/libstagefright/include/media/stagefright/MediaErrors.h b/media/libstagefright/include/media/stagefright/MediaErrors.h
index d1df2ca..b91c850 100644
--- a/media/libstagefright/include/media/stagefright/MediaErrors.h
+++ b/media/libstagefright/include/media/stagefright/MediaErrors.h
@@ -163,11 +163,28 @@
|| (ERROR_DRM_VENDOR_MIN <= err && err <= ERROR_DRM_VENDOR_MAX);
}
-static inline std::string StrCryptoError(status_t err) {
#define STATUS_CASE(STATUS) \
case STATUS: \
return #STATUS
+static inline std::string StrMediaError(status_t err) {
+ switch(err) {
+ STATUS_CASE(ERROR_ALREADY_CONNECTED);
+ STATUS_CASE(ERROR_NOT_CONNECTED);
+ STATUS_CASE(ERROR_UNKNOWN_HOST);
+ STATUS_CASE(ERROR_CANNOT_CONNECT);
+ STATUS_CASE(ERROR_IO);
+ STATUS_CASE(ERROR_CONNECTION_LOST);
+ STATUS_CASE(ERROR_MALFORMED);
+ STATUS_CASE(ERROR_OUT_OF_RANGE);
+ STATUS_CASE(ERROR_BUFFER_TOO_SMALL);
+ STATUS_CASE(ERROR_UNSUPPORTED);
+ STATUS_CASE(ERROR_END_OF_STREAM);
+ }
+ return statusToString(err);
+}
+
+static inline std::string StrCryptoError(status_t err) {
switch (err) {
STATUS_CASE(ERROR_DRM_UNKNOWN);
STATUS_CASE(ERROR_DRM_NO_LICENSE);
@@ -209,10 +226,10 @@
STATUS_CASE(ERROR_DRM_STORAGE_READ);
STATUS_CASE(ERROR_DRM_STORAGE_WRITE);
STATUS_CASE(ERROR_DRM_ZERO_SUBSAMPLES);
-#undef STATUS_CASE
}
return statusToString(err);
}
+#undef STATUS_CASE
} // namespace android
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index 6f25cec..38e422d 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -277,8 +277,8 @@
break;
}
msg->findString("detail", &detail);
- ALOGE("Codec reported error(0x%x), actionCode(%d), detail(%s)",
- err, actionCode, detail.c_str());
+ ALOGE("Codec reported error(0x%x/%s), actionCode(%d), detail(%s)",
+ err, StrMediaError(err).c_str(), actionCode, detail.c_str());
Mutex::Autolock _l(mCodec->mAsyncCallbackLock);
if (mCodec->mAsyncCallback.onAsyncError != NULL) {
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index 3b079c6..a38ef57 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -33,9 +33,11 @@
"MediaUtilsDelayed.cpp",
"MemoryLeakTrackUtil.cpp",
"MethodStatistics.cpp",
+ "Process.cpp",
"ProcessInfo.cpp",
"SchedulingPolicyService.cpp",
"ServiceUtilities.cpp",
+ "ThreadSnapshot.cpp",
"TimeCheck.cpp",
"TimerThread.cpp",
],
diff --git a/media/utils/Process.cpp b/media/utils/Process.cpp
new file mode 100644
index 0000000..8fe8003
--- /dev/null
+++ b/media/utils/Process.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 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 "Process"
+#include <utils/Log.h>
+#include <mediautils/Process.h>
+
+#include <android-base/file.h>
+#include <android-base/strings.h>
+#include <cstdlib>
+
+namespace {
+
+void processLine(std::string_view s, std::map<std::string, double>& m) {
+ if (s.empty()) return;
+
+ const size_t colon_pos = s.find(':');
+ if (colon_pos == std::string_view::npos) return;
+
+ const size_t space_pos = s.find(' ');
+ if (space_pos == 0 || space_pos == std::string_view::npos || space_pos > colon_pos) return;
+ std::string key(s.data(), s.data() + space_pos);
+
+ const size_t value_pos = s.find_first_not_of(' ', colon_pos + 1);
+ if (value_pos == std::string_view::npos) return;
+
+ const double value = strtod(s.data() + value_pos, nullptr /* end */);
+ m[std::move(key)] = value;
+}
+
+} // namespace
+
+namespace android::mediautils {
+
+std::string getThreadSchedAsString(pid_t tid) {
+ const pid_t pid = getpid();
+ const std::string path = std::string("/proc/").append(std::to_string(pid))
+ .append("/task/").append(std::to_string(tid)).append("/sched");
+ std::string sched;
+ (void)android::base::ReadFileToString(path.c_str(), &sched);
+ return sched;
+}
+
+std::map<std::string, double> parseThreadSchedString(const std::string& schedString) {
+ std::map<std::string, double> m;
+ if (schedString.empty()) return m;
+ std::vector<std::string> stringlist = android::base::Split(schedString, "\n");
+
+ // OK we use values not strings... m["summary"] = stringlist[0];
+ for (size_t i = 2; i < stringlist.size(); ++i) {
+ processLine(stringlist[i], m);
+ }
+ return m;
+}
+
+} // namespace android::mediautils
diff --git a/media/utils/ThreadSnapshot.cpp b/media/utils/ThreadSnapshot.cpp
new file mode 100644
index 0000000..382738e
--- /dev/null
+++ b/media/utils/ThreadSnapshot.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2022 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 "ThreadSnapshot"
+#include <utils/Log.h>
+#include <utils/Timers.h>
+#include <mediautils/ThreadSnapshot.h>
+
+#include <mediautils/Process.h>
+
+namespace android::mediautils {
+
+pid_t ThreadSnapshot::getTid() const {
+ std::lock_guard lg(mLock);
+ return mState.mTid;
+}
+
+void ThreadSnapshot::setTid(pid_t tid) {
+ std::lock_guard lg(mLock);
+ if (mState.mTid == tid) return;
+ mState.reset(tid);
+}
+
+void ThreadSnapshot::reset() {
+ std::lock_guard lg(mLock);
+ mState.reset(mState.mTid);
+}
+
+void ThreadSnapshot::onBegin() {
+ std::string sched = getThreadSchedAsString(getTid()); // tid could race here,
+ // accept as benign.
+ std::lock_guard lg(mLock);
+ mState.onBegin(std::move(sched));
+}
+
+void ThreadSnapshot::onEnd() {
+ std::lock_guard lg(mLock);
+ mState.onEnd();
+}
+
+std::string ThreadSnapshot::toString() const {
+ // Make a local copy of the stats data under lock.
+ State state;
+ {
+ std::lock_guard lg(mLock);
+ state = mState;
+ }
+ return state.toString();
+}
+
+void ThreadSnapshot::State::reset(pid_t tid) {
+ mTid = tid;
+ mBeginTimeNs = -2;
+ mEndTimeNs = -1;
+ mCumulativeTimeNs = 0;
+ mBeginSched.clear();
+}
+
+void ThreadSnapshot::State::onBegin(std::string sched) {
+ if (mBeginTimeNs < mEndTimeNs) {
+ mBeginTimeNs = systemTime();
+ mBeginSched = std::move(sched);
+ }
+}
+
+void ThreadSnapshot::State::onEnd() {
+ if (mEndTimeNs < mBeginTimeNs) {
+ mEndTimeNs = systemTime();
+ mCumulativeTimeNs += mEndTimeNs - mBeginTimeNs;
+ }
+}
+
+std::string ThreadSnapshot::State::toString() const {
+ if (mBeginTimeNs < 0) return {}; // never begun.
+
+ // compute time intervals.
+ const int64_t nowNs = systemTime();
+ int64_t cumulativeTimeNs = mCumulativeTimeNs;
+ int64_t diffNs = mEndTimeNs - mBeginTimeNs; // if onEnd() isn't matched, diffNs < 0.
+ if (diffNs < 0) {
+ diffNs = nowNs - mBeginTimeNs;
+ cumulativeTimeNs += diffNs;
+ }
+ // normalization for rate variables
+ const double lastRunPerSec = 1e9 / diffNs;
+ const double totalPerSec = 1e9 / cumulativeTimeNs;
+
+ // HANDLE THE SCHEDULER STATISTICS HERE
+ // current and differential statistics for the scheduler.
+ std::string schedNow = getThreadSchedAsString(mTid);
+ const auto schedMapThen = parseThreadSchedString(mBeginSched);
+ const auto schedMapNow = parseThreadSchedString(schedNow);
+ static const char * schedDiffKeyList[] = {
+ "se.sum_exec_runtime",
+ "se.nr_migrations",
+ "se.statistics.wait_sum",
+ "se.statistics.wait_count",
+ "se.statistics.iowait_sum",
+ "se.statistics.iowait_count",
+ "se.statistics.nr_forced_migrations",
+ "nr_involuntary_switches",
+ };
+
+ // compute differential rate statistics.
+ std::string diffString;
+ for (const auto diffKey : schedDiffKeyList) {
+ if (auto itThen = schedMapThen.find(diffKey);
+ itThen != schedMapThen.end()) {
+
+ if (auto itNow = schedMapNow.find(diffKey);
+ itNow != schedMapNow.end()) {
+ auto diff = itNow->second - itThen->second;
+ diff *= lastRunPerSec;
+ auto total = itNow->second * totalPerSec;
+ diffString.append(diffKey).append(" last-run:")
+ .append(std::to_string(diff))
+ .append(" cumulative:")
+ .append(std::to_string(total))
+ .append("\n");
+ }
+ }
+ }
+
+ if (!diffString.empty()) {
+ schedNow.append("*** per second stats ***\n").append(diffString);
+ }
+
+ // Return snapshot string.
+ return schedNow;
+}
+
+} // android::mediautils
diff --git a/media/utils/include/mediautils/Process.h b/media/utils/include/mediautils/Process.h
new file mode 100644
index 0000000..d249c3a
--- /dev/null
+++ b/media/utils/include/mediautils/Process.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2022 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 <map>
+#include <string>
+#include <unistd.h>
+
+/*
+ * This header contains utilities to read the linux system /proc/pid files
+ *
+ * The format of this is not guaranteed to be stable, so use for diagnostic purposes only.
+ *
+ * The linux "proc" directory documentation:
+ * https://kernel.org/doc/Documentation/filesystems/proc.txt
+ * https://www.kernel.org/doc/html/latest/filesystems/proc.html?highlight=proc%20pid#chapter-3-per-process-parameters
+ */
+
+namespace android::mediautils {
+
+/**
+ * Return the thread schedule information for tid.
+ *
+ * String will be empty if the process does not have permission to
+ * access the /proc/pid tables, or if not on a Linux device.
+ *
+ * Linux scheduler documentation:
+ * https://www.kernel.org/doc/html/latest/scheduler/index.html
+ * https://man7.org/linux/man-pages/man7/sched.7.html
+ *
+ * Sample as follows:
+
+AudioOut_8D (10800, #threads: 36)
+-------------------------------------------------------------------
+se.exec_start : 8132077.598026
+se.vruntime : 798689.872087
+se.sum_exec_runtime : 136466.957838
+se.nr_migrations : 132487
+se.statistics.sum_sleep_runtime : 5629794.565945
+se.statistics.wait_start : 0.000000
+se.statistics.sleep_start : 8195727.586392
+se.statistics.block_start : 0.000000
+se.statistics.sleep_max : 1995665.869808
+se.statistics.block_max : 0.591675
+se.statistics.exec_max : 2.477580
+se.statistics.slice_max : 0.000000
+se.statistics.wait_max : 8.608642
+se.statistics.wait_sum : 4683.266835
+se.statistics.wait_count : 300964
+se.statistics.iowait_sum : 0.000000
+se.statistics.iowait_count : 0
+se.statistics.nr_migrations_cold : 0
+se.statistics.nr_failed_migrations_affine : 297
+se.statistics.nr_failed_migrations_running : 1412
+se.statistics.nr_failed_migrations_hot : 96
+se.statistics.nr_forced_migrations : 26
+se.statistics.nr_wakeups : 281263
+se.statistics.nr_wakeups_sync : 84
+se.statistics.nr_wakeups_migrate : 132322
+se.statistics.nr_wakeups_local : 2165
+se.statistics.nr_wakeups_remote : 279098
+se.statistics.nr_wakeups_affine : 0
+se.statistics.nr_wakeups_affine_attempts : 0
+se.statistics.nr_wakeups_passive : 0
+se.statistics.nr_wakeups_idle : 0
+avg_atom : 0.453434
+avg_per_cpu : 1.030040
+nr_switches : 300963
+nr_voluntary_switches : 281252
+nr_involuntary_switches : 19711
+se.load.weight : 73477120
+se.avg.load_sum : 58
+se.avg.runnable_sum : 27648
+se.avg.util_sum : 21504
+se.avg.load_avg : 48
+se.avg.runnable_avg : 0
+se.avg.util_avg : 0
+se.avg.last_update_time : 8132075824128
+se.avg.util_est.ewma : 8
+se.avg.util_est.enqueued : 1
+uclamp.min : 0
+uclamp.max : 1024
+effective uclamp.min : 0
+effective uclamp.max : 1024
+policy : 0
+prio : 101
+clock-delta : 163
+*/
+std::string getThreadSchedAsString(pid_t tid);
+
+/**
+ * Returns map for the raw thread schedule string.
+ */
+std::map<std::string, double> parseThreadSchedString(const std::string& schedString);
+
+/**
+ * Returns map for /proc/pid/task/tid/sched
+ */
+inline std::map<std::string, double> getThreadSchedAsMap(pid_t tid) {
+ return parseThreadSchedString(getThreadSchedAsString(tid));
+}
+
+// TODO: Extend to other /proc/pid file information.
+//
+// See "ps" command get_ps().
+// https://cs.android.com/android/platform/superproject/+/master:external/toybox/toys/posix/ps.c;l=707
+
+} // android::mediautils
diff --git a/media/utils/include/mediautils/ThreadSnapshot.h b/media/utils/include/mediautils/ThreadSnapshot.h
new file mode 100644
index 0000000..c470822
--- /dev/null
+++ b/media/utils/include/mediautils/ThreadSnapshot.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2022 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 <string>
+
+#include <android-base/thread_annotations.h>
+
+namespace android::mediautils {
+
+/**
+ * Collect Thread performance statistics.
+ *
+ * An onBegin() and onEnd() signal a continuous "run".
+ * Statistics are returned by toString().
+ */
+class ThreadSnapshot {
+public:
+ explicit ThreadSnapshot(pid_t tid = -1) { mState.reset(tid); };
+
+ // Returns current tid
+ pid_t getTid() const;
+
+ // Sets the tid
+ void setTid(pid_t tid);
+
+ // Reset statistics, keep same tid.
+ void reset();
+
+ // Signal a timing run is beginning
+ void onBegin();
+
+ // Signal a timing run is ending
+ void onEnd();
+
+ // Return the thread snapshot statistics in a string
+ std::string toString() const;
+
+private:
+ mutable std::mutex mLock;
+
+ // State represents our statistics at a given point in time.
+ // It is not thread-safe, so any locking must occur at the caller.
+ struct State {
+ pid_t mTid;
+ int64_t mBeginTimeNs; // when last run began
+ int64_t mEndTimeNs; // when last run ends (if less than begin time, not started)
+ int64_t mCumulativeTimeNs;
+
+ // Sched is the scheduler statistics obtained as a string.
+ // This is parsed only when toString() is called.
+ std::string mBeginSched;
+
+ // Clears existing state.
+ void reset(pid_t tid);
+
+ // onBegin() takes a std::string sched should can be captured outside
+ // of locking.
+ void onBegin(std::string sched);
+ void onEnd();
+ std::string toString() const;
+ };
+
+ // Our current state. We only keep the current running state.
+ State mState GUARDED_BY(mLock);
+};
+
+} // android::mediautils
diff --git a/media/utils/tests/Android.bp b/media/utils/tests/Android.bp
index 30c10b7..a6f408d 100644
--- a/media/utils/tests/Android.bp
+++ b/media/utils/tests/Android.bp
@@ -64,6 +64,26 @@
}
cc_test {
+ name: "media_process_tests",
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+
+ shared_libs: [
+ "liblog",
+ "libmediautils",
+ "libutils",
+ ],
+
+ srcs: [
+ "media_process_tests.cpp",
+ ],
+}
+
+cc_test {
name: "media_synchronization_tests",
cflags: [
@@ -84,6 +104,26 @@
}
cc_test {
+ name: "media_threadsnapshot_tests",
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+
+ shared_libs: [
+ "liblog",
+ "libmediautils",
+ "libutils",
+ ],
+
+ srcs: [
+ "media_threadsnapshot_tests.cpp",
+ ],
+}
+
+cc_test {
name: "methodstatistics_tests",
cflags: [
diff --git a/media/utils/tests/media_process_tests.cpp b/media/utils/tests/media_process_tests.cpp
new file mode 100644
index 0000000..2ae3f70
--- /dev/null
+++ b/media/utils/tests/media_process_tests.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2022 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 <mediautils/Process.h>
+
+#define LOG_TAG "media_process_tests"
+
+#include <gtest/gtest.h>
+#include <utils/Log.h>
+
+using namespace android;
+using namespace android::mediautils;
+
+TEST(media_process_tests, basic) {
+ const std::string schedString = getThreadSchedAsString(gettid());
+
+ (void)schedString;
+ // We don't test schedString, only that we haven't crashed.
+ // ASSERT_FALSE(schedString.empty());
+
+ // schedString is not normative. So we conjure up our own string
+ const std::string fakeString = "\
+AudioOut_8D (10800, #threads: 36)\n\
+-------------------------------------------------------------------\n\
+se.exec_start : 8132077.598026\n\
+se.vruntime : 798689.872087\n\
+se.sum_exec_runtime : 136466.957838\n\
+se.nr_migrations : 132487\n\
+se.statistics.sum_sleep_runtime : 5629794.565945\n\
+se.statistics.wait_start : 0.000000\n\
+se.statistics.sleep_start : 8195727.586392\n\
+se.statistics.block_start : 0.000000\n\
+se.statistics.sleep_max : 1995665.869808\n\
+se.statistics.block_max : 0.591675\n\
+se.statistics.exec_max : 2.477580\n\
+se.statistics.slice_max : 0.000000\n\
+se.statistics.wait_max : 8.608642\n\
+se.statistics.wait_sum : 4683.266835\n\
+se.statistics.wait_count : 300964\n\
+se.statistics.iowait_sum : 0.000000\n\
+se.statistics.iowait_count : 0\n\
+se.statistics.nr_migrations_cold : 0\n\
+se.statistics.nr_failed_migrations_affine : 297\n\
+se.statistics.nr_failed_migrations_running : 1412\n\
+se.statistics.nr_failed_migrations_hot : 96\n\
+se.statistics.nr_forced_migrations : 26\n\
+se.statistics.nr_wakeups : 281263\n\
+se.statistics.nr_wakeups_sync : 84\n\
+se.statistics.nr_wakeups_migrate : 132322\n\
+se.statistics.nr_wakeups_local : 2165\n\
+se.statistics.nr_wakeups_remote : 279098\n\
+se.statistics.nr_wakeups_affine : 0\n\
+se.statistics.nr_wakeups_affine_attempts : 0\n\
+se.statistics.nr_wakeups_passive : 0\n\
+se.statistics.nr_wakeups_idle : 0\n\
+avg_atom : 0.453434\n\
+avg_per_cpu : 1.030040\n\
+nr_switches : 300963\n\
+nr_voluntary_switches : 281252\n\
+nr_involuntary_switches : 19711\n\
+se.load.weight : 73477120\n\
+se.avg.load_sum : 58\n\
+se.avg.runnable_sum : 27648\n\
+se.avg.util_sum : 21504\n\
+se.avg.load_avg : 48\n\
+se.avg.runnable_avg : 0\n\
+se.avg.util_avg : 0\n\
+se.avg.last_update_time : 8132075824128\n\
+se.avg.util_est.ewma : 8\n\
+se.avg.util_est.enqueued : 1\n\
+uclamp.min : 0\n\
+uclamp.max : 1024\n\
+effective uclamp.min : 0\n\
+effective uclamp.max : 1024\n\
+policy : 0\n\
+prio : 101\n\
+clock-delta : 163";
+
+ std::map<std::string, double> m = parseThreadSchedString(fakeString);
+
+ auto it = m.find("clock-delta");
+ ASSERT_NE(it, m.end());
+ ASSERT_EQ(it->second, 163);
+
+ it = m.find("se.avg.load_avg");
+ ASSERT_NE(it, m.end());
+ ASSERT_EQ(it->second, 48);
+}
diff --git a/media/utils/tests/media_threadsnapshot_tests.cpp b/media/utils/tests/media_threadsnapshot_tests.cpp
new file mode 100644
index 0000000..c7a45e2
--- /dev/null
+++ b/media/utils/tests/media_threadsnapshot_tests.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 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 <mediautils/ThreadSnapshot.h>
+
+#define LOG_TAG "media_threadsnapshot_tests"
+
+#include <gtest/gtest.h>
+#include <utils/Log.h>
+
+#include <chrono>
+#include <thread>
+
+using namespace android;
+using namespace android::mediautils;
+
+TEST(media_threadsnapshot_tests, basic) {
+ using namespace std::chrono_literals;
+
+ ThreadSnapshot threadSnapshot(gettid());
+
+ threadSnapshot.onBegin();
+
+ std::string snapshot1 = threadSnapshot.toString();
+
+ std::this_thread::sleep_for(100ms);
+
+ threadSnapshot.onEnd();
+
+ std::string snapshot2 = threadSnapshot.toString();
+
+ // Either we can't get a snapshot, or they must be different when taken when thread is running.
+ if (snapshot1.empty()) {
+ ASSERT_TRUE(snapshot2.empty());
+ } else {
+ ASSERT_FALSE(snapshot2.empty());
+ ASSERT_NE(snapshot1, snapshot2);
+ }
+}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 59f22eb..8e4383c 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -76,6 +76,7 @@
#include <media/VolumeShaper.h>
#include <mediautils/ServiceUtilities.h>
#include <mediautils/Synchronization.h>
+#include <mediautils/ThreadSnapshot.h>
#include <audio_utils/clock.h>
#include <audio_utils/FdToString.h>
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 0f27f90..9344e20 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -65,6 +65,7 @@
#include <media/nbaio/PipeReader.h>
#include <media/nbaio/SourceAudioBufferProvider.h>
#include <mediautils/BatteryNotifier.h>
+#include <mediautils/Process.h>
#include <audiomanager/AudioManager.h>
#include <powermanager/PowerManager.h>
@@ -923,6 +924,20 @@
dprintf(fd, " Local log:\n");
mLocalLog.dump(fd, " " /* prefix */, 40 /* lines */);
+
+ // --all does the statistics
+ bool dumpAll = false;
+ for (const auto &arg : args) {
+ if (arg == String16("--all")) {
+ dumpAll = true;
+ }
+ }
+ if (dumpAll || type() == SPATIALIZER) {
+ const std::string sched = mThreadSnapshot.toString();
+ if (!sched.empty()) {
+ (void)write(fd, sched.c_str(), sched.size());
+ }
+ }
}
void AudioFlinger::ThreadBase::dumpBase_l(int fd, const Vector<String16>& args __unused)
@@ -2098,6 +2113,7 @@
}
}
run(mThreadName, ANDROID_PRIORITY_URGENT_AUDIO);
+ mThreadSnapshot.setTid(getTid());
}
// ThreadBase virtuals
@@ -3339,6 +3355,7 @@
mInWrite = false;
if (mStandby) {
mThreadMetrics.logBeginInterval();
+ mThreadSnapshot.onBegin();
mStandby = false;
}
return bytesWritten;
@@ -3824,6 +3841,7 @@
if (!mStandby) {
LOG_AUDIO_STATE();
mThreadMetrics.logEndInterval();
+ mThreadSnapshot.onEnd();
mStandby = true;
}
sendStatistics(false /* force */);
@@ -5959,6 +5977,7 @@
mOutput->standby();
if (!mStandby) {
mThreadMetrics.logEndInterval();
+ mThreadSnapshot.onEnd();
mStandby = true;
}
mBytesWritten = 0;
@@ -6480,6 +6499,7 @@
mOutput->standby();
if (!mStandby) {
mThreadMetrics.logEndInterval();
+ mThreadSnapshot.onEnd();
mStandby = true;
}
mBytesWritten = 0;
@@ -7066,6 +7086,7 @@
}
if (mStandby) {
mThreadMetrics.logBeginInterval();
+ mThreadSnapshot.onBegin();
mStandby = false;
}
return (ssize_t)mSinkBufferSize;
@@ -7591,6 +7612,7 @@
doBroadcast = true;
if (mStandby) {
mThreadMetrics.logBeginInterval();
+ mThreadSnapshot.onBegin();
mStandby = false;
}
activeTrack->mState = TrackBase::ACTIVE;
@@ -8072,6 +8094,7 @@
if (!mStandby) {
inputStandBy();
mThreadMetrics.logEndInterval();
+ mThreadSnapshot.onEnd();
mStandby = true;
}
}
@@ -9457,6 +9480,7 @@
}
if (mStandby) {
mThreadMetrics.logBeginInterval();
+ mThreadSnapshot.onBegin();
mStandby = false;
}
return NO_ERROR;
@@ -9653,6 +9677,7 @@
mHalStream->standby();
if (!mStandby) {
mThreadMetrics.logEndInterval();
+ mThreadSnapshot.onEnd();
mStandby = true;
}
releaseWakeLock();
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 1fccdc5..b2962ed8 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -687,6 +687,9 @@
int64_t mLastIoBeginNs = -1;
int64_t mLastIoEndNs = -1;
+ // ThreadSnapshot is thread-safe (internally locked)
+ mediautils::ThreadSnapshot mThreadSnapshot;
+
// This should be read under ThreadBase lock (if not on the threadLoop thread).
audio_utils::Statistics<double> mIoJitterMs{0.995 /* alpha */};
audio_utils::Statistics<double> mProcessTimeMs{0.995 /* alpha */};
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 701206a..1f0e095 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -518,6 +518,10 @@
metadataRequestList.push_back(physicalSettingsList);
surfaceMapList.push_back(surfaceMap);
+
+ if (!request.mUserTag.empty()) {
+ mUserTag = request.mUserTag;
+ }
}
mRequestIdCounter++;
@@ -1964,7 +1968,8 @@
if (remoteCb != 0) {
remoteCb->onDeviceIdle();
}
- Camera2ClientBase::notifyIdle(requestCount, resultErrorCount, deviceError, streamStats);
+ Camera2ClientBase::notifyIdleWithUserTag(requestCount, resultErrorCount, deviceError,
+ streamStats, mUserTag);
}
void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 9d1deb1..3af0b80 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -349,6 +349,9 @@
// Override the camera characteristics for performance class primary cameras.
bool mOverrideForPerfClass;
+
+ // The string representation of object passed into CaptureRequest.setTag.
+ std::string mUserTag;
};
}; // namespace android
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 6ed3c02..0ac047a 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -332,9 +332,10 @@
}
template <typename TClientBase>
-void Camera2ClientBase<TClientBase>::notifyIdle(
+void Camera2ClientBase<TClientBase>::notifyIdleWithUserTag(
int64_t requestCount, int64_t resultErrorCount, bool deviceError,
- const std::vector<hardware::CameraStreamStats>& streamStats) {
+ const std::vector<hardware::CameraStreamStats>& streamStats,
+ const std::string& userTag) {
if (mDeviceActive) {
status_t res = TClientBase::finishCameraStreamingOps();
if (res != OK) {
@@ -342,7 +343,7 @@
TClientBase::mCameraIdStr.string(), res);
}
CameraServiceProxyWrapper::logIdle(TClientBase::mCameraIdStr,
- requestCount, resultErrorCount, deviceError, streamStats);
+ requestCount, resultErrorCount, deviceError, userTag, streamStats);
}
mDeviceActive = false;
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 6b90f5e..9cba2f1 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -75,9 +75,9 @@
const CaptureResultExtras& resultExtras);
// Returns errors on app ops permission failures
virtual status_t notifyActive(float maxPreviewFps);
- virtual void notifyIdle(int64_t requestCount, int64_t resultErrorCount,
- bool deviceError,
- const std::vector<hardware::CameraStreamStats>& streamStats);
+ virtual void notifyIdle(int64_t /*requestCount*/, int64_t /*resultErrorCount*/,
+ bool /*deviceError*/,
+ const std::vector<hardware::CameraStreamStats>&) {}
virtual void notifyShutter(const CaptureResultExtras& resultExtras,
nsecs_t timestamp);
virtual void notifyAutoFocus(uint8_t newState, int triggerId);
@@ -88,6 +88,11 @@
virtual void notifyRequestQueueEmpty();
virtual void notifyRepeatingRequestError(long lastFrameNumber);
+ void notifyIdleWithUserTag(int64_t requestCount, int64_t resultErrorCount,
+ bool deviceError,
+ const std::vector<hardware::CameraStreamStats>& streamStats,
+ const std::string& userTag);
+
int getCameraId() const;
const sp<CameraDeviceBase>&
getCameraDevice();
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
index 82d58e0..a00b221 100644
--- a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
@@ -80,6 +80,7 @@
void CameraServiceProxyWrapper::CameraSessionStatsWrapper::onIdle(
int64_t requestCount, int64_t resultErrorCount, bool deviceError,
+ const std::string& userTag,
const std::vector<hardware::CameraStreamStats>& streamStats) {
Mutex::Autolock l(mLock);
@@ -87,6 +88,7 @@
mSessionStats.mRequestCount = requestCount;
mSessionStats.mResultErrorCount = resultErrorCount;
mSessionStats.mDeviceError = deviceError;
+ mSessionStats.mUserTag = String16(userTag.c_str());
mSessionStats.mStreamStats = streamStats;
updateProxyDeviceState(mSessionStats);
@@ -177,6 +179,7 @@
void CameraServiceProxyWrapper::logIdle(const String8& id,
int64_t requestCount, int64_t resultErrorCount, bool deviceError,
+ const std::string& userTag,
const std::vector<hardware::CameraStreamStats>& streamStats) {
std::shared_ptr<CameraSessionStatsWrapper> sessionStats;
{
@@ -190,8 +193,9 @@
return;
}
- ALOGV("%s: id %s, requestCount %" PRId64 ", resultErrorCount %" PRId64 ", deviceError %d",
- __FUNCTION__, id.c_str(), requestCount, resultErrorCount, deviceError);
+ ALOGV("%s: id %s, requestCount %" PRId64 ", resultErrorCount %" PRId64 ", deviceError %d"
+ ", userTag %s", __FUNCTION__, id.c_str(), requestCount, resultErrorCount,
+ deviceError, userTag.c_str());
for (size_t i = 0; i < streamStats.size(); i++) {
ALOGV("%s: streamStats[%zu]: w %d h %d, requestedCount %" PRId64 ", dropCount %"
PRId64 ", startTimeMs %d" ,
@@ -200,7 +204,7 @@
streamStats[i].mStartLatencyMs);
}
- sessionStats->onIdle(requestCount, resultErrorCount, deviceError, streamStats);
+ sessionStats->onIdle(requestCount, resultErrorCount, deviceError, userTag, streamStats);
}
void CameraServiceProxyWrapper::logOpen(const String8& id, int facing,
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
index 037316d..6604aa1 100644
--- a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
@@ -50,6 +50,7 @@
void onStreamConfigured(int operatingMode, bool internalReconfig, int32_t latencyMs);
void onActive(float maxPreviewFps);
void onIdle(int64_t requestCount, int64_t resultErrorCount, bool deviceError,
+ const std::string& userTag,
const std::vector<hardware::CameraStreamStats>& streamStats);
};
@@ -86,6 +87,7 @@
// Session state becomes idle
static void logIdle(const String8& id,
int64_t requestCount, int64_t resultErrorCount, bool deviceError,
+ const std::string& userTag,
const std::vector<hardware::CameraStreamStats>& streamStats);
// Ping camera service proxy for user update
diff --git a/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp b/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp
index 7a7707c..c3aac72 100644
--- a/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp
+++ b/services/camera/libcameraservice/utils/SessionStatsBuilder.cpp
@@ -60,6 +60,7 @@
mErrorResultCount = 0;
mCounterStopped = false;
mDeviceError = false;
+ mUserTag.clear();
for (auto& streamStats : mStatsMap) {
StreamStats& streamStat = streamStats.second;
streamStat.mRequestedFrameCount = 0;
diff --git a/services/camera/libcameraservice/utils/SessionStatsBuilder.h b/services/camera/libcameraservice/utils/SessionStatsBuilder.h
index c23abb6..2936531 100644
--- a/services/camera/libcameraservice/utils/SessionStatsBuilder.h
+++ b/services/camera/libcameraservice/utils/SessionStatsBuilder.h
@@ -84,6 +84,7 @@
int64_t mErrorResultCount;
bool mCounterStopped;
bool mDeviceError;
+ std::string mUserTag;
// Map from stream id to stream statistics
std::map<int, StreamStats> mStatsMap;
};
diff --git a/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp b/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp
index 8f25ee6..e4aaea0 100644
--- a/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp
+++ b/services/mediaresourcemanager/fuzzer/mediaresourcemanager_fuzzer.cpp
@@ -227,33 +227,31 @@
mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinThreadPairs, kMaxThreadPairs);
// Make even number of threads
size_t numThreads = numThreadPairs * 2;
- resourceThreadArgs threadArgs;
- vector<MediaResourceParcel> mediaResource;
+ resourceThreadArgs threadArgs[numThreadPairs];
+ vector<MediaResourceParcel> mediaResource[numThreadPairs];
pthread_t pt[numThreads];
- int i;
- for (i = 0; i < numThreads - 1; i += 2) {
- threadArgs.pid = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
- threadArgs.uid = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+ for (int k = 0; k < numThreadPairs; ++k) {
+ threadArgs[k].pid = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+ threadArgs[k].uid = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
int32_t mediaResourceType = mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(
kMinResourceType, kMaxResourceType);
int32_t mediaResourceSubType = mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(
kMinResourceType, kMaxResourceType);
uint64_t mediaResourceValue = mFuzzedDataProvider->ConsumeIntegral<uint64_t>();
- threadArgs.service = mService;
+ threadArgs[k].service = mService;
shared_ptr<IResourceManagerClient> testClient =
- ::ndk::SharedRefBase::make<TestClient>(threadArgs.pid, mService);
- threadArgs.testClient = testClient;
- threadArgs.testClientId = getId(testClient);
- mediaResource.push_back(MediaResource(static_cast<MedResType>(mediaResourceType),
- static_cast<MedResSubType>(mediaResourceSubType),
- mediaResourceValue));
- threadArgs.mediaResource = mediaResource;
- pthread_create(&pt[i], nullptr, addResource, &threadArgs);
- pthread_create(&pt[i + 1], nullptr, removeResource, &threadArgs);
- mediaResource.clear();
+ ::ndk::SharedRefBase::make<TestClient>(threadArgs[k].pid, mService);
+ threadArgs[k].testClient = testClient;
+ threadArgs[k].testClientId = getId(testClient);
+ mediaResource[k].push_back(MediaResource(static_cast<MedResType>(mediaResourceType),
+ static_cast<MedResSubType>(mediaResourceSubType),
+ mediaResourceValue));
+ threadArgs[k].mediaResource = mediaResource[k];
+ pthread_create(&pt[2 * k], nullptr, addResource, &threadArgs[k]);
+ pthread_create(&pt[2 * k + 1], nullptr, removeResource, &threadArgs[k]);
}
- for (i = 0; i < numThreads; ++i) {
+ for (int i = 0; i < numThreads; ++i) {
pthread_join(pt[i], nullptr);
}
@@ -266,14 +264,14 @@
int32_t mediaResourceSubType =
mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(kMinResourceType, kMaxResourceType);
uint64_t mediaResourceValue = mFuzzedDataProvider->ConsumeIntegral<uint64_t>();
- mediaResource.push_back(MediaResource(static_cast<MedResType>(mediaResourceType),
- static_cast<MedResSubType>(mediaResourceSubType),
- mediaResourceValue));
+ vector<MediaResourceParcel> mediaRes;
+ mediaRes.push_back(MediaResource(static_cast<MedResType>(mediaResourceType),
+ static_cast<MedResSubType>(mediaResourceSubType),
+ mediaResourceValue));
bool result;
- mService->reclaimResource(pidZero, mediaResource, &result);
- mService->removeResource(pidZero, getId(testClient), mediaResource);
+ mService->reclaimResource(pidZero, mediaRes, &result);
+ mService->removeResource(pidZero, getId(testClient), mediaRes);
mService->removeClient(pidZero, getId(testClient));
- mediaResource.clear();
}
void ResourceManagerServiceFuzzer::setServiceLog() {