Merge "codec2: fix output delay update" into qt-dev
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 7cd832a..8dd6e00 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -7689,14 +7689,14 @@
* case, when the application configures a RAW stream, the camera device will make sure
* the active physical camera will remain active to ensure consistent RAW output
* behavior, and not switch to other physical cameras.</p>
- * <p>To maintain backward compatibility, the capture request and result metadata tags
- * required for basic camera functionalities will be solely based on the
- * logical camera capabiltity. Other request and result metadata tags, on the other
- * hand, will be based on current active physical camera. For example, the physical
- * cameras' sensor sensitivity and lens capability could be different from each other.
- * So when the application manually controls sensor exposure time/gain, or does manual
- * focus control, it must checks the current active physical camera's exposure, gain,
- * and focus distance range.</p>
+ * <p>The capture request and result metadata tags required for backward compatible camera
+ * functionalities will be solely based on the logical camera capabiltity. On the other
+ * hand, the use of manual capture controls (sensor or post-processing) with a
+ * logical camera may result in unexpected behavior when the HAL decides to switch
+ * between physical cameras with different characteristics under the hood. For example,
+ * when the application manually sets exposure time and sensitivity while zooming in,
+ * the brightness of the camera images may suddenly change because HAL switches from one
+ * physical camera to the other.</p>
*
* @see ACAMERA_LENS_DISTORTION
* @see ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION
@@ -8330,7 +8330,7 @@
* fire the flash for flash power metering during precapture, and then fire the flash
* for the final capture, if a flash is available on the device and the AE mode is set to
* enable the flash.</p>
- * <p>Devices that initially shipped with Android version <a href="https://developer.android.com/reference/android/os/Build.VERSION_CODES.html#Q">Q</a> or newer will not include any LEGACY-level devices.</p>
+ * <p>Devices that initially shipped with Android version <a href="https://developer.android.com/reference/android/os/Build/VERSION_CODES.html#Q">Q</a> or newer will not include any LEGACY-level devices.</p>
*
* @see ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER
* @see ACAMERA_REQUEST_AVAILABLE_CAPABILITIES
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.cpp b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
index 6509a88..6dab70b 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
@@ -127,14 +127,14 @@
}
switch (mBitrateMode->value) {
- case C2Config::BITRATE_VARIABLE:
- mBitrateControlMode = VPX_VBR;
- break;
case C2Config::BITRATE_CONST:
- default:
mBitrateControlMode = VPX_CBR;
break;
- break;
+ case C2Config::BITRATE_VARIABLE:
+ [[fallthrough]];
+ default:
+ mBitrateControlMode = VPX_VBR;
+ break;
}
setCodecSpecificInterface();
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.h b/media/codec2/components/vpx/C2SoftVpxEnc.h
index 90758f9..62ccd1b 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.h
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.h
@@ -275,7 +275,7 @@
addParameter(
DefineParam(mBitrateMode, C2_PARAMKEY_BITRATE_MODE)
.withDefault(new C2StreamBitrateModeTuning::output(
- 0u, C2Config::BITRATE_CONST))
+ 0u, C2Config::BITRATE_VARIABLE))
.withFields({
C2F(mBitrateMode, value).oneOf({
C2Config::BITRATE_CONST, C2Config::BITRATE_VARIABLE })
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/Android.bp b/media/codec2/hidl/1.0/vts/functional/audio/Android.bp
index 687754b..65f0d09 100644
--- a/media/codec2/hidl/1.0/vts/functional/audio/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/audio/Android.bp
@@ -15,19 +15,19 @@
*/
cc_test {
- name: "VtsHidlC2V1_0TargetAudioDecTest",
- defaults: ["VtsMediaC2V1_0Defaults"],
+ name: "VtsHalMediaC2V1_0TargetAudioDecTest",
+ defaults: ["VtsHalMediaC2V1_0Defaults"],
srcs: [
- "VtsHidlC2V1_0TargetAudioDecTest.cpp",
+ "VtsHalMediaC2V1_0TargetAudioDecTest.cpp",
//"media_audio_hidl_test_common.cpp"
],
}
cc_test {
- name: "VtsHidlC2V1_0TargetAudioEncTest",
- defaults: ["VtsMediaC2V1_0Defaults"],
+ name: "VtsHalMediaC2V1_0TargetAudioEncTest",
+ defaults: ["VtsHalMediaC2V1_0Defaults"],
srcs: [
- "VtsHidlC2V1_0TargetAudioEncTest.cpp",
+ "VtsHalMediaC2V1_0TargetAudioEncTest.cpp",
//"media_audio_hidl_test_common.cpp"
],
}
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
similarity index 100%
rename from media/codec2/hidl/1.0/vts/functional/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp
rename to media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
similarity index 100%
rename from media/codec2/hidl/1.0/vts/functional/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp
rename to media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
diff --git a/media/codec2/hidl/1.0/vts/functional/common/Android.bp b/media/codec2/hidl/1.0/vts/functional/common/Android.bp
index da0061a..a011ba3 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/common/Android.bp
@@ -1,5 +1,5 @@
cc_library_static {
- name: "VtsMediaC2V1_0CommonUtil",
+ name: "VtsHalMediaC2V1_0CommonUtil",
defaults: [
"VtsHalTargetTestDefaults",
"libcodec2-hidl-client-defaults",
@@ -17,14 +17,14 @@
}
cc_defaults {
- name: "VtsMediaC2V1_0Defaults",
+ name: "VtsHalMediaC2V1_0Defaults",
defaults: [
"VtsHalTargetTestDefaults",
"libcodec2-hidl-client-defaults",
],
static_libs: [
- "VtsMediaC2V1_0CommonUtil",
+ "VtsHalMediaC2V1_0CommonUtil",
],
shared_libs: [
diff --git a/media/codec2/hidl/1.0/vts/functional/common/README.md b/media/codec2/hidl/1.0/vts/functional/common/README.md
index 3deab10..50e8356 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/README.md
+++ b/media/codec2/hidl/1.0/vts/functional/common/README.md
@@ -3,29 +3,29 @@
#### master :
Functionality of master is to enumerate all the Codec2 components available in C2 media service.
-usage: VtsHidlC2V1\_0TargetMasterTest -I default
+usage: VtsHalMediaC2V1\_0TargetMasterTest -I default
#### component :
Functionality of component test is to validate common functionality across all the Codec2 components available in C2 media service. For a standard C2 component, these tests are expected to pass.
-usage: VtsHidlC2V1\_0TargetComponentTest -I software -C <comp name>
-example: VtsHidlC2V1\_0TargetComponentTest -I software -C c2.android.vorbis.decoder
+usage: VtsHalMediaC2V1\_0TargetComponentTest -I software -C <comp name>
+example: VtsHalMediaC2V1\_0TargetComponentTest -I software -C c2.android.vorbis.decoder
#### audio :
Functionality of audio test is to validate audio specific functionality Codec2 components. The resource files for this test are taken from media/codec2/hidl/1.0/vts/functional/res. The path to these files on the device is required to be given for bitstream tests.
-usage: VtsHidlC2V1\_0TargetAudioDecTest -I default -C <comp name> -P /sdcard/res/
-usage: VtsHidlC2V1\_0TargetAudioEncTest -I software -C <comp name> -P /sdcard/res/
+usage: VtsHalMediaC2V1\_0TargetAudioDecTest -I default -C <comp name> -P /sdcard/media/
+usage: VtsHalMediaC2V1\_0TargetAudioEncTest -I software -C <comp name> -P /sdcard/media/
-example: VtsHidlC2V1\_0TargetAudioDecTest -I software -C c2.android.flac.decoder -P /sdcard/res/
-example: VtsHidlC2V1\_0TargetAudioEncTest -I software -C c2.android.opus.encoder -P /sdcard/res/
+example: VtsHalMediaC2V1\_0TargetAudioDecTest -I software -C c2.android.flac.decoder -P /sdcard/media/
+example: VtsHalMediaC2V1\_0TargetAudioEncTest -I software -C c2.android.opus.encoder -P /sdcard/media/
#### video :
Functionality of video test is to validate video specific functionality Codec2 components. The resource files for this test are taken from media/codec2/hidl/1.0/vts/functional/res. The path to these files on the device is required to be given for bitstream tests.
-usage: VtsHidlC2V1\_0TargetVideoDecTest -I default -C <comp name> -P /sdcard/res/
-usage: VtsHidlC2V1\_0TargetVideoEncTest -I software -C <comp name> -P /sdcard/res/
+usage: VtsHalMediaC2V1\_0TargetVideoDecTest -I default -C <comp name> -P /sdcard/media/
+usage: VtsHalMediaC2V1\_0TargetVideoEncTest -I software -C <comp name> -P /sdcard/media/
-example: VtsHidlC2V1\_0TargetVideoDecTest -I software -C c2.android.avc.decoder -P /sdcard/res/
-example: VtsHidlC2V1\_0TargetVideoEncTest -I software -C c2.android.vp9.encoder -P /sdcard/res/
+example: VtsHalMediaC2V1\_0TargetVideoDecTest -I software -C c2.android.avc.decoder -P /sdcard/media/
+example: VtsHalMediaC2V1\_0TargetVideoEncTest -I software -C c2.android.vp9.encoder -P /sdcard/media/
diff --git a/media/codec2/hidl/1.0/vts/functional/component/Android.bp b/media/codec2/hidl/1.0/vts/functional/component/Android.bp
index 4b913b6..7ec64ee 100644
--- a/media/codec2/hidl/1.0/vts/functional/component/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/component/Android.bp
@@ -15,8 +15,8 @@
*/
cc_test {
- name: "VtsHidlC2V1_0TargetComponentTest",
- defaults: ["VtsMediaC2V1_0Defaults"],
- srcs: ["VtsHidlC2V1_0TargetComponentTest.cpp"],
+ name: "VtsHalMediaC2V1_0TargetComponentTest",
+ defaults: ["VtsHalMediaC2V1_0Defaults"],
+ srcs: ["VtsHalMediaC2V1_0TargetComponentTest.cpp"],
}
diff --git a/media/codec2/hidl/1.0/vts/functional/component/VtsHidlC2V1_0TargetComponentTest.cpp b/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
similarity index 100%
rename from media/codec2/hidl/1.0/vts/functional/component/VtsHidlC2V1_0TargetComponentTest.cpp
rename to media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
diff --git a/media/codec2/hidl/1.0/vts/functional/master/Android.bp b/media/codec2/hidl/1.0/vts/functional/master/Android.bp
index e164d68..53e323e 100644
--- a/media/codec2/hidl/1.0/vts/functional/master/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/master/Android.bp
@@ -15,8 +15,8 @@
*/
cc_test {
- name: "VtsHidlC2V1_0TargetMasterTest",
- defaults: ["VtsMediaC2V1_0Defaults"],
- srcs: ["VtsHidlC2V1_0TargetMasterTest.cpp"],
+ name: "VtsHalMediaC2V1_0TargetMasterTest",
+ defaults: ["VtsHalMediaC2V1_0Defaults"],
+ srcs: ["VtsHalMediaC2V1_0TargetMasterTest.cpp"],
}
diff --git a/media/codec2/hidl/1.0/vts/functional/master/VtsHidlC2V1_0TargetMasterTest.cpp b/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
similarity index 100%
rename from media/codec2/hidl/1.0/vts/functional/master/VtsHidlC2V1_0TargetMasterTest.cpp
rename to media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
diff --git a/media/codec2/hidl/1.0/vts/functional/video/Android.bp b/media/codec2/hidl/1.0/vts/functional/video/Android.bp
index 6e57ee7..b951306 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/video/Android.bp
@@ -15,14 +15,14 @@
*/
cc_test {
- name: "VtsHidlC2V1_0TargetVideoDecTest",
- defaults: ["VtsMediaC2V1_0Defaults"],
- srcs: ["VtsHidlC2V1_0TargetVideoDecTest.cpp"],
+ name: "VtsHalMeidaC2V1_0TargetVideoDecTest",
+ defaults: ["VtsHalMediaC2V1_0Defaults"],
+ srcs: ["VtsHalMediaC2V1_0TargetVideoDecTest.cpp"],
}
cc_test {
- name: "VtsHidlC2V1_0TargetVideoEncTest",
- defaults: ["VtsMediaC2V1_0Defaults"],
- srcs: ["VtsHidlC2V1_0TargetVideoEncTest.cpp"],
+ name: "VtsHalMediaC2V1_0TargetVideoEncTest",
+ defaults: ["VtsHalMediaC2V1_0Defaults"],
+ srcs: ["VtsHalMediaC2V1_0TargetVideoEncTest.cpp"],
}
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHidlC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
similarity index 100%
rename from media/codec2/hidl/1.0/vts/functional/video/VtsHidlC2V1_0TargetVideoDecTest.cpp
rename to media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHidlC2V1_0TargetVideoEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
similarity index 100%
rename from media/codec2/hidl/1.0/vts/functional/video/VtsHidlC2V1_0TargetVideoEncTest.cpp
rename to media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
diff --git a/media/codec2/sfplugin/C2OMXNode.cpp b/media/codec2/sfplugin/C2OMXNode.cpp
index 3a93c2a..d27fe32 100644
--- a/media/codec2/sfplugin/C2OMXNode.cpp
+++ b/media/codec2/sfplugin/C2OMXNode.cpp
@@ -36,6 +36,7 @@
#include <media/stagefright/MediaErrors.h>
#include <ui/Fence.h>
#include <ui/GraphicBuffer.h>
+#include <utils/Thread.h>
#include "C2OMXNode.h"
@@ -50,16 +51,126 @@
} // namespace
+class C2OMXNode::QueueThread : public Thread {
+public:
+ QueueThread() : Thread(false) {}
+ ~QueueThread() override = default;
+ void queue(
+ const std::shared_ptr<Codec2Client::Component> &comp,
+ int fenceFd,
+ std::unique_ptr<C2Work> &&work,
+ android::base::unique_fd &&fd0,
+ android::base::unique_fd &&fd1) {
+ Mutexed<Jobs>::Locked jobs(mJobs);
+ auto it = jobs->queues.try_emplace(comp, comp, systemTime()).first;
+ it->second.workList.emplace_back(
+ std::move(work), fenceFd, std::move(fd0), std::move(fd1));
+ jobs->cond.broadcast();
+ }
+
+protected:
+ bool threadLoop() override {
+ constexpr nsecs_t kIntervalNs = nsecs_t(10) * 1000 * 1000; // 10ms
+ constexpr nsecs_t kWaitNs = kIntervalNs * 2;
+ for (int i = 0; i < 2; ++i) {
+ Mutexed<Jobs>::Locked jobs(mJobs);
+ nsecs_t nowNs = systemTime();
+ bool queued = false;
+ for (auto it = jobs->queues.begin(); it != jobs->queues.end(); ++it) {
+ Queue &queue = it->second;
+ if (queue.workList.empty()
+ || nowNs - queue.lastQueuedTimestampNs < kIntervalNs) {
+ continue;
+ }
+ std::shared_ptr<Codec2Client::Component> comp = queue.component.lock();
+ if (!comp) {
+ it = jobs->queues.erase(it);
+ continue;
+ }
+ std::list<std::unique_ptr<C2Work>> items;
+ std::vector<int> fenceFds;
+ std::vector<android::base::unique_fd> uniqueFds;
+ while (!queue.workList.empty()) {
+ items.push_back(std::move(queue.workList.front().work));
+ fenceFds.push_back(queue.workList.front().fenceFd);
+ uniqueFds.push_back(std::move(queue.workList.front().fd0));
+ uniqueFds.push_back(std::move(queue.workList.front().fd1));
+ queue.workList.pop_front();
+ }
+
+ jobs.unlock();
+ for (int fenceFd : fenceFds) {
+ sp<Fence> fence(new Fence(fenceFd));
+ fence->waitForever(LOG_TAG);
+ }
+ comp->queue(&items);
+ for (android::base::unique_fd &ufd : uniqueFds) {
+ (void)ufd.release();
+ }
+ jobs.lock();
+
+ queued = true;
+ }
+ if (queued) {
+ return true;
+ }
+ if (i == 0) {
+ jobs.waitForConditionRelative(jobs->cond, kWaitNs);
+ }
+ }
+ return true;
+ }
+
+private:
+ struct WorkFence {
+ WorkFence(std::unique_ptr<C2Work> &&w, int fd) : work(std::move(w)), fenceFd(fd) {}
+
+ WorkFence(
+ std::unique_ptr<C2Work> &&w,
+ int fd,
+ android::base::unique_fd &&uniqueFd0,
+ android::base::unique_fd &&uniqueFd1)
+ : work(std::move(w)),
+ fenceFd(fd),
+ fd0(std::move(uniqueFd0)),
+ fd1(std::move(uniqueFd1)) {}
+
+ std::unique_ptr<C2Work> work;
+ int fenceFd;
+ android::base::unique_fd fd0;
+ android::base::unique_fd fd1;
+ };
+ struct Queue {
+ Queue(const std::shared_ptr<Codec2Client::Component> &comp, nsecs_t timestamp)
+ : component(comp), lastQueuedTimestampNs(timestamp) {}
+ Queue(const Queue &) = delete;
+ Queue &operator =(const Queue &) = delete;
+
+ std::weak_ptr<Codec2Client::Component> component;
+ std::list<WorkFence> workList;
+ nsecs_t lastQueuedTimestampNs;
+ };
+ struct Jobs {
+ std::map<std::weak_ptr<Codec2Client::Component>,
+ Queue,
+ std::owner_less<std::weak_ptr<Codec2Client::Component>>> queues;
+ Condition cond;
+ };
+ Mutexed<Jobs> mJobs;
+};
+
C2OMXNode::C2OMXNode(const std::shared_ptr<Codec2Client::Component> &comp)
: mComp(comp), mFrameIndex(0), mWidth(0), mHeight(0), mUsage(0),
- mAdjustTimestampGapUs(0), mFirstInputFrame(true) {
+ mAdjustTimestampGapUs(0), mFirstInputFrame(true),
+ mQueueThread(new QueueThread) {
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS);
+ mQueueThread->run("C2OMXNode", PRIORITY_AUDIO);
}
status_t C2OMXNode::freeNode() {
mComp.reset();
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
- return OK;
+ return mQueueThread->requestExitAndWait();
}
status_t C2OMXNode::sendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param) {
@@ -216,11 +327,6 @@
status_t C2OMXNode::emptyBuffer(
buffer_id buffer, const OMXBuffer &omxBuf,
OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
- // TODO: better fence handling
- if (fenceFd >= 0) {
- sp<Fence> fence = new Fence(fenceFd);
- fence->waitForever(LOG_TAG);
- }
std::shared_ptr<Codec2Client::Component> comp = mComp.lock();
if (!comp) {
return NO_INIT;
@@ -299,22 +405,8 @@
}
work->worklets.clear();
work->worklets.emplace_back(new C2Worklet);
- std::list<std::unique_ptr<C2Work>> items;
- uint64_t index = work->input.ordinal.frameIndex.peeku();
- items.push_back(std::move(work));
-
- c2_status_t err = comp->queue(&items);
- if (err != C2_OK) {
- (void)fd0.release();
- (void)fd1.release();
- return UNKNOWN_ERROR;
- }
-
- mBufferIdsInUse.lock()->emplace(index, buffer);
-
- // release ownership of the fds
- (void)fd0.release();
- (void)fd1.release();
+ mBufferIdsInUse.lock()->emplace(work->input.ordinal.frameIndex.peeku(), buffer);
+ mQueueThread->queue(comp, fenceFd, std::move(work), std::move(fd0), std::move(fd1));
return OK;
}
diff --git a/media/codec2/sfplugin/C2OMXNode.h b/media/codec2/sfplugin/C2OMXNode.h
index 3ca6c0a..1717c96 100644
--- a/media/codec2/sfplugin/C2OMXNode.h
+++ b/media/codec2/sfplugin/C2OMXNode.h
@@ -113,6 +113,9 @@
c2_cntr64_t mPrevCodecTimestamp; // adjusted (codec) timestamp for previous frame
Mutexed<std::map<uint64_t, buffer_id>> mBufferIdsInUse;
+
+ class QueueThread;
+ sp<QueueThread> mQueueThread;
};
} // namespace android
diff --git a/media/codec2/vndk/Android.bp b/media/codec2/vndk/Android.bp
index ca69810..b6ddfab 100644
--- a/media/codec2/vndk/Android.bp
+++ b/media/codec2/vndk/Android.bp
@@ -50,8 +50,10 @@
shared_libs: [
"android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.bufferqueue@2.0",
"android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@3.0",
"android.hardware.media.bufferpool@2.0",
"libbase",
"libbinder",
diff --git a/media/codec2/vndk/C2AllocatorGralloc.cpp b/media/codec2/vndk/C2AllocatorGralloc.cpp
index 286c48a..af97e61 100644
--- a/media/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/codec2/vndk/C2AllocatorGralloc.cpp
@@ -20,6 +20,8 @@
#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
#include <cutils/native_handle.h>
#include <hardware/gralloc.h>
@@ -29,7 +31,7 @@
namespace android {
-namespace {
+namespace /* unnamed */ {
enum : uint64_t {
/**
* Usage mask that is passed through from gralloc to Codec 2.0 usage.
@@ -40,7 +42,7 @@
// verify that passthrough mask is within the platform mask
static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
-}
+} // unnamed
C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
// gralloc does not support WRITE_PROTECTED
@@ -59,39 +61,59 @@
(expected & PASSTHROUGH_USAGE_MASK));
}
-using ::android::hardware::graphics::allocator::V2_0::IAllocator;
-using ::android::hardware::graphics::common::V1_0::BufferUsage;
-using ::android::hardware::graphics::common::V1_0::PixelFormat;
-using ::android::hardware::graphics::mapper::V2_0::BufferDescriptor;
-using ::android::hardware::graphics::mapper::V2_0::Error;
-using ::android::hardware::graphics::mapper::V2_0::IMapper;
-using ::android::hardware::graphics::mapper::V2_0::YCbCrLayout;
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_vec;
+using ::android::hardware::graphics::common::V1_0::BufferUsage;
+using PixelFormat2 = ::android::hardware::graphics::common::V1_0::PixelFormat;
+using PixelFormat3 = ::android::hardware::graphics::common::V1_2::PixelFormat;
-namespace {
+using IAllocator2 = ::android::hardware::graphics::allocator::V2_0::IAllocator;
+using BufferDescriptor2 = ::android::hardware::graphics::mapper::V2_0::BufferDescriptor;
+using Error2 = ::android::hardware::graphics::mapper::V2_0::Error;
+using IMapper2 = ::android::hardware::graphics::mapper::V2_0::IMapper;
-struct BufferDescriptorInfo {
- IMapper::BufferDescriptorInfo mapperInfo;
+using IAllocator3 = ::android::hardware::graphics::allocator::V3_0::IAllocator;
+using BufferDescriptor3 = ::android::hardware::graphics::mapper::V3_0::BufferDescriptor;
+using Error3 = ::android::hardware::graphics::mapper::V3_0::Error;
+using IMapper3 = ::android::hardware::graphics::mapper::V3_0::IMapper;
+
+namespace /* unnamed */ {
+
+struct BufferDescriptorInfo2 {
+ IMapper2::BufferDescriptorInfo mapperInfo;
uint32_t stride;
};
-}
+struct BufferDescriptorInfo3 {
+ IMapper3::BufferDescriptorInfo mapperInfo;
+ uint32_t stride;
+};
/* ===================================== GRALLOC ALLOCATION ==================================== */
-static c2_status_t maperr2error(Error maperr) {
+c2_status_t maperr2error(Error2 maperr) {
switch (maperr) {
- case Error::NONE: return C2_OK;
- case Error::BAD_DESCRIPTOR: return C2_BAD_VALUE;
- case Error::BAD_BUFFER: return C2_BAD_VALUE;
- case Error::BAD_VALUE: return C2_BAD_VALUE;
- case Error::NO_RESOURCES: return C2_NO_MEMORY;
- case Error::UNSUPPORTED: return C2_CANNOT_DO;
+ case Error2::NONE: return C2_OK;
+ case Error2::BAD_DESCRIPTOR: return C2_BAD_VALUE;
+ case Error2::BAD_BUFFER: return C2_BAD_VALUE;
+ case Error2::BAD_VALUE: return C2_BAD_VALUE;
+ case Error2::NO_RESOURCES: return C2_NO_MEMORY;
+ case Error2::UNSUPPORTED: return C2_CANNOT_DO;
}
return C2_CORRUPTED;
}
-static
+c2_status_t maperr2error(Error3 maperr) {
+ switch (maperr) {
+ case Error3::NONE: return C2_OK;
+ case Error3::BAD_DESCRIPTOR: return C2_BAD_VALUE;
+ case Error3::BAD_BUFFER: return C2_BAD_VALUE;
+ case Error3::BAD_VALUE: return C2_BAD_VALUE;
+ case Error3::NO_RESOURCES: return C2_NO_MEMORY;
+ case Error3::UNSUPPORTED: return C2_CANNOT_DO;
+ }
+ return C2_CORRUPTED;
+}
+
bool native_handle_is_invalid(const native_handle_t *const handle) {
// perform basic validation of a native handle
if (handle == nullptr) {
@@ -230,23 +252,6 @@
return res;
}
- static native_handle_t* UnwrapNativeHandle(
- const C2Handle *const handle,
- uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
- const ExtraData *xd = getExtraData(handle);
- if (xd == nullptr || xd->magic != MAGIC) {
- return nullptr;
- }
- *generation = xd->generation;
- *igbp_id = unsigned(xd->igbp_id_lo) | uint64_t(unsigned(xd->igbp_id_hi)) << 32;
- *igbp_slot = xd->igbp_slot;
- native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
- if (res != nullptr) {
- memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
- }
- return res;
- }
-
static const C2HandleGralloc* Import(
const C2Handle *const handle,
uint32_t *width, uint32_t *height, uint32_t *format,
@@ -268,16 +273,12 @@
}
};
+} // unnamed namespace
+
native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
return C2HandleGralloc::UnwrapNativeHandle(handle);
}
-native_handle_t *UnwrapNativeCodec2GrallocHandle(
- const C2Handle *const handle,
- uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
- return C2HandleGralloc::UnwrapNativeHandle(handle, generation, igbp_id, igbp_slot);
-}
-
C2Handle *WrapNativeCodec2GrallocHandle(
const native_handle_t *const handle,
uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
@@ -309,8 +310,14 @@
// internal methods
// |handle| will be moved.
C2AllocationGralloc(
- const BufferDescriptorInfo &info,
- const sp<IMapper> &mapper,
+ const BufferDescriptorInfo2 &info,
+ const sp<IMapper2> &mapper,
+ hidl_handle &hidlHandle,
+ const C2HandleGralloc *const handle,
+ C2Allocator::id_t allocatorId);
+ C2AllocationGralloc(
+ const BufferDescriptorInfo3 &info,
+ const sp<IMapper3> &mapper,
hidl_handle &hidlHandle,
const C2HandleGralloc *const handle,
C2Allocator::id_t allocatorId);
@@ -318,8 +325,10 @@
c2_status_t status() const;
private:
- const BufferDescriptorInfo mInfo;
- const sp<IMapper> mMapper;
+ const BufferDescriptorInfo2 mInfo2{};
+ const sp<IMapper2> mMapper2{nullptr};
+ const BufferDescriptorInfo3 mInfo3{};
+ const sp<IMapper3> mMapper3{nullptr};
const hidl_handle mHidlHandle;
const C2HandleGralloc *mHandle;
buffer_handle_t mBuffer;
@@ -330,14 +339,31 @@
};
C2AllocationGralloc::C2AllocationGralloc(
- const BufferDescriptorInfo &info,
- const sp<IMapper> &mapper,
+ const BufferDescriptorInfo2 &info,
+ const sp<IMapper2> &mapper,
hidl_handle &hidlHandle,
const C2HandleGralloc *const handle,
C2Allocator::id_t allocatorId)
: C2GraphicAllocation(info.mapperInfo.width, info.mapperInfo.height),
- mInfo(info),
- mMapper(mapper),
+ mInfo2(info),
+ mMapper2(mapper),
+ mHidlHandle(std::move(hidlHandle)),
+ mHandle(handle),
+ mBuffer(nullptr),
+ mLockedHandle(nullptr),
+ mLocked(false),
+ mAllocatorId(allocatorId) {
+}
+
+C2AllocationGralloc::C2AllocationGralloc(
+ const BufferDescriptorInfo3 &info,
+ const sp<IMapper3> &mapper,
+ hidl_handle &hidlHandle,
+ const C2HandleGralloc *const handle,
+ C2Allocator::id_t allocatorId)
+ : C2GraphicAllocation(info.mapperInfo.width, info.mapperInfo.height),
+ mInfo3(info),
+ mMapper3(mapper),
mHidlHandle(std::move(hidlHandle)),
mHandle(handle),
mBuffer(nullptr),
@@ -353,7 +379,17 @@
unmap(addr, C2Rect(), nullptr);
}
if (mBuffer) {
- mMapper->freeBuffer(const_cast<native_handle_t *>(mBuffer));
+ if (mMapper2) {
+ if (!mMapper2->freeBuffer(const_cast<native_handle_t *>(
+ mBuffer)).isOk()) {
+ ALOGE("failed transaction: freeBuffer");
+ }
+ } else {
+ if (!mMapper3->freeBuffer(const_cast<native_handle_t *>(
+ mBuffer)).isOk()) {
+ ALOGE("failed transaction: freeBuffer");
+ }
+ }
}
if (mHandle) {
native_handle_delete(
@@ -388,13 +424,29 @@
c2_status_t err = C2_OK;
if (!mBuffer) {
- mMapper->importBuffer(
- mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) {
- err = maperr2error(maperr);
- if (err == C2_OK) {
- mBuffer = static_cast<buffer_handle_t>(buffer);
- }
- });
+ if (mMapper2) {
+ if (!mMapper2->importBuffer(
+ mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) {
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ mBuffer = static_cast<buffer_handle_t>(buffer);
+ }
+ }).isOk()) {
+ ALOGE("failed transaction: importBuffer");
+ return C2_CORRUPTED;
+ }
+ } else {
+ if (!mMapper3->importBuffer(
+ mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) {
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ mBuffer = static_cast<buffer_handle_t>(buffer);
+ }
+ }).isOk()) {
+ ALOGE("failed transaction: importBuffer (@3.0)");
+ return C2_CORRUPTED;
+ }
+ }
if (err != C2_OK) {
ALOGD("importBuffer failed: %d", err);
return err;
@@ -409,30 +461,66 @@
if (mHandle) {
mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot);
}
- mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
- mBuffer, mInfo.mapperInfo.width, mInfo.mapperInfo.height,
- (uint32_t)mInfo.mapperInfo.format, mInfo.mapperInfo.usage, mInfo.stride,
- generation, igbp_id, igbp_slot);
+ if (mMapper2) {
+ mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
+ mBuffer, mInfo2.mapperInfo.width, mInfo2.mapperInfo.height,
+ (uint32_t)mInfo2.mapperInfo.format, mInfo2.mapperInfo.usage,
+ mInfo2.stride, generation, igbp_id, igbp_slot);
+ } else {
+ mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
+ mBuffer, mInfo3.mapperInfo.width, mInfo3.mapperInfo.height,
+ (uint32_t)mInfo3.mapperInfo.format, mInfo3.mapperInfo.usage,
+ mInfo3.stride, generation, igbp_id, igbp_slot);
+ }
}
- switch (mInfo.mapperInfo.format) {
- case PixelFormat::RGBA_1010102: {
+ PixelFormat3 format = mMapper2 ?
+ PixelFormat3(mInfo2.mapperInfo.format) :
+ PixelFormat3(mInfo3.mapperInfo.format);
+ switch (format) {
+ case PixelFormat3::RGBA_1010102: {
// TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
// Surface. In all other cases it is RGBA. We don't know which case it is here, so
// default to YUV for now.
void *pointer = nullptr;
- mMapper->lock(
- const_cast<native_handle_t *>(mBuffer),
- grallocUsage,
- { (int32_t)rect.left, (int32_t)rect.top, (int32_t)rect.width, (int32_t)rect.height },
- // TODO: fence
- hidl_handle(),
- [&err, &pointer](const auto &maperr, const auto &mapPointer) {
- err = maperr2error(maperr);
- if (err == C2_OK) {
- pointer = mapPointer;
- }
- });
+ if (mMapper2) {
+ if (!mMapper2->lock(
+ const_cast<native_handle_t *>(mBuffer),
+ grallocUsage,
+ { (int32_t)rect.left, (int32_t)rect.top,
+ (int32_t)rect.width, (int32_t)rect.height },
+ // TODO: fence
+ hidl_handle(),
+ [&err, &pointer](const auto &maperr, const auto &mapPointer) {
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ pointer = mapPointer;
+ }
+ }).isOk()) {
+ ALOGE("failed transaction: lock(RGBA_1010102)");
+ return C2_CORRUPTED;
+ }
+ } else {
+ if (!mMapper3->lock(
+ const_cast<native_handle_t *>(mBuffer),
+ grallocUsage,
+ { (int32_t)rect.left, (int32_t)rect.top,
+ (int32_t)rect.width, (int32_t)rect.height },
+ // TODO: fence
+ hidl_handle(),
+ [&err, &pointer](const auto &maperr, const auto &mapPointer,
+ int32_t bytesPerPixel, int32_t bytesPerStride) {
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ pointer = mapPointer;
+ }
+ (void)bytesPerPixel;
+ (void)bytesPerStride;
+ }).isOk()) {
+ ALOGE("failed transaction: lock(RGBA_1010102) (@3.0)");
+ return C2_CORRUPTED;
+ }
+ }
if (err != C2_OK) {
ALOGD("lock failed: %d", err);
return err;
@@ -445,10 +533,13 @@
layout->type = C2PlanarLayout::TYPE_YUVA;
layout->numPlanes = 4;
layout->rootPlanes = 1;
+ int32_t stride = mMapper2 ?
+ int32_t(mInfo2.stride) :
+ int32_t(mInfo3.stride);
layout->planes[C2PlanarLayout::PLANE_Y] = {
C2PlaneInfo::CHANNEL_Y, // channel
4, // colInc
- 4 * (int32_t)mInfo.stride, // rowInc
+ 4 * stride, // rowInc
1, // mColSampling
1, // mRowSampling
32, // allocatedDepth
@@ -461,7 +552,7 @@
layout->planes[C2PlanarLayout::PLANE_U] = {
C2PlaneInfo::CHANNEL_CB, // channel
4, // colInc
- 4 * (int32_t)mInfo.stride, // rowInc
+ 4 * stride, // rowInc
1, // mColSampling
1, // mRowSampling
32, // allocatedDepth
@@ -474,7 +565,7 @@
layout->planes[C2PlanarLayout::PLANE_V] = {
C2PlaneInfo::CHANNEL_CR, // channel
4, // colInc
- 4 * (int32_t)mInfo.stride, // rowInc
+ 4 * stride, // rowInc
1, // mColSampling
1, // mRowSampling
32, // allocatedDepth
@@ -487,7 +578,7 @@
layout->planes[C2PlanarLayout::PLANE_A] = {
C2PlaneInfo::CHANNEL_A, // channel
4, // colInc
- 4 * (int32_t)mInfo.stride, // rowInc
+ 4 * stride, // rowInc
1, // mColSampling
1, // mRowSampling
32, // allocatedDepth
@@ -500,23 +591,49 @@
break;
}
- case PixelFormat::RGBA_8888:
+ case PixelFormat3::RGBA_8888:
// TODO: alpha channel
// fall-through
- case PixelFormat::RGBX_8888: {
+ case PixelFormat3::RGBX_8888: {
void *pointer = nullptr;
- mMapper->lock(
- const_cast<native_handle_t *>(mBuffer),
- grallocUsage,
- { (int32_t)rect.left, (int32_t)rect.top, (int32_t)rect.width, (int32_t)rect.height },
- // TODO: fence
- hidl_handle(),
- [&err, &pointer](const auto &maperr, const auto &mapPointer) {
- err = maperr2error(maperr);
- if (err == C2_OK) {
- pointer = mapPointer;
- }
- });
+ if (mMapper2) {
+ if (!mMapper2->lock(
+ const_cast<native_handle_t *>(mBuffer),
+ grallocUsage,
+ { (int32_t)rect.left, (int32_t)rect.top,
+ (int32_t)rect.width, (int32_t)rect.height },
+ // TODO: fence
+ hidl_handle(),
+ [&err, &pointer](const auto &maperr, const auto &mapPointer) {
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ pointer = mapPointer;
+ }
+ }).isOk()) {
+ ALOGE("failed transaction: lock(RGBA_8888)");
+ return C2_CORRUPTED;
+ }
+ } else {
+ if (!mMapper3->lock(
+ const_cast<native_handle_t *>(mBuffer),
+ grallocUsage,
+ { (int32_t)rect.left, (int32_t)rect.top,
+ (int32_t)rect.width, (int32_t)rect.height },
+ // TODO: fence
+ hidl_handle(),
+ [&err, &pointer](const auto &maperr, const auto &mapPointer,
+ int32_t bytesPerPixel, int32_t bytesPerStride) {
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ pointer = mapPointer;
+ }
+ (void)bytesPerPixel;
+ (void)bytesPerStride;
+ }).isOk()) {
+ ALOGE("failed transaction: lock(RGBA_8888) (@3.0)");
+ return C2_CORRUPTED;
+ }
+ }
if (err != C2_OK) {
ALOGD("lock failed: %d", err);
return err;
@@ -527,10 +644,13 @@
layout->type = C2PlanarLayout::TYPE_RGB;
layout->numPlanes = 3;
layout->rootPlanes = 1;
+ int32_t stride = mMapper2 ?
+ int32_t(mInfo2.stride) :
+ int32_t(mInfo3.stride);
layout->planes[C2PlanarLayout::PLANE_R] = {
C2PlaneInfo::CHANNEL_R, // channel
4, // colInc
- 4 * (int32_t)mInfo.stride, // rowInc
+ 4 * stride, // rowInc
1, // mColSampling
1, // mRowSampling
8, // allocatedDepth
@@ -543,7 +663,7 @@
layout->planes[C2PlanarLayout::PLANE_G] = {
C2PlaneInfo::CHANNEL_G, // channel
4, // colInc
- 4 * (int32_t)mInfo.stride, // rowInc
+ 4 * stride, // rowInc
1, // mColSampling
1, // mRowSampling
8, // allocatedDepth
@@ -556,7 +676,7 @@
layout->planes[C2PlanarLayout::PLANE_B] = {
C2PlaneInfo::CHANNEL_B, // channel
4, // colInc
- 4 * (int32_t)mInfo.stride, // rowInc
+ 4 * stride, // rowInc
1, // mColSampling
1, // mRowSampling
8, // allocatedDepth
@@ -569,23 +689,65 @@
break;
}
- case PixelFormat::YCBCR_420_888:
+ case PixelFormat3::YCBCR_420_888:
// fall-through
- case PixelFormat::YV12:
+ case PixelFormat3::YV12:
// fall-through
default: {
+ struct YCbCrLayout {
+ void* y;
+ void* cb;
+ void* cr;
+ uint32_t yStride;
+ uint32_t cStride;
+ uint32_t chromaStep;
+ };
YCbCrLayout ycbcrLayout;
- mMapper->lockYCbCr(
- const_cast<native_handle_t *>(mBuffer), grallocUsage,
- { (int32_t)rect.left, (int32_t)rect.top, (int32_t)rect.width, (int32_t)rect.height },
- // TODO: fence
- hidl_handle(),
- [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
- err = maperr2error(maperr);
- if (err == C2_OK) {
- ycbcrLayout = mapLayout;
- }
- });
+ if (mMapper2) {
+ if (!mMapper2->lockYCbCr(
+ const_cast<native_handle_t *>(mBuffer), grallocUsage,
+ { (int32_t)rect.left, (int32_t)rect.top,
+ (int32_t)rect.width, (int32_t)rect.height },
+ // TODO: fence
+ hidl_handle(),
+ [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ ycbcrLayout = YCbCrLayout{
+ mapLayout.y,
+ mapLayout.cb,
+ mapLayout.cr,
+ mapLayout.yStride,
+ mapLayout.cStride,
+ mapLayout.chromaStep};
+ }
+ }).isOk()) {
+ ALOGE("failed transaction: lockYCbCr");
+ return C2_CORRUPTED;
+ }
+ } else {
+ if (!mMapper3->lockYCbCr(
+ const_cast<native_handle_t *>(mBuffer), grallocUsage,
+ { (int32_t)rect.left, (int32_t)rect.top,
+ (int32_t)rect.width, (int32_t)rect.height },
+ // TODO: fence
+ hidl_handle(),
+ [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ ycbcrLayout = YCbCrLayout{
+ mapLayout.y,
+ mapLayout.cb,
+ mapLayout.cr,
+ mapLayout.yStride,
+ mapLayout.cStride,
+ mapLayout.chromaStep};
+ }
+ }).isOk()) {
+ ALOGE("failed transaction: lockYCbCr (@3.0)");
+ return C2_CORRUPTED;
+ }
+ }
if (err != C2_OK) {
ALOGD("lockYCbCr failed: %d", err);
return err;
@@ -662,17 +824,37 @@
std::lock_guard<std::mutex> lock(mMappedLock);
c2_status_t err = C2_OK;
- mMapper->unlock(
- const_cast<native_handle_t *>(mBuffer),
- [&err, &fence](const auto &maperr, const auto &releaseFence) {
- // TODO
- (void) fence;
- (void) releaseFence;
- err = maperr2error(maperr);
- if (err == C2_OK) {
- // TODO: fence
- }
- });
+ if (mMapper2) {
+ if (!mMapper2->unlock(
+ const_cast<native_handle_t *>(mBuffer),
+ [&err, &fence](const auto &maperr, const auto &releaseFence) {
+ // TODO
+ (void) fence;
+ (void) releaseFence;
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ // TODO: fence
+ }
+ }).isOk()) {
+ ALOGE("failed transaction: unlock");
+ return C2_CORRUPTED;
+ }
+ } else {
+ if (!mMapper3->unlock(
+ const_cast<native_handle_t *>(mBuffer),
+ [&err, &fence](const auto &maperr, const auto &releaseFence) {
+ // TODO
+ (void) fence;
+ (void) releaseFence;
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ // TODO: fence
+ }
+ }).isOk()) {
+ ALOGE("failed transaction: unlock (@3.0)");
+ return C2_CORRUPTED;
+ }
+ }
if (err == C2_OK) {
mLocked = false;
}
@@ -713,8 +895,10 @@
private:
std::shared_ptr<C2Allocator::Traits> mTraits;
c2_status_t mInit;
- sp<IAllocator> mAllocator;
- sp<IMapper> mMapper;
+ sp<IAllocator2> mAllocator2;
+ sp<IMapper2> mMapper2;
+ sp<IAllocator3> mAllocator3;
+ sp<IMapper3> mMapper3;
const bool mBufferQueue;
};
@@ -734,10 +918,18 @@
mTraits = std::make_shared<C2Allocator::Traits>(traits);
// gralloc allocator is a singleton, so all objects share a global service
- mAllocator = IAllocator::getService();
- mMapper = IMapper::getService();
- if (mAllocator == nullptr || mMapper == nullptr) {
- mInit = C2_CORRUPTED;
+ mAllocator3 = IAllocator3::getService();
+ mMapper3 = IMapper3::getService();
+ if (!mAllocator3 || !mMapper3) {
+ mAllocator3 = nullptr;
+ mMapper3 = nullptr;
+ mAllocator2 = IAllocator2::getService();
+ mMapper2 = IMapper2::getService();
+ if (!mAllocator2 || !mMapper2) {
+ mAllocator2 = nullptr;
+ mMapper2 = nullptr;
+ mInit = C2_CORRUPTED;
+ }
}
}
@@ -748,84 +940,176 @@
ALOGV("allocating buffer with usage %#llx => %#llx",
(long long)usage.expected, (long long)grallocUsage);
- BufferDescriptorInfo info = {
- {
- width,
- height,
- 1u, // layerCount
- (PixelFormat)format,
- grallocUsage,
- },
- 0u, // stride placeholder
- };
c2_status_t err = C2_OK;
- BufferDescriptor desc;
- mMapper->createDescriptor(
- info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
- err = maperr2error(maperr);
- if (err == C2_OK) {
- desc = descriptor;
- }
- });
- if (err != C2_OK) {
- return err;
+ hidl_handle buffer{};
+
+ if (mMapper2) {
+ BufferDescriptorInfo2 info = {
+ {
+ width,
+ height,
+ 1u, // layerCount
+ PixelFormat2(format),
+ grallocUsage,
+ },
+ 0u, // stride placeholder
+ };
+ BufferDescriptor2 desc;
+ if (!mMapper2->createDescriptor(
+ info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ desc = descriptor;
+ }
+ }).isOk()) {
+ ALOGE("failed transaction: createDescriptor");
+ return C2_CORRUPTED;
+ }
+ if (err != C2_OK) {
+ return err;
+ }
+
+ // IAllocator shares IMapper error codes.
+ if (!mAllocator2->allocate(
+ desc,
+ 1u,
+ [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
+ err = maperr2error(maperr);
+ if (err != C2_OK) {
+ return;
+ }
+ if (buffers.size() != 1u) {
+ err = C2_CORRUPTED;
+ return;
+ }
+ info.stride = stride;
+ buffer = buffers[0];
+ }).isOk()) {
+ ALOGE("failed transaction: allocate");
+ return C2_CORRUPTED;
+ }
+ if (err != C2_OK) {
+ return err;
+ }
+ allocation->reset(new C2AllocationGralloc(
+ info, mMapper2, buffer,
+ C2HandleGralloc::WrapAndMoveNativeHandle(
+ buffer.getNativeHandle(),
+ width, height,
+ format, grallocUsage, info.stride,
+ 0, 0, mBufferQueue ? ~0 : 0),
+ mTraits->id));
+ return C2_OK;
+ } else {
+ BufferDescriptorInfo3 info = {
+ {
+ width,
+ height,
+ 1u, // layerCount
+ PixelFormat3(format),
+ grallocUsage,
+ },
+ 0u, // stride placeholder
+ };
+ BufferDescriptor3 desc;
+ if (!mMapper3->createDescriptor(
+ info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
+ err = maperr2error(maperr);
+ if (err == C2_OK) {
+ desc = descriptor;
+ }
+ }).isOk()) {
+ ALOGE("failed transaction: createDescriptor");
+ return C2_CORRUPTED;
+ }
+ if (err != C2_OK) {
+ return err;
+ }
+
+ // IAllocator shares IMapper error codes.
+ if (!mAllocator3->allocate(
+ desc,
+ 1u,
+ [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
+ err = maperr2error(maperr);
+ if (err != C2_OK) {
+ return;
+ }
+ if (buffers.size() != 1u) {
+ err = C2_CORRUPTED;
+ return;
+ }
+ info.stride = stride;
+ buffer = buffers[0];
+ }).isOk()) {
+ ALOGE("failed transaction: allocate");
+ return C2_CORRUPTED;
+ }
+ if (err != C2_OK) {
+ return err;
+ }
+ allocation->reset(new C2AllocationGralloc(
+ info, mMapper3, buffer,
+ C2HandleGralloc::WrapAndMoveNativeHandle(
+ buffer.getNativeHandle(),
+ width, height,
+ format, grallocUsage, info.stride,
+ 0, 0, mBufferQueue ? ~0 : 0),
+ mTraits->id));
+ return C2_OK;
}
-
- // IAllocator shares IMapper error codes.
- hidl_handle buffer;
- mAllocator->allocate(
- desc,
- 1u,
- [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
- err = maperr2error(maperr);
- if (err != C2_OK) {
- return;
- }
- if (buffers.size() != 1u) {
- err = C2_CORRUPTED;
- return;
- }
- info.stride = stride;
- buffer = buffers[0];
- });
- if (err != C2_OK) {
- return err;
- }
-
-
- allocation->reset(new C2AllocationGralloc(
- info, mMapper, buffer,
- C2HandleGralloc::WrapAndMoveNativeHandle(
- buffer.getNativeHandle(),
- info.mapperInfo.width, info.mapperInfo.height,
- (uint32_t)info.mapperInfo.format, info.mapperInfo.usage, info.stride,
- 0, 0, mBufferQueue ? ~0 : 0),
- mTraits->id));
- return C2_OK;
}
c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
const C2Handle *handle,
std::shared_ptr<C2GraphicAllocation> *allocation) {
- BufferDescriptorInfo info;
- info.mapperInfo.layerCount = 1u;
- uint32_t generation;
- uint64_t igbp_id;
- uint32_t igbp_slot;
- const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
- handle,
- &info.mapperInfo.width, &info.mapperInfo.height,
- (uint32_t *)&info.mapperInfo.format, (uint64_t *)&info.mapperInfo.usage, &info.stride,
- &generation, &igbp_id, &igbp_slot);
- if (grallocHandle == nullptr) {
- return C2_BAD_VALUE;
+ if (mMapper2) {
+ BufferDescriptorInfo2 info;
+ info.mapperInfo.layerCount = 1u;
+ uint32_t generation;
+ uint64_t igbp_id;
+ uint32_t igbp_slot;
+ const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
+ handle,
+ &info.mapperInfo.width, &info.mapperInfo.height,
+ (uint32_t *)&info.mapperInfo.format,
+ (uint64_t *)&info.mapperInfo.usage,
+ &info.stride,
+ &generation, &igbp_id, &igbp_slot);
+ if (grallocHandle == nullptr) {
+ return C2_BAD_VALUE;
+ }
+
+ hidl_handle hidlHandle;
+ hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
+
+ allocation->reset(new C2AllocationGralloc(
+ info, mMapper2, hidlHandle, grallocHandle, mTraits->id));
+ return C2_OK;
+ } else {
+ BufferDescriptorInfo3 info;
+ info.mapperInfo.layerCount = 1u;
+ uint32_t generation;
+ uint64_t igbp_id;
+ uint32_t igbp_slot;
+ const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
+ handle,
+ &info.mapperInfo.width, &info.mapperInfo.height,
+ (uint32_t *)&info.mapperInfo.format,
+ (uint64_t *)&info.mapperInfo.usage,
+ &info.stride,
+ &generation, &igbp_id, &igbp_slot);
+ if (grallocHandle == nullptr) {
+ return C2_BAD_VALUE;
+ }
+
+ hidl_handle hidlHandle;
+ hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
+
+ allocation->reset(new C2AllocationGralloc(
+ info, mMapper3, hidlHandle, grallocHandle, mTraits->id));
+ return C2_OK;
}
-
- hidl_handle hidlHandle;
- hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
-
- allocation->reset(new C2AllocationGralloc(info, mMapper, hidlHandle, grallocHandle, mTraits->id));
- return C2_OK;
}
C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)