Merge "CCodecConfig: map KEY_HDR10_PLUS_INFO to C2StreamHdrDynamicMetadataInfo" into tm-dev
diff --git a/apex/manifest.json b/apex/manifest.json
index f908f97..4b75b04 100644
--- a/apex/manifest.json
+++ b/apex/manifest.json
@@ -1,6 +1,6 @@
{
"name": "com.android.media",
- "version": 330090000,
+ "version": 339990000,
"requireNativeLibs": [
"libandroid.so",
"libbinder_ndk.so",
diff --git a/apex/manifest_codec.json b/apex/manifest_codec.json
index 01a85ae..fbcbb69 100644
--- a/apex/manifest_codec.json
+++ b/apex/manifest_codec.json
@@ -1,6 +1,6 @@
{
"name": "com.android.media.swcodec",
- "version": 330090000,
+ "version": 339990000,
"requireNativeLibs": [
":sphal"
]
diff --git a/camera/cameraserver/Android.bp b/camera/cameraserver/Android.bp
index 22bb234..094a3c1 100644
--- a/camera/cameraserver/Android.bp
+++ b/camera/cameraserver/Android.bp
@@ -47,7 +47,6 @@
"android.hardware.camera.device@1.0",
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.4",
- "android.hardware.camera.device@3.8",
],
compile_multilib: "first",
cflags: [
diff --git a/media/codec2/components/aac/C2SoftAacDec.cpp b/media/codec2/components/aac/C2SoftAacDec.cpp
index 57cdcd0..4e4a9a1 100644
--- a/media/codec2/components/aac/C2SoftAacDec.cpp
+++ b/media/codec2/components/aac/C2SoftAacDec.cpp
@@ -221,6 +221,12 @@
.withFields({C2F(mDrcOutputLoudness, value).inRange(-57.75, 0.25)})
.withSetter(Setter<decltype(*mDrcOutputLoudness)>::StrictValueWithNoDeps)
.build());
+
+ addParameter(DefineParam(mChannelMask, C2_PARAMKEY_CHANNEL_MASK)
+ .withDefault(new C2StreamChannelMaskInfo::output(0u, 0))
+ .withFields({C2F(mChannelMask, value).inRange(0, 4294967292)})
+ .withSetter(Setter<decltype(*mChannelMask)>::StrictValueWithNoDeps)
+ .build());
}
bool isAdts() const { return mAacFormat->value == C2Config::AAC_PACKAGING_ADTS; }
@@ -255,6 +261,7 @@
std::shared_ptr<C2StreamDrcAlbumModeTuning::input> mDrcAlbumMode;
std::shared_ptr<C2StreamMaxChannelCountInfo::input> mMaxChannelCount;
std::shared_ptr<C2StreamDrcOutputLoudnessTuning::output> mDrcOutputLoudness;
+ std::shared_ptr<C2StreamChannelMaskInfo::output> mChannelMask;
// TODO Add : C2StreamAacSbrModeTuning
};
@@ -829,9 +836,11 @@
C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate);
C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels);
+ C2StreamChannelMaskInfo::output channelMaskInfo(0u,
+ maskFromCount(mStreamInfo->numChannels));
std::vector<std::unique_ptr<C2SettingResult>> failures;
c2_status_t err = mIntf->config(
- { &sampleRateInfo, &channelCountInfo },
+ { &sampleRateInfo, &channelCountInfo, &channelMaskInfo },
C2_MAY_BLOCK,
&failures);
if (err == OK) {
@@ -840,6 +849,7 @@
C2FrameData &output = work->worklets.front()->output;
output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
+ output.configUpdate.push_back(C2Param::Copy(channelMaskInfo));
} else {
ALOGE("Config Update failed");
mSignalledError = true;
@@ -1056,6 +1066,47 @@
}
}
+// definitions based on android.media.AudioFormat.CHANNEL_OUT_*
+#define CHANNEL_OUT_FL 0x4
+#define CHANNEL_OUT_FR 0x8
+#define CHANNEL_OUT_FC 0x10
+#define CHANNEL_OUT_LFE 0x20
+#define CHANNEL_OUT_BL 0x40
+#define CHANNEL_OUT_BR 0x80
+#define CHANNEL_OUT_SL 0x800
+#define CHANNEL_OUT_SR 0x1000
+
+uint32_t C2SoftAacDec::maskFromCount(uint32_t channelCount) {
+ // KEY_CHANNEL_MASK expects masks formatted according to Java android.media.AudioFormat
+ // where the two left-most bits are 0 for output channel mask
+ switch (channelCount) {
+ case 1: // mono is front left
+ return (CHANNEL_OUT_FL);
+ case 2: // stereo
+ return (CHANNEL_OUT_FL | CHANNEL_OUT_FR);
+ case 4: // 4.0 = stereo with backs
+ return (CHANNEL_OUT_FL | CHANNEL_OUT_FC
+ | CHANNEL_OUT_BL | CHANNEL_OUT_BR);
+ case 5: // 5.0
+ return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR
+ | CHANNEL_OUT_BL | CHANNEL_OUT_BR);
+ case 6: // 5.1 = 5.0 + LFE
+ return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR
+ | CHANNEL_OUT_BL | CHANNEL_OUT_BR
+ | CHANNEL_OUT_LFE);
+ case 7: // 7.0 = 5.0 + Sides
+ return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR
+ | CHANNEL_OUT_BL | CHANNEL_OUT_BR
+ | CHANNEL_OUT_SL | CHANNEL_OUT_SR);
+ case 8: // 7.1 = 7.0 + LFE
+ return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR
+ | CHANNEL_OUT_BL | CHANNEL_OUT_BR | CHANNEL_OUT_SL | CHANNEL_OUT_SR
+ | CHANNEL_OUT_LFE);
+ default:
+ return 0;
+ }
+}
+
class C2SoftAacDecFactory : public C2ComponentFactory {
public:
C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
diff --git a/media/codec2/components/aac/C2SoftAacDec.h b/media/codec2/components/aac/C2SoftAacDec.h
index a03fc70..b45f148 100644
--- a/media/codec2/components/aac/C2SoftAacDec.h
+++ b/media/codec2/components/aac/C2SoftAacDec.h
@@ -101,6 +101,7 @@
int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples);
int32_t outputDelayRingBufferSamplesAvailable();
int32_t outputDelayRingBufferSpaceLeft();
+ uint32_t maskFromCount(uint32_t channelCount);
C2_DO_NOT_COPY(C2SoftAacDec);
};
diff --git a/media/codec2/components/aom/C2SoftAomDec.cpp b/media/codec2/components/aom/C2SoftAomDec.cpp
index 3b0e949..d65488e 100644
--- a/media/codec2/components/aom/C2SoftAomDec.cpp
+++ b/media/codec2/components/aom/C2SoftAomDec.cpp
@@ -585,10 +585,9 @@
const uint16_t *srcV = (const uint16_t *)img->planes[AOM_PLANE_V];
if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
- convertYUV420Planar16ToY410((uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2,
- srcUStride / 2, srcVStride / 2,
- dstYStride / sizeof(uint32_t),
- mWidth, mHeight);
+ convertYUV420Planar16ToY410OrRGBA1010102(
+ (uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2, srcUStride / 2,
+ srcVStride / 2, dstYStride / sizeof(uint32_t), mWidth, mHeight);
} else {
convertYUV420Planar16ToYV12(dstY, dstU, dstV, srcY, srcU, srcV, srcYStride / 2,
srcUStride / 2, srcVStride / 2, dstYStride, dstUVStride,
diff --git a/media/codec2/components/base/SimpleC2Component.cpp b/media/codec2/components/base/SimpleC2Component.cpp
index b30eed5..678c269 100644
--- a/media/codec2/components/base/SimpleC2Component.cpp
+++ b/media/codec2/components/base/SimpleC2Component.cpp
@@ -137,7 +137,118 @@
dst += dstStride * 2;
}
}
+#define CLIP3(min, v, max) (((v) < (min)) ? (min) : (((max) > (v)) ? (v) : (max)))
+void convertYUV420Planar16ToRGBA1010102(uint32_t *dst, const uint16_t *srcY, const uint16_t *srcU,
+ const uint16_t *srcV, size_t srcYStride, size_t srcUStride,
+ size_t srcVStride, size_t dstStride, size_t width,
+ size_t height) {
+ // Converting two lines at a time, slightly faster
+ for (size_t y = 0; y < height; y += 2) {
+ uint32_t *dstTop = (uint32_t *)dst;
+ uint32_t *dstBot = (uint32_t *)(dst + dstStride);
+ uint16_t *ySrcTop = (uint16_t *)srcY;
+ uint16_t *ySrcBot = (uint16_t *)(srcY + srcYStride);
+ uint16_t *uSrc = (uint16_t *)srcU;
+ uint16_t *vSrc = (uint16_t *)srcV;
+ // BT.2020 Limited Range conversion
+
+ // B = 1.168 *(Y - 64) + 2.148 *(U - 512)
+ // G = 1.168 *(Y - 64) - 0.652 *(V - 512) - 0.188 *(U - 512)
+ // R = 1.168 *(Y - 64) + 1.683 *(V - 512)
+
+ // B = 1196/1024 *(Y - 64) + 2200/1024 *(U - 512)
+ // G = .................... - 668/1024 *(V - 512) - 192/1024 *(U - 512)
+ // R = .................... + 1723/1024 *(V - 512)
+
+ // min_B = (1196 *(- 64) + 2200 *(- 512)) / 1024 = -1175
+ // min_G = (1196 *(- 64) - 668 *(1023 - 512) - 192 *(1023 - 512)) / 1024 = -504
+ // min_R = (1196 *(- 64) + 1723 *(- 512)) / 1024 = -937
+
+ // max_B = (1196 *(1023 - 64) + 2200 *(1023 - 512)) / 1024 = 2218
+ // max_G = (1196 *(1023 - 64) - 668 *(- 512) - 192 *(- 512)) / 1024 = 1551
+ // max_R = (1196 *(1023 - 64) + 1723 *(1023 - 512)) / 1024 = 1980
+
+ int32_t mY = 1196, mU_B = 2200, mV_G = -668, mV_R = 1723, mU_G = -192;
+ for (size_t x = 0; x < width; x += 2) {
+ int32_t u, v, y00, y01, y10, y11;
+ u = *uSrc - 512;
+ uSrc += 1;
+ v = *vSrc - 512;
+ vSrc += 1;
+
+ y00 = *ySrcTop - 64;
+ ySrcTop += 1;
+ y01 = *ySrcTop - 64;
+ ySrcTop += 1;
+ y10 = *ySrcBot - 64;
+ ySrcBot += 1;
+ y11 = *ySrcBot - 64;
+ ySrcBot += 1;
+
+ int32_t u_b = u * mU_B;
+ int32_t u_g = u * mU_G;
+ int32_t v_g = v * mV_G;
+ int32_t v_r = v * mV_R;
+
+ int32_t yMult, b, g, r;
+ yMult = y00 * mY;
+ b = (yMult + u_b) / 1024;
+ g = (yMult + v_g + u_g) / 1024;
+ r = (yMult + v_r) / 1024;
+ b = CLIP3(0, b, 1023);
+ g = CLIP3(0, g, 1023);
+ r = CLIP3(0, r, 1023);
+ *dstTop++ = 3 << 30 | (b << 20) | (g << 10) | r;
+
+ yMult = y01 * mY;
+ b = (yMult + u_b) / 1024;
+ g = (yMult + v_g + u_g) / 1024;
+ r = (yMult + v_r) / 1024;
+ b = CLIP3(0, b, 1023);
+ g = CLIP3(0, g, 1023);
+ r = CLIP3(0, r, 1023);
+ *dstTop++ = 3 << 30 | (b << 20) | (g << 10) | r;
+
+ yMult = y10 * mY;
+ b = (yMult + u_b) / 1024;
+ g = (yMult + v_g + u_g) / 1024;
+ r = (yMult + v_r) / 1024;
+ b = CLIP3(0, b, 1023);
+ g = CLIP3(0, g, 1023);
+ r = CLIP3(0, r, 1023);
+ *dstBot++ = 3 << 30 | (b << 20) | (g << 10) | r;
+
+ yMult = y11 * mY;
+ b = (yMult + u_b) / 1024;
+ g = (yMult + v_g + u_g) / 1024;
+ r = (yMult + v_r) / 1024;
+ b = CLIP3(0, b, 1023);
+ g = CLIP3(0, g, 1023);
+ r = CLIP3(0, r, 1023);
+ *dstBot++ = 3 << 30 | (b << 20) | (g << 10) | r;
+ }
+
+ srcY += srcYStride * 2;
+ srcU += srcUStride;
+ srcV += srcVStride;
+ dst += dstStride * 2;
+ }
+}
+
+void convertYUV420Planar16ToY410OrRGBA1010102(uint32_t *dst, const uint16_t *srcY,
+ const uint16_t *srcU, const uint16_t *srcV,
+ size_t srcYStride, size_t srcUStride,
+ size_t srcVStride, size_t dstStride, size_t width,
+ size_t height) {
+ if (isAtLeastT()) {
+ convertYUV420Planar16ToRGBA1010102(dst, srcY, srcU, srcV, srcYStride, srcUStride,
+ srcVStride, dstStride, width, height);
+ } else {
+ convertYUV420Planar16ToY410(dst, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride,
+ dstStride, width, height);
+ }
+}
void convertYUV420Planar16ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint16_t *srcY,
const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride,
size_t srcUStride, size_t srcVStride, size_t dstYStride,
@@ -799,10 +910,15 @@
// Add YV12 in the end as a fall-back option
mBitDepth10HalPixelFormats.push_back(HAL_PIXEL_FORMAT_YV12);
}
- // When RGBA1010102 is not allowed and if the first supported hal pixel is format is
- // HAL_PIXEL_FORMAT_RGBA_1010102, then return HAL_PIXEL_FORMAT_YV12
- if (!allowRGBA1010102 && mBitDepth10HalPixelFormats[0] == HAL_PIXEL_FORMAT_RGBA_1010102) {
- return HAL_PIXEL_FORMAT_YV12;
+ // From Android T onwards, HAL_PIXEL_FORMAT_RGBA_1010102 corresponds to true
+ // RGBA 1010102 format unlike earlier versions where it was used to represent
+ // YUVA 1010102 data
+ if (!isAtLeastT()) {
+ // When RGBA1010102 is not allowed and if the first supported hal pixel is format is
+ // HAL_PIXEL_FORMAT_RGBA_1010102, then return HAL_PIXEL_FORMAT_YV12
+ if (!allowRGBA1010102 && mBitDepth10HalPixelFormats[0] == HAL_PIXEL_FORMAT_RGBA_1010102) {
+ return HAL_PIXEL_FORMAT_YV12;
+ }
}
// Return the first entry from supported formats
return mBitDepth10HalPixelFormats[0];
diff --git a/media/codec2/components/base/include/SimpleC2Component.h b/media/codec2/components/base/include/SimpleC2Component.h
index 52ae3b8..3172f29 100644
--- a/media/codec2/components/base/include/SimpleC2Component.h
+++ b/media/codec2/components/base/include/SimpleC2Component.h
@@ -33,9 +33,11 @@
size_t srcUStride, size_t srcVStride, size_t dstYStride,
size_t dstUVStride, uint32_t width, uint32_t height,
bool isMonochrome = false);
-void convertYUV420Planar16ToY410(uint32_t *dst, const uint16_t *srcY, const uint16_t *srcU,
- const uint16_t *srcV, size_t srcYStride, size_t srcUStride,
- size_t srcVStride, size_t dstStride, size_t width, size_t height);
+void convertYUV420Planar16ToY410OrRGBA1010102(uint32_t *dst, const uint16_t *srcY,
+ const uint16_t *srcU, const uint16_t *srcV,
+ size_t srcYStride, size_t srcUStride,
+ size_t srcVStride, size_t dstStride, size_t width,
+ size_t height);
void convertYUV420Planar16ToYV12(uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, const uint16_t *srcY,
const uint16_t *srcU, const uint16_t *srcV, size_t srcYStride,
size_t srcUStride, size_t srcVStride, size_t dstYStride,
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index f5c8138..a22c750 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -714,9 +714,9 @@
const uint16_t *srcV = (const uint16_t *)buffer->plane[2];
if (format == HAL_PIXEL_FORMAT_RGBA_1010102) {
- convertYUV420Planar16ToY410((uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2,
- srcUStride / 2, srcVStride / 2, dstYStride / sizeof(uint32_t),
- mWidth, mHeight);
+ convertYUV420Planar16ToY410OrRGBA1010102((uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2,
+ srcUStride / 2, srcVStride / 2,
+ dstYStride / sizeof(uint32_t), mWidth, mHeight);
} else if (format == HAL_PIXEL_FORMAT_YCBCR_P010) {
convertYUV420Planar16ToP010((uint16_t *)dstY, (uint16_t *)dstU, srcY, srcU, srcV,
srcYStride / 2, srcUStride / 2, srcVStride / 2, dstYStride / 2,
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.cpp b/media/codec2/components/vpx/C2SoftVpxDec.cpp
index e81f044..c2ccfa0 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxDec.cpp
@@ -760,7 +760,7 @@
[dstY, srcY, srcU, srcV,
srcYStride, srcUStride, srcVStride, dstYStride,
width = mWidth, height = std::min(mHeight - i, kHeight)] {
- convertYUV420Planar16ToY410(
+ convertYUV420Planar16ToY410OrRGBA1010102(
(uint32_t *)dstY, srcY, srcU, srcV, srcYStride / 2,
srcUStride / 2, srcVStride / 2, dstYStride / sizeof(uint32_t),
width, height);
diff --git a/media/codec2/core/include/C2Config.h b/media/codec2/core/include/C2Config.h
index 07c2864..6ff3dbc 100644
--- a/media/codec2/core/include/C2Config.h
+++ b/media/codec2/core/include/C2Config.h
@@ -60,6 +60,7 @@
enum drc_effect_type_t : int32_t; ///< DRC effect type
enum drc_album_mode_t : int32_t; ///< DRC album mode
enum hdr_dynamic_metadata_type_t : uint32_t; ///< HDR dynamic metadata type
+ enum hdr_format_t : uint32_t; ///< HDR format
enum intra_refresh_mode_t : uint32_t; ///< intra refresh modes
enum level_t : uint32_t; ///< coding level
enum ordinal_key_t : uint32_t; ///< work ordering keys
@@ -78,6 +79,7 @@
struct C2PlatformConfig {
enum encoding_quality_level_t : uint32_t; ///< encoding quality level
+ enum tunnel_peek_mode_t: uint32_t; ///< tunnel peek mode
};
namespace {
@@ -192,10 +194,9 @@
kParamIndexPictureType,
// deprecated
kParamIndexHdr10PlusMetadata,
-
kParamIndexPictureQuantization,
-
kParamIndexHdrDynamicMetadata,
+ kParamIndexHdrFormat,
/* ------------------------------------ video components ------------------------------------ */
@@ -280,6 +281,9 @@
// channel mask for decoded audio
kParamIndexAndroidChannelMask, // uint32
+
+ // allow tunnel peek behavior to be unspecified for app compatibility
+ kParamIndexTunnelPeekMode, // tunnel mode, enum
};
}
@@ -1667,6 +1671,34 @@
constexpr char C2_PARAMKEY_INPUT_HDR_DYNAMIC_INFO[] = "input.hdr-dynamic-info";
constexpr char C2_PARAMKEY_OUTPUT_HDR_DYNAMIC_INFO[] = "output.hdr-dynamic-info";
+/**
+ * HDR Format
+ */
+C2ENUM(C2Config::hdr_format_t, uint32_t,
+ UNKNOWN, ///< HDR format not known (default)
+ SDR, ///< not HDR (SDR)
+ HLG, ///< HLG
+ HDR10, ///< HDR10
+ HDR10_PLUS, ///< HDR10+
+);
+
+/**
+ * HDR Format Info
+ *
+ * This information may be present during configuration to allow encoders to
+ * prepare encoding certain HDR formats. When this information is not present
+ * before start, encoders should determine the HDR format based on the available
+ * HDR metadata on the first input frame.
+ *
+ * While this information is optional, it is not a hint. When present, encoders
+ * that do not support dynamic reconfiguration do not need to switch to the HDR
+ * format based on the metadata on the first input frame.
+ */
+typedef C2StreamParam<C2Info, C2SimpleValueStruct<C2EasyEnum<C2Config::hdr_format_t>>,
+ kParamIndexHdrFormat>
+ C2StreamHdrFormatInfo;
+constexpr char C2_PARAMKEY_HDR_FORMAT[] = "coded.hdr-format";
+
/* ------------------------------------ block-based coding ----------------------------------- */
/**
@@ -2454,6 +2486,28 @@
C2StreamTunnelStartRender;
constexpr char C2_PARAMKEY_TUNNEL_START_RENDER[] = "output.tunnel-start-render";
+/** Tunnel Peek Mode. */
+C2ENUM(C2PlatformConfig::tunnel_peek_mode_t, uint32_t,
+ UNSPECIFIED_PEEK = 0,
+ SPECIFIED_PEEK = 1
+);
+
+/**
+ * Tunnel Peek Mode Tuning parameter.
+ *
+ * If set to UNSPECIFIED_PEEK_MODE, the decoder is free to ignore the
+ * C2StreamTunnelHoldRender and C2StreamTunnelStartRender flags and associated
+ * features. Additionally, it becomes up to the decoder to display any frame
+ * before receiving synchronization information.
+ *
+ * Note: This parameter allows a decoder to ignore the video peek machinery and
+ * to revert to its preferred behavior.
+ */
+typedef C2StreamParam<C2Tuning, C2EasyEnum<C2PlatformConfig::tunnel_peek_mode_t>,
+ kParamIndexTunnelPeekMode> C2StreamTunnelPeekModeTuning;
+constexpr char C2_PARAMKEY_TUNNEL_PEEK_MODE[] =
+ "output.tunnel-peek-mode";
+
/**
* Encoding quality level signaling.
*
diff --git a/media/codec2/hidl/1.0/utils/types.cpp b/media/codec2/hidl/1.0/utils/types.cpp
index 72f7c43..5c24bd7 100644
--- a/media/codec2/hidl/1.0/utils/types.cpp
+++ b/media/codec2/hidl/1.0/utils/types.cpp
@@ -26,6 +26,7 @@
#include <C2BlockInternal.h>
#include <C2Buffer.h>
#include <C2Component.h>
+#include <C2FenceFactory.h>
#include <C2Param.h>
#include <C2ParamInternal.h>
#include <C2PlatformSupport.h>
@@ -759,17 +760,14 @@
// Note: File descriptors are not duplicated. The original file descriptor must
// not be closed before the transaction is complete.
bool objcpy(hidl_handle* d, const C2Fence& s) {
- (void)s; // TODO: implement s.fd()
- int fenceFd = -1;
d->setTo(nullptr);
- if (fenceFd >= 0) {
- native_handle_t *handle = native_handle_create(1, 0);
- if (!handle) {
- LOG(ERROR) << "Failed to create a native handle.";
- return false;
- }
- handle->data[0] = fenceFd;
+ native_handle_t* handle = _C2FenceFactory::CreateNativeHandle(s);
+ if (handle) {
d->setTo(handle, true /* owns */);
+// } else if (!s.ready()) {
+// // TODO: we should wait for unmarshallable fences but this may not be
+// // the best place for it. We can safely ignore here as at this time
+// // all fences used here are marshallable.
}
return true;
}
@@ -1184,9 +1182,8 @@
// Note: File descriptors are not duplicated. The original file descriptor must
// not be closed before the transaction is complete.
bool objcpy(C2Fence* d, const hidl_handle& s) {
- // TODO: Implement.
- (void)s;
- *d = C2Fence();
+ const native_handle_t* handle = s.getNativeHandle();
+ *d = _C2FenceFactory::CreateFromNativeHandle(handle);
return true;
}
diff --git a/media/codec2/hidl/plugin/samples/SampleFilterPlugin.cpp b/media/codec2/hidl/plugin/samples/SampleFilterPlugin.cpp
index b942be7..5c13b0e 100644
--- a/media/codec2/hidl/plugin/samples/SampleFilterPlugin.cpp
+++ b/media/codec2/hidl/plugin/samples/SampleFilterPlugin.cpp
@@ -807,7 +807,8 @@
// affectedParams
{
C2StreamHdrStaticInfo::output::PARAM_TYPE,
- C2StreamHdr10PlusInfo::output::PARAM_TYPE,
+ C2StreamHdr10PlusInfo::output::PARAM_TYPE, // will be deprecated
+ C2StreamHdrDynamicMetadataInfo::output::PARAM_TYPE,
C2StreamColorAspectsInfo::output::PARAM_TYPE,
},
};
diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp
index c36ae94..5a652a3 100644
--- a/media/codec2/sfplugin/Android.bp
+++ b/media/codec2/sfplugin/Android.bp
@@ -43,6 +43,10 @@
"media_ndk_headers",
],
+ static_libs: [
+ "SurfaceFlingerProperties",
+ ],
+
shared_libs: [
"android.hardware.cas.native@1.0",
"android.hardware.drm@1.0",
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 19bb206..529ee36 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1435,7 +1435,7 @@
int64_t blockUsage =
usage.value | C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE;
std::shared_ptr<C2GraphicBlock> block = FetchGraphicBlock(
- width, height, pixelFormat, blockUsage, {comp->getName()});
+ width, height, componentColorFormat, blockUsage, {comp->getName()});
sp<GraphicBlockBuffer> buffer;
if (block) {
buffer = GraphicBlockBuffer::Allocate(
@@ -1826,13 +1826,20 @@
return;
}
+ // preparation of input buffers may not succeed due to the lack of
+ // memory; returning correct error code (NO_MEMORY) as an error allows
+ // MediaCodec to try reclaim and restart codec gracefully.
+ std::map<size_t, sp<MediaCodecBuffer>> clientInputBuffers;
+ err2 = mChannel->prepareInitialInputBuffers(&clientInputBuffers);
+ if (err2 != OK) {
+ ALOGE("Initial preparation for Input Buffers failed");
+ mCallback->onError(err2, ACTION_CODE_FATAL);
+ return;
+ }
+
mCallback->onStartCompleted();
- err2 = mChannel->requestInitialInputBuffers();
- if (err2 != OK) {
- ALOGE("Initial request for Input Buffers failed");
- mCallback->onError(err2, ACTION_CODE_FATAL);
- }
+ mChannel->requestInitialInputBuffers(std::move(clientInputBuffers));
}
void CCodec::initiateShutdown(bool keepComponentAllocated) {
@@ -2126,11 +2133,14 @@
state->set(RUNNING);
}
- status_t err = mChannel->requestInitialInputBuffers();
+ std::map<size_t, sp<MediaCodecBuffer>> clientInputBuffers;
+ status_t err = mChannel->prepareInitialInputBuffers(&clientInputBuffers);
if (err != OK) {
ALOGE("Resume request for Input Buffers failed");
mCallback->onError(err, ACTION_CODE_FATAL);
+ return;
}
+ mChannel->requestInitialInputBuffers(std::move(clientInputBuffers));
}
void CCodec::signalSetParameters(const sp<AMessage> &msg) {
@@ -2415,7 +2425,8 @@
C2StreamColorAspectsInfo::output::PARAM_TYPE,
C2StreamDataSpaceInfo::output::PARAM_TYPE,
C2StreamHdrStaticInfo::output::PARAM_TYPE,
- C2StreamHdr10PlusInfo::output::PARAM_TYPE,
+ C2StreamHdr10PlusInfo::output::PARAM_TYPE, // will be deprecated
+ C2StreamHdrDynamicMetadataInfo::output::PARAM_TYPE,
C2StreamPixelAspectRatioInfo::output::PARAM_TYPE,
C2StreamSurfaceScalingInfo::output::PARAM_TYPE
};
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 159e885..f27cc21 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -432,6 +432,10 @@
for (size_t i = 0; i < numSubSamples; ++i) {
size += subSamples[i].mNumBytesOfClearData + subSamples[i].mNumBytesOfEncryptedData;
}
+ if (size == 0) {
+ buffer->setRange(0, 0);
+ return OK;
+ }
std::shared_ptr<C2BlockPool> pool = mBlockPools.lock()->inputPool;
std::shared_ptr<C2LinearBlock> block;
c2_status_t err = pool->fetchLinearBlock(
@@ -439,6 +443,8 @@
secure ? kSecureUsage : kDefaultReadWriteUsage,
&block);
if (err != C2_OK) {
+ ALOGI("[%s] attachEncryptedBuffer: fetchLinearBlock failed: size = %zu (%s) err = %d",
+ mName, size, secure ? "secure" : "non-secure", err);
return NO_MEMORY;
}
if (!secure) {
@@ -463,18 +469,9 @@
key, iv, mode, pattern, src, 0, subSamples, numSubSamples,
dst, &errorDetailMsg);
if (result < 0) {
+ ALOGI("[%s] attachEncryptedBuffer: decrypt failed: result = %zd", mName, result);
return result;
}
- if (dst.type == DrmBufferType::SHARED_MEMORY) {
- C2WriteView view = block->map().get();
- if (view.error() != C2_OK) {
- return false;
- }
- if (view.size() < result) {
- return false;
- }
- memcpy(view.data(), mDecryptDestination->unsecurePointer(), result);
- }
} else {
// Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample
// directly, the structure definitions should match as checked in DescramblerImpl.cpp.
@@ -523,16 +520,22 @@
}
if (result < codecDataOffset) {
- ALOGD("invalid codec data offset: %zd, result %zd", codecDataOffset, result);
+ ALOGD("[%s] invalid codec data offset: %zd, result %zd",
+ mName, codecDataOffset, result);
return BAD_VALUE;
}
}
if (!secure) {
C2WriteView view = block->map().get();
if (view.error() != C2_OK) {
+ ALOGI("[%s] attachEncryptedBuffer: block map error: %d (non-secure)",
+ mName, view.error());
return UNKNOWN_ERROR;
}
if (view.size() < result) {
+ ALOGI("[%s] attachEncryptedBuffer: block size too small: size=%u result=%zd "
+ "(non-secure)",
+ mName, view.size(), result);
return UNKNOWN_ERROR;
}
memcpy(view.data(), mDecryptDestination->unsecurePointer(), result);
@@ -540,6 +543,7 @@
std::shared_ptr<C2Buffer> c2Buffer{C2Buffer::CreateLinearBuffer(
block->share(codecDataOffset, result - codecDataOffset, C2Fence{}))};
if (!buffer->copy(c2Buffer)) {
+ ALOGI("[%s] attachEncryptedBuffer: buffer copy failed", mName);
return -ENOSYS;
}
return OK;
@@ -880,6 +884,19 @@
return UNKNOWN_ERROR;
}
const C2ConstGraphicBlock &block = blocks.front();
+ C2Fence c2fence = block.fence();
+ sp<Fence> fence = Fence::NO_FENCE;
+ // TODO: it's not sufficient to just check isHW() and then construct android::fence from it.
+ // Once C2Fence::type() is added, check the exact C2Fence type
+ if (c2fence.isHW()) {
+ int fenceFd = c2fence.fd();
+ fence = sp<Fence>::make(fenceFd);
+ if (!fence) {
+ ALOGE("[%s] Failed to allocate a fence", mName);
+ close(fenceFd);
+ return NO_MEMORY;
+ }
+ }
// TODO: revisit this after C2Fence implementation.
android::IGraphicBufferProducer::QueueBufferInput qbi(
@@ -892,7 +909,7 @@
blocks.front().crop().bottom()),
videoScalingMode,
transform,
- Fence::NO_FENCE, 0);
+ fence, 0);
if (hdrStaticInfo || hdrDynamicInfo) {
HdrMetadata hdr;
if (hdrStaticInfo) {
@@ -1457,54 +1474,47 @@
return OK;
}
-status_t CCodecBufferChannel::requestInitialInputBuffers() {
+status_t CCodecBufferChannel::prepareInitialInputBuffers(
+ std::map<size_t, sp<MediaCodecBuffer>> *clientInputBuffers) {
if (mInputSurface) {
return OK;
}
+ size_t numInputSlots = mInput.lock()->numSlots;
+
+ {
+ Mutexed<Input>::Locked input(mInput);
+ while (clientInputBuffers->size() < numInputSlots) {
+ size_t index;
+ sp<MediaCodecBuffer> buffer;
+ if (!input->buffers->requestNewBuffer(&index, &buffer)) {
+ break;
+ }
+ clientInputBuffers->emplace(index, buffer);
+ }
+ }
+ if (clientInputBuffers->empty()) {
+ ALOGW("[%s] start: cannot allocate memory at all", mName);
+ return NO_MEMORY;
+ } else if (clientInputBuffers->size() < numInputSlots) {
+ ALOGD("[%s] start: cannot allocate memory for all slots, "
+ "only %zu buffers allocated",
+ mName, clientInputBuffers->size());
+ } else {
+ ALOGV("[%s] %zu initial input buffers available",
+ mName, clientInputBuffers->size());
+ }
+ return OK;
+}
+
+status_t CCodecBufferChannel::requestInitialInputBuffers(
+ std::map<size_t, sp<MediaCodecBuffer>> &&clientInputBuffers) {
C2StreamBufferTypeSetting::output oStreamFormat(0u);
C2PrependHeaderModeSetting prepend(PREPEND_HEADER_TO_NONE);
c2_status_t err = mComponent->query({ &oStreamFormat, &prepend }, {}, C2_DONT_BLOCK, nullptr);
if (err != C2_OK && err != C2_BAD_INDEX) {
return UNKNOWN_ERROR;
}
- size_t numInputSlots = mInput.lock()->numSlots;
-
- struct ClientInputBuffer {
- size_t index;
- sp<MediaCodecBuffer> buffer;
- size_t capacity;
- };
- std::list<ClientInputBuffer> clientInputBuffers;
-
- {
- Mutexed<Input>::Locked input(mInput);
- while (clientInputBuffers.size() < numInputSlots) {
- ClientInputBuffer clientInputBuffer;
- if (!input->buffers->requestNewBuffer(&clientInputBuffer.index,
- &clientInputBuffer.buffer)) {
- break;
- }
- clientInputBuffer.capacity = clientInputBuffer.buffer->capacity();
- clientInputBuffers.emplace_back(std::move(clientInputBuffer));
- }
- }
- if (clientInputBuffers.empty()) {
- ALOGW("[%s] start: cannot allocate memory at all", mName);
- return NO_MEMORY;
- } else if (clientInputBuffers.size() < numInputSlots) {
- ALOGD("[%s] start: cannot allocate memory for all slots, "
- "only %zu buffers allocated",
- mName, clientInputBuffers.size());
- } else {
- ALOGV("[%s] %zu initial input buffers available",
- mName, clientInputBuffers.size());
- }
- // Sort input buffers by their capacities in increasing order.
- clientInputBuffers.sort(
- [](const ClientInputBuffer& a, const ClientInputBuffer& b) {
- return a.capacity < b.capacity;
- });
std::list<std::unique_ptr<C2Work>> flushedConfigs;
mFlushedConfigs.lock()->swap(flushedConfigs);
@@ -1526,25 +1536,31 @@
}
}
if (oStreamFormat.value == C2BufferData::LINEAR &&
- (!prepend || prepend.value == PREPEND_HEADER_TO_NONE)) {
- sp<MediaCodecBuffer> buffer = clientInputBuffers.front().buffer;
+ (!prepend || prepend.value == PREPEND_HEADER_TO_NONE) &&
+ !clientInputBuffers.empty()) {
+ size_t minIndex = clientInputBuffers.begin()->first;
+ sp<MediaCodecBuffer> minBuffer = clientInputBuffers.begin()->second;
+ for (const auto &[index, buffer] : clientInputBuffers) {
+ if (minBuffer->capacity() > buffer->capacity()) {
+ minIndex = index;
+ minBuffer = buffer;
+ }
+ }
// WORKAROUND: Some apps expect CSD available without queueing
// any input. Queue an empty buffer to get the CSD.
- buffer->setRange(0, 0);
- buffer->meta()->clear();
- buffer->meta()->setInt64("timeUs", 0);
- if (queueInputBufferInternal(buffer) != OK) {
+ minBuffer->setRange(0, 0);
+ minBuffer->meta()->clear();
+ minBuffer->meta()->setInt64("timeUs", 0);
+ if (queueInputBufferInternal(minBuffer) != OK) {
ALOGW("[%s] Error while queueing an empty buffer to get CSD",
mName);
return UNKNOWN_ERROR;
}
- clientInputBuffers.pop_front();
+ clientInputBuffers.erase(minIndex);
}
- for (const ClientInputBuffer& clientInputBuffer: clientInputBuffers) {
- mCallback->onInputBufferAvailable(
- clientInputBuffer.index,
- clientInputBuffer.buffer);
+ for (const auto &[index, buffer] : clientInputBuffers) {
+ mCallback->onInputBufferAvailable(index, buffer);
}
return OK;
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index b3a5f4b..f29a225 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -130,9 +130,23 @@
bool buffersBoundToCodec);
/**
- * Request initial input buffers to be filled by client.
+ * Prepare initial input buffers to be filled by client.
+ *
+ * \param clientInputBuffers[out] pointer to slot index -> buffer map.
+ * On success, it contains prepared
+ * initial input buffers.
*/
- status_t requestInitialInputBuffers();
+ status_t prepareInitialInputBuffers(
+ std::map<size_t, sp<MediaCodecBuffer>> *clientInputBuffers);
+
+ /**
+ * Request initial input buffers as prepared in clientInputBuffers.
+ *
+ * \param clientInputBuffers[in] slot index -> buffer map with prepared
+ * initial input buffers.
+ */
+ status_t requestInitialInputBuffers(
+ std::map<size_t, sp<MediaCodecBuffer>> &&clientInputBuffers);
/**
* Stop queueing buffers to the component. This object should never queue
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
index 57c70c1..0f4a8d8 100644
--- a/media/codec2/sfplugin/CCodecBuffers.cpp
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
@@ -208,7 +208,7 @@
bool OutputBuffers::convert(
const std::shared_ptr<C2Buffer> &src, sp<Codec2Buffer> *dst) {
- if (!src || src->data().type() != C2BufferData::LINEAR) {
+ if (src && src->data().type() != C2BufferData::LINEAR) {
return false;
}
int32_t configEncoding = kAudioEncodingPcm16bit;
@@ -237,7 +237,12 @@
if (!mDataConverter) {
return false;
}
- sp<MediaCodecBuffer> srcBuffer = ConstLinearBlockBuffer::Allocate(mFormat, src);
+ sp<MediaCodecBuffer> srcBuffer;
+ if (src) {
+ srcBuffer = ConstLinearBlockBuffer::Allocate(mFormat, src);
+ } else {
+ srcBuffer = new MediaCodecBuffer(mFormat, new ABuffer(0));
+ }
if (!srcBuffer) {
return false;
}
@@ -1259,8 +1264,8 @@
if (newBuffer == nullptr) {
return NO_MEMORY;
}
+ newBuffer->setFormat(mFormat);
}
- newBuffer->setFormat(mFormat);
*index = mImpl.assignSlot(newBuffer);
handleImageData(newBuffer);
*clientBuffer = newBuffer;
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index 3ca9177..ba2b150 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -400,10 +400,10 @@
// Rotation
// Note: SDK rotation is clock-wise, while C2 rotation is counter-clock-wise
add(ConfigMapper(KEY_ROTATION, C2_PARAMKEY_VUI_ROTATION, "value")
- .limitTo(D::VIDEO & D::CODED)
+ .limitTo((D::VIDEO | D::IMAGE) & D::CODED)
.withMappers(negate, negate));
add(ConfigMapper(KEY_ROTATION, C2_PARAMKEY_ROTATION, "value")
- .limitTo(D::VIDEO & D::RAW)
+ .limitTo((D::VIDEO | D::IMAGE) & D::RAW)
.withMappers(negate, negate));
// android 'video-scaling'
@@ -513,6 +513,9 @@
add(ConfigMapper("cta861.max-fall", C2_PARAMKEY_HDR_STATIC_INFO, "max-fall")
.limitTo((D::VIDEO | D::IMAGE) & D::RAW));
+ add(ConfigMapper(C2_PARAMKEY_HDR_FORMAT, C2_PARAMKEY_HDR_FORMAT, "value")
+ .limitTo((D::VIDEO | D::IMAGE) & D::CODED & D::CONFIG));
+
add(ConfigMapper(std::string(KEY_FEATURE_) + FEATURE_SecurePlayback,
C2_PARAMKEY_SECURE_MODE, "value"));
@@ -982,11 +985,37 @@
return value == 0 ? C2_FALSE : C2_TRUE;
}));
+ add(ConfigMapper("android._tunnel-peek-set-legacy", C2_PARAMKEY_TUNNEL_PEEK_MODE, "value")
+ .limitTo(D::PARAM & D::VIDEO & D::DECODER)
+ .withMapper([](C2Value v) -> C2Value {
+ int32_t value = 0;
+ (void)v.get(&value);
+ return value == 0
+ ? C2Value(C2PlatformConfig::SPECIFIED_PEEK)
+ : C2Value(C2PlatformConfig::UNSPECIFIED_PEEK);
+ }));
+
add(ConfigMapper(KEY_VIDEO_QP_AVERAGE, C2_PARAMKEY_AVERAGE_QP, "value")
.limitTo(D::ENCODER & D::VIDEO & D::READ));
add(ConfigMapper(KEY_PICTURE_TYPE, C2_PARAMKEY_PICTURE_TYPE, "value")
- .limitTo(D::ENCODER & D::VIDEO & D::READ));
+ .limitTo(D::ENCODER & D::VIDEO & D::READ)
+ .withMappers([](C2Value v) -> C2Value {
+ int32_t sdk;
+ C2Config::picture_type_t c2;
+ if (v.get(&sdk) && C2Mapper::map(sdk, &c2)) {
+ return C2Value(c2);
+ }
+ return C2Value();
+ }, [](C2Value v) -> C2Value {
+ C2Config::picture_type_t c2;
+ int32_t sdk = PICTURE_TYPE_UNKNOWN;
+ using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(c2)>::type;
+ if (v.get((C2ValueType*)&c2) && C2Mapper::map(c2, &sdk)) {
+ return sdk;
+ }
+ return C2Value();
+ }));
/* still to do
not yet used by MediaCodec, but defined as MediaFormat
@@ -1660,6 +1689,27 @@
params->setFloat(C2_PARAMKEY_INPUT_TIME_STRETCH, captureRate / frameRate);
}
}
+
+ // add HDR format for video encoding
+ if (configDomain == IS_CONFIG) {
+ // don't assume here that transfer is set for HDR, only require it for HLG
+ int transfer = 0;
+ params->findInt32(KEY_COLOR_TRANSFER, &transfer);
+
+ int profile;
+ if (params->findInt32(KEY_PROFILE, &profile)) {
+ std::shared_ptr<C2Mapper::ProfileLevelMapper> mapper =
+ C2Mapper::GetProfileLevelMapper(mCodingMediaType);
+ C2Config::hdr_format_t c2 = C2Config::hdr_format_t::UNKNOWN;
+ if (mapper && mapper->mapHdrFormat(profile, &c2)) {
+ if (c2 == C2Config::hdr_format_t::HLG &&
+ transfer != COLOR_TRANSFER_HLG) {
+ c2 = C2Config::hdr_format_t::UNKNOWN;
+ }
+ params->setInt32(C2_PARAMKEY_HDR_FORMAT, c2);
+ }
+ }
+ }
}
{ // reflect temporal layering into a binary blob
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index c2405e8..6084ee3 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -1178,9 +1178,6 @@
}
if (dynamicInfo && *dynamicInfo && dynamicInfo->flexCount() > 0) {
ALOGV("Setting dynamic HDR info as gralloc4 metadata");
- hidl_vec<uint8_t> vec;
- vec.resize(dynamicInfo->flexCount());
- memcpy(vec.data(), dynamicInfo->m.data, dynamicInfo->flexCount());
std::optional<IMapper4::MetadataType> metadataType;
switch (dynamicInfo->m.type_) {
case C2Config::HDR_DYNAMIC_METADATA_TYPE_SMPTE_2094_10:
@@ -1190,12 +1187,20 @@
metadataType = MetadataType_Smpte2094_40;
break;
}
+
if (metadataType) {
- Return<Error4> ret = mapper->set(buffer.get(), *metadataType, vec);
- if (!ret.isOk()) {
- err = C2_REFUSED;
- } else if (ret != Error4::NONE) {
- err = C2_CORRUPTED;
+ std::vector<uint8_t> smpte2094_40;
+ smpte2094_40.resize(dynamicInfo->flexCount());
+ memcpy(smpte2094_40.data(), dynamicInfo->m.data, dynamicInfo->flexCount());
+
+ hidl_vec<uint8_t> vec;
+ if (gralloc4::encodeSmpte2094_40({ smpte2094_40 }, &vec) == OK) {
+ Return<Error4> ret = mapper->set(buffer.get(), *metadataType, vec);
+ if (!ret.isOk()) {
+ err = C2_REFUSED;
+ } else if (ret != Error4::NONE) {
+ err = C2_CORRUPTED;
+ }
}
} else {
err = C2_BAD_VALUE;
diff --git a/media/codec2/sfplugin/Codec2InfoBuilder.cpp b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
index 2b8a160..3f9a40d 100644
--- a/media/codec2/sfplugin/Codec2InfoBuilder.cpp
+++ b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
@@ -33,6 +33,7 @@
#include <OMX_Video.h>
#include <OMX_VideoExt.h>
#include <OMX_AsString.h>
+#include <SurfaceFlingerProperties.sysprop.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
#include <android/hardware/media/omx/1.0/IOmxObserver.h>
@@ -136,7 +137,9 @@
continue;
}
switch (type.coreIndex()) {
- case C2StreamHdr10PlusInfo::CORE_INDEX:
+ case C2StreamHdrDynamicMetadataInfo::CORE_INDEX:
+ [[fallthrough]];
+ case C2StreamHdr10PlusInfo::CORE_INDEX: // will be deprecated
supportsHdr10Plus = true;
break;
case C2StreamHdrStaticInfo::CORE_INDEX:
@@ -148,14 +151,21 @@
}
}
- // For VP9/AV1, the static info is always propagated by framework.
+ // VP9 does not support HDR metadata in the bitstream and static metadata
+ // can always be carried by the framework. (The framework does not propagate
+ // dynamic metadata as that needs to be frame accurate.)
supportsHdr |= (mediaType == MIMETYPE_VIDEO_VP9);
- supportsHdr |= (mediaType == MIMETYPE_VIDEO_AV1);
// HDR support implies 10-bit support.
// TODO: directly check this from the component interface
supports10Bit = (supportsHdr || supportsHdr10Plus);
+ // If the device doesn't support HDR display, then no codec on the device
+ // can advertise support for HDR profiles.
+ // Default to true to maintain backward compatibility
+ auto ret = sysprop::SurfaceFlingerProperties::has_HDR_display();
+ bool hasHDRDisplay = ret.has_value() ? *ret : true;
+
bool added = false;
for (C2Value::Primitive profile : profileQuery[0].values.values) {
@@ -181,8 +191,8 @@
if (mapper && mapper->mapProfile(pl.profile, &sdkProfile)
&& mapper->mapLevel(pl.level, &sdkLevel)) {
caps->addProfileLevel((uint32_t)sdkProfile, (uint32_t)sdkLevel);
- // also list HDR profiles if component supports HDR
- if (supportsHdr) {
+ // also list HDR profiles if component supports HDR and device has HDR display
+ if (supportsHdr && hasHDRDisplay) {
auto hdrMapper = C2Mapper::GetHdrProfileLevelMapper(trait.mediaType);
if (hdrMapper && hdrMapper->mapProfile(pl.profile, &sdkProfile)) {
caps->addProfileLevel((uint32_t)sdkProfile, (uint32_t)sdkLevel);
diff --git a/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp b/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp
index 41e4fff..a471291 100644
--- a/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp
+++ b/media/codec2/sfplugin/tests/CCodecBuffers_test.cpp
@@ -861,4 +861,57 @@
+ std::to_string(std::get<3>(info.param));
});
+TEST(LinearOutputBuffersTest, PcmConvertFormat) {
+ // Prepare LinearOutputBuffers
+ std::shared_ptr<LinearOutputBuffers> buffers =
+ std::make_shared<LinearOutputBuffers>("test");
+ sp<AMessage> format{new AMessage};
+ format->setInt32(KEY_CHANNEL_COUNT, 1);
+ format->setInt32(KEY_SAMPLE_RATE, 8000);
+ format->setInt32(KEY_PCM_ENCODING, kAudioEncodingPcmFloat);
+ format->setInt32("android._config-pcm-encoding", kAudioEncodingPcm16bit);
+ format->setInt32("android._codec-pcm-encoding", kAudioEncodingPcmFloat);
+ buffers->setFormat(format);
+
+ // Prepare a linear C2Buffer
+ std::shared_ptr<C2BlockPool> pool;
+ ASSERT_EQ(OK, GetCodec2BlockPool(C2BlockPool::BASIC_LINEAR, nullptr, &pool));
+
+ std::shared_ptr<C2LinearBlock> block;
+ ASSERT_EQ(OK, pool->fetchLinearBlock(
+ 1024, C2MemoryUsage{C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block));
+ std::shared_ptr<C2Buffer> c2Buffer =
+ C2Buffer::CreateLinearBuffer(block->share(0, 1024, C2Fence()));
+
+ // Test regular buffer convert
+ size_t index;
+ sp<MediaCodecBuffer> clientBuffer;
+ ASSERT_EQ(OK, buffers->registerBuffer(c2Buffer, &index, &clientBuffer));
+ int32_t pcmEncoding = 0;
+ ASSERT_TRUE(clientBuffer->format()->findInt32(KEY_PCM_ENCODING, &pcmEncoding));
+ EXPECT_EQ(kAudioEncodingPcm16bit, pcmEncoding);
+ ASSERT_TRUE(buffers->releaseBuffer(clientBuffer, &c2Buffer));
+
+ // Test null buffer convert
+ ASSERT_EQ(OK, buffers->registerBuffer(nullptr, &index, &clientBuffer));
+ ASSERT_TRUE(clientBuffer->format()->findInt32(KEY_PCM_ENCODING, &pcmEncoding));
+ EXPECT_EQ(kAudioEncodingPcm16bit, pcmEncoding);
+ ASSERT_TRUE(buffers->releaseBuffer(clientBuffer, &c2Buffer));
+
+ // Do the same test in the array mode
+ std::shared_ptr<OutputBuffersArray> array = buffers->toArrayMode(8);
+
+ // Test regular buffer convert
+ ASSERT_EQ(OK, buffers->registerBuffer(c2Buffer, &index, &clientBuffer));
+ ASSERT_TRUE(clientBuffer->format()->findInt32(KEY_PCM_ENCODING, &pcmEncoding));
+ EXPECT_EQ(kAudioEncodingPcm16bit, pcmEncoding);
+ ASSERT_TRUE(buffers->releaseBuffer(clientBuffer, &c2Buffer));
+
+ // Test null buffer convert
+ ASSERT_EQ(OK, buffers->registerBuffer(nullptr, &index, &clientBuffer));
+ ASSERT_TRUE(clientBuffer->format()->findInt32(KEY_PCM_ENCODING, &pcmEncoding));
+ EXPECT_EQ(kAudioEncodingPcm16bit, pcmEncoding);
+ ASSERT_TRUE(buffers->releaseBuffer(clientBuffer, &c2Buffer));
+}
+
} // namespace android
diff --git a/media/codec2/sfplugin/utils/Codec2Mapper.cpp b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
index 93f29ca..c606d6f 100644
--- a/media/codec2/sfplugin/utils/Codec2Mapper.cpp
+++ b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
@@ -276,6 +276,13 @@
{ C2Config::PROFILE_HEVC_MAIN_10, HEVCProfileMain10HDR10Plus },
};
+ALookup<C2Config::hdr_format_t, int32_t> sHevcHdrFormats = {
+ { C2Config::hdr_format_t::SDR, HEVCProfileMain },
+ { C2Config::hdr_format_t::HLG, HEVCProfileMain10 },
+ { C2Config::hdr_format_t::HDR10, HEVCProfileMain10HDR10 },
+ { C2Config::hdr_format_t::HDR10_PLUS, HEVCProfileMain10HDR10Plus },
+};
+
ALookup<C2Config::level_t, int32_t> sMpeg2Levels = {
{ C2Config::LEVEL_MP2V_LOW, MPEG2LevelLL },
{ C2Config::LEVEL_MP2V_MAIN, MPEG2LevelML },
@@ -365,6 +372,17 @@
{ C2Config::PROFILE_VP9_3, VP9Profile3HDR10Plus },
};
+ALookup<C2Config::hdr_format_t, int32_t> sVp9HdrFormats = {
+ { C2Config::hdr_format_t::SDR, VP9Profile0 },
+ { C2Config::hdr_format_t::SDR, VP9Profile1 },
+ { C2Config::hdr_format_t::HLG, VP9Profile2 },
+ { C2Config::hdr_format_t::HLG, VP9Profile3 },
+ { C2Config::hdr_format_t::HDR10, VP9Profile2HDR },
+ { C2Config::hdr_format_t::HDR10, VP9Profile3HDR },
+ { C2Config::hdr_format_t::HDR10_PLUS, VP9Profile2HDR10Plus },
+ { C2Config::hdr_format_t::HDR10_PLUS, VP9Profile3HDR10Plus },
+};
+
ALookup<C2Config::level_t, int32_t> sAv1Levels = {
{ C2Config::LEVEL_AV1_2, AV1Level2 },
{ C2Config::LEVEL_AV1_2_1, AV1Level21 },
@@ -411,6 +429,13 @@
{ C2Config::PROFILE_AV1_0, AV1ProfileMain10HDR10Plus },
};
+ALookup<C2Config::hdr_format_t, int32_t> sAv1HdrFormats = {
+ { C2Config::hdr_format_t::SDR, AV1ProfileMain8 },
+ { C2Config::hdr_format_t::HLG, AV1ProfileMain10 },
+ { C2Config::hdr_format_t::HDR10, AV1ProfileMain10HDR10 },
+ { C2Config::hdr_format_t::HDR10_PLUS, AV1ProfileMain10HDR10Plus },
+};
+
// HAL_PIXEL_FORMAT_* -> COLOR_Format*
ALookup<uint32_t, int32_t> sPixelFormats = {
{ HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, COLOR_FormatSurface },
@@ -435,6 +460,13 @@
{ HAL_PIXEL_FORMAT_RGBA_FP16, COLOR_Format64bitABGRFloat },
};
+ALookup<C2Config::picture_type_t, int32_t> sPictureType = {
+ { C2Config::picture_type_t::SYNC_FRAME, PICTURE_TYPE_I },
+ { C2Config::picture_type_t::I_FRAME, PICTURE_TYPE_I },
+ { C2Config::picture_type_t::P_FRAME, PICTURE_TYPE_P },
+ { C2Config::picture_type_t::B_FRAME, PICTURE_TYPE_B },
+};
+
/**
* A helper that passes through vendor extension profile and level values.
*/
@@ -487,6 +519,10 @@
virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
return sAacProfiles.map(from, to);
}
+ // AAC does not have HDR format
+ virtual bool mapHdrFormat(int32_t, C2Config::hdr_format_t*) override {
+ return false;
+ }
};
struct AvcProfileLevelMapper : ProfileLevelMapperHelper {
@@ -517,6 +553,12 @@
virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
return sDolbyVisionProfiles.map(from, to);
}
+ // Dolby Vision is always HDR and the profile is fully expressive so use unknown
+ // HDR format
+ virtual bool mapHdrFormat(int32_t, C2Config::hdr_format_t *to) override {
+ *to = C2Config::hdr_format_t::UNKNOWN;
+ return true;
+ }
};
struct H263ProfileLevelMapper : ProfileLevelMapperHelper {
@@ -555,6 +597,9 @@
mIsHdr ? sHevcHdrProfiles.map(from, to) :
sHevcProfiles.map(from, to);
}
+ virtual bool mapHdrFormat(int32_t from, C2Config::hdr_format_t *to) override {
+ return sHevcHdrFormats.map(from, to);
+ }
private:
bool mIsHdr;
@@ -633,6 +678,9 @@
mIsHdr ? sVp9HdrProfiles.map(from, to) :
sVp9Profiles.map(from, to);
}
+ virtual bool mapHdrFormat(int32_t from, C2Config::hdr_format_t *to) override {
+ return sVp9HdrFormats.map(from, to);
+ }
private:
bool mIsHdr;
@@ -662,6 +710,9 @@
mIsHdr ? sAv1HdrProfiles.map(from, to) :
sAv1Profiles.map(from, to);
}
+ virtual bool mapHdrFormat(int32_t from, C2Config::hdr_format_t *to) override {
+ return sAv1HdrFormats.map(from, to);
+ }
private:
bool mIsHdr;
@@ -671,6 +722,13 @@
} // namespace
+// the default mapper is used for media types that do not support HDR
+bool C2Mapper::ProfileLevelMapper::mapHdrFormat(int32_t, C2Config::hdr_format_t *to) {
+ // by default map all (including vendor) profiles to SDR
+ *to = C2Config::hdr_format_t::SDR;
+ return true;
+}
+
// static
std::shared_ptr<C2Mapper::ProfileLevelMapper>
C2Mapper::GetProfileLevelMapper(std::string mediaType) {
@@ -1024,3 +1082,13 @@
}
return true;
}
+
+// static
+bool C2Mapper::map(C2Config::picture_type_t from, int32_t *to) {
+ return sPictureType.map(from, to);
+}
+
+// static
+bool C2Mapper::map(int32_t from, C2Config::picture_type_t *to) {
+ return sPictureType.map(from, to);
+}
diff --git a/media/codec2/sfplugin/utils/Codec2Mapper.h b/media/codec2/sfplugin/utils/Codec2Mapper.h
index 33d305e..c8e9e13 100644
--- a/media/codec2/sfplugin/utils/Codec2Mapper.h
+++ b/media/codec2/sfplugin/utils/Codec2Mapper.h
@@ -34,6 +34,16 @@
virtual bool mapProfile(int32_t, C2Config::profile_t*) = 0;
virtual bool mapLevel(C2Config::level_t, int32_t*) = 0;
virtual bool mapLevel(int32_t, C2Config::level_t*) = 0;
+
+ /**
+ * Mapper method that maps a MediaCodec profile to the supported
+ * HDR format for that profile. Since 10-bit profiles are used for
+ * HLG, this method will return HLG for all 10-bit profiles, but
+ * the caller should also verify that the transfer function is
+ * indeed HLG.
+ */
+ // not an abstract method as we have a default implementation for SDR
+ virtual bool mapHdrFormat(int32_t, C2Config::hdr_format_t *hdr);
virtual ~ProfileLevelMapper() = default;
};
diff --git a/media/codec2/vndk/C2Fence.cpp b/media/codec2/vndk/C2Fence.cpp
index 9c5183e..0b556aa 100644
--- a/media/codec2/vndk/C2Fence.cpp
+++ b/media/codec2/vndk/C2Fence.cpp
@@ -16,13 +16,24 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "C2FenceFactory"
+#include <cutils/native_handle.h>
#include <utils/Log.h>
+#include <ui/Fence.h>
#include <C2FenceFactory.h>
#include <C2SurfaceSyncObj.h>
+#define MAX_FENCE_FDS 1
+
class C2Fence::Impl {
public:
+ enum type_t : uint32_t {
+ INVALID_FENCE,
+ NULL_FENCE,
+ SURFACE_FENCE,
+ SYNC_FENCE,
+ };
+
virtual c2_status_t wait(c2_nsecs_t timeoutNs) = 0;
virtual bool valid() const = 0;
@@ -33,9 +44,26 @@
virtual bool isHW() const = 0;
+ virtual type_t type() const = 0;
+
+ /**
+ * Create a native handle for the fence so it can be marshalled.
+ * The native handle must store fence type in the first integer.
+ *
+ * \return a valid native handle if the fence can be marshalled, otherwise return null.
+ */
+ virtual native_handle_t *createNativeHandle() const = 0;
+
virtual ~Impl() = default;
Impl() = default;
+
+ static type_t GetTypeFromNativeHandle(const native_handle_t* nh) {
+ if (nh && nh->numFds >= 0 && nh->numFds <= MAX_FENCE_FDS && nh->numInts > 0) {
+ return static_cast<type_t>(nh->data[nh->numFds]);
+ }
+ return INVALID_FENCE;
+ }
};
c2_status_t C2Fence::wait(c2_nsecs_t timeoutNs) {
@@ -115,6 +143,15 @@
return false;
}
+ virtual type_t type() const {
+ return SURFACE_FENCE;
+ }
+
+ virtual native_handle_t *createNativeHandle() const {
+ ALOGD("Cannot create native handle from surface fence");
+ return nullptr;
+ }
+
virtual ~SurfaceFenceImpl() {};
SurfaceFenceImpl(std::shared_ptr<C2SurfaceSyncMemory> syncMem, uint32_t waitId) :
@@ -143,3 +180,120 @@
}
return C2Fence();
}
+
+using namespace android;
+
+class _C2FenceFactory::SyncFenceImpl : public C2Fence::Impl {
+public:
+ virtual c2_status_t wait(c2_nsecs_t timeoutNs) {
+ c2_nsecs_t timeoutMs = timeoutNs / 1000;
+ if (timeoutMs > INT_MAX) {
+ timeoutMs = INT_MAX;
+ }
+
+ switch (mFence->wait((int)timeoutMs)) {
+ case NO_ERROR:
+ return C2_OK;
+ case -ETIME:
+ return C2_TIMED_OUT;
+ default:
+ return C2_CORRUPTED;
+ }
+ }
+
+ virtual bool valid() const {
+ return mFence->getStatus() != Fence::Status::Invalid;
+ }
+
+ virtual bool ready() const {
+ return mFence->getStatus() == Fence::Status::Signaled;
+ }
+
+ virtual int fd() const {
+ return mFence->dup();
+ }
+
+ virtual bool isHW() const {
+ return true;
+ }
+
+ virtual type_t type() const {
+ return SYNC_FENCE;
+ }
+
+ virtual native_handle_t *createNativeHandle() const {
+ native_handle_t* nh = native_handle_create(1, 1);
+ if (!nh) {
+ ALOGE("Failed to allocate native handle for sync fence");
+ return nullptr;
+ }
+ nh->data[0] = fd();
+ nh->data[1] = type();
+ return nh;
+ }
+
+ virtual ~SyncFenceImpl() {};
+
+ SyncFenceImpl(int fenceFd) :
+ mFence(sp<Fence>::make(fenceFd)) {}
+
+ static std::shared_ptr<SyncFenceImpl> CreateFromNativeHandle(const native_handle_t* nh) {
+ if (!nh || nh->numFds != 1 || nh->numInts != 1) {
+ ALOGE("Invalid handle for sync fence");
+ return nullptr;
+ }
+ int fd = dup(nh->data[0]);
+ std::shared_ptr<SyncFenceImpl> p = std::make_shared<SyncFenceImpl>(fd);
+ if (!p) {
+ ALOGE("Failed to allocate sync fence impl");
+ close(fd);
+ }
+ return p;
+ }
+
+private:
+ const sp<Fence> mFence;
+};
+
+C2Fence _C2FenceFactory::CreateSyncFence(int fenceFd) {
+ std::shared_ptr<C2Fence::Impl> p;
+ if (fenceFd >= 0) {
+ p = std::make_shared<_C2FenceFactory::SyncFenceImpl>(fenceFd);
+ if (!p) {
+ ALOGE("Failed to allocate sync fence impl");
+ close(fenceFd);
+ }
+ if (!p->valid()) {
+ p.reset();
+ }
+ } else {
+ ALOGE("Create sync fence from invalid fd");
+ }
+ return C2Fence(p);
+}
+
+native_handle_t* _C2FenceFactory::CreateNativeHandle(const C2Fence& fence) {
+ return fence.mImpl? fence.mImpl->createNativeHandle() : nullptr;
+}
+
+C2Fence _C2FenceFactory::CreateFromNativeHandle(const native_handle_t* handle) {
+ if (!handle) {
+ return C2Fence();
+ }
+ C2Fence::Impl::type_t type = C2Fence::Impl::GetTypeFromNativeHandle(handle);
+ std::shared_ptr<C2Fence::Impl> p;
+ switch (type) {
+ case C2Fence::Impl::SYNC_FENCE:
+ p = SyncFenceImpl::CreateFromNativeHandle(handle);
+ break;
+ default:
+ ALOGD("Unsupported fence type %d", type);
+ // return a null-fence in this case
+ break;
+ }
+ if (p && !p->valid()) {
+ p.reset();
+ }
+ return C2Fence(p);
+}
+
diff --git a/media/codec2/vndk/include/C2FenceFactory.h b/media/codec2/vndk/include/C2FenceFactory.h
index d4bed26..4944115 100644
--- a/media/codec2/vndk/include/C2FenceFactory.h
+++ b/media/codec2/vndk/include/C2FenceFactory.h
@@ -28,6 +28,7 @@
struct _C2FenceFactory {
class SurfaceFenceImpl;
+ class SyncFenceImpl;
/*
* Create C2Fence for BufferQueueBased blockpool.
@@ -38,6 +39,30 @@
static C2Fence CreateSurfaceFence(
std::shared_ptr<C2SurfaceSyncMemory> syncMem,
uint32_t waitId);
+
+ /*
+ * Create C2Fence from a fence file fd.
+ *
+ * \param fenceFd Fence file descriptor.
+ * It will be owned and closed by the returned fence object.
+ */
+ static C2Fence CreateSyncFence(int fenceFd);
+
+ /**
+ * Create a native handle from fence for marshalling
+ *
+ * \return a non-null pointer if the fence can be marshalled, otherwise return nullptr
+ */
+ static native_handle_t* CreateNativeHandle(const C2Fence& fence);
+
+ /*
+ * Create C2Fence from a native handle.
+
+ * \param handle A native handle representing a fence
+ * The fd in the native handle will be duplicated, so the caller will
+ * still own the handle and have to close it.
+ */
+ static C2Fence CreateFromNativeHandle(const native_handle_t* handle);
};
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index eccbf46..7f97ddc 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -4775,7 +4775,7 @@
if (len2 == 0) {
return ERROR_MALFORMED;
}
- if (offset >= csd_size || csd[offset] != 0x01) {
+ if (offset + len1 > csd_size || csd[offset] != 0x01) {
return ERROR_MALFORMED;
}
diff --git a/media/libaaudio/src/flowgraph/FlowgraphUtilities.h b/media/libaaudio/src/flowgraph/FlowgraphUtilities.h
index ce2bc82..5e90588 100644
--- a/media/libaaudio/src/flowgraph/FlowgraphUtilities.h
+++ b/media/libaaudio/src/flowgraph/FlowgraphUtilities.h
@@ -39,9 +39,9 @@
static const float limneg = -1.;
if (f <= limneg) {
- return -0x80000000; /* or 0x80000000 */
+ return INT32_MIN;
} else if (f >= limpos) {
- return 0x7fffffff;
+ return INT32_MAX;
}
f *= scale;
/* integer conversion is through truncation (though int to float is not).
diff --git a/media/libaaudio/tests/test_flowgraph.cpp b/media/libaaudio/tests/test_flowgraph.cpp
index 913feb0..66b77eb 100644
--- a/media/libaaudio/tests/test_flowgraph.cpp
+++ b/media/libaaudio/tests/test_flowgraph.cpp
@@ -16,6 +16,9 @@
/*
* Test FlowGraph
+ *
+ * This file also tests a few different conversion techniques because
+ * sometimes that have caused compiler bugs.
*/
#include <iostream>
@@ -30,6 +33,7 @@
#include "flowgraph/SinkFloat.h"
#include "flowgraph/SinkI16.h"
#include "flowgraph/SinkI24.h"
+#include "flowgraph/SinkI32.h"
#include "flowgraph/SourceI16.h"
#include "flowgraph/SourceI24.h"
@@ -37,6 +41,22 @@
constexpr int kBytesPerI24Packed = 3;
+constexpr int kNumSamples = 8;
+constexpr std::array<float, kNumSamples> kInputFloat = {
+ 1.0f, 0.5f, -0.25f, -1.0f,
+ 0.0f, 53.9f, -87.2f, -1.02f};
+
+// Corresponding PCM values as integers.
+constexpr std::array<int16_t, kNumSamples> kExpectedI16 = {
+ INT16_MAX, 1 << 14, INT16_MIN / 4, INT16_MIN,
+ 0, INT16_MAX, INT16_MIN, INT16_MIN};
+
+constexpr std::array<int32_t, kNumSamples> kExpectedI32 = {
+ INT32_MAX, 1 << 30, INT32_MIN / 4, INT32_MIN,
+ 0, INT32_MAX, INT32_MIN, INT32_MIN};
+
+// =================================== FLOAT to I16 ==============
+
// Simple test that tries to reproduce a Clang compiler bug.
__attribute__((noinline))
void local_convert_float_to_int16(const float *input,
@@ -49,18 +69,11 @@
}
TEST(test_flowgraph, local_convert_float_int16) {
- static constexpr int kNumSamples = 8;
- static constexpr std::array<float, kNumSamples> input = {
- 1.0f, 0.5f, -0.25f, -1.0f,
- 0.0f, 53.9f, -87.2f, -1.02f};
- static constexpr std::array<int16_t, kNumSamples> expected = {
- 32767, 16384, -8192, -32768,
- 0, 32767, -32768, -32768};
std::array<int16_t, kNumSamples> output;
// Do it inline, which will probably work even with the buggy compiler.
// This validates the expected data.
- const float *in = input.data();
+ const float *in = kInputFloat.data();
int16_t *out = output.data();
output.fill(777);
for (int i = 0; i < kNumSamples; i++) {
@@ -68,38 +81,106 @@
*out++ = std::min(INT16_MAX, std::max(INT16_MIN, n)); // clip
}
for (int i = 0; i < kNumSamples; i++) {
- EXPECT_EQ(expected.at(i), output.at(i)) << ", i = " << i;
+ EXPECT_EQ(kExpectedI16.at(i), output.at(i)) << ", i = " << i;
}
// Convert audio signal using the function.
output.fill(777);
- local_convert_float_to_int16(input.data(), output.data(), kNumSamples);
+ local_convert_float_to_int16(kInputFloat.data(), output.data(), kNumSamples);
for (int i = 0; i < kNumSamples; i++) {
- EXPECT_EQ(expected.at(i), output.at(i)) << ", i = " << i;
+ EXPECT_EQ(kExpectedI16.at(i), output.at(i)) << ", i = " << i;
}
}
TEST(test_flowgraph, module_sinki16) {
static constexpr int kNumSamples = 8;
- static constexpr std::array<float, kNumSamples> input = {
- 1.0f, 0.5f, -0.25f, -1.0f,
- 0.0f, 53.9f, -87.2f, -1.02f};
- static constexpr std::array<int16_t, kNumSamples> expected = {
- 32767, 16384, -8192, -32768,
- 0, 32767, -32768, -32768};
std::array<int16_t, kNumSamples + 10> output; // larger than input
SourceFloat sourceFloat{1};
SinkI16 sinkI16{1};
- sourceFloat.setData(input.data(), kNumSamples);
+ sourceFloat.setData(kInputFloat.data(), kNumSamples);
sourceFloat.output.connect(&sinkI16.input);
output.fill(777);
int32_t numRead = sinkI16.read(output.data(), output.size());
ASSERT_EQ(kNumSamples, numRead);
for (int i = 0; i < numRead; i++) {
- EXPECT_EQ(expected.at(i), output.at(i)) << ", i = " << i;
+ EXPECT_EQ(kExpectedI16.at(i), output.at(i)) << ", i = " << i;
+ }
+}
+
+// =================================== FLOAT to I32 ==============
+// Simple test that tries to reproduce a Clang compiler bug.
+__attribute__((noinline))
+static int32_t clamp32FromFloat(float f)
+{
+ static const float scale = (float)(1UL << 31);
+ static const float limpos = 1.;
+ static const float limneg = -1.;
+
+ if (f <= limneg) {
+ return INT32_MIN;
+ } else if (f >= limpos) {
+ return INT32_MAX;
+ }
+ f *= scale;
+ /* integer conversion is through truncation (though int to float is not).
+ * ensure that we round to nearest, ties away from 0.
+ */
+ return f > 0 ? f + 0.5 : f - 0.5;
+}
+
+void local_convert_float_to_int32(const float *input,
+ int32_t *output,
+ int count) {
+ for (int i = 0; i < count; i++) {
+ *output++ = clamp32FromFloat(*input++);
+ }
+}
+
+TEST(test_flowgraph, simple_convert_float_int32) {
+ std::array<int32_t, kNumSamples> output;
+
+ // Do it inline, which will probably work even with a buggy compiler.
+ // This validates the expected data.
+ const float *in = kInputFloat.data();
+ output.fill(777);
+ int32_t *out = output.data();
+ for (int i = 0; i < kNumSamples; i++) {
+ int64_t n = (int64_t) (*in++ * 2147483648.0f);
+ *out++ = (int32_t)std::min((int64_t)INT32_MAX,
+ std::max((int64_t)INT32_MIN, n)); // clip
+ }
+ for (int i = 0; i < kNumSamples; i++) {
+ EXPECT_EQ(kExpectedI32.at(i), output.at(i)) << ", i = " << i;
+ }
+}
+
+TEST(test_flowgraph, local_convert_float_int32) {
+ std::array<int32_t, kNumSamples> output;
+ // Convert audio signal using the function.
+ output.fill(777);
+ local_convert_float_to_int32(kInputFloat.data(), output.data(), kNumSamples);
+ for (int i = 0; i < kNumSamples; i++) {
+ EXPECT_EQ(kExpectedI32.at(i), output.at(i)) << ", i = " << i;
+ }
+}
+
+TEST(test_flowgraph, module_sinki32) {
+ std::array<int32_t, kNumSamples + 10> output; // larger than input
+
+ SourceFloat sourceFloat{1};
+ SinkI32 sinkI32{1};
+
+ sourceFloat.setData(kInputFloat.data(), kNumSamples);
+ sourceFloat.output.connect(&sinkI32.input);
+
+ output.fill(777);
+ int32_t numRead = sinkI32.read(output.data(), output.size());
+ ASSERT_EQ(kNumSamples, numRead);
+ for (int i = 0; i < numRead; i++) {
+ EXPECT_EQ(kExpectedI32.at(i), output.at(i)) << ", i = " << i;
}
}
diff --git a/media/libaudioclient/include/media/AidlConversionUtil.h b/media/libaudioclient/include/media/AidlConversionUtil.h
index 9f294cb..8817c35 100644
--- a/media/libaudioclient/include/media/AidlConversionUtil.h
+++ b/media/libaudioclient/include/media/AidlConversionUtil.h
@@ -279,6 +279,20 @@
return std::find(er.begin(), er.end(), value) != er.end();
}
+// T is a "container" of enum binder types with a toString().
+template <typename T>
+std::string enumsToString(const T& t) {
+ std::string s;
+ for (const auto item : t) {
+ if (s.empty()) {
+ s = toString(item);
+ } else {
+ s.append("|").append(toString(item));
+ }
+ }
+ return s;
+}
+
/**
* Return the equivalent Android status_t from a binder exception code.
*
diff --git a/media/libheadtracking/Android.bp b/media/libheadtracking/Android.bp
index 1d41889..9d63f9b 100644
--- a/media/libheadtracking/Android.bp
+++ b/media/libheadtracking/Android.bp
@@ -46,6 +46,7 @@
],
export_shared_lib_headers: [
"libheadtracking",
+ "libsensor",
],
}
diff --git a/media/libheadtracking/SensorPoseProvider.cpp b/media/libheadtracking/SensorPoseProvider.cpp
index 4884ae4..8ebaf6e 100644
--- a/media/libheadtracking/SensorPoseProvider.cpp
+++ b/media/libheadtracking/SensorPoseProvider.cpp
@@ -26,7 +26,6 @@
#include <android-base/thread_annotations.h>
#include <log/log_main.h>
-#include <sensor/Sensor.h>
#include <sensor/SensorEventQueue.h>
#include <sensor/SensorManager.h>
#include <utils/Looper.h>
@@ -285,7 +284,7 @@
return DataFormat::kUnknown;
}
- std::optional<const Sensor> getSensorByHandle(int32_t handle) {
+ std::optional<const Sensor> getSensorByHandle(int32_t handle) override {
const Sensor* const* list;
ssize_t size;
diff --git a/media/libheadtracking/include/media/SensorPoseProvider.h b/media/libheadtracking/include/media/SensorPoseProvider.h
index d2a6b77..0f42074 100644
--- a/media/libheadtracking/include/media/SensorPoseProvider.h
+++ b/media/libheadtracking/include/media/SensorPoseProvider.h
@@ -20,6 +20,7 @@
#include <optional>
#include <android/sensor.h>
+#include <sensor/Sensor.h>
#include "Pose.h"
#include "Twist.h"
@@ -91,6 +92,14 @@
* @param handle The sensor handle, as provided to startSensor().
*/
virtual void stopSensor(int32_t handle) = 0;
+
+ /**
+ * Returns the sensor or nullopt if it does not exist.
+ *
+ * The Sensor object has const methods that can be used to
+ * discover properties of the sensor.
+ */
+ virtual std::optional<const Sensor> getSensorByHandle(int32_t handle) = 0;
};
} // namespace media
diff --git a/media/libmediametrics/include/MediaMetricsConstants.h b/media/libmediametrics/include/MediaMetricsConstants.h
index 90472eb..1c30510 100644
--- a/media/libmediametrics/include/MediaMetricsConstants.h
+++ b/media/libmediametrics/include/MediaMetricsConstants.h
@@ -51,6 +51,12 @@
// The AudioRecord key appends the "trackId" to the prefix.
#define AMEDIAMETRICS_KEY_PREFIX_AUDIO_RECORD AMEDIAMETRICS_KEY_PREFIX_AUDIO "record."
+// The Audio Sensor key appends the sensor handle integer.
+#define AMEDIAMETRICS_KEY_PREFIX_AUDIO_SENSOR AMEDIAMETRICS_KEY_PREFIX_AUDIO "sensor."
+
+// The Audio Spatializer key appends the spatializerId (currently 0)
+#define AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER AMEDIAMETRICS_KEY_PREFIX_AUDIO "spatializer."
+
// The AudioStream key appends the "streamId" to the prefix.
#define AMEDIAMETRICS_KEY_PREFIX_AUDIO_STREAM AMEDIAMETRICS_KEY_PREFIX_AUDIO "stream."
@@ -135,13 +141,17 @@
#define AMEDIAMETRICS_PROP_FLAGS "flags"
#define AMEDIAMETRICS_PROP_FRAMECOUNT "frameCount" // int32
+#define AMEDIAMETRICS_PROP_HEADTRACKINGMODES "headTrackingModes" // string |, like modes.
#define AMEDIAMETRICS_PROP_INPUTDEVICES "inputDevices" // string value
#define AMEDIAMETRICS_PROP_INTERNALTRACKID "internalTrackId" // int32
#define AMEDIAMETRICS_PROP_INTERVALCOUNT "intervalCount" // int32
#define AMEDIAMETRICS_PROP_LATENCYMS "latencyMs" // double value
+#define AMEDIAMETRICS_PROP_LEVELS "levels" // string | with levels
#define AMEDIAMETRICS_PROP_LOGSESSIONID "logSessionId" // hex string, "" none
#define AMEDIAMETRICS_PROP_METHODCODE "methodCode" // int64_t an int indicating method
#define AMEDIAMETRICS_PROP_METHODNAME "methodName" // string method name
+#define AMEDIAMETRICS_PROP_MODE "mode" // string
+#define AMEDIAMETRICS_PROP_MODES "modes" // string | with modes
#define AMEDIAMETRICS_PROP_NAME "name" // string value
#define AMEDIAMETRICS_PROP_ORIGINALFLAGS "originalFlags" // int32
#define AMEDIAMETRICS_PROP_OUTPUTDEVICES "outputDevices" // string value
@@ -241,6 +251,11 @@
#define AMEDIAMETRICS_PROP_CALLERNAME_VALUE_TONEGENERATOR "tonegenerator" // dial tones
#define AMEDIAMETRICS_PROP_CALLERNAME_VALUE_UNKNOWN "unknown" // callerName not set
+// Many properties are available for the sensor.
+// The mode is how the sensor is being currently used.
+#define AMEDIAMETRICS_PROP_MODE_VALUE_HEAD "head" // used for head tracking
+#define AMEDIAMETRICS_PROP_MODE_VALUE_SCREEN "screen" // used for screen
+
// MediaMetrics errors are expected to cover the following sources:
// https://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html
// https://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index a71631a..8e19d02 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -611,29 +611,42 @@
IPCThreadState::self()->getCallingUid());
result.append(buffer);
} else {
- Mutex::Autolock lock(mLock);
- for (int i = 0, n = mClients.size(); i < n; ++i) {
- sp<Client> c = mClients[i].promote();
- if (c != 0) c->dump(fd, args);
- clients.add(c);
- }
- if (mMediaRecorderClients.size() == 0) {
- result.append(" No media recorder client\n\n");
- } else {
+ {
+ // capture clients under lock
+ Mutex::Autolock lock(mLock);
+ for (int i = 0, n = mClients.size(); i < n; ++i) {
+ sp<Client> c = mClients[i].promote();
+ if (c != nullptr) {
+ clients.add(c);
+ }
+ }
+
for (int i = 0, n = mMediaRecorderClients.size(); i < n; ++i) {
sp<MediaRecorderClient> c = mMediaRecorderClients[i].promote();
- if (c != 0) {
- snprintf(buffer, 255, " MediaRecorderClient pid(%d)\n",
- c->mAttributionSource.pid);
- result.append(buffer);
- write(fd, result.string(), result.size());
- result = "\n";
- c->dump(fd, args);
+ if (c != nullptr) {
mediaRecorderClients.add(c);
}
}
}
+ // dump clients outside of lock
+ for (const sp<Client> &c : clients) {
+ c->dump(fd, args);
+ }
+ if (mediaRecorderClients.size() == 0) {
+ result.append(" No media recorder client\n\n");
+ } else {
+ for (const sp<MediaRecorderClient> &c : mediaRecorderClients) {
+ snprintf(buffer, 255, " MediaRecorderClient pid(%d)\n",
+ c->mAttributionSource.pid);
+ result.append(buffer);
+ write(fd, result.string(), result.size());
+ result = "\n";
+ c->dump(fd, args);
+
+ }
+ }
+
result.append(" Files opened and/or mapped:\n");
snprintf(buffer, SIZE - 1, "/proc/%d/maps", getpid());
FILE *f = fopen(buffer, "r");
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index c6b22a6..9b4fc8f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -2893,6 +2893,38 @@
in.writeInt32(recvTimeUs & 0xFFFFFFFF);
break;
}
+ case ARTPSource::RTCP_RR:
+ {
+ int64_t recvTimeUs;
+ int32_t senderId;
+ int32_t ssrc;
+ int32_t fraction;
+ int32_t lost;
+ int32_t lastSeq;
+ int32_t jitter;
+ int32_t lsr;
+ int32_t dlsr;
+ CHECK(msg->findInt64("recv-time-us", &recvTimeUs));
+ CHECK(msg->findInt32("rtcp-rr-ssrc", &senderId));
+ CHECK(msg->findInt32("rtcp-rrb-ssrc", &ssrc));
+ CHECK(msg->findInt32("rtcp-rrb-fraction", &fraction));
+ CHECK(msg->findInt32("rtcp-rrb-lost", &lost));
+ CHECK(msg->findInt32("rtcp-rrb-lastSeq", &lastSeq));
+ CHECK(msg->findInt32("rtcp-rrb-jitter", &jitter));
+ CHECK(msg->findInt32("rtcp-rrb-lsr", &lsr));
+ CHECK(msg->findInt32("rtcp-rrb-dlsr", &dlsr));
+ in.writeInt32(recvTimeUs >> 32);
+ in.writeInt32(recvTimeUs & 0xFFFFFFFF);
+ in.writeInt32(senderId);
+ in.writeInt32(ssrc);
+ in.writeInt32(fraction);
+ in.writeInt32(lost);
+ in.writeInt32(lastSeq);
+ in.writeInt32(jitter);
+ in.writeInt32(lsr);
+ in.writeInt32(dlsr);
+ break;
+ }
case ARTPSource::RTCP_TSFB: // RTCP TSFB
case ARTPSource::RTCP_PSFB: // RTCP PSFB
case ARTPSource::RTP_AUTODOWN:
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 7917395..52c4c0f 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -77,6 +77,7 @@
namespace {
constexpr char TUNNEL_PEEK_KEY[] = "android._trigger-tunnel-peek";
+constexpr char TUNNEL_PEEK_SET_LEGACY_KEY[] = "android._tunnel-peek-set-legacy";
}
@@ -2483,17 +2484,39 @@
return BAD_VALUE;
}
- OMX_CONFIG_BOOLEANTYPE config;
- InitOMXParams(&config);
- config.bEnabled = (OMX_BOOL)(tunnelPeek != 0);
+ OMX_CONFIG_BOOLEANTYPE tunnelPeekConfig;
+ InitOMXParams(&tunnelPeekConfig);
+ tunnelPeekConfig.bEnabled = (OMX_BOOL)(tunnelPeek != 0);
status_t err = mOMXNode->setConfig(
(OMX_INDEXTYPE)OMX_IndexConfigAndroidTunnelPeek,
- &config, sizeof(config));
+ &tunnelPeekConfig, sizeof(tunnelPeekConfig));
if (err != OK) {
ALOGE("decoder cannot set %s to %d (err %d)",
- TUNNEL_PEEK_KEY, tunnelPeek, err);
+ TUNNEL_PEEK_KEY, tunnelPeek, err);
+ }
+ return err;
+}
+
+status_t ACodec::setTunnelPeekLegacy(int32_t isLegacy) {
+ if (mIsEncoder) {
+ ALOGE("encoder does not support %s", TUNNEL_PEEK_SET_LEGACY_KEY);
+ return BAD_VALUE;
+ }
+ if (!mTunneled) {
+ ALOGE("%s is only supported in tunnel mode", TUNNEL_PEEK_SET_LEGACY_KEY);
+ return BAD_VALUE;
}
+ OMX_CONFIG_BOOLEANTYPE tunnelPeekLegacyModeConfig;
+ InitOMXParams(&tunnelPeekLegacyModeConfig);
+ tunnelPeekLegacyModeConfig.bEnabled = (OMX_BOOL)(isLegacy != 0);
+ status_t err = mOMXNode->setConfig(
+ (OMX_INDEXTYPE)OMX_IndexConfigAndroidTunnelPeekLegacyMode,
+ &tunnelPeekLegacyModeConfig, sizeof(tunnelPeekLegacyModeConfig));
+ if (err != OK) {
+ ALOGE("decoder cannot set video peek legacy mode to %d (err %d)",
+ isLegacy, err);
+ }
return err;
}
@@ -7934,11 +7957,22 @@
}
}
- int32_t tunnelPeek = 0;
- if (params->findInt32(TUNNEL_PEEK_KEY, &tunnelPeek)) {
- status_t err = setTunnelPeek(tunnelPeek);
- if (err != OK) {
- return err;
+ {
+ int32_t tunnelPeek = 0;
+ if (params->findInt32(TUNNEL_PEEK_KEY, &tunnelPeek)) {
+ status_t err = setTunnelPeek(tunnelPeek);
+ if (err != OK) {
+ return err;
+ }
+ }
+ }
+ {
+ int32_t tunnelPeekSetLegacy = 0;
+ if (params->findInt32(TUNNEL_PEEK_SET_LEGACY_KEY, &tunnelPeekSetLegacy)) {
+ status_t err = setTunnelPeekLegacy(tunnelPeekSetLegacy);
+ if (err != OK) {
+ return err;
+ }
}
}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 5a27362..ab1368f 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -120,7 +120,9 @@
static const char *kCodecParsedColorStandard = "android.media.mediacodec.parsed-color-standard";
static const char *kCodecParsedColorRange = "android.media.mediacodec.parsed-color-range";
static const char *kCodecParsedColorTransfer = "android.media.mediacodec.parsed-color-transfer";
-static const char *kCodecHDRMetadataFlags = "android.media.mediacodec.hdr-metadata-flags";
+static const char *kCodecHDRStaticInfo = "android.media.mediacodec.hdr-static-info";
+static const char *kCodecHDR10PlusInfo = "android.media.mediacodec.hdr10-plus-info";
+static const char *kCodecHDRFormat = "android.media.mediacodec.hdr-format";
// Min/Max QP before shaping
static const char *kCodecOriginalVideoQPIMin = "android.media.mediacodec.original-video-qp-i-min";
@@ -805,7 +807,9 @@
mWidth(0),
mHeight(0),
mRotationDegrees(0),
- mHDRMetadataFlags(0),
+ mConfigColorTransfer(-1),
+ mHDRStaticInfo(false),
+ mHDR10PlusInfo(false),
mDequeueInputTimeoutGeneration(0),
mDequeueInputReplyID(0),
mDequeueOutputTimeoutGeneration(0),
@@ -813,7 +817,7 @@
mTunneledInputWidth(0),
mTunneledInputHeight(0),
mTunneled(false),
- mTunnelPeekState(TunnelPeekState::kEnabledNoBuffer),
+ mTunnelPeekState(TunnelPeekState::kLegacyMode),
mHaveInputSurface(false),
mHavePendingInputBuffers(false),
mCpuBoostRequested(false),
@@ -951,13 +955,71 @@
mIndexOfFirstFrameWhenLowLatencyOn);
}
- mediametrics_setInt32(mMetricsHandle, kCodecHDRMetadataFlags, mHDRMetadataFlags);
+ mediametrics_setInt32(mMetricsHandle, kCodecHDRStaticInfo, mHDRStaticInfo ? 1 : 0);
+ mediametrics_setInt32(mMetricsHandle, kCodecHDR10PlusInfo, mHDR10PlusInfo ? 1 : 0);
#if 0
// enable for short term, only while debugging
updateEphemeralMediametrics(mMetricsHandle);
#endif
}
+void MediaCodec::updateHDRFormatMetric() {
+ int32_t profile = -1;
+ AString mediaType;
+ if (mOutputFormat->findInt32(KEY_PROFILE, &profile)
+ && mOutputFormat->findString("mime", &mediaType)) {
+ hdr_format hdrFormat = getHDRFormat(profile, mConfigColorTransfer, mediaType);
+ mediametrics_setInt32(mMetricsHandle, kCodecHDRFormat, static_cast<int>(hdrFormat));
+ }
+}
+
+hdr_format MediaCodec::getHDRFormat(const int32_t profile, const int32_t transfer,
+ const AString &mediaType) {
+ switch (transfer) {
+ case COLOR_TRANSFER_ST2084:
+ if (mediaType.equalsIgnoreCase(MEDIA_MIMETYPE_VIDEO_VP9)) {
+ switch (profile) {
+ case VP9Profile2HDR:
+ return HDR_FORMAT_HDR10;
+ case VP9Profile2HDR10Plus:
+ return HDR_FORMAT_HDR10PLUS;
+ default:
+ return HDR_FORMAT_NONE;
+ }
+ } else if (mediaType.equalsIgnoreCase(MEDIA_MIMETYPE_VIDEO_AV1)) {
+ switch (profile) {
+ case AV1ProfileMain10HDR10:
+ return HDR_FORMAT_HDR10;
+ case AV1ProfileMain10HDR10Plus:
+ return HDR_FORMAT_HDR10PLUS;
+ default:
+ return HDR_FORMAT_NONE;
+ }
+ } else if (mediaType.equalsIgnoreCase(MEDIA_MIMETYPE_VIDEO_HEVC)) {
+ switch (profile) {
+ case HEVCProfileMain10HDR10:
+ return HDR_FORMAT_HDR10;
+ case HEVCProfileMain10HDR10Plus:
+ return HDR_FORMAT_HDR10PLUS;
+ default:
+ return HDR_FORMAT_NONE;
+ }
+ } else {
+ return HDR_FORMAT_NONE;
+ }
+ case COLOR_TRANSFER_HLG:
+ if (!mediaType.equalsIgnoreCase(MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
+ return HDR_FORMAT_HLG;
+ } else {
+ // TODO: DOLBY format
+ return HDR_FORMAT_NONE;
+ }
+ default:
+ return HDR_FORMAT_NONE;
+ }
+}
+
+
void MediaCodec::updateEphemeralMediametrics(mediametrics_handle_t item) {
ALOGD("MediaCodec::updateEphemeralMediametrics()");
@@ -1025,6 +1087,8 @@
constexpr const char *MediaCodec::asString(TunnelPeekState state, const char *default_string){
switch(state) {
+ case TunnelPeekState::kLegacyMode:
+ return "LegacyMode";
case TunnelPeekState::kEnabledNoBuffer:
return "EnabledNoBuffer";
case TunnelPeekState::kDisabledNoBuffer:
@@ -1051,6 +1115,9 @@
TunnelPeekState previousState = mTunnelPeekState;
if(tunnelPeek == 0){
switch (mTunnelPeekState) {
+ case TunnelPeekState::kLegacyMode:
+ msg->setInt32("android._tunnel-peek-set-legacy", 0);
+ [[fallthrough]];
case TunnelPeekState::kEnabledNoBuffer:
mTunnelPeekState = TunnelPeekState::kDisabledNoBuffer;
break;
@@ -1063,6 +1130,9 @@
}
} else {
switch (mTunnelPeekState) {
+ case TunnelPeekState::kLegacyMode:
+ msg->setInt32("android._tunnel-peek-set-legacy", 0);
+ [[fallthrough]];
case TunnelPeekState::kDisabledNoBuffer:
mTunnelPeekState = TunnelPeekState::kEnabledNoBuffer;
break;
@@ -1647,12 +1717,13 @@
}
int32_t colorTransfer = -1;
if (format->findInt32(KEY_COLOR_TRANSFER, &colorTransfer)) {
+ mConfigColorTransfer = colorTransfer;
mediametrics_setInt32(mMetricsHandle, kCodecConfigColorTransfer, colorTransfer);
}
HDRStaticInfo info;
if (ColorUtils::getHDRStaticInfoFromFormat(format, &info)
&& ColorUtils::isHDRStaticInfoValid(&info)) {
- mHDRMetadataFlags |= kFlagHDRStaticInfo;
+ mHDRStaticInfo = true;
}
}
@@ -3307,6 +3378,8 @@
CHECK(msg->findMessage("input-format", &mInputFormat));
CHECK(msg->findMessage("output-format", &mOutputFormat));
+ updateHDRFormatMetric();
+
// limit to confirming the opt-in behavior to minimize any behavioral change
if (mSurface != nullptr && !mAllowFrameDroppingBySurface) {
// signal frame dropping mode in the input format as this may also be
@@ -3388,6 +3461,7 @@
mComponentName.c_str(),
mInputFormat->debugString(4).c_str(),
mOutputFormat->debugString(4).c_str());
+ updateHDRFormatMetric();
CHECK(obj != NULL);
response->setObject("input-surface", obj);
mHaveInputSurface = true;
@@ -3412,6 +3486,7 @@
if (!msg->findInt32("err", &err)) {
CHECK(msg->findMessage("input-format", &mInputFormat));
CHECK(msg->findMessage("output-format", &mOutputFormat));
+ updateHDRFormatMetric();
mHaveInputSurface = true;
} else {
response->setInt32("err", err);
@@ -3472,10 +3547,12 @@
break;
}
TunnelPeekState previousState = mTunnelPeekState;
- mTunnelPeekState = TunnelPeekState::kBufferRendered;
- ALOGV("TunnelPeekState: %s -> %s",
- asString(previousState),
- asString(TunnelPeekState::kBufferRendered));
+ if (mTunnelPeekState != TunnelPeekState::kLegacyMode) {
+ mTunnelPeekState = TunnelPeekState::kBufferRendered;
+ ALOGV("TunnelPeekState: %s -> %s",
+ asString(previousState),
+ asString(TunnelPeekState::kBufferRendered));
+ }
updatePlaybackDuration(msg);
// check that we have a notification set
if (mOnFrameRenderedNotification != NULL) {
@@ -3892,6 +3969,14 @@
mTunneled = false;
}
+ // If mTunnelPeekState is still in kLegacyMode at this point,
+ // configure the codec in legacy mode
+ if (mTunneled && (mTunnelPeekState == TunnelPeekState::kLegacyMode)) {
+ sp<AMessage> params = new AMessage;
+ params->setInt32("android._tunnel-peek-set-legacy", 1);
+ onSetParameters(params);
+ }
+
int32_t background = 0;
if (format->findInt32("android._background-mode", &background) && background) {
androidSetThreadPriority(gettid(), ANDROID_PRIORITY_BACKGROUND);
@@ -4010,10 +4095,12 @@
sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
TunnelPeekState previousState = mTunnelPeekState;
- mTunnelPeekState = TunnelPeekState::kEnabledNoBuffer;
- ALOGV("TunnelPeekState: %s -> %s",
- asString(previousState),
- asString(TunnelPeekState::kEnabledNoBuffer));
+ if (previousState != TunnelPeekState::kLegacyMode) {
+ mTunnelPeekState = TunnelPeekState::kEnabledNoBuffer;
+ ALOGV("TunnelPeekState: %s -> %s",
+ asString(previousState),
+ asString(TunnelPeekState::kEnabledNoBuffer));
+ }
mReplyID = replyID;
setState(STARTING);
@@ -4155,26 +4242,29 @@
break;
}
- if (asyncNotify != nullptr) {
- if (mSurface != NULL) {
- if (!mReleaseSurface) {
- uint64_t usage = 0;
- if (mSurface->getConsumerUsage(&usage) != OK) {
- usage = 0;
- }
- mReleaseSurface.reset(new ReleaseSurface(usage));
+ bool forceSync = false;
+ if (asyncNotify != nullptr && mSurface != NULL) {
+ if (!mReleaseSurface) {
+ uint64_t usage = 0;
+ if (mSurface->getConsumerUsage(&usage) != OK) {
+ usage = 0;
}
- if (mSurface != mReleaseSurface->getSurface()) {
- status_t err = connectToSurface(mReleaseSurface->getSurface());
- ALOGW_IF(err != OK, "error connecting to release surface: err = %d", err);
- if (err == OK && !(mFlags & kFlagUsesSoftwareRenderer)) {
- err = mCodec->setSurface(mReleaseSurface->getSurface());
- ALOGW_IF(err != OK, "error setting release surface: err = %d", err);
- }
- if (err == OK) {
- (void)disconnectFromSurface();
- mSurface = mReleaseSurface->getSurface();
- }
+ mReleaseSurface.reset(new ReleaseSurface(usage));
+ }
+ if (mSurface != mReleaseSurface->getSurface()) {
+ status_t err = connectToSurface(mReleaseSurface->getSurface());
+ ALOGW_IF(err != OK, "error connecting to release surface: err = %d", err);
+ if (err == OK && !(mFlags & kFlagUsesSoftwareRenderer)) {
+ err = mCodec->setSurface(mReleaseSurface->getSurface());
+ ALOGW_IF(err != OK, "error setting release surface: err = %d", err);
+ }
+ if (err == OK) {
+ (void)disconnectFromSurface();
+ mSurface = mReleaseSurface->getSurface();
+ } else {
+ // We were not able to switch the surface, so force
+ // synchronous release.
+ forceSync = true;
}
}
}
@@ -4198,8 +4288,10 @@
}
if (asyncNotify != nullptr) {
- mResourceManagerProxy->markClientForPendingRemoval();
- postPendingRepliesAndDeferredMessages("kWhatRelease:async");
+ if (!forceSync) {
+ mResourceManagerProxy->markClientForPendingRemoval();
+ postPendingRepliesAndDeferredMessages("kWhatRelease:async");
+ }
asyncNotifyPost.clear();
mAsyncReleaseCompleteNotification = asyncNotify;
}
@@ -4449,10 +4541,12 @@
mCodec->signalFlush();
returnBuffersToCodec();
TunnelPeekState previousState = mTunnelPeekState;
- mTunnelPeekState = TunnelPeekState::kEnabledNoBuffer;
- ALOGV("TunnelPeekState: %s -> %s",
- asString(previousState),
- asString(TunnelPeekState::kEnabledNoBuffer));
+ if (previousState != TunnelPeekState::kLegacyMode) {
+ mTunnelPeekState = TunnelPeekState::kEnabledNoBuffer;
+ ALOGV("TunnelPeekState: %s -> %s",
+ asString(previousState),
+ asString(TunnelPeekState::kEnabledNoBuffer));
+ }
break;
}
@@ -4583,6 +4677,7 @@
buffer->meta()->setObject("changedKeys", changedKeys);
}
mOutputFormat = format;
+ updateHDRFormatMetric();
mapFormat(mComponentName, format, nullptr, true);
ALOGV("[%s] output format changed to: %s",
mComponentName.c_str(), mOutputFormat->debugString(4).c_str());
@@ -4609,7 +4704,7 @@
if (ColorUtils::getHDRStaticInfoFromFormat(mOutputFormat, &info)) {
setNativeWindowHdrMetadata(mSurface.get(), &info);
if (ColorUtils::isHDRStaticInfoValid(&info)) {
- mHDRMetadataFlags |= kFlagHDRStaticInfo;
+ mHDRStaticInfo = true;
}
}
}
@@ -4619,7 +4714,7 @@
&& hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0) {
native_window_set_buffers_hdr10_plus_metadata(mSurface.get(),
hdr10PlusInfo->size(), hdr10PlusInfo->data());
- mHDRMetadataFlags |= kFlagHDR10PlusInfo;
+ mHDR10PlusInfo = true;
}
if (mime.startsWithIgnoreCase("video/")) {
@@ -4988,6 +5083,8 @@
offset = buffer->offset();
size = buffer->size();
if (err != OK) {
+ ALOGI("block model buffer attach failed: err = %s (%d)",
+ StrMediaError(err).c_str(), err);
return err;
}
}
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index 632b32c..5a21755 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -522,6 +522,7 @@
status_t setLatency(uint32_t latency);
status_t getLatency(uint32_t *latency);
status_t setTunnelPeek(int32_t tunnelPeek);
+ status_t setTunnelPeekLegacy(int32_t isLegacy);
status_t setAudioPresentation(int32_t presentationId, int32_t programId);
status_t setOperatingRate(float rateFloat, bool isVideo);
status_t getIntraRefreshPeriod(uint32_t *intraRefreshPeriod);
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index f5af50d..1d2d711 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -25,6 +25,7 @@
#include <media/hardware/CryptoAPI.h>
#include <media/MediaCodecInfo.h>
#include <media/MediaMetrics.h>
+#include <media/MediaProfiles.h>
#include <media/stagefright/foundation/AHandler.h>
#include <media/stagefright/FrameRenderTracker.h>
#include <utils/Vector.h>
@@ -397,6 +398,7 @@
// <all states> -> EnabledNoBuffer when flush
// <all states> -> EnabledNoBuffer when stop then configure then start
enum struct TunnelPeekState {
+ kLegacyMode,
kDisabledNoBuffer,
kEnabledNoBuffer,
kDisabledQueued,
@@ -451,11 +453,12 @@
int32_t mRotationDegrees;
int32_t mAllowFrameDroppingBySurface;
- uint32_t mHDRMetadataFlags; /* bitmask of kFlagHDR* */
- enum {
- kFlagHDRStaticInfo = 1 << 0,
- kFlagHDR10PlusInfo = 1 << 1,
- };
+ int32_t mConfigColorTransfer;
+ bool mHDRStaticInfo;
+ bool mHDR10PlusInfo;
+ void updateHDRFormatMetric();
+ hdr_format getHDRFormat(const int32_t profile, const int32_t transfer,
+ const AString &mediaType);
// initial create parameters
AString mInitName;
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 7d72510..a61f48f 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "ARTPConnection"
#include <utils/Log.h>
+#include <media/stagefright/rtsp/ARTPAssembler.h>
#include <media/stagefright/rtsp/ARTPConnection.h>
#include <media/stagefright/rtsp/ARTPSource.h>
#include <media/stagefright/rtsp/ASessionDescription.h>
@@ -41,6 +42,10 @@
return data[0] << 8 | data[1];
}
+static uint32_t u24at(const uint8_t *data) {
+ return u16at(data) << 16 | data[2];
+}
+
static uint32_t u32at(const uint8_t *data) {
return u16at(data) << 16 | u16at(&data[2]);
}
@@ -877,11 +882,15 @@
switch (data[1]) {
case 200:
{
- parseSR(s, data, headerLength);
+ parseSenderReport(s, data, headerLength);
break;
}
case 201: // RR
+ {
+ parseReceiverReport(s, data, headerLength);
+ break;
+ }
case 202: // SDES
case 204: // APP
break;
@@ -940,18 +949,44 @@
return OK;
}
-status_t ARTPConnection::parseSR(
+status_t ARTPConnection::parseSenderReport(
StreamInfo *s, const uint8_t *data, size_t size) {
- size_t RC = data[0] & 0x1f;
-
- if (size < (7 + RC * 6) * 4) {
- // Packet too short for the minimal SR header.
+ ALOG_ASSERT(size >= 1, "parseSenderReport: invalid packet size.");
+ size_t receptionReportCount = data[0] & 0x1f;
+ if (size < (7 + (receptionReportCount * 6)) * 4) {
+ // Packet too short for the minimal sender report header.
return -1;
}
- uint32_t id = u32at(&data[4]);
+ int64_t recvTimeUs = ALooper::GetNowUs();
+ uint32_t senderId = u32at(&data[4]);
uint64_t ntpTime = u64at(&data[8]);
uint32_t rtpTime = u32at(&data[16]);
+ uint32_t pktCount = u32at(&data[20]);
+ uint32_t octCount = u32at(&data[24]);
+
+ ALOGD("SR received: ssrc=0x%08x, rtpTime%u == ntpTime %llu, pkt=%u, oct=%u",
+ senderId, rtpTime, (unsigned long long)ntpTime, pktCount, octCount);
+
+ sp<ARTPSource> source = findSource(s, senderId);
+ source->timeUpdate(recvTimeUs, rtpTime, ntpTime);
+
+ for (int32_t i = 0; i < receptionReportCount; i++) {
+ int32_t offset = 28 + (i * 24);
+ parseReceptionReportBlock(s, recvTimeUs, senderId, data + offset, size - offset);
+ }
+
+ return 0;
+}
+
+status_t ARTPConnection::parseReceiverReport(
+ StreamInfo *s, const uint8_t *data, size_t size) {
+ ALOG_ASSERT(size >= 1, "parseReceiverReport: invalid packet size.");
+ size_t receptionReportCount = data[0] & 0x1f;
+ if (size < (2 + (receptionReportCount * 6)) * 4) {
+ // Packet too short for the minimal receiver report header.
+ return -1;
+ }
#if 0
ALOGI("XXX timeUpdate: ssrc=0x%08x, rtpTime %u == ntpTime %.3f",
@@ -959,10 +994,40 @@
rtpTime,
(ntpTime >> 32) + (double)(ntpTime & 0xffffffff) / (1ll << 32));
#endif
+ int64_t recvTimeUs = ALooper::GetNowUs();
+ uint32_t senderId = u32at(&data[4]);
- sp<ARTPSource> source = findSource(s, id);
+ for (int i = 0; i < receptionReportCount; i++) {
+ int32_t offset = 8 + (i * 24);
+ parseReceptionReportBlock(s, recvTimeUs, senderId, data + offset, size - offset);
+ }
- source->timeUpdate(rtpTime, ntpTime);
+ return 0;
+}
+
+status_t ARTPConnection::parseReceptionReportBlock(
+ StreamInfo *s, int64_t recvTimeUs, uint32_t senderId, const uint8_t *data, size_t size) {
+ ALOG_ASSERT(size >= 24, "parseReceptionReportBlock: invalid packet size.");
+ if (size < 24) {
+ // remaining size is smaller than reception report block size.
+ return -1;
+ }
+
+ uint32_t rbId = u32at(&data[0]);
+ uint32_t fLost = data[4];
+ int32_t cumLost = u24at(&data[5]);
+ uint32_t ehSeq = u32at(&data[8]);
+ uint32_t jitter = u32at(&data[12]);
+ uint32_t lsr = u32at(&data[16]);
+ uint32_t dlsr = u32at(&data[20]);
+
+ ALOGD("Reception Report Block: t:%llu sid:%u rid:%u fl:%u cl:%u hs:%u jt:%u lsr:%u dlsr:%u",
+ (unsigned long long)recvTimeUs, senderId, rbId, fLost, cumLost,
+ ehSeq, jitter, lsr, dlsr);
+ sp<ARTPSource> source = findSource(s, senderId);
+ sp<ReceptionReportBlock> rrb = new ReceptionReportBlock(
+ rbId, fLost, cumLost, ehSeq, jitter, lsr, dlsr);
+ source->processReceptionReportBlock(recvTimeUs, senderId, rrb);
return 0;
}
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 5f62b9d..717d8af 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -132,10 +132,10 @@
}
}
-void ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) {
+void ARTPSource::timeUpdate(int64_t recvTimeUs, uint32_t rtpTime, uint64_t ntpTime) {
mLastSrRtpTime = rtpTime;
mLastSrNtpTime = ntpTime;
- mLastSrUpdateTimeUs = ALooper::GetNowUs();
+ mLastSrUpdateTimeUs = recvTimeUs;
sp<AMessage> notify = mNotify->dup();
notify->setInt32("time-update", true);
@@ -143,7 +143,30 @@
notify->setInt64("ntp-time", ntpTime);
notify->setInt32("rtcp-event", 1);
notify->setInt32("payload-type", RTCP_SR);
- notify->setInt64("recv-time-us", mLastSrUpdateTimeUs);
+ notify->setInt64("recv-time-us", recvTimeUs);
+ notify->post();
+}
+
+void ARTPSource::processReceptionReportBlock(
+ int64_t recvTimeUs, uint32_t senderId, sp<ReceptionReportBlock> rrb) {
+ mLastRrUpdateTimeUs = recvTimeUs;
+
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("rtcp-event", 1);
+ // A Reception Report Block (RRB) can be included in both Sender Report and Receiver Report.
+ // But it means 'Packet Reception Report' actually.
+ // So that, we will report RRB as RR since there is no meaning difference
+ // between RRB(Reception Report Block) and RR(Receiver Report).
+ notify->setInt32("payload-type", RTCP_RR);
+ notify->setInt64("recv-time-us", recvTimeUs);
+ notify->setInt32("rtcp-rr-ssrc", senderId);
+ notify->setInt32("rtcp-rrb-ssrc", rrb->ssrc);
+ notify->setInt32("rtcp-rrb-fraction", rrb->fraction);
+ notify->setInt32("rtcp-rrb-lost", rrb->lost);
+ notify->setInt32("rtcp-rrb-lastSeq", rrb->lastSeq);
+ notify->setInt32("rtcp-rrb-jitter", rrb->jitter);
+ notify->setInt32("rtcp-rrb-lsr", rrb->lsr);
+ notify->setInt32("rtcp-rrb-dlsr", rrb->dlsr);
notify->post();
}
@@ -453,7 +476,8 @@
data[18] = (mHighestSeqNumber >> 8) & 0xff;
data[19] = mHighestSeqNumber & 0xff;
- uint32_t jitterTime = 0;
+ uint32_t jitterTimeMs = (uint32_t)getInterArrivalJitterTimeMs();
+ uint32_t jitterTime = jitterTimeMs * mClockRate / 1000;
data[20] = jitterTime >> 24; // Interarrival jitter
data[21] = (jitterTime >> 16) & 0xff;
data[22] = (jitterTime >> 8) & 0xff;
diff --git a/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPAssembler.h b/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPAssembler.h
index f959c40..39161b6 100644
--- a/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPAssembler.h
+++ b/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPAssembler.h
@@ -105,6 +105,27 @@
(long long)rtp, (long long)play, (long long)exp, isExp);
}
+struct ReceptionReportBlock : public RefBase {
+ uint32_t ssrc; // ssrc of data source being reported
+ uint32_t fraction; // fraction lost since last SR/RR
+ int32_t lost; // cumul. no. pkts lost (signed!)
+ uint32_t lastSeq; // extended last seq. no. received
+ uint32_t jitter; // interarrival jitter
+ uint32_t lsr; // last SR packet from this source
+ uint32_t dlsr; // delay since last SR packet
+
+ ReceptionReportBlock(uint32_t ssrc, uint32_t fraction, int32_t lost, uint32_t lastSeq,
+ uint32_t jitter, uint32_t lsr, uint32_t dlsr) {
+ this->ssrc = ssrc;
+ this->fraction = fraction;
+ this->lost = lost;
+ this->lastSeq = lastSeq;
+ this->jitter = jitter;
+ this->lsr = lsr;
+ this->dlsr = dlsr;
+ }
+};
+
} // namespace android
#endif // A_RTP_ASSEMBLER_H_
diff --git a/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPConnection.h b/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPConnection.h
index 36cca31..73d2866 100644
--- a/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPConnection.h
+++ b/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPConnection.h
@@ -110,7 +110,10 @@
status_t parseRTP(StreamInfo *info, const sp<ABuffer> &buffer);
status_t parseRTPExt(StreamInfo *s, const uint8_t *extData, size_t extLen, int32_t *cvoDegrees);
status_t parseRTCP(StreamInfo *info, const sp<ABuffer> &buffer);
- status_t parseSR(StreamInfo *info, const uint8_t *data, size_t size);
+ status_t parseSenderReport(StreamInfo *info, const uint8_t *data, size_t size);
+ status_t parseReceiverReport(StreamInfo *info, const uint8_t *data, size_t size);
+ status_t parseReceptionReportBlock(StreamInfo *info,
+ int64_t recvTimeUs, uint32_t senderId, const uint8_t *data, size_t size);
status_t parseTSFB(StreamInfo *info, const uint8_t *data, size_t size);
status_t parsePSFB(StreamInfo *info, const uint8_t *data, size_t size);
status_t parseBYE(StreamInfo *info, const uint8_t *data, size_t size);
diff --git a/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPSource.h b/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPSource.h
index 4984e91..e9b4942 100644
--- a/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPSource.h
+++ b/media/libstagefright/rtsp/include/media/stagefright/rtsp/ARTPSource.h
@@ -36,6 +36,7 @@
struct ABuffer;
struct AMessage;
struct ARTPAssembler;
+struct ReceptionReportBlock;
struct ASessionDescription;
struct ARTPSource : public RefBase {
@@ -59,8 +60,10 @@
void processRTPPacket(const sp<ABuffer> &buffer);
void processRTPPacket();
+ void processReceptionReportBlock(
+ int64_t recvTimeUs, uint32_t senderId, sp<ReceptionReportBlock> rrb);
void timeReset();
- void timeUpdate(uint32_t rtpTime, uint64_t ntpTime);
+ void timeUpdate(int64_t recvTimeUs, uint32_t rtpTime, uint64_t ntpTime);
void byeReceived();
List<sp<ABuffer> > *queue() { return &mQueue; }
@@ -135,6 +138,8 @@
uint64_t mLastSrNtpTime;
int64_t mLastSrUpdateTimeUs;
+ int64_t mLastRrUpdateTimeUs;
+
bool mIsFirstRtpRtcpGap;
double mAvgRtpRtcpGapMs;
double mAvgUnderlineDelayMs;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 894b31c..f7576f6 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -3889,17 +3889,24 @@
goto Exit;
}
} else if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
- if (!isAudioServerUid(callingUid)) {
- ALOGE("%s: only APM can create using AUDIO_SESSION_OUTPUT_STAGE", __func__);
- lStatus = PERMISSION_DENIED;
- goto Exit;
- }
-
if (io == AUDIO_IO_HANDLE_NONE) {
ALOGE("%s: APM must specify output when using AUDIO_SESSION_OUTPUT_STAGE", __func__);
lStatus = BAD_VALUE;
goto Exit;
}
+ PlaybackThread *thread = checkPlaybackThread_l(io);
+ if (thread == nullptr) {
+ ALOGE("%s: invalid output %d specified for AUDIO_SESSION_OUTPUT_STAGE", __func__, io);
+ lStatus = BAD_VALUE;
+ goto Exit;
+ }
+ if (!modifyDefaultAudioEffectsAllowed(adjAttributionSource)
+ && !isAudioServerUid(callingUid)) {
+ ALOGE("%s: effect on AUDIO_SESSION_OUTPUT_STAGE not granted for uid %d",
+ __func__, callingUid);
+ lStatus = PERMISSION_DENIED;
+ goto Exit;
+ }
} else if (sessionId == AUDIO_SESSION_DEVICE) {
if (!modifyDefaultAudioEffectsAllowed(adjAttributionSource)) {
ALOGE("%s: device effect permission denied for uid %d", __func__, callingUid);
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index 9baaf93..c199a76 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -31,6 +31,7 @@
#include <media/audiohal/EffectsFactoryHalInterface.h>
#include <media/stagefright/foundation/AHandler.h>
#include <media/stagefright/foundation/AMessage.h>
+#include <media/MediaMetricsItem.h>
#include <media/ShmemCompat.h>
#include <mediautils/ServiceUtilities.h>
#include <utils/Thread.h>
@@ -57,6 +58,19 @@
if (!_tmp.ok()) return aidl_utils::binderStatusFromStatusT(_tmp.error()); \
std::move(_tmp.value()); })
+audio_channel_mask_t getMaxChannelMask(std::vector<audio_channel_mask_t> masks) {
+ uint32_t maxCount = 0;
+ audio_channel_mask_t maxMask = AUDIO_CHANNEL_NONE;
+ for (auto mask : masks) {
+ const size_t count = audio_channel_count_from_out_mask(mask);
+ if (count > maxCount) {
+ maxMask = mask;
+ maxCount = count;
+ }
+ }
+ return maxMask;
+}
+
// ---------------------------------------------------------------------------
class Spatializer::EngineCallbackHandler : public AHandler {
@@ -286,6 +300,21 @@
ALOGW("%s: SPATIALIZER_PARAM_SUPPORTED_CHANNEL_MASKS reports empty", __func__);
return BAD_VALUE;
}
+
+ // Currently we expose only RELATIVE_WORLD.
+ // This is a limitation of the head tracking library based on a UX choice.
+ mHeadTrackingModes.push_back(SpatializerHeadTrackingMode::DISABLED);
+ if (mSupportsHeadTracking) {
+ mHeadTrackingModes.push_back(SpatializerHeadTrackingMode::RELATIVE_WORLD);
+ }
+ mediametrics::LogItem(mMetricsId)
+ .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE)
+ .set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)getMaxChannelMask(mChannelMasks))
+ .set(AMEDIAMETRICS_PROP_LEVELS, aidl_utils::enumsToString(mLevels))
+ .set(AMEDIAMETRICS_PROP_MODES, aidl_utils::enumsToString(mSpatializationModes))
+ .set(AMEDIAMETRICS_PROP_HEADTRACKINGMODES, aidl_utils::enumsToString(mHeadTrackingModes))
+ .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)status)
+ .record();
return NO_ERROR;
}
@@ -294,14 +323,7 @@
std::lock_guard lock(mLock);
audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
// For now use highest supported channel count
- uint32_t maxCount = 0;
- for ( auto mask : mChannelMasks) {
- const size_t count = audio_channel_count_from_out_mask(mask);
- if (count > maxCount) {
- config.channel_mask = mask;
- maxCount = count;
- }
- }
+ config.channel_mask = getMaxChannelMask(mChannelMasks);
return config;
}
@@ -338,7 +360,7 @@
if (levels == nullptr) {
return binderStatusFromStatusT(BAD_VALUE);
}
- levels->push_back(SpatializationLevel::NONE);
+ // SpatializationLevel::NONE is already required from the effect or we don't load it.
levels->insert(levels->end(), mLevels.begin(), mLevels.end());
return Status::ok();
}
@@ -399,11 +421,7 @@
if (modes == nullptr) {
return binderStatusFromStatusT(BAD_VALUE);
}
-
- modes->push_back(SpatializerHeadTrackingMode::DISABLED);
- if (mSupportsHeadTracking) {
- modes->push_back(SpatializerHeadTrackingMode::RELATIVE_WORLD);
- }
+ modes->insert(modes->end(), mHeadTrackingModes.begin(), mHeadTrackingModes.end());
return Status::ok();
}
@@ -501,9 +519,11 @@
return binderStatusFromStatusT(INVALID_OPERATION);
}
std::lock_guard lock(mLock);
- mHeadSensor = sensorHandle;
- checkPoseController_l();
- checkSensorsState_l();
+ if (mHeadSensor != sensorHandle) {
+ mHeadSensor = sensorHandle;
+ checkPoseController_l();
+ checkSensorsState_l();
+ }
return Status::ok();
}
@@ -513,8 +533,13 @@
return binderStatusFromStatusT(INVALID_OPERATION);
}
std::lock_guard lock(mLock);
- mScreenSensor = sensorHandle;
- checkSensorsState_l();
+ if (mScreenSensor != sensorHandle) {
+ mScreenSensor = sensorHandle;
+ // TODO: consider a new method setHeadAndScreenSensor()
+ // because we generally set both at the same time.
+ // This will avoid duplicated work and recentering.
+ checkSensorsState_l();
+ }
return Status::ok();
}
diff --git a/services/audiopolicy/service/Spatializer.h b/services/audiopolicy/service/Spatializer.h
index a36ba61..29f4b08 100644
--- a/services/audiopolicy/service/Spatializer.h
+++ b/services/audiopolicy/service/Spatializer.h
@@ -298,7 +298,10 @@
/** Effect engine descriptor */
const effect_descriptor_t mEngineDescriptor;
/** Callback interface to parent audio policy service */
- SpatializerPolicyCallback* mPolicyCallback;
+ SpatializerPolicyCallback* const mPolicyCallback;
+
+ /** Currently there is only one version of the spatializer running */
+ const std::string mMetricsId = AMEDIAMETRICS_KEY_PREFIX_AUDIO_SPATIALIZER "0";
/** Mutex protecting internal state */
mutable std::mutex mLock;
@@ -339,6 +342,7 @@
float mDisplayOrientation GUARDED_BY(mLock) = kDisplayOrientationInvalid;
std::vector<media::SpatializationLevel> mLevels;
+ std::vector<media::SpatializerHeadTrackingMode> mHeadTrackingModes;
std::vector<media::SpatializationMode> mSpatializationModes;
std::vector<audio_channel_mask_t> mChannelMasks;
bool mSupportsHeadTracking;
diff --git a/services/audiopolicy/service/SpatializerPoseController.cpp b/services/audiopolicy/service/SpatializerPoseController.cpp
index 0a9f4d9..304d44a 100644
--- a/services/audiopolicy/service/SpatializerPoseController.cpp
+++ b/services/audiopolicy/service/SpatializerPoseController.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "SpatializerPoseController"
//#define LOG_NDEBUG 0
#include <sensor/Sensor.h>
+#include <media/MediaMetricsItem.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
@@ -75,6 +76,10 @@
// How many ticks in a second.
constexpr auto kTicksPerSecond = Ticks::period::den;
+std::string getSensorMetricsId(int32_t sensorId) {
+ return std::string(AMEDIAMETRICS_KEY_PREFIX_AUDIO_SENSOR).append(std::to_string(sensorId));
+}
+
} // namespace
SpatializerPoseController::SpatializerPoseController(Listener* listener,
@@ -144,9 +149,16 @@
void SpatializerPoseController::setHeadSensor(int32_t sensor) {
std::lock_guard lock(mMutex);
+ if (sensor == mHeadSensor) return;
+ ALOGV("%s: new sensor:%d mHeadSensor:%d mScreenSensor:%d",
+ __func__, sensor, mHeadSensor, mScreenSensor);
+
// Stop current sensor, if valid and different from the other sensor.
if (mHeadSensor != INVALID_SENSOR && mHeadSensor != mScreenSensor) {
mPoseProvider->stopSensor(mHeadSensor);
+ mediametrics::LogItem(getSensorMetricsId(mHeadSensor))
+ .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_STOP)
+ .record();
}
if (sensor != INVALID_SENSOR) {
@@ -154,6 +166,15 @@
// Start new sensor.
mHeadSensor =
mPoseProvider->startSensor(sensor, mSensorPeriod) ? sensor : INVALID_SENSOR;
+ if (mHeadSensor != INVALID_SENSOR) {
+ auto sensor = mPoseProvider->getSensorByHandle(mHeadSensor);
+ std::string stringType = sensor ? sensor->getStringType().c_str() : "";
+ mediametrics::LogItem(getSensorMetricsId(mHeadSensor))
+ .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_START)
+ .set(AMEDIAMETRICS_PROP_MODE, AMEDIAMETRICS_PROP_MODE_VALUE_HEAD)
+ .set(AMEDIAMETRICS_PROP_TYPE, stringType)
+ .record();
+ }
} else {
// Sensor is already enabled.
mHeadSensor = mScreenSensor;
@@ -162,14 +183,21 @@
mHeadSensor = INVALID_SENSOR;
}
- mProcessor->recenter(true, false);
+ mProcessor->recenter(true /* recenterHead */, false /* recenterScreen */);
}
void SpatializerPoseController::setScreenSensor(int32_t sensor) {
std::lock_guard lock(mMutex);
+ if (sensor == mScreenSensor) return;
+ ALOGV("%s: new sensor:%d mHeadSensor:%d mScreenSensor:%d",
+ __func__, sensor, mHeadSensor, mScreenSensor);
+
// Stop current sensor, if valid and different from the other sensor.
if (mScreenSensor != INVALID_SENSOR && mScreenSensor != mHeadSensor) {
mPoseProvider->stopSensor(mScreenSensor);
+ mediametrics::LogItem(getSensorMetricsId(mScreenSensor))
+ .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_STOP)
+ .record();
}
if (sensor != INVALID_SENSOR) {
@@ -177,6 +205,13 @@
// Start new sensor.
mScreenSensor =
mPoseProvider->startSensor(sensor, mSensorPeriod) ? sensor : INVALID_SENSOR;
+ auto sensor = mPoseProvider->getSensorByHandle(mScreenSensor);
+ std::string stringType = sensor ? sensor->getStringType().c_str() : "";
+ mediametrics::LogItem(getSensorMetricsId(mScreenSensor))
+ .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_START)
+ .set(AMEDIAMETRICS_PROP_MODE, AMEDIAMETRICS_PROP_MODE_VALUE_SCREEN)
+ .set(AMEDIAMETRICS_PROP_TYPE, stringType)
+ .record();
} else {
// Sensor is already enabled.
mScreenSensor = mHeadSensor;
@@ -185,7 +220,7 @@
mScreenSensor = INVALID_SENSOR;
}
- mProcessor->recenter(false, true);
+ mProcessor->recenter(false /* recenterHead */, true /* recenterScreen */);
}
void SpatializerPoseController::setDesiredMode(HeadTrackingMode mode) {
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index e98975e..981c569 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -163,7 +163,6 @@
"android.hardware.camera.device@3.5",
"android.hardware.camera.device@3.6",
"android.hardware.camera.device@3.7",
- "android.hardware.camera.device@3.8",
"android.hardware.camera.device-V1-ndk",
"media_permission-aidl-cpp",
],
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index c4b5a6c..80410ab 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -887,29 +887,37 @@
BasicClient::BasicClient::sCameraService = nullptr;
}
-int CameraService::getDeviceVersion(const String8& cameraId, int* facing, int* orientation) {
+std::pair<int, IPCTransport> CameraService::getDeviceVersion(const String8& cameraId, int* facing,
+ int* orientation) {
ATRACE_CALL();
int deviceVersion = 0;
status_t res;
hardware::hidl_version maxVersion{0,0};
+ IPCTransport transport = IPCTransport::INVALID;
res = mCameraProviderManager->getHighestSupportedVersion(cameraId.string(),
- &maxVersion);
- if (res != OK) return -1;
+ &maxVersion, &transport);
+ if (res != OK || transport == IPCTransport::INVALID) {
+ ALOGE("%s: Unable to get highest supported version for camera id %s", __FUNCTION__,
+ cameraId.string());
+ return std::make_pair(-1, IPCTransport::INVALID) ;
+ }
deviceVersion = HARDWARE_DEVICE_API_VERSION(maxVersion.get_major(), maxVersion.get_minor());
hardware::CameraInfo info;
if (facing) {
res = mCameraProviderManager->getCameraInfo(cameraId.string(), &info);
- if (res != OK) return -1;
+ if (res != OK) {
+ return std::make_pair(-1, IPCTransport::INVALID);
+ }
*facing = info.facing;
if (orientation) {
*orientation = info.orientation;
}
}
- return deviceVersion;
+ return std::make_pair(deviceVersion, transport);
}
Status CameraService::filterGetInfoErrorCode(status_t err) {
@@ -933,45 +941,47 @@
const sp<IInterface>& cameraCb, const String16& packageName, bool systemNativeClient,
const std::optional<String16>& featureId, const String8& cameraId,
int api1CameraId, int facing, int sensorOrientation, int clientPid, uid_t clientUid,
- int servicePid, int deviceVersion, apiLevel effectiveApiLevel, bool overrideForPerfClass,
- /*out*/sp<BasicClient>* client) {
-
- // Create CameraClient based on device version reported by the HAL.
- switch(deviceVersion) {
- case CAMERA_DEVICE_API_VERSION_1_0:
- ALOGE("Camera using old HAL version: %d", deviceVersion);
- return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
- "Camera device \"%s\" HAL version %d no longer supported",
- cameraId.string(), deviceVersion);
- break;
- case CAMERA_DEVICE_API_VERSION_3_0:
- case CAMERA_DEVICE_API_VERSION_3_1:
- case CAMERA_DEVICE_API_VERSION_3_2:
- case CAMERA_DEVICE_API_VERSION_3_3:
- case CAMERA_DEVICE_API_VERSION_3_4:
- case CAMERA_DEVICE_API_VERSION_3_5:
- case CAMERA_DEVICE_API_VERSION_3_6:
- case CAMERA_DEVICE_API_VERSION_3_7:
- case CAMERA_DEVICE_API_VERSION_3_8:
- if (effectiveApiLevel == API_1) { // Camera1 API route
- sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
- *client = new Camera2Client(cameraService, tmp, packageName, featureId,
- cameraId, api1CameraId, facing, sensorOrientation, clientPid, clientUid,
- servicePid, overrideForPerfClass);
- } else { // Camera2 API route
- sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
- static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
- *client = new CameraDeviceClient(cameraService, tmp, packageName,
- systemNativeClient, featureId, cameraId, facing, sensorOrientation,
- clientPid, clientUid, servicePid, overrideForPerfClass);
- }
- break;
- default:
- // Should not be reachable
- ALOGE("Unknown camera device HAL version: %d", deviceVersion);
- return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
- "Camera device \"%s\" has unknown HAL version %d",
- cameraId.string(), deviceVersion);
+ int servicePid, std::pair<int, IPCTransport> deviceVersionAndTransport,
+ apiLevel effectiveApiLevel, bool overrideForPerfClass, /*out*/sp<BasicClient>* client) {
+ // For HIDL devices
+ if (deviceVersionAndTransport.second == IPCTransport::HIDL) {
+ // Create CameraClient based on device version reported by the HAL.
+ int deviceVersion = deviceVersionAndTransport.first;
+ switch(deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_1_0:
+ ALOGE("Camera using old HAL version: %d", deviceVersion);
+ return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
+ "Camera device \"%s\" HAL version %d no longer supported",
+ cameraId.string(), deviceVersion);
+ break;
+ case CAMERA_DEVICE_API_VERSION_3_0:
+ case CAMERA_DEVICE_API_VERSION_3_1:
+ case CAMERA_DEVICE_API_VERSION_3_2:
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_4:
+ case CAMERA_DEVICE_API_VERSION_3_5:
+ case CAMERA_DEVICE_API_VERSION_3_6:
+ case CAMERA_DEVICE_API_VERSION_3_7:
+ break;
+ default:
+ // Should not be reachable
+ ALOGE("Unknown camera device HAL version: %d", deviceVersion);
+ return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
+ "Camera device \"%s\" has unknown HAL version %d",
+ cameraId.string(), deviceVersion);
+ }
+ }
+ if (effectiveApiLevel == API_1) { // Camera1 API route
+ sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
+ *client = new Camera2Client(cameraService, tmp, packageName, featureId,
+ cameraId, api1CameraId, facing, sensorOrientation, clientPid, clientUid,
+ servicePid, overrideForPerfClass);
+ } else { // Camera2 API route
+ sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
+ static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
+ *client = new CameraDeviceClient(cameraService, tmp, packageName,
+ systemNativeClient, featureId, cameraId, facing, sensorOrientation,
+ clientPid, clientUid, servicePid, overrideForPerfClass);
}
return Status::ok();
}
@@ -1822,7 +1832,8 @@
// give flashlight a chance to close devices if necessary.
mFlashlight->prepareDeviceOpen(cameraId);
- int deviceVersion = getDeviceVersion(cameraId, /*out*/&facing, /*out*/&orientation);
+ auto deviceVersionAndTransport =
+ getDeviceVersion(cameraId, /*out*/&facing, /*out*/&orientation);
if (facing == -1) {
ALOGE("%s: Unable to get camera device \"%s\" facing", __FUNCTION__, cameraId.string());
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
@@ -1835,7 +1846,7 @@
if(!(ret = makeClient(this, cameraCb, clientPackageName, systemNativeClient,
clientFeatureId, cameraId, api1CameraId, facing, orientation,
clientPid, clientUid, getpid(),
- deviceVersion, effectiveApiLevel, overrideForPerfClass,
+ deviceVersionAndTransport, effectiveApiLevel, overrideForPerfClass,
/*out*/&tmp)).isOk()) {
return ret;
}
@@ -2708,45 +2719,48 @@
return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
}
- int deviceVersion = getDeviceVersion(id);
- switch (deviceVersion) {
- case CAMERA_DEVICE_API_VERSION_1_0:
- case CAMERA_DEVICE_API_VERSION_3_0:
- case CAMERA_DEVICE_API_VERSION_3_1:
- if (apiVersion == API_VERSION_2) {
- ALOGV("%s: Camera id %s uses HAL version %d <3.2, doesn't support api2 without shim",
- __FUNCTION__, id.string(), deviceVersion);
- *isSupported = false;
- } else { // if (apiVersion == API_VERSION_1) {
- ALOGV("%s: Camera id %s uses older HAL before 3.2, but api1 is always supported",
+ auto deviceVersionAndTransport = getDeviceVersion(id);
+ if (deviceVersionAndTransport.first == -1) {
+ String8 msg = String8::format("Unknown camera ID %s", id.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
+ if (deviceVersionAndTransport.second == IPCTransport::HIDL) {
+ int deviceVersion = deviceVersionAndTransport.first;
+ switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_1_0:
+ case CAMERA_DEVICE_API_VERSION_3_0:
+ case CAMERA_DEVICE_API_VERSION_3_1:
+ if (apiVersion == API_VERSION_2) {
+ ALOGV("%s: Camera id %s uses HAL version %d <3.2, doesn't support api2 without "
+ "shim", __FUNCTION__, id.string(), deviceVersion);
+ *isSupported = false;
+ } else { // if (apiVersion == API_VERSION_1) {
+ ALOGV("%s: Camera id %s uses older HAL before 3.2, but api1 is always "
+ "supported", __FUNCTION__, id.string());
+ *isSupported = true;
+ }
+ break;
+ case CAMERA_DEVICE_API_VERSION_3_2:
+ case CAMERA_DEVICE_API_VERSION_3_3:
+ case CAMERA_DEVICE_API_VERSION_3_4:
+ case CAMERA_DEVICE_API_VERSION_3_5:
+ case CAMERA_DEVICE_API_VERSION_3_6:
+ case CAMERA_DEVICE_API_VERSION_3_7:
+ ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly",
__FUNCTION__, id.string());
*isSupported = true;
+ break;
+ default: {
+ String8 msg = String8::format("Unknown device version %x for device %s",
+ deviceVersion, id.string());
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.string());
}
- break;
- case CAMERA_DEVICE_API_VERSION_3_2:
- case CAMERA_DEVICE_API_VERSION_3_3:
- case CAMERA_DEVICE_API_VERSION_3_4:
- case CAMERA_DEVICE_API_VERSION_3_5:
- case CAMERA_DEVICE_API_VERSION_3_6:
- case CAMERA_DEVICE_API_VERSION_3_7:
- case CAMERA_DEVICE_API_VERSION_3_8:
- ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly",
- __FUNCTION__, id.string());
- *isSupported = true;
- break;
- case -1: {
- String8 msg = String8::format("Unknown camera ID %s", id.string());
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
}
- default: {
- String8 msg = String8::format("Unknown device version %x for device %s",
- deviceVersion, id.string());
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.string());
- }
+ } else {
+ *isSupported = true;
}
-
return Status::ok();
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 89a537d..d96ea00 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -47,6 +47,7 @@
#include "media/RingBuffer.h"
#include "utils/AutoConditionLock.h"
#include "utils/ClientManager.h"
+#include "utils/IPCTransport.h"
#include <set>
#include <string>
@@ -242,7 +243,7 @@
/////////////////////////////////////////////////////////////////////
// CameraDeviceFactory functionality
- int getDeviceVersion(const String8& cameraId, int* facing = nullptr,
+ std::pair<int, IPCTransport> getDeviceVersion(const String8& cameraId, int* facing = nullptr,
int* orientation = nullptr);
/////////////////////////////////////////////////////////////////////
@@ -1240,8 +1241,9 @@
const sp<IInterface>& cameraCb, const String16& packageName,
bool systemNativeClient, const std::optional<String16>& featureId,
const String8& cameraId, int api1CameraId, int facing, int sensorOrientation,
- int clientPid, uid_t clientUid, int servicePid, int deviceVersion,
- apiLevel effectiveApiLevel, bool overrideForPerfClass, /*out*/sp<BasicClient>* client);
+ int clientPid, uid_t clientUid, int servicePid,
+ std::pair<int, IPCTransport> deviceVersionAndIPCTransport, apiLevel effectiveApiLevel,
+ bool overrideForPerfClass, /*out*/sp<BasicClient>* client);
status_t checkCameraAccess(const String16& opPackageName);
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index a6a89af..68dc7f8 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -112,7 +112,7 @@
{
SharedParameters::Lock l(mParameters);
- res = l.mParameters.initialize(mDevice.get(), mDeviceVersion);
+ res = l.mParameters.initialize(mDevice.get());
if (res != OK) {
ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
__FUNCTION__, mCameraId, strerror(-res), res);
@@ -1689,12 +1689,15 @@
__FUNCTION__, mCameraId, degrees);
return BAD_VALUE;
}
- SharedParameters::Lock l(mParameters);
- if (mRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_NONE) {
- ALOGI("%s: Rotate and crop set to: %d, skipping display orientation!", __FUNCTION__,
- mRotateAndCropMode);
- transform = mRotateAndCropPreviewTransform;
+ {
+ Mutex::Autolock icl(mRotateAndCropLock);
+ if (mRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_NONE) {
+ ALOGI("%s: Rotate and crop set to: %d, skipping display orientation!", __FUNCTION__,
+ mRotateAndCropMode);
+ transform = mRotateAndCropPreviewTransform;
+ }
}
+ SharedParameters::Lock l(mParameters);
if (transform != l.mParameters.previewTransform &&
getPreviewStreamId() != NO_STREAM) {
mDevice->setStreamTransform(getPreviewStreamId(), transform);
@@ -2317,7 +2320,7 @@
if (rotateAndCrop > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE;
{
- Mutex::Autolock icl(mBinderSerializationLock);
+ Mutex::Autolock icl(mRotateAndCropLock);
if (mRotateAndCropIsSupported) {
mRotateAndCropMode = rotateAndCrop;
} else {
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index 58e0e19..c8dfc46 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -240,6 +240,8 @@
bool isZslEnabledInStillTemplate();
// The current rotate & crop mode passed by camera service
uint8_t mRotateAndCropMode;
+ // Synchronize access to 'mRotateAndCropMode'
+ mutable Mutex mRotateAndCropLock;
// Contains the preview stream transformation that would normally be applied
// when the display rotation is 0
int mRotateAndCropPreviewTransform;
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp
index 9a7ada2..123cd75 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.cpp
+++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp
@@ -50,7 +50,7 @@
Parameters::~Parameters() {
}
-status_t Parameters::initialize(CameraDeviceBase *device, int deviceVersion) {
+status_t Parameters::initialize(CameraDeviceBase *device) {
status_t res;
if (device == nullptr) {
ALOGE("%s: device is null!", __FUNCTION__);
@@ -63,7 +63,6 @@
return BAD_VALUE;
}
Parameters::info = &info;
- mDeviceVersion = deviceVersion;
res = buildFastInfo(device);
if (res != OK) return res;
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h
index 263025e..cbe62a7 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.h
+++ b/services/camera/libcameraservice/api1/client2/Parameters.h
@@ -269,7 +269,7 @@
~Parameters();
// Sets up default parameters
- status_t initialize(CameraDeviceBase *device, int deviceVersion);
+ status_t initialize(CameraDeviceBase *device);
// Build fast-access device static info from static info
status_t buildFastInfo(CameraDeviceBase *device);
@@ -459,7 +459,6 @@
// Helper function to get the suggested video sizes
Vector<Size> getPreferredVideoSizes() const;
- int mDeviceVersion;
uint8_t mDefaultSceneMode;
};
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 6c6ddbd..5e91501 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -168,9 +168,8 @@
__FUNCTION__, mCameraIdStr.c_str(), entry.data.i64[i]);
}
}
- mDynamicProfileMap.emplace(
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- standardBitmap);
+ mDynamicProfileMap[ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD] =
+ standardBitmap;
} else {
ALOGE("%s: Device %s supports 10-bit output but doesn't include a dynamic range"
" profile map!", __FUNCTION__, mCameraIdStr.c_str());
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 49a9760..dc5002b 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -64,7 +64,6 @@
clientFeatureId, cameraId, api1CameraId, cameraFacing, sensorOrientation, clientPid,
clientUid, servicePid),
mSharedCameraCallbacks(remoteCallback),
- mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
mDeviceActive(false), mApi1CameraId(api1CameraId)
{
ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
@@ -423,11 +422,6 @@
}
template <typename TClientBase>
-int Camera2ClientBase<TClientBase>::getCameraDeviceVersion() const {
- return mDeviceVersion;
-}
-
-template <typename TClientBase>
const sp<CameraDeviceBase>& Camera2ClientBase<TClientBase>::getCameraDevice() {
return mDevice;
}
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index ec33f46..b0d1c3f 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -152,8 +152,6 @@
/** CameraDeviceBase instance wrapping HAL3+ entry */
- const int mDeviceVersion;
-
// Note: This was previously set to const to avoid mDevice being updated -
// b/112639939 (update of sp<> is racy) during dumpDevice (which is important to be lock free
// for debugging purpose). The const has been removed since CameraDeviceBase
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 6edf1ac..abaea66 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -21,7 +21,6 @@
#include "CameraProviderManager.h"
#include <aidl/android/hardware/camera/device/ICameraDevice.h>
-#include <android/hardware/camera/device/3.8/ICameraDevice.h>
#include <algorithm>
#include <chrono>
@@ -61,11 +60,6 @@
const float CameraProviderManager::kDepthARTolerance = .1f;
-// AIDL Devices start with major version 1, offset added to bring them up to HIDL.
-const uint16_t kAidlDeviceMajorOffset = 2;
-// AIDL Devices start with minor version 1, offset added to bring them up to HIDL.
-const uint16_t kAidlDeviceMinorOffset = 7;
-
CameraProviderManager::HidlServiceInteractionProxyImpl
CameraProviderManager::sHidlServiceInteractionProxy{};
@@ -280,15 +274,13 @@
return deviceIds;
}
-bool CameraProviderManager::isValidDevice(const std::string &id, uint16_t majorVersion) const {
- std::lock_guard<std::mutex> lock(mInterfaceMutex);
- return isValidDeviceLocked(id, majorVersion);
-}
-
-bool CameraProviderManager::isValidDeviceLocked(const std::string &id, uint16_t majorVersion) const {
+bool CameraProviderManager::isValidDeviceLocked(const std::string &id, uint16_t majorVersion,
+ IPCTransport transport) const {
for (auto& provider : mProviders) {
+ IPCTransport providerTransport = provider->getIPCTransport();
for (auto& deviceInfo : provider->mDevices) {
- if (deviceInfo->mId == id && deviceInfo->mVersion.get_major() == majorVersion) {
+ if (deviceInfo->mId == id && deviceInfo->mVersion.get_major() == majorVersion &&
+ transport == providerTransport) {
return true;
}
}
@@ -369,29 +361,32 @@
return getCameraCharacteristicsLocked(id, overrideForPerfClass, characteristics);
}
-// Till hidl is removed from the android source tree, we use this for aidl as
-// well. We artificially give aidl camera device version 1 a major version 3 and minor
-// version 8.
status_t CameraProviderManager::getHighestSupportedVersion(const std::string &id,
- hardware::hidl_version *v) {
+ hardware::hidl_version *v, IPCTransport *transport) {
+ if (v == nullptr || transport == nullptr) {
+ return BAD_VALUE;
+ }
std::lock_guard<std::mutex> lock(mInterfaceMutex);
hardware::hidl_version maxVersion{0,0};
bool found = false;
+ IPCTransport providerTransport = IPCTransport::INVALID;
for (auto& provider : mProviders) {
for (auto& deviceInfo : provider->mDevices) {
if (deviceInfo->mId == id) {
if (deviceInfo->mVersion > maxVersion) {
maxVersion = deviceInfo->mVersion;
+ providerTransport = provider->getIPCTransport();
found = true;
}
}
}
}
- if (!found) {
+ if (!found || providerTransport == IPCTransport::INVALID) {
return NAME_NOT_FOUND;
}
*v = maxVersion;
+ *transport = providerTransport;
return OK;
}
@@ -442,9 +437,10 @@
bool CameraProviderManager::supportSetTorchMode(const std::string &id) const {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
for (auto& provider : mProviders) {
- auto deviceInfo = findDeviceInfoLocked(id);
- if (deviceInfo != nullptr) {
- return provider->mSetTorchModeSupported;
+ for (auto& deviceInfo : provider->mDevices) {
+ if (deviceInfo->mId == id) {
+ return provider->mSetTorchModeSupported;
+ }
}
}
return false;
@@ -613,8 +609,7 @@
std::lock_guard<std::mutex> lock(mInterfaceMutex);
- auto deviceInfo = findDeviceInfoLocked(id,
- /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
+ auto deviceInfo = findDeviceInfoLocked(id);
if (deviceInfo == nullptr) return NAME_NOT_FOUND;
auto *aidlDeviceInfo3 = static_cast<AidlProviderInfo::AidlDeviceInfo3*>(deviceInfo);
@@ -695,8 +690,7 @@
std::lock_guard<std::mutex> lock(mInterfaceMutex);
- auto deviceInfo = findDeviceInfoLocked(id,
- /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
+ auto deviceInfo = findDeviceInfoLocked(id);
if (deviceInfo == nullptr) return NAME_NOT_FOUND;
auto *hidlDeviceInfo3 = static_cast<HidlProviderInfo::HidlDeviceInfo3*>(deviceInfo);
@@ -897,9 +891,16 @@
}
CameraProviderManager::ProviderInfo::DeviceInfo* CameraProviderManager::findDeviceInfoLocked(
- const std::string& id,
- hardware::hidl_version minVersion, hardware::hidl_version maxVersion) const {
+ const std::string& id) const {
for (auto& provider : mProviders) {
+ using hardware::hidl_version;
+ IPCTransport transport = provider->getIPCTransport();
+ // AIDL min version starts at major: 1 minor: 1
+ hidl_version minVersion =
+ (transport == IPCTransport::HIDL) ? hidl_version{3, 2} : hidl_version{1, 1} ;
+ hidl_version maxVersion =
+ (transport == IPCTransport::HIDL) ? hidl_version{3, 7} : hidl_version{1000, 0};
+
for (auto& deviceInfo : provider->mDevices) {
if (deviceInfo->mId == id &&
minVersion <= deviceInfo->mVersion && maxVersion >= deviceInfo->mVersion) {
@@ -911,16 +912,13 @@
}
metadata_vendor_id_t CameraProviderManager::getProviderTagIdLocked(
- const std::string& id, hardware::hidl_version minVersion,
- hardware::hidl_version maxVersion) const {
+ const std::string& id) const {
metadata_vendor_id_t ret = CAMERA_METADATA_INVALID_VENDOR_ID;
std::lock_guard<std::mutex> lock(mInterfaceMutex);
for (auto& provider : mProviders) {
for (auto& deviceInfo : provider->mDevices) {
- if (deviceInfo->mId == id &&
- minVersion <= deviceInfo->mVersion &&
- maxVersion >= deviceInfo->mVersion) {
+ if (deviceInfo->mId == id) {
return provider->mProviderTagid;
}
}
@@ -1274,9 +1272,14 @@
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::fixupMonochromeTags() {
status_t res = OK;
auto& c = mCameraCharacteristics;
-
+ sp<ProviderInfo> parentProvider = mParentProvider.promote();
+ if (parentProvider == nullptr) {
+ return DEAD_OBJECT;
+ }
+ IPCTransport ipcTransport = parentProvider->getIPCTransport();
// Override static metadata for MONOCHROME camera with older device version
- if (mVersion.get_major() == 3 && mVersion.get_minor() < 5) {
+ if (ipcTransport == IPCTransport::HIDL &&
+ (mVersion.get_major() == 3 && mVersion.get_minor() < 5)) {
camera_metadata_entry cap = c.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
for (size_t i = 0; i < cap.count; i++) {
if (cap.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
@@ -1636,6 +1639,7 @@
}
for (auto& provider : mProviders) {
+ IPCTransport transport = provider->getIPCTransport();
for (auto& deviceInfo : provider->mDevices) {
std::vector<std::string> physicalIds;
if (deviceInfo->mIsLogicalCamera) {
@@ -1643,7 +1647,8 @@
cameraId) != deviceInfo->mPhysicalIds.end()) {
int deviceVersion = HARDWARE_DEVICE_API_VERSION(
deviceInfo->mVersion.get_major(), deviceInfo->mVersion.get_minor());
- if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_5) {
+ if (transport == IPCTransport::HIDL &&
+ deviceVersion < CAMERA_DEVICE_API_VERSION_3_5) {
ALOGE("%s: Wrong deviceVersion %x for hiddenPhysicalCameraId %s",
__FUNCTION__, deviceVersion, cameraId.c_str());
return falseRet;
@@ -1861,39 +1866,49 @@
uint16_t major, minor;
std::string type, id;
+ IPCTransport transport = getIPCTransport();
status_t res = parseDeviceName(name, &major, &minor, &type, &id);
if (res != OK) {
return res;
}
- if (getIPCTransport() == IPCTransport::AIDL) {
- // Till HIDL support exists, map AIDL versions to HIDL.
- // TODO:b/196432585 Explore if we can get rid of this.
- major += kAidlDeviceMajorOffset;
- minor += kAidlDeviceMinorOffset;
- }
if (type != mType) {
ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
type.c_str(), mType.c_str());
return BAD_VALUE;
}
- if (mManager->isValidDeviceLocked(id, major)) {
+ if (mManager->isValidDeviceLocked(id, major, transport)) {
ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
name.c_str(), id.c_str(), major);
return BAD_VALUE;
}
std::unique_ptr<DeviceInfo> deviceInfo;
- switch (major) {
- case 3:
- deviceInfo = initializeDeviceInfo(name, mProviderTagid, id, minor);
+ switch (transport) {
+ case IPCTransport::HIDL:
+ switch (major) {
+ case 3:
+ break;
+ default:
+ ALOGE("%s: Device %s: Unsupported HIDL device HAL major version %d:",
+ __FUNCTION__, name.c_str(), major);
+ return BAD_VALUE;
+ }
+ break;
+ case IPCTransport::AIDL:
+ if (major != 1) {
+ ALOGE("%s: Device %s: Unsupported AIDL device HAL major version %d:", __FUNCTION__,
+ name.c_str(), major);
+ return BAD_VALUE;
+ }
break;
default:
- ALOGE("%s: Device %s: Unsupported IDL device HAL major version %d:", __FUNCTION__,
- name.c_str(), major);
+ ALOGE("%s Invalid transport %d", __FUNCTION__, transport);
return BAD_VALUE;
}
+
+ deviceInfo = initializeDeviceInfo(name, mProviderTagid, id, minor);
if (deviceInfo == nullptr) return BAD_VALUE;
deviceInfo->notifyDeviceStateChange(getDeviceState());
deviceInfo->mStatus = initialStatus;
@@ -2675,7 +2690,7 @@
status_t CameraProviderManager::getCameraCharacteristicsLocked(const std::string &id,
bool overrideForPerfClass, CameraMetadata* characteristics) const {
- auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3, 0}, /*maxVersion*/ {5, 0});
+ auto deviceInfo = findDeviceInfoLocked(id);
if (deviceInfo != nullptr) {
return deviceInfo->getCameraCharacteristics(overrideForPerfClass, characteristics);
}
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 3a366e5..a66598d 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -41,7 +41,6 @@
#include <android/hardware/camera/provider/2.6/ICameraProvider.h>
#include <android/hardware/camera/provider/2.7/ICameraProvider.h>
#include <android/hardware/camera/device/3.7/types.h>
-#include <android/hardware/camera/device/3.8/types.h>
#include <android/hidl/manager/1.0/IServiceNotification.h>
#include <binder/IServiceManager.h>
#include <camera/VendorTagDescriptor.h>
@@ -96,7 +95,6 @@
#define CAMERA_DEVICE_API_VERSION_3_5 HARDWARE_DEVICE_API_VERSION(3, 5)
#define CAMERA_DEVICE_API_VERSION_3_6 HARDWARE_DEVICE_API_VERSION(3, 6)
#define CAMERA_DEVICE_API_VERSION_3_7 HARDWARE_DEVICE_API_VERSION(3, 7)
-#define CAMERA_DEVICE_API_VERSION_3_8 HARDWARE_DEVICE_API_VERSION(3, 8)
/**
* The vendor tag descriptor class that takes HIDL/AIDL vendor tag information as
@@ -233,11 +231,6 @@
std::vector<std::string> getAPI1CompatibleCameraDeviceIds() const;
/**
- * Return true if a device with a given ID and major version exists
- */
- bool isValidDevice(const std::string &id, uint16_t majorVersion) const;
-
- /**
* Return true if a device with a given ID has a flash unit. Returns false
* for devices that are unknown.
*/
@@ -286,7 +279,7 @@
* Return the highest supported device interface version for this ID
*/
status_t getHighestSupportedVersion(const std::string &id,
- hardware::hidl_version *v);
+ hardware::hidl_version *v, IPCTransport *transport);
/**
* Check if a given camera device support setTorchMode API.
@@ -392,9 +385,7 @@
/*
* Return provider type for a specific device.
*/
- metadata_vendor_id_t getProviderTagIdLocked(const std::string& id,
- hardware::hidl_version minVersion = hardware::hidl_version{0,0},
- hardware::hidl_version maxVersion = hardware::hidl_version{1000,0}) const;
+ metadata_vendor_id_t getProviderTagIdLocked(const std::string& id) const;
/*
* Check if a camera is a logical camera. And if yes, return
@@ -796,12 +787,8 @@
// Utility to find a DeviceInfo by ID; pointer is only valid while mInterfaceMutex is held
// and the calling code doesn't mutate the list of providers or their lists of devices.
- // Finds the first device of the given ID that falls within the requested version range
- // minVersion <= deviceVersion < maxVersion
// No guarantees on the order of traversal
- ProviderInfo::DeviceInfo* findDeviceInfoLocked(const std::string& id,
- hardware::hidl_version minVersion = hardware::hidl_version{0,0},
- hardware::hidl_version maxVersion = hardware::hidl_version{1000,0}) const;
+ ProviderInfo::DeviceInfo* findDeviceInfoLocked(const std::string& id) const;
// Map external providers to USB devices in order to handle USB hotplug
// events for lazy HALs
@@ -828,7 +815,8 @@
status_t removeProvider(const std::string& provider);
sp<StatusListener> getStatusListener() const;
- bool isValidDeviceLocked(const std::string &id, uint16_t majorVersion) const;
+ bool isValidDeviceLocked(const std::string &id, uint16_t majorVersion,
+ IPCTransport transport) const;
size_t mProviderInstanceId = 0;
std::vector<sp<ProviderInfo>> mProviders;
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index b3cce1c..bded9aa 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -27,7 +27,6 @@
#include <utils/Trace.h>
#include <android/hardware/camera/device/3.7/ICameraDevice.h>
-#include <android/hardware/camera/device/3.8/ICameraDevice.h>
namespace {
const bool kEnableLazyHal(property_get_bool("ro.camera.enableLazyHal", false));
@@ -766,74 +765,14 @@
}
status_t HidlProviderInfo::HidlDeviceInfo3::turnOnTorchWithStrengthLevel(
- int32_t torchStrength) {
- const sp<hardware::camera::device::V3_2::ICameraDevice> interface = startDeviceInterface();
- if (interface == nullptr) {
- return DEAD_OBJECT;
- }
- sp<hardware::camera::device::V3_8::ICameraDevice> interface_3_8 = nullptr;
- auto castResult_3_8 = device::V3_8::ICameraDevice::castFrom(interface);
- if (castResult_3_8.isOk()) {
- interface_3_8 = castResult_3_8;
- }
-
- if (interface_3_8 == nullptr) {
- return INVALID_OPERATION;
- }
-
- Status s = interface_3_8->turnOnTorchWithStrengthLevel(torchStrength);
- if (s == Status::OK) {
- mTorchStrengthLevel = torchStrength;
- }
- return mapToStatusT(s);
+ int32_t /*torchStrengthLevel*/) {
+ ALOGE("%s HIDL does not support turning on torch with variable strength", __FUNCTION__);
+ return INVALID_OPERATION;
}
-status_t HidlProviderInfo::HidlDeviceInfo3::getTorchStrengthLevel(int32_t *torchStrength) {
- if (torchStrength == nullptr) {
- return BAD_VALUE;
- }
- const sp<hardware::camera::device::V3_2::ICameraDevice> interface = startDeviceInterface();
- if (interface == nullptr) {
- return DEAD_OBJECT;
- }
- auto castResult_3_8 = device::V3_8::ICameraDevice::castFrom(interface);
- sp<hardware::camera::device::V3_8::ICameraDevice> interface_3_8 = nullptr;
- if (castResult_3_8.isOk()) {
- interface_3_8 = castResult_3_8;
- }
-
- if (interface_3_8 == nullptr) {
- return INVALID_OPERATION;
- }
-
- Status callStatus;
- status_t res;
- hardware::Return<void> ret = interface_3_8->getTorchStrengthLevel([&callStatus, &torchStrength]
- (Status status, const int32_t& torchStrengthLevel) {
- callStatus = status;
- if (status == Status::OK) {
- *torchStrength = torchStrengthLevel;
- } });
-
- if (ret.isOk()) {
- switch (callStatus) {
- case Status::OK:
- // Expected case, do nothing.
- res = OK;
- break;
- case Status::METHOD_NOT_SUPPORTED:
- res = INVALID_OPERATION;
- break;
- default:
- ALOGE("%s: Get torch strength level failed: %d", __FUNCTION__, callStatus);
- res = UNKNOWN_ERROR;
- }
- } else {
- ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, ret.description().c_str());
- res = UNKNOWN_ERROR;
- }
-
- return res;
+status_t HidlProviderInfo::HidlDeviceInfo3::getTorchStrengthLevel(int32_t * /*torchStrength*/) {
+ ALOGE("%s HIDL does not support variable torch strength level", __FUNCTION__);
+ return INVALID_OPERATION;
}
sp<hardware::camera::device::V3_2::ICameraDevice>
@@ -888,11 +827,11 @@
const SessionConfiguration &configuration, bool overrideForPerfClass,
metadataGetter getMetadata, bool *status) {
- hardware::camera::device::V3_8::StreamConfiguration streamConfiguration;
+ hardware::camera::device::V3_7::StreamConfiguration configuration_3_7;
bool earlyExit = false;
auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
String8(mId.c_str()), mCameraCharacteristics, getMetadata, mPhysicalIds,
- streamConfiguration, overrideForPerfClass, &earlyExit);
+ configuration_3_7, overrideForPerfClass, &earlyExit);
if (!bRes.isOk()) {
return UNKNOWN_ERROR;
@@ -914,8 +853,6 @@
sp<hardware::camera::device::V3_5::ICameraDevice> interface_3_5 = castResult_3_5;
auto castResult_3_7 = device::V3_7::ICameraDevice::castFrom(interface);
sp<hardware::camera::device::V3_7::ICameraDevice> interface_3_7 = castResult_3_7;
- auto castResult_3_8 = device::V3_8::ICameraDevice::castFrom(interface);
- sp<hardware::camera::device::V3_8::ICameraDevice> interface_3_8 = castResult_3_8;
status_t res;
Status callStatus;
@@ -925,27 +862,11 @@
callStatus = s;
*status = combStatus;
};
- if (interface_3_8 != nullptr) {
- ret = interface_3_8->isStreamCombinationSupported_3_8(streamConfiguration, halCb);
- } else if (interface_3_7 != nullptr) {
- hardware::camera::device::V3_7::StreamConfiguration configuration_3_7;
- bool success = SessionConfigurationUtils::convertHALStreamCombinationFromV38ToV37(
- configuration_3_7, streamConfiguration);
- if (!success) {
- *status = false;
- return OK;
- }
+ if (interface_3_7 != nullptr) {
ret = interface_3_7->isStreamCombinationSupported_3_7(configuration_3_7, halCb);
} else if (interface_3_5 != nullptr) {
- hardware::camera::device::V3_7::StreamConfiguration configuration_3_7;
- bool success = SessionConfigurationUtils::convertHALStreamCombinationFromV38ToV37(
- configuration_3_7, streamConfiguration);
- if (!success) {
- *status = false;
- return OK;
- }
hardware::camera::device::V3_4::StreamConfiguration configuration_3_4;
- success = SessionConfigurationUtils::convertHALStreamCombinationFromV37ToV34(
+ bool success = SessionConfigurationUtils::convertHALStreamCombinationFromV37ToV34(
configuration_3_4, configuration_3_7);
if (!success) {
*status = false;
@@ -988,7 +909,7 @@
status_t res = OK;
for (auto &cameraIdAndSessionConfig : cameraIdsAndSessionConfigs) {
const std::string& cameraId = cameraIdAndSessionConfig.mCameraId;
- hardware::camera::device::V3_8::StreamConfiguration streamConfiguration;
+ hardware::camera::device::V3_7::StreamConfiguration streamConfiguration;
CameraMetadata deviceInfo;
bool overrideForPerfClass =
SessionConfigurationUtils::targetPerfClassPrimaryCamera(
@@ -1022,8 +943,7 @@
}
CameraIdAndStreamCombination halCameraIdAndStream;
halCameraIdAndStream.cameraId = cameraId;
- SessionConfigurationUtils::convertHALStreamCombinationFromV38ToV37(
- halCameraIdAndStream.streamConfiguration, streamConfiguration);
+ halCameraIdAndStream.streamConfiguration = streamConfiguration;
halCameraIdsAndStreamsV.push_back(halCameraIdAndStream);
}
*halCameraIdsAndStreamCombinations = halCameraIdsAndStreamsV;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index b133263..dec439f 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -4265,8 +4265,8 @@
if (parent != nullptr) {
parent->mRequestBufferSM.onRequestThreadPaused();
}
- mRequestClearing = false;
}
+ mRequestClearing = false;
// Stop waiting for now and let thread management happen
return NULL;
}
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.h b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
index dd01408..d6107c2 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
@@ -26,8 +26,6 @@
#include <common/CameraDeviceBase.h>
-#include <android/hardware/camera/device/3.8/ICameraDeviceCallback.h>
-
#include "device3/BufferUtils.h"
#include "device3/DistortionMapper.h"
#include "device3/ZoomRatioMapper.h"
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp
index 3809f37..02eebd2 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3OutputUtils.cpp
@@ -244,6 +244,8 @@
__FUNCTION__, streamId, strerror(-res), res);
if (res == TIMED_OUT || res == NO_MEMORY) {
bufRet.val.set<Tag::error>(StreamBufferRequestError::NO_BUFFER_AVAILABLE);
+ } else if (res == INVALID_OPERATION) {
+ bufRet.val.set<Tag::error>(StreamBufferRequestError::MAX_BUFFER_EXCEEDED);
} else {
bufRet.val.set<Tag::error>(StreamBufferRequestError::UNKNOWN_ERROR);
}
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
index 6d76687..4bb426c 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
@@ -65,16 +65,9 @@
using namespace android::hardware::camera;
using namespace android::hardware::camera::device::V3_2;
using android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode;
-using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidScalerAvailableStreamUseCases;
namespace android {
-CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap
-HidlCamera3Device::mapToHidlDynamicProfile(int64_t dynamicRangeProfile) {
- return static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap>(
- dynamicRangeProfile);
-}
-
hardware::graphics::common::V1_0::PixelFormat HidlCamera3Device::mapToPixelFormat(
int frameworkFormat) {
return (hardware::graphics::common::V1_0::PixelFormat) frameworkFormat;
@@ -285,7 +278,8 @@
// Metadata tags needs fixup for monochrome camera device version less
// than 3.5.
hardware::hidl_version maxVersion{0,0};
- res = manager->getHighestSupportedVersion(mId.string(), &maxVersion);
+ IPCTransport transport = IPCTransport::HIDL;
+ res = manager->getHighestSupportedVersion(mId.string(), &maxVersion, &transport);
if (res != OK) {
ALOGE("%s: Error in getting camera device version id: %s (%d)",
__FUNCTION__, strerror(-res), res);
@@ -446,11 +440,6 @@
return notifyHelper<hardware::camera::device::V3_2::NotifyMsg>(msgs);
}
-hardware::Return<void> HidlCamera3Device::notify_3_8(
- const hardware::hidl_vec<hardware::camera::device::V3_8::NotifyMsg>& msgs) {
- return notifyHelper<hardware::camera::device::V3_8::NotifyMsg>(msgs);
-}
-
template<typename NotifyMsgType>
hardware::Return<void> HidlCamera3Device::notifyHelper(
const hardware::hidl_vec<NotifyMsgType>& msgs) {
@@ -735,10 +724,6 @@
mRequestMetadataQueue(queue) {
// Check with hardware service manager if we can downcast these interfaces
// Somewhat expensive, so cache the results at startup
- auto castResult_3_8 = device::V3_8::ICameraDeviceSession::castFrom(mHidlSession);
- if (castResult_3_8.isOk()) {
- mHidlSession_3_8 = castResult_3_8;
- }
auto castResult_3_7 = device::V3_7::ICameraDeviceSession::castFrom(mHidlSession);
if (castResult_3_7.isOk()) {
mHidlSession_3_7 = castResult_3_7;
@@ -766,7 +751,6 @@
}
void HidlCamera3Device::HidlHalInterface::clear() {
- mHidlSession_3_8.clear();
mHidlSession_3_7.clear();
mHidlSession_3_6.clear();
mHidlSession_3_5.clear();
@@ -905,16 +889,13 @@
device::V3_2::StreamConfiguration requestedConfiguration3_2;
device::V3_4::StreamConfiguration requestedConfiguration3_4;
device::V3_7::StreamConfiguration requestedConfiguration3_7;
- device::V3_8::StreamConfiguration requestedConfiguration3_8;
requestedConfiguration3_2.streams.resize(config->num_streams);
requestedConfiguration3_4.streams.resize(config->num_streams);
requestedConfiguration3_7.streams.resize(config->num_streams);
- requestedConfiguration3_8.streams.resize(config->num_streams);
for (size_t i = 0; i < config->num_streams; i++) {
device::V3_2::Stream &dst3_2 = requestedConfiguration3_2.streams[i];
device::V3_4::Stream &dst3_4 = requestedConfiguration3_4.streams[i];
device::V3_7::Stream &dst3_7 = requestedConfiguration3_7.streams[i];
- device::V3_8::Stream &dst3_8 = requestedConfiguration3_8.streams[i];
camera3::camera_stream_t *src = config->streams[i];
Camera3Stream* cam3stream = Camera3Stream::cast(src);
@@ -963,23 +944,17 @@
dst3_7.sensorPixelModesUsed[j++] =
static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
}
- if ((src->dynamic_range_profile !=
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) &&
- (mHidlSession_3_8 == nullptr)) {
+ if (src->dynamic_range_profile !=
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
ALOGE("%s: Camera device doesn't support non-standard dynamic range profiles: %" PRIx64,
__FUNCTION__, src->dynamic_range_profile);
return BAD_VALUE;
}
- if (src->use_case != ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT &&
- mHidlSession_3_8 == nullptr) {
+ if (src->use_case != ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
ALOGE("%s: Camera device doesn't support non-default stream use case %" PRId64 "!",
__FUNCTION__, src->use_case);
return BAD_VALUE;
}
- dst3_8.v3_7 = dst3_7;
- dst3_8.dynamicRangeProfile = mapToHidlDynamicProfile(src->dynamic_range_profile);
- dst3_8.useCase =
- static_cast<CameraMetadataEnumAndroidScalerAvailableStreamUseCases>(src->use_case);
activeStreams.insert(streamId);
// Create Buffer ID map if necessary
mBufferRecords.tryCreateBufferCache(streamId);
@@ -1004,10 +979,6 @@
requestedConfiguration3_7.sessionParams.setToExternal(
reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
sessionParamSize);
- requestedConfiguration3_8.operationMode = operationMode;
- requestedConfiguration3_8.sessionParams.setToExternal(
- reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
- sessionParamSize);
// Invoke configureStreams
device::V3_3::HalStreamConfiguration finalConfiguration;
@@ -1053,18 +1024,7 @@
return OK;
};
- // See which version of HAL we have
- if (mHidlSession_3_8 != nullptr) {
- ALOGV("%s: v3.8 device found", __FUNCTION__);
- requestedConfiguration3_8.streamConfigCounter = mNextStreamConfigCounter++;
- requestedConfiguration3_8.multiResolutionInputImage = config->input_is_multi_resolution;
- auto err = mHidlSession_3_8->configureStreams_3_8(requestedConfiguration3_8,
- configStream36Cb);
- res = postprocConfigStream36(err);
- if (res != OK) {
- return res;
- }
- } else if (mHidlSession_3_7 != nullptr) {
+ if (mHidlSession_3_7 != nullptr) {
ALOGV("%s: v3.7 device found", __FUNCTION__);
requestedConfiguration3_7.streamConfigCounter = mNextStreamConfigCounter++;
requestedConfiguration3_7.multiResolutionInputImage = config->input_is_multi_resolution;
@@ -1474,15 +1434,10 @@
return OK;
}
-status_t HidlCamera3Device::HidlHalInterface::repeatingRequestEnd(uint32_t frameNumber,
- const std::vector<int32_t> &streamIds) {
+status_t HidlCamera3Device::HidlHalInterface::repeatingRequestEnd(uint32_t /*frameNumber*/,
+ const std::vector<int32_t> &/*streamIds*/) {
ATRACE_NAME("CameraHal::repeatingRequestEnd");
- if (!valid()) return INVALID_OPERATION;
-
- if (mHidlSession_3_8.get() != nullptr) {
- mHidlSession_3_8->repeatingRequestEnd(frameNumber, streamIds);
- }
- return OK;
+ return INVALID_OPERATION;
}
status_t HidlCamera3Device::HidlHalInterface::close() {
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
index 56c999a..2e98fe0 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
@@ -22,13 +22,12 @@
namespace android {
-using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap;
/**
* CameraDevice for HIDL HAL devices with version CAMERA_DEVICE_API_VERSION_3_0 or higher.
*/
class HidlCamera3Device :
- virtual public hardware::camera::device::V3_8::ICameraDeviceCallback,
+ virtual public hardware::camera::device::V3_5::ICameraDeviceCallback,
public Camera3Device {
public:
@@ -44,8 +43,6 @@
static hardware::camera::device::V3_2::DataspaceFlags mapToHidlDataspace(
android_dataspace dataSpace);
static hardware::camera::device::V3_2::BufferUsageFlags mapToConsumerUsage(uint64_t usage);
- static CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap mapToHidlDynamicProfile(
- int64_t dynamicRangeProfile);
static hardware::camera::device::V3_2::StreamRotation mapToStreamRotation(
camera_stream_rotation_t rotation);
// Returns a negative error code if the passed-in operation mode is not valid.
@@ -84,10 +81,6 @@
const hardware::hidl_vec<
hardware::camera::device::V3_2::StreamBuffer>& buffers) override;
- hardware::Return<void> notify_3_8(
- const hardware::hidl_vec<
- hardware::camera::device::V3_8::NotifyMsg>& msgs) override;
-
// Handle one notify message
void notify(const hardware::camera::device::V3_2::NotifyMsg& msg);
@@ -164,8 +157,6 @@
sp<hardware::camera::device::V3_6::ICameraDeviceSession> mHidlSession_3_6;
// Valid if ICameraDeviceSession is @3.7 or newer
sp<hardware::camera::device::V3_7::ICameraDeviceSession> mHidlSession_3_7;
- // Valid if ICameraDeviceSession is @3.7 or newer
- sp<hardware::camera::device::V3_8::ICameraDeviceSession> mHidlSession_3_8;
std::shared_ptr<RequestMetadataQueue> mRequestMetadataQueue;
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3OutputUtils.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3OutputUtils.cpp
index 60e4e42..8b0cd65 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3OutputUtils.cpp
@@ -63,29 +63,7 @@
}
void notify(CaptureOutputStates& states,
- const hardware::camera::device::V3_8::NotifyMsg& msg) {
- using android::hardware::camera::device::V3_2::MsgType;
-
- hardware::camera::device::V3_2::NotifyMsg msg_3_2;
- msg_3_2.type = msg.type;
- bool hasReadoutTime = false;
- uint64_t readoutTime = 0;
- switch (msg.type) {
- case MsgType::ERROR:
- msg_3_2.msg.error = msg.msg.error;
- break;
- case MsgType::SHUTTER:
- msg_3_2.msg.shutter = msg.msg.shutter.v3_2;
- hasReadoutTime = true;
- readoutTime = msg.msg.shutter.readoutTimestamp;
- break;
- }
- notify(states, msg_3_2, hasReadoutTime, readoutTime);
-}
-
-void notify(CaptureOutputStates& states,
- const hardware::camera::device::V3_2::NotifyMsg& msg,
- bool hasReadoutTime, uint64_t readoutTime) {
+ const hardware::camera::device::V3_2::NotifyMsg& msg) {
using android::hardware::camera::device::V3_2::MsgType;
using android::hardware::camera::device::V3_2::ErrorCode;
@@ -127,8 +105,7 @@
m.type = CAMERA_MSG_SHUTTER;
m.message.shutter.frame_number = msg.msg.shutter.frameNumber;
m.message.shutter.timestamp = msg.msg.shutter.timestamp;
- m.message.shutter.readout_timestamp = hasReadoutTime ?
- readoutTime : m.message.shutter.timestamp;
+ m.message.shutter.readout_timestamp = 0LL;
break;
}
notify(states, &m);
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3OutputUtils.h b/services/camera/libcameraservice/device3/hidl/HidlCamera3OutputUtils.h
index 583d738..5e6cba6 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3OutputUtils.h
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3OutputUtils.h
@@ -26,18 +26,12 @@
#include <common/CameraDeviceBase.h>
-#include <android/hardware/camera/device/3.8/ICameraDeviceCallback.h>
+#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
#include "device3/BufferUtils.h"
-//#include "device3/DistortionMapper.h"
-//#include "device3/ZoomRatioMapper.h"
-//#include "device3/RotateAndCropMapper.h"
#include "device3/InFlightRequest.h"
#include "device3/Camera3Stream.h"
-//#include "device3/Camera3OutputStreamInterface.h"
#include "device3/Camera3OutputUtils.h"
-//#include "utils/SessionStatsBuilder.h"
-//#include "utils/TagMonitor.h"
namespace android {
@@ -65,11 +59,7 @@
// Handle one notify message
void notify(CaptureOutputStates& states,
- const hardware::camera::device::V3_2::NotifyMsg& msg,
- bool hasReadoutTime = false, uint64_t readoutTime = 0LL);
- void notify(CaptureOutputStates& states,
- const hardware::camera::device::V3_8::NotifyMsg& msg);
-
+ const hardware::camera::device::V3_2::NotifyMsg& msg);
void requestStreamBuffers(RequestBufferStates& states,
const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& bufReqs,
hardware::camera::device::V3_5::ICameraDeviceCallback::requestStreamBuffers_cb
diff --git a/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp b/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
index 3c98a5e..e43b91f 100644
--- a/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
+++ b/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
@@ -60,7 +60,6 @@
"android.hardware.camera.device@3.5",
"android.hardware.camera.device@3.6",
"android.hardware.camera.device@3.7",
- "android.hardware.camera.device@3.8",
],
fuzz_config: {
cc: [
diff --git a/services/camera/libcameraservice/tests/Android.bp b/services/camera/libcameraservice/tests/Android.bp
index 4928faf..3616572 100644
--- a/services/camera/libcameraservice/tests/Android.bp
+++ b/services/camera/libcameraservice/tests/Android.bp
@@ -49,7 +49,6 @@
"android.hardware.camera.device@3.2",
"android.hardware.camera.device@3.4",
"android.hardware.camera.device@3.7",
- "android.hardware.camera.device@3.8",
"android.hidl.token@1.0-utils",
],
diff --git a/services/camera/libcameraservice/utils/ClientManager.h b/services/camera/libcameraservice/utils/ClientManager.h
index d164885..074c84d 100644
--- a/services/camera/libcameraservice/utils/ClientManager.h
+++ b/services/camera/libcameraservice/utils/ClientManager.h
@@ -527,12 +527,7 @@
if (!returnIncompatibleClients) {
// Find evicted clients
- if (conflicting && curPriority < priority) {
- // Pre-existing conflicting client with higher priority exists
- evictList.clear();
- evictList.push_back(client);
- return evictList;
- } else if (conflicting && owner == curOwner) {
+ if (conflicting && owner == curOwner) {
// Pre-existing conflicting client with the same client owner exists
// Open the same device twice -> most recent open wins
// Otherwise let the existing client wins to avoid behaviors difference
@@ -546,6 +541,11 @@
evictList.push_back(client);
return evictList;
}
+ } else if (conflicting && curPriority < priority) {
+ // Pre-existing conflicting client with higher priority exists
+ evictList.clear();
+ evictList.push_back(client);
+ return evictList;
} else if (conflicting || ((totalCost > mMaxCost && curCost > 0) &&
(curPriority >= priority) &&
!(highestPriorityOwner == owner && owner == curOwner))) {
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index d5ddf9f..6b1a0b2 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -19,7 +19,6 @@
#include "SessionConfigurationUtils.h"
#include "../api2/DepthCompositeStream.h"
#include "../api2/HeicCompositeStream.h"
-#include "android/hardware/camera/metadata/3.8/types.h"
#include "common/CameraDeviceBase.h"
#include "common/HalConversionsTemplated.h"
#include "../CameraService.h"
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index 97ca6b7..a127c7b 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -21,11 +21,9 @@
#include <camera/camera2/OutputConfiguration.h>
#include <camera/camera2/SessionConfiguration.h>
#include <camera/camera2/SubmitInfo.h>
-#include <android/hardware/camera/device/3.8/types.h>
#include <aidl/android/hardware/camera/device/ICameraDevice.h>
#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
-#include <android/hardware/camera/device/3.8/ICameraDeviceSession.h>
#include <device3/Camera3StreamInterface.h>
#include <utils/IPCTransport.h>
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
index 07b55e1..4e6f832 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
@@ -27,8 +27,6 @@
using android::camera3::OutputStreamInfo;
using android::hardware::camera2::ICameraDeviceUser;
using android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode;
-using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap;
-using android::hardware::camera::metadata::V3_8::CameraMetadataEnumAndroidScalerAvailableStreamUseCases;
namespace android {
namespace camera3 {
@@ -36,9 +34,9 @@
namespace SessionConfigurationUtils {
status_t
-convertAidlToHidl38StreamCombination(
+convertAidlToHidl37StreamCombination(
const aidl::android::hardware::camera::device::StreamConfiguration &aidl,
- hardware::camera::device::V3_8::StreamConfiguration &hidl) {
+ hardware::camera::device::V3_7::StreamConfiguration &hidl) {
hidl.operationMode =
static_cast<hardware::camera::device::V3_2::StreamConfigurationMode>(aidl.operationMode);
if (aidl.streamConfigCounter < 0) {
@@ -50,97 +48,66 @@
hidl.streams.resize(aidl.streams.size());
size_t i = 0;
for (const auto &stream : aidl.streams) {
- //hidlv3_8
- hidl.streams[i].dynamicRangeProfile =
- static_cast<
- CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap>
- (stream.dynamicRangeProfile);
- hidl.streams[i].useCase =
- static_cast<
- CameraMetadataEnumAndroidScalerAvailableStreamUseCases>
- (stream.useCase);
+ if (static_cast<int>(stream.dynamicRangeProfile) !=
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
+ ALOGE("%s Dynamic range profile %" PRId64 " not supported by HIDL", __FUNCTION__,
+ stream.dynamicRangeProfile);
+ return BAD_VALUE;
+ }
+
+ if (static_cast<int>(stream.useCase) != ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
+ ALOGE("%s Stream use case %" PRId64 "not supported by HIDL", __FUNCTION__,
+ stream.useCase);
+ return BAD_VALUE;
+ }
// hidl v3_7
- hidl.streams[i].v3_7.groupId = stream.groupId;
- hidl.streams[i].v3_7.sensorPixelModesUsed.resize(stream.sensorPixelModesUsed.size());
+ hidl.streams[i].groupId = stream.groupId;
+ hidl.streams[i].sensorPixelModesUsed.resize(stream.sensorPixelModesUsed.size());
size_t j = 0;
for (const auto &mode : stream.sensorPixelModesUsed) {
- hidl.streams[i].v3_7.sensorPixelModesUsed[j] =
+ hidl.streams[i].sensorPixelModesUsed[j] =
static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
j++;
}
//hidl v3_4
- hidl.streams[i].v3_7.v3_4.physicalCameraId = stream.physicalCameraId;
+ hidl.streams[i].v3_4.physicalCameraId = stream.physicalCameraId;
if (stream.bufferSize < 0) {
return BAD_VALUE;
}
- hidl.streams[i].v3_7.v3_4.bufferSize = static_cast<uint32_t>(stream.bufferSize);
+ hidl.streams[i].v3_4.bufferSize = static_cast<uint32_t>(stream.bufferSize);
// hild v3_2
- hidl.streams[i].v3_7.v3_4.v3_2.id = stream.id;
- hidl.streams[i].v3_7.v3_4.v3_2.format =
+ hidl.streams[i].v3_4.v3_2.id = stream.id;
+ hidl.streams[i].v3_4.v3_2.format =
static_cast<hardware::graphics::common::V1_0::PixelFormat>(stream.format);
if (stream.width < 0 || stream.height < 0) {
return BAD_VALUE;
}
- hidl.streams[i].v3_7.v3_4.v3_2.width = static_cast<uint32_t>(stream.width);
- hidl.streams[i].v3_7.v3_4.v3_2.height = static_cast<uint32_t>(stream.height);
- hidl.streams[i].v3_7.v3_4.v3_2.usage =
+ hidl.streams[i].v3_4.v3_2.width = static_cast<uint32_t>(stream.width);
+ hidl.streams[i].v3_4.v3_2.height = static_cast<uint32_t>(stream.height);
+ hidl.streams[i].v3_4.v3_2.usage =
static_cast<hardware::camera::device::V3_2::BufferUsageFlags>(stream.usage);
- hidl.streams[i].v3_7.v3_4.v3_2.streamType =
+ hidl.streams[i].v3_4.v3_2.streamType =
static_cast<hardware::camera::device::V3_2::StreamType>(stream.streamType);
- hidl.streams[i].v3_7.v3_4.v3_2.dataSpace =
+ hidl.streams[i].v3_4.v3_2.dataSpace =
static_cast<hardware::camera::device::V3_2::DataspaceFlags>(stream.dataSpace);
- hidl.streams[i].v3_7.v3_4.v3_2.rotation =
+ hidl.streams[i].v3_4.v3_2.rotation =
static_cast<hardware::camera::device::V3_2::StreamRotation>(stream.rotation);
i++;
}
return OK;
}
-void mapStreamInfo(const OutputStreamInfo &streamInfo,
- camera3::camera_stream_rotation_t rotation, String8 physicalId,
- int32_t groupId, hardware::camera::device::V3_8::Stream *stream /*out*/) {
- if (stream == nullptr) {
- return;
- }
-
- stream->v3_7.v3_4.v3_2.streamType = hardware::camera::device::V3_2::StreamType::OUTPUT;
- stream->v3_7.v3_4.v3_2.width = streamInfo.width;
- stream->v3_7.v3_4.v3_2.height = streamInfo.height;
- stream->v3_7.v3_4.v3_2.format = HidlCamera3Device::mapToPixelFormat(streamInfo.format);
- auto u = streamInfo.consumerUsage;
- camera3::Camera3OutputStream::applyZSLUsageQuirk(streamInfo.format, &u);
- stream->v3_7.v3_4.v3_2.usage = HidlCamera3Device::mapToConsumerUsage(u);
- stream->v3_7.v3_4.v3_2.dataSpace = HidlCamera3Device::mapToHidlDataspace(streamInfo.dataSpace);
- stream->v3_7.v3_4.v3_2.rotation = HidlCamera3Device::mapToStreamRotation(rotation);
- stream->v3_7.v3_4.v3_2.id = -1; // Invalid stream id
- stream->v3_7.v3_4.physicalCameraId = std::string(physicalId.string());
- stream->v3_7.v3_4.bufferSize = 0;
- stream->v3_7.groupId = groupId;
- stream->v3_7.sensorPixelModesUsed.resize(streamInfo.sensorPixelModesUsed.size());
-
- size_t idx = 0;
- for (auto mode : streamInfo.sensorPixelModesUsed) {
- stream->v3_7.sensorPixelModesUsed[idx++] =
- static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
- }
- stream->dynamicRangeProfile =
- static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> (
- streamInfo.dynamicRangeProfile);
- stream->useCase = static_cast<CameraMetadataEnumAndroidScalerAvailableStreamUseCases>(
- streamInfo.streamUseCase);
-}
-
binder::Status
convertToHALStreamCombination(
const SessionConfiguration& sessionConfiguration,
const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
- hardware::camera::device::V3_8::StreamConfiguration &streamConfiguration,
+ hardware::camera::device::V3_7::StreamConfiguration &streamConfiguration,
bool overrideForPerfClass, bool *earlyExit) {
aidl::android::hardware::camera::device::StreamConfiguration aidlStreamConfiguration;
auto ret = convertToHALStreamCombination(sessionConfiguration, logicalCameraId, deviceInfo,
@@ -153,38 +120,14 @@
return binder::Status::ok();
}
- if (convertAidlToHidl38StreamCombination(aidlStreamConfiguration, streamConfiguration) != OK) {
+ if (convertAidlToHidl37StreamCombination(aidlStreamConfiguration, streamConfiguration) != OK) {
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
- "Invalid AIDL->HIDL3.8 conversion");
+ "Invalid AIDL->HIDL3.7 conversion");
}
return binder::Status::ok();
}
-bool convertHALStreamCombinationFromV38ToV37(
- hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37,
- const hardware::camera::device::V3_8::StreamConfiguration &streamConfigV38) {
- streamConfigV37.streams.resize(streamConfigV38.streams.size());
- for (size_t i = 0; i < streamConfigV38.streams.size(); i++) {
- if (static_cast<int64_t>(streamConfigV38.streams[i].dynamicRangeProfile) !=
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
- // ICameraDevice older than 3.8 doesn't support 10-bit dynamic range profiles
- // image
- return false;
- }
- if (static_cast<int64_t>(streamConfigV38.streams[i].useCase) !=
- ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
- // ICameraDevice older than 3.8 doesn't support stream use case
- return false;
- }
- streamConfigV37.streams[i] = streamConfigV38.streams[i].v3_7;
- }
- streamConfigV37.operationMode = streamConfigV38.operationMode;
- streamConfigV37.sessionParams = streamConfigV38.sessionParams;
-
- return true;
-}
-
bool convertHALStreamCombinationFromV37ToV34(
hardware::camera::device::V3_4::StreamConfiguration &streamConfigV34,
const hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37) {
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h
index 66956c5..c47abe0 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.h
@@ -16,10 +16,8 @@
#ifndef ANDROID_SERVERS_CAMERA_SESSION_CONFIGURATION_UTILS_HIDL_H
#define ANDROID_SERVERS_CAMERA_SESSION_CONFIGURATION_UTILS_HIDL_H
-#include <android/hardware/camera/device/3.8/types.h>
#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
-#include <android/hardware/camera/device/3.8/ICameraDeviceSession.h>
#include <utils/SessionConfigurationUtils.h>
@@ -30,10 +28,6 @@
namespace SessionConfigurationUtils {
-void mapStreamInfo(const camera3::OutputStreamInfo &streamInfo,
- camera3::camera_stream_rotation_t rotation, String8 physicalId, int32_t groupId,
- hardware::camera::device::V3_8::Stream *stream /*out*/);
-
// utility function to convert AIDL SessionConfiguration to HIDL
// streamConfiguration. Also checks for validity of SessionConfiguration and
// returns a non-ok binder::Status if the passed in session configuration
@@ -42,16 +36,9 @@
convertToHALStreamCombination(const SessionConfiguration& sessionConfiguration,
const String8 &cameraId, const CameraMetadata &deviceInfo,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
- hardware::camera::device::V3_8::StreamConfiguration &streamConfiguration,
+ hardware::camera::device::V3_7::StreamConfiguration &streamConfiguration,
bool overrideForPerfClass, bool *earlyExit);
-// Utility function to convert a V3_8::StreamConfiguration to
-// V3_7::StreamConfiguration. Return false if the original V3_8 configuration cannot
-// be used by older version HAL.
-bool convertHALStreamCombinationFromV38ToV37(
- hardware::camera::device::V3_7::StreamConfiguration &streamConfigV37,
- const hardware::camera::device::V3_8::StreamConfiguration &streamConfigV38);
-
// Utility function to convert a V3_7::StreamConfiguration to
// V3_4::StreamConfiguration. Return false if the original V3_7 configuration cannot
// be used by older version HAL.
diff --git a/services/mediametrics/statsd_codec.cpp b/services/mediametrics/statsd_codec.cpp
index e322d62..a737ba0 100644
--- a/services/mediametrics/statsd_codec.cpp
+++ b/services/mediametrics/statsd_codec.cpp
@@ -390,47 +390,59 @@
}
AStatsEvent_writeInt32(event, qpBMaxOri);
- // int32_t configColorStandard = -1;
- // if (item->getInt32("android.media.mediacodec.config-color-standard", &configColorStandard)) {
- // metrics_proto.set_config_color_standard(configColorStandard);
- // }
- // AStatsEvent_writeInt32(event, configColorStandard);
+ int32_t configColorStandard = -1;
+ if (item->getInt32("android.media.mediacodec.config-color-standard", &configColorStandard)) {
+ metrics_proto.set_config_color_standard(configColorStandard);
+ }
+ AStatsEvent_writeInt32(event, configColorStandard);
- // int32_t configColorRange = -1;
- // if (item->getInt32("android.media.mediacodec.config-color-range", &configColorRange)) {
- // metrics_proto.set_config_color_range(configColorRange);
- // }
- // AStatsEvent_writeInt32(event, configColorRange);
+ int32_t configColorRange = -1;
+ if (item->getInt32("android.media.mediacodec.config-color-range", &configColorRange)) {
+ metrics_proto.set_config_color_range(configColorRange);
+ }
+ AStatsEvent_writeInt32(event, configColorRange);
- // int32_t configColorTransfer = -1;
- // if (item->getInt32("android.media.mediacodec.config-color-transfer", &configColorTransfer)) {
- // metrics_proto.set_config_color_transfer(configColorTransfer);
- // }
- // AStatsEvent_writeInt32(event, configColorTransfer);
+ int32_t configColorTransfer = -1;
+ if (item->getInt32("android.media.mediacodec.config-color-transfer", &configColorTransfer)) {
+ metrics_proto.set_config_color_transfer(configColorTransfer);
+ }
+ AStatsEvent_writeInt32(event, configColorTransfer);
- // int32_t parsedColorStandard = -1;
- // if (item->getInt32("android.media.mediacodec.parsed-color-standard", &parsedColorStandard)) {
- // metrics_proto.set_parsed_color_standard(parsedColorStandard);
- // }
- // AStatsEvent_writeInt32(event, parsedColorStandard);
+ int32_t parsedColorStandard = -1;
+ if (item->getInt32("android.media.mediacodec.parsed-color-standard", &parsedColorStandard)) {
+ metrics_proto.set_parsed_color_standard(parsedColorStandard);
+ }
+ AStatsEvent_writeInt32(event, parsedColorStandard);
- // int32_t parsedColorRange = -1;
- // if (item->getInt32("android.media.mediacodec.parsed-color-range", &parsedColorRange)) {
- // metrics_proto.set_parsed_color_range(parsedColorRange);
- // }
- // AStatsEvent_writeInt32(event, parsedColorRange);
+ int32_t parsedColorRange = -1;
+ if (item->getInt32("android.media.mediacodec.parsed-color-range", &parsedColorRange)) {
+ metrics_proto.set_parsed_color_range(parsedColorRange);
+ }
+ AStatsEvent_writeInt32(event, parsedColorRange);
- // int32_t parsedColorTransfer = -1;
- // if (item->getInt32("android.media.mediacodec.parsed-color-transfer", &parsedColorTransfer)) {
- // metrics_proto.set_parsed_color_transfer(parsedColorTransfer);
- // }
- // AStatsEvent_writeInt32(event, parsedColorTransfer);
+ int32_t parsedColorTransfer = -1;
+ if (item->getInt32("android.media.mediacodec.parsed-color-transfer", &parsedColorTransfer)) {
+ metrics_proto.set_parsed_color_transfer(parsedColorTransfer);
+ }
+ AStatsEvent_writeInt32(event, parsedColorTransfer);
- // int32_t hdrMetadataFlags = -1;
- // if (item->getInt32("android.media.mediacodec.hdr-metadata-flags", &hdrMetadataFlags)) {
- // metrics_proto.set_hdr_metadata_flags(hdrMetadataFlags);
- // }
- // AStatsEvent_writeInt32(event, hdrMetadataFlags);
+ int32_t hdrStaticInfo = -1;
+ if (item->getInt32("android.media.mediacodec.hdr-static-info", &hdrStaticInfo)) {
+ metrics_proto.set_hdr_static_info(hdrStaticInfo);
+ }
+ AStatsEvent_writeInt32(event, hdrStaticInfo);
+
+ int32_t hdr10PlusInfo = -1;
+ if (item->getInt32("android.media.mediacodec.hdr10-plus-info", &hdr10PlusInfo)) {
+ metrics_proto.set_hdr10_plus_info(hdr10PlusInfo);
+ }
+ AStatsEvent_writeInt32(event, hdr10PlusInfo);
+
+ int32_t hdrFormat= -1;
+ if (item->getInt32("android.media.mediacodec.hdr-format", &hdrFormat)) {
+ metrics_proto.set_hdr_format(hdrFormat);
+ }
+ AStatsEvent_writeInt32(event, hdrFormat);
int err = AStatsEvent_write(event);
if (err < 0) {