Merge "Recategorize ALOGE() and other diagnostics" into sc-dev
diff --git a/media/codec2/sfplugin/C2OMXNode.cpp b/media/codec2/sfplugin/C2OMXNode.cpp
index ab73245..1a92c08 100644
--- a/media/codec2/sfplugin/C2OMXNode.cpp
+++ b/media/codec2/sfplugin/C2OMXNode.cpp
@@ -33,12 +33,14 @@
#include <OMX_IndexExt.h>
#include <android/fdsan.h>
+#include <media/stagefright/foundation/ColorUtils.h>
#include <media/stagefright/omx/OMXUtils.h>
#include <media/stagefright/MediaErrors.h>
#include <ui/Fence.h>
#include <ui/GraphicBuffer.h>
#include <utils/Thread.h>
+#include "utils/Codec2Mapper.h"
#include "C2OMXNode.h"
namespace android {
@@ -71,6 +73,25 @@
jobs->cond.broadcast();
}
+ void setDataspace(android_dataspace dataspace) {
+ Mutexed<Jobs>::Locked jobs(mJobs);
+ ColorUtils::convertDataSpaceToV0(dataspace);
+ jobs->configUpdate.emplace_back(new C2StreamDataSpaceInfo::input(0u, dataspace));
+ int32_t standard = (int32_t(dataspace) & HAL_DATASPACE_STANDARD_MASK)
+ >> HAL_DATASPACE_STANDARD_SHIFT;
+ int32_t transfer = (int32_t(dataspace) & HAL_DATASPACE_TRANSFER_MASK)
+ >> HAL_DATASPACE_TRANSFER_SHIFT;
+ int32_t range = (int32_t(dataspace) & HAL_DATASPACE_RANGE_MASK)
+ >> HAL_DATASPACE_RANGE_SHIFT;
+ std::unique_ptr<C2StreamColorAspectsInfo::input> colorAspects =
+ std::make_unique<C2StreamColorAspectsInfo::input>(0u);
+ if (C2Mapper::map(standard, &colorAspects->primaries, &colorAspects->matrix)
+ && C2Mapper::map(transfer, &colorAspects->transfer)
+ && C2Mapper::map(range, &colorAspects->range)) {
+ jobs->configUpdate.push_back(std::move(colorAspects));
+ }
+ }
+
protected:
bool threadLoop() override {
constexpr nsecs_t kIntervalNs = nsecs_t(10) * 1000 * 1000; // 10ms
@@ -102,6 +123,9 @@
uniqueFds.push_back(std::move(queue.workList.front().fd1));
queue.workList.pop_front();
}
+ for (const std::unique_ptr<C2Param> ¶m : jobs->configUpdate) {
+ items.front()->input.configUpdate.emplace_back(C2Param::Copy(*param));
+ }
jobs.unlock();
for (int fenceFd : fenceFds) {
@@ -119,6 +143,7 @@
queued = true;
}
if (queued) {
+ jobs->configUpdate.clear();
return true;
}
if (i == 0) {
@@ -161,6 +186,7 @@
std::map<std::weak_ptr<Codec2Client::Component>,
Queue,
std::owner_less<std::weak_ptr<Codec2Client::Component>>> queues;
+ std::vector<std::unique_ptr<C2Param>> configUpdate;
Condition cond;
};
Mutexed<Jobs> mJobs;
@@ -172,6 +198,9 @@
mQueueThread(new QueueThread) {
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS);
mQueueThread->run("C2OMXNode", PRIORITY_AUDIO);
+
+ Mutexed<android_dataspace>::Locked ds(mDataspace);
+ *ds = HAL_DATASPACE_UNKNOWN;
}
status_t C2OMXNode::freeNode() {
@@ -459,8 +488,11 @@
android_dataspace dataSpace = (android_dataspace)msg.u.event_data.data1;
uint32_t pixelFormat = msg.u.event_data.data3;
- // TODO: set dataspace on component to see if it impacts color aspects
ALOGD("dataspace changed to %#x pixel format: %#x", dataSpace, pixelFormat);
+ mQueueThread->setDataspace(dataSpace);
+
+ Mutexed<android_dataspace>::Locked ds(mDataspace);
+ *ds = dataSpace;
return OK;
}
@@ -493,4 +525,8 @@
(void)mBufferSource->onInputBufferEmptied(bufferId, -1);
}
+android_dataspace C2OMXNode::getDataspace() {
+ return *mDataspace.lock();
+}
+
} // namespace android
diff --git a/media/codec2/sfplugin/C2OMXNode.h b/media/codec2/sfplugin/C2OMXNode.h
index 1717c96..5d587bc 100644
--- a/media/codec2/sfplugin/C2OMXNode.h
+++ b/media/codec2/sfplugin/C2OMXNode.h
@@ -93,6 +93,8 @@
*/
void onInputBufferDone(c2_cntr64_t index);
+ android_dataspace getDataspace();
+
private:
std::weak_ptr<Codec2Client::Component> mComp;
sp<IOMXBufferSource> mBufferSource;
@@ -101,6 +103,7 @@
uint32_t mWidth;
uint32_t mHeight;
uint64_t mUsage;
+ Mutexed<android_dataspace> mDataspace;
// WORKAROUND: timestamp adjustment
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index f3cde54..fe451f6 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -211,8 +211,6 @@
(OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
&usage, sizeof(usage));
- // NOTE: we do not use/pass through color aspects from GraphicBufferSource as we
- // communicate that directly to the component.
mSource->configure(
mOmxNode, static_cast<hardware::graphics::common::V1_0::Dataspace>(mDataSpace));
return OK;
@@ -411,6 +409,10 @@
mNode->onInputBufferDone(index);
}
+ android_dataspace getDataspace() override {
+ return mNode->getDataspace();
+ }
+
private:
sp<HGraphicBufferSource> mSource;
sp<C2OMXNode> mNode;
@@ -1029,6 +1031,29 @@
}
}
+ // get color aspects
+ getColorAspectsFromFormat(msg, config->mClientColorAspects);
+
+ /*
+ * Handle dataspace
+ */
+ int32_t usingRecorder;
+ if (msg->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) {
+ android_dataspace dataSpace = HAL_DATASPACE_BT709;
+ int32_t width, height;
+ if (msg->findInt32("width", &width)
+ && msg->findInt32("height", &height)) {
+ setDefaultCodecColorAspectsIfNeeded(config->mClientColorAspects, width, height);
+ // TODO: read dataspace / color aspect from the component
+ setColorAspectsIntoFormat(
+ config->mClientColorAspects, const_cast<sp<AMessage> &>(msg));
+ dataSpace = getDataSpaceForColorAspects(
+ config->mClientColorAspects, true /* mayexpand */);
+ }
+ msg->setInt32("android._dataspace", (int32_t)dataSpace);
+ ALOGD("setting dataspace to %x", dataSpace);
+ }
+
int32_t subscribeToAllVendorParams;
if (msg->findInt32("x-*", &subscribeToAllVendorParams) && subscribeToAllVendorParams) {
if (config->subscribeToAllVendorParams(comp, C2_MAY_BLOCK) != OK) {
@@ -1962,6 +1987,44 @@
}
}
+static void HandleDataspace(
+ android_dataspace dataspace, ColorAspects *colorAspects, sp<AMessage> *format) {
+ ColorUtils::convertDataSpaceToV0(dataspace);
+ int32_t range, standard, transfer;
+ range = (dataspace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT;
+ if (range == 0) {
+ range = ColorUtils::wrapColorAspectsIntoColorRange(
+ colorAspects->mRange);
+ }
+ standard = (dataspace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
+ if (standard == 0) {
+ standard = ColorUtils::wrapColorAspectsIntoColorStandard(
+ colorAspects->mPrimaries,
+ colorAspects->mMatrixCoeffs);
+ }
+ transfer = (dataspace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
+ if (transfer == 0) {
+ transfer = ColorUtils::wrapColorAspectsIntoColorTransfer(
+ colorAspects->mTransfer);
+ }
+ ColorAspects newColorAspects;
+ ColorUtils::convertPlatformColorAspectsToCodecAspects(
+ range, standard, transfer, newColorAspects);
+ if (ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
+ newColorAspects, *colorAspects)) {
+ *format = (*format)->dup();
+ (*format)->setInt32(KEY_COLOR_RANGE, range);
+ (*format)->setInt32(KEY_COLOR_STANDARD, standard);
+ (*format)->setInt32(KEY_COLOR_TRANSFER, transfer);
+ // Record current color aspects into |colorAspects|.
+ // NOTE: newColorAspects could have been modified by
+ // checkIfAspectsChangedAndUnspecifyThem() above,
+ // so *colorAspects = newColorAspects does not work as intended.
+ ColorUtils::convertPlatformColorAspectsToCodecAspects(
+ range, standard, transfer, *colorAspects);
+ }
+}
+
void CCodec::onMessageReceived(const sp<AMessage> &msg) {
TimePoint now = std::chrono::steady_clock::now();
CCodecWatchdog::getInstance()->watch(this);
@@ -2076,6 +2139,10 @@
sp<AMessage> outputFormat = config->mOutputFormat;
config->updateConfiguration(updates, config->mOutputDomain);
+ if (config->mInputSurface) {
+ android_dataspace ds = config->mInputSurface->getDataspace();
+ HandleDataspace(ds, &config->mClientColorAspects, &config->mOutputFormat);
+ }
RevertOutputFormatIfNeeded(outputFormat, config->mOutputFormat);
// copy standard infos to graphic buffers if not already present (otherwise, we
diff --git a/media/codec2/sfplugin/CCodecConfig.h b/media/codec2/sfplugin/CCodecConfig.h
index 7e060f6..d9116f7 100644
--- a/media/codec2/sfplugin/CCodecConfig.h
+++ b/media/codec2/sfplugin/CCodecConfig.h
@@ -27,6 +27,7 @@
#include <C2Debug.h>
#include <codec2/hidl/client.h>
+#include <media/stagefright/foundation/ColorUtils.h>
#include <utils/RefBase.h>
#include "InputSurfaceWrapper.h"
@@ -124,6 +125,7 @@
std::shared_ptr<InputSurfaceWrapper> mInputSurface;
std::unique_ptr<InputSurfaceWrapper::Config> mISConfig;
+ ColorAspects mClientColorAspects;
/// the current configuration. Updated after configure() and based on configUpdate in
/// onWorkDone
diff --git a/media/codec2/sfplugin/InputSurfaceWrapper.h b/media/codec2/sfplugin/InputSurfaceWrapper.h
index 479acb1..d29738c 100644
--- a/media/codec2/sfplugin/InputSurfaceWrapper.h
+++ b/media/codec2/sfplugin/InputSurfaceWrapper.h
@@ -106,6 +106,8 @@
*/
virtual void onInputBufferDone(c2_cntr64_t /* index */) {}
+ virtual android_dataspace getDataspace() { return mDataSpace; }
+
protected:
android_dataspace mDataSpace;
};
diff --git a/media/libeffects/preprocessing/Android.bp b/media/libeffects/preprocessing/Android.bp
index eb3ce34..87ed8b6 100644
--- a/media/libeffects/preprocessing/Android.bp
+++ b/media/libeffects/preprocessing/Android.bp
@@ -22,6 +22,7 @@
name: "libaudiopreprocessing",
vendor: true,
relative_install_path: "soundfx",
+ host_supported: true,
srcs: ["PreProcessing.cpp"],
local_include_dirs: [
".",
@@ -47,4 +48,9 @@
"libhardware_headers",
"libwebrtc_absl_headers",
],
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index e8ae58e..3b0b6d6 100644
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -670,8 +670,8 @@
return 0;
}
-int NsGetParameter(preproc_effect_t* effect __unused, void* pParam __unused,
- uint32_t* pValueSize __unused, void* pValue __unused) {
+int NsGetParameter(preproc_effect_t* /*effect __unused*/, void* /*pParam __unused*/,
+ uint32_t* /*pValueSize __unused*/, void* /*pValue __unused*/) {
int status = 0;
return status;
}
@@ -1551,7 +1551,7 @@
}
int PreProcessingFx_ProcessReverse(effect_handle_t self, audio_buffer_t* inBuffer,
- audio_buffer_t* outBuffer __unused) {
+ audio_buffer_t* outBuffer) {
preproc_effect_t* effect = (preproc_effect_t*)self;
if (effect == NULL) {
diff --git a/media/libeffects/preprocessing/tests/Android.bp b/media/libeffects/preprocessing/tests/Android.bp
index 8848e79..6413945 100644
--- a/media/libeffects/preprocessing/tests/Android.bp
+++ b/media/libeffects/preprocessing/tests/Android.bp
@@ -13,6 +13,8 @@
cc_test {
name: "AudioPreProcessingTest",
vendor: true,
+ host_supported: true,
+ gtest: false,
srcs: ["PreProcessingTest.cpp"],
shared_libs: [
"libaudioutils",
@@ -27,7 +29,11 @@
"libaudioeffects",
"libhardware_headers",
],
- gtest: false,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
cc_test {
diff --git a/media/libeffects/preprocessing/tests/PreProcessingTest.cpp b/media/libeffects/preprocessing/tests/PreProcessingTest.cpp
index 5f223c9..e0025fe 100644
--- a/media/libeffects/preprocessing/tests/PreProcessingTest.cpp
+++ b/media/libeffects/preprocessing/tests/PreProcessingTest.cpp
@@ -24,6 +24,7 @@
#include <audio_effects/effect_agc.h>
#include <audio_effects/effect_agc2.h>
#include <audio_effects/effect_ns.h>
+#include <audio_utils/channels.h>
#include <log/log.h>
// This is the only symbol that needs to be imported
@@ -55,7 +56,9 @@
ARG_NS_LVL,
ARG_AGC2_GAIN,
ARG_AGC2_LVL,
- ARG_AGC2_SAT_MGN
+ ARG_AGC2_SAT_MGN,
+ ARG_FILE_CHANNELS,
+ ARG_MONO_MODE
};
struct preProcConfigParams_t {
@@ -68,6 +71,8 @@
float agc2SaturationMargin = 2.f; // in dB
int agc2Level = 0; // either kRms(0) or kPeak(1)
int aecDelay = 0; // in ms
+ int fileChannels = 1;
+ int monoMode = 0;
};
const effect_uuid_t kPreProcUuids[PREPROC_NUM_EFFECTS] = {
@@ -106,7 +111,7 @@
printf("\n Prints this usage information");
printf("\n --fs <sampling_freq>");
printf("\n Sampling frequency in Hz, default 16000.");
- printf("\n -ch_mask <channel_mask>\n");
+ printf("\n --ch_mask <channel_mask>\n");
printf("\n 0 - AUDIO_CHANNEL_IN_MONO");
printf("\n 1 - AUDIO_CHANNEL_IN_STEREO");
printf("\n 2 - AUDIO_CHANNEL_IN_FRONT_BACK");
@@ -144,6 +149,10 @@
printf("\n AGC Adaptive Digital Saturation Margin in dB, default value 2dB");
printf("\n --aec_delay <delay>");
printf("\n AEC delay value in ms, default value 0ms");
+ printf("\n --fch <fileChannels>");
+ printf("\n number of channels in the input file");
+ printf("\n --mono <Mono Mode>");
+ printf("\n Mode to make data of all channels the same as first channel");
printf("\n");
}
@@ -189,10 +198,17 @@
printUsage();
return EXIT_FAILURE;
}
+
+ // Print the arguments passed
+ for (int i = 1; i < argc; i++) {
+ printf("%s ", argv[i]);
+ }
+
const char* inputFile = nullptr;
const char* outputFile = nullptr;
const char* farFile = nullptr;
int effectEn[PREPROC_NUM_EFFECTS] = {0};
+ struct preProcConfigParams_t preProcCfgParams {};
const option long_opts[] = {
{"help", no_argument, nullptr, ARG_HELP},
@@ -212,9 +228,10 @@
{"agc", no_argument, &effectEn[PREPROC_AGC], 1},
{"agc2", no_argument, &effectEn[PREPROC_AGC2], 1},
{"ns", no_argument, &effectEn[PREPROC_NS], 1},
+ {"fch", required_argument, nullptr, ARG_FILE_CHANNELS},
+ {"mono", no_argument, &preProcCfgParams.monoMode, 1},
{nullptr, 0, nullptr, 0},
};
- struct preProcConfigParams_t preProcCfgParams {};
while (true) {
const int opt = getopt_long(argc, (char* const*)argv, "i:o:", long_opts, nullptr);
@@ -279,6 +296,14 @@
preProcCfgParams.nsLevel = atoi(optarg);
break;
}
+ case ARG_FILE_CHANNELS: {
+ preProcCfgParams.fileChannels = atoi(optarg);
+ break;
+ }
+ case ARG_MONO_MODE: {
+ preProcCfgParams.monoMode = 1;
+ break;
+ }
default:
break;
}
@@ -402,16 +427,28 @@
// Process Call
const int frameLength = (int)(preProcCfgParams.samplingFreq * kTenMilliSecVal);
const int ioChannelCount = audio_channel_count_from_in_mask(preProcCfgParams.chMask);
+ const int fileChannelCount = preProcCfgParams.fileChannels;
const int ioFrameSize = ioChannelCount * sizeof(short);
+ const int inFrameSize = fileChannelCount * sizeof(short);
int frameCounter = 0;
while (true) {
std::vector<short> in(frameLength * ioChannelCount);
std::vector<short> out(frameLength * ioChannelCount);
std::vector<short> farIn(frameLength * ioChannelCount);
- size_t samplesRead = fread(in.data(), ioFrameSize, frameLength, inputFp.get());
+ size_t samplesRead = fread(in.data(), inFrameSize, frameLength, inputFp.get());
if (samplesRead == 0) {
break;
}
+ if (fileChannelCount != ioChannelCount) {
+ adjust_channels(in.data(), fileChannelCount, in.data(), ioChannelCount, sizeof(short),
+ frameLength * inFrameSize);
+ if (preProcCfgParams.monoMode == 1) {
+ for (int i = 0; i < frameLength; ++i) {
+ auto* fp = &in[i * ioChannelCount];
+ std::fill(fp + 1, fp + ioChannelCount, *fp); // replicate ch 0
+ }
+ }
+ }
audio_buffer_t inputBuffer, outputBuffer;
audio_buffer_t farInBuffer{};
inputBuffer.frameCount = samplesRead;
@@ -420,10 +457,21 @@
outputBuffer.s16 = out.data();
if (farFp != nullptr) {
- samplesRead = fread(farIn.data(), ioFrameSize, frameLength, farFp.get());
+ samplesRead = fread(farIn.data(), inFrameSize, frameLength, farFp.get());
if (samplesRead == 0) {
break;
}
+ if (fileChannelCount != ioChannelCount) {
+ adjust_channels(farIn.data(), fileChannelCount, farIn.data(), ioChannelCount,
+ sizeof(short), frameLength * inFrameSize);
+ if (preProcCfgParams.monoMode == 1) {
+ for (int i = 0; i < frameLength; ++i) {
+ auto* fp = &farIn[i * ioChannelCount];
+ std::fill(fp + 1, fp + ioChannelCount, *fp); // replicate ch 0
+ }
+ }
+ }
+
farInBuffer.frameCount = samplesRead;
farInBuffer.s16 = farIn.data();
}
@@ -458,8 +506,12 @@
}
}
if (outputFp != nullptr) {
+ if (fileChannelCount != ioChannelCount) {
+ adjust_channels(out.data(), ioChannelCount, out.data(), fileChannelCount,
+ sizeof(short), frameLength * ioFrameSize);
+ }
size_t samplesWritten =
- fwrite(out.data(), ioFrameSize, outputBuffer.frameCount, outputFp.get());
+ fwrite(out.data(), inFrameSize, outputBuffer.frameCount, outputFp.get());
if (samplesWritten != outputBuffer.frameCount) {
ALOGE("\nError: Output file writing failed");
break;
diff --git a/media/libeffects/preprocessing/tests/build_and_run_all_unit_tests.sh b/media/libeffects/preprocessing/tests/build_and_run_all_unit_tests.sh
new file mode 100755
index 0000000..942f2ec
--- /dev/null
+++ b/media/libeffects/preprocessing/tests/build_and_run_all_unit_tests.sh
@@ -0,0 +1,115 @@
+#!/bin/bash
+#
+# Run tests in this directory.
+#
+
+if [ -z "$ANDROID_BUILD_TOP" ]; then
+ echo "Android build environment not set"
+ exit -1
+fi
+
+# ensure we have mm
+. $ANDROID_BUILD_TOP/build/envsetup.sh
+
+mm -j
+
+echo "waiting for device"
+
+adb root && adb wait-for-device remount
+
+# location of test files
+testdir="/data/local/tmp/AudioPreProcessingTest"
+
+echo "========================================"
+echo "testing PreProcessing modules"
+adb shell mkdir -p $testdir
+adb push $ANDROID_BUILD_TOP/frameworks/av/media/libeffects/res/raw/sinesweepraw.raw $testdir
+adb push $OUT/testcases/snr/arm64/snr $testdir
+
+E_VAL=1
+if [ -z "$1" ]
+then
+ cmds=("adb push $OUT/testcases/AudioPreProcessingTest/arm64/AudioPreProcessingTest $testdir"
+ "adb push $OUT/testcases/AudioPreProcessingTest/arm/AudioPreProcessingTest $testdir"
+)
+elif [ "$1" == "32" ]
+then
+ cmds="adb push $OUT/testcases/AudioPreProcessingTest/arm/AudioPreProcessingTest $testdir"
+elif [ "$1" == "64" ]
+then
+ cmds="adb push $OUT/testcases/AudioPreProcessingTest/arm64/AudioPreProcessingTest $testdir"
+else
+ echo ""
+ echo "Invalid \"val\""
+ echo "Usage:"
+ echo " "$0" [val]"
+ echo " where, val can be either 32 or 64."
+ echo ""
+ echo " If val is not specified then both 32 bit and 64 bit binaries"
+ echo " are tested."
+ exit $E_VAL
+fi
+
+flags_arr=(
+ "--agc --mono"
+ "--ns --mono"
+ "--agc2 --mono"
+ "--aec --mono"
+)
+
+fs_arr=(
+ 8000
+ 16000
+ 24000
+ 32000
+ 48000
+)
+
+# run multichannel effects at different configs, saving only the mono channel
+error_count=0
+test_count=0
+for cmd in "${cmds[@]}"
+do
+ $cmd
+ for flags in "${flags_arr[@]}"
+ do
+ for fs in ${fs_arr[*]}
+ do
+ for chMask in {0..7}
+ do
+ adb shell $testdir/AudioPreProcessingTest $flags \
+ --i $testdir/sinesweepraw.raw --far $testdir/sinesweepraw.raw \
+ --output $testdir/sinesweep_$((chMask))_$((fs)).raw --ch_mask $chMask \
+ --fs $fs --fch 1
+
+ shell_ret=$?
+ if [ $shell_ret -ne 0 ]; then
+ echo "error shell_ret here is zero: $shell_ret"
+ ((++error_count))
+ fi
+
+
+ # single channel files should be identical to higher channel
+ # computation (first channel).
+ if [[ "$chMask" -gt 1 ]]
+ then
+ adb shell cmp $testdir/sinesweep_1_$((fs)).raw \
+ $testdir/sinesweep_$((chMask))_$((fs)).raw
+ fi
+
+ # cmp return EXIT_FAILURE on mismatch.
+ shell_ret=$?
+ if [ $shell_ret -ne 0 ]; then
+ echo "error: $shell_ret"
+ ((++error_count))
+ fi
+ ((++test_count))
+ done
+ done
+ done
+done
+
+adb shell rm -r $testdir
+echo "$test_count tests performed"
+echo "$error_count errors"
+exit $error_count
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index b85e139..dc4aea5 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1831,8 +1831,7 @@
//static
void MediaPlayerService::AudioOutput::setMinBufferCount()
{
- char value[PROPERTY_VALUE_MAX];
- if (property_get("ro.kernel.qemu", value, 0)) {
+ if (property_get_bool("ro.boot.qemu", false)) {
mIsOnEmulator = true;
mMinBufferCount = 12; // to prevent systematic buffer underrun for emulator
}
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index bcf418a..b1aa7a9 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -658,7 +658,7 @@
mStartTimeUs = 0;
mNumInputBuffers = 0;
mEncoderFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
- mEncoderDataSpace = HAL_DATASPACE_V0_BT709;
+ mEncoderDataSpace = mBufferDataSpace = HAL_DATASPACE_V0_BT709;
if (meta) {
int64_t startTimeUs;
@@ -678,6 +678,7 @@
}
if (meta->findInt32(kKeyColorSpace, &mEncoderDataSpace)) {
ALOGI("Using encoder data space: %#x", mEncoderDataSpace);
+ mBufferDataSpace = mEncoderDataSpace;
}
}
@@ -908,6 +909,11 @@
(*buffer)->setObserver(this);
(*buffer)->add_ref();
(*buffer)->meta_data().setInt64(kKeyTime, frameTime);
+ if (mBufferDataSpace != mEncoderDataSpace) {
+ ALOGD("Data space updated to %x", mBufferDataSpace);
+ (*buffer)->meta_data().setInt32(kKeyColorSpace, mBufferDataSpace);
+ mEncoderDataSpace = mBufferDataSpace;
+ }
}
return OK;
}
@@ -1039,6 +1045,7 @@
// Find a available memory slot to store the buffer as VideoNativeMetadata.
sp<IMemory> data = *mMemoryBases.begin();
mMemoryBases.erase(mMemoryBases.begin());
+ mBufferDataSpace = buffer.mDataSpace;
ssize_t offset;
size_t size;
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 447d599..76a5cab 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -4260,13 +4260,20 @@
void MPEG4Writer::Track::writeColrBox() {
ColorAspects aspects;
memset(&aspects, 0, sizeof(aspects));
+ // Color metadata may have changed.
+ sp<MetaData> meta = mSource->getFormat();
// TRICKY: using | instead of || because we want to execute all findInt32-s
- if (mMeta->findInt32(kKeyColorPrimaries, (int32_t*)&aspects.mPrimaries)
- | mMeta->findInt32(kKeyTransferFunction, (int32_t*)&aspects.mTransfer)
- | mMeta->findInt32(kKeyColorMatrix, (int32_t*)&aspects.mMatrixCoeffs)
- | mMeta->findInt32(kKeyColorRange, (int32_t*)&aspects.mRange)) {
+ if (meta->findInt32(kKeyColorPrimaries, (int32_t*)&aspects.mPrimaries)
+ | meta->findInt32(kKeyTransferFunction, (int32_t*)&aspects.mTransfer)
+ | meta->findInt32(kKeyColorMatrix, (int32_t*)&aspects.mMatrixCoeffs)
+ | meta->findInt32(kKeyColorRange, (int32_t*)&aspects.mRange)) {
int32_t primaries, transfer, coeffs;
bool fullRange;
+ ALOGV("primaries=%s transfer=%s matrix=%s range=%s",
+ asString(aspects.mPrimaries),
+ asString(aspects.mTransfer),
+ asString(aspects.mMatrixCoeffs),
+ asString(aspects.mRange));
ColorUtils::convertCodecColorAspectsToIsoAspects(
aspects, &primaries, &transfer, &coeffs, &fullRange);
mOwner->beginBox("colr");
@@ -4276,6 +4283,8 @@
mOwner->writeInt16(coeffs);
mOwner->writeInt8(int8_t(fullRange ? 0x80 : 0x0));
mOwner->endBox(); // colr
+ } else {
+ ALOGV("no color information");
}
}
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index bc656a2..0f7df24 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -30,6 +30,7 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/ColorUtils.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaCodecConstants.h>
@@ -768,6 +769,26 @@
memcpy(inbuf->data(), mbuf->data(), size);
if (mIsVideo) {
+ int32_t ds = 0;
+ if (mbuf->meta_data().findInt32(kKeyColorSpace, &ds)
+ && ds != HAL_DATASPACE_UNKNOWN) {
+ android_dataspace dataspace = static_cast<android_dataspace>(ds);
+ ColorUtils::convertDataSpaceToV0(dataspace);
+ ALOGD("Updating dataspace to %x", dataspace);
+ int32_t standard = (int32_t(dataspace) & HAL_DATASPACE_STANDARD_MASK)
+ >> HAL_DATASPACE_STANDARD_SHIFT;
+ int32_t transfer = (int32_t(dataspace) & HAL_DATASPACE_TRANSFER_MASK)
+ >> HAL_DATASPACE_TRANSFER_SHIFT;
+ int32_t range = (int32_t(dataspace) & HAL_DATASPACE_RANGE_MASK)
+ >> HAL_DATASPACE_RANGE_SHIFT;
+ sp<AMessage> msg = new AMessage;
+ msg->setInt32(KEY_COLOR_STANDARD, standard);
+ msg->setInt32(KEY_COLOR_TRANSFER, transfer);
+ msg->setInt32(KEY_COLOR_RANGE, range);
+ msg->setInt32("android._dataspace", dataspace);
+ mEncoder->setParameters(msg);
+ }
+
// video encoder will release MediaBuffer when done
// with underlying data.
inbuf->meta()->setObject("mediaBufferHolder", new MediaBufferHolder(mbuf));
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index f242b19..6bb7b37 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -1078,6 +1078,17 @@
return OK;
}
+status_t AMessage::removeEntryByName(const char *name) {
+ if (name == nullptr) {
+ return BAD_VALUE;
+ }
+ size_t index = findEntryByName(name);
+ if (index >= mNumItems) {
+ return BAD_INDEX;
+ }
+ return removeEntryAt(index);
+}
+
void AMessage::setItem(const char *name, const ItemData &item) {
if (item.used()) {
Item *it = allocateItem(name);
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h b/media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h
index 31e58ba..98d6147 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h
@@ -261,6 +261,17 @@
*/
status_t removeEntryAt(size_t index);
+ /**
+ * Removes an entry based on name.
+ *
+ * \param name name of the entry
+ *
+ * \retval OK the entry was removed successfully
+ * \retval BAD_VALUE name is invalid (null)
+ * \retval BAD_INDEX name not found
+ */
+ status_t removeEntryByName(const char *name);
+
protected:
virtual ~AMessage();
diff --git a/media/libstagefright/foundation/tests/AMessage_test.cpp b/media/libstagefright/foundation/tests/AMessage_test.cpp
new file mode 100644
index 0000000..2b11326
--- /dev/null
+++ b/media/libstagefright/foundation/tests/AMessage_test.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AData_test"
+
+#include <gtest/gtest.h>
+#include <utils/RefBase.h>
+
+#include <media/stagefright/foundation/AMessage.h>
+
+using namespace android;
+
+class AMessageTest : public ::testing::Test {
+};
+
+
+TEST(AMessage_tests, item_manipulation) {
+ sp<AMessage> m1 = new AMessage();
+
+ m1->setInt32("value", 2);
+ m1->setInt32("bar", 3);
+
+ int32_t i32;
+ EXPECT_TRUE(m1->findInt32("value", &i32));
+ EXPECT_EQ(2, i32);
+
+ EXPECT_TRUE(m1->findInt32("bar", &i32));
+ EXPECT_EQ(3, i32);
+
+
+ m1->setInt64("big", INT64_MAX);
+ m1->setInt64("smaller", INT64_MAX - 2);
+ m1->setInt64("smallest", 257);
+
+ int64_t i64;
+ EXPECT_TRUE(m1->findInt64("big", &i64));
+ EXPECT_EQ(INT64_MAX, i64);
+
+ EXPECT_TRUE(m1->findInt64("smaller", &i64));
+ EXPECT_EQ(INT64_MAX - 2, i64);
+
+ m1->setSize("size1", 257);
+ m1->setSize("size2", 1023);
+
+ size_t sizing;
+ EXPECT_TRUE(m1->findSize("size2", &sizing));
+ EXPECT_EQ(1023, sizing);
+ EXPECT_TRUE(m1->findSize("size1", &sizing));
+ EXPECT_EQ(257, sizing);
+
+ m1->setDouble("precise", 10.5);
+ m1->setDouble("small", 0.125);
+
+ double d;
+ EXPECT_TRUE(m1->findDouble("precise", &d));
+ EXPECT_EQ(10.5, d);
+
+ EXPECT_TRUE(m1->findDouble("small", &d));
+ EXPECT_EQ(0.125, d);
+
+ // should be unchanged from the top of the test
+ EXPECT_TRUE(m1->findInt32("bar", &i32));
+ EXPECT_EQ(3, i32);
+
+ EXPECT_FALSE(m1->findInt32("nonesuch", &i32));
+ EXPECT_FALSE(m1->findInt64("nonesuch2", &i64));
+ // types disagree, not found
+ EXPECT_FALSE(m1->findInt32("big", &i32));
+ EXPECT_FALSE(m1->findInt32("precise", &i32));
+
+ // integral types should come back true
+ EXPECT_TRUE(m1->findAsInt64("big", &i64));
+ EXPECT_EQ(INT64_MAX, i64);
+ EXPECT_TRUE(m1->findAsInt64("bar", &i64));
+ EXPECT_EQ(3, i64);
+ EXPECT_FALSE(m1->findAsInt64("precise", &i64));
+
+ // recovers ints, size, and floating point values
+ float value;
+ EXPECT_TRUE(m1->findAsFloat("value", &value));
+ EXPECT_EQ(2, value);
+ EXPECT_TRUE(m1->findAsFloat("smallest", &value));
+ EXPECT_EQ(257, value);
+ EXPECT_TRUE(m1->findAsFloat("size2", &value));
+ EXPECT_EQ(1023, value);
+ EXPECT_TRUE(m1->findAsFloat("precise", &value));
+ EXPECT_EQ(10.5, value);
+ EXPECT_TRUE(m1->findAsFloat("small", &value));
+ EXPECT_EQ(0.125, value);
+
+
+ // need to handle still:
+ // strings
+ // Object
+ // Buffer
+ // Message (nested)
+ //
+
+ // removal
+ m1->setInt32("shortlived", 2);
+ m1->setInt32("alittlelonger", 2);
+ EXPECT_EQ(OK, m1->removeEntryByName("shortlived"));
+ EXPECT_EQ(BAD_VALUE, m1->removeEntryByName(nullptr));
+ EXPECT_EQ(BAD_INDEX, m1->removeEntryByName("themythicalnonesuch"));
+ EXPECT_FALSE(m1->findInt32("shortlived", &i32));
+ EXPECT_TRUE(m1->findInt32("alittlelonger", &i32));
+
+ EXPECT_NE(OK, m1->removeEntryByName("notpresent"));
+
+}
+
diff --git a/media/libstagefright/foundation/tests/Android.bp b/media/libstagefright/foundation/tests/Android.bp
index 715b57a..e50742e 100644
--- a/media/libstagefright/foundation/tests/Android.bp
+++ b/media/libstagefright/foundation/tests/Android.bp
@@ -30,6 +30,7 @@
srcs: [
"AData_test.cpp",
+ "AMessage_test.cpp",
"Base64_test.cpp",
"Flagged_test.cpp",
"TypeTraits_test.cpp",
diff --git a/media/libstagefright/include/media/stagefright/CameraSource.h b/media/libstagefright/include/media/stagefright/CameraSource.h
index 16e7d89..e8770ed 100644
--- a/media/libstagefright/include/media/stagefright/CameraSource.h
+++ b/media/libstagefright/include/media/stagefright/CameraSource.h
@@ -159,6 +159,7 @@
int32_t mColorFormat;
int32_t mEncoderFormat;
int32_t mEncoderDataSpace;
+ int32_t mBufferDataSpace;
status_t mInitCheck;
sp<Camera> mCamera;
diff --git a/media/ndk/TEST_MAPPING b/media/ndk/TEST_MAPPING
index 1a81538..e420812 100644
--- a/media/ndk/TEST_MAPPING
+++ b/media/ndk/TEST_MAPPING
@@ -1,6 +1,7 @@
// mappings for frameworks/av/media/ndk
{
"presubmit": [
- { "name": "AImageReaderWindowHandleTest" }
+ { "name": "AImageReaderWindowHandleTest" },
+ { "name": "libmediandk_test" }
]
}
diff --git a/media/ndk/tests/Android.bp b/media/ndk/tests/Android.bp
new file mode 100644
index 0000000..984b3ee
--- /dev/null
+++ b/media/ndk/tests/Android.bp
@@ -0,0 +1,41 @@
+// Copyright (C) 2016 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.
+
+// Headers module is in frameworks/av/Android.bp because modules are not allowed
+// to refer to headers in parent directories and the headers live in
+// frameworks/av/include.
+
+package {
+ default_applicable_licenses: ["frameworks_av_media_ndk_license"],
+}
+
+cc_test {
+ name: "libmediandk_test",
+ test_suites: ["device-tests"],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ shared_libs: [
+ "liblog",
+ "libmediandk",
+ "libutils",
+ ],
+
+ srcs: [
+ "NdkMediaFormat_test.cpp",
+ ],
+}
diff --git a/media/ndk/tests/NdkMediaFormat_test.cpp b/media/ndk/tests/NdkMediaFormat_test.cpp
new file mode 100644
index 0000000..668d0a4
--- /dev/null
+++ b/media/ndk/tests/NdkMediaFormat_test.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "NdkMediaFormat_test"
+
+#include <gtest/gtest.h>
+#include <utils/RefBase.h>
+
+#include <media/NdkMediaFormat.h>
+
+namespace android {
+
+class NdkMediaFormatTest : public ::testing::Test {
+};
+
+
+TEST(NdkMediaFormat_tests, test_create) {
+
+ AMediaFormat *fmt1 = AMediaFormat_new();
+ AMediaFormat *fmt2 = AMediaFormat_new();
+
+ EXPECT_NE(fmt1, fmt2);
+ EXPECT_NE(fmt1, nullptr);
+ EXPECT_NE(fmt2, nullptr);
+
+ AMediaFormat_delete(fmt1);
+ AMediaFormat_delete(fmt2);
+}
+
+TEST(NdkMediaFormat_tests, test_int32) {
+ AMediaFormat *fmt1 = AMediaFormat_new();
+ int32_t i32;
+ int64_t i64;
+ AMediaFormat_setInt32(fmt1, "five", 5);
+
+ EXPECT_TRUE(AMediaFormat_getInt32(fmt1, "five", &i32));
+ EXPECT_FALSE(AMediaFormat_getInt64(fmt1, "five", &i64));
+ EXPECT_EQ(i32, 5);
+
+ AMediaFormat_delete(fmt1);
+}
+
+TEST(NdkMediaFormat_tests, test_int64) {
+ AMediaFormat *fmt1 = AMediaFormat_new();
+ int64_t i64;
+ AMediaFormat_setInt64(fmt1, "verylarge", INT64_MAX);
+
+ EXPECT_TRUE(AMediaFormat_getInt64(fmt1, "verylarge", &i64));
+ EXPECT_EQ(i64, INT64_MAX);
+
+ // return unchanged if not found
+ i64 = -1;
+ EXPECT_FALSE(AMediaFormat_getInt64(fmt1, "five", &i64));
+ EXPECT_EQ(i64, -1);
+
+ AMediaFormat_delete(fmt1);
+}
+
+TEST(NdkMediaFormat_tests, test_size) {
+ AMediaFormat *fmt1 = AMediaFormat_new();
+
+ size_t size = -15;
+ AMediaFormat_setSize(fmt1, "small", 1);
+ AMediaFormat_setSize(fmt1, "medium", 10);
+ AMediaFormat_setSize(fmt1, "large", 100);
+ EXPECT_TRUE(AMediaFormat_getSize(fmt1, "medium", &size));
+ EXPECT_EQ(size, 10);
+
+ AMediaFormat_delete(fmt1);
+}
+
+TEST(NdkMediaFormat_tests, test_float) {
+ AMediaFormat *fmt1 = AMediaFormat_new();
+ float f;
+ AMediaFormat_setFloat(fmt1, "boat", 1.5);
+ AMediaFormat_setFloat(fmt1, "ship", 0.5);
+ EXPECT_TRUE(AMediaFormat_getFloat(fmt1, "boat", &f));
+ EXPECT_EQ(f, 1.5);
+ AMediaFormat_delete(fmt1);
+}
+
+TEST(NdkMediaFormat_tests, test_double) {
+ AMediaFormat *fmt1 = AMediaFormat_new();
+ double d;
+ AMediaFormat_setDouble(fmt1, "trouble", 100.5);
+ AMediaFormat_setDouble(fmt1, "dip", 0.5);
+ EXPECT_TRUE(AMediaFormat_getDouble(fmt1, "trouble", &d));
+ EXPECT_EQ(d, 100.5);
+ AMediaFormat_delete(fmt1);
+}
+
+TEST(NdkMediaFormat_tests, test_string) {
+ AMediaFormat *fmt1 = AMediaFormat_new();
+
+ const char *content = "This is my test string";
+ const char *out = nullptr;
+ AMediaFormat_setString(fmt1, "stringtheory", content);
+ EXPECT_TRUE(AMediaFormat_getString(fmt1, "stringtheory", &out));
+ EXPECT_NE(out, nullptr);
+ EXPECT_EQ(strcmp(out,content), 0);
+
+ AMediaFormat_delete(fmt1);
+}
+
+
+TEST(NdkMediaFormat_tests, test_clear) {
+ AMediaFormat *fmt1 = AMediaFormat_new();
+
+ int32_t i32;
+ AMediaFormat_setInt32(fmt1, "five", 5);
+ size_t size = -15;
+ AMediaFormat_setSize(fmt1, "medium", 10);
+ float f;
+ AMediaFormat_setFloat(fmt1, "boat", 1.5);
+
+ AMediaFormat_clear(fmt1);
+ EXPECT_FALSE(AMediaFormat_getInt32(fmt1, "five", &i32));
+ EXPECT_FALSE(AMediaFormat_getSize(fmt1, "medium", &size));
+ EXPECT_FALSE(AMediaFormat_getFloat(fmt1, "boat", &f));
+
+ AMediaFormat_delete(fmt1);
+}
+
+TEST(NdkMediaFormat_tests, test_copy) {
+ AMediaFormat *fmt1 = AMediaFormat_new();
+ AMediaFormat *fmt2 = AMediaFormat_new();
+
+ double d;
+ int32_t i32;
+
+ // test copy functionality (NB: we cleared everything just above here)
+ AMediaFormat_setDouble(fmt1, "trouble", 100.5);
+ EXPECT_TRUE(AMediaFormat_getDouble(fmt1, "trouble", &d));
+ EXPECT_FALSE(AMediaFormat_getDouble(fmt2, "trouble", &d));
+
+ EXPECT_EQ(AMEDIA_OK, AMediaFormat_copy(fmt2, fmt1));
+
+ EXPECT_TRUE(AMediaFormat_getDouble(fmt2, "trouble", &d));
+ EXPECT_EQ(d, 100.5);
+
+ AMediaFormat *fmt3 = nullptr;
+ EXPECT_NE(AMEDIA_OK, AMediaFormat_copy(fmt3, fmt1));
+ EXPECT_NE(AMEDIA_OK, AMediaFormat_copy(fmt1, fmt3));
+
+ // we should lose an entry when we copy over it
+ AMediaFormat_setInt32(fmt2, "vanishing", 50);
+ EXPECT_FALSE(AMediaFormat_getInt32(fmt1, "vanishing", &i32));
+ EXPECT_TRUE(AMediaFormat_getInt32(fmt2, "vanishing", &i32));
+ EXPECT_EQ(AMEDIA_OK, AMediaFormat_copy(fmt2, fmt1));
+ EXPECT_FALSE(AMediaFormat_getInt32(fmt2, "vanishing", &i32));
+
+ AMediaFormat_delete(fmt1);
+ AMediaFormat_delete(fmt2);
+}
+
+TEST(NdkMediaFormat_tests, test_buffer) {
+ AMediaFormat *fmt1 = AMediaFormat_new();
+
+ typedef struct blockomem {
+ int leading;
+ int filled[100];
+ int trailing;
+ } block_t;
+ block_t buf = {};
+ buf.leading = 1;
+ buf.trailing = 2;
+ void *data;
+ size_t bsize;
+
+ AMediaFormat_setBuffer(fmt1, "mybuffer", &buf, sizeof(buf));
+ EXPECT_TRUE(AMediaFormat_getBuffer(fmt1, "mybuffer", &data, &bsize));
+ EXPECT_NE(&buf, data);
+ EXPECT_EQ(sizeof(buf), bsize);
+ block_t *bufp = (block_t*) data;
+ EXPECT_EQ(bufp->leading, buf.leading);
+ EXPECT_EQ(bufp->trailing, buf.trailing);
+ EXPECT_EQ(0, memcmp(&buf, data, bsize));
+
+ AMediaFormat_delete(fmt1);
+}
+
+} // namespace android
diff --git a/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp
index 8baf8dc..0b69bf6 100644
--- a/services/oboeservice/AAudioService.cpp
+++ b/services/oboeservice/AAudioService.cpp
@@ -39,7 +39,7 @@
using namespace aaudio;
#define MAX_STREAMS_PER_PROCESS 8
-#define AIDL_RETURN(x) *_aidl_return = (x); return Status::ok();
+#define AIDL_RETURN(x) { *_aidl_return = (x); return Status::ok(); }
#define VALUE_OR_RETURN_ILLEGAL_ARG_STATUS(x) \
({ auto _tmp = (x); \
@@ -116,12 +116,11 @@
// Enforce limit on client processes.
Identity callingIdentity = request.getIdentity();
+ pid_t pid = IPCThreadState::self()->getCallingPid();
callingIdentity.pid = VALUE_OR_RETURN_ILLEGAL_ARG_STATUS(
- legacy2aidl_pid_t_int32_t(IPCThreadState::self()->getCallingPid()));
+ legacy2aidl_pid_t_int32_t(pid));
callingIdentity.uid = VALUE_OR_RETURN_ILLEGAL_ARG_STATUS(
legacy2aidl_uid_t_int32_t(IPCThreadState::self()->getCallingUid()));
- pid_t pid = VALUE_OR_RETURN_ILLEGAL_ARG_STATUS(
- aidl2legacy_int32_t_pid_t(callingIdentity.pid));
if (callingIdentity.pid != mAudioClient.identity.pid) {
int32_t count = AAudioClientTracker::getInstance().getStreamCount(pid);
if (count >= MAX_STREAMS_PER_PROCESS) {