Merge branch android10-qpr3-release
Change-Id: Ie04a66168a33e7c7e2b8b1fb6de92a772d3f054b
diff --git a/apex/manifest.json b/apex/manifest.json
index b11187d..3011ee8 100644
--- a/apex/manifest.json
+++ b/apex/manifest.json
@@ -1,4 +1,4 @@
{
"name": "com.android.media",
- "version": 299900000
+ "version": 290000000
}
diff --git a/apex/manifest_codec.json b/apex/manifest_codec.json
index 09c436d..83a5178 100644
--- a/apex/manifest_codec.json
+++ b/apex/manifest_codec.json
@@ -1,4 +1,4 @@
{
"name": "com.android.media.swcodec",
- "version": 299900000
+ "version": 290000000
}
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index fa98178..2be51dd 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -500,7 +500,7 @@
status_t C2SoftAvcDec::initDecoder() {
if (OK != createDecoder()) return UNKNOWN_ERROR;
mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
- mStride = ALIGN64(mWidth);
+ mStride = ALIGN128(mWidth);
mSignalledError = false;
resetPlugin();
(void) setNumCores();
@@ -755,8 +755,8 @@
ALOGE("not supposed to be here, invalid decoder context");
return C2_CORRUPTED;
}
- if (mStride != ALIGN64(mWidth)) {
- mStride = ALIGN64(mWidth);
+ if (mStride != ALIGN128(mWidth)) {
+ mStride = ALIGN128(mWidth);
if (OK != setParams(mStride, IVD_DECODE_FRAME)) return C2_CORRUPTED;
}
if (mOutBlock &&
@@ -908,7 +908,7 @@
if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
if (mHeaderDecoded == false) {
mHeaderDecoded = true;
- setParams(ALIGN64(s_decode_op.u4_pic_wd), IVD_DECODE_FRAME);
+ setParams(ALIGN128(s_decode_op.u4_pic_wd), IVD_DECODE_FRAME);
}
if (s_decode_op.u4_pic_wd != mWidth || s_decode_op.u4_pic_ht != mHeight) {
mWidth = s_decode_op.u4_pic_wd;
diff --git a/media/codec2/components/avc/C2SoftAvcDec.h b/media/codec2/components/avc/C2SoftAvcDec.h
index 4414a26..ed27493 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.h
+++ b/media/codec2/components/avc/C2SoftAvcDec.h
@@ -40,6 +40,7 @@
#define ivdext_ctl_get_vui_params_ip_t ih264d_ctl_get_vui_params_ip_t
#define ivdext_ctl_get_vui_params_op_t ih264d_ctl_get_vui_params_op_t
#define ALIGN64(x) ((((x) + 63) >> 6) << 6)
+#define ALIGN128(x) ((((x) + 127) >> 7) << 7)
#define MAX_NUM_CORES 4
#define IVDEXT_CMD_CTL_SET_NUM_CORES \
(IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
index df677c2..6db4387 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -497,7 +497,7 @@
status_t C2SoftHevcDec::initDecoder() {
if (OK != createDecoder()) return UNKNOWN_ERROR;
mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
- mStride = ALIGN64(mWidth);
+ mStride = ALIGN128(mWidth);
mSignalledError = false;
resetPlugin();
(void) setNumCores();
@@ -752,8 +752,8 @@
ALOGE("not supposed to be here, invalid decoder context");
return C2_CORRUPTED;
}
- if (mStride != ALIGN64(mWidth)) {
- mStride = ALIGN64(mWidth);
+ if (mStride != ALIGN128(mWidth)) {
+ mStride = ALIGN128(mWidth);
if (OK != setParams(mStride, IVD_DECODE_FRAME)) return C2_CORRUPTED;
}
if (mOutBlock &&
@@ -904,7 +904,7 @@
if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
if (mHeaderDecoded == false) {
mHeaderDecoded = true;
- setParams(ALIGN64(s_decode_op.u4_pic_wd), IVD_DECODE_FRAME);
+ setParams(ALIGN128(s_decode_op.u4_pic_wd), IVD_DECODE_FRAME);
}
if (s_decode_op.u4_pic_wd != mWidth || s_decode_op.u4_pic_ht != mHeight) {
mWidth = s_decode_op.u4_pic_wd;
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.h b/media/codec2/components/hevc/C2SoftHevcDec.h
index ce63a6c..aecd101 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.h
+++ b/media/codec2/components/hevc/C2SoftHevcDec.h
@@ -38,6 +38,7 @@
#define ivdext_ctl_get_vui_params_ip_t ihevcd_cxa_ctl_get_vui_params_ip_t
#define ivdext_ctl_get_vui_params_op_t ihevcd_cxa_ctl_get_vui_params_op_t
#define ALIGN64(x) ((((x) + 63) >> 6) << 6)
+#define ALIGN128(x) ((((x) + 127) >> 7) << 7)
#define MAX_NUM_CORES 4
#define IVDEXT_CMD_CTL_SET_NUM_CORES \
(IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
index c747190..15bdb5b 100644
--- a/media/codec2/hidl/client/client.cpp
+++ b/media/codec2/hidl/client/client.cpp
@@ -89,6 +89,69 @@
return i;
}
+class Client2Store : public C2ComponentStore {
+ std::shared_ptr<Codec2Client> mClient;
+
+public:
+ Client2Store(std::shared_ptr<Codec2Client> const& client)
+ : mClient(client) { }
+
+ virtual ~Client2Store() = default;
+
+ virtual c2_status_t config_sm(
+ std::vector<C2Param*> const ¶ms,
+ std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
+ return mClient->config(params, C2_MAY_BLOCK, failures);
+ };
+
+ virtual c2_status_t copyBuffer(
+ std::shared_ptr<C2GraphicBuffer>,
+ std::shared_ptr<C2GraphicBuffer>) {
+ return C2_OMITTED;
+ }
+
+ virtual c2_status_t createComponent(
+ C2String, std::shared_ptr<C2Component>* const component) {
+ component->reset();
+ return C2_OMITTED;
+ }
+
+ virtual c2_status_t createInterface(
+ C2String, std::shared_ptr<C2ComponentInterface>* const interface) {
+ interface->reset();
+ return C2_OMITTED;
+ }
+
+ virtual c2_status_t query_sm(
+ std::vector<C2Param*> const& stackParams,
+ std::vector<C2Param::Index> const& heapParamIndices,
+ std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
+ return mClient->query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
+ }
+
+ virtual c2_status_t querySupportedParams_nb(
+ std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
+ return mClient->querySupportedParams(params);
+ }
+
+ virtual c2_status_t querySupportedValues_sm(
+ std::vector<C2FieldSupportedValuesQuery>& fields) const {
+ return mClient->querySupportedValues(fields, C2_MAY_BLOCK);
+ }
+
+ virtual C2String getName() const {
+ return mClient->getName();
+ }
+
+ virtual std::shared_ptr<C2ParamReflector> getParamReflector() const {
+ return mClient->getParamReflector();
+ }
+
+ virtual std::vector<std::shared_ptr<C2Component::Traits const>> listComponents() {
+ return std::vector<std::shared_ptr<C2Component::Traits const>>();
+ }
+};
+
} // unnamed namespace
// This class caches a Codec2Client object and its component traits. The client
@@ -806,10 +869,24 @@
}
std::shared_ptr<Codec2Client> Codec2Client::CreateFromService(
- const char* name) {
+ const char* name,
+ bool setAsPreferredCodec2ComponentStore) {
size_t index = getServiceIndex(name);
- return index == GetServiceNames().size() ?
- nullptr : _CreateFromIndex(index);
+ if (index == GetServiceNames().size()) {
+ if (setAsPreferredCodec2ComponentStore) {
+ LOG(WARNING) << "CreateFromService(" << name
+ << ") -- preferred C2ComponentStore not set.";
+ }
+ return nullptr;
+ }
+ std::shared_ptr<Codec2Client> client = _CreateFromIndex(index);
+ if (setAsPreferredCodec2ComponentStore) {
+ SetPreferredCodec2ComponentStore(
+ std::make_shared<Client2Store>(client));
+ LOG(INFO) << "CreateFromService(" << name
+ << ") -- service set as preferred C2ComponentStore.";
+ }
+ return client;
}
std::vector<std::shared_ptr<Codec2Client>> Codec2Client::
diff --git a/media/codec2/hidl/client/include/codec2/hidl/client.h b/media/codec2/hidl/client/include/codec2/hidl/client.h
index c37407f..f5884a0 100644
--- a/media/codec2/hidl/client/include/codec2/hidl/client.h
+++ b/media/codec2/hidl/client/include/codec2/hidl/client.h
@@ -172,8 +172,15 @@
// Note: A software service will have "_software" as a suffix.
static std::vector<std::string> const& GetServiceNames();
- // Create a service with a given service name.
- static std::shared_ptr<Codec2Client> CreateFromService(char const* name);
+ // Create a client to a service with a given name.
+ //
+ // After a client to the service is successfully created, if
+ // setAsPreferredCodec2ComponentStore is true, the component store that the
+ // service hosts will be set as the preferred C2ComponentStore for this
+ // process. (See SetPreferredCodec2ComponentStore() for more information.)
+ static std::shared_ptr<Codec2Client> CreateFromService(
+ char const* name,
+ bool setAsPreferredCodec2ComponentStore = false);
// Get clients to all services.
static std::vector<std::shared_ptr<Codec2Client>> CreateFromAllServices();
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 44f246d..93356f8 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -3316,6 +3316,7 @@
{ MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
{ MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision },
{ MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC, OMX_VIDEO_CodingImageHEIC },
+ { MEDIA_MIMETYPE_VIDEO_AV1, OMX_VIDEO_CodingAV1 },
};
static status_t GetVideoCodingTypeFromMime(
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index 359df3d..4711315 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -31,9 +31,14 @@
namespace android {
-static int ALIGN(int x, int y) {
- // y must be a power of 2.
- return (x + y - 1) & ~(y - 1);
+inline void initDstYUV(
+ const android_ycbcr &ycbcr, int32_t cropTop, int32_t cropLeft,
+ uint8_t **dst_y, uint8_t **dst_u, uint8_t **dst_v) {
+ *dst_y = (uint8_t *)ycbcr.y + cropTop * ycbcr.ystride + cropLeft;
+
+ int32_t c_offset = (cropTop / 2) * ycbcr.cstride + cropLeft / 2;
+ *dst_v = (uint8_t *)ycbcr.cr + c_offset;
+ *dst_u = (uint8_t *)ycbcr.cb + c_offset;
}
SoftwareRenderer::SoftwareRenderer(
@@ -269,10 +274,21 @@
Rect bounds(mCropWidth, mCropHeight);
- void *dst;
- CHECK_EQ(0, mapper.lock(buf->handle,
- GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_RARELY,
- bounds, &dst));
+ void *dst = NULL;
+ struct android_ycbcr ycbcr;
+ if ( !mConverter &&
+ (mColorFormat == OMX_COLOR_FormatYUV420Planar ||
+ mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
+ mColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar ||
+ mColorFormat == OMX_COLOR_FormatYUV420Planar16)) {
+ CHECK_EQ(0, mapper.lockYCbCr(buf->handle,
+ GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_RARELY,
+ bounds, &ycbcr));
+ } else {
+ CHECK_EQ(0, mapper.lock(buf->handle,
+ GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_RARELY,
+ bounds, &dst));
+ }
// TODO move the other conversions also into ColorConverter, and
// fix cropping issues (when mCropLeft/Top != 0 or mWidth != mCropWidth)
@@ -289,22 +305,14 @@
const uint8_t *src_u = (const uint8_t *)data + mStride * mHeight + mCropTop * mStride / 4;
const uint8_t *src_v = (const uint8_t *)src_u + mStride * mHeight / 4;
- uint8_t *dst_y = (uint8_t *)dst;
- size_t dst_y_size = buf->stride * buf->height;
- size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
- size_t dst_c_size = dst_c_stride * buf->height / 2;
- uint8_t *dst_v = dst_y + dst_y_size;
- uint8_t *dst_u = dst_v + dst_c_size;
-
- dst_y += mCropTop * buf->stride + mCropLeft;
- dst_v += (mCropTop/2) * dst_c_stride + mCropLeft/2;
- dst_u += (mCropTop/2) * dst_c_stride + mCropLeft/2;
+ uint8_t *dst_y, *dst_u, *dst_v;
+ initDstYUV(ycbcr, mCropTop, mCropLeft, &dst_y, &dst_u, &dst_v);
for (int y = 0; y < mCropHeight; ++y) {
memcpy(dst_y, src_y, mCropWidth);
src_y += mStride;
- dst_y += buf->stride;
+ dst_y += ycbcr.ystride;
}
for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
@@ -313,24 +321,16 @@
src_u += mStride / 2;
src_v += mStride / 2;
- dst_u += dst_c_stride;
- dst_v += dst_c_stride;
+ dst_u += ycbcr.cstride;
+ dst_v += ycbcr.cstride;
}
} else if (mColorFormat == OMX_COLOR_FormatYUV420Planar16) {
const uint8_t *src_y = (const uint8_t *)data + mCropTop * mStride + mCropLeft * 2;
const uint8_t *src_u = (const uint8_t *)data + mStride * mHeight + mCropTop * mStride / 4;
const uint8_t *src_v = (const uint8_t *)src_u + mStride * mHeight / 4;
- uint8_t *dst_y = (uint8_t *)dst;
- size_t dst_y_size = buf->stride * buf->height;
- size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
- size_t dst_c_size = dst_c_stride * buf->height / 2;
- uint8_t *dst_v = dst_y + dst_y_size;
- uint8_t *dst_u = dst_v + dst_c_size;
-
- dst_y += mCropTop * buf->stride + mCropLeft;
- dst_v += (mCropTop / 2) * dst_c_stride + mCropLeft / 2;
- dst_u += (mCropTop / 2) * dst_c_stride + mCropLeft / 2;
+ uint8_t *dst_y, *dst_u, *dst_v;
+ initDstYUV(ycbcr, mCropTop, mCropLeft, &dst_y, &dst_u, &dst_v);
for (int y = 0; y < mCropHeight; ++y) {
for (int x = 0; x < mCropWidth; ++x) {
@@ -338,7 +338,7 @@
}
src_y += mStride;
- dst_y += buf->stride;
+ dst_y += ycbcr.ystride;
}
for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
@@ -349,8 +349,8 @@
src_u += mStride / 2;
src_v += mStride / 2;
- dst_u += dst_c_stride;
- dst_v += dst_c_stride;
+ dst_u += ycbcr.cstride;
+ dst_v += ycbcr.cstride;
}
} else if (mColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
|| mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
@@ -361,23 +361,14 @@
src_y += mCropLeft + mCropTop * mWidth;
src_uv += (mCropLeft + mCropTop * mWidth) / 2;
- uint8_t *dst_y = (uint8_t *)dst;
-
- size_t dst_y_size = buf->stride * buf->height;
- size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
- size_t dst_c_size = dst_c_stride * buf->height / 2;
- uint8_t *dst_v = dst_y + dst_y_size;
- uint8_t *dst_u = dst_v + dst_c_size;
-
- dst_y += mCropTop * buf->stride + mCropLeft;
- dst_v += (mCropTop/2) * dst_c_stride + mCropLeft/2;
- dst_u += (mCropTop/2) * dst_c_stride + mCropLeft/2;
+ uint8_t *dst_y, *dst_u, *dst_v;
+ initDstYUV(ycbcr, mCropTop, mCropLeft, &dst_y, &dst_u, &dst_v);
for (int y = 0; y < mCropHeight; ++y) {
memcpy(dst_y, src_y, mCropWidth);
src_y += mWidth;
- dst_y += buf->stride;
+ dst_y += ycbcr.ystride;
}
for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
@@ -388,8 +379,8 @@
}
src_uv += mWidth;
- dst_u += dst_c_stride;
- dst_v += dst_c_stride;
+ dst_u += ycbcr.cstride;
+ dst_v += ycbcr.cstride;
}
} else if (mColorFormat == OMX_COLOR_Format24bitRGB888) {
uint8_t* srcPtr = (uint8_t*)data + mWidth * mCropTop * 3 + mCropLeft * 3;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 670e026..7e83209 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -3288,9 +3288,21 @@
return;
}
bool isHidden = isPublicallyHiddenSecureCamera(cameraId);
+ bool supportsHAL3 = false;
+ // supportsCameraApi also holds mInterfaceMutex, we can't call it in the
+ // HIDL onStatusChanged wrapper call (we'll hold mStatusListenerLock and
+ // mInterfaceMutex together, which can lead to deadlocks)
+ binder::Status sRet =
+ supportsCameraApi(String16(cameraId), hardware::ICameraService::API_VERSION_2,
+ &supportsHAL3);
+ if (!sRet.isOk()) {
+ ALOGW("%s: Failed to determine if device supports HAL3 %s, supportsCameraApi call failed",
+ __FUNCTION__, cameraId.string());
+ return;
+ }
// Update the status for this camera state, then send the onStatusChangedCallbacks to each
// of the listeners with both the mStatusStatus and mStatusListenerLock held
- state->updateStatus(status, cameraId, rejectSourceStates, [this,&isHidden]
+ state->updateStatus(status, cameraId, rejectSourceStates, [this, &isHidden, &supportsHAL3]
(const String8& cameraId, StatusInternal status) {
if (status != StatusInternal::ENUMERATING) {
@@ -3312,7 +3324,14 @@
Mutex::Autolock lock(mStatusListenerLock);
for (auto& listener : mListenerList) {
- if (!listener.first && isHidden) {
+ bool isVendorListener = listener.first;
+ if (isVendorListener && !supportsHAL3) {
+ ALOGV("Skipping vendor listener camera discovery callback for HAL1 camera %s",
+ cameraId.c_str());
+ continue;
+ }
+
+ if (!isVendorListener && isHidden) {
ALOGV("Skipping camera discovery callback for system-only camera %s",
cameraId.c_str());
continue;
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index fd9b4b0..f707ef8 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -70,7 +70,7 @@
mFormatOverridden(false),
mOriginalFormat(format),
mDataSpaceOverridden(false),
- mOriginalDataSpace(HAL_DATASPACE_UNKNOWN),
+ mOriginalDataSpace(dataSpace),
mPhysicalCameraId(physicalCameraId),
mLastTimestamp(0) {
@@ -137,9 +137,6 @@
void Camera3Stream::setDataSpaceOverride(bool dataSpaceOverridden) {
mDataSpaceOverridden = dataSpaceOverridden;
- if (dataSpaceOverridden && mOriginalDataSpace == HAL_DATASPACE_UNKNOWN) {
- mOriginalDataSpace = camera3_stream::data_space;
- }
}
bool Camera3Stream::isDataSpaceOverridden() const {
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index 67afd0f..805df82 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -588,7 +588,7 @@
//Keep track of original dataSpace in case it gets overridden
bool mDataSpaceOverridden;
- android_dataspace mOriginalDataSpace;
+ const android_dataspace mOriginalDataSpace;
String8 mPhysicalCameraId;
nsecs_t mLastTimestamp;
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index 74cfe42..1daa035 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -191,6 +191,14 @@
_hidl_cb(status, {});
return Void();
}
+ cameraStatusAndIds.erase(std::remove_if(cameraStatusAndIds.begin(), cameraStatusAndIds.end(),
+ [this](const hardware::CameraStatus& s) {
+ bool supportsHAL3 = false;
+ binder::Status sRet =
+ mAidlICameraService->supportsCameraApi(String16(s.cameraId),
+ hardware::ICameraService::API_VERSION_2, &supportsHAL3);
+ return !sRet.isOk() || !supportsHAL3;
+ }), cameraStatusAndIds.end());
hidl_vec<HCameraStatusAndId> hCameraStatusAndIds;
//Convert cameraStatusAndIds to HIDL and call callback
convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
diff --git a/services/mediacodec/registrant/Android.bp b/services/mediacodec/registrant/Android.bp
index fa5bc4a..765ac99 100644
--- a/services/mediacodec/registrant/Android.bp
+++ b/services/mediacodec/registrant/Android.bp
@@ -14,6 +14,7 @@
"libbase",
"libcodec2_hidl@1.0",
"libcodec2_vndk",
+ "libhidlbase",
"libutils",
],
diff --git a/services/mediacodec/registrant/CodecServiceRegistrant.cpp b/services/mediacodec/registrant/CodecServiceRegistrant.cpp
index 706ebee..7f7ceca 100644
--- a/services/mediacodec/registrant/CodecServiceRegistrant.cpp
+++ b/services/mediacodec/registrant/CodecServiceRegistrant.cpp
@@ -18,21 +18,411 @@
#define LOG_TAG "CodecServiceRegistrant"
#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <C2Component.h>
#include <C2PlatformSupport.h>
#include <codec2/hidl/1.0/ComponentStore.h>
+#include <codec2/hidl/1.0/Configurable.h>
+#include <codec2/hidl/1.0/types.h>
+#include <hidl/HidlSupport.h>
#include <media/CodecServiceRegistrant.h>
+namespace /* unnamed */ {
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using namespace ::android::hardware::media::c2::V1_0;
+using namespace ::android::hardware::media::c2::V1_0::utils;
+
+constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED;
+
+// Converter from IComponentStore to C2ComponentStore.
+class H2C2ComponentStore : public C2ComponentStore {
+protected:
+ sp<IComponentStore> mStore;
+ sp<IConfigurable> mConfigurable;
+public:
+ explicit H2C2ComponentStore(sp<IComponentStore> const& store)
+ : mStore{store},
+ mConfigurable{[store]() -> sp<IConfigurable>{
+ if (!store) {
+ return nullptr;
+ }
+ Return<sp<IConfigurable>> transResult =
+ store->getConfigurable();
+ return transResult.isOk() ?
+ static_cast<sp<IConfigurable>>(transResult) :
+ nullptr;
+ }()} {
+ if (!mConfigurable) {
+ LOG(ERROR) << "Preferred store is corrupted.";
+ }
+ }
+
+ virtual ~H2C2ComponentStore() override = default;
+
+ virtual c2_status_t config_sm(
+ std::vector<C2Param*> const ¶ms,
+ std::vector<std::unique_ptr<C2SettingResult>>* const failures
+ ) override {
+ Params hidlParams;
+ if (!createParamsBlob(&hidlParams, params)) {
+ LOG(ERROR) << "config -- bad input.";
+ return C2_TRANSACTION_FAILED;
+ }
+ c2_status_t status{};
+ Return<void> transResult = mConfigurable->config(
+ hidlParams,
+ true,
+ [&status, ¶ms, failures](
+ Status s,
+ const hidl_vec<SettingResult> f,
+ const Params& o) {
+ status = static_cast<c2_status_t>(s);
+ if (status != C2_OK && status != C2_BAD_INDEX) {
+ LOG(DEBUG) << "config -- call failed: "
+ << status << ".";
+ }
+ size_t i = failures->size();
+ failures->resize(i + f.size());
+ for (const SettingResult& sf : f) {
+ if (!objcpy(&(*failures)[i++], sf)) {
+ LOG(ERROR) << "config -- "
+ << "invalid SettingResult returned.";
+ return;
+ }
+ }
+ if (!updateParamsFromBlob(params, o)) {
+ LOG(ERROR) << "config -- "
+ << "failed to parse returned params.";
+ status = C2_CORRUPTED;
+ }
+ });
+ if (!transResult.isOk()) {
+ LOG(ERROR) << "config -- transaction failed.";
+ return C2_TRANSACTION_FAILED;
+ }
+ return status;
+ };
+
+ virtual c2_status_t copyBuffer(
+ std::shared_ptr<C2GraphicBuffer>,
+ std::shared_ptr<C2GraphicBuffer>) override {
+ LOG(ERROR) << "copyBuffer -- not supported.";
+ return C2_OMITTED;
+ }
+
+ virtual c2_status_t createComponent(
+ C2String, std::shared_ptr<C2Component> *const component) override {
+ component->reset();
+ LOG(ERROR) << "createComponent -- not supported.";
+ return C2_OMITTED;
+ }
+
+ virtual c2_status_t createInterface(
+ C2String, std::shared_ptr<C2ComponentInterface> *const interface) {
+ interface->reset();
+ LOG(ERROR) << "createInterface -- not supported.";
+ return C2_OMITTED;
+ }
+
+ virtual c2_status_t query_sm(
+ const std::vector<C2Param *> &stackParams,
+ const std::vector<C2Param::Index> &heapParamIndices,
+ std::vector<std::unique_ptr<C2Param>> *const heapParams) const
+ override {
+ hidl_vec<ParamIndex> indices(
+ stackParams.size() + heapParamIndices.size());
+ size_t numIndices = 0;
+ for (C2Param* const& stackParam : stackParams) {
+ if (!stackParam) {
+ LOG(WARNING) << "query -- null stack param encountered.";
+ continue;
+ }
+ indices[numIndices++] = static_cast<ParamIndex>(stackParam->index());
+ }
+ size_t numStackIndices = numIndices;
+ for (const C2Param::Index& index : heapParamIndices) {
+ indices[numIndices++] =
+ static_cast<ParamIndex>(static_cast<uint32_t>(index));
+ }
+ indices.resize(numIndices);
+ if (heapParams) {
+ heapParams->reserve(heapParams->size() + numIndices);
+ }
+ c2_status_t status;
+ Return<void> transResult = mConfigurable->query(
+ indices,
+ true,
+ [&status, &numStackIndices, &stackParams, heapParams](
+ Status s, const Params& p) {
+ status = static_cast<c2_status_t>(s);
+ if (status != C2_OK && status != C2_BAD_INDEX) {
+ LOG(DEBUG) << "query -- call failed: "
+ << status << ".";
+ return;
+ }
+ std::vector<C2Param*> paramPointers;
+ if (!parseParamsBlob(¶mPointers, p)) {
+ LOG(ERROR) << "query -- error while parsing params.";
+ status = C2_CORRUPTED;
+ return;
+ }
+ size_t i = 0;
+ for (auto it = paramPointers.begin();
+ it != paramPointers.end(); ) {
+ C2Param* paramPointer = *it;
+ if (numStackIndices > 0) {
+ --numStackIndices;
+ if (!paramPointer) {
+ LOG(WARNING) << "query -- null stack param.";
+ ++it;
+ continue;
+ }
+ for (; i < stackParams.size() && !stackParams[i]; ) {
+ ++i;
+ }
+ if (i >= stackParams.size()) {
+ LOG(ERROR) << "query -- unexpected error.";
+ status = C2_CORRUPTED;
+ return;
+ }
+ if (stackParams[i]->index() != paramPointer->index()) {
+ LOG(WARNING) << "query -- param skipped: "
+ "index = "
+ << stackParams[i]->index() << ".";
+ stackParams[i++]->invalidate();
+ continue;
+ }
+ if (!stackParams[i++]->updateFrom(*paramPointer)) {
+ LOG(WARNING) << "query -- param update failed: "
+ "index = "
+ << paramPointer->index() << ".";
+ }
+ } else {
+ if (!paramPointer) {
+ LOG(WARNING) << "query -- null heap param.";
+ ++it;
+ continue;
+ }
+ if (!heapParams) {
+ LOG(WARNING) << "query -- "
+ "unexpected extra stack param.";
+ } else {
+ heapParams->emplace_back(
+ C2Param::Copy(*paramPointer));
+ }
+ }
+ ++it;
+ }
+ });
+ if (!transResult.isOk()) {
+ LOG(ERROR) << "query -- transaction failed.";
+ return C2_TRANSACTION_FAILED;
+ }
+ return status;
+ }
+
+ virtual c2_status_t querySupportedParams_nb(
+ std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
+ c2_status_t status;
+ Return<void> transResult = mConfigurable->querySupportedParams(
+ std::numeric_limits<uint32_t>::min(),
+ std::numeric_limits<uint32_t>::max(),
+ [&status, params](
+ Status s,
+ const hidl_vec<ParamDescriptor>& p) {
+ status = static_cast<c2_status_t>(s);
+ if (status != C2_OK) {
+ LOG(DEBUG) << "querySupportedParams -- call failed: "
+ << status << ".";
+ return;
+ }
+ size_t i = params->size();
+ params->resize(i + p.size());
+ for (const ParamDescriptor& sp : p) {
+ if (!objcpy(&(*params)[i++], sp)) {
+ LOG(ERROR) << "querySupportedParams -- "
+ << "invalid returned ParamDescriptor.";
+ return;
+ }
+ }
+ });
+ if (!transResult.isOk()) {
+ LOG(ERROR) << "querySupportedParams -- transaction failed.";
+ return C2_TRANSACTION_FAILED;
+ }
+ return status;
+ }
+
+ virtual c2_status_t querySupportedValues_sm(
+ std::vector<C2FieldSupportedValuesQuery> &fields) const {
+ hidl_vec<FieldSupportedValuesQuery> inFields(fields.size());
+ for (size_t i = 0; i < fields.size(); ++i) {
+ if (!objcpy(&inFields[i], fields[i])) {
+ LOG(ERROR) << "querySupportedValues -- bad input";
+ return C2_TRANSACTION_FAILED;
+ }
+ }
+
+ c2_status_t status;
+ Return<void> transResult = mConfigurable->querySupportedValues(
+ inFields,
+ true,
+ [&status, &inFields, &fields](
+ Status s,
+ const hidl_vec<FieldSupportedValuesQueryResult>& r) {
+ status = static_cast<c2_status_t>(s);
+ if (status != C2_OK) {
+ LOG(DEBUG) << "querySupportedValues -- call failed: "
+ << status << ".";
+ return;
+ }
+ if (r.size() != fields.size()) {
+ LOG(ERROR) << "querySupportedValues -- "
+ "input and output lists "
+ "have different sizes.";
+ status = C2_CORRUPTED;
+ return;
+ }
+ for (size_t i = 0; i < fields.size(); ++i) {
+ if (!objcpy(&fields[i], inFields[i], r[i])) {
+ LOG(ERROR) << "querySupportedValues -- "
+ "invalid returned value.";
+ status = C2_CORRUPTED;
+ return;
+ }
+ }
+ });
+ if (!transResult.isOk()) {
+ LOG(ERROR) << "querySupportedValues -- transaction failed.";
+ return C2_TRANSACTION_FAILED;
+ }
+ return status;
+ }
+
+ virtual C2String getName() const {
+ C2String outName;
+ Return<void> transResult = mConfigurable->getName(
+ [&outName](const hidl_string& name) {
+ outName = name.c_str();
+ });
+ if (!transResult.isOk()) {
+ LOG(ERROR) << "getName -- transaction failed.";
+ }
+ return outName;
+ }
+
+ virtual std::shared_ptr<C2ParamReflector> getParamReflector() const
+ override {
+ struct SimpleParamReflector : public C2ParamReflector {
+ virtual std::unique_ptr<C2StructDescriptor> describe(
+ C2Param::CoreIndex coreIndex) const {
+ hidl_vec<ParamIndex> indices(1);
+ indices[0] = static_cast<ParamIndex>(coreIndex.coreIndex());
+ std::unique_ptr<C2StructDescriptor> descriptor;
+ Return<void> transResult = mBase->getStructDescriptors(
+ indices,
+ [&descriptor](
+ Status s,
+ const hidl_vec<StructDescriptor>& sd) {
+ c2_status_t status = static_cast<c2_status_t>(s);
+ if (status != C2_OK) {
+ LOG(DEBUG) << "SimpleParamReflector -- "
+ "getStructDescriptors() failed: "
+ << status << ".";
+ descriptor.reset();
+ return;
+ }
+ if (sd.size() != 1) {
+ LOG(DEBUG) << "SimpleParamReflector -- "
+ "getStructDescriptors() "
+ "returned vector of size "
+ << sd.size() << ". "
+ "It should be 1.";
+ descriptor.reset();
+ return;
+ }
+ if (!objcpy(&descriptor, sd[0])) {
+ LOG(DEBUG) << "SimpleParamReflector -- "
+ "getStructDescriptors() returned "
+ "corrupted data.";
+ descriptor.reset();
+ return;
+ }
+ });
+ return descriptor;
+ }
+
+ explicit SimpleParamReflector(sp<IComponentStore> base)
+ : mBase(base) { }
+
+ sp<IComponentStore> mBase;
+ };
+
+ return std::make_shared<SimpleParamReflector>(mStore);
+ }
+
+ virtual std::vector<std::shared_ptr<const C2Component::Traits>>
+ listComponents() override {
+ LOG(ERROR) << "listComponents -- not supported.";
+ return {};
+ }
+};
+
+bool ionPropertiesDefined() {
+ using namespace ::android::base;
+ std::string heapMask =
+ GetProperty("ro.com.android.media.swcodec.ion.heapmask", "undefined");
+ std::string flags =
+ GetProperty("ro.com.android.media.swcodec.ion.flags", "undefined");
+ std::string align =
+ GetProperty("ro.com.android.media.swcodec.ion.align", "undefined");
+ if (heapMask != "undefined" ||
+ flags != "undefined" ||
+ align != "undefined") {
+ LOG(INFO)
+ << "Some system properties for mediaswcodec ION usage are set: "
+ << "heapmask = " << heapMask << ", "
+ << "flags = " << flags << ", "
+ << "align = " << align << ". "
+ << "Preferred Codec2 store is defaulted to \"software\".";
+ return true;
+ }
+ return false;
+}
+
+} // unnamed namespace
+
extern "C" void RegisterCodecServices() {
- using namespace ::android::hardware::media::c2::V1_0;
+ using ComponentStore = ::android::hardware::media::c2::V1_0::utils::
+ ComponentStore;
LOG(INFO) << "Creating software Codec2 service...";
- android::sp<IComponentStore> store =
- new utils::ComponentStore(
- android::GetCodec2PlatformComponentStore());
+ sp<ComponentStore> store =
+ new ComponentStore(::android::GetCodec2PlatformComponentStore());
if (store == nullptr) {
LOG(ERROR) <<
"Cannot create software Codec2 service.";
} else {
+ if (!ionPropertiesDefined()) {
+ std::string preferredStoreName = "default";
+ sp<IComponentStore> preferredStore =
+ IComponentStore::getService(preferredStoreName.c_str());
+ if (preferredStore) {
+ ::android::SetPreferredCodec2ComponentStore(
+ std::make_shared<H2C2ComponentStore>(preferredStore));
+ LOG(INFO) <<
+ "Preferred Codec2 store is set to \"" <<
+ preferredStoreName << "\".";
+ } else {
+ LOG(INFO) <<
+ "Preferred Codec2 store is defaulted to \"software\".";
+ }
+ }
if (store->registerAsService("software") != android::OK) {
LOG(ERROR) <<
"Cannot register software Codec2 service.";