Merge "Log requested sharing mode." into sc-dev
diff --git a/apex/mediatranscoding.rc b/apex/mediatranscoding.rc
index ae9f8ba..87df2d5 100644
--- a/apex/mediatranscoding.rc
+++ b/apex/mediatranscoding.rc
@@ -7,6 +7,7 @@
group media
ioprio rt 4
# Restrict to little cores only with system-background cpuset.
- writepid /dev/cpuset/system-background/tasks
+ # Lower IO priority to background.
+ writepid /dev/cpuset/system-background/tasks /dev/blkio/background/tasks
interface aidl media.transcoding
disabled
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index bab651f..0b121ad 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -28,6 +28,7 @@
#include <media/stagefright/foundation/AUtils.h>
#include <C2Debug.h>
+#include <Codec2Mapper.h>
#include <C2PlatformSupport.h>
#include <Codec2BufferUtils.h>
#include <SimpleC2Interface.h>
@@ -213,6 +214,42 @@
.withFields({C2F(mSyncFramePeriod, value).any()})
.withSetter(Setter<decltype(*mSyncFramePeriod)>::StrictValueWithNoDeps)
.build());
+
+ addParameter(
+ DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
+ .withDefault(new C2StreamColorAspectsInfo::input(
+ 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+ .withFields({
+ C2F(mColorAspects, range).inRange(
+ C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
+ C2F(mColorAspects, primaries).inRange(
+ C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+ C2F(mColorAspects, transfer).inRange(
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
+ C2F(mColorAspects, matrix).inRange(
+ C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
+ })
+ .withSetter(ColorAspectsSetter)
+ .build());
+
+ addParameter(
+ DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
+ .withDefault(new C2StreamColorAspectsInfo::output(
+ 0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+ .withFields({
+ C2F(mCodedColorAspects, range).inRange(
+ C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
+ C2F(mCodedColorAspects, primaries).inRange(
+ C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+ C2F(mCodedColorAspects, transfer).inRange(
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
+ C2F(mCodedColorAspects, matrix).inRange(
+ C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
+ })
+ .withSetter(CodedColorAspectsSetter, mColorAspects)
+ .build());
}
static C2R InputDelaySetter(
@@ -359,6 +396,33 @@
return C2R::Ok();
}
+ static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me) {
+ (void)mayBlock;
+ if (me.v.range > C2Color::RANGE_OTHER) {
+ me.set().range = C2Color::RANGE_OTHER;
+ }
+ if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+ me.set().primaries = C2Color::PRIMARIES_OTHER;
+ }
+ if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+ me.set().transfer = C2Color::TRANSFER_OTHER;
+ }
+ if (me.v.matrix > C2Color::MATRIX_OTHER) {
+ me.set().matrix = C2Color::MATRIX_OTHER;
+ }
+ return C2R::Ok();
+ }
+
+ static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me,
+ const C2P<C2StreamColorAspectsInfo::input> &coded) {
+ (void)mayBlock;
+ me.set().range = coded.v.range;
+ me.set().primaries = coded.v.primaries;
+ me.set().transfer = coded.v.transfer;
+ me.set().matrix = coded.v.matrix;
+ return C2R::Ok();
+ }
+
IV_PROFILE_T getProfile_l() const {
switch (mProfileLevel->profile) {
case PROFILE_AVC_CONSTRAINED_BASELINE: [[fallthrough]];
@@ -418,6 +482,9 @@
std::shared_ptr<C2StreamGopTuning::output> getGop_l() const { return mGop; }
std::shared_ptr<C2StreamPictureQuantizationTuning::output> getPictureQuantization_l() const
{ return mPictureQuantization; }
+ std::shared_ptr<C2StreamColorAspectsInfo::output> getCodedColorAspects_l() const {
+ return mCodedColorAspects;
+ }
private:
std::shared_ptr<C2StreamUsageTuning::input> mUsage;
@@ -430,6 +497,8 @@
std::shared_ptr<C2StreamSyncFrameIntervalTuning::output> mSyncFramePeriod;
std::shared_ptr<C2StreamGopTuning::output> mGop;
std::shared_ptr<C2StreamPictureQuantizationTuning::output> mPictureQuantization;
+ std::shared_ptr<C2StreamColorAspectsInfo::input> mColorAspects;
+ std::shared_ptr<C2StreamColorAspectsInfo::output> mCodedColorAspects;
};
#define ive_api_function ih264e_api_function
@@ -980,6 +1049,55 @@
return;
}
+c2_status_t C2SoftAvcEnc::setVuiParams()
+{
+ ColorAspects sfAspects;
+ if (!C2Mapper::map(mColorAspects->primaries, &sfAspects.mPrimaries)) {
+ sfAspects.mPrimaries = android::ColorAspects::PrimariesUnspecified;
+ }
+ if (!C2Mapper::map(mColorAspects->range, &sfAspects.mRange)) {
+ sfAspects.mRange = android::ColorAspects::RangeUnspecified;
+ }
+ if (!C2Mapper::map(mColorAspects->matrix, &sfAspects.mMatrixCoeffs)) {
+ sfAspects.mMatrixCoeffs = android::ColorAspects::MatrixUnspecified;
+ }
+ if (!C2Mapper::map(mColorAspects->transfer, &sfAspects.mTransfer)) {
+ sfAspects.mTransfer = android::ColorAspects::TransferUnspecified;
+ }
+ int32_t primaries, transfer, matrixCoeffs;
+ bool range;
+ ColorUtils::convertCodecColorAspectsToIsoAspects(sfAspects,
+ &primaries,
+ &transfer,
+ &matrixCoeffs,
+ &range);
+ ih264e_vui_ip_t s_vui_params_ip {};
+ ih264e_vui_op_t s_vui_params_op {};
+
+ s_vui_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+ s_vui_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_VUI_PARAMS;
+
+ s_vui_params_ip.u1_video_signal_type_present_flag = 1;
+ s_vui_params_ip.u1_colour_description_present_flag = 1;
+ s_vui_params_ip.u1_colour_primaries = primaries;
+ s_vui_params_ip.u1_transfer_characteristics = transfer;
+ s_vui_params_ip.u1_matrix_coefficients = matrixCoeffs;
+ s_vui_params_ip.u1_video_full_range_flag = range;
+
+ s_vui_params_ip.u4_size = sizeof(ih264e_vui_ip_t);
+ s_vui_params_op.u4_size = sizeof(ih264e_vui_op_t);
+
+ IV_STATUS_T status = ih264e_api_function(mCodecCtx, &s_vui_params_ip,
+ &s_vui_params_op);
+ if(status != IV_SUCCESS)
+ {
+ ALOGE("Unable to set vui params = 0x%x\n",
+ s_vui_params_op.u4_error_code);
+ return C2_CORRUPTED;
+ }
+ return C2_OK;
+}
+
c2_status_t C2SoftAvcEnc::initEncoder() {
IV_STATUS_T status;
WORD32 level;
@@ -999,6 +1117,7 @@
mIInterval = mIntf->getSyncFramePeriod_l();
mIDRInterval = mIntf->getSyncFramePeriod_l();
gop = mIntf->getGop_l();
+ mColorAspects = mIntf->getCodedColorAspects_l();
}
if (gop && gop->flexCount() > 0) {
uint32_t syncInterval = 1;
@@ -1223,6 +1342,9 @@
/* Video control Set Profile params */
setProfileParams();
+ /* Video control Set VUI params */
+ setVuiParams();
+
/* Video control Set in Encode header mode */
setEncMode(IVE_ENC_MODE_HEADER);
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.h b/media/codec2/components/avc/C2SoftAvcEnc.h
index 673a282..baf33e2 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.h
+++ b/media/codec2/components/avc/C2SoftAvcEnc.h
@@ -196,6 +196,7 @@
std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
+ std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
uint32_t mOutBufferSize;
UWORD32 mHeaderGenerated;
@@ -229,6 +230,7 @@
c2_status_t setProfileParams();
c2_status_t setDeblockParams();
c2_status_t setVbvParams();
+ c2_status_t setVuiParams();
void logVersion();
c2_status_t setEncodeArgs(
ive_video_encode_ip_t *ps_encode_ip,
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index 436a2c4..4bc1777 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -25,6 +25,7 @@
#include <media/stagefright/foundation/AUtils.h>
#include <C2Debug.h>
+#include <Codec2Mapper.h>
#include <C2PlatformSupport.h>
#include <Codec2BufferUtils.h>
#include <SimpleC2Interface.h>
@@ -208,6 +209,42 @@
.withSetter(
Setter<decltype(*mSyncFramePeriod)>::StrictValueWithNoDeps)
.build());
+
+ addParameter(
+ DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
+ .withDefault(new C2StreamColorAspectsInfo::input(
+ 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+ .withFields({
+ C2F(mColorAspects, range).inRange(
+ C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
+ C2F(mColorAspects, primaries).inRange(
+ C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+ C2F(mColorAspects, transfer).inRange(
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
+ C2F(mColorAspects, matrix).inRange(
+ C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
+ })
+ .withSetter(ColorAspectsSetter)
+ .build());
+
+ addParameter(
+ DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
+ .withDefault(new C2StreamColorAspectsInfo::output(
+ 0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+ .withFields({
+ C2F(mCodedColorAspects, range).inRange(
+ C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
+ C2F(mCodedColorAspects, primaries).inRange(
+ C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+ C2F(mCodedColorAspects, transfer).inRange(
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
+ C2F(mCodedColorAspects, matrix).inRange(
+ C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
+ })
+ .withSetter(CodedColorAspectsSetter, mColorAspects)
+ .build());
}
static C2R InputDelaySetter(
@@ -402,6 +439,34 @@
std::shared_ptr<C2StreamGopTuning::output> getGop_l() const {
return mGop;
}
+ static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me) {
+ (void)mayBlock;
+ if (me.v.range > C2Color::RANGE_OTHER) {
+ me.set().range = C2Color::RANGE_OTHER;
+ }
+ if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+ me.set().primaries = C2Color::PRIMARIES_OTHER;
+ }
+ if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+ me.set().transfer = C2Color::TRANSFER_OTHER;
+ }
+ if (me.v.matrix > C2Color::MATRIX_OTHER) {
+ me.set().matrix = C2Color::MATRIX_OTHER;
+ }
+ return C2R::Ok();
+ }
+ static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me,
+ const C2P<C2StreamColorAspectsInfo::input> &coded) {
+ (void)mayBlock;
+ me.set().range = coded.v.range;
+ me.set().primaries = coded.v.primaries;
+ me.set().transfer = coded.v.transfer;
+ me.set().matrix = coded.v.matrix;
+ return C2R::Ok();
+ }
+ std::shared_ptr<C2StreamColorAspectsInfo::output> getCodedColorAspects_l() {
+ return mCodedColorAspects;
+ }
private:
std::shared_ptr<C2StreamUsageTuning::input> mUsage;
@@ -415,6 +480,8 @@
std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
std::shared_ptr<C2StreamSyncFrameIntervalTuning::output> mSyncFramePeriod;
std::shared_ptr<C2StreamGopTuning::output> mGop;
+ std::shared_ptr<C2StreamColorAspectsInfo::input> mColorAspects;
+ std::shared_ptr<C2StreamColorAspectsInfo::output> mCodedColorAspects;
};
static size_t GetCPUCoreCount() {
@@ -533,6 +600,32 @@
mBframes = maxBframes;
}
}
+ ColorAspects sfAspects;
+ if (!C2Mapper::map(mColorAspects->primaries, &sfAspects.mPrimaries)) {
+ sfAspects.mPrimaries = android::ColorAspects::PrimariesUnspecified;
+ }
+ if (!C2Mapper::map(mColorAspects->range, &sfAspects.mRange)) {
+ sfAspects.mRange = android::ColorAspects::RangeUnspecified;
+ }
+ if (!C2Mapper::map(mColorAspects->matrix, &sfAspects.mMatrixCoeffs)) {
+ sfAspects.mMatrixCoeffs = android::ColorAspects::MatrixUnspecified;
+ }
+ if (!C2Mapper::map(mColorAspects->transfer, &sfAspects.mTransfer)) {
+ sfAspects.mTransfer = android::ColorAspects::TransferUnspecified;
+ }
+ int32_t primaries, transfer, matrixCoeffs;
+ bool range;
+ ColorUtils::convertCodecColorAspectsToIsoAspects(sfAspects,
+ &primaries,
+ &transfer,
+ &matrixCoeffs,
+ &range);
+ mEncParams.s_out_strm_prms.i4_vui_enable = 1;
+ mEncParams.s_vui_sei_prms.u1_colour_description_present_flag = 1;
+ mEncParams.s_vui_sei_prms.u1_colour_primaries = primaries;
+ mEncParams.s_vui_sei_prms.u1_transfer_characteristics = transfer;
+ mEncParams.s_vui_sei_prms.u1_matrix_coefficients = matrixCoeffs;
+ mEncParams.s_vui_sei_prms.u1_video_full_range_flag = range;
// update configuration
mEncParams.s_src_prms.i4_width = mSize->width;
mEncParams.s_src_prms.i4_height = mSize->height;
@@ -629,6 +722,7 @@
mQuality = mIntf->getQuality_l();
mGop = mIntf->getGop_l();
mRequestSync = mIntf->getRequestSync_l();
+ mColorAspects = mIntf->getCodedColorAspects_l();
}
c2_status_t status = initEncParams();
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.h b/media/codec2/components/hevc/C2SoftHevcEnc.h
index 5ea4602..9dbf682 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.h
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.h
@@ -89,6 +89,7 @@
std::shared_ptr<C2StreamQualityTuning::output> mQuality;
std::shared_ptr<C2StreamGopTuning::output> mGop;
std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
+ std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
#ifdef FILE_DUMP_ENABLE
char mInFile[200];
char mOutFile[200];
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.h b/media/codec2/components/vpx/C2SoftVpxEnc.h
index 5e34b8a..c98b802 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.h
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.h
@@ -345,6 +345,42 @@
.withFields({C2F(mRequestSync, value).oneOf({ C2_FALSE, C2_TRUE }) })
.withSetter(Setter<decltype(*mRequestSync)>::NonStrictValueWithNoDeps)
.build());
+
+ addParameter(
+ DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
+ .withDefault(new C2StreamColorAspectsInfo::input(
+ 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+ .withFields({
+ C2F(mColorAspects, range).inRange(
+ C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
+ C2F(mColorAspects, primaries).inRange(
+ C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+ C2F(mColorAspects, transfer).inRange(
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
+ C2F(mColorAspects, matrix).inRange(
+ C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
+ })
+ .withSetter(ColorAspectsSetter)
+ .build());
+
+ addParameter(
+ DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
+ .withDefault(new C2StreamColorAspectsInfo::output(
+ 0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
+ .withFields({
+ C2F(mCodedColorAspects, range).inRange(
+ C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
+ C2F(mCodedColorAspects, primaries).inRange(
+ C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
+ C2F(mCodedColorAspects, transfer).inRange(
+ C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
+ C2F(mCodedColorAspects, matrix).inRange(
+ C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
+ })
+ .withSetter(CodedColorAspectsSetter, mColorAspects)
+ .build());
}
static C2R BitrateSetter(bool mayBlock, C2P<C2StreamBitrateInfo::output> &me) {
@@ -415,6 +451,31 @@
double period = mSyncFramePeriod->value / 1e6 * mFrameRate->value;
return (uint32_t)c2_max(c2_min(period + 0.5, double(UINT32_MAX)), 1.);
}
+ static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me) {
+ (void)mayBlock;
+ if (me.v.range > C2Color::RANGE_OTHER) {
+ me.set().range = C2Color::RANGE_OTHER;
+ }
+ if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
+ me.set().primaries = C2Color::PRIMARIES_OTHER;
+ }
+ if (me.v.transfer > C2Color::TRANSFER_OTHER) {
+ me.set().transfer = C2Color::TRANSFER_OTHER;
+ }
+ if (me.v.matrix > C2Color::MATRIX_OTHER) {
+ me.set().matrix = C2Color::MATRIX_OTHER;
+ }
+ return C2R::Ok();
+ }
+ static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me,
+ const C2P<C2StreamColorAspectsInfo::input> &coded) {
+ (void)mayBlock;
+ me.set().range = coded.v.range;
+ me.set().primaries = coded.v.primaries;
+ me.set().transfer = coded.v.transfer;
+ me.set().matrix = coded.v.matrix;
+ return C2R::Ok();
+ }
private:
std::shared_ptr<C2StreamUsageTuning::input> mUsage;
@@ -427,6 +488,8 @@
std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
+ std::shared_ptr<C2StreamColorAspectsInfo::input> mColorAspects;
+ std::shared_ptr<C2StreamColorAspectsInfo::output> mCodedColorAspects;
};
} // namespace android
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
index efc5813..58a568e 100644
--- a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
@@ -23,21 +23,18 @@
#include <stdio.h>
#include <algorithm>
-#include <C2AllocatorIon.h>
#include <C2Buffer.h>
#include <C2BufferPriv.h>
#include <C2Config.h>
#include <C2Debug.h>
#include <codec2/hidl/client.h>
-using android::C2AllocatorIon;
-
#include "media_c2_hidl_test_common.h"
using DecodeTestParameters = std::tuple<std::string, std::string, uint32_t, bool>;
-static std::vector<DecodeTestParameters> kDecodeTestParameters;
+static std::vector<DecodeTestParameters> gDecodeTestParameters;
using CsdFlushTestParameters = std::tuple<std::string, std::string, bool>;
-static std::vector<CsdFlushTestParameters> kCsdFlushTestParameters;
+static std::vector<CsdFlushTestParameters> gCsdFlushTestParameters;
struct CompToURL {
std::string mime;
@@ -45,7 +42,7 @@
std::string info;
};
-std::vector<CompToURL> kCompToURL = {
+std::vector<CompToURL> gCompToURL = {
{"mp4a-latm", "bbb_aac_stereo_128kbps_48000hz.aac", "bbb_aac_stereo_128kbps_48000hz.info"},
{"mp4a-latm", "bbb_aac_stereo_128kbps_48000hz.aac",
"bbb_aac_stereo_128kbps_48000hz_multi_frame.info"},
@@ -290,11 +287,11 @@
// LookUpTable of clips and metadata for component testing
void Codec2AudioDecHidlTestBase::GetURLForComponent(char* mURL, char* info, size_t streamIndex) {
int streamCount = 0;
- for (size_t i = 0; i < kCompToURL.size(); ++i) {
- if (mMime.find(kCompToURL[i].mime) != std::string::npos) {
+ for (size_t i = 0; i < gCompToURL.size(); ++i) {
+ if (mMime.find(gCompToURL[i].mime) != std::string::npos) {
if (streamCount == streamIndex) {
- strcat(mURL, kCompToURL[i].mURL.c_str());
- strcat(info, kCompToURL[i].info.c_str());
+ strcat(mURL, gCompToURL[i].mURL.c_str());
+ strcat(info, gCompToURL[i].info.c_str());
return;
}
streamCount++;
@@ -859,36 +856,36 @@
ASSERT_EQ(mComponent->stop(), C2_OK);
}
-INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2AudioDecHidlTest, testing::ValuesIn(kTestParameters),
+INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2AudioDecHidlTest, testing::ValuesIn(gTestParameters),
PrintInstanceTupleNameToString<>);
// DecodeTest with StreamIndex and EOS / No EOS
INSTANTIATE_TEST_SUITE_P(StreamIndexAndEOS, Codec2AudioDecDecodeTest,
- testing::ValuesIn(kDecodeTestParameters),
+ testing::ValuesIn(gDecodeTestParameters),
PrintInstanceTupleNameToString<>);
INSTANTIATE_TEST_SUITE_P(CsdInputs, Codec2AudioDecCsdInputTests,
- testing::ValuesIn(kCsdFlushTestParameters),
+ testing::ValuesIn(gCsdFlushTestParameters),
PrintInstanceTupleNameToString<>);
} // anonymous namespace
int main(int argc, char** argv) {
parseArgs(argc, argv);
- kTestParameters = getTestParameters(C2Component::DOMAIN_AUDIO, C2Component::KIND_DECODER);
- for (auto params : kTestParameters) {
- kDecodeTestParameters.push_back(
+ gTestParameters = getTestParameters(C2Component::DOMAIN_AUDIO, C2Component::KIND_DECODER);
+ for (auto params : gTestParameters) {
+ gDecodeTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 0, false));
- kDecodeTestParameters.push_back(
+ gDecodeTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 0, true));
- kDecodeTestParameters.push_back(
+ gDecodeTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 1, false));
- kDecodeTestParameters.push_back(
+ gDecodeTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 1, true));
- kCsdFlushTestParameters.push_back(
+ gCsdFlushTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), true));
- kCsdFlushTestParameters.push_back(
+ gCsdFlushTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), false));
}
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
index 562c77f..92b53a0 100644
--- a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
@@ -24,20 +24,17 @@
#include <algorithm>
#include <fstream>
-#include <C2AllocatorIon.h>
#include <C2Buffer.h>
#include <C2BufferPriv.h>
#include <C2Config.h>
#include <C2Debug.h>
#include <codec2/hidl/client.h>
-using android::C2AllocatorIon;
-
#include "media_c2_hidl_test_common.h"
using EncodeTestParameters = std::tuple<std::string, std::string, bool, int32_t>;
-static std::vector<EncodeTestParameters> kEncodeTestParameters;
+static std::vector<EncodeTestParameters> gEncodeTestParameters;
class LinearBuffer : public C2Buffer {
public:
@@ -45,6 +42,8 @@
: C2Buffer({block->share(block->offset(), block->size(), ::C2Fence())}) {}
};
+constexpr uint32_t kMaxSamplesPerFrame = 256;
+
namespace {
class Codec2AudioEncHidlTestBase : public ::testing::Test {
@@ -98,7 +97,7 @@
// Get the test parameters from GetParam call.
virtual void getParams() {}
- void GetURLForComponent(char* mURL);
+ void GetURLForComponent(char* mURL, int32_t channelCount, int32_t sampleRate);
// callback function to process onWorkDone received by Listener
void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
@@ -223,53 +222,105 @@
return false;
}
+c2_status_t getChannelCount(const std::shared_ptr<android::Codec2Client::Component>& component,
+ int32_t* nChannels) {
+ std::unique_ptr<C2StreamChannelCountInfo::input> channelCount =
+ std::make_unique<C2StreamChannelCountInfo::input>();
+ std::vector<C2FieldSupportedValuesQuery> validValueInfos = {
+ C2FieldSupportedValuesQuery::Current(
+ C2ParamField(channelCount.get(), &C2StreamChannelCountInfo::value))};
+ c2_status_t c2err = component->querySupportedValues(validValueInfos, C2_DONT_BLOCK);
+ if (c2err != C2_OK || validValueInfos.size() != 1u) {
+ ALOGE("querySupportedValues_vb failed for channelCount");
+ return c2err;
+ }
+
+ // setting default value of channelCount
+ *nChannels = 1;
+ const auto& c2FSV = validValueInfos[0].values;
+ switch (c2FSV.type) {
+ case C2FieldSupportedValues::type_t::RANGE: {
+ const auto& range = c2FSV.range;
+ uint32_t rmax = (uint32_t)(range.max).ref<uint32_t>();
+ if (rmax >= 2) {
+ *nChannels = 2;
+ } else {
+ *nChannels = 1;
+ }
+ break;
+ }
+ case C2FieldSupportedValues::type_t::VALUES: {
+ for (const C2Value::Primitive& prim : c2FSV.values) {
+ if ((uint32_t)prim.ref<uint32_t>() == 2) {
+ *nChannels = 2;
+ } else if ((uint32_t)prim.ref<uint32_t>() == 1) {
+ *nChannels = 1;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return C2_OK;
+}
+
+c2_status_t getSampleRate(const std::shared_ptr<android::Codec2Client::Component>& component,
+ int32_t* nSampleRate) {
+ // Use the default sample rate for components
+ std::vector<std::unique_ptr<C2Param>> queried;
+ c2_status_t c2err = component->query({}, {C2StreamSampleRateInfo::input::PARAM_TYPE},
+ C2_DONT_BLOCK, &queried);
+ if (c2err != C2_OK || queried.size() == 0) return c2err;
+
+ size_t offset = sizeof(C2Param);
+ C2Param* param = queried[0].get();
+ *nSampleRate = *(int32_t*)((uint8_t*)param + offset);
+
+ return C2_OK;
+}
+
+c2_status_t getSamplesPerFrame(const std::shared_ptr<android::Codec2Client::Component>& component,
+ int32_t nChannels, int32_t* samplesPerFrame) {
+ std::vector<std::unique_ptr<C2Param>> queried;
+ c2_status_t c2err = component->query({}, {C2StreamMaxBufferSizeInfo::input::PARAM_TYPE},
+ C2_DONT_BLOCK, &queried);
+ if (c2err != C2_OK || queried.size() == 0) return c2err;
+
+ size_t offset = sizeof(C2Param);
+ C2Param* param = queried[0].get();
+ uint32_t maxInputSize = *(uint32_t*)((uint8_t*)param + offset);
+ *samplesPerFrame = std::min((maxInputSize / (nChannels * 2)), kMaxSamplesPerFrame);
+
+ return C2_OK;
+}
+
// Get config params for a component
-bool getConfigParams(std::string mime, int32_t* nChannels, int32_t* nSampleRate,
- int32_t* samplesPerFrame) {
- if (mime.find("mp4a-latm") != std::string::npos) {
- *nChannels = 2;
- *nSampleRate = 48000;
- *samplesPerFrame = 1024;
- } else if (mime.find("flac") != std::string::npos) {
- *nChannels = 2;
- *nSampleRate = 48000;
- *samplesPerFrame = 1152;
- } else if (mime.find("opus") != std::string::npos) {
- *nChannels = 2;
- *nSampleRate = 48000;
- *samplesPerFrame = 960;
- } else if (mime.find("3gpp") != std::string::npos) {
- *nChannels = 1;
- *nSampleRate = 8000;
- *samplesPerFrame = 160;
- } else if (mime.find("amr-wb") != std::string::npos) {
- *nChannels = 1;
- *nSampleRate = 16000;
- *samplesPerFrame = 160;
- } else
- return false;
+bool getConfigParams(const std::shared_ptr<android::Codec2Client::Component>& component,
+ int32_t* nChannels, int32_t* nSampleRate, int32_t* samplesPerFrame) {
+ c2_status_t status = getChannelCount(component, nChannels);
+ if (status != C2_OK) return false;
+
+ status = getSampleRate(component, nSampleRate);
+ if (status != C2_OK) return false;
+
+ status = getSamplesPerFrame(component, *nChannels, samplesPerFrame);
+ if (status != C2_OK) return false;
return true;
}
// LookUpTable of clips and metadata for component testing
-void Codec2AudioEncHidlTestBase::GetURLForComponent(char* mURL) {
- struct CompToURL {
- std::string mime;
- const char* mURL;
- };
- static const CompToURL kCompToURL[] = {
- {"mp4a-latm", "bbb_raw_2ch_48khz_s16le.raw"}, {"3gpp", "bbb_raw_1ch_8khz_s16le.raw"},
- {"amr-wb", "bbb_raw_1ch_16khz_s16le.raw"}, {"flac", "bbb_raw_2ch_48khz_s16le.raw"},
- {"opus", "bbb_raw_2ch_48khz_s16le.raw"},
- };
-
- for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
- if (mMime.find(kCompToURL[i].mime) != std::string::npos) {
- strcat(mURL, kCompToURL[i].mURL);
- return;
- }
+void Codec2AudioEncHidlTestBase::GetURLForComponent(char* mURL, int32_t channelCount,
+ int32_t sampleRate) {
+ std::string rawInput = "bbb_raw_1ch_8khz_s16le.raw";
+ if (channelCount == 1 && sampleRate == 16000) {
+ rawInput = "bbb_raw_1ch_16khz_s16le.raw";
+ } else if (channelCount == 2) {
+ rawInput = "bbb_raw_2ch_48khz_s16le.raw";
}
+
+ strcat(mURL, rawInput.c_str());
}
void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
@@ -283,9 +334,17 @@
uint32_t frameID = 0;
uint32_t maxRetry = 0;
- int bytesCount = samplesPerFrame * nChannels * 2;
+ uint32_t bytesCount = samplesPerFrame * nChannels * 2;
int32_t timestampIncr = (int)(((float)samplesPerFrame / nSampleRate) * 1000000);
uint64_t timestamp = 0;
+
+ // get length of file:
+ int32_t currPos = eleStream.tellg();
+ eleStream.seekg(0, eleStream.end);
+ uint32_t remainingBytes = (uint32_t)eleStream.tellg() - currPos;
+ eleStream.seekg(currPos, eleStream.beg);
+
+ nFrames = std::min(nFrames, remainingBytes / bytesCount);
while (1) {
if (nFrames == 0) break;
uint32_t flags = 0;
@@ -319,7 +378,12 @@
char* data = (char*)malloc(bytesCount);
ASSERT_NE(data, nullptr);
eleStream.read(data, bytesCount);
- ASSERT_EQ(eleStream.gcount(), bytesCount);
+ // if we have reached at the end of input stream, signal eos
+ if (eleStream.gcount() < bytesCount) {
+ bytesCount = eleStream.gcount();
+ if (signalEOS) flags |= C2FrameData::FLAG_END_OF_STREAM;
+ }
+
std::shared_ptr<C2LinearBlock> block;
ASSERT_EQ(C2_OK,
linearPool->fetchLinearBlock(
@@ -373,9 +437,6 @@
TEST_P(Codec2AudioEncEncodeTest, EncodeTest) {
ALOGV("EncodeTest");
if (mDisableTest) GTEST_SKIP() << "Test is disabled";
- char mURL[512];
- strcpy(mURL, sResourceDir.c_str());
- GetURLForComponent(mURL);
bool signalEOS = std::get<2>(GetParam());
// Ratio w.r.t to mInputMaxBufSize
int32_t inputMaxBufRatio = std::get<3>(GetParam());
@@ -384,7 +445,7 @@
int32_t nSampleRate;
int32_t samplesPerFrame;
- if (!getConfigParams(mMime, &nChannels, &nSampleRate, &samplesPerFrame)) {
+ if (!getConfigParams(mComponent, &nChannels, &nSampleRate, &samplesPerFrame)) {
std::cout << "Failed to get the config params for " << mComponentName << "\n";
std::cout << "[ WARN ] Test Skipped \n";
return;
@@ -398,6 +459,10 @@
std::cout << "[ WARN ] Test Skipped \n";
return;
}
+ char mURL[512];
+ strcpy(mURL, sResourceDir.c_str());
+ GetURLForComponent(mURL, nChannels, nSampleRate);
+
ASSERT_EQ(mComponent->start(), C2_OK);
std::ifstream eleStream;
uint32_t numFrames = 16;
@@ -479,16 +544,12 @@
description("Test Request for flush");
if (mDisableTest) GTEST_SKIP() << "Test is disabled";
- char mURL[512];
- strcpy(mURL, sResourceDir.c_str());
- GetURLForComponent(mURL);
-
mFlushedIndices.clear();
int32_t nChannels;
int32_t nSampleRate;
int32_t samplesPerFrame;
- if (!getConfigParams(mMime, &nChannels, &nSampleRate, &samplesPerFrame)) {
+ if (!getConfigParams(mComponent, &nChannels, &nSampleRate, &samplesPerFrame)) {
std::cout << "Failed to get the config params for " << mComponentName << "\n";
std::cout << "[ WARN ] Test Skipped \n";
return;
@@ -498,6 +559,10 @@
std::cout << "[ WARN ] Test Skipped \n";
return;
}
+ char mURL[512];
+ strcpy(mURL, sResourceDir.c_str());
+ GetURLForComponent(mURL, nChannels, nSampleRate);
+
ASSERT_EQ(mComponent->start(), C2_OK);
std::ifstream eleStream;
@@ -544,26 +609,25 @@
description("Encodes input file for different channel count");
if (mDisableTest) GTEST_SKIP() << "Test is disabled";
- char mURL[512];
- strcpy(mURL, sResourceDir.c_str());
- GetURLForComponent(mURL);
-
- std::ifstream eleStream;
- eleStream.open(mURL, std::ifstream::binary);
- ASSERT_EQ(eleStream.is_open(), true) << mURL << " file not found";
- ALOGV("mURL : %s", mURL);
-
int32_t nSampleRate;
int32_t samplesPerFrame;
int32_t nChannels;
int32_t numFrames = 16;
int32_t maxChannelCount = 8;
- if (!getConfigParams(mMime, &nChannels, &nSampleRate, &samplesPerFrame)) {
+ if (!getConfigParams(mComponent, &nChannels, &nSampleRate, &samplesPerFrame)) {
std::cout << "Failed to get the config params for " << mComponentName << "\n";
std::cout << "[ WARN ] Test Skipped \n";
return;
}
+ char mURL[512];
+ strcpy(mURL, sResourceDir.c_str());
+ GetURLForComponent(mURL, nChannels, nSampleRate);
+
+ std::ifstream eleStream;
+ eleStream.open(mURL, std::ifstream::binary);
+ ASSERT_EQ(eleStream.is_open(), true) << mURL << " file not found";
+ ALOGV("mURL : %s", mURL);
uint64_t prevOutputSize = 0u;
uint32_t prevChannelCount = 0u;
@@ -591,8 +655,11 @@
}
// To check if the input stream is sufficient to encode for the higher channel count
+ struct stat buf;
+ stat(mURL, &buf);
+ size_t fileSize = buf.st_size;
int32_t bytesCount = (samplesPerFrame * nChannels * 2) * numFrames;
- if (eleStream.gcount() < bytesCount) {
+ if (fileSize < bytesCount) {
std::cout << "[ WARN ] Test Skipped for ChannelCount " << nChannels
<< " because of insufficient input data\n";
continue;
@@ -616,9 +683,6 @@
// blocking call to ensures application to Wait till all the inputs are consumed
waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue);
- // Validate output size based on chosen ChannelCount
- EXPECT_GE(mOutputSize, prevOutputSize);
-
prevChannelCount = nChannels;
prevOutputSize = mOutputSize;
@@ -633,7 +697,8 @@
ASSERT_TRUE(mCsd) << "CSD buffer missing";
}
ASSERT_TRUE(mEos);
- ASSERT_EQ(mComponent->stop(), C2_OK);
+ // TODO(b/147348711) Use reset instead of stop when using the same instance of codec.
+ ASSERT_EQ(mComponent->reset(), C2_OK);
mFramesReceived = 0;
mOutputSize = 0;
mEos = false;
@@ -646,25 +711,24 @@
description("Encodes input file for different SampleRate");
if (mDisableTest) GTEST_SKIP() << "Test is disabled";
- char mURL[512];
- strcpy(mURL, sResourceDir.c_str());
- GetURLForComponent(mURL);
-
- std::ifstream eleStream;
- eleStream.open(mURL, std::ifstream::binary);
- ASSERT_EQ(eleStream.is_open(), true) << mURL << " file not found";
- ALOGV("mURL : %s", mURL);
-
int32_t nSampleRate;
int32_t samplesPerFrame;
int32_t nChannels;
int32_t numFrames = 16;
- if (!getConfigParams(mMime, &nChannels, &nSampleRate, &samplesPerFrame)) {
+ if (!getConfigParams(mComponent, &nChannels, &nSampleRate, &samplesPerFrame)) {
std::cout << "Failed to get the config params for " << mComponentName << "\n";
std::cout << "[ WARN ] Test Skipped \n";
return;
}
+ char mURL[512];
+ strcpy(mURL, sResourceDir.c_str());
+ GetURLForComponent(mURL, nChannels, nSampleRate);
+
+ std::ifstream eleStream;
+ eleStream.open(mURL, std::ifstream::binary);
+ ASSERT_EQ(eleStream.is_open(), true) << mURL << " file not found";
+ ALOGV("mURL : %s", mURL);
int32_t sampleRateValues[] = {1000, 8000, 16000, 24000, 48000, 96000, 192000};
@@ -694,8 +758,11 @@
}
// To check if the input stream is sufficient to encode for the higher SampleRate
+ struct stat buf;
+ stat(mURL, &buf);
+ size_t fileSize = buf.st_size;
int32_t bytesCount = (samplesPerFrame * nChannels * 2) * numFrames;
- if (eleStream.gcount() < bytesCount) {
+ if (fileSize < bytesCount) {
std::cout << "[ WARN ] Test Skipped for SampleRate " << nSampleRate
<< " because of insufficient input data\n";
continue;
@@ -719,12 +786,6 @@
// blocking call to ensures application to Wait till all the inputs are consumed
waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue);
- // Validate output size based on chosen samplerate
- if (prevSampleRate >= nSampleRate) {
- EXPECT_LE(mOutputSize, prevOutputSize);
- } else {
- EXPECT_GT(mOutputSize, prevOutputSize);
- }
prevSampleRate = nSampleRate;
prevOutputSize = mOutputSize;
@@ -739,7 +800,8 @@
ASSERT_TRUE(mCsd) << "CSD buffer missing";
}
ASSERT_TRUE(mEos);
- ASSERT_EQ(mComponent->stop(), C2_OK);
+ // TODO(b/147348711) Use reset instead of stop when using the same instance of codec.
+ ASSERT_EQ(mComponent->reset(), C2_OK);
mFramesReceived = 0;
mOutputSize = 0;
mEos = false;
@@ -748,28 +810,28 @@
}
}
-INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2AudioEncHidlTest, testing::ValuesIn(kTestParameters),
+INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2AudioEncHidlTest, testing::ValuesIn(gTestParameters),
PrintInstanceTupleNameToString<>);
// EncodeTest with EOS / No EOS and inputMaxBufRatio
// inputMaxBufRatio is ratio w.r.t. to mInputMaxBufSize
INSTANTIATE_TEST_SUITE_P(EncodeTest, Codec2AudioEncEncodeTest,
- testing::ValuesIn(kEncodeTestParameters),
+ testing::ValuesIn(gEncodeTestParameters),
PrintInstanceTupleNameToString<>);
} // anonymous namespace
int main(int argc, char** argv) {
parseArgs(argc, argv);
- kTestParameters = getTestParameters(C2Component::DOMAIN_AUDIO, C2Component::KIND_ENCODER);
- for (auto params : kTestParameters) {
- kEncodeTestParameters.push_back(
+ gTestParameters = getTestParameters(C2Component::DOMAIN_AUDIO, C2Component::KIND_ENCODER);
+ for (auto params : gTestParameters) {
+ gEncodeTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), false, 1));
- kEncodeTestParameters.push_back(
+ gEncodeTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), false, 2));
- kEncodeTestParameters.push_back(
+ gEncodeTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), true, 1));
- kEncodeTestParameters.push_back(
+ gEncodeTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), true, 2));
}
diff --git a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h
index e74f247..2222aaf 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h
+++ b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h
@@ -41,7 +41,7 @@
using namespace ::std::chrono;
using TestParameters = std::tuple<std::string, std::string>;
-static std::vector<TestParameters> kTestParameters;
+static std::vector<TestParameters> gTestParameters;
// Resource directory
extern std::string sResourceDir;
diff --git a/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp b/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
index 29acd33..ffec897 100644
--- a/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
@@ -54,7 +54,7 @@
namespace {
using InputTestParameters = std::tuple<std::string, std::string, uint32_t, bool>;
-static std::vector<InputTestParameters> kInputTestParameters;
+static std::vector<InputTestParameters> gInputTestParameters;
// google.codec2 Component test setup
class Codec2ComponentHidlTestBase : public ::testing::Test {
@@ -345,28 +345,28 @@
ASSERT_EQ(mComponent->reset(), C2_OK);
}
-INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2ComponentHidlTest, testing::ValuesIn(kTestParameters),
+INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2ComponentHidlTest, testing::ValuesIn(gTestParameters),
PrintInstanceTupleNameToString<>);
INSTANTIATE_TEST_CASE_P(NonStdInputs, Codec2ComponentInputTests,
- testing::ValuesIn(kInputTestParameters), PrintInstanceTupleNameToString<>);
+ testing::ValuesIn(gInputTestParameters), PrintInstanceTupleNameToString<>);
} // anonymous namespace
// TODO: Add test for Invalid work,
// TODO: Add test for Invalid states
int main(int argc, char** argv) {
parseArgs(argc, argv);
- kTestParameters = getTestParameters();
- for (auto params : kTestParameters) {
- kInputTestParameters.push_back(
+ gTestParameters = getTestParameters();
+ for (auto params : gTestParameters) {
+ gInputTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 0, true));
- kInputTestParameters.push_back(std::make_tuple(std::get<0>(params), std::get<1>(params),
+ gInputTestParameters.push_back(std::make_tuple(std::get<0>(params), std::get<1>(params),
C2FrameData::FLAG_END_OF_STREAM, true));
- kInputTestParameters.push_back(
+ gInputTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 0, false));
- kInputTestParameters.push_back(std::make_tuple(std::get<0>(params), std::get<1>(params),
+ gInputTestParameters.push_back(std::make_tuple(std::get<0>(params), std::get<1>(params),
C2FrameData::FLAG_CODEC_CONFIG, false));
- kInputTestParameters.push_back(std::make_tuple(std::get<0>(params), std::get<1>(params),
+ gInputTestParameters.push_back(std::make_tuple(std::get<0>(params), std::get<1>(params),
C2FrameData::FLAG_END_OF_STREAM, false));
}
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
index d0a1c31..8d917b3 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
@@ -24,7 +24,6 @@
#include <openssl/md5.h>
-#include <C2AllocatorIon.h>
#include <C2Buffer.h>
#include <C2BufferPriv.h>
#include <C2Config.h>
@@ -35,16 +34,14 @@
#include <gui/IProducerListener.h>
#include <system/window.h>
-using android::C2AllocatorIon;
-
#include "media_c2_hidl_test_common.h"
#include "media_c2_video_hidl_test_common.h"
using DecodeTestParameters = std::tuple<std::string, std::string, uint32_t, bool>;
-static std::vector<DecodeTestParameters> kDecodeTestParameters;
+static std::vector<DecodeTestParameters> gDecodeTestParameters;
using CsdFlushTestParameters = std::tuple<std::string, std::string, bool>;
-static std::vector<CsdFlushTestParameters> kCsdFlushTestParameters;
+static std::vector<CsdFlushTestParameters> gCsdFlushTestParameters;
struct CompToURL {
std::string mime;
@@ -52,7 +49,7 @@
std::string info;
std::string chksum;
};
-std::vector<CompToURL> kCompToURL = {
+std::vector<CompToURL> gCompToURL = {
{"avc", "bbb_avc_176x144_300kbps_60fps.h264", "bbb_avc_176x144_300kbps_60fps.info",
"bbb_avc_176x144_300kbps_60fps_chksum.md5"},
{"avc", "bbb_avc_640x360_768kbps_30fps.h264", "bbb_avc_640x360_768kbps_30fps.info",
@@ -365,12 +362,12 @@
void Codec2VideoDecHidlTestBase::GetURLChksmForComponent(char* mURL, char* info, char* chksum,
size_t streamIndex) {
int streamCount = 0;
- for (size_t i = 0; i < kCompToURL.size(); ++i) {
- if (mMime.find(kCompToURL[i].mime) != std::string::npos) {
+ for (size_t i = 0; i < gCompToURL.size(); ++i) {
+ if (mMime.find(gCompToURL[i].mime) != std::string::npos) {
if (streamCount == streamIndex) {
- strcat(mURL, kCompToURL[i].mURL.c_str());
- strcat(info, kCompToURL[i].info.c_str());
- strcat(chksum, kCompToURL[i].chksum.c_str());
+ strcat(mURL, gCompToURL[i].mURL.c_str());
+ strcat(info, gCompToURL[i].info.c_str());
+ strcat(chksum, gCompToURL[i].chksum.c_str());
return;
}
streamCount++;
@@ -1074,16 +1071,16 @@
ASSERT_EQ(mComponent->stop(), C2_OK);
}
-INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2VideoDecHidlTest, testing::ValuesIn(kTestParameters),
+INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2VideoDecHidlTest, testing::ValuesIn(gTestParameters),
PrintInstanceTupleNameToString<>);
// DecodeTest with StreamIndex and EOS / No EOS
INSTANTIATE_TEST_SUITE_P(StreamIndexAndEOS, Codec2VideoDecDecodeTest,
- testing::ValuesIn(kDecodeTestParameters),
+ testing::ValuesIn(gDecodeTestParameters),
PrintInstanceTupleNameToString<>);
INSTANTIATE_TEST_SUITE_P(CsdInputs, Codec2VideoDecCsdInputTests,
- testing::ValuesIn(kCsdFlushTestParameters),
+ testing::ValuesIn(gCsdFlushTestParameters),
PrintInstanceTupleNameToString<>);
} // anonymous namespace
@@ -1091,24 +1088,24 @@
// TODO : Video specific configuration Test
int main(int argc, char** argv) {
parseArgs(argc, argv);
- kTestParameters = getTestParameters(C2Component::DOMAIN_VIDEO, C2Component::KIND_DECODER);
- for (auto params : kTestParameters) {
- kDecodeTestParameters.push_back(
+ gTestParameters = getTestParameters(C2Component::DOMAIN_VIDEO, C2Component::KIND_DECODER);
+ for (auto params : gTestParameters) {
+ gDecodeTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 0, false));
- kDecodeTestParameters.push_back(
+ gDecodeTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 0, true));
- kDecodeTestParameters.push_back(
+ gDecodeTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 1, false));
- kDecodeTestParameters.push_back(
+ gDecodeTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 1, true));
- kDecodeTestParameters.push_back(
+ gDecodeTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 2, false));
- kDecodeTestParameters.push_back(
+ gDecodeTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 2, true));
- kCsdFlushTestParameters.push_back(
+ gCsdFlushTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), true));
- kCsdFlushTestParameters.push_back(
+ gCsdFlushTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), false));
}
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
index 23ceff4..dfd649d 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
@@ -23,15 +23,12 @@
#include <stdio.h>
#include <fstream>
-#include <C2AllocatorIon.h>
#include <C2Buffer.h>
#include <C2BufferPriv.h>
#include <C2Config.h>
#include <C2Debug.h>
#include <codec2/hidl/client.h>
-using android::C2AllocatorIon;
-
#include "media_c2_hidl_test_common.h"
#include "media_c2_video_hidl_test_common.h"
@@ -42,10 +39,10 @@
};
using EncodeTestParameters = std::tuple<std::string, std::string, bool, bool, bool>;
-static std::vector<EncodeTestParameters> kEncodeTestParameters;
+static std::vector<EncodeTestParameters> gEncodeTestParameters;
using EncodeResolutionTestParameters = std::tuple<std::string, std::string, int32_t, int32_t>;
-static std::vector<EncodeResolutionTestParameters> kEncodeResolutionTestParameters;
+static std::vector<EncodeResolutionTestParameters> gEncodeResolutionTestParameters;
namespace {
@@ -706,16 +703,16 @@
ASSERT_EQ(mComponent->reset(), C2_OK);
}
-INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2VideoEncHidlTest, testing::ValuesIn(kTestParameters),
+INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2VideoEncHidlTest, testing::ValuesIn(gTestParameters),
PrintInstanceTupleNameToString<>);
INSTANTIATE_TEST_SUITE_P(NonStdSizes, Codec2VideoEncResolutionTest,
- ::testing::ValuesIn(kEncodeResolutionTestParameters),
+ ::testing::ValuesIn(gEncodeResolutionTestParameters),
PrintInstanceTupleNameToString<>);
// EncodeTest with EOS / No EOS
INSTANTIATE_TEST_SUITE_P(EncodeTestwithEOS, Codec2VideoEncEncodeTest,
- ::testing::ValuesIn(kEncodeTestParameters),
+ ::testing::ValuesIn(gEncodeTestParameters),
PrintInstanceTupleNameToString<>);
TEST_P(Codec2VideoEncHidlTest, AdaptiveBitrateTest) {
@@ -808,24 +805,24 @@
int main(int argc, char** argv) {
parseArgs(argc, argv);
- kTestParameters = getTestParameters(C2Component::DOMAIN_VIDEO, C2Component::KIND_ENCODER);
- for (auto params : kTestParameters) {
+ gTestParameters = getTestParameters(C2Component::DOMAIN_VIDEO, C2Component::KIND_ENCODER);
+ for (auto params : gTestParameters) {
for (size_t i = 0; i < 1 << 3; ++i) {
- kEncodeTestParameters.push_back(std::make_tuple(
+ gEncodeTestParameters.push_back(std::make_tuple(
std::get<0>(params), std::get<1>(params), i & 1, (i >> 1) & 1, (i >> 2) & 1));
}
- kEncodeResolutionTestParameters.push_back(
+ gEncodeResolutionTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 52, 18));
- kEncodeResolutionTestParameters.push_back(
+ gEncodeResolutionTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 365, 365));
- kEncodeResolutionTestParameters.push_back(
+ gEncodeResolutionTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 484, 362));
- kEncodeResolutionTestParameters.push_back(
+ gEncodeResolutionTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 244, 488));
- kEncodeResolutionTestParameters.push_back(
+ gEncodeResolutionTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 852, 608));
- kEncodeResolutionTestParameters.push_back(
+ gEncodeResolutionTestParameters.push_back(
std::make_tuple(std::get<0>(params), std::get<1>(params), 1400, 442));
}
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index e33a5ba..c6ff825 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -1780,7 +1780,7 @@
{
Mutexed<Output>::Locked output(mOutput);
numOutputSlots = output->numSlots;
- reorderDepth = output->buffers->getReorderDepth();
+ reorderDepth = output->buffers ? output->buffers->getReorderDepth() : 0;
}
{
Mutexed<OutputSurface>::Locked output(mOutputSurface);
diff --git a/media/libdatasource/DataSourceFactory.cpp b/media/libdatasource/DataSourceFactory.cpp
index bb6a08c..f91e3ea 100644
--- a/media/libdatasource/DataSourceFactory.cpp
+++ b/media/libdatasource/DataSourceFactory.cpp
@@ -65,6 +65,9 @@
sp<HTTPBase> mediaHTTP = httpSource;
if (mediaHTTP == NULL) {
mediaHTTP = static_cast<HTTPBase *>(CreateMediaHTTP(httpService).get());
+ if (mediaHTTP == NULL) {
+ return NULL;
+ }
}
String8 cacheConfig;
diff --git a/media/libmediatranscoding/TranscoderWrapper.cpp b/media/libmediatranscoding/TranscoderWrapper.cpp
index 5e4c671..60b780f 100644
--- a/media/libmediatranscoding/TranscoderWrapper.cpp
+++ b/media/libmediatranscoding/TranscoderWrapper.cpp
@@ -478,7 +478,7 @@
media_status_t err =
setupTranscoder(clientId, sessionId, request, callingUid, clientCb, &reason);
if (err != AMEDIA_OK) {
- ALOGI("%s: failed to setup transcoder", __FUNCTION__);
+ ALOGE("%s: failed to setup transcoder", __FUNCTION__);
logSessionEnded(reason, err);
return err;
}
@@ -613,7 +613,7 @@
Event event = *mQueue.begin();
mQueue.pop_front();
- ALOGD("%s: %s", __FUNCTION__, toString(event).c_str());
+ ALOGV("%s: %s", __FUNCTION__, toString(event).c_str());
if (event.type == Event::Abandon) {
break;
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index c19fe38..e3931b1 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -73,6 +73,8 @@
return AppOpsManager::OP_RECORD_AUDIO_HOTWORD;
case AUDIO_SOURCE_REMOTE_SUBMIX:
return AppOpsManager::OP_RECORD_AUDIO_OUTPUT;
+ case AUDIO_SOURCE_VOICE_DOWNLINK:
+ return AppOpsManager::OP_RECORD_INCOMING_PHONE_AUDIO;
case AUDIO_SOURCE_DEFAULT:
default:
return AppOpsManager::OP_RECORD_AUDIO;
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index b953c0b..451c198 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -70,7 +70,7 @@
audio_input_flags_t flags,
track_type type,
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE,
- int64_t startTimeMs = -1);
+ int32_t startFrames = -1);
virtual ~RecordTrack();
virtual status_t initCheck() const;
@@ -110,7 +110,7 @@
status_t setPreferredMicrophoneFieldDimension(float zoom);
status_t shareAudioHistory(const std::string& sharedAudioPackageName,
int64_t sharedAudioStartMs);
- int64_t startTimeMs() { return mStartTimeMs; }
+ int32_t startFrames() { return mStartFrames; }
static bool checkServerLatencySupported(
audio_format_t format, audio_input_flags_t flags) {
@@ -152,7 +152,7 @@
// used to enforce OP_RECORD_AUDIO
sp<OpRecordAudioMonitor> mOpRecordAudioMonitor;
std::string mSharedAudioPackageName = {};
- int64_t mStartTimeMs = -1;
+ int32_t mStartFrames = -1;
};
// playback track, used by PatchPanel
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 6da4543..51f3032 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -124,12 +124,26 @@
// 50 * ~20msecs = 1 second
static const int8_t kMaxTrackRetries = 50;
static const int8_t kMaxTrackStartupRetries = 50;
+
// allow less retry attempts on direct output thread.
// direct outputs can be a scarce resource in audio hardware and should
// be released as quickly as possible.
-static const int8_t kMaxTrackRetriesDirect = 2;
-
-
+// Notes:
+// 1) The retry duration kMaxTrackRetriesDirectMs may be increased
+// in case the data write is bursty for the AudioTrack. The application
+// should endeavor to write at least once every kMaxTrackRetriesDirectMs
+// to prevent an underrun situation. If the data is bursty, then
+// the application can also throttle the data sent to be even.
+// 2) For compressed audio data, any data present in the AudioTrack buffer
+// will be sent and reset the retry count. This delivers data as
+// it arrives, with approximately kDirectMinSleepTimeUs = 10ms checking interval.
+// 3) For linear PCM or proportional PCM, we wait one period for a period's worth
+// of data to be available, then any remaining data is delivered.
+// This is required to ensure the last bit of data is delivered before underrun.
+//
+// Sleep time per cycle is kDirectMinSleepTimeUs for compressed tracks
+// or the size of the HAL period for proportional / linear PCM tracks.
+static const int32_t kMaxTrackRetriesDirectMs = 200;
// don't warn about blocked writes or record buffer overflows more often than this
static const nsecs_t kWarningThrottleNs = seconds(5);
@@ -5931,11 +5945,19 @@
// Allow draining the buffer in case the client
// app does not call stop() and relies on underrun to stop:
// hence the test on (track->mRetryCount > 1).
- // If retryCount<=1 then track is about to underrun and be removed.
+ // If track->mRetryCount <= 1 then track is about to be disabled, paused, removed,
+ // so we accept any nonzero amount of data delivered by the AudioTrack (which will
+ // reset the retry counter).
// Do not use a high threshold for compressed audio.
+
+ // target retry count that we will use is based on the time we wait for retries.
+ const int32_t targetRetryCount = kMaxTrackRetriesDirectMs * 1000 / mActiveSleepTimeUs;
+ // the retry threshold is when we accept any size for PCM data. This is slightly
+ // smaller than the retry count so we can push small bits of data without a glitch.
+ const int32_t retryThreshold = targetRetryCount > 2 ? targetRetryCount - 1 : 1;
uint32_t minFrames;
if ((track->sharedBuffer() == 0) && !track->isStopping_1() && !track->isPausing()
- && (track->mRetryCount > 1) && audio_has_proportional_frames(mFormat)) {
+ && (track->mRetryCount > retryThreshold) && audio_has_proportional_frames(mFormat)) {
minFrames = mNormalFrameCount;
} else {
minFrames = 1;
@@ -5979,7 +6001,7 @@
mPreviousTrack = track;
// reset retry count
- track->mRetryCount = kMaxTrackRetriesDirect;
+ track->mRetryCount = targetRetryCount;
mActiveTrack = t;
mixerStatus = MIXER_TRACKS_READY;
if (mHwPaused) {
@@ -6033,15 +6055,17 @@
// indicate to client process that the track was disabled because of underrun;
// it will then automatically call start() when data is available
track->disable();
- } else if (last) {
+ // only do hw pause when track is going to be removed due to BUFFER TIMEOUT.
+ // unlike mixerthread, HAL can be paused for direct output
ALOGW("pause because of UNDERRUN, framesReady = %zu,"
"minFrames = %u, mFormat = %#x",
framesReady, minFrames, mFormat);
- mixerStatus = MIXER_TRACKS_ENABLED;
- if (mHwSupportsPause && !mHwPaused && !mStandby) {
+ if (last && mHwSupportsPause && !mHwPaused && !mStandby) {
doHwPause = true;
mHwPaused = true;
}
+ } else if (last) {
+ mixerStatus = MIXER_TRACKS_ENABLED;
}
}
}
@@ -6113,16 +6137,13 @@
mSleepTimeUs = mIdleSleepTimeUs;
return;
}
- if (mSleepTimeUs == 0) {
- if (mMixerStatus == MIXER_TRACKS_ENABLED) {
- mSleepTimeUs = mActiveSleepTimeUs;
- } else {
- mSleepTimeUs = mIdleSleepTimeUs;
- }
- } else if (mBytesWritten != 0 && audio_has_proportional_frames(mFormat)) {
- memset(mSinkBuffer, 0, mFrameCount * mFrameSize);
- mSleepTimeUs = 0;
+ if (mMixerStatus == MIXER_TRACKS_ENABLED) {
+ mSleepTimeUs = mActiveSleepTimeUs;
+ } else {
+ mSleepTimeUs = mIdleSleepTimeUs;
}
+ // Note: In S or later, we do not write zeroes for
+ // linear or proportional PCM direct tracks in underrun.
}
void AudioFlinger::DirectOutputThread::threadLoop_exit()
@@ -7932,18 +7953,18 @@
{ // scope for mLock
Mutex::Autolock _l(mLock);
- long startTimeMs = -1;
+ int32_t startFrames = -1;
if (!mSharedAudioPackageName.empty()
&& mSharedAudioPackageName == checkedIdentity.packageName
&& mSharedAudioSessionId == sessionId
&& captureHotwordAllowed(checkedIdentity)) {
- startTimeMs = mSharedAudioStartMs;
+ startFrames = mSharedAudioStartFrames;
}
track = new RecordTrack(this, client, attr, sampleRate,
format, channelMask, frameCount,
nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, creatorPid,
- checkedIdentity, *flags, TrackBase::TYPE_DEFAULT, portId, startTimeMs);
+ checkedIdentity, *flags, TrackBase::TYPE_DEFAULT, portId, startFrames);
lStatus = track->initCheck();
if (lStatus != NO_ERROR) {
@@ -8200,17 +8221,32 @@
if ((hasAudioSession_l(sharedSessionId) & ThreadBase::TRACK_SESSION) == 0) {
return BAD_VALUE;
}
- if (sharedAudioStartMs < 0 || sharedAudioStartMs * mSampleRate / 1000 > mRsmpInRear) {
+
+ if (sharedAudioStartMs < 0
+ || sharedAudioStartMs > INT64_MAX / mSampleRate) {
return BAD_VALUE;
}
+ // Current implementation of the input resampling buffer wraps around indexes at 32 bit.
+ // As we cannot detect more than one wraparound, only accept values up current write position
+ // after one wraparound
+ // We assume recent wraparounds on mRsmpInRear only given it is unlikely that the requesting
+ // app waits several hours after the start time was computed.
+ const int64_t sharedAudioStartFrames = sharedAudioStartMs * mSampleRate / 1000;
+ const int32_t sharedOffset = audio_utils::safe_sub_overflow(mRsmpInRear,
+ (int32_t)sharedAudioStartFrames);
+ if (sharedOffset < 0
+ || sharedOffset > mRsmpInFrames) {
+ return BAD_VALUE;
+ }
+
mSharedAudioPackageName = sharedAudioPackageName;
if (mSharedAudioPackageName.empty()) {
mSharedAudioSessionId = AUDIO_SESSION_NONE;
- mSharedAudioStartMs = -1;
+ mSharedAudioStartFrames = -1;
} else {
mSharedAudioSessionId = sharedSessionId;
- mSharedAudioStartMs = sharedAudioStartMs;
+ mSharedAudioStartFrames = (int32_t)sharedAudioStartFrames;
}
return NO_ERROR;
}
@@ -8357,14 +8393,14 @@
mRsmpInUnrel = 0;
const int32_t rear = recordThread->mRsmpInRear;
ssize_t deltaFrames = 0;
- if (mRecordTrack->startTimeMs() >= 0) {
- int32_t startFrames = mRecordTrack->startTimeMs() * recordThread->sampleRate() / 1000;
- // start frame has to be in the past
- //TODO: b/185972521 fix in case rear or startFrames wrap around
- if (startFrames > rear) {
- startFrames = rear;
+ if (mRecordTrack->startFrames() >= 0) {
+ int32_t startFrames = mRecordTrack->startFrames();
+ // Accept a recent wraparound of mRsmpInRear
+ if (startFrames <= rear) {
+ deltaFrames = rear - startFrames;
+ } else {
+ deltaFrames = (int32_t)((int64_t)rear + UINT32_MAX + 1 - startFrames);
}
- deltaFrames = rear - startFrames;
// start frame cannot be further in the past than start of resampling buffer
if ((size_t) deltaFrames > recordThread->mRsmpInFrames) {
deltaFrames = recordThread->mRsmpInFrames;
@@ -8826,17 +8862,22 @@
if (mTracks.size() == 0) {
return 0;
}
- //TODO: b/185972521 fix in case of wrap around on one track:
- // want the max(rear - front) for all tracks.
- int32_t front = INT_MAX;
+ int32_t oldestFront = mRsmpInRear;
+ int32_t maxFilled = 0;
for (size_t i = 0; i < mTracks.size(); i++) {
- front = std::min(front, mTracks[i]->mResamplerBufferProvider->getFront());
+ int32_t front = mTracks[i]->mResamplerBufferProvider->getFront();
+ int32_t filled;
+ if (front <= mRsmpInRear) {
+ filled = mRsmpInRear - front;
+ } else {
+ filled = (int32_t)((int64_t)mRsmpInRear + UINT32_MAX + 1 - front);
+ }
+ if (filled > maxFilled) {
+ oldestFront = front;
+ maxFilled = filled;
+ }
}
- // discard any audio past the buffer size
- if (audio_utils::safe_add_overflow(front, (int32_t)mRsmpInFrames) < mRsmpInRear) {
- front = audio_utils::safe_sub_overflow(mRsmpInRear, (int32_t)mRsmpInFrames);
- }
- return front;
+ return oldestFront;
}
void AudioFlinger::RecordThread::updateFronts_l(int32_t offset)
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 03ed6fd..b6f7f24 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1863,7 +1863,7 @@
DeviceDescriptorBaseVector mOutDevices;
std::string mSharedAudioPackageName = {};
- long mSharedAudioStartMs = 0;
+ int32_t mSharedAudioStartFrames = -1;
audio_session_t mSharedAudioSessionId = AUDIO_SESSION_NONE;
};
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 6549236..3e04804 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -2378,7 +2378,7 @@
audio_input_flags_t flags,
track_type type,
audio_port_handle_t portId,
- int64_t startTimeMs)
+ int32_t startFrames)
: TrackBase(thread, client, attr, sampleRate, format,
channelMask, frameCount, buffer, bufferSize, sessionId,
creatorPid,
@@ -2396,7 +2396,7 @@
mFlags(flags),
mSilenced(false),
mOpRecordAudioMonitor(OpRecordAudioMonitor::createIfNeeded(identity, attr)),
- mStartTimeMs(startTimeMs)
+ mStartFrames(startFrames)
{
if (mCblk == NULL) {
return;
diff --git a/services/mediametrics/statsd_codec.cpp b/services/mediametrics/statsd_codec.cpp
index 4539ad5..2cfdf24 100644
--- a/services/mediametrics/statsd_codec.cpp
+++ b/services/mediametrics/statsd_codec.cpp
@@ -294,6 +294,12 @@
metrics_proto.set_video_input_frames(inputFrames);
}
+ // android.media.mediacodec.original.bitrate
+ int32_t originalBitrate = -1;
+ if ( item->getInt32("android.media.mediacodec.original.bitrate", &originalBitrate)) {
+ metrics_proto.set_original_bitrate(originalBitrate);
+ }
+
std::string serialized;
if (!metrics_proto.SerializeToString(&serialized)) {
ALOGE("Failed to serialize codec metrics");